From a7ebcb59d95e03029f68ecee3632fdbe73eafa79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E4=B8=8E=E5=8E=9F?= Date: Wed, 10 Apr 2024 13:11:57 +0800 Subject: [PATCH] feat(TorrentDetail): add bulk renaming (#1624) --- src/components/Core/HistoryField.vue | 2 +- .../Dialogs/BulkRenameFilesDialog.vue | 390 ++++++++++++++++++ src/constants/vuetorrent/HistoryKey.ts | 4 +- src/locales/en.json | 16 + src/locales/zh-Hans.json | 16 + src/stores/content.ts | 16 +- 6 files changed, 436 insertions(+), 8 deletions(-) create mode 100644 src/components/Dialogs/BulkRenameFilesDialog.vue diff --git a/src/components/Core/HistoryField.vue b/src/components/Core/HistoryField.vue index 5361ef6a..8c4dcbfd 100644 --- a/src/components/Core/HistoryField.vue +++ b/src/components/Core/HistoryField.vue @@ -27,7 +27,7 @@ defineExpose({ diff --git a/src/components/Dialogs/BulkRenameFilesDialog.vue b/src/components/Dialogs/BulkRenameFilesDialog.vue new file mode 100644 index 00000000..5b1a9c8e --- /dev/null +++ b/src/components/Dialogs/BulkRenameFilesDialog.vue @@ -0,0 +1,390 @@ + + + + + diff --git a/src/constants/vuetorrent/HistoryKey.ts b/src/constants/vuetorrent/HistoryKey.ts index d1dc54e4..d690c743 100644 --- a/src/constants/vuetorrent/HistoryKey.ts +++ b/src/constants/vuetorrent/HistoryKey.ts @@ -1,5 +1,7 @@ export enum HistoryKey { COOKIE = 'cookie', SEARCH_ENGINE_QUERY = 'searchEngineQuery', - TORRENT_PATH = 'torrentPath' + TORRENT_PATH = 'torrentPath', + BULK_RENAME_REGEXP = 'bulkRenameRegexp', + BULK_RENAME_TARGET = 'bulkRenameTarget' } diff --git a/src/locales/en.json b/src/locales/en.json index 976db9c9..2f269ae3 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -360,6 +360,22 @@ "sameName": "New name must be different from old name", "title": "Rename Torrent" }, + "bulkRenameFiles": { + "title": "Bulk Rename", + "regexp": "Regular Expression", + "target": "Replacement Input", + "col_origin_name": "Original", + "col_result_name": "Result", + "run": "Run", + "success": "Rename Successful", + "duplicated": "Duplicate Filename", + "not_changed": "Filename Not Changed", + "fold": "Collapse", + "unfold": "Expand", + "notForFolder": "Folder Renaming Not Supported", + "select_regex_flags": "Select Regular Expression Flags", + "nothing_to_do": "No tasks to do" + }, "rss": { "feed": { "name": "Name", diff --git a/src/locales/zh-Hans.json b/src/locales/zh-Hans.json index 7ab29bfc..f9db6c26 100644 --- a/src/locales/zh-Hans.json +++ b/src/locales/zh-Hans.json @@ -354,6 +354,22 @@ "sameName": "新名称必须与旧名称不同", "title": "重命名种子" }, + "bulkRenameFiles": { + "title": "批量重命名", + "regexp": "正则表达式", + "target": "替换输入", + "col_origin_name": "原始", + "col_result_name": "结果", + "run": "执行", + "success": "重命名成功", + "duplicated": "文件名重复", + "not_changed": "文件名未修改", + "fold": "收起", + "unfold": "展开", + "notForFolder": "不支持修改文件夹名", + "select_regex_flags": "选择正则表达式Flags", + "nothing_to_do": "无任务可做" + }, "rss": { "feed": { "name": "名称", diff --git a/src/stores/content.ts b/src/stores/content.ts index 42cc4ed7..70e8e9d5 100644 --- a/src/stores/content.ts +++ b/src/stores/content.ts @@ -5,10 +5,10 @@ import { useDialogStore } from '@/stores/dialog' import { useMaindataStore } from '@/stores/maindata' import { useVueTorrentStore } from '@/stores/vuetorrent' import { TorrentFile } from '@/types/qbit/models' -import { RightClickMenuEntryType, RightClickProperties, TreeNode } from '@/types/vuetorrent' +import { RightClickMenuEntryType, RightClickProperties, TreeFolder, TreeNode } from '@/types/vuetorrent' import { useIntervalFn } from '@vueuse/core' import { defineStore, storeToRefs } from 'pinia' -import { computed, nextTick, reactive, ref, watch } from 'vue' +import { computed, nextTick, reactive, ref, toRaw, watch } from 'vue' import { useI18n } from 'vue-i18n' import { useRoute } from 'vue-router' @@ -67,8 +67,8 @@ export const useContentStore = defineStore('content', () => { { text: t(`torrentDetail.content.rename.bulk`), icon: 'mdi-rename', - hidden: true, // internalSelection.value.size <= 1 - action: bulkRename + hidden: internalSelection.value.size !== 1 || (selectedNode.value?.type || 'file') === 'file', + action: () => bulkRename(toRaw(selectedNode.value!) as TreeFolder) }, { text: t(`torrentDetail.content.rename.${selectedNode.value?.type || 'file'}`), @@ -120,8 +120,12 @@ export const useContentStore = defineStore('content', () => { renameDialog.value = dialogStore.createDialog(MoveTorrentFileDialog, renamePayload) } - async function bulkRename() { - //TODO + async function bulkRename(node: TreeFolder) { + const { default: BulkRenameFilesDialog } = await import('@/components/Dialogs/BulkRenameFilesDialog.vue') + renameDialog.value = dialogStore.createDialog(BulkRenameFilesDialog, { + hash: hash.value, + node + }) } async function renameTorrentFile(hash: string, oldPath: string, newPath: string) {