diff --git a/src/i18n-strings.ts b/src/i18n-strings.ts index 314f382..fd6d42c 100644 --- a/src/i18n-strings.ts +++ b/src/i18n-strings.ts @@ -45,6 +45,10 @@ export const STRINGS: Record> = { copyFailed: '复制失败:{error}', actionFailed: '{label}失败:{error}', exported: '已导出 → {path}', + exportCancelled: '已取消导出', + confirmExportOverwrite: '导出文件已存在:{path}\n是否覆盖?', + confirmExportCancel: '取消', + confirmExportOverwriteButton: '覆盖', noCurrentNote: '没有当前笔记', cacheClearedFile: '已清除缓存:{name}', cacheClearedAll: '已清除 {count} 条缓存', @@ -207,6 +211,10 @@ export const STRINGS: Record> = { copyFailed: 'Copy failed: {error}', actionFailed: '{label} failed: {error}', exported: 'Exported → {path}', + exportCancelled: 'Export cancelled', + confirmExportOverwrite: 'Export file already exists: {path}\nOverwrite it?', + confirmExportCancel: 'Cancel', + confirmExportOverwriteButton: 'Overwrite', noCurrentNote: 'No current note', cacheClearedFile: 'Cleared cache: {name}', cacheClearedAll: 'Cleared {count} cache entries', diff --git a/src/modal.ts b/src/modal.ts index 11009d7..cfc754a 100644 --- a/src/modal.ts +++ b/src/modal.ts @@ -4,7 +4,7 @@ import { type App, Modal } from 'obsidian'; import type { CardPatch, PluginHost, ResolvedCard } from './types'; import { addTextButton } from './ui-helpers'; -export function confirmRegenerateEditedCards( +function confirmAction( app: App, title: string, message: string, @@ -35,6 +35,26 @@ export function confirmRegenerateEditedCards( }); } +export function confirmRegenerateEditedCards( + app: App, + title: string, + message: string, + cancelText: string, + confirmText: string, +): Promise { + return confirmAction(app, title, message, cancelText, confirmText); +} + +export function confirmExportOverwrite( + app: App, + title: string, + message: string, + cancelText: string, + confirmText: string, +): Promise { + return confirmAction(app, title, message, cancelText, confirmText); +} + export class CardEditModal extends Modal { plugin: PluginHost; card: ResolvedCard; diff --git a/src/view.ts b/src/view.ts index 4f3cf54..6ad4a0a 100644 --- a/src/view.ts +++ b/src/view.ts @@ -3,7 +3,7 @@ import { ItemView, MarkdownRenderer, Menu, Notice, TFile, type WorkspaceLeaf } from 'obsidian'; import { activeIndexAfterCardDelete, removeCardAt, updateCardAt } from './cards'; import { cardsToMarkdown, cardToMarkdown, cardToPlain } from './markdown'; -import { CardEditModal } from './modal'; +import { CardEditModal, confirmExportOverwrite } from './modal'; import { activeSectionLine, nextCardIndex } from './navigation'; import type { CardPatch, PluginHost, ResolvedCard } from './types'; import { addIconButton, addTextButton, copyToClipboard } from './ui-helpers'; @@ -438,6 +438,17 @@ export class ParallelReaderView extends ItemView { const existing = app.vault.getAbstractFileByPath(targetPath); if (existing instanceof TFile) { + const shouldOverwrite = await confirmExportOverwrite( + this.app, + this.plugin.t('displayName'), + this.plugin.t('confirmExportOverwrite', { path: targetPath }), + this.plugin.t('confirmExportCancel'), + this.plugin.t('confirmExportOverwriteButton'), + ); + if (!shouldOverwrite) { + new Notice(this.plugin.t('exportCancelled')); + return; + } await app.vault.modify(existing, markdown); } else { await app.vault.create(targetPath, markdown); diff --git a/tests/i18n.test.js b/tests/i18n.test.js index 42f0b48..2986eb6 100644 --- a/tests/i18n.test.js +++ b/tests/i18n.test.js @@ -27,5 +27,9 @@ assert.strictEqual(t.translate({ uiLanguage: 'zh' }, 'appTitle'), '对照阅读 assert.strictEqual(t.translate({ uiLanguage: 'en' }, '__no_such_key__'), '__no_such_key__', 'missing key returns key'); assert.strictEqual(t.translate({ uiLanguage: 'zh' }, 'settingTestBackendButton'), '测试'); assert.strictEqual(t.translate({ uiLanguage: 'en' }, 'confirmRegenerateProceed'), 'Regenerate'); +assert.strictEqual( + t.translate({ uiLanguage: 'en' }, 'confirmExportOverwrite', { path: 'Reading/A.md' }), + 'Export file already exists: Reading/A.md\nOverwrite it?', +); console.log('i18n tests passed');