fix: localize file type labels
This commit is contained in:
parent
484d599a9f
commit
c9c26faf56
|
|
@ -224,7 +224,7 @@
|
||||||
return EXT_MAP[ext] || 'generic';
|
return EXT_MAP[ext] || 'generic';
|
||||||
}
|
}
|
||||||
|
|
||||||
function fileIconLabel(category) {
|
function fileIconLabel(category, translate) {
|
||||||
var labels = {
|
var labels = {
|
||||||
folder: 'Folder',
|
folder: 'Folder',
|
||||||
markdown: 'Markdown file',
|
markdown: 'Markdown file',
|
||||||
|
|
@ -244,7 +244,8 @@
|
||||||
json: 'JSON file',
|
json: 'JSON file',
|
||||||
generic: 'File'
|
generic: 'File'
|
||||||
};
|
};
|
||||||
return labels[category] || labels.generic;
|
var label = labels[category] || labels.generic;
|
||||||
|
return typeof translate === 'function' ? translate('ui.icon.' + (labels[category] ? category : 'generic'), null, label) : label;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fileIcon(entry) {
|
function fileIcon(entry) {
|
||||||
|
|
@ -267,8 +268,8 @@
|
||||||
return date.toLocaleString(undefined, { year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' });
|
return date.toLocaleString(undefined, { year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' });
|
||||||
}
|
}
|
||||||
|
|
||||||
function typeLabel(entry) {
|
function typeLabel(entry, folderLabel) {
|
||||||
if (entry.type === 'folder') return 'folder';
|
if (entry.type === 'folder') return folderLabel || 'Folder';
|
||||||
return (entry.extension || extension(entry.name) || 'file').toLowerCase();
|
return (entry.extension || extension(entry.name) || 'file').toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -383,6 +384,10 @@
|
||||||
return fallback || key;
|
return fallback || key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function displayType(entry) {
|
||||||
|
return typeLabel(entry, tr('ui.folderType', null, 'Folder'));
|
||||||
|
}
|
||||||
|
|
||||||
function reportError(key, fallback, err) {
|
function reportError(key, fallback, err) {
|
||||||
if (typeof console !== 'undefined' && typeof console.warn === 'function') {
|
if (typeof console !== 'undefined' && typeof console.warn === 'function') {
|
||||||
console.warn('[verstak.files] ' + key, err);
|
console.warn('[verstak.files] ' + key, err);
|
||||||
|
|
@ -523,7 +528,7 @@
|
||||||
if (a.type !== 'folder' && b.type === 'folder') return 1;
|
if (a.type !== 'folder' && b.type === 'folder') return 1;
|
||||||
}
|
}
|
||||||
if (sortMode === 'type') {
|
if (sortMode === 'type') {
|
||||||
var typeCmp = typeLabel(a).localeCompare(typeLabel(b));
|
var typeCmp = displayType(a).localeCompare(displayType(b));
|
||||||
if (typeCmp) return typeCmp;
|
if (typeCmp) return typeCmp;
|
||||||
}
|
}
|
||||||
if (sortMode === 'modified-desc') {
|
if (sortMode === 'modified-desc') {
|
||||||
|
|
@ -645,7 +650,7 @@
|
||||||
|
|
||||||
shown.forEach(function (entry) {
|
shown.forEach(function (entry) {
|
||||||
var iconCategory = fileIconCategory(entry);
|
var iconCategory = fileIconCategory(entry);
|
||||||
var iconLabel = fileIconLabel(iconCategory);
|
var iconLabel = fileIconLabel(iconCategory, tr);
|
||||||
var row = el('div', {
|
var row = el('div', {
|
||||||
className: 'files-item' + (selectedPaths[entry.relativePath] ? ' selected' : ''),
|
className: 'files-item' + (selectedPaths[entry.relativePath] ? ' selected' : ''),
|
||||||
'data-file-name': entry.name,
|
'data-file-name': entry.name,
|
||||||
|
|
@ -678,7 +683,7 @@
|
||||||
el('span', { className: 'files-item-icon', 'data-file-icon': iconCategory, title: iconLabel, 'aria-label': iconLabel, innerHTML: fileIcon(entry) }),
|
el('span', { className: 'files-item-icon', 'data-file-icon': iconCategory, title: iconLabel, 'aria-label': iconLabel, innerHTML: fileIcon(entry) }),
|
||||||
el('span', { className: 'files-item-name', textContent: entry.name, title: entry.name })
|
el('span', { className: 'files-item-name', textContent: entry.name, title: entry.name })
|
||||||
]),
|
]),
|
||||||
el('span', { className: 'files-item-meta' }, [typeLabel(entry)]),
|
el('span', { className: 'files-item-meta' }, [displayType(entry)]),
|
||||||
el('span', { className: 'files-item-meta hide-narrow' }, [entry.type === 'folder' ? '' : formatSize(entry.size)]),
|
el('span', { className: 'files-item-meta hide-narrow' }, [entry.type === 'folder' ? '' : formatSize(entry.size)]),
|
||||||
el('span', { className: 'files-item-meta hide-narrow' }, [formatDate(entry.modifiedAt)]),
|
el('span', { className: 'files-item-meta hide-narrow' }, [formatDate(entry.modifiedAt)]),
|
||||||
el('div', { className: 'files-row-actions' }, [
|
el('div', { className: 'files-row-actions' }, [
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,24 @@
|
||||||
"ui.column.modified": "Modified",
|
"ui.column.modified": "Modified",
|
||||||
"ui.column.size": "Size",
|
"ui.column.size": "Size",
|
||||||
"ui.column.actions": "Actions",
|
"ui.column.actions": "Actions",
|
||||||
|
"ui.folderType": "Folder",
|
||||||
|
"ui.icon.folder": "Folder",
|
||||||
|
"ui.icon.markdown": "Markdown file",
|
||||||
|
"ui.icon.image": "Image file",
|
||||||
|
"ui.icon.video": "Video file",
|
||||||
|
"ui.icon.audio": "Audio file",
|
||||||
|
"ui.icon.archive": "Archive file",
|
||||||
|
"ui.icon.pdf": "PDF file",
|
||||||
|
"ui.icon.text": "Text file",
|
||||||
|
"ui.icon.document": "Document file",
|
||||||
|
"ui.icon.spreadsheet": "Spreadsheet file",
|
||||||
|
"ui.icon.presentation": "Presentation file",
|
||||||
|
"ui.icon.code": "Code file",
|
||||||
|
"ui.icon.database": "Database file",
|
||||||
|
"ui.icon.font": "Font file",
|
||||||
|
"ui.icon.config": "Config file",
|
||||||
|
"ui.icon.json": "JSON file",
|
||||||
|
"ui.icon.generic": "File",
|
||||||
"ui.create": "Create",
|
"ui.create": "Create",
|
||||||
"ui.cancel": "Cancel",
|
"ui.cancel": "Cancel",
|
||||||
"ui.createFolderTitle": "Create folder",
|
"ui.createFolderTitle": "Create folder",
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,24 @@
|
||||||
"ui.column.modified": "Изменён",
|
"ui.column.modified": "Изменён",
|
||||||
"ui.column.size": "Размер",
|
"ui.column.size": "Размер",
|
||||||
"ui.column.actions": "Действия",
|
"ui.column.actions": "Действия",
|
||||||
|
"ui.folderType": "Папка",
|
||||||
|
"ui.icon.folder": "Папка",
|
||||||
|
"ui.icon.markdown": "Файл Markdown",
|
||||||
|
"ui.icon.image": "Изображение",
|
||||||
|
"ui.icon.video": "Видео",
|
||||||
|
"ui.icon.audio": "Аудиофайл",
|
||||||
|
"ui.icon.archive": "Архив",
|
||||||
|
"ui.icon.pdf": "PDF-файл",
|
||||||
|
"ui.icon.text": "Текстовый файл",
|
||||||
|
"ui.icon.document": "Документ",
|
||||||
|
"ui.icon.spreadsheet": "Таблица",
|
||||||
|
"ui.icon.presentation": "Презентация",
|
||||||
|
"ui.icon.code": "Исходный код",
|
||||||
|
"ui.icon.database": "База данных",
|
||||||
|
"ui.icon.font": "Шрифт",
|
||||||
|
"ui.icon.config": "Файл конфигурации",
|
||||||
|
"ui.icon.json": "JSON-файл",
|
||||||
|
"ui.icon.generic": "Файл",
|
||||||
"ui.create": "Создать",
|
"ui.create": "Создать",
|
||||||
"ui.cancel": "Отмена",
|
"ui.cancel": "Отмена",
|
||||||
"ui.createFolderTitle": "Создать папку",
|
"ui.createFolderTitle": "Создать папку",
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,15 @@ function makeApi(options = {}) {
|
||||||
size: 12,
|
size: 12,
|
||||||
modifiedAt: '2026-06-27T00:00:00Z',
|
modifiedAt: '2026-06-27T00:00:00Z',
|
||||||
}];
|
}];
|
||||||
|
if (options.includeFolder) {
|
||||||
|
entries.push({
|
||||||
|
name: 'Archive',
|
||||||
|
relativePath: 'Docs/Archive',
|
||||||
|
type: 'folder',
|
||||||
|
size: 0,
|
||||||
|
modifiedAt: '2026-06-27T00:00:00Z',
|
||||||
|
});
|
||||||
|
}
|
||||||
if (restored) {
|
if (restored) {
|
||||||
entries.push({
|
entries.push({
|
||||||
name: 'deleted.md',
|
name: 'deleted.md',
|
||||||
|
|
@ -456,6 +465,7 @@ async function flush() {
|
||||||
const russianDocument = makeDocument();
|
const russianDocument = makeDocument();
|
||||||
const { component: russianComponent } = loadFilesComponent(russianDocument);
|
const { component: russianComponent } = loadFilesComponent(russianDocument);
|
||||||
const russianApi = makeApi({
|
const russianApi = makeApi({
|
||||||
|
includeFolder: true,
|
||||||
translations: {
|
translations: {
|
||||||
'ui.open': 'Открыть',
|
'ui.open': 'Открыть',
|
||||||
'ui.openExternal': 'Открыть во внешнем приложении',
|
'ui.openExternal': 'Открыть во внешнем приложении',
|
||||||
|
|
@ -465,13 +475,22 @@ async function flush() {
|
||||||
'ui.cut': 'Вырезать',
|
'ui.cut': 'Вырезать',
|
||||||
'ui.copy': 'Копировать',
|
'ui.copy': 'Копировать',
|
||||||
'ui.trash': 'Переместить в корзину',
|
'ui.trash': 'Переместить в корзину',
|
||||||
|
'ui.folderType': 'Папка',
|
||||||
|
'ui.icon.markdown': 'Файл Markdown',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const russianContainer = new FakeNode('div');
|
const russianContainer = new FakeNode('div');
|
||||||
russianComponent.mount(russianContainer, {}, russianApi);
|
russianComponent.mount(russianContainer, {}, russianApi);
|
||||||
await flush();
|
await flush();
|
||||||
|
if (!russianContainer.textContent.includes('Папка') || russianContainer.textContent.includes('folder')) {
|
||||||
|
throw new Error(`folder type was not localized: ${russianContainer.textContent}`);
|
||||||
|
}
|
||||||
const russianList = walk(russianContainer, (node) => node.getAttribute && node.getAttribute('data-files-list') !== undefined);
|
const russianList = walk(russianContainer, (node) => node.getAttribute && node.getAttribute('data-files-list') !== undefined);
|
||||||
const russianRow = walk(russianContainer, (node) => node.getAttribute && node.getAttribute('data-file-path') === 'Docs/readme.md');
|
const russianRow = walk(russianContainer, (node) => node.getAttribute && node.getAttribute('data-file-path') === 'Docs/readme.md');
|
||||||
|
const russianIcon = walk(russianRow, (node) => node.getAttribute && node.getAttribute('data-file-icon') === 'markdown');
|
||||||
|
if (!russianIcon || russianIcon.getAttribute('title') !== 'Файл Markdown' || russianIcon.getAttribute('aria-label') !== 'Файл Markdown') {
|
||||||
|
throw new Error(`file icon label was not localized: ${russianIcon && russianIcon.getAttribute('title')}`);
|
||||||
|
}
|
||||||
russianList.dispatchEvent('contextmenu', { target: russianRow, clientX: 20, clientY: 20 });
|
russianList.dispatchEvent('contextmenu', { target: russianRow, clientX: 20, clientY: 20 });
|
||||||
const russianMenuText = russianDocument.body.textContent;
|
const russianMenuText = russianDocument.body.textContent;
|
||||||
['Открыть во внешнем приложении', 'Показать в папке', 'Переименовать', 'Создать копию', 'Вырезать', 'Копировать', 'Переместить в корзину'].forEach((label) => {
|
['Открыть во внешнем приложении', 'Показать в папке', 'Переименовать', 'Создать копию', 'Вырезать', 'Копировать', 'Переместить в корзину'].forEach((label) => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue