mirror of
https://github.com/lostpaul/obsidian-folder-notes.git
synced 2026-07-22 07:40:24 +00:00
Add Chinese (中文) language support with i18n system
- Create src/i18n/ module with en.ts, zh.ts, and index.ts (t() function) - Add `language` setting to FolderNotesSettings with dropdown selector in General tab - Translate all settings UI: GeneralSettings, FileExplorerSettings, PathSettings, ExcludedFoldersSettings, FolderOverviewSettings, SettingsTab tab names and notices - Translate Commands.ts menu items and notices - Translate DeleteConfirmation modal - Language change takes effect immediately without restart https://claude.ai/code/session_01R8HoXuSmtpXUtqdMjNCs6w
This commit is contained in:
parent
2683ee1a1a
commit
3b242c056d
12 changed files with 712 additions and 232 deletions
|
|
@ -30,6 +30,7 @@ import {
|
|||
hideFolderNoteInFileExplorer,
|
||||
showFolderNoteInFileExplorer,
|
||||
} from './functions/styleFunctions';
|
||||
import { t } from './i18n';
|
||||
|
||||
|
||||
|
||||
|
|
@ -49,7 +50,7 @@ export class Commands {
|
|||
regularCommands(): void {
|
||||
this.plugin.addCommand({
|
||||
id: 'turn-into-folder-note',
|
||||
name: 'Use this file as the folder note for its parent folder',
|
||||
name: t('cmdUseFolderNote'),
|
||||
checkCallback: (checking: boolean) => {
|
||||
const file = this.app.workspace.getActiveFile();
|
||||
if (!(file instanceof TFile)) return false;
|
||||
|
|
@ -66,7 +67,7 @@ export class Commands {
|
|||
|
||||
this.plugin.addCommand({
|
||||
id: 'create-folder-note',
|
||||
name: 'Make a folder with this file as its folder note',
|
||||
name: t('cmdMakeFolderWithNote'),
|
||||
callback: async () => {
|
||||
const file = this.app.workspace.getActiveFile();
|
||||
if (!(file instanceof TFile)) return;
|
||||
|
|
@ -75,7 +76,7 @@ export class Commands {
|
|||
newPath = file.basename;
|
||||
}
|
||||
if (this.plugin.app.vault.getAbstractFileByPath(newPath)) {
|
||||
return new Notice('Folder already exists');
|
||||
return new Notice(t('noticeFolderAlreadyExists'));
|
||||
}
|
||||
const automaticallyCreateFolderNote =
|
||||
this.plugin.settings.autoCreate;
|
||||
|
|
@ -92,7 +93,7 @@ export class Commands {
|
|||
|
||||
this.plugin.addCommand({
|
||||
id: 'create-folder-note-for-current-folder',
|
||||
name: 'Create markdown folder note for this folder',
|
||||
name: t('cmdCreateMarkdownFolderNote'),
|
||||
checkCallback: (checking) => {
|
||||
const file = this.app.workspace.getActiveFile();
|
||||
if (!(file instanceof TFile)) return false;
|
||||
|
|
@ -108,7 +109,7 @@ export class Commands {
|
|||
if (fileType === 'md') return;
|
||||
this.plugin.addCommand({
|
||||
id: `create-${fileType}-folder-note-for-current-folder`,
|
||||
name: `Create ${fileType} folder note for this folder`,
|
||||
name: t('cmdCreateFileTypeFolderNote', { fileType }),
|
||||
checkCallback: (checking) => {
|
||||
const file = this.app.workspace.getActiveFile();
|
||||
if (!(file instanceof TFile)) return false;
|
||||
|
|
@ -124,7 +125,7 @@ export class Commands {
|
|||
const type = fileType === 'md' ? 'markdown' : fileType;
|
||||
this.plugin.addCommand({
|
||||
id: `create-${type}-folder-note-for-active-file-explorer-folder`,
|
||||
name: `Create ${type} folder note for current active folder in file explorer`,
|
||||
name: t('cmdCreateFileTypeFolderNoteForActive', { type }),
|
||||
checkCallback: (checking: boolean) => {
|
||||
const folder = getFileExplorerActiveFolder();
|
||||
if (!folder) return false;
|
||||
|
|
@ -143,7 +144,7 @@ export class Commands {
|
|||
|
||||
this.plugin.addCommand({
|
||||
id: 'delete-folder-note-for-current-folder',
|
||||
name: 'Delete this folder\'s linked note',
|
||||
name: t('cmdDeleteFolderNote'),
|
||||
checkCallback: (checking) => {
|
||||
const file = this.app.workspace.getActiveFile();
|
||||
if (!(file instanceof TFile)) return false;
|
||||
|
|
@ -158,7 +159,7 @@ export class Commands {
|
|||
|
||||
this.plugin.addCommand({
|
||||
id: 'delete-folder-note-of-active-file-explorer-folder',
|
||||
name: 'Delete folder note of current active folder in file explorer',
|
||||
name: t('cmdDeleteFolderNoteActive'),
|
||||
checkCallback: (checking: boolean) => {
|
||||
const folder = getFileExplorerActiveFolder();
|
||||
if (!folder) return false;
|
||||
|
|
@ -173,7 +174,7 @@ export class Commands {
|
|||
});
|
||||
this.plugin.addCommand({
|
||||
id: 'open-folder-note-for-current-folder',
|
||||
name: 'Open this folder\'s linked note',
|
||||
name: t('cmdOpenFolderNote'),
|
||||
checkCallback: (checking) => {
|
||||
const file = this.app.workspace.getActiveFile();
|
||||
if (!(file instanceof TFile)) return false;
|
||||
|
|
@ -187,7 +188,7 @@ export class Commands {
|
|||
});
|
||||
this.plugin.addCommand({
|
||||
id: 'open-folder-note-of-active-file-explorer-folder',
|
||||
name: 'Open folder note of current active folder in file explorer',
|
||||
name: t('cmdOpenFolderNoteActive'),
|
||||
checkCallback: (checking: boolean) => {
|
||||
const folder = getFileExplorerActiveFolder();
|
||||
if (!folder) return false;
|
||||
|
|
@ -203,7 +204,7 @@ export class Commands {
|
|||
|
||||
this.plugin.addCommand({
|
||||
id: 'create-folder-note-from-selected-text',
|
||||
name: 'Create folder note from selection',
|
||||
name: t('cmdCreateFolderNoteFromSelection'),
|
||||
editorCheckCallback: (checking: boolean, editor: Editor, view: MarkdownView) => {
|
||||
const text = editor.getSelection().trim();
|
||||
const { file } = view;
|
||||
|
|
@ -214,12 +215,12 @@ export class Commands {
|
|||
for (const char of blacklist) {
|
||||
if (text.includes(char)) {
|
||||
// eslint-disable-next-line max-len
|
||||
new Notice('File name cannot contain any of the following characters: * " \\ / < > : | ?');
|
||||
new Notice(t('noticeInvalidFileName'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (text.endsWith('.')) {
|
||||
new Notice('File name cannot end with a dot');
|
||||
new Notice(t('noticeFileNameEndDot'));
|
||||
return;
|
||||
}
|
||||
let folder: TAbstractFile | null;
|
||||
|
|
@ -227,7 +228,7 @@ export class Commands {
|
|||
if (folderPath === '') {
|
||||
folder = this.plugin.app.vault.getAbstractFileByPath(text);
|
||||
if (folder instanceof TFolder) {
|
||||
new Notice('Folder note already exists');
|
||||
new Notice(t('noticeFolderNoteAlreadyExists'));
|
||||
return false;
|
||||
}
|
||||
this.plugin.app.vault.createFolder(text);
|
||||
|
|
@ -237,7 +238,7 @@ export class Commands {
|
|||
const folderFullPath = folderPath + '/' + text;
|
||||
folder = this.plugin.app.vault.getAbstractFileByPath(folderFullPath);
|
||||
if (folder instanceof TFolder) {
|
||||
new Notice('Folder note already exists');
|
||||
new Notice(t('noticeFolderNoteAlreadyExists'));
|
||||
return false;
|
||||
}
|
||||
if (this.plugin.settings.storageLocation === 'parentFolder') {
|
||||
|
|
@ -246,7 +247,7 @@ export class Commands {
|
|||
folderPath + '/' + text + this.plugin.settings.folderNoteType,
|
||||
)
|
||||
) {
|
||||
new Notice('File already exists');
|
||||
new Notice(t('noticeFileAlreadyExists'));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -303,7 +304,7 @@ export class Commands {
|
|||
const addFolderNoteActions = (folderMenu: Menu): void => {
|
||||
if (file instanceof TFile) {
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Create folder note');
|
||||
item.setTitle(t('menuCreateFolderNote'));
|
||||
item.setIcon('edit');
|
||||
item.onClick(async () => {
|
||||
if (!folder) return;
|
||||
|
|
@ -312,7 +313,7 @@ export class Commands {
|
|||
newPath = file.basename;
|
||||
}
|
||||
if (this.plugin.app.vault.getAbstractFileByPath(newPath)) {
|
||||
return new Notice('Folder already exists');
|
||||
return new Notice(t('noticeFolderAlreadyExists'));
|
||||
}
|
||||
const automaticallyCreateFolderNote =
|
||||
this.plugin.settings.autoCreate;
|
||||
|
|
@ -342,7 +343,7 @@ export class Commands {
|
|||
if (folder.path === '' || folder.path === '/') return;
|
||||
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle(`Turn into folder note for ${folder?.name}`);
|
||||
item.setTitle(t('menuTurnIntoFolderNote', { folderName: folder?.name ?? '' }));
|
||||
item.setIcon('edit');
|
||||
item.onClick(() => {
|
||||
if (!folder || !(folder instanceof TFolder)) return;
|
||||
|
|
@ -372,7 +373,7 @@ export class Commands {
|
|||
// });
|
||||
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Remove folder from excluded folders');
|
||||
item.setTitle(t('menuRemoveFromExcluded'));
|
||||
item.setIcon('trash');
|
||||
item.onClick(() => {
|
||||
this.plugin.settings.excludeFolders =
|
||||
|
|
@ -381,7 +382,7 @@ export class Commands {
|
|||
(excluded.path !== file.path) || excluded.detached,
|
||||
);
|
||||
this.plugin.saveSettings(true);
|
||||
new Notice('Successfully removed folder from excluded folders');
|
||||
new Notice(t('noticeRemovedFromExcluded'));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -390,7 +391,7 @@ export class Commands {
|
|||
|
||||
if (detachedExcludedFolder) {
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Remove folder from detached folders');
|
||||
item.setTitle(t('menuRemoveFromDetached'));
|
||||
item.setIcon('trash');
|
||||
item.onClick(() => {
|
||||
deleteExcludedFolder(this.plugin, detachedExcludedFolder);
|
||||
|
|
@ -401,7 +402,7 @@ export class Commands {
|
|||
if (detachedExcludedFolder) { return; }
|
||||
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Exclude folder from folder notes');
|
||||
item.setTitle(t('menuExcludeFromFolderNotes'));
|
||||
item.setIcon('x-circle');
|
||||
item.onClick(() => {
|
||||
const newExcludedFolder = new ExcludedFolder(
|
||||
|
|
@ -412,7 +413,7 @@ export class Commands {
|
|||
);
|
||||
this.plugin.settings.excludeFolders.push(newExcludedFolder);
|
||||
this.plugin.saveSettings(true);
|
||||
new Notice('Successfully excluded folder from folder notes');
|
||||
new Notice(t('noticeExcluded'));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -422,7 +423,7 @@ export class Commands {
|
|||
|
||||
if (folderNote instanceof TFile && !detachedExcludedFolder) {
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Delete folder note');
|
||||
item.setTitle(t('menuDeleteFolderNote'));
|
||||
item.setIcon('trash');
|
||||
item.onClick(() => {
|
||||
deleteFolderNote(this.plugin, folderNote, true);
|
||||
|
|
@ -430,7 +431,7 @@ export class Commands {
|
|||
});
|
||||
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Open folder note');
|
||||
item.setTitle(t('menuOpenFolderNote'));
|
||||
item.setIcon('chevron-right-square');
|
||||
item.onClick(() => {
|
||||
openFolderNote(this.plugin, folderNote);
|
||||
|
|
@ -438,7 +439,7 @@ export class Commands {
|
|||
});
|
||||
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Detach folder note');
|
||||
item.setTitle(t('menuDetachFolderNote'));
|
||||
item.setIcon('unlink');
|
||||
item.onClick(() => {
|
||||
detachFolderNote(this.plugin, folderNote);
|
||||
|
|
@ -446,7 +447,7 @@ export class Commands {
|
|||
});
|
||||
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Copy Obsidian URL');
|
||||
item.setTitle(t('menuCopyObsidianUrl'));
|
||||
item.setIcon('link');
|
||||
item.onClick(() => {
|
||||
this.app.copyObsidianUrl(folderNote);
|
||||
|
|
@ -456,7 +457,7 @@ export class Commands {
|
|||
if (this.plugin.settings.hideFolderNote) {
|
||||
if (excludedFolder?.showFolderNote) {
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Hide folder note in explorer');
|
||||
item.setTitle(t('menuHideFolderNoteInExplorer'));
|
||||
item.setIcon('eye-off');
|
||||
item.onClick(() => {
|
||||
hideFolderNoteInFileExplorer(file.path, this.plugin);
|
||||
|
|
@ -464,7 +465,7 @@ export class Commands {
|
|||
});
|
||||
} else {
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Show folder note in explorer');
|
||||
item.setTitle(t('menuShowFolderNoteInExplorer'));
|
||||
item.setIcon('eye');
|
||||
item.onClick(() => {
|
||||
showFolderNoteInFileExplorer(file.path, this.plugin);
|
||||
|
|
@ -474,7 +475,7 @@ export class Commands {
|
|||
}
|
||||
} else {
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle('Create markdown folder note');
|
||||
item.setTitle(t('menuCreateMarkdownFolderNote'));
|
||||
item.setIcon('edit');
|
||||
item.onClick(() => {
|
||||
createFolderNote(this.plugin, file.path, true, '.md');
|
||||
|
|
@ -484,7 +485,7 @@ export class Commands {
|
|||
this.plugin.settings.supportedFileTypes.forEach((fileType) => {
|
||||
if (fileType === 'md') return;
|
||||
folderMenu.addItem((item) => {
|
||||
item.setTitle(`Create ${fileType} folder note`);
|
||||
item.setTitle(t('menuCreateFileTypeFolderNote', { fileType }));
|
||||
item.setIcon('edit');
|
||||
item.onClick(() => {
|
||||
createFolderNote(this.plugin, file.path, true, '.' + fileType);
|
||||
|
|
@ -500,7 +501,7 @@ export class Commands {
|
|||
this.plugin.settings.useSubmenus
|
||||
) {
|
||||
menu.addItem(async (item) => {
|
||||
item.setTitle('Folder Note Commands').setIcon('folder-edit');
|
||||
item.setTitle(t('menuFolderNoteCommands')).setIcon('folder-edit');
|
||||
let subMenu: Menu = item.setSubmenu() as Menu;
|
||||
addFolderNoteActions(subMenu);
|
||||
});
|
||||
|
|
@ -516,7 +517,7 @@ export class Commands {
|
|||
const text = editor.getSelection().trim();
|
||||
if (!text || text.trim() === '') return;
|
||||
menu.addItem((item) => {
|
||||
item.setTitle('Create folder note')
|
||||
item.setTitle(t('menuCreateFolderNote'))
|
||||
.setIcon('edit')
|
||||
.onClick(() => {
|
||||
const { file } = view;
|
||||
|
|
@ -525,12 +526,12 @@ export class Commands {
|
|||
for (const char of blacklist) {
|
||||
if (text.includes(char)) {
|
||||
// eslint-disable-next-line max-len
|
||||
new Notice('File name cannot contain any of the following characters: * " \\ / < > : | ?');
|
||||
new Notice(t('noticeInvalidFileName'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (text.endsWith('.')) {
|
||||
new Notice('File name cannot end with a dot');
|
||||
new Notice(t('noticeFileNameEndDot'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -541,7 +542,7 @@ export class Commands {
|
|||
if (folderPath === '') {
|
||||
folder = this.plugin.app.vault.getAbstractFileByPath(text);
|
||||
if (folder instanceof TFolder) {
|
||||
return new Notice('Folder note already exists');
|
||||
return new Notice(t('noticeFolderNoteAlreadyExists'));
|
||||
}
|
||||
this.plugin.app.vault.createFolder(text);
|
||||
createFolderNote(this.plugin, text, false);
|
||||
|
|
@ -551,7 +552,7 @@ export class Commands {
|
|||
folderPath + '/' + text,
|
||||
);
|
||||
if (folder instanceof TFolder) {
|
||||
return new Notice('Folder note already exists');
|
||||
return new Notice(t('noticeFolderNoteAlreadyExists'));
|
||||
}
|
||||
if (this.plugin.settings.storageLocation === 'parentFolder') {
|
||||
if (
|
||||
|
|
@ -562,7 +563,7 @@ export class Commands {
|
|||
this.plugin.settings.folderNoteType,
|
||||
)
|
||||
) {
|
||||
return new Notice('File already exists');
|
||||
return new Notice(t('noticeFileAlreadyExists'));
|
||||
}
|
||||
}
|
||||
this.plugin.app.vault.createFolder(folderPath + '/' + text);
|
||||
|
|
|
|||
211
src/i18n/en.ts
Normal file
211
src/i18n/en.ts
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
export const en = {
|
||||
// Tab names
|
||||
tabGeneral: 'General',
|
||||
tabFolderOverview: 'Folder overview',
|
||||
tabExcludeFolders: 'Exclude folders',
|
||||
tabFileExplorer: 'File explorer',
|
||||
tabPath: 'Path',
|
||||
|
||||
// Common
|
||||
requiresRestart: 'Requires a restart to take effect',
|
||||
styleSettings: 'Style settings',
|
||||
manage: 'Manage',
|
||||
|
||||
// Language selector
|
||||
language: 'Language',
|
||||
languageDesc: 'Select the language for the plugin interface',
|
||||
langEnglish: 'English',
|
||||
langChinese: '中文',
|
||||
|
||||
// GeneralSettings
|
||||
folderNoteNameTemplate: 'Folder note name template',
|
||||
folderNoteNameTemplateDesc: 'All folder notes will use this name. Use {{folder_name}} to insert the folder\'s name. Existing notes won\'t update automatically; click on the button to apply the new name.',
|
||||
renameExistingFolderNotes: 'Rename existing folder notes',
|
||||
renameAllExistingFolderNotes: 'Rename all existing folder notes',
|
||||
renameConfirmMsg: 'When you click on "Confirm" all existing folder notes will be renamed to the new folder note name.',
|
||||
displayFolderNameInTabTitle: 'Display Folder Name in Tab Title',
|
||||
displayFolderNameInTabTitleDesc: 'Use the actual folder name in the tab title instead of the custom folder note name (e.g., "Folder Note").',
|
||||
defaultFileType: 'Default file type for new folder notes',
|
||||
defaultFileTypeDesc: 'Choose the default file type (canvas, markdown, ...) used when creating new folder notes.',
|
||||
askForFileType: 'ask for file type',
|
||||
markdown: 'markdown',
|
||||
supportedFileTypes: 'Supported file types',
|
||||
supportedFileTypesDesc: 'Specify which file types are allowed as folder notes. Applies to both new and existing folders. Adding many types may affect performance.',
|
||||
addCustomFileType: 'Add custom file type',
|
||||
customExtension: 'Custom extension',
|
||||
templatePath: 'Template path',
|
||||
templatePathDesc: 'Can be used with templater/templates plugin. If you add the location of the templates there.',
|
||||
templatePathPlaceholder: 'Template path',
|
||||
storageLocation: 'Storage location',
|
||||
storageLocationDesc: 'Choose where to store the folder notes',
|
||||
insideFolder: 'Inside the folder',
|
||||
inParentFolder: 'In the parent folder',
|
||||
switchButton: 'Switch',
|
||||
switchStorageLocationTitle: 'Switch storage location',
|
||||
switchStorageLocationMsg: 'When you click on "Confirm" all folder notes will be moved to the new storage location.',
|
||||
deleteFolderNotesOnFolderDelete: 'Delete folder notes when deleting the folder',
|
||||
deleteFolderNotesOnFolderDeleteDesc: 'Delete the folder note when deleting the folder',
|
||||
moveFolderNotesOnFolderMove: 'Move folder notes when moving the folder',
|
||||
moveFolderNotesOnFolderMoveDesc: 'Move the folder note file along with the folder when it is moved',
|
||||
keyboardShortcuts: 'Keyboard Shortcuts',
|
||||
keyForCreatingFolderNote: 'Key for creating folder note',
|
||||
keyForCreatingFolderNoteDesc: 'The key combination to create a folder note',
|
||||
ctrlClick: 'Ctrl + Click',
|
||||
altClick: 'Alt + Click',
|
||||
cmdClick: 'Cmd + Click',
|
||||
optionClick: 'Option + Click',
|
||||
keyForOpeningFolderNote: 'Key for opening folder note',
|
||||
keyForOpeningFolderNoteDesc: 'Select the combination to open a folder note',
|
||||
mouseClick: 'Mouse Click',
|
||||
folderNoteBehavior: 'Folder note behavior',
|
||||
confirmFolderNoteDeletion: 'Confirm folder note deletion',
|
||||
confirmFolderNoteDeletionDesc: 'Ask for confirmation before deleting a folder note',
|
||||
deletedFolderNotes: 'Deleted folder notes',
|
||||
deletedFolderNotesDesc: 'What happens to the folder note after you delete it',
|
||||
moveToSystemTrash: 'Move to system trash',
|
||||
moveToObsidianTrash: 'Move to Obsidian trash (.trash folder)',
|
||||
deletePermanently: 'Delete permanently',
|
||||
openInNewTab: 'Open folder note in a new tab by default',
|
||||
openInNewTabDesc: 'Always open folder notes in a new tab unless the note is already open in the current tab.',
|
||||
focusExistingTab: 'Focus existing tab instead of creating a new one',
|
||||
focusExistingTabDesc: 'If a folder note is already open in a tab, focus that tab instead of creating a new one.',
|
||||
syncFolderName: 'Sync folder name',
|
||||
syncFolderNameDesc: 'Automatically rename the folder note when the folder name is changed',
|
||||
automationSettings: 'Automation settings',
|
||||
createFolderNotesForAllFolders: 'Create folder notes for all folders',
|
||||
createFolderNotesForAllFoldersDesc: 'Generate folder notes for every folder in the vault.',
|
||||
autoCreateOnFolderCreation: 'Auto-create on folder creation',
|
||||
autoCreateOnFolderCreationDesc: 'Automatically create a folder note whenever a new folder is added.',
|
||||
autoOpenAfterCreation: 'Auto-open after creation',
|
||||
autoOpenAfterCreationDesc: 'Open the folder note immediately after it\'s created automatically.',
|
||||
autoCreateForAttachmentFolders: 'Auto-create for attachment folders',
|
||||
autoCreateForAttachmentFoldersDesc: 'Also automatically create folder notes for attachment folders (e.g., "Attachments", "Media", etc.).',
|
||||
autoCreateWhenCreatingNotes: 'Auto-create when creating notes',
|
||||
autoCreateWhenCreatingNotesDesc: 'Automatically create a folder note when a regular note is created inside a folder. Works for supported file types only.',
|
||||
integrationCompatibility: 'Integration & Compatibility',
|
||||
enableFmtpIntegration: 'Enable front matter title plugin integration',
|
||||
enableFmtpIntegrationDesc: 'Allows you to use the {link} with folder notes. It allows you to set the folder name to some name you set in the front matter.',
|
||||
frontMatterTitlePlugin: 'front matter title plugin',
|
||||
sessionPersistence: 'Session & Persistence',
|
||||
persistTabAfterRestart: 'Persist tab after restart',
|
||||
persistTabAfterRestartDesc: 'Restore the same settings tab after restarting Obsidian.',
|
||||
persistTabDuringSession: 'Persist tab during session only',
|
||||
persistTabDuringSessionDesc: 'Keep the current settings tab open during the session, but reset it after a restart or reload.',
|
||||
|
||||
// FileExplorerSettings
|
||||
hideFolderNote: 'Hide folder note',
|
||||
hideFolderNoteDesc: 'Hide the folder note file from appearing in the file explorer',
|
||||
disableClickToOpenOnMobile: 'Disable click-to-open folder note on mobile',
|
||||
disableClickToOpenOnMobileDesc: 'Prevents folder notes from opening when tapping the folder name or surrounding area on mobile devices. They can now only be opened via the context menu or a command.',
|
||||
openByClickingFolderNameOnly: 'Open folder notes by only clicking directly on the folder name',
|
||||
openByClickingFolderNameOnlyDesc: 'Only allow folder notes to open when clicking directly on the folder name in the file explorer',
|
||||
disableFolderCollapsing: 'Disable folder collapsing',
|
||||
disableFolderCollapsingDesc: 'When enabled, folders in the file explorer will only collapse when clicking the collapse icon next to the folder name, not when clicking near a folder name when it has a folder note.',
|
||||
useSubmenus: 'Use submenus',
|
||||
useSubmenusDesc: 'Use submenus for file/folder commands',
|
||||
autoUpdateFolderNameInExplorer: 'Auto update folder name in the file explorer (front matter title plugin only)',
|
||||
autoUpdateFolderNameInExplorerDesc: 'Automatically update the folder name in the file explorer when the front matter title plugin is enabled and the title for a folder note is changed in the front matter. This will not change the file name, only the displayed name in the file explorer.',
|
||||
highlightFolder: 'Highlight folder in the file explorer',
|
||||
highlightFolderDesc: 'Highlight the folder in the file explorer when it has a folder note and the folder note is open in the editor',
|
||||
hideCollapseIcon: 'Hide collapse icon',
|
||||
hideCollapseIconDesc: 'Hide the collapse icon in the file explorer next to the name of a folder when a folder only contains a folder note',
|
||||
hideCollapseIconForEmptyFolders: 'Hide collapse icon for every empty folder',
|
||||
hideCollapseIconForEmptyFoldersDesc: 'Hide the collapse icon in the file explorer next to the name of a folder when a folder is empty',
|
||||
hideCollapseIconForAttachmentFolder: 'Hide collapse icon also when only the attachment folder is in the same folder',
|
||||
underlineFolderNote: 'Underline the name of folder notes',
|
||||
underlineFolderNoteDesc: 'Add an underline to folders that have a folder note in the file explorer',
|
||||
boldFolderNote: 'Bold the name of folder notes',
|
||||
boldFolderNoteDesc: 'Make the folder name bold in the file explorer when it has a folder note',
|
||||
cursiveFolderNote: 'Cursive the name of folder notes',
|
||||
cursiveFolderNoteDesc: 'Make the folder name cursive in the file explorer when it has a folder note',
|
||||
|
||||
// PathSettings
|
||||
openFolderNoteThroughPath: 'Open folder note through path',
|
||||
openFolderNoteThroughPathDesc: 'Open a folder note when clicking on a folder name in the path if it is a folder note',
|
||||
openSidebarMobile: 'Open sidebar when opening a folder note through path (Mobile only)',
|
||||
openSidebarMobileDesc: 'Open the sidebar when opening a folder note through the path on mobile',
|
||||
openSidebarDesktop: 'Open sidebar when opening a folder note through path (Desktop only)',
|
||||
openSidebarDesktopDesc: 'Open the sidebar when opening a folder note through the path on desktop',
|
||||
autoUpdateFolderNameInPath: 'Auto update folder name in the path (front matter title plugin only)',
|
||||
autoUpdateFolderNameInPathDesc: 'Automatically update the folder name in the path when the front matter title plugin is enabled and the title for a folder note is changed in the front matter. This will not change the file name, only the displayed name in the path.',
|
||||
underlineFoldersInPath: 'Underline folders in the path',
|
||||
underlineFoldersInPathDesc: 'Add an underline to folders that have a folder note in the path above a note',
|
||||
boldFoldersInPath: 'Bold folders in the path',
|
||||
boldFoldersInPathDesc: 'Make the folder name bold in the path above a note when it has a folder note',
|
||||
cursiveFoldersInPath: 'Cursive the name of folder notes in the path',
|
||||
cursiveFoldersInPathDesc: 'Make the folder name cursive in the path above a note when it has a folder note',
|
||||
hideFolderNoteNameInPath: 'Hide folder note name in the path',
|
||||
hideFolderNoteNameInPathDesc: 'Only show the folder name in the path and hide the folder note name.',
|
||||
|
||||
// ExcludedFoldersSettings
|
||||
manageExcludedFolders: 'Manage excluded folders',
|
||||
manageExcludedFoldersDesc1: 'Add {regex} at the beginning of the folder name to use a regex pattern.',
|
||||
manageExcludedFoldersDesc2: 'Use * before and after to exclude folders that include the name between the *s.',
|
||||
manageExcludedFoldersDesc3: 'Use * before the folder name to exclude folders that end with the folder name.',
|
||||
manageExcludedFoldersDesc4: 'Use * after the folder name to exclude folders that start with the folder name.',
|
||||
excludedFoldersInfo1: 'The regexes and wildcards are only for the folder name, not the path.',
|
||||
excludedFoldersInfo2: 'If you want to switch to a folder path delete the pattern first.',
|
||||
whitelistedFolders: 'Whitelisted folders',
|
||||
whitelistedFoldersDesc: 'Folders that override the excluded folders/patterns',
|
||||
excludeFolderDefaultSettings: 'Exclude folder default settings',
|
||||
excludePatternDefaultSettings: 'Exclude pattern default settings',
|
||||
addExcludedFolder: 'Add excluded folder',
|
||||
|
||||
// FolderOverviewSettings
|
||||
globalSettings: 'Global settings',
|
||||
autoUpdateLinks: 'Auto-update links without opening the overview',
|
||||
autoUpdateLinksDesc: 'If enabled, the links that appear in the graph view will be updated even when you don\'t have the overview open somewhere.',
|
||||
overviewDefaultSettings: 'Overviews default settings',
|
||||
overviewDefaultSettingsDesc: 'Edit the default settings for new folder overviews, ',
|
||||
overviewDefaultSettingsSpan: 'this won\'t apply to already existing overviews.',
|
||||
|
||||
// SettingsTab notices
|
||||
startingUpdateFolderNotes: 'Starting to update folder notes...',
|
||||
finishedUpdatingFolderNotes: 'Finished updating folder notes',
|
||||
startingSwitchStorageLocation: 'Starting to switch storage location...',
|
||||
finishedSwitchingStorageLocation: 'Finished switching storage location',
|
||||
|
||||
// Commands
|
||||
cmdUseFolderNote: 'Use this file as the folder note for its parent folder',
|
||||
cmdMakeFolderWithNote: 'Make a folder with this file as its folder note',
|
||||
cmdCreateMarkdownFolderNote: 'Create markdown folder note for this folder',
|
||||
cmdCreateFileTypeFolderNote: 'Create {fileType} folder note for this folder',
|
||||
cmdCreateFileTypeFolderNoteForActive: 'Create {type} folder note for current active folder in file explorer',
|
||||
cmdDeleteFolderNote: 'Delete this folder\'s linked note',
|
||||
cmdDeleteFolderNoteActive: 'Delete folder note of current active folder in file explorer',
|
||||
cmdOpenFolderNote: 'Open this folder\'s linked note',
|
||||
cmdOpenFolderNoteActive: 'Open folder note of current active folder in file explorer',
|
||||
cmdCreateFolderNoteFromSelection: 'Create folder note from selection',
|
||||
noticeFolderAlreadyExists: 'Folder already exists',
|
||||
noticeInvalidFileName: 'File name cannot contain any of the following characters: * " \\ / < > : | ?',
|
||||
noticeFileNameEndDot: 'File name cannot end with a dot',
|
||||
noticeFolderNoteAlreadyExists: 'Folder note already exists',
|
||||
noticeFileAlreadyExists: 'File already exists',
|
||||
menuCreateFolderNote: 'Create folder note',
|
||||
menuTurnIntoFolderNote: 'Turn into folder note for {folderName}',
|
||||
menuRemoveFromExcluded: 'Remove folder from excluded folders',
|
||||
noticeRemovedFromExcluded: 'Successfully removed folder from excluded folders',
|
||||
menuRemoveFromDetached: 'Remove folder from detached folders',
|
||||
menuExcludeFromFolderNotes: 'Exclude folder from folder notes',
|
||||
noticeExcluded: 'Successfully excluded folder from folder notes',
|
||||
menuDeleteFolderNote: 'Delete folder note',
|
||||
menuOpenFolderNote: 'Open folder note',
|
||||
menuDetachFolderNote: 'Detach folder note',
|
||||
menuCopyObsidianUrl: 'Copy Obsidian URL',
|
||||
menuHideFolderNoteInExplorer: 'Hide folder note in explorer',
|
||||
menuShowFolderNoteInExplorer: 'Show folder note in explorer',
|
||||
menuCreateMarkdownFolderNote: 'Create markdown folder note',
|
||||
menuCreateFileTypeFolderNote: 'Create {fileType} folder note',
|
||||
menuFolderNoteCommands: 'Folder Note Commands',
|
||||
|
||||
// DeleteConfirmation modal
|
||||
deleteFolderNoteTitle: 'Delete folder note',
|
||||
deleteConfirmMsg: 'Are you sure you want to delete the folder note \'{fileName}\' ?',
|
||||
willMoveToSystemTrash: 'It will be moved to your system trash.',
|
||||
willMoveToObsidianTrash: 'It will be moved to your Obsidian trash, which is located in the ".trash" hidden folder in your vault.',
|
||||
willBeDeleted: 'It will be permanently deleted.',
|
||||
dontAskAgain: 'Don\'t ask again',
|
||||
deleteAndDontAsk: 'Delete and don\'t ask again',
|
||||
delete: 'Delete',
|
||||
cancel: 'Cancel',
|
||||
} as const;
|
||||
28
src/i18n/index.ts
Normal file
28
src/i18n/index.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { en } from './en';
|
||||
import { zh } from './zh';
|
||||
|
||||
export type TranslationKey = keyof typeof en;
|
||||
|
||||
type Translations = { [K in TranslationKey]: string };
|
||||
|
||||
const translations: Record<string, Translations> = {
|
||||
en: en as Translations,
|
||||
zh: zh as Translations,
|
||||
};
|
||||
|
||||
let currentLang = 'en';
|
||||
|
||||
export function setLanguage(lang: string): void {
|
||||
currentLang = lang;
|
||||
}
|
||||
|
||||
export function t(key: TranslationKey, vars?: Record<string, string>): string {
|
||||
const langMap = translations[currentLang] ?? translations['en'];
|
||||
let str: string = langMap[key] ?? (translations['en'][key] as string) ?? key;
|
||||
if (vars) {
|
||||
for (const [k, v] of Object.entries(vars)) {
|
||||
str = str.replace(`{${k}}`, v);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
211
src/i18n/zh.ts
Normal file
211
src/i18n/zh.ts
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
export const zh = {
|
||||
// Tab names
|
||||
tabGeneral: '常规',
|
||||
tabFolderOverview: '文件夹概览',
|
||||
tabExcludeFolders: '排除文件夹',
|
||||
tabFileExplorer: '文件资源管理器',
|
||||
tabPath: '路径',
|
||||
|
||||
// Common
|
||||
requiresRestart: '需要重启才能生效',
|
||||
styleSettings: '样式设置',
|
||||
manage: '管理',
|
||||
|
||||
// Language selector
|
||||
language: '语言',
|
||||
languageDesc: '选择插件界面语言',
|
||||
langEnglish: 'English',
|
||||
langChinese: '中文',
|
||||
|
||||
// GeneralSettings
|
||||
folderNoteNameTemplate: '文件夹笔记名称模板',
|
||||
folderNoteNameTemplateDesc: '所有文件夹笔记将使用此名称。使用 {{folder_name}} 插入文件夹名称。现有笔记不会自动更新,请点击按钮应用新名称。',
|
||||
renameExistingFolderNotes: '重命名现有文件夹笔记',
|
||||
renameAllExistingFolderNotes: '重命名所有现有文件夹笔记',
|
||||
renameConfirmMsg: '点击"确认"后,所有现有文件夹笔记将被重命名为新的文件夹笔记名称。',
|
||||
displayFolderNameInTabTitle: '在标签页标题中显示文件夹名称',
|
||||
displayFolderNameInTabTitleDesc: '在标签页标题中使用实际文件夹名称,而非自定义文件夹笔记名称(如"Folder Note")。',
|
||||
defaultFileType: '新文件夹笔记的默认文件类型',
|
||||
defaultFileTypeDesc: '选择创建新文件夹笔记时使用的默认文件类型(Canvas、Markdown 等)。',
|
||||
askForFileType: '每次询问文件类型',
|
||||
markdown: 'Markdown',
|
||||
supportedFileTypes: '支持的文件类型',
|
||||
supportedFileTypesDesc: '指定允许作为文件夹笔记的文件类型。适用于新建和现有文件夹。添加过多类型可能影响性能。',
|
||||
addCustomFileType: '添加自定义文件类型',
|
||||
customExtension: '自定义扩展名',
|
||||
templatePath: '模板路径',
|
||||
templatePathDesc: '可与 Templater/Templates 插件配合使用。在此处添加模板的位置。',
|
||||
templatePathPlaceholder: '模板路径',
|
||||
storageLocation: '存储位置',
|
||||
storageLocationDesc: '选择文件夹笔记的存储位置',
|
||||
insideFolder: '文件夹内部',
|
||||
inParentFolder: '父文件夹中',
|
||||
switchButton: '切换',
|
||||
switchStorageLocationTitle: '切换存储位置',
|
||||
switchStorageLocationMsg: '点击"确认"后,所有文件夹笔记将被移动到新的存储位置。',
|
||||
deleteFolderNotesOnFolderDelete: '删除文件夹时同步删除文件夹笔记',
|
||||
deleteFolderNotesOnFolderDeleteDesc: '删除文件夹时同时删除对应的文件夹笔记',
|
||||
moveFolderNotesOnFolderMove: '移动文件夹时同步移动文件夹笔记',
|
||||
moveFolderNotesOnFolderMoveDesc: '移动文件夹时同时移动对应的文件夹笔记文件',
|
||||
keyboardShortcuts: '键盘快捷键',
|
||||
keyForCreatingFolderNote: '创建文件夹笔记的快捷键',
|
||||
keyForCreatingFolderNoteDesc: '创建文件夹笔记的按键组合',
|
||||
ctrlClick: 'Ctrl + 单击',
|
||||
altClick: 'Alt + 单击',
|
||||
cmdClick: 'Cmd + 单击',
|
||||
optionClick: 'Option + 单击',
|
||||
keyForOpeningFolderNote: '打开文件夹笔记的快捷键',
|
||||
keyForOpeningFolderNoteDesc: '选择打开文件夹笔记的按键组合',
|
||||
mouseClick: '鼠标单击',
|
||||
folderNoteBehavior: '文件夹笔记行为',
|
||||
confirmFolderNoteDeletion: '确认文件夹笔记删除',
|
||||
confirmFolderNoteDeletionDesc: '删除文件夹笔记前询问确认',
|
||||
deletedFolderNotes: '已删除的文件夹笔记',
|
||||
deletedFolderNotesDesc: '删除文件夹笔记后的处理方式',
|
||||
moveToSystemTrash: '移至系统回收站',
|
||||
moveToObsidianTrash: '移至 Obsidian 回收站(.trash 文件夹)',
|
||||
deletePermanently: '永久删除',
|
||||
openInNewTab: '默认在新标签页中打开文件夹笔记',
|
||||
openInNewTabDesc: '始终在新标签页中打开文件夹笔记,除非该笔记已在当前标签页中打开。',
|
||||
focusExistingTab: '聚焦已有标签页而非创建新标签页',
|
||||
focusExistingTabDesc: '如果文件夹笔记已在某个标签页中打开,则聚焦该标签页而非创建新标签页。',
|
||||
syncFolderName: '同步文件夹名称',
|
||||
syncFolderNameDesc: '文件夹名称更改时自动重命名文件夹笔记',
|
||||
automationSettings: '自动化设置',
|
||||
createFolderNotesForAllFolders: '为所有文件夹创建文件夹笔记',
|
||||
createFolderNotesForAllFoldersDesc: '为仓库中的每个文件夹生成文件夹笔记。',
|
||||
autoCreateOnFolderCreation: '创建文件夹时自动创建笔记',
|
||||
autoCreateOnFolderCreationDesc: '每次添加新文件夹时自动创建文件夹笔记。',
|
||||
autoOpenAfterCreation: '创建后自动打开',
|
||||
autoOpenAfterCreationDesc: '自动创建文件夹笔记后立即打开该笔记。',
|
||||
autoCreateForAttachmentFolders: '为附件文件夹自动创建',
|
||||
autoCreateForAttachmentFoldersDesc: '同时为附件文件夹(如"Attachments"、"Media"等)自动创建文件夹笔记。',
|
||||
autoCreateWhenCreatingNotes: '创建笔记时自动创建文件夹笔记',
|
||||
autoCreateWhenCreatingNotesDesc: '在文件夹内创建普通笔记时自动创建文件夹笔记。仅适用于支持的文件类型。',
|
||||
integrationCompatibility: '集成与兼容',
|
||||
enableFmtpIntegration: '启用 Front Matter Title 插件集成',
|
||||
enableFmtpIntegrationDesc: '允许将 {link} 与文件夹笔记配合使用,可将文件夹名称设置为 Front Matter 中指定的名称。',
|
||||
frontMatterTitlePlugin: 'Front Matter Title 插件',
|
||||
sessionPersistence: '会话与持久化',
|
||||
persistTabAfterRestart: '重启后保留标签页',
|
||||
persistTabAfterRestartDesc: '重启 Obsidian 后恢复到相同的设置标签页。',
|
||||
persistTabDuringSession: '仅在会话期间保留标签页',
|
||||
persistTabDuringSessionDesc: '在会话期间保持当前设置标签页打开,但重启或重新加载后重置。',
|
||||
|
||||
// FileExplorerSettings
|
||||
hideFolderNote: '隐藏文件夹笔记',
|
||||
hideFolderNoteDesc: '在文件资源管理器中隐藏文件夹笔记文件',
|
||||
disableClickToOpenOnMobile: '在移动端禁用点击打开文件夹笔记',
|
||||
disableClickToOpenOnMobileDesc: '防止在移动设备上通过点击文件夹名称或周围区域打开文件夹笔记。只能通过右键菜单或命令打开。',
|
||||
openByClickingFolderNameOnly: '仅通过直接点击文件夹名称打开文件夹笔记',
|
||||
openByClickingFolderNameOnlyDesc: '只允许在文件资源管理器中直接点击文件夹名称时打开文件夹笔记',
|
||||
disableFolderCollapsing: '禁用文件夹折叠',
|
||||
disableFolderCollapsingDesc: '启用后,文件资源管理器中的文件夹只有点击折叠图标时才会折叠,而不是在有文件夹笔记的情况下点击文件夹名称附近。',
|
||||
useSubmenus: '使用子菜单',
|
||||
useSubmenusDesc: '为文件/文件夹命令使用子菜单',
|
||||
autoUpdateFolderNameInExplorer: '自动更新文件资源管理器中的文件夹名称(仅限 Front Matter Title 插件)',
|
||||
autoUpdateFolderNameInExplorerDesc: '启用 Front Matter Title 插件后,当 Front Matter 中的文件夹笔记标题更改时,自动更新文件资源管理器中的文件夹名称。这不会更改文件名,只更改资源管理器中显示的名称。',
|
||||
highlightFolder: '在文件资源管理器中高亮显示文件夹',
|
||||
highlightFolderDesc: '当文件夹有文件夹笔记且该笔记在编辑器中打开时,在文件资源管理器中高亮显示该文件夹',
|
||||
hideCollapseIcon: '隐藏折叠图标',
|
||||
hideCollapseIconDesc: '当文件夹只包含文件夹笔记时,隐藏文件资源管理器中文件夹名称旁边的折叠图标',
|
||||
hideCollapseIconForEmptyFolders: '为每个空文件夹隐藏折叠图标',
|
||||
hideCollapseIconForEmptyFoldersDesc: '当文件夹为空时,隐藏文件资源管理器中文件夹名称旁边的折叠图标',
|
||||
hideCollapseIconForAttachmentFolder: '当同文件夹中只有附件文件夹时也隐藏折叠图标',
|
||||
underlineFolderNote: '为文件夹笔记名称添加下划线',
|
||||
underlineFolderNoteDesc: '在文件资源管理器中为有文件夹笔记的文件夹添加下划线',
|
||||
boldFolderNote: '加粗文件夹笔记名称',
|
||||
boldFolderNoteDesc: '在文件资源管理器中有文件夹笔记时将文件夹名称加粗显示',
|
||||
cursiveFolderNote: '斜体显示文件夹笔记名称',
|
||||
cursiveFolderNoteDesc: '在文件资源管理器中有文件夹笔记时将文件夹名称斜体显示',
|
||||
|
||||
// PathSettings
|
||||
openFolderNoteThroughPath: '通过路径打开文件夹笔记',
|
||||
openFolderNoteThroughPathDesc: '点击路径中的文件夹名称时,如果它是文件夹笔记则打开该笔记',
|
||||
openSidebarMobile: '通过路径打开文件夹笔记时打开侧边栏(仅限移动端)',
|
||||
openSidebarMobileDesc: '在移动端通过路径打开文件夹笔记时打开侧边栏',
|
||||
openSidebarDesktop: '通过路径打开文件夹笔记时打开侧边栏(仅限桌面端)',
|
||||
openSidebarDesktopDesc: '在桌面端通过路径打开文件夹笔记时打开侧边栏',
|
||||
autoUpdateFolderNameInPath: '自动更新路径中的文件夹名称(仅限 Front Matter Title 插件)',
|
||||
autoUpdateFolderNameInPathDesc: '启用 Front Matter Title 插件后,当 Front Matter 中的文件夹笔记标题更改时,自动更新路径中的文件夹名称。这不会更改文件名,只更改路径中显示的名称。',
|
||||
underlineFoldersInPath: '为路径中的文件夹添加下划线',
|
||||
underlineFoldersInPathDesc: '为笔记上方路径中有文件夹笔记的文件夹添加下划线',
|
||||
boldFoldersInPath: '加粗路径中的文件夹',
|
||||
boldFoldersInPathDesc: '笔记上方路径中有文件夹笔记时将文件夹名称加粗显示',
|
||||
cursiveFoldersInPath: '斜体显示路径中的文件夹笔记名称',
|
||||
cursiveFoldersInPathDesc: '笔记上方路径中有文件夹笔记时将文件夹名称斜体显示',
|
||||
hideFolderNoteNameInPath: '在路径中隐藏文件夹笔记名称',
|
||||
hideFolderNoteNameInPathDesc: '仅在路径中显示文件夹名称,隐藏文件夹笔记名称。',
|
||||
|
||||
// ExcludedFoldersSettings
|
||||
manageExcludedFolders: '管理排除的文件夹',
|
||||
manageExcludedFoldersDesc1: '在文件夹名称开头添加 {regex} 以使用正则表达式模式。',
|
||||
manageExcludedFoldersDesc2: '在名称前后使用 * 排除包含 * 之间名称的文件夹。',
|
||||
manageExcludedFoldersDesc3: '在文件夹名称前使用 * 排除以该名称结尾的文件夹。',
|
||||
manageExcludedFoldersDesc4: '在文件夹名称后使用 * 排除以该名称开头的文件夹。',
|
||||
excludedFoldersInfo1: '正则表达式和通配符仅适用于文件夹名称,不适用于路径。',
|
||||
excludedFoldersInfo2: '如需切换到文件夹路径,请先删除该模式。',
|
||||
whitelistedFolders: '白名单文件夹',
|
||||
whitelistedFoldersDesc: '可覆盖排除文件夹/模式的文件夹',
|
||||
excludeFolderDefaultSettings: '排除文件夹默认设置',
|
||||
excludePatternDefaultSettings: '排除模式默认设置',
|
||||
addExcludedFolder: '添加排除文件夹',
|
||||
|
||||
// FolderOverviewSettings
|
||||
globalSettings: '全局设置',
|
||||
autoUpdateLinks: '不打开概览也自动更新链接',
|
||||
autoUpdateLinksDesc: '启用后,即使没有在任何地方打开概览,图谱视图中显示的链接也会自动更新。',
|
||||
overviewDefaultSettings: '概览默认设置',
|
||||
overviewDefaultSettingsDesc: '编辑新文件夹概览的默认设置,',
|
||||
overviewDefaultSettingsSpan: '这不会应用到已有的概览。',
|
||||
|
||||
// SettingsTab notices
|
||||
startingUpdateFolderNotes: '开始更新文件夹笔记...',
|
||||
finishedUpdatingFolderNotes: '文件夹笔记更新完成',
|
||||
startingSwitchStorageLocation: '开始切换存储位置...',
|
||||
finishedSwitchingStorageLocation: '存储位置切换完成',
|
||||
|
||||
// Commands
|
||||
cmdUseFolderNote: '将此文件用作父文件夹的文件夹笔记',
|
||||
cmdMakeFolderWithNote: '以此文件为笔记创建文件夹',
|
||||
cmdCreateMarkdownFolderNote: '为此文件夹创建 Markdown 文件夹笔记',
|
||||
cmdCreateFileTypeFolderNote: '为此文件夹创建 {fileType} 文件夹笔记',
|
||||
cmdCreateFileTypeFolderNoteForActive: '为文件资源管理器中当前活动文件夹创建 {type} 文件夹笔记',
|
||||
cmdDeleteFolderNote: '删除此文件夹的关联笔记',
|
||||
cmdDeleteFolderNoteActive: '删除文件资源管理器中当前活动文件夹的文件夹笔记',
|
||||
cmdOpenFolderNote: '打开此文件夹的关联笔记',
|
||||
cmdOpenFolderNoteActive: '打开文件资源管理器中当前活动文件夹的文件夹笔记',
|
||||
cmdCreateFolderNoteFromSelection: '从选中文字创建文件夹笔记',
|
||||
noticeFolderAlreadyExists: '文件夹已存在',
|
||||
noticeInvalidFileName: '文件名不能包含以下字符:* " \\ / < > : | ?',
|
||||
noticeFileNameEndDot: '文件名不能以点结尾',
|
||||
noticeFolderNoteAlreadyExists: '文件夹笔记已存在',
|
||||
noticeFileAlreadyExists: '文件已存在',
|
||||
menuCreateFolderNote: '创建文件夹笔记',
|
||||
menuTurnIntoFolderNote: '设为 {folderName} 的文件夹笔记',
|
||||
menuRemoveFromExcluded: '从排除文件夹中移除',
|
||||
noticeRemovedFromExcluded: '已成功从排除文件夹中移除',
|
||||
menuRemoveFromDetached: '从分离文件夹中移除',
|
||||
menuExcludeFromFolderNotes: '将文件夹排除出文件夹笔记',
|
||||
noticeExcluded: '已成功将文件夹排除出文件夹笔记',
|
||||
menuDeleteFolderNote: '删除文件夹笔记',
|
||||
menuOpenFolderNote: '打开文件夹笔记',
|
||||
menuDetachFolderNote: '分离文件夹笔记',
|
||||
menuCopyObsidianUrl: '复制 Obsidian URL',
|
||||
menuHideFolderNoteInExplorer: '在资源管理器中隐藏文件夹笔记',
|
||||
menuShowFolderNoteInExplorer: '在资源管理器中显示文件夹笔记',
|
||||
menuCreateMarkdownFolderNote: '创建 Markdown 文件夹笔记',
|
||||
menuCreateFileTypeFolderNote: '创建 {fileType} 文件夹笔记',
|
||||
menuFolderNoteCommands: '文件夹笔记命令',
|
||||
|
||||
// DeleteConfirmation modal
|
||||
deleteFolderNoteTitle: '删除文件夹笔记',
|
||||
deleteConfirmMsg: '确定要删除文件夹笔记"{fileName}"吗?',
|
||||
willMoveToSystemTrash: '它将被移至系统回收站。',
|
||||
willMoveToObsidianTrash: '它将被移至 Obsidian 回收站(仓库中的".trash"隐藏文件夹)。',
|
||||
willBeDeleted: '它将被永久删除。',
|
||||
dontAskAgain: '不再询问',
|
||||
deleteAndDontAsk: '删除且不再询问',
|
||||
delete: '删除',
|
||||
cancel: '取消',
|
||||
} as const;
|
||||
|
|
@ -9,6 +9,7 @@ import {
|
|||
import {
|
||||
type FolderNotesSettings, DEFAULT_SETTINGS, SettingsTab,
|
||||
} from './settings/SettingsTab';
|
||||
import { setLanguage } from './i18n';
|
||||
import { Commands } from './Commands';
|
||||
import type { FileExplorerWorkspaceLeaf } from './globals';
|
||||
import {
|
||||
|
|
@ -53,6 +54,7 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
async onload(): Promise<void> {
|
||||
console.log('loading folder notes plugin');
|
||||
await this.loadSettings();
|
||||
setLanguage(this.settings.language ?? 'en');
|
||||
this.settingsTab = new SettingsTab(this.app, this);
|
||||
this.addSettingTab(this.settingsTab);
|
||||
this.saveSettings();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { Modal, Platform, type App, type TFile } from 'obsidian';
|
||||
import type FolderNotesPlugin from '../main';
|
||||
import { deleteFolderNote } from 'src/functions/folderNoteFunctions';
|
||||
import { t } from '../i18n';
|
||||
|
||||
export default class DeleteConfirmationModal extends Modal {
|
||||
plugin: FolderNotesPlugin;
|
||||
app: App;
|
||||
|
|
@ -15,20 +17,20 @@ export default class DeleteConfirmationModal extends Modal {
|
|||
const { contentEl, plugin } = this;
|
||||
const modalTitle = contentEl.createDiv({ cls: 'fn-modal-title' });
|
||||
const modalContent = contentEl.createDiv({ cls: 'fn-modal-content' });
|
||||
modalTitle.createEl('h2', { text: 'Delete folder note' });
|
||||
modalTitle.createEl('h2', { text: t('deleteFolderNoteTitle') });
|
||||
// eslint-disable-next-line max-len
|
||||
modalContent.createEl('p', { text: `Are you sure you want to delete the folder note '${this.file.name}' ?` });
|
||||
modalContent.createEl('p', { text: t('deleteConfirmMsg', { fileName: this.file.name }) });
|
||||
switch (plugin.settings.deleteFilesAction) {
|
||||
case 'trash':
|
||||
modalContent.createEl('p', { text: 'It will be moved to your system trash.' });
|
||||
modalContent.createEl('p', { text: t('willMoveToSystemTrash') });
|
||||
break;
|
||||
case 'obsidianTrash':
|
||||
// eslint-disable-next-line max-len
|
||||
modalContent.createEl('p', { text: 'It will be moved to your Obsidian trash, which is located in the ".trash" hidden folder in your vault.' });
|
||||
modalContent.createEl('p', { text: t('willMoveToObsidianTrash') });
|
||||
break;
|
||||
case 'delete':
|
||||
modalContent
|
||||
.createEl('p', { text: 'It will be permanently deleted.' })
|
||||
.createEl('p', { text: t('willBeDeleted') })
|
||||
.setCssStyles({ color: 'red' });
|
||||
break;
|
||||
}
|
||||
|
|
@ -39,7 +41,7 @@ export default class DeleteConfirmationModal extends Modal {
|
|||
const checkbox = buttonContainer.createEl('label', { cls: 'mod-checkbox' });
|
||||
checkbox.tabIndex = -1;
|
||||
const input = checkbox.createEl('input', { type: 'checkbox' });
|
||||
checkbox.appendText('Don\'t ask again');
|
||||
checkbox.appendText(t('dontAskAgain'));
|
||||
input.addEventListener('change', (e) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
if (target.checked) {
|
||||
|
|
@ -51,7 +53,7 @@ export default class DeleteConfirmationModal extends Modal {
|
|||
});
|
||||
} else {
|
||||
const confirmButton = buttonContainer.createEl('button', {
|
||||
text: 'Delete and don\'t ask again',
|
||||
text: t('deleteAndDontAsk'),
|
||||
cls: 'mod-destructive',
|
||||
});
|
||||
confirmButton.addEventListener('click', async () => {
|
||||
|
|
@ -63,7 +65,7 @@ export default class DeleteConfirmationModal extends Modal {
|
|||
}
|
||||
|
||||
const deleteButton = buttonContainer.createEl('button', {
|
||||
text: 'Delete',
|
||||
text: t('delete'),
|
||||
cls: 'mod-warning',
|
||||
});
|
||||
deleteButton.addEventListener('click', async () => {
|
||||
|
|
@ -73,7 +75,7 @@ export default class DeleteConfirmationModal extends Modal {
|
|||
deleteButton.focus();
|
||||
|
||||
const cancelButton = buttonContainer.createEl('button', {
|
||||
text: 'Cancel',
|
||||
text: t('cancel'),
|
||||
cls: 'mod-cancel',
|
||||
});
|
||||
cancelButton.addEventListener('click', async () => {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import type { SettingsTab } from './SettingsTab';
|
|||
import ExcludedFolderSettings from 'src/ExcludeFolders/modals/ExcludeFolderSettings';
|
||||
import PatternSettings from 'src/ExcludeFolders/modals/PatternSettings';
|
||||
import WhitelistedFoldersSettings from 'src/ExcludeFolders/modals/WhitelistedFoldersSettings';
|
||||
import { t } from '../i18n';
|
||||
// import ExcludedFoldersWhitelist from 'src/ExcludeFolders/modals/WhitelistModal';
|
||||
|
||||
export async function renderExcludeFolders(settingsTab: SettingsTab): Promise<void> {
|
||||
|
|
@ -16,32 +17,32 @@ export async function renderExcludeFolders(settingsTab: SettingsTab): Promise<vo
|
|||
const manageExcluded = new Setting(containerEl)
|
||||
.setHeading()
|
||||
.setClass('fn-excluded-folder-heading')
|
||||
.setName('Manage excluded folders');
|
||||
.setName(t('manageExcludedFolders'));
|
||||
const desc3 = document.createDocumentFragment();
|
||||
desc3.append(
|
||||
'Add {regex} at the beginning of the folder name to use a regex pattern.',
|
||||
t('manageExcludedFoldersDesc1'),
|
||||
desc3.createEl('br'),
|
||||
'Use * before and after to exclude folders that include the name between the *s.',
|
||||
t('manageExcludedFoldersDesc2'),
|
||||
desc3.createEl('br'),
|
||||
'Use * before the folder name to exclude folders that end with the folder name.',
|
||||
t('manageExcludedFoldersDesc3'),
|
||||
desc3.createEl('br'),
|
||||
'Use * after the folder name to exclude folders that start with the folder name.',
|
||||
t('manageExcludedFoldersDesc4'),
|
||||
);
|
||||
manageExcluded.setDesc(desc3);
|
||||
// eslint-disable-next-line max-len
|
||||
manageExcluded.infoEl.appendText('The regexes and wildcards are only for the folder name, not the path.');
|
||||
manageExcluded.infoEl.appendText(t('excludedFoldersInfo1'));
|
||||
manageExcluded.infoEl.createEl('br');
|
||||
// eslint-disable-next-line max-len
|
||||
manageExcluded.infoEl.appendText('If you want to switch to a folder path delete the pattern first.');
|
||||
manageExcluded.infoEl.appendText(t('excludedFoldersInfo2'));
|
||||
// eslint-disable-next-line max-len
|
||||
manageExcluded.infoEl.style.color = settingsTab.app.vault.getConfig('accentColor') as string || '#7d5bed';
|
||||
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Whitelisted folders')
|
||||
.setDesc('Folders that override the excluded folders/patterns')
|
||||
.setName(t('whitelistedFolders'))
|
||||
.setDesc(t('whitelistedFoldersDesc'))
|
||||
.addButton((cb) => {
|
||||
cb.setButtonText('Manage');
|
||||
cb.setButtonText(t('manage'));
|
||||
cb.setCta();
|
||||
cb.onClick(async () => {
|
||||
new WhitelistedFoldersSettings(settingsTab).open();
|
||||
|
|
@ -49,9 +50,9 @@ export async function renderExcludeFolders(settingsTab: SettingsTab): Promise<vo
|
|||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Exclude folder default settings')
|
||||
.setName(t('excludeFolderDefaultSettings'))
|
||||
.addButton((cb) => {
|
||||
cb.setButtonText('Manage');
|
||||
cb.setButtonText(t('manage'));
|
||||
cb.setCta();
|
||||
cb.onClick(async () => {
|
||||
new ExcludedFolderSettings(
|
||||
|
|
@ -63,9 +64,9 @@ export async function renderExcludeFolders(settingsTab: SettingsTab): Promise<vo
|
|||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Exclude pattern default settings')
|
||||
.setName(t('excludePatternDefaultSettings'))
|
||||
.addButton((cb) => {
|
||||
cb.setButtonText('Manage');
|
||||
cb.setButtonText(t('manage'));
|
||||
cb.setCta();
|
||||
cb.onClick(async () => {
|
||||
new PatternSettings(
|
||||
|
|
@ -78,12 +79,12 @@ export async function renderExcludeFolders(settingsTab: SettingsTab): Promise<vo
|
|||
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Add excluded folder')
|
||||
.setName(t('addExcludedFolder'))
|
||||
.setClass('add-exclude-folder-item')
|
||||
.addButton((cb) => {
|
||||
cb.setIcon('plus');
|
||||
cb.setClass('add-exclude-folder');
|
||||
cb.setTooltip('Add excluded folder');
|
||||
cb.setTooltip(t('addExcludedFolder'));
|
||||
cb.onClick(() => {
|
||||
const excludedFolder = new ExcludedFolder(
|
||||
'',
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
/* eslint-disable max-len */
|
||||
import { Setting } from 'obsidian';
|
||||
import type { SettingsTab } from './SettingsTab';
|
||||
import { t } from '../i18n';
|
||||
|
||||
export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void> {
|
||||
const containerEl = settingsTab.settingsPage;
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Hide folder note')
|
||||
.setDesc('Hide the folder note file from appearing in the file explorer')
|
||||
.setName(t('hideFolderNote'))
|
||||
.setDesc(t('hideFolderNoteDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.hideFolderNote)
|
||||
|
|
@ -23,8 +25,8 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
);
|
||||
|
||||
const setting2 = new Setting(containerEl)
|
||||
.setName('Disable click-to-open folder note on mobile')
|
||||
.setDesc('Prevents folder notes from opening when tapping the folder name or surrounding area on mobile devices. They can now only be opened via the context menu or a command.')
|
||||
.setName(t('disableClickToOpenOnMobile'))
|
||||
.setDesc(t('disableClickToOpenOnMobileDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.disableOpenFolderNoteOnClick)
|
||||
|
|
@ -34,13 +36,13 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
}),
|
||||
);
|
||||
|
||||
setting2.infoEl.appendText('Requires a restart to take effect');
|
||||
setting2.infoEl.appendText(t('requiresRestart'));
|
||||
const setting2AccentColor = settingsTab.app.vault.getConfig('accentColor') as string || '#7d5bed';
|
||||
setting2.infoEl.style.color = setting2AccentColor;
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Open folder notes by only clicking directly on the folder name')
|
||||
.setDesc('Only allow folder notes to open when clicking directly on the folder name in the file explorer')
|
||||
.setName(t('openByClickingFolderNameOnly'))
|
||||
.setDesc(t('openByClickingFolderNameOnlyDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(!settingsTab.plugin.settings.stopWhitespaceCollapsing)
|
||||
|
|
@ -56,8 +58,8 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
);
|
||||
|
||||
const disableSetting = new Setting(containerEl);
|
||||
disableSetting.setName('Disable folder collapsing');
|
||||
disableSetting.setDesc('When enabled, folders in the file explorer will only collapse when clicking the collapse icon next to the folder name, not when clicking near a folder name when it has a folder note.');
|
||||
disableSetting.setName(t('disableFolderCollapsing'));
|
||||
disableSetting.setDesc(t('disableFolderCollapsingDesc'));
|
||||
disableSetting.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(!settingsTab.plugin.settings.enableCollapsing)
|
||||
|
|
@ -66,13 +68,13 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
await settingsTab.plugin.saveSettings();
|
||||
}),
|
||||
);
|
||||
disableSetting.infoEl.appendText('Requires a restart to take effect');
|
||||
disableSetting.infoEl.appendText(t('requiresRestart'));
|
||||
const accentColor = settingsTab.app.vault.getConfig('accentColor') as string || '#7d5bed';
|
||||
disableSetting.infoEl.style.color = accentColor;
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Use submenus')
|
||||
.setDesc('Use submenus for file/folder commands')
|
||||
.setName(t('useSubmenus'))
|
||||
.setDesc(t('useSubmenusDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.useSubmenus)
|
||||
|
|
@ -85,8 +87,8 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
|
||||
if (settingsTab.plugin.settings.frontMatterTitle.enabled) {
|
||||
new Setting(containerEl)
|
||||
.setName('Auto update folder name in the file explorer (front matter title plugin only)')
|
||||
.setDesc('Automatically update the folder name in the file explorer when the front matter title plugin is enabled and the title for a folder note is changed in the front matter. This will not change the file name, only the displayed name in the file explorer.')
|
||||
.setName(t('autoUpdateFolderNameInExplorer'))
|
||||
.setDesc(t('autoUpdateFolderNameInExplorerDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.frontMatterTitle.explorer)
|
||||
|
|
@ -108,11 +110,11 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
);
|
||||
}
|
||||
|
||||
settingsTab.settingsPage.createEl('h3', { text: 'Style settings' });
|
||||
settingsTab.settingsPage.createEl('h3', { text: t('styleSettings') });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Highlight folder in the file explorer')
|
||||
.setDesc('Highlight the folder in the file explorer when it has a folder note and the folder note is open in the editor')
|
||||
.setName(t('highlightFolder'))
|
||||
.setDesc(t('highlightFolderDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.highlightFolder)
|
||||
|
|
@ -128,8 +130,8 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Hide collapse icon')
|
||||
.setDesc('Hide the collapse icon in the file explorer next to the name of a folder when a folder only contains a folder note')
|
||||
.setName(t('hideCollapseIcon'))
|
||||
.setDesc(t('hideCollapseIconDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.hideCollapsingIcon)
|
||||
|
|
@ -146,8 +148,8 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Hide collapse icon for every empty folder')
|
||||
.setDesc('Hide the collapse icon in the file explorer next to the name of a folder when a folder is empty')
|
||||
.setName(t('hideCollapseIconForEmptyFolders'))
|
||||
.setDesc(t('hideCollapseIconForEmptyFoldersDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.hideCollapsingIconForEmptyFolders)
|
||||
|
|
@ -165,7 +167,7 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
|
||||
if (settingsTab.plugin.settings.hideCollapsingIcon) {
|
||||
new Setting(containerEl)
|
||||
.setName('Hide collapse icon also when only the attachment folder is in the same folder')
|
||||
.setName(t('hideCollapseIconForAttachmentFolder'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.ignoreAttachmentFolder)
|
||||
|
|
@ -182,8 +184,8 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
}
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Underline the name of folder notes')
|
||||
.setDesc('Add an underline to folders that have a folder note in the file explorer')
|
||||
.setName(t('underlineFolderNote'))
|
||||
.setDesc(t('underlineFolderNoteDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.underlineFolder)
|
||||
|
|
@ -199,8 +201,8 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Bold the name of folder notes')
|
||||
.setDesc('Make the folder name bold in the file explorer when it has a folder note')
|
||||
.setName(t('boldFolderNote'))
|
||||
.setDesc(t('boldFolderNoteDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.boldName)
|
||||
|
|
@ -216,8 +218,8 @@ export async function renderFileExplorer(settingsTab: SettingsTab): Promise<void
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Cursive the name of folder notes')
|
||||
.setDesc('Make the folder name cursive in the file explorer when it has a folder note')
|
||||
.setName(t('cursiveFolderNote'))
|
||||
.setDesc(t('cursiveFolderNoteDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.cursiveName)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
import { Setting } from 'obsidian';
|
||||
import type { SettingsTab } from './SettingsTab';
|
||||
import { createOverviewSettings } from 'src/obsidian-folder-overview/src/settings';
|
||||
import { t } from '../i18n';
|
||||
|
||||
export async function renderFolderOverview(settingsTab: SettingsTab): Promise<void> {
|
||||
const { plugin } = settingsTab;
|
||||
const defaultOverviewSettings = plugin.settings.defaultOverview;
|
||||
const containerEl = settingsTab.settingsPage;
|
||||
|
||||
containerEl.createEl('h3', { text: 'Global settings' });
|
||||
containerEl.createEl('h3', { text: t('globalSettings') });
|
||||
new Setting(containerEl)
|
||||
.setName('Auto-update links without opening the overview')
|
||||
.setName(t('autoUpdateLinks'))
|
||||
// eslint-disable-next-line max-len
|
||||
.setDesc('If enabled, the links that appear in the graph view will be updated even when you don\'t have the overview open somewhere.')
|
||||
.setDesc(t('autoUpdateLinksDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(plugin.settings.fvGlobalSettings.autoUpdateLinks)
|
||||
|
|
@ -26,12 +27,12 @@ export async function renderFolderOverview(settingsTab: SettingsTab): Promise<vo
|
|||
}),
|
||||
);
|
||||
|
||||
containerEl.createEl('h3', { text: 'Overviews default settings' });
|
||||
containerEl.createEl('h3', { text: t('overviewDefaultSettings') });
|
||||
const pEl = containerEl.createEl('p', {
|
||||
text: 'Edit the default settings for new folder overviews, ',
|
||||
text: t('overviewDefaultSettingsDesc'),
|
||||
cls: 'setting-item-description',
|
||||
});
|
||||
const span = createSpan({ text: "this won't apply to already existing overviews.", cls: '' });
|
||||
const span = createSpan({ text: t('overviewDefaultSettingsSpan'), cls: '' });
|
||||
const accentColor = (settingsTab.app.vault.getConfig('accentColor') as string) || '#7d5bed';
|
||||
span.setAttr('style', `color: ${accentColor};`);
|
||||
pEl.appendChild(span);
|
||||
|
|
|
|||
|
|
@ -9,15 +9,33 @@ import { TemplateSuggest } from '../suggesters/TemplateSuggester';
|
|||
import { refreshAllFolderStyles } from '../functions/styleFunctions';
|
||||
import BackupWarningModal from './modals/BackupWarning';
|
||||
import RenameFolderNotesModal from './modals/RenameFns';
|
||||
import { t, setLanguage } from '../i18n';
|
||||
|
||||
let debounceTimer: NodeJS.Timeout;
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
||||
const containerEl = settingsTab.settingsPage;
|
||||
|
||||
// Language selector
|
||||
new Setting(containerEl)
|
||||
.setName(t('language'))
|
||||
.setDesc(t('languageDesc'))
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown.addOption('en', t('langEnglish'));
|
||||
dropdown.addOption('zh', t('langChinese'));
|
||||
dropdown.setValue(settingsTab.plugin.settings.language ?? 'en');
|
||||
dropdown.onChange(async (value) => {
|
||||
settingsTab.plugin.settings.language = value;
|
||||
await settingsTab.plugin.saveSettings();
|
||||
setLanguage(value);
|
||||
settingsTab.display();
|
||||
});
|
||||
});
|
||||
|
||||
const nameSetting = new Setting(containerEl)
|
||||
.setName('Folder note name template')
|
||||
.setDesc('All folder notes will use this name. Use {{folder_name}} to insert the folder’s name. Existing notes won’t update automatically; click on the button to apply the new name.')
|
||||
.setName(t('folderNoteNameTemplate'))
|
||||
.setDesc(t('folderNoteNameTemplateDesc'))
|
||||
.addText((text) =>
|
||||
text
|
||||
.setValue(settingsTab.plugin.settings.folderNoteName)
|
||||
|
|
@ -45,25 +63,25 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
)
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText('Rename existing folder notes')
|
||||
.setButtonText(t('renameExistingFolderNotes'))
|
||||
.setCta()
|
||||
.onClick(async () => {
|
||||
new RenameFolderNotesModal(
|
||||
settingsTab.plugin,
|
||||
'Rename all existing folder notes',
|
||||
'When you click on "Confirm" all existing folder notes will be renamed to the new folder note name.',
|
||||
t('renameAllExistingFolderNotes'),
|
||||
t('renameConfirmMsg'),
|
||||
settingsTab.renameFolderNotes,
|
||||
[])
|
||||
.open();
|
||||
}),
|
||||
);
|
||||
nameSetting.infoEl.appendText('Requires a restart to take effect');
|
||||
nameSetting.infoEl.appendText(t('requiresRestart'));
|
||||
nameSetting.infoEl.style.color = settingsTab.app.vault.getConfig('accentColor') as string || '#7d5bed';
|
||||
|
||||
if (!settingsTab.plugin.settings.folderNoteName.includes('{{folder_name}}')) {
|
||||
new Setting(containerEl)
|
||||
.setName('Display Folder Name in Tab Title')
|
||||
.setDesc('Use the actual folder name in the tab title instead of the custom folder note name (e.g., "Folder Note").')
|
||||
.setName(t('displayFolderNameInTabTitle'))
|
||||
.setDesc(t('displayFolderNameInTabTitleDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.tabManagerEnabled)
|
||||
|
|
@ -82,13 +100,13 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
}
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Default file type for new folder notes')
|
||||
.setDesc('Choose the default file type (canvas, markdown, ...) used when creating new folder notes.')
|
||||
.setName(t('defaultFileType'))
|
||||
.setDesc(t('defaultFileTypeDesc'))
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown.addOption('.ask', 'ask for file type');
|
||||
dropdown.addOption('.ask', t('askForFileType'));
|
||||
settingsTab.plugin.settings.supportedFileTypes.forEach((type) => {
|
||||
if (type === '.md' || type === 'md') {
|
||||
dropdown.addOption('.md', 'markdown');
|
||||
dropdown.addOption('.md', t('markdown'));
|
||||
} else {
|
||||
dropdown.addOption('.' + type, type);
|
||||
}
|
||||
|
|
@ -126,11 +144,9 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
});
|
||||
|
||||
const setting0 = new Setting(containerEl);
|
||||
setting0.setName('Supported file types');
|
||||
setting0.setName(t('supportedFileTypes'));
|
||||
const desc0 = document.createDocumentFragment();
|
||||
desc0.append(
|
||||
'Specify which file types are allowed as folder notes. Applies to both new and existing folders. Adding many types may affect performance.',
|
||||
);
|
||||
desc0.append(t('supportedFileTypesDesc'));
|
||||
setting0.setDesc(desc0);
|
||||
const list = new ListComponent(
|
||||
setting0.settingEl,
|
||||
|
|
@ -154,7 +170,7 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
{ value: 'canvas', label: 'Canvas' },
|
||||
{ value: 'base', label: 'Bases' },
|
||||
{ value: 'excalidraw', label: 'Excalidraw' },
|
||||
{ value: 'custom', label: 'Custom extension' },
|
||||
{ value: 'custom', label: t('customExtension') },
|
||||
];
|
||||
|
||||
options.forEach((option) => {
|
||||
|
|
@ -181,7 +197,7 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
} else {
|
||||
setting0.addButton((button) =>
|
||||
button
|
||||
.setButtonText('Add custom file type')
|
||||
.setButtonText(t('addCustomFileType'))
|
||||
.setCta()
|
||||
.onClick(async () => {
|
||||
new AddSupportedFileModal(
|
||||
|
|
@ -196,11 +212,11 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
|
||||
|
||||
const templateSetting = new Setting(containerEl)
|
||||
.setDesc('Can be used with templater/templates plugin. If you add the location of the templates there.')
|
||||
.setName('Template path')
|
||||
.setDesc(t('templatePathDesc'))
|
||||
.setName(t('templatePath'))
|
||||
.addSearch((cb) => {
|
||||
new TemplateSuggest(cb.inputEl, settingsTab.plugin);
|
||||
cb.setPlaceholder('Template path');
|
||||
cb.setPlaceholder(t('templatePathPlaceholder'));
|
||||
const templateFile = settingsTab.plugin.app.vault.getAbstractFileByPath(
|
||||
settingsTab.plugin.settings.templatePath,
|
||||
);
|
||||
|
|
@ -215,16 +231,16 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
}
|
||||
});
|
||||
});
|
||||
templateSetting.infoEl.appendText('Requires a restart to take effect');
|
||||
templateSetting.infoEl.appendText(t('requiresRestart'));
|
||||
templateSetting.infoEl.style.color = settingsTab.app.vault.getConfig('accentColor') as string || '#7d5bed';
|
||||
|
||||
const storageLocation = new Setting(containerEl)
|
||||
.setName('Storage location')
|
||||
.setDesc('Choose where to store the folder notes')
|
||||
.setName(t('storageLocation'))
|
||||
.setDesc(t('storageLocationDesc'))
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption('insideFolder', 'Inside the folder')
|
||||
.addOption('parentFolder', 'In the parent folder')
|
||||
.addOption('insideFolder', t('insideFolder'))
|
||||
.addOption('parentFolder', t('inParentFolder'))
|
||||
.setValue(settingsTab.plugin.settings.storageLocation)
|
||||
.onChange(async (value: 'insideFolder' | 'parentFolder' | 'vaultFolder') => {
|
||||
settingsTab.plugin.settings.storageLocation = value;
|
||||
|
|
@ -235,7 +251,7 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
)
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText('Switch')
|
||||
.setButtonText(t('switchButton'))
|
||||
.setCta()
|
||||
.onClick(async () => {
|
||||
let oldStorageLocation = settingsTab.plugin.settings.storageLocation;
|
||||
|
|
@ -246,20 +262,20 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
}
|
||||
new BackupWarningModal(
|
||||
settingsTab.plugin,
|
||||
'Switch storage location',
|
||||
'When you click on "Confirm" all folder notes will be moved to the new storage location.',
|
||||
t('switchStorageLocationTitle'),
|
||||
t('switchStorageLocationMsg'),
|
||||
settingsTab.switchStorageLocation,
|
||||
[oldStorageLocation],
|
||||
).open();
|
||||
}),
|
||||
);
|
||||
storageLocation.infoEl.appendText('Requires a restart to take effect');
|
||||
storageLocation.infoEl.appendText(t('requiresRestart'));
|
||||
storageLocation.infoEl.style.color = settingsTab.app.vault.getConfig('accentColor') as string || '#7d5bed';
|
||||
|
||||
if (settingsTab.plugin.settings.storageLocation === 'parentFolder') {
|
||||
new Setting(containerEl)
|
||||
.setName('Delete folder notes when deleting the folder')
|
||||
.setDesc('Delete the folder note when deleting the folder')
|
||||
.setName(t('deleteFolderNotesOnFolderDelete'))
|
||||
.setDesc(t('deleteFolderNotesOnFolderDeleteDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.syncDelete)
|
||||
|
|
@ -270,8 +286,8 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
),
|
||||
);
|
||||
new Setting(containerEl)
|
||||
.setName('Move folder notes when moving the folder')
|
||||
.setDesc('Move the folder note file along with the folder when it is moved')
|
||||
.setName(t('moveFolderNotesOnFolderMove'))
|
||||
.setDesc(t('moveFolderNotesOnFolderMoveDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.syncMove)
|
||||
|
|
@ -282,18 +298,18 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
);
|
||||
}
|
||||
if (Platform.isDesktopApp) {
|
||||
settingsTab.settingsPage.createEl('h3', { text: 'Keyboard Shortcuts' });
|
||||
settingsTab.settingsPage.createEl('h3', { text: t('keyboardShortcuts') });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Key for creating folder note')
|
||||
.setDesc('The key combination to create a folder note')
|
||||
.setName(t('keyForCreatingFolderNote'))
|
||||
.setDesc(t('keyForCreatingFolderNoteDesc'))
|
||||
.addDropdown((dropdown) => {
|
||||
if (!Platform.isMacOS) {
|
||||
dropdown.addOption('ctrl', 'Ctrl + Click');
|
||||
dropdown.addOption('alt', 'Alt + Click');
|
||||
dropdown.addOption('ctrl', t('ctrlClick'));
|
||||
dropdown.addOption('alt', t('altClick'));
|
||||
} else {
|
||||
dropdown.addOption('ctrl', 'Cmd + Click');
|
||||
dropdown.addOption('alt', 'Option + Click');
|
||||
dropdown.addOption('ctrl', t('cmdClick'));
|
||||
dropdown.addOption('alt', t('optionClick'));
|
||||
}
|
||||
dropdown.setValue(settingsTab.plugin.settings.ctrlKey ? 'ctrl' : 'alt');
|
||||
dropdown.onChange(async (value) => {
|
||||
|
|
@ -305,16 +321,16 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Key for opening folder note')
|
||||
.setDesc('Select the combination to open a folder note')
|
||||
.setName(t('keyForOpeningFolderNote'))
|
||||
.setDesc(t('keyForOpeningFolderNoteDesc'))
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown.addOption('click', 'Mouse Click');
|
||||
dropdown.addOption('click', t('mouseClick'));
|
||||
if (!Platform.isMacOS) {
|
||||
dropdown.addOption('ctrl', 'Ctrl + Click');
|
||||
dropdown.addOption('alt', 'Alt + Click');
|
||||
dropdown.addOption('ctrl', t('ctrlClick'));
|
||||
dropdown.addOption('alt', t('altClick'));
|
||||
} else {
|
||||
dropdown.addOption('ctrl', 'Cmd + Click');
|
||||
dropdown.addOption('alt', 'Option + Click');
|
||||
dropdown.addOption('ctrl', t('cmdClick'));
|
||||
dropdown.addOption('alt', t('optionClick'));
|
||||
}
|
||||
if (settingsTab.plugin.settings.openByClick) {
|
||||
dropdown.setValue('click');
|
||||
|
|
@ -333,11 +349,11 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
});
|
||||
}
|
||||
|
||||
settingsTab.settingsPage.createEl('h3', { text: 'Folder note behavior' });
|
||||
settingsTab.settingsPage.createEl('h3', { text: t('folderNoteBehavior') });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Confirm folder note deletion')
|
||||
.setDesc('Ask for confirmation before deleting a folder note')
|
||||
.setName(t('confirmFolderNoteDeletion'))
|
||||
.setDesc(t('confirmFolderNoteDeletionDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.showDeleteConfirmation)
|
||||
|
|
@ -349,12 +365,12 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Deleted folder notes')
|
||||
.setDesc('What happens to the folder note after you delete it')
|
||||
.setName(t('deletedFolderNotes'))
|
||||
.setDesc(t('deletedFolderNotesDesc'))
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown.addOption('trash', 'Move to system trash');
|
||||
dropdown.addOption('obsidianTrash', 'Move to Obsidian trash (.trash folder)');
|
||||
dropdown.addOption('delete', 'Delete permanently');
|
||||
dropdown.addOption('trash', t('moveToSystemTrash'));
|
||||
dropdown.addOption('obsidianTrash', t('moveToObsidianTrash'));
|
||||
dropdown.addOption('delete', t('deletePermanently'));
|
||||
dropdown.setValue(settingsTab.plugin.settings.deleteFilesAction);
|
||||
dropdown.onChange(async (value: 'trash' | 'delete' | 'obsidianTrash') => {
|
||||
settingsTab.plugin.settings.deleteFilesAction = value;
|
||||
|
|
@ -365,8 +381,8 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
|
||||
if (Platform.isDesktop) {
|
||||
const setting3 = new Setting(containerEl);
|
||||
setting3.setName('Open folder note in a new tab by default');
|
||||
setting3.setDesc('Always open folder notes in a new tab unless the note is already open in the current tab.');
|
||||
setting3.setName(t('openInNewTab'));
|
||||
setting3.setDesc(t('openInNewTabDesc'));
|
||||
setting3.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.openInNewTab)
|
||||
|
|
@ -376,14 +392,14 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
settingsTab.display();
|
||||
}),
|
||||
);
|
||||
setting3.infoEl.appendText('Requires a restart to take effect');
|
||||
setting3.infoEl.appendText(t('requiresRestart'));
|
||||
setting3.infoEl.style.color = settingsTab.app.vault.getConfig('accentColor') as string || '#7d5bed';
|
||||
}
|
||||
|
||||
if (settingsTab.plugin.settings.openInNewTab) {
|
||||
new Setting(containerEl)
|
||||
.setName('Focus existing tab instead of creating a new one')
|
||||
.setDesc('If a folder note is already open in a tab, focus that tab instead of creating a new one.')
|
||||
.setName(t('focusExistingTab'))
|
||||
.setDesc(t('focusExistingTabDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.focusExistingTab)
|
||||
|
|
@ -396,8 +412,8 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
}
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Sync folder name')
|
||||
.setDesc('Automatically rename the folder note when the folder name is changed')
|
||||
.setName(t('syncFolderName'))
|
||||
.setDesc(t('syncFolderNameDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.syncFolderName)
|
||||
|
|
@ -408,22 +424,22 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
}),
|
||||
);
|
||||
|
||||
settingsTab.settingsPage.createEl('h4', { text: 'Automation settings' });
|
||||
settingsTab.settingsPage.createEl('h4', { text: t('automationSettings') });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Create folder notes for all folders')
|
||||
.setDesc('Generate folder notes for every folder in the vault.')
|
||||
.setName(t('createFolderNotesForAllFolders'))
|
||||
.setDesc(t('createFolderNotesForAllFoldersDesc'))
|
||||
.addButton((cb) => {
|
||||
cb.setIcon('plus');
|
||||
cb.setTooltip('Create folder notes');
|
||||
cb.setTooltip(t('createFolderNotesForAllFolders'));
|
||||
cb.onClick(async () => {
|
||||
new ConfirmationModal(settingsTab.app, settingsTab.plugin).open();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Auto-create on folder creation')
|
||||
.setDesc('Automatically create a folder note whenever a new folder is added.')
|
||||
.setName(t('autoCreateOnFolderCreation'))
|
||||
.setDesc(t('autoCreateOnFolderCreationDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.autoCreate)
|
||||
|
|
@ -436,8 +452,8 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
|
||||
if (settingsTab.plugin.settings.autoCreate) {
|
||||
new Setting(containerEl)
|
||||
.setName('Auto-open after creation')
|
||||
.setDesc('Open the folder note immediately after it’s created automatically.')
|
||||
.setName(t('autoOpenAfterCreation'))
|
||||
.setDesc(t('autoOpenAfterCreationDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.autoCreateFocusFiles)
|
||||
|
|
@ -449,8 +465,8 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Auto-create for attachment folders')
|
||||
.setDesc('Also automatically create folder notes for attachment folders (e.g., "Attachments", "Media", etc.).')
|
||||
.setName(t('autoCreateForAttachmentFolders'))
|
||||
.setDesc(t('autoCreateForAttachmentFoldersDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.autoCreateForAttachmentFolder)
|
||||
|
|
@ -463,8 +479,8 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
}
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Auto-create when creating notes')
|
||||
.setDesc('Automatically create a folder note when a regular note is created inside a folder. Works for supported file types only.')
|
||||
.setName(t('autoCreateWhenCreatingNotes'))
|
||||
.setDesc(t('autoCreateWhenCreatingNotesDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.autoCreateForFiles)
|
||||
|
|
@ -475,23 +491,21 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
}),
|
||||
);
|
||||
|
||||
settingsTab.settingsPage.createEl('h3', { text: 'Integration & Compatibility' });
|
||||
settingsTab.settingsPage.createEl('h3', { text: t('integrationCompatibility') });
|
||||
|
||||
const desc1 = document.createDocumentFragment();
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.href = 'https://github.com/snezhig/obsidian-front-matter-title';
|
||||
link.textContent = 'front matter title plugin';
|
||||
link.textContent = t('frontMatterTitlePlugin');
|
||||
link.target = '_blank';
|
||||
|
||||
desc1.append(
|
||||
'Allows you to use the ',
|
||||
link,
|
||||
' with folder notes. It allows you to set the folder name to some name you set in the front matter.',
|
||||
);
|
||||
const fmtpDescText = t('enableFmtpIntegrationDesc');
|
||||
const [before, after] = fmtpDescText.split('{link}');
|
||||
desc1.append(before ?? '');
|
||||
desc1.appendChild(link);
|
||||
desc1.append(after ?? '');
|
||||
|
||||
const fmtpSetting = new Setting(containerEl)
|
||||
.setName('Enable front matter title plugin integration')
|
||||
.setName(t('enableFmtpIntegration'))
|
||||
.setDesc(desc1)
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
|
|
@ -524,14 +538,14 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
settingsTab.display();
|
||||
}),
|
||||
);
|
||||
fmtpSetting.infoEl.appendText('Requires a restart to take effect');
|
||||
fmtpSetting.infoEl.appendText(t('requiresRestart'));
|
||||
fmtpSetting.infoEl.style.color = settingsTab.app.vault.getConfig('accentColor') as string || '#7d5bed';
|
||||
|
||||
settingsTab.settingsPage.createEl('h3', { text: 'Session & Persistence' });
|
||||
settingsTab.settingsPage.createEl('h3', { text: t('sessionPersistence') });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Persist tab after restart')
|
||||
.setDesc('Restore the same settings tab after restarting Obsidian.')
|
||||
.setName(t('persistTabAfterRestart'))
|
||||
.setDesc(t('persistTabAfterRestartDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.persistentSettingsTab.afterRestart)
|
||||
|
|
@ -543,8 +557,8 @@ export async function renderGeneral(settingsTab: SettingsTab): Promise<void> {
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Persist tab during session only')
|
||||
.setDesc('Keep the current settings tab open during the session, but reset it after a restart or reload.')
|
||||
.setName(t('persistTabDuringSession'))
|
||||
.setDesc(t('persistTabDuringSessionDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.persistentSettingsTab.afterChangingTab)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
/* eslint-disable max-len */
|
||||
import { Setting } from 'obsidian';
|
||||
import type { SettingsTab } from './SettingsTab';
|
||||
import { t } from '../i18n';
|
||||
|
||||
export async function renderPath(settingsTab: SettingsTab): Promise<void> {
|
||||
const containerEl = settingsTab.settingsPage;
|
||||
new Setting(containerEl)
|
||||
.setName('Open folder note through path')
|
||||
.setDesc('Open a folder note when clicking on a folder name in the path if it is a folder note')
|
||||
.setName(t('openFolderNoteThroughPath'))
|
||||
.setDesc(t('openFolderNoteThroughPathDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.openFolderNoteOnClickInPath)
|
||||
|
|
@ -18,8 +20,8 @@ export async function renderPath(settingsTab: SettingsTab): Promise<void> {
|
|||
|
||||
if (settingsTab.plugin.settings.openFolderNoteOnClickInPath) {
|
||||
new Setting(containerEl)
|
||||
.setName('Open sidebar when opening a folder note through path (Mobile only)')
|
||||
.setDesc('Open the sidebar when opening a folder note through the path on mobile')
|
||||
.setName(t('openSidebarMobile'))
|
||||
.setDesc(t('openSidebarMobileDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.openSidebar.mobile)
|
||||
|
|
@ -30,8 +32,8 @@ export async function renderPath(settingsTab: SettingsTab): Promise<void> {
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Open sidebar when opening a folder note through path (Desktop only)')
|
||||
.setDesc('Open the sidebar when opening a folder note through the path on desktop')
|
||||
.setName(t('openSidebarDesktop'))
|
||||
.setDesc(t('openSidebarDesktopDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.openSidebar.desktop)
|
||||
|
|
@ -44,8 +46,8 @@ export async function renderPath(settingsTab: SettingsTab): Promise<void> {
|
|||
|
||||
if (settingsTab.plugin.settings.frontMatterTitle.enabled) {
|
||||
new Setting(containerEl)
|
||||
.setName('Auto update folder name in the path (front matter title plugin only)')
|
||||
.setDesc('Automatically update the folder name in the path when the front matter title plugin is enabled and the title for a folder note is changed in the front matter. This will not change the file name, only the displayed name in the path.')
|
||||
.setName(t('autoUpdateFolderNameInPath'))
|
||||
.setDesc(t('autoUpdateFolderNameInPathDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.frontMatterTitle.path)
|
||||
|
|
@ -61,11 +63,11 @@ export async function renderPath(settingsTab: SettingsTab): Promise<void> {
|
|||
);
|
||||
}
|
||||
|
||||
settingsTab.settingsPage.createEl('h3', { text: 'Style settings' });
|
||||
settingsTab.settingsPage.createEl('h3', { text: t('styleSettings') });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Underline folders in the path')
|
||||
.setDesc('Add an underline to folders that have a folder note in the path above a note')
|
||||
.setName(t('underlineFoldersInPath'))
|
||||
.setDesc(t('underlineFoldersInPathDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.underlineFolderInPath)
|
||||
|
|
@ -81,8 +83,8 @@ export async function renderPath(settingsTab: SettingsTab): Promise<void> {
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Bold folders in the path')
|
||||
.setDesc('Make the folder name bold in the path above a note when it has a folder note')
|
||||
.setName(t('boldFoldersInPath'))
|
||||
.setDesc(t('boldFoldersInPathDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.boldNameInPath)
|
||||
|
|
@ -98,8 +100,8 @@ export async function renderPath(settingsTab: SettingsTab): Promise<void> {
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Cursive the name of folder notes in the path')
|
||||
.setDesc('Make the folder name cursive in the path above a note when it has a folder note')
|
||||
.setName(t('cursiveFoldersInPath'))
|
||||
.setDesc(t('cursiveFoldersInPathDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.cursiveNameInPath)
|
||||
|
|
@ -115,8 +117,8 @@ export async function renderPath(settingsTab: SettingsTab): Promise<void> {
|
|||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Hide folder note name in the path')
|
||||
.setDesc('Only show the folder name in the path and hide the folder note name.')
|
||||
.setName(t('hideFolderNoteNameInPath'))
|
||||
.setDesc(t('hideFolderNoteNameInPathDesc'))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(settingsTab.plugin.settings.hideFolderNoteNameInPath)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import {
|
|||
Notice, PluginSettingTab, TFile,
|
||||
TFolder, type App, type MarkdownPostProcessorContext,
|
||||
} from 'obsidian';
|
||||
import { t } from '../i18n';
|
||||
import type FolderNotesPlugin from '../main';
|
||||
import type { ExcludePattern } from 'src/ExcludeFolders/ExcludePattern';
|
||||
import type { ExcludedFolder } from 'src/ExcludeFolders/ExcludeFolder';
|
||||
|
|
@ -83,6 +84,7 @@ export interface FolderNotesSettings {
|
|||
autoUpdateLinks: boolean;
|
||||
}
|
||||
hideFolderNoteNameInPath: boolean;
|
||||
language: string;
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: FolderNotesSettings = {
|
||||
|
|
@ -208,6 +210,7 @@ export const DEFAULT_SETTINGS: FolderNotesSettings = {
|
|||
autoUpdateLinks: false,
|
||||
},
|
||||
hideFolderNoteNameInPath: false,
|
||||
language: 'en',
|
||||
};
|
||||
|
||||
export class SettingsTab extends PluginSettingTab {
|
||||
|
|
@ -219,28 +222,30 @@ export class SettingsTab extends PluginSettingTab {
|
|||
constructor(app: App, plugin: FolderNotesPlugin) {
|
||||
super(app, plugin);
|
||||
}
|
||||
TABS = {
|
||||
GENERAL: {
|
||||
name: 'General',
|
||||
id: 'general',
|
||||
},
|
||||
FOLDER_OVERVIEW: {
|
||||
name: 'Folder overview',
|
||||
id: 'folder_overview',
|
||||
},
|
||||
EXCLUDE_FOLDERS: {
|
||||
name: 'Exclude folders',
|
||||
id: 'exclude_folders',
|
||||
},
|
||||
FILE_EXPLORER: {
|
||||
name: 'File explorer',
|
||||
id: 'file_explorer',
|
||||
},
|
||||
PATH: {
|
||||
name: 'Path',
|
||||
id: 'path',
|
||||
},
|
||||
};
|
||||
get TABS() {
|
||||
return {
|
||||
GENERAL: {
|
||||
name: t('tabGeneral'),
|
||||
id: 'general',
|
||||
},
|
||||
FOLDER_OVERVIEW: {
|
||||
name: t('tabFolderOverview'),
|
||||
id: 'folder_overview',
|
||||
},
|
||||
EXCLUDE_FOLDERS: {
|
||||
name: t('tabExcludeFolders'),
|
||||
id: 'exclude_folders',
|
||||
},
|
||||
FILE_EXPLORER: {
|
||||
name: t('tabFileExplorer'),
|
||||
id: 'file_explorer',
|
||||
},
|
||||
PATH: {
|
||||
name: t('tabPath'),
|
||||
id: 'path',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
renderSettingsPage(tabId: string): void {
|
||||
this.settingsPage.empty();
|
||||
|
|
@ -321,7 +326,7 @@ export class SettingsTab extends PluginSettingTab {
|
|||
}
|
||||
|
||||
renameFolderNotes(): void {
|
||||
new Notice('Starting to update folder notes...');
|
||||
new Notice(t('startingUpdateFolderNotes'));
|
||||
const oldTemplate = this.plugin.settings.oldFolderNoteName ?? '{{folder_name}}';
|
||||
|
||||
for (const folder of this.app.vault.getAllLoadedFiles()) {
|
||||
|
|
@ -357,11 +362,11 @@ export class SettingsTab extends PluginSettingTab {
|
|||
|
||||
this.plugin.settings.oldFolderNoteName = this.plugin.settings.folderNoteName;
|
||||
this.plugin.saveSettings();
|
||||
new Notice('Finished updating folder notes');
|
||||
new Notice(t('finishedUpdatingFolderNotes'));
|
||||
}
|
||||
|
||||
switchStorageLocation(oldMethod: string): void {
|
||||
new Notice('Starting to switch storage location...');
|
||||
new Notice(t('startingSwitchStorageLocation'));
|
||||
this.app.vault.getAllLoadedFiles().forEach((file) => {
|
||||
if (file instanceof TFolder) {
|
||||
const folderNote = getFolderNote(this.plugin, file.path, oldMethod);
|
||||
|
|
@ -385,7 +390,7 @@ export class SettingsTab extends PluginSettingTab {
|
|||
}
|
||||
}
|
||||
});
|
||||
new Notice('Finished switching storage location');
|
||||
new Notice(t('finishedSwitchingStorageLocation'));
|
||||
}
|
||||
|
||||
onClose(): void {
|
||||
|
|
|
|||
Loading…
Reference in a new issue