mirror of
https://github.com/VueTorrent/VueTorrent.git
synced 2025-03-14 12:10:18 +03:00
feat: Add optional backend handling (#1547)
This commit is contained in:
parent
4cbb45679c
commit
d513e097bf
21 changed files with 241 additions and 135 deletions
22
README.md
22
README.md
|
@ -2,8 +2,7 @@
|
|||
|
||||
The sleekest looking WebUI for qBittorrent made with Vue.js!
|
||||
|
||||
[](https://discord.gg/KDQP7fR467)
|
||||
[](https://github.com/VueTorrent/VueTorrent/wiki)
|
||||
[](https://discord.gg/KDQP7fR467)
|
||||
|
||||

|
||||
|
||||
|
@ -82,6 +81,9 @@ Checkout the [wiki](https://github.com/VueTorrent/VueTorrent/wiki/Installation)!
|
|||
- mobile friendly! (can be installed as a PWA)
|
||||
- Configureable Dashboard: choose which torrent properties are shown for both busy and completed torrents
|
||||
- Optimized for the latest version of qBittorrent
|
||||
- Additional backend for improved experience, [see the repo for more info](https://github.com/VueTorrent/vuetorrent-backend)
|
||||
- This is a work in progress, and is not required to use VueTorrent
|
||||
- Stores server-side settings
|
||||
|
||||
## Important Information
|
||||
|
||||
|
@ -91,10 +93,18 @@ Everything that is compatible with qBittorrent will work regardless of the WebUI
|
|||
|
||||
## Contributing
|
||||
|
||||
Refer to the [Contributing Guidelines](https://github.com/VueTorrent/VueTorrent/blob/master/.github/CONTRIBUTING.md)
|
||||
We gladly accept contributions!
|
||||
|
||||
Any help is appreciated, whether it's reporting bugs, suggesting enhancements, contributing code or localizing the app.
|
||||
|
||||
See the [Contributing Guidelines](https://github.com/VueTorrent/VueTorrent/blob/master/.github/CONTRIBUTING.md) for more information.
|
||||
|
||||
## Support
|
||||
|
||||
[](https://discord.gg/KDQP7fR467)
|
||||
[](https://github.com/VueTorrent/VueTorrent/wiki)
|
||||
[](https://github.com/VueTorrent/VueTorrent/wiki/FAQ)
|
||||
|
||||
Open up an issue 😛
|
||||
|
||||
but before you do that:
|
||||
|
@ -102,7 +112,11 @@ but before you do that:
|
|||
- confirm you're on the latest version of VueTorrent
|
||||
- confirm there is no other issue mentioning the same problem
|
||||
|
||||
<a href="https://www.buymeacoffee.com/wdaan"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=wdaan&button_colour=FFDD00&font_colour=000000&font_family=Arial&outline_colour=000000&coffee_colour=ffffff"></a>
|
||||
## Funding
|
||||
|
||||
All donations are appreciated but purely optional.
|
||||
|
||||
Checkout the sponsor section of the repository.
|
||||
|
||||
## Contributors
|
||||
|
||||
|
|
|
@ -16,3 +16,12 @@ services:
|
|||
ports:
|
||||
- '8080:8080'
|
||||
restart: unless-stopped
|
||||
|
||||
backend:
|
||||
image: ghcr.io/vuetorrent/vuetorrent-backend:latest
|
||||
container_name: vuetorrent-backend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- '8081:3000'
|
||||
volumes:
|
||||
- ./docker/backend:/app/data
|
||||
|
|
47
package-lock.json
generated
47
package-lock.json
generated
|
@ -21,7 +21,7 @@
|
|||
"dayjs": "^1.11.9",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"pinia": "^2.1.6",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"pinia-persistence-plugin": "^0.0.5",
|
||||
"pixi.js": "^8.1.0",
|
||||
"uuid": "^9.0.1",
|
||||
"vite-plugin-vuetify": "^2.0.3",
|
||||
|
@ -4058,47 +4058,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pinia-plugin-persist": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pinia-plugin-persist/-/pinia-plugin-persist-1.0.0.tgz",
|
||||
"integrity": "sha512-M4hBBd8fz/GgNmUPaaUsC29y1M09lqbXrMAHcusVoU8xlQi1TqgkWnnhvMikZwr7Le/hVyMx8KUcumGGrR6GVw==",
|
||||
"dependencies": {
|
||||
"vue-demi": "^0.12.1"
|
||||
},
|
||||
"node_modules/pinia-persistence-plugin": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/pinia-persistence-plugin/-/pinia-persistence-plugin-0.0.5.tgz",
|
||||
"integrity": "sha512-P+IRzlfn9WO17/Lb487bC4dwd4uUM9rxXyzVLbDDqGxfuUY5LK9pqX0FigFxLQZLViZliHPXBbnZhiBTyJqsPg==",
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0",
|
||||
"pinia": "^2.0.0",
|
||||
"vue": "^2.0.0 || >=3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pinia-plugin-persist/node_modules/vue-demi": {
|
||||
"version": "0.12.5",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz",
|
||||
"integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
}
|
||||
"pinia": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pinia/node_modules/vue-demi": {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"dayjs": "^1.11.9",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"pinia": "^2.1.6",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"pinia-persistence-plugin": "^0.0.5",
|
||||
"pixi.js": "^8.1.0",
|
||||
"uuid": "^9.0.1",
|
||||
"vite-plugin-vuetify": "^2.0.3",
|
||||
|
|
|
@ -4,9 +4,9 @@ import DnDZone from '@/components/DnDZone.vue'
|
|||
import Navbar from '@/components/Navbar/Navbar.vue'
|
||||
import { TitleOptions } from '@/constants/vuetorrent'
|
||||
import { formatPercent, formatSpeed } from '@/helpers'
|
||||
import { backend } from '@/services/backend'
|
||||
import { useAddTorrentStore, useAppStore, useAuthStore, useDialogStore, useLogStore, useMaindataStore, usePreferenceStore, useTorrentStore, useVueTorrentStore } from '@/stores'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
import { onBeforeMount, watch, watchEffect } from 'vue'
|
||||
|
||||
const addTorrentStore = useAddTorrentStore()
|
||||
|
@ -42,6 +42,8 @@ const blockContextMenu = () => {
|
|||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
backend.init(vuetorrentStore.backendUrl)
|
||||
backend.ping()
|
||||
vuetorrentStore.updateTheme()
|
||||
vuetorrentStore.setLanguage(language.value)
|
||||
checkAuthentication()
|
||||
|
|
|
@ -99,6 +99,10 @@ const checkNewVersion = async () => {
|
|||
toast.info(t('toast.new_version'))
|
||||
}
|
||||
|
||||
function openBackendHelp() {
|
||||
window.open('https://github.com/VueTorrent/vuetorrent-backend/wiki/Installation', '_blank', 'noreferrer')
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
appStore.fetchQbitVersion()
|
||||
})
|
||||
|
@ -166,7 +170,7 @@ onBeforeMount(() => {
|
|||
</v-row>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item>
|
||||
<v-list-item class="mt-3">
|
||||
<v-row>
|
||||
<v-col cols="12" md="4">
|
||||
<v-text-field v-model.number="vueTorrentStore.refreshInterval" type="number" hide-details suffix="ms" :label="t('settings.vuetorrent.general.refreshInterval')" />
|
||||
|
@ -177,9 +181,7 @@ onBeforeMount(() => {
|
|||
<v-col cols="12" md="4">
|
||||
<v-text-field v-model.number="historyStore.historySize" type="number" hide-details :label="t('settings.vuetorrent.general.historySize')" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<v-select v-model="vueTorrentStore.language" flat hide-details :items="LOCALES" :label="t('settings.vuetorrent.general.language')" />
|
||||
</v-col>
|
||||
|
@ -188,13 +190,12 @@ onBeforeMount(() => {
|
|||
v-model="paginationSize"
|
||||
:messages="paginationSizeMessages"
|
||||
flat
|
||||
hide-details
|
||||
:items="paginationSizes"
|
||||
:return-object="false"
|
||||
:label="t('settings.vuetorrent.general.paginationSize.label')" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" md="4">
|
||||
<v-select v-model="vueTorrentStore.uiTitleType" flat hide-details :items="titleOptionsList" :label="t('settings.vuetorrent.general.vueTorrentTitle')" />
|
||||
</v-col>
|
||||
|
@ -211,6 +212,14 @@ onBeforeMount(() => {
|
|||
<v-col cols="12" md="6">
|
||||
<v-text-field v-model="vueTorrentStore.dateFormat" :placeholder="defaultDateFormat" hint="using Dayjs" :label="t('settings.vuetorrent.general.dateFormat')" />
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12" md="6">
|
||||
<v-text-field v-model="vueTorrentStore.backendUrl"
|
||||
:label="t('settings.vuetorrent.general.backendUrl')"
|
||||
placeholder="https://YOUR-HOST:PORT/"
|
||||
append-inner-icon="mdi-help-circle"
|
||||
@click:appendInner="openBackendHelp" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-list-item>
|
||||
|
||||
|
|
|
@ -917,6 +917,7 @@
|
|||
"title": "Settings",
|
||||
"vuetorrent": {
|
||||
"general": {
|
||||
"backendUrl": "Backend URL",
|
||||
"canvasRefreshThreshold": "Piece count to disable canvas auto-refresh",
|
||||
"canvasRenderThreshold": "Piece count to disable canvas rendering",
|
||||
"check_new": "Check for new version",
|
||||
|
|
|
@ -14,7 +14,8 @@ import VTorrentCardList from '@/components/Settings/VueTorrent/TorrentCard/List.
|
|||
import VTorrentCardGrid from '@/components/Settings/VueTorrent/TorrentCard/Grid.vue'
|
||||
import VTorrentCardTable from '@/components/Settings/VueTorrent/TorrentCard/Table.vue'
|
||||
import WebUI from '@/components/Settings/WebUI.vue'
|
||||
import { useDialogStore, usePreferenceStore } from '@/stores'
|
||||
import { backend } from '@/services/backend'
|
||||
import { useDialogStore, usePreferenceStore, useVueTorrentStore } from '@/stores'
|
||||
import { onBeforeUnmount, onMounted, ref, watchEffect } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
@ -24,6 +25,7 @@ const router = useRouter()
|
|||
const { t } = useI18n()
|
||||
const dialogStore = useDialogStore()
|
||||
const preferenceStore = usePreferenceStore()
|
||||
const vuetorrentStore = useVueTorrentStore()
|
||||
|
||||
const tabs = [
|
||||
{ text: t('settings.tabs.vuetorrent.title'), value: 'vuetorrent' },
|
||||
|
@ -60,6 +62,10 @@ const saveSettings = async () => {
|
|||
toast.success(t('settings.saveSuccess'))
|
||||
await preferenceStore.fetchPreferences()
|
||||
|
||||
const oldInit = backend.isInitialized
|
||||
backend.init(vuetorrentStore.backendUrl)
|
||||
const newInit = backend.isInitialized
|
||||
|
||||
if (!preferenceStore.preferences!.alternative_webui_enabled) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
const registrations = await navigator.serviceWorker.getRegistrations()
|
||||
|
@ -70,7 +76,11 @@ const saveSettings = async () => {
|
|||
location.hash = ''
|
||||
location.reload()
|
||||
} else {
|
||||
goHome()
|
||||
if (!oldInit && newInit) {
|
||||
location.reload()
|
||||
} else {
|
||||
await backend.ping()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import { createPinia } from 'pinia'
|
||||
import piniaPersist from 'pinia-plugin-persist'
|
||||
import { persistencePlugin } from 'pinia-persistence-plugin'
|
||||
|
||||
const pinia = createPinia()
|
||||
pinia.use(piniaPersist)
|
||||
pinia.use(
|
||||
persistencePlugin({
|
||||
assertStorage: () => {},
|
||||
storeKeysPrefix: 'vuetorrent',
|
||||
persistenceDefault: false,
|
||||
ensureAsyncStorageUpdateOrder: true,
|
||||
debug: import.meta.env.DEV
|
||||
})
|
||||
)
|
||||
|
||||
export default pinia
|
||||
|
|
139
src/services/backend.ts
Normal file
139
src/services/backend.ts
Normal file
|
@ -0,0 +1,139 @@
|
|||
import i18n from '@/plugins/i18n'
|
||||
import { StorageLikeAsync } from '@vueuse/core'
|
||||
import axios, { AxiosInstance } from 'axios'
|
||||
import { toast } from 'vue3-toastify'
|
||||
|
||||
class BackendProvider {
|
||||
private axios: AxiosInstance
|
||||
private _isInitialized: boolean = false
|
||||
private up: boolean = true
|
||||
private pingPromise: Promise<boolean> | null = null
|
||||
|
||||
constructor() {
|
||||
this.axios = axios.create({
|
||||
withCredentials: true,
|
||||
headers: {
|
||||
put: { 'Content-Type': 'application/json' }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get isInitialized() {
|
||||
return this._isInitialized
|
||||
}
|
||||
|
||||
init(baseURL: string) {
|
||||
this.axios.defaults.baseURL = baseURL
|
||||
this._isInitialized = !!baseURL
|
||||
}
|
||||
|
||||
/**
|
||||
* Ping the backend to check if it's up
|
||||
* @returns true if backend is up, false otherwise
|
||||
*/
|
||||
async ping(): Promise<boolean> {
|
||||
if (!this._isInitialized) return false
|
||||
if (this.pingPromise) {
|
||||
return this.pingPromise
|
||||
}
|
||||
|
||||
this.pingPromise = this.axios
|
||||
.get('/ping')
|
||||
.then(
|
||||
res => res.data === 'pong',
|
||||
() => false
|
||||
)
|
||||
.then(ok => {
|
||||
this.up = ok
|
||||
this.pingPromise = null
|
||||
|
||||
if (!ok) {
|
||||
// @ts-expect-error: TS2589: Type instantiation is excessively deep and possibly infinite.
|
||||
toast.error(i18n.global.t('toast.backend_unreachable'), { delay: 1000, autoClose: 2500 })
|
||||
}
|
||||
|
||||
return ok
|
||||
})
|
||||
|
||||
return await this.pingPromise
|
||||
}
|
||||
|
||||
private async waitForPing() {
|
||||
if (this.pingPromise) {
|
||||
await this.pingPromise
|
||||
}
|
||||
}
|
||||
|
||||
shouldDiscardCalls() {
|
||||
return !this._isInitialized || !this.up
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all values
|
||||
*/
|
||||
async getAll(): Promise<Record<string, string>> {
|
||||
await this.waitForPing()
|
||||
if (this.shouldDiscardCalls()) return {}
|
||||
|
||||
return this.axios.get('/config').then(res => res.data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single value
|
||||
* @param key
|
||||
* @returns string or null if key doesn't exists
|
||||
*/
|
||||
async get(key: string): Promise<string | null> {
|
||||
await this.waitForPing()
|
||||
if (this.shouldDiscardCalls()) return null
|
||||
|
||||
return this.axios.get(`/config/${key}`).then(
|
||||
res => res.data[key],
|
||||
() => null
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value
|
||||
* @param key
|
||||
* @param value
|
||||
* @returns true if value was set, false otherwise
|
||||
*/
|
||||
async set(key: string, value: string): Promise<boolean> {
|
||||
await this.waitForPing()
|
||||
if (this.shouldDiscardCalls()) return false
|
||||
|
||||
return this.axios.put(`/config/${key}`, { value }).then(
|
||||
() => true,
|
||||
() => false
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a value
|
||||
* @param key
|
||||
* @returns true if value was deleted, false otherwise
|
||||
*/
|
||||
async del(key: string): Promise<boolean> {
|
||||
await this.waitForPing()
|
||||
if (this.shouldDiscardCalls()) return false
|
||||
|
||||
return this.axios.delete(`/config/${key}`).then(
|
||||
() => true,
|
||||
() => false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const backend = new BackendProvider()
|
||||
export const backendStorage: StorageLikeAsync = {
|
||||
async getItem(key) {
|
||||
return await backend.get(key)
|
||||
},
|
||||
async setItem(key, state) {
|
||||
await backend.set(key, state)
|
||||
},
|
||||
async removeItem(key) {
|
||||
await backend.del(key)
|
||||
}
|
||||
}
|
|
@ -87,14 +87,9 @@ export const useAddTorrentStore = defineStore(
|
|||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
storage: sessionStorage,
|
||||
key: 'vuetorrent_addTorrents'
|
||||
}
|
||||
]
|
||||
storageItems: [{ storage: sessionStorage }]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -132,15 +132,9 @@ export const useDashboardStore = defineStore(
|
|||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
storage: localStorage,
|
||||
key: 'vuetorrent_dashboard',
|
||||
paths: ['displayMode']
|
||||
}
|
||||
]
|
||||
storageItems: [{ storage: localStorage, includePaths: ['displayMode'] }]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -45,14 +45,9 @@ export const useHistoryStore = defineStore(
|
|||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
storage: localStorage,
|
||||
key: 'vuetorrent_history'
|
||||
}
|
||||
]
|
||||
storageItems: [{ storage: localStorage }]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useVueTorrentStore } from './vuetorrent'
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useVueTorrentStore } from './vuetorrent'
|
||||
|
||||
export const useNavbarStore = defineStore(
|
||||
'navbar',
|
||||
|
@ -45,14 +45,9 @@ export const useNavbarStore = defineStore(
|
|||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
storage: sessionStorage,
|
||||
key: 'vuetorrent_navbar'
|
||||
}
|
||||
]
|
||||
storageItems: [{ storage: sessionStorage }]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -26,14 +26,9 @@ export const usePreferenceStore = defineStore(
|
|||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
storage: sessionStorage,
|
||||
key: 'vuetorrent_preferences'
|
||||
}
|
||||
]
|
||||
storageItems: [{ storage: sessionStorage }]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -164,14 +164,9 @@ export const useRssStore = defineStore(
|
|||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
storage: sessionStorage,
|
||||
key: 'vuetorrent_rss'
|
||||
}
|
||||
]
|
||||
storageItems: [{ storage: sessionStorage }]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -90,14 +90,9 @@ export const useSearchEngineStore = defineStore(
|
|||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
storage: sessionStorage,
|
||||
key: 'vuetorrent_searchEngine'
|
||||
}
|
||||
]
|
||||
storageItems: [{ storage: sessionStorage }]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -187,27 +187,9 @@ export const useTorrentStore = defineStore(
|
|||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
storage: localStorage,
|
||||
key: 'vuetorrent_torrents',
|
||||
paths: [
|
||||
'isTextFilterActive',
|
||||
'textFilter',
|
||||
'isStatusFilterActive',
|
||||
'statusFilter',
|
||||
'isCategoryFilterActive',
|
||||
'categoryFilter',
|
||||
'isTagFilterActive',
|
||||
'tagFilter',
|
||||
'isTrackerFilterActive',
|
||||
'trackerFilter',
|
||||
'sortOptions'
|
||||
]
|
||||
}
|
||||
]
|
||||
storageItems: [{ storage: localStorage, excludePaths: ['torrents'] }]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { DashboardProperty, defaultDateFormat, PropertyData, propsData, propsMetadata, TitleOptions, TorrentProperty, VuetorrentTheme } from '@/constants/vuetorrent'
|
||||
import { Theme } from '@/plugins/vuetify'
|
||||
import { backendStorage } from '@/services/backend'
|
||||
import { useMediaQuery } from '@vueuse/core'
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
@ -10,6 +11,8 @@ import { useTheme } from 'vuetify'
|
|||
export const useVueTorrentStore = defineStore(
|
||||
'vuetorrent',
|
||||
() => {
|
||||
const backendUrl = ref('')
|
||||
|
||||
const language = ref('en')
|
||||
const vuetorrentTheme = ref<VuetorrentTheme>(VuetorrentTheme.SYSTEM)
|
||||
const showFreeSpace = ref(true)
|
||||
|
@ -215,6 +218,7 @@ export const useVueTorrentStore = defineStore(
|
|||
}
|
||||
|
||||
return {
|
||||
backendUrl,
|
||||
vuetorrentTheme,
|
||||
dateFormat,
|
||||
deleteWithFiles,
|
||||
|
@ -267,6 +271,7 @@ export const useVueTorrentStore = defineStore(
|
|||
toggleDoneGridProperty,
|
||||
toggleTableProperty,
|
||||
$reset: () => {
|
||||
backendUrl.value = ''
|
||||
language.value = 'en'
|
||||
vuetorrentTheme.value = VuetorrentTheme.SYSTEM
|
||||
showFreeSpace.value = true
|
||||
|
@ -305,13 +310,11 @@ export const useVueTorrentStore = defineStore(
|
|||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
strategies: [
|
||||
{
|
||||
storage: localStorage,
|
||||
key: 'vuetorrent_webuiSettings'
|
||||
}
|
||||
storageItems: [
|
||||
{ storage: localStorage, key: 'webuiSettings' },
|
||||
{ storage: backendStorage, key: 'webuiSettings', excludePaths: ['backendUrl']}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
"types": ["node", "vue3-toastify/global", "pinia-plugin-persist", "vitest/globals"]
|
||||
"types": ["node", "vue3-toastify/global", "vitest/globals"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
|
|
|
@ -21,7 +21,7 @@ export default defineConfig(({ mode }) => {
|
|||
output: {
|
||||
manualChunks: {
|
||||
// apexcharts: ['apexcharts', 'vue3-apexcharts'],
|
||||
vue: ['vue', 'vue-router', 'vue-i18n', 'vue3-toastify', 'vuedraggable', 'pinia', 'pinia-plugin-persist'],
|
||||
vue: ['vue', 'vue-router', 'vue-i18n', 'vue3-toastify', 'vuedraggable', 'pinia', 'pinia-persistence-plugin'],
|
||||
vuetify: ['vuetify']
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue