mirror of
https://github.com/VueTorrent/VueTorrent.git
synced 2025-03-31 13:54:34 +03:00
perf(AddTorrentDialog): persist form in sessionStorage (#1193)
This commit is contained in:
parent
fcffa6983f
commit
e59f6bf206
2 changed files with 91 additions and 117 deletions
|
@ -1,14 +1,12 @@
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
import { useDialog } from '@/composables'
|
import { useDialog } from '@/composables'
|
||||||
import { AppPreferences } from '@/constants/qbit'
|
import { AppPreferences } from '@/constants/qbit'
|
||||||
import { ContentLayout, StopCondition } from '@/constants/qbit/AppPreferences'
|
|
||||||
import { useMaindataStore } from '@/stores/maindata'
|
import { useMaindataStore } from '@/stores/maindata'
|
||||||
import { useNavbarStore } from '@/stores/navbar'
|
import { useNavbarStore } from '@/stores/navbar'
|
||||||
import { usePreferenceStore } from '@/stores/preferences'
|
import { usePreferenceStore } from '@/stores/preferences'
|
||||||
import { useVueTorrentStore } from '@/stores/vuetorrent'
|
import { useVueTorrentStore } from '@/stores/vuetorrent'
|
||||||
import { Category } from '@/types/qbit/models'
|
|
||||||
import { AddTorrentPayload } from '@/types/qbit/payloads'
|
import { AddTorrentPayload } from '@/types/qbit/payloads'
|
||||||
import { computed, onBeforeMount, reactive, ref } from 'vue'
|
import { computed, onBeforeMount, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
|
@ -28,18 +26,6 @@ const vueTorrentStore = useVueTorrentStore()
|
||||||
const fileOverflowDisplayLimit = 2
|
const fileOverflowDisplayLimit = 2
|
||||||
|
|
||||||
const isFormValid = computed(() => navbarStore.addTorrentDialogUrls.length > 0 || navbarStore.addTorrentDialogFiles.length > 0)
|
const isFormValid = computed(() => navbarStore.addTorrentDialogUrls.length > 0 || navbarStore.addTorrentDialogFiles.length > 0)
|
||||||
const formData = reactive({
|
|
||||||
autoTMM: false,
|
|
||||||
skipChecking: false,
|
|
||||||
sequentialDownload: false,
|
|
||||||
firstLastPiecePrio: false,
|
|
||||||
startNow: true,
|
|
||||||
contentLayout: ContentLayout.ORIGINAL,
|
|
||||||
stopCondition: StopCondition.NONE,
|
|
||||||
savepath: '',
|
|
||||||
category: null as Category | null,
|
|
||||||
tags: [] as string[]
|
|
||||||
})
|
|
||||||
const tagSearch = ref('')
|
const tagSearch = ref('')
|
||||||
const categorySearch = ref('')
|
const categorySearch = ref('')
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
|
@ -55,45 +41,29 @@ const stopConditionOptions = ref([
|
||||||
{ title: t('constants.stopCondition.filesChecked'), value: AppPreferences.StopCondition.FILES_CHECKED }
|
{ title: t('constants.stopCondition.filesChecked'), value: AppPreferences.StopCondition.FILES_CHECKED }
|
||||||
])
|
])
|
||||||
|
|
||||||
const resetForm = () => {
|
|
||||||
navbarStore.addTorrentDialogUrls = ''
|
|
||||||
navbarStore.addTorrentDialogFiles = []
|
|
||||||
|
|
||||||
formData.autoTMM = false
|
|
||||||
formData.skipChecking = false
|
|
||||||
formData.sequentialDownload = false
|
|
||||||
formData.firstLastPiecePrio = false
|
|
||||||
formData.startNow = true
|
|
||||||
formData.contentLayout = preferenceStore.preferences!.torrent_content_layout
|
|
||||||
formData.stopCondition = preferenceStore.preferences!.torrent_stop_condition
|
|
||||||
formData.savepath = preferenceStore.preferences!.save_path
|
|
||||||
formData.category = null
|
|
||||||
formData.tags = []
|
|
||||||
}
|
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
if (!isFormValid.value) return
|
if (!isFormValid.value) return
|
||||||
|
|
||||||
const params: AddTorrentPayload = {
|
const params: AddTorrentPayload = {
|
||||||
savepath: formData.savepath,
|
savepath: navbarStore.addTorrentDialogForm.savepath,
|
||||||
paused: !formData.startNow,
|
paused: !navbarStore.addTorrentDialogForm.startNow,
|
||||||
skip_checking: formData.skipChecking,
|
skip_checking: navbarStore.addTorrentDialogForm.skipChecking,
|
||||||
autoTMM: formData.autoTMM,
|
autoTMM: navbarStore.addTorrentDialogForm.autoTMM,
|
||||||
sequentialDownload: formData.sequentialDownload,
|
sequentialDownload: navbarStore.addTorrentDialogForm.sequentialDownload,
|
||||||
firstLastPiecePrio: formData.firstLastPiecePrio,
|
firstLastPiecePrio: navbarStore.addTorrentDialogForm.firstLastPiecePrio,
|
||||||
contentLayout: formData.contentLayout,
|
contentLayout: navbarStore.addTorrentDialogForm.contentLayout,
|
||||||
stopCondition: formData.stopCondition
|
stopCondition: navbarStore.addTorrentDialogForm.stopCondition
|
||||||
}
|
}
|
||||||
|
|
||||||
if (navbarStore.addTorrentDialogUrls.length > 0) params.urls = navbarStore.addTorrentDialogUrls
|
if (navbarStore.addTorrentDialogUrls.length > 0) params.urls = navbarStore.addTorrentDialogUrls
|
||||||
if (formData.category && formData.category.name) params.category = formData.category.name
|
if (navbarStore.addTorrentDialogForm.category && navbarStore.addTorrentDialogForm.category.name) params.category = navbarStore.addTorrentDialogForm.category.name
|
||||||
if (formData.tags.length > 0) params.tags = formData.tags.join(',')
|
if (navbarStore.addTorrentDialogForm.tags.length > 0) params.tags = navbarStore.addTorrentDialogForm.tags.join(',')
|
||||||
|
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
await maindataStore.addTorrents(params, navbarStore.addTorrentDialogFiles)
|
await maindataStore.addTorrents(params, navbarStore.addTorrentDialogFiles)
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
|
|
||||||
resetForm()
|
navbarStore.resetAddTorrentDialogForm()
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
const close = () => {
|
const close = () => {
|
||||||
|
@ -101,36 +71,28 @@ const close = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const onCategoryChanged = () => {
|
const onCategoryChanged = () => {
|
||||||
formData.savepath = formData.category && formData.category.savePath ? formData.category.savePath : preferenceStore.preferences!.save_path
|
navbarStore.addTorrentDialogForm.savepath = navbarStore.addTorrentDialogForm.category && navbarStore.addTorrentDialogForm.category.savePath ? navbarStore.addTorrentDialogForm.category.savePath : preferenceStore.preferences!.save_path
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
|
const promises = []
|
||||||
if (!preferenceStore.preferences) {
|
if (!preferenceStore.preferences) {
|
||||||
await preferenceStore.fetchPreferences()
|
promises.push(preferenceStore.fetchPreferences())
|
||||||
}
|
}
|
||||||
formData.autoTMM = preferenceStore.preferences!.auto_tmm_enabled
|
|
||||||
formData.startNow = !preferenceStore.preferences!.start_paused_enabled
|
|
||||||
formData.contentLayout = preferenceStore.preferences!.torrent_content_layout
|
|
||||||
formData.stopCondition = preferenceStore.preferences!.torrent_stop_condition
|
|
||||||
formData.savepath = preferenceStore.preferences!.save_path
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
|
||||||
if (maindataStore.categories.length < 1) {
|
if (maindataStore.categories.length < 1) {
|
||||||
await maindataStore.fetchCategories()
|
promises.push(maindataStore.fetchCategories())
|
||||||
}
|
}
|
||||||
if (maindataStore.tags.length < 1) {
|
if (maindataStore.tags.length < 1) {
|
||||||
await maindataStore.fetchTags()
|
promises.push(maindataStore.fetchTags())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Promise.all(promises)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-dialog
|
<v-dialog v-model="isOpened" :class="$vuetify.display.mobile ? '' : 'w-50'"
|
||||||
v-model="isOpened"
|
:fullscreen="$vuetify.display.mobile" :transition="openSuddenly ? 'none' : 'dialog-bottom-transition'">
|
||||||
:transition="openSuddenly ? 'none' : 'dialog-bottom-transition'"
|
|
||||||
:fullscreen="$vuetify.display.mobile"
|
|
||||||
:class="$vuetify.display.mobile ? '' : 'w-50'">
|
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title>
|
<v-card-title>
|
||||||
<v-toolbar color="transparent">
|
<v-toolbar color="transparent">
|
||||||
|
@ -142,30 +104,24 @@ onBeforeMount(async () => {
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-file-input
|
<v-file-input v-model="navbarStore.addTorrentDialogFiles" :label="t('dialogs.add.files')" :show-size="vueTorrentStore.useBinarySize ? 1024 : 1000"
|
||||||
v-model="navbarStore.addTorrentDialogFiles"
|
accept=".torrent" counter multiple
|
||||||
accept=".torrent"
|
persistent-clear persistent-hint prepend-icon="" variant="outlined">
|
||||||
counter
|
|
||||||
:show-size="vueTorrentStore.useBinarySize ? 1024 : 1000"
|
|
||||||
multiple
|
|
||||||
persistent-clear
|
|
||||||
persistent-hint
|
|
||||||
prepend-icon=""
|
|
||||||
variant="outlined"
|
|
||||||
:label="t('dialogs.add.files')">
|
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<v-icon color="accent">mdi-paperclip</v-icon>
|
<v-icon color="accent">mdi-paperclip</v-icon>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:selection="{ fileNames }">
|
<template v-slot:selection="{ fileNames }">
|
||||||
<template v-for="(filename, index) in fileNames">
|
<template v-for="(filename, index) in fileNames">
|
||||||
<v-chip v-if="index < fileOverflowDisplayLimit" color="accent" label size="small" class="mr-2">{{ filename }} </v-chip>
|
<v-chip v-if="index < fileOverflowDisplayLimit" class="mr-2" color="accent" label size="small">
|
||||||
|
{{ filename }}
|
||||||
|
</v-chip>
|
||||||
</template>
|
</template>
|
||||||
<span v-if="fileNames.length == fileOverflowDisplayLimit" class="text-overline text-grey-darken-2 ml-2">
|
<span v-if="fileNames.length == fileOverflowDisplayLimit" class="text-overline text-grey-darken-2 ml-2">
|
||||||
{{ t('dialogs.add.fileOverflow', fileNames.length - fileOverflowDisplayLimit) }}
|
{{ t('dialogs.add.fileOverflow', fileNames.length - fileOverflowDisplayLimit) }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</v-file-input>
|
</v-file-input>
|
||||||
<v-textarea v-model="navbarStore.addTorrentDialogUrls" clearable :label="t('dialogs.add.links')">
|
<v-textarea v-model="navbarStore.addTorrentDialogUrls" :label="t('dialogs.add.links')" clearable>
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<v-icon color="accent">mdi-link</v-icon>
|
<v-icon color="accent">mdi-link</v-icon>
|
||||||
</template>
|
</template>
|
||||||
|
@ -175,15 +131,9 @@ onBeforeMount(async () => {
|
||||||
|
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-combobox
|
<v-combobox v-model="navbarStore.addTorrentDialogForm.tags" v-model:search="tagSearch"
|
||||||
v-model="formData.tags"
|
:hide-no-data="false" :items="maindataStore.tags" :label="t('dialogs.add.tags')" chips clearable
|
||||||
v-model:search="tagSearch"
|
multiple>
|
||||||
:items="maindataStore.tags"
|
|
||||||
:hide-no-data="false"
|
|
||||||
clearable
|
|
||||||
chips
|
|
||||||
multiple
|
|
||||||
:label="t('dialogs.add.tags')">
|
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<v-icon color="accent">mdi-tag</v-icon>
|
<v-icon color="accent">mdi-tag</v-icon>
|
||||||
</template>
|
</template>
|
||||||
|
@ -198,17 +148,9 @@ onBeforeMount(async () => {
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</template>
|
</template>
|
||||||
</v-combobox>
|
</v-combobox>
|
||||||
<v-combobox
|
<v-combobox v-model="navbarStore.addTorrentDialogForm.category" v-model:search="categorySearch"
|
||||||
v-model="formData.category"
|
:hide-no-data="false" :items="maindataStore.categories" chips clearable
|
||||||
v-model:search="categorySearch"
|
item-title="name" label="Category" return-object @update:modelValue="onCategoryChanged">
|
||||||
:items="maindataStore.categories"
|
|
||||||
item-title="name"
|
|
||||||
return-object
|
|
||||||
:hide-no-data="false"
|
|
||||||
clearable
|
|
||||||
chips
|
|
||||||
label="Category"
|
|
||||||
@update:modelValue="onCategoryChanged">
|
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<v-icon color="accent">mdi-label</v-icon>
|
<v-icon color="accent">mdi-label</v-icon>
|
||||||
</template>
|
</template>
|
||||||
|
@ -228,7 +170,8 @@ onBeforeMount(async () => {
|
||||||
|
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-text-field v-model="formData.savepath" :disabled="formData.autoTMM" :label="t('dialogs.add.savePath')">
|
<v-text-field v-model="navbarStore.addTorrentDialogForm.savepath"
|
||||||
|
:disabled="navbarStore.addTorrentDialogForm.autoTMM" :label="t('dialogs.add.savePath')">
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<v-icon color="accent">mdi-folder</v-icon>
|
<v-icon color="accent">mdi-folder</v-icon>
|
||||||
</template>
|
</template>
|
||||||
|
@ -238,27 +181,17 @@ onBeforeMount(async () => {
|
||||||
|
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-select
|
<v-select v-model="navbarStore.addTorrentDialogForm.contentLayout" :items="contentLayoutOptions"
|
||||||
v-model="formData.contentLayout"
|
:label="t('constants.contentLayout.title')" color="accent" hide-details rounded="xl"
|
||||||
:items="contentLayoutOptions"
|
variant="solo-filled" />
|
||||||
hide-details
|
|
||||||
color="accent"
|
|
||||||
variant="solo-filled"
|
|
||||||
rounded="xl"
|
|
||||||
:label="t('constants.contentLayout.title')" />
|
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-select
|
<v-select v-model="navbarStore.addTorrentDialogForm.stopCondition" :items="stopConditionOptions"
|
||||||
v-model="formData.stopCondition"
|
:label="t('constants.stopCondition.title')" color="accent" hide-details rounded="xl"
|
||||||
:items="stopConditionOptions"
|
variant="solo-filled" />
|
||||||
hide-details
|
|
||||||
color="accent"
|
|
||||||
variant="solo-filled"
|
|
||||||
rounded="xl"
|
|
||||||
:label="t('constants.stopCondition.title')" />
|
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
|
@ -266,19 +199,24 @@ onBeforeMount(async () => {
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-checkbox v-model="formData.startNow" density="compact" hide-details :label="t('dialogs.add.startNow')" />
|
<v-checkbox v-model="navbarStore.addTorrentDialogForm.startNow" :label="t('dialogs.add.startNow')" density="compact"
|
||||||
|
hide-details />
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-checkbox v-model="formData.skipChecking" density="compact" hide-details :label="t('dialogs.add.skipChecking')" />
|
<v-checkbox v-model="navbarStore.addTorrentDialogForm.skipChecking" :label="t('dialogs.add.skipChecking')" density="compact"
|
||||||
|
hide-details />
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-checkbox v-model="formData.autoTMM" density="compact" hide-details :label="t('dialogs.add.autoTMM')" />
|
<v-checkbox v-model="navbarStore.addTorrentDialogForm.autoTMM" :label="t('dialogs.add.autoTMM')" density="compact"
|
||||||
|
hide-details />
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-checkbox v-model="formData.sequentialDownload" density="compact" hide-details :label="t('dialogs.add.sequentialDownload')" />
|
<v-checkbox v-model="navbarStore.addTorrentDialogForm.sequentialDownload" :label="t('dialogs.add.sequentialDownload')" density="compact"
|
||||||
|
hide-details />
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-checkbox v-model="formData.firstLastPiecePrio" density="compact" hide-details :label="t('dialogs.add.firstLastPiecePrio')" />
|
<v-checkbox v-model="navbarStore.addTorrentDialogForm.firstLastPiecePrio" :label="t('dialogs.add.firstLastPiecePrio')" density="compact"
|
||||||
|
hide-details />
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
|
@ -1,15 +1,33 @@
|
||||||
|
import { ContentLayout, StopCondition } from '@/constants/qbit/AppPreferences.ts'
|
||||||
|
import { usePreferenceStore } from '@/stores/preferences.ts'
|
||||||
|
import { Category } from '@/types/qbit/models'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, reactive, ref } from 'vue'
|
||||||
|
|
||||||
export const useNavbarStore = defineStore(
|
export const useNavbarStore = defineStore(
|
||||||
'navbar',
|
'navbar',
|
||||||
() => {
|
() => {
|
||||||
|
const preferenceStore = usePreferenceStore()
|
||||||
|
|
||||||
const downloadData = ref<number[]>(new Array(15).fill(0))
|
const downloadData = ref<number[]>(new Array(15).fill(0))
|
||||||
const uploadData = ref<number[]>(new Array(15).fill(0))
|
const uploadData = ref<number[]>(new Array(15).fill(0))
|
||||||
|
|
||||||
const addTorrentDialogFiles = ref<File[]>([])
|
const addTorrentDialogFiles = ref<File[]>([])
|
||||||
const addTorrentDialogUrls = ref('')
|
const addTorrentDialogUrls = ref('')
|
||||||
|
|
||||||
|
const addTorrentDialogForm = reactive({
|
||||||
|
autoTMM: false,
|
||||||
|
skipChecking: false,
|
||||||
|
sequentialDownload: false,
|
||||||
|
firstLastPiecePrio: false,
|
||||||
|
startNow: true,
|
||||||
|
contentLayout: ContentLayout.ORIGINAL,
|
||||||
|
stopCondition: StopCondition.NONE,
|
||||||
|
savepath: '',
|
||||||
|
category: null as Category | null,
|
||||||
|
tags: [] as string[]
|
||||||
|
})
|
||||||
|
|
||||||
const pendingTorrentsCount = computed(() => addTorrentDialogFiles.value.length + addTorrentDialogUrls.value.split('\n').filter(url => url.trim() !== '').length)
|
const pendingTorrentsCount = computed(() => addTorrentDialogFiles.value.length + addTorrentDialogUrls.value.split('\n').filter(url => url.trim() !== '').length)
|
||||||
|
|
||||||
function pushDownloadData(data: number) {
|
function pushDownloadData(data: number) {
|
||||||
|
@ -33,15 +51,33 @@ export const useNavbarStore = defineStore(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetAddTorrentDialogForm() {
|
||||||
|
addTorrentDialogUrls.value = ''
|
||||||
|
addTorrentDialogFiles.value = []
|
||||||
|
|
||||||
|
addTorrentDialogForm.autoTMM = preferenceStore.preferences!.auto_tmm_enabled
|
||||||
|
addTorrentDialogForm.skipChecking = false
|
||||||
|
addTorrentDialogForm.sequentialDownload = false
|
||||||
|
addTorrentDialogForm.firstLastPiecePrio = false
|
||||||
|
addTorrentDialogForm.startNow = !preferenceStore.preferences!.start_paused_enabled
|
||||||
|
addTorrentDialogForm.contentLayout = preferenceStore.preferences!.torrent_content_layout
|
||||||
|
addTorrentDialogForm.stopCondition = preferenceStore.preferences!.torrent_stop_condition
|
||||||
|
addTorrentDialogForm.savepath = preferenceStore.preferences!.save_path
|
||||||
|
addTorrentDialogForm.category = null
|
||||||
|
addTorrentDialogForm.tags = []
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
downloadData,
|
downloadData,
|
||||||
uploadData,
|
uploadData,
|
||||||
addTorrentDialogFiles,
|
addTorrentDialogFiles,
|
||||||
addTorrentDialogUrls,
|
addTorrentDialogUrls,
|
||||||
|
addTorrentDialogForm,
|
||||||
pendingTorrentsCount,
|
pendingTorrentsCount,
|
||||||
pushDownloadData,
|
pushDownloadData,
|
||||||
pushUploadData,
|
pushUploadData,
|
||||||
pushTorrentToQueue
|
pushTorrentToQueue,
|
||||||
|
resetAddTorrentDialogForm
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue