Localizes timeline strings

This commit is contained in:
Eric Amodio 2020-02-24 22:56:37 -05:00
parent 5e80bf449c
commit 89cafb24e5
5 changed files with 138 additions and 114 deletions

View file

@ -430,25 +430,25 @@ export class CommandCenter {
case Status.INDEX_MODIFIED:
case Status.INDEX_RENAMED:
case Status.INDEX_ADDED:
return `${basename} (Index)`;
return localize('git.title.index', '{0} (Index)', basename);
case Status.MODIFIED:
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return `${basename} (Working Tree)`;
return localize('git.title.workingTree', '{0} (Working Tree)', basename);
case Status.DELETED_BY_US:
return `${basename} (Theirs)`;
return localize('git.title.theirs', '{0} (Theirs)', basename);
case Status.DELETED_BY_THEM:
return `${basename} (Ours)`;
return localize('git.title.ours', '{0} (Ours)', basename);
case Status.UNTRACKED:
return localize('git.title.untracked', '{0} (Untracked)', basename);
return `${basename} (Untracked)`;
default:
return '';
}
return '';
}
@command('git.clone')
@ -2348,12 +2348,12 @@ export class CommandCenter {
let title;
if ((item.previousRef === 'HEAD' || item.previousRef === '~') && item.ref === '') {
title = `${basename} (Working Tree)`;
title = localize('git.title.workingTree', '{0} (Working Tree)', basename);
}
else if (item.previousRef === 'HEAD' && item.ref === '~') {
title = `${basename} (Index)`;
title = localize('git.title.index', '{0} (Index)', basename);
} else {
title = `${basename} (${item.shortPreviousRef}) \u27f7 ${basename} (${item.shortRef})`;
title = localize('git.title.diffRefs', '{0} ({1}) \u27f7 {0} ({2})', basename, item.shortPreviousRef, item.shortRef);
}
return commands.executeCommand('vscode.diff', toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title);

View file

@ -40,6 +40,29 @@ export const enum ResourceGroupType {
export class Resource implements SourceControlResourceState {
static getStatusText(type: Status) {
switch (type) {
case Status.INDEX_MODIFIED: return localize('index modified', "Index Modified");
case Status.MODIFIED: return localize('modified', "Modified");
case Status.INDEX_ADDED: return localize('index added', "Index Added");
case Status.INDEX_DELETED: return localize('index deleted', "Index Deleted");
case Status.DELETED: return localize('deleted', "Deleted");
case Status.INDEX_RENAMED: return localize('index renamed', "Index Renamed");
case Status.INDEX_COPIED: return localize('index copied', "Index Copied");
case Status.UNTRACKED: return localize('untracked', "Untracked");
case Status.IGNORED: return localize('ignored', "Ignored");
case Status.INTENT_TO_ADD: return localize('intent to add', "Intent to Add");
case Status.BOTH_DELETED: return localize('both deleted', "Both Deleted");
case Status.ADDED_BY_US: return localize('added by us', "Added By Us");
case Status.DELETED_BY_THEM: return localize('deleted by them', "Deleted By Them");
case Status.ADDED_BY_THEM: return localize('added by them', "Added By Them");
case Status.DELETED_BY_US: return localize('deleted by us', "Deleted By Us");
case Status.BOTH_ADDED: return localize('both added', "Both Added");
case Status.BOTH_MODIFIED: return localize('both modified', "Both Modified");
default: return '';
}
}
@memoize
get resourceUri(): Uri {
if (this.renameResourceUri && (this._type === Status.MODIFIED || this._type === Status.DELETED || this._type === Status.INDEX_RENAMED || this._type === Status.INDEX_COPIED)) {
@ -110,26 +133,7 @@ export class Resource implements SourceControlResourceState {
}
private get tooltip(): string {
switch (this.type) {
case Status.INDEX_MODIFIED: return localize('index modified', "Index Modified");
case Status.MODIFIED: return localize('modified', "Modified");
case Status.INDEX_ADDED: return localize('index added', "Index Added");
case Status.INDEX_DELETED: return localize('index deleted', "Index Deleted");
case Status.DELETED: return localize('deleted', "Deleted");
case Status.INDEX_RENAMED: return localize('index renamed', "Index Renamed");
case Status.INDEX_COPIED: return localize('index copied', "Index Copied");
case Status.UNTRACKED: return localize('untracked', "Untracked");
case Status.IGNORED: return localize('ignored', "Ignored");
case Status.INTENT_TO_ADD: return localize('intent to add', "Intent to Add");
case Status.BOTH_DELETED: return localize('both deleted', "Both Deleted");
case Status.ADDED_BY_US: return localize('added by us', "Added By Us");
case Status.DELETED_BY_THEM: return localize('deleted by them', "Deleted By Them");
case Status.ADDED_BY_THEM: return localize('added by them', "Added By Them");
case Status.DELETED_BY_US: return localize('deleted by us', "Deleted By Us");
case Status.BOTH_ADDED: return localize('both added', "Both Added");
case Status.BOTH_MODIFIED: return localize('both modified', "Both Modified");
default: return '';
}
return Resource.getStatusText(this.type);
}
private get strikeThrough(): boolean {

View file

@ -3,17 +3,18 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls';
import * as dayjs from 'dayjs';
import * as advancedFormat from 'dayjs/plugin/advancedFormat';
import { CancellationToken, Disposable, Event, EventEmitter, ThemeIcon, Timeline, TimelineChangeEvent, TimelineItem, TimelineOptions, TimelineProvider, Uri, workspace } from 'vscode';
import { Model } from './model';
import { Repository } from './repository';
import { Repository, Resource } from './repository';
import { debounce } from './decorators';
import { Status } from './api/git';
dayjs.extend(advancedFormat);
// TODO[ECA]: Localize all the strings
const localize = nls.loadMessageBundle();
// TODO[ECA]: Localize or use a setting for date format
export class GitTimelineItem extends TimelineItem {
@ -68,7 +69,7 @@ export class GitTimelineProvider implements TimelineProvider {
}
readonly id = 'git-history';
readonly label = 'Git History';
readonly label = localize('git.timeline.source', 'Git History');
private _disposable: Disposable;
@ -171,38 +172,18 @@ export class GitTimelineProvider implements TimelineProvider {
});
if (options.cursor === undefined || options.before) {
const you = localize('git.timeline.you', 'You');
const index = repo.indexGroup.resourceStates.find(r => r.resourceUri.fsPath === uri.fsPath);
if (index) {
const date = this._repoStatusDate ?? new Date();
dateFormatter = dayjs(date);
let status;
switch (index.type) {
case Status.INDEX_MODIFIED:
status = 'Modified';
break;
case Status.INDEX_ADDED:
status = 'Added';
break;
case Status.INDEX_DELETED:
status = 'Deleted';
break;
case Status.INDEX_RENAMED:
status = 'Renamed';
break;
case Status.INDEX_COPIED:
status = 'Copied';
break;
default:
status = '';
break;
}
const item = new GitTimelineItem('~', 'HEAD', 'Staged Changes', date.getTime(), 'index', 'git:file:index');
const item = new GitTimelineItem('~', 'HEAD', localize('git.timeline.stagedChanges', 'Staged Changes'), date.getTime(), 'index', 'git:file:index');
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new (ThemeIcon as any)('git-commit');
item.description = 'You';
item.detail = `You \u2014 Index\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n${status}`;
item.description = you;
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.index', 'Index'), dateFormatter.format('MMMM Do, YYYY h:mma'), Resource.getStatusText(index.type));
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',
@ -217,33 +198,11 @@ export class GitTimelineProvider implements TimelineProvider {
const date = new Date();
dateFormatter = dayjs(date);
let status;
switch (working.type) {
case Status.INDEX_MODIFIED:
status = 'Modified';
break;
case Status.INDEX_ADDED:
status = 'Added';
break;
case Status.INDEX_DELETED:
status = 'Deleted';
break;
case Status.INDEX_RENAMED:
status = 'Renamed';
break;
case Status.INDEX_COPIED:
status = 'Copied';
break;
default:
status = '';
break;
}
const item = new GitTimelineItem('', index ? '~' : 'HEAD', 'Uncommited Changes', date.getTime(), 'working', 'git:file:working');
const item = new GitTimelineItem('', index ? '~' : 'HEAD', localize('git.timeline.uncommitedChanges', 'Uncommited Changes'), date.getTime(), 'working', 'git:file:working');
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
item.iconPath = new (ThemeIcon as any)('git-commit');
item.description = 'You';
item.detail = `You \u2014 Working Tree\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n${status}`;
item.description = you;
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.workingTree', 'Working Tree'), dateFormatter.format('MMMM Do, YYYY h:mma'), Resource.getStatusText(working.type));
item.command = {
title: 'Open Comparison',
command: 'git.timeline.openDiff',

View file

@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { pad } from './strings';
import { localize } from 'vs/nls';
const minute = 60;
const hour = minute * 60;
@ -12,7 +13,6 @@ const week = day * 7;
const month = day * 30;
const year = day * 365;
// TODO[ECA]: Localize strings
export function fromNow(date: number | Date, appendAgoLabel?: boolean): string {
if (typeof date !== 'number') {
date = date.getTime();
@ -20,36 +20,99 @@ export function fromNow(date: number | Date, appendAgoLabel?: boolean): string {
const seconds = Math.round((new Date().getTime() - date) / 1000);
if (seconds < 30) {
return 'now';
return localize('date.fromNow.now', 'now');
}
let value: number;
let unit: string;
if (seconds < minute) {
value = seconds;
unit = 'sec';
} else if (seconds < hour) {
value = Math.floor(seconds / minute);
unit = 'min';
} else if (seconds < day) {
value = Math.floor(seconds / hour);
unit = 'hr';
} else if (seconds < week) {
value = Math.floor(seconds / day);
unit = 'day';
} else if (seconds < month) {
value = Math.floor(seconds / week);
unit = 'wk';
} else if (seconds < year) {
value = Math.floor(seconds / month);
unit = 'mo';
} else {
value = Math.floor(seconds / year);
unit = 'yr';
if (appendAgoLabel) {
return value === 1
? localize('date.fromNow.seconds.singular.ago', '{0} sec ago', value)
: localize('date.fromNow.seconds.plural.ago', '{0} secs ago', value);
} else {
return value === 1
? localize('date.fromNow.seconds.singular', '{0} sec', value)
: localize('date.fromNow.seconds.plural', '{0} secs', value);
}
}
return `${value} ${unit}${value === 1 ? '' : 's'}${appendAgoLabel ? ' ago' : ''}`;
if (seconds < hour) {
value = Math.floor(seconds / minute);
if (appendAgoLabel) {
return value === 1
? localize('date.fromNow.minutes.singular.ago', '{0} min ago', value)
: localize('date.fromNow.minutes.plural.ago', '{0} mins ago', value);
} else {
return value === 1
? localize('date.fromNow.minutes.singular', '{0} min', value)
: localize('date.fromNow.minutes.plural', '{0} mins', value);
}
}
if (seconds < day) {
value = Math.floor(seconds / hour);
if (appendAgoLabel) {
return value === 1
? localize('date.fromNow.hours.singular.ago', '{0} hr ago', value)
: localize('date.fromNow.hours.plural.ago', '{0} hrs ago', value);
} else {
return value === 1
? localize('date.fromNow.hours.singular', '{0} hr', value)
: localize('date.fromNow.hours.plural', '{0} hrs', value);
}
}
if (seconds < week) {
value = Math.floor(seconds / day);
if (appendAgoLabel) {
return value === 1
? localize('date.fromNow.days.singular.ago', '{0} day ago', value)
: localize('date.fromNow.days.plural.ago', '{0} days ago', value);
} else {
return value === 1
? localize('date.fromNow.days.singular', '{0} day', value)
: localize('date.fromNow.days.plural', '{0} days', value);
}
}
if (seconds < month) {
value = Math.floor(seconds / week);
if (appendAgoLabel) {
return value === 1
? localize('date.fromNow.weeks.singular.ago', '{0} wk ago', value)
: localize('date.fromNow.weeks.plural.ago', '{0} wks ago', value);
} else {
return value === 1
? localize('date.fromNow.weeks.singular', '{0} wk', value)
: localize('date.fromNow.weeks.plural', '{0} wks', value);
}
}
if (seconds < year) {
value = Math.floor(seconds / month);
if (appendAgoLabel) {
return value === 1
? localize('date.fromNow.months.singular.ago', '{0} mo ago', value)
: localize('date.fromNow.months.plural.ago', '{0} mos ago', value);
} else {
return value === 1
? localize('date.fromNow.months.singular', '{0} mo', value)
: localize('date.fromNow.months.plural', '{0} mos', value);
}
}
value = Math.floor(seconds / year);
if (appendAgoLabel) {
return value === 1
? localize('date.fromNow.years.singular.ago', '{0} yr ago', value)
: localize('date.fromNow.years.plural.ago', '{0} yrs ago', value);
} else {
return value === 1
? localize('date.fromNow.years.singular', '{0} yr', value)
: localize('date.fromNow.years.plural', '{0} yrs', value);
}
}
export function toLocalISOString(date: Date): string {

View file

@ -38,8 +38,6 @@ import { MenuItemAction, IMenuService, MenuId } from 'vs/platform/actions/common
import { fromNow } from 'vs/base/common/date';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
// TODO[ECA]: Localize all the strings
const InitialPageSize = 20;
const SubsequentPageSize = 40;
@ -240,7 +238,7 @@ export class TimelinePane extends ViewPane {
// TODO[ECA]: Are these the right the list of schemes to exclude? Is there a better way?
if (this._uri && (this._uri.scheme === 'vscode-settings' || this._uri.scheme === 'webview-panel' || this._uri.scheme === 'walkThrough')) {
this.message = 'The active editor cannot provide timeline information.';
this.message = localize('timeline.editorCannotProvideTimeline', 'The active editor cannot provide timeline information.');
this._tree.setChildren(null, undefined);
return;
@ -253,7 +251,7 @@ export class TimelinePane extends ViewPane {
}
this._tree.setChildren(null, undefined);
this.message = `Loading timeline for ${basename(uri.fsPath)}...`;
this.message = localize('timeline.loading', 'Loading timeline for ${0}...', basename(uri.fsPath));
}, 500, this._uri);
}
}
@ -410,7 +408,7 @@ export class TimelinePane extends ViewPane {
this._items.push({
element: {
handle: 'vscode-command:loadMore',
label: 'Load more',
label: localize('timeline.loadMore', 'Load more'),
timestamp: 0
} as CommandItem
});
@ -512,7 +510,7 @@ export class TimelinePane extends ViewPane {
}
if (this._items.length === 0) {
this.message = 'No timeline information was provided.';
this.message = localize('timeline.noTimelineInfo', 'No timeline information was provided.');
} else {
this.message = undefined;
}
@ -556,7 +554,7 @@ export class TimelinePane extends ViewPane {
this._messageElement = DOM.append(this._container, DOM.$('.message'));
DOM.addClass(this._messageElement, 'timeline-subtle');
this.message = 'The active editor cannot provide timeline information.';
this.message = localize('timeline.editorCannotProvideTimeline', 'The active editor cannot provide timeline information.');
this._treeElement = document.createElement('div');
DOM.addClasses(this._treeElement, 'customview-tree', 'file-icon-themable-tree', 'hide-arrows');