From c70cb2a9f0b124aab0a0dff400e584779707327f Mon Sep 17 00:00:00 2001 From: ydy0615 Date: Sun, 5 Apr 2026 23:30:01 +0800 Subject: [PATCH] refactor(ui): add context menu and file content viewer to Docs view Introduce ContextMenu.vue and FileContent.vue components for interactive file operations and file preview. Update FileTree to support root drop, integrate the new components into DocsView, and refresh i18n strings for file actions. Refactor MilkdownEditor to embed TTS menu and player. --- src/components/ContextMenu.vue | 164 ++++++++++ src/components/FileContent.vue | 272 +++++++++++++++++ src/components/FileTree.vue | 12 +- src/components/MilkdownEditor.vue | 169 +++++++++++ src/utils/i18n.js | 186 +++++++++++- src/views/DocsView.vue | 476 +++++++++++++++++++++++++++++- 6 files changed, 1258 insertions(+), 21 deletions(-) create mode 100644 src/components/ContextMenu.vue create mode 100644 src/components/FileContent.vue diff --git a/src/components/ContextMenu.vue b/src/components/ContextMenu.vue new file mode 100644 index 0000000..81e58cc --- /dev/null +++ b/src/components/ContextMenu.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/src/components/FileContent.vue b/src/components/FileContent.vue new file mode 100644 index 0000000..a75cd66 --- /dev/null +++ b/src/components/FileContent.vue @@ -0,0 +1,272 @@ + + + + + + + diff --git a/src/components/FileTree.vue b/src/components/FileTree.vue index 018a046..406d698 100644 --- a/src/components/FileTree.vue +++ b/src/components/FileTree.vue @@ -79,6 +79,14 @@ function handleDrop(event, targetNode) { } } +function handleDropRoot(event) { + event.preventDefault() + const draggedId = event.dataTransfer.getData('text/plain') + if (draggedId) { + emit('drop', draggedId, null) + } +} + function isClipped(id) { return props.clipboard && props.clipboard.node && props.clipboard.node.id === id } @@ -104,8 +112,8 @@ function getIconClass(type, name) {
diff --git a/src/utils/i18n.js b/src/utils/i18n.js index b34c94b..a0f4d1b 100644 --- a/src/utils/i18n.js +++ b/src/utils/i18n.js @@ -60,7 +60,36 @@ export const translations = { editor: 'Editor', docs: 'Docs', docsManagement: 'Document Management', - docsEmptyDesc: 'Document management interface is under development...' + docsEmptyDesc: 'Document management interface is under development...', + files: 'Files', + noFiles: '暂无文件', + newFile: '新建文件', + newFolder: '新建文件夹', + untitledFile: 'untitled.md', + untitledFolder: '新建文件夹', + rename: '重命名', + delete: '删除', + copy: '复制', + cut: '剪切', + paste: '粘贴', + confirmDelete: '确认删除', + confirmDeleteDesc: '确定要删除', + confirmDeleteFolderDesc: '此操作将删除文件夹内的所有内容。', + confirmDeleteFileDesc: '此操作不可撤销。', + cancel: '取消', + rootDir: '根目录', + expandSidebar: '展开侧边栏', + collapseSidebar: '收起侧边栏', + fileLimitReached: '文件数量已达上限', + folderLimitReached: '文件夹数量已达上限', + fileSizeLimit: '文件大小不能超过 50MB', + storageError: '存储空间不足', + selectFileToView: '选择一个文件以查看内容', + folderContains: '包含', + items: '个项目', + unsupportedPreview: '暂不支持预览此文件类型', + fileNamePlaceholder: '文件名.md', + folderNamePlaceholder: '文件夹名' }, zh: { settings: '设置', @@ -123,7 +152,36 @@ export const translations = { editor: '编辑器', docs: '文档', docsManagement: '文档管理', - docsEmptyDesc: '文档管理界面开发中...' + docsEmptyDesc: '文档管理界面开发中...', + files: '文件', + noFiles: '暂无文件', + newFile: '新建文件', + newFolder: '新建文件夹', + untitledFile: '未命名.md', + untitledFolder: '新建文件夹', + rename: '重命名', + delete: '删除', + copy: '复制', + cut: '剪切', + paste: '粘贴', + confirmDelete: '确认删除', + confirmDeleteDesc: '确定要删除', + confirmDeleteFolderDesc: '此操作将删除文件夹内的所有内容。', + confirmDeleteFileDesc: '此操作不可撤销。', + cancel: '取消', + rootDir: '根目录', + expandSidebar: '展开侧边栏', + collapseSidebar: '收起侧边栏', + fileLimitReached: '文件数量已达上限', + folderLimitReached: '文件夹数量已达上限', + fileSizeLimit: '文件大小不能超过 50MB', + storageError: '存储空间不足', + selectFileToView: '选择一个文件以查看内容', + folderContains: '包含', + items: '个项目', + unsupportedPreview: '暂不支持预览此文件类型', + fileNamePlaceholder: '文件名.md', + folderNamePlaceholder: '文件夹名' }, ja: { settings: '設定', @@ -181,7 +239,36 @@ export const translations = { editor: 'エディター', docs: 'ドキュメント', docsManagement: 'ドキュメント管理', - docsEmptyDesc: 'ドキュメント管理画面は開発中です...' + docsEmptyDesc: 'ドキュメント管理画面は開発中です...', + files: 'ファイル', + noFiles: 'ファイルはありません', + newFile: '新規ファイル', + newFolder: '新規フォルダー', + untitledFile: '無題.md', + untitledFolder: '新しいフォルダー', + rename: '名前を変更', + delete: '削除', + copy: 'コピー', + cut: '切り取り', + paste: '貼り付け', + confirmDelete: '削除の確認', + confirmDeleteDesc: '本当に削除しますか', + confirmDeleteFolderDesc: 'フォルダー内のすべてのコンテンツが削除されます。', + confirmDeleteFileDesc: 'この操作は元に戻せません。', + cancel: 'キャンセル', + rootDir: 'ルートディレクトリ', + expandSidebar: 'サイドバーを展開', + collapseSidebar: 'サイドバーを折りたたむ', + fileLimitReached: 'ファイル数の上限に達しました', + folderLimitReached: 'フォルダー数の上限に達しました', + fileSizeLimit: 'ファイルサイズは50MBを超えられません', + storageError: 'ストレージが不足しています', + selectFileToView: 'ファイルを選択して内容を表示', + folderContains: '含む', + items: '項目', + unsupportedPreview: 'このファイルタイプはプレビューに対応していません', + fileNamePlaceholder: 'ファイル名.md', + folderNamePlaceholder: 'フォルダー名' }, ko: { settings: '설정', @@ -236,7 +323,36 @@ export const translations = { editor: '에디터', docs: '문서', docsManagement: '문서 관리', - docsEmptyDesc: '문서 관리 화면은 개발 중입니다...' + docsEmptyDesc: '문서 관리 화면은 개발 중입니다...', + files: '파일', + noFiles: '파일이 없습니다', + newFile: '새 파일', + newFolder: '새 폴더', + untitledFile: '제목 없음.md', + untitledFolder: '새 폴더', + rename: '이름 변경', + delete: '삭제', + copy: '복사', + cut: '잘라내기', + paste: '붙여넣기', + confirmDelete: '삭제 확인', + confirmDeleteDesc: '정말 삭제하시겠습니까', + confirmDeleteFolderDesc: '폴더의 모든 콘텐츠가 삭제됩니다.', + confirmDeleteFileDesc: '이 작업은 취소할 수 없습니다.', + cancel: '취소', + rootDir: '루트 디렉토리', + expandSidebar: '사이드바 펼치기', + collapseSidebar: '사이드바 접기', + fileLimitReached: '파일 수上限에 도달했습니다', + folderLimitReached: '폴더 수上限에 도달했습니다', + fileSizeLimit: '파일 크기는 50MB를 초과할 수 없습니다', + storageError: '저장 공간이 부족합니다', + selectFileToView: '파일을 선택하여 내용 보기', + folderContains: '포함', + items: '항목', + unsupportedPreview: '이 파일 유형은 미리보기를 지원하지 않습니다', + fileNamePlaceholder: '파일명.md', + folderNamePlaceholder: '폴더명' }, de: { settings: 'Einstellungen', @@ -291,7 +407,36 @@ export const translations = { editor: 'Editor', docs: 'Dokumente', docsManagement: 'Dokumentenverwaltung', - docsEmptyDesc: 'Die Dokumentenverwaltung ist in Entwicklung...' + docsEmptyDesc: 'Die Dokumentenverwaltung ist in Entwicklung...', + files: 'Dateien', + noFiles: 'Keine Dateien', + newFile: 'Neue Datei', + newFolder: 'Neuer Ordner', + untitledFile: 'Unbenannt.md', + untitledFolder: 'Neuer Ordner', + rename: 'Umbenennen', + delete: 'Löschen', + copy: 'Kopieren', + cut: 'Ausschneiden', + paste: 'Einfügen', + confirmDelete: 'Löschen bestätigen', + confirmDeleteDesc: 'Möchten Sie wirklich löschen', + confirmDeleteFolderDesc: 'Dies entfernt alle Inhalte im Ordner.', + confirmDeleteFileDesc: 'Diese Aktion kann nicht rückgängig gemacht werden.', + cancel: 'Abbrechen', + rootDir: 'Stammverzeichnis', + expandSidebar: 'Seitenleiste erweitern', + collapseSidebar: 'Seitenleiste einklappen', + fileLimitReached: 'Maximale Dateianzahl erreicht', + folderLimitReached: 'Maximale Ordneranzahl erreicht', + fileSizeLimit: 'Dateigröße darf 50MB nicht überschreiten', + storageError: 'Speicherplatz unzureichend', + selectFileToView: 'Datei auswählen zum Anzeigen', + folderContains: 'Enthält', + items: 'Elemente', + unsupportedPreview: 'Dieser Dateityp wird nicht in der Vorschau unterstützt', + fileNamePlaceholder: 'Dateiname.md', + folderNamePlaceholder: 'Ordnername' }, fr: { settings: 'Paramètres', @@ -346,6 +491,35 @@ export const translations = { editor: 'Éditeur', docs: 'Documents', docsManagement: 'Gestion des documents', - docsEmptyDesc: 'L\'interface de gestion des documents est en développement...' + docsEmptyDesc: 'L\'interface de gestion des documents est en développement...', + files: 'Fichiers', + noFiles: 'Aucun fichier', + newFile: 'Nouveau fichier', + newFolder: 'Nouveau dossier', + untitledFile: 'Sans titre.md', + untitledFolder: 'Nouveau dossier', + rename: 'Renommer', + delete: 'Supprimer', + copy: 'Copier', + cut: 'Couper', + paste: 'Coller', + confirmDelete: 'Confirmer la suppression', + confirmDeleteDesc: 'Êtes-vous sûr de vouloir supprimer', + confirmDeleteFolderDesc: 'Cela supprimera tout le contenu du dossier.', + confirmDeleteFileDesc: 'Cette action est irréversible.', + cancel: 'Annuler', + rootDir: 'Répertoire racine', + expandSidebar: 'Développer la barre latérale', + collapseSidebar: 'Réduire la barre latérale', + fileLimitReached: 'Nombre maximum de fichiers atteint', + folderLimitReached: 'Nombre maximum de dossiers atteint', + fileSizeLimit: 'La taille du fichier ne peut pas dépasser 50 Mo', + storageError: 'Espace de stockage insuffisant', + selectFileToView: 'Sélectionnez un fichier pour afficher le contenu', + folderContains: 'Contient', + items: 'éléments', + unsupportedPreview: 'Ce type de fichier n\'est pas pris en charge pour l\'aperçu', + fileNamePlaceholder: 'Nom du fichier.md', + folderNamePlaceholder: 'Nom du dossier' } } diff --git a/src/views/DocsView.vue b/src/views/DocsView.vue index 4361b72..3c3736c 100644 --- a/src/views/DocsView.vue +++ b/src/views/DocsView.vue @@ -1,40 +1,490 @@