diff --git a/src/App.vue b/src/App.vue index d0f06f24..da2ce8ac 100644 --- a/src/App.vue +++ b/src/App.vue @@ -106,7 +106,7 @@ watchEffect(() => { <template> <v-app class="text-noselect"> - <component v-for="dialog in dialogStore.dialogs" :is="dialog.component" v-bind="{ guid: dialog.guid, ...dialog.props }" /> + <component v-for="dialog in dialogStore.dialogs.values()" :is="dialog.component" v-bind="{ guid: dialog.guid, ...dialog.props }" /> <Navbar v-if="authStore.isAuthenticated" /> <v-main> <router-view /> diff --git a/src/components/DnDZone.vue b/src/components/DnDZone.vue index a5517013..6f71f6fe 100644 --- a/src/components/DnDZone.vue +++ b/src/components/DnDZone.vue @@ -36,7 +36,7 @@ function onDrop(files: File[] | null, event: DragEvent) { links.forEach(addTorrentStore.pushTorrentToQueue) if (!dialogStore.hasActiveDialog) { - dialogStore.createDialog(AddTorrentDialog, {}) + dialogStore.createDialog(AddTorrentDialog) } } diff --git a/src/components/Settings/TagsAndCategories.vue b/src/components/Settings/TagsAndCategories.vue index 023b6bee..a53224ba 100644 --- a/src/components/Settings/TagsAndCategories.vue +++ b/src/components/Settings/TagsAndCategories.vue @@ -3,14 +3,11 @@ import CategoryFormDialog from '@/components/Dialogs/CategoryFormDialog.vue' import TagFormDialog from '@/components/Dialogs/TagFormDialog.vue' import { useDialogStore, useMaindataStore } from '@/stores' import { Category } from '@/types/qbit/models' -import { onBeforeMount, ref, watch } from 'vue' +import { onBeforeMount } from 'vue' const dialogStore = useDialogStore() const maindataStore = useMaindataStore() -const tagDialog = ref('') -const categoryDialog = ref('') - async function deleteTag(tagName: string) { await maindataStore.deleteTags([tagName]) await maindataStore.fetchTags() @@ -22,35 +19,17 @@ async function deleteCategory(category: Category) { } function openTagFormDialog(initialTag?: string) { - tagDialog.value = dialogStore.createDialog(TagFormDialog, { initialTag }) + dialogStore.createDialog(TagFormDialog, { initialTag }, maindataStore.fetchTags) } function openCategoryFormDialog(initialCategory?: Category) { - categoryDialog.value = dialogStore.createDialog(CategoryFormDialog, { initialCategory }) + dialogStore.createDialog(CategoryFormDialog, { initialCategory }, maindataStore.fetchCategories) } onBeforeMount(async () => { await maindataStore.fetchCategories() await maindataStore.fetchTags() }) - -watch( - () => dialogStore.isDialogOpened(tagDialog.value), - value => { - if (!value) { - maindataStore.fetchTags() - } - } -) - -watch( - () => dialogStore.isDialogOpened(categoryDialog.value), - value => { - if (!value) { - maindataStore.fetchCategories() - } - } -) </script> <template> diff --git a/src/pages/MagnetHandler.vue b/src/pages/MagnetHandler.vue index d47455e8..0a6af71c 100644 --- a/src/pages/MagnetHandler.vue +++ b/src/pages/MagnetHandler.vue @@ -14,7 +14,7 @@ onBeforeMount(async () => { if (magnetLink.startsWith('magnet:')) { addTorrentStore.isFirstInit = false addTorrentStore.pushTorrentToQueue(magnetLink) - dialogStore.createDialog(AddTorrentDialog, {}) + dialogStore.createDialog(AddTorrentDialog) } await router.push({ name: 'dashboard' }) }) diff --git a/src/stores/content.ts b/src/stores/content.ts index 6c14415b..c323a3ee 100644 --- a/src/stores/content.ts +++ b/src/stores/content.ts @@ -8,7 +8,7 @@ import { TorrentFile } from '@/types/qbit/models' import { RightClickMenuEntryType, RightClickProperties, TreeFolder, TreeNode } from '@/types/vuetorrent' import { useIntervalFn } from '@vueuse/core' import { defineStore, storeToRefs } from 'pinia' -import { computed, nextTick, reactive, ref, toRaw, watch } from 'vue' +import { computed, nextTick, reactive, ref, toRaw } from 'vue' import { useI18n } from 'vue-i18n' import { useRoute } from 'vue-router' @@ -104,28 +104,20 @@ export const useContentStore = defineStore('content', () => { await nextTick() } - const renameDialog = ref('') - - const renamePayload = reactive({ - hash: '', - isFolder: false, - oldName: '' - }) - async function renameNode(node: TreeNode) { const { default: MoveTorrentFileDialog } = await import('@/components/Dialogs/MoveTorrentFileDialog.vue') - renamePayload.hash = hash.value - renamePayload.isFolder = node.type === 'folder' - renamePayload.oldName = node.fullName - renameDialog.value = dialogStore.createDialog(MoveTorrentFileDialog, renamePayload) + const payload = { + hash: hash.value, + isFolder: node.type === 'folder', + oldName: node.fullName + } + dialogStore.createDialog(MoveTorrentFileDialog, payload, updateFileTree) } async function bulkRename(node: TreeFolder) { const { default: BulkRenameFilesDialog } = await import('@/components/Dialogs/BulkRenameFilesDialog.vue') - renameDialog.value = dialogStore.createDialog(BulkRenameFilesDialog, { - hash: hash.value, - node - }) + const payload = { hash: hash.value, node } + dialogStore.createDialog(BulkRenameFilesDialog, payload, updateFileTree) } async function renameTorrentFile(hash: string, oldPath: string, newPath: string) { @@ -141,15 +133,6 @@ export const useContentStore = defineStore('content', () => { await updateFileTree() } - watch( - () => dialogStore.isDialogOpened(renameDialog.value), - async v => { - if (!v) { - await updateFileTree() - } - } - ) - return { rightClickProperties, internalSelection, diff --git a/src/stores/dialog.ts b/src/stores/dialog.ts index 5f2b517e..21884869 100644 --- a/src/stores/dialog.ts +++ b/src/stores/dialog.ts @@ -8,33 +8,38 @@ type DialogTemplate<C extends Component> = { component: C props: ComponentProps<C> guid: string + onClose?: () => any | Promise<any> } export const useDialogStore = defineStore('dialogs', () => { - const dialogs = shallowRef<DialogTemplate<any>[]>([]) + const dialogs = shallowRef<Map<string, DialogTemplate<any>>>(new Map()) - const hasActiveDialog = computed(() => dialogs.value.length > 0) + const hasActiveDialog = computed(() => dialogs.value.size > 0) function isDialogOpened(guid: string) { - return !!dialogs.value.find(dialog => dialog.guid === guid) + return dialogs.value.has(guid) } - function createDialog<C extends Component>(component: C, props?: Omit<ComponentProps<C>, 'guid'>) { + function createDialog<C extends Component>(component: C, props?: Omit<ComponentProps<C>, 'guid'>, onClose?: () => any | Promise<any>) { const guid = uuidv4() - const template = { + dialogs.value.set(guid, { component, props: props || {}, - guid - } - - dialogs.value.push(template) + guid, + onClose + }) triggerRef(dialogs) return guid } function deleteDialog(guid: string) { - dialogs.value = dialogs.value.filter(dialog => dialog.guid !== guid) + const template = dialogs.value.get(guid) + if (template && template.onClose) { + template.onClose() + } + dialogs.value.delete(guid) + triggerRef(dialogs) } return { @@ -44,7 +49,8 @@ export const useDialogStore = defineStore('dialogs', () => { createDialog, deleteDialog, $reset: () => { - dialogs.value = [] + dialogs.value.clear() + triggerRef(dialogs) } } }) diff --git a/src/stores/rss.ts b/src/stores/rss.ts index 9184a23f..26fc2f4c 100644 --- a/src/stores/rss.ts +++ b/src/stores/rss.ts @@ -66,7 +66,6 @@ export const useRssStore = defineStore( async function setFeedUrl(feedName: string, feedUrl: string) { await qbit.setFeedUrl(feedName, feedUrl).catch((error: AxiosError) => { - console.log(error) if (error.response?.status === 404) { toast.error(t('toast.qbit.not_supported', { version: '4.6.0' })) }