mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-06-30 12:01:37 +08:00
refactor: implement lazy-loaded tab components with silent background data refresh for settings pages
This commit is contained in:
@@ -8,10 +8,18 @@ import StorageCard from '@/components/cards/StorageCard.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useTheme } from 'vuetify'
|
||||
import { storageAttributes } from '@/api/constants'
|
||||
import { useSilentSettingRefresh } from '@/composables/useSilentSettingRefresh'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { global: globalTheme } = useTheme()
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 拖拽排序和分类编辑弹窗按需加载,避免设置框架预加载目录页时带上这些交互依赖。
|
||||
const Draggable = defineAsyncComponent(() => import('vuedraggable').then(module => module.default))
|
||||
const ProgressDialog = defineAsyncComponent(() => import('@/components/dialog/ProgressDialog.vue'))
|
||||
@@ -247,12 +255,17 @@ async function saveSystemSettings(value: any) {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPageData() {
|
||||
await Promise.all([loadDirectories(), loadStorages(), loadMediaCategories(), loadSystemSettings()])
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
onMounted(() => {
|
||||
loadDirectories()
|
||||
loadStorages()
|
||||
loadMediaCategories()
|
||||
loadSystemSettings()
|
||||
loadPageData()
|
||||
})
|
||||
|
||||
useSilentSettingRefresh(loadPageData, {
|
||||
active: computed(() => props.active),
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import NotificationChannelCard from '@/components/cards/NotificationChannelCard.
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { notificationSwitchDict } from '@/api/constants'
|
||||
import { useTheme, useDisplay } from 'vuetify'
|
||||
import { useSilentSettingRefresh } from '@/composables/useSilentSettingRefresh'
|
||||
|
||||
// 显示器宽度
|
||||
const display = useDisplay()
|
||||
@@ -13,6 +14,13 @@ const display = useDisplay()
|
||||
// 国际化
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 通知渠道排序和进度弹窗按需加载,避免通知设置 chunk 直接包含拖拽库。
|
||||
const Draggable = defineAsyncComponent(() => import('vuedraggable').then(module => module.default))
|
||||
const ProgressDialog = defineAsyncComponent(() => import('@/components/dialog/ProgressDialog.vue'))
|
||||
@@ -308,12 +316,22 @@ function getNotificationSwitchText(type: string | undefined) {
|
||||
return notificationSwitchDict[type]
|
||||
}
|
||||
|
||||
async function loadPageData() {
|
||||
await Promise.all([
|
||||
loadNotificationSetting(),
|
||||
loadNotificationSwitchs(),
|
||||
loadNotificationTime(),
|
||||
loadTemplateConfigs(),
|
||||
])
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
onMounted(() => {
|
||||
loadNotificationSetting()
|
||||
loadNotificationSwitchs()
|
||||
loadNotificationTime()
|
||||
loadTemplateConfigs()
|
||||
loadPageData()
|
||||
})
|
||||
|
||||
useSilentSettingRefresh(loadPageData, {
|
||||
active: computed(() => props.active && !editorVisible.value),
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -7,10 +7,18 @@ import { CustomRule, FilterRuleGroup } from '@/api/types'
|
||||
import CustomerRuleCard from '@/components/cards/CustomRuleCard.vue'
|
||||
import FilterRuleGroupCard from '@/components/cards/FilterRuleGroupCard.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useSilentSettingRefresh } from '@/composables/useSilentSettingRefresh'
|
||||
|
||||
// 国际化
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 拖拽库和导入弹窗只在规则编辑交互中需要,拆出设置页入口 chunk。
|
||||
const Draggable = defineAsyncComponent(() => import('vuedraggable').then(module => module.default))
|
||||
const ImportCodeDialog = defineAsyncComponent(() => import('@/components/dialog/ImportCodeDialog.vue'))
|
||||
@@ -365,12 +373,17 @@ async function saveTorrentPriority() {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPageData() {
|
||||
await Promise.all([loadMediaCategories(), queryCustomRules(), queryFilterRuleGroups(), queryTorrentPriority()])
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
onMounted(() => {
|
||||
loadMediaCategories()
|
||||
queryCustomRules()
|
||||
queryFilterRuleGroups()
|
||||
queryTorrentPriority()
|
||||
loadPageData()
|
||||
})
|
||||
|
||||
useSilentSettingRefresh(loadPageData, {
|
||||
active: computed(() => props.active),
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -3,10 +3,18 @@ import { useToast } from 'vue-toastification'
|
||||
import api from '@/api'
|
||||
import type { FilterRuleGroup, Site } from '@/api/types'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useSilentSettingRefresh } from '@/composables/useSilentSettingRefresh'
|
||||
|
||||
// 国际化
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 提示框
|
||||
const $toast = useToast()
|
||||
|
||||
@@ -176,12 +184,16 @@ async function loadSystemSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPageData() {
|
||||
await Promise.all([querySites(), queryFilterRuleGroups(), querySelectedSites(), loadSearchSetting(), loadSystemSettings()])
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
querySites()
|
||||
queryFilterRuleGroups()
|
||||
querySelectedSites()
|
||||
loadSearchSetting()
|
||||
loadSystemSettings()
|
||||
loadPageData()
|
||||
})
|
||||
|
||||
useSilentSettingRefresh(loadPageData, {
|
||||
active: computed(() => props.active),
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -3,10 +3,18 @@ import { useToast } from 'vue-toastification'
|
||||
import api from '@/api'
|
||||
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useSilentSettingRefresh } from '@/composables/useSilentSettingRefresh'
|
||||
|
||||
// 国际化
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 提示框
|
||||
const $toast = useToast()
|
||||
|
||||
@@ -122,6 +130,10 @@ async function saveSiteSetting(value: { [key: string]: any }) {
|
||||
onMounted(() => {
|
||||
loadSiteSettings()
|
||||
})
|
||||
|
||||
useSilentSettingRefresh(loadSiteSettings, {
|
||||
active: computed(() => props.active),
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -4,10 +4,18 @@ import api from '@/api'
|
||||
import type { FilterRuleGroup, Site } from '@/api/types'
|
||||
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useSilentSettingRefresh } from '@/composables/useSilentSettingRefresh'
|
||||
|
||||
// 国际化
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 提示框
|
||||
const $toast = useToast()
|
||||
|
||||
@@ -184,12 +192,22 @@ async function saveSubscribeSetting() {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadPageData() {
|
||||
await Promise.all([
|
||||
querySites(),
|
||||
queryFilterRuleGroups(),
|
||||
querySelectedRssSites(),
|
||||
querySubscribeRules(),
|
||||
loadSystemSettings(),
|
||||
])
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
querySites()
|
||||
queryFilterRuleGroups()
|
||||
querySelectedRssSites()
|
||||
querySubscribeRules()
|
||||
loadSystemSettings()
|
||||
loadPageData()
|
||||
})
|
||||
|
||||
useSilentSettingRefresh(loadPageData, {
|
||||
active: computed(() => props.active),
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { downloaderOptions, mediaServerOptions } from '@/api/constants'
|
||||
import { useDisplay, useTheme } from 'vuetify'
|
||||
import { useLlmProviderDirectory } from '@/composables/useLlmProviderDirectory'
|
||||
import { useSilentSettingRefresh } from '@/composables/useSilentSettingRefresh'
|
||||
|
||||
const display = useDisplay()
|
||||
const theme = useTheme()
|
||||
@@ -19,6 +20,13 @@ const isTransparentTheme = computed(() => theme.name.value === 'transparent')
|
||||
// 国际化
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
|
||||
// 下载器/媒体服务器排序和进度弹窗按需加载,降低系统设置页入口解析量。
|
||||
const Draggable = defineAsyncComponent(() => import('vuedraggable').then(module => module.default))
|
||||
const ProgressDialog = defineAsyncComponent(() => import('@/components/dialog/ProgressDialog.vue'))
|
||||
@@ -847,12 +855,11 @@ async function saveScrapingSwitchs() {
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
onMounted(() => {
|
||||
loadDownloaderSetting()
|
||||
loadMediaServerSetting()
|
||||
loadSystemSettings()
|
||||
loadScrapingSwitchs()
|
||||
})
|
||||
async function loadPageData() {
|
||||
await Promise.all([loadDownloaderSetting(), loadMediaServerSetting(), loadSystemSettings(), loadScrapingSwitchs()])
|
||||
}
|
||||
|
||||
onMounted(loadPageData)
|
||||
|
||||
onActivated(async () => {
|
||||
isRequest.value = true
|
||||
@@ -866,6 +873,16 @@ onBeforeUnmount(() => {
|
||||
invalidateLlmTestState()
|
||||
})
|
||||
|
||||
useSilentSettingRefresh(
|
||||
async () => {
|
||||
if (progressDialog.value || advancedDialog.value || testingLlm.value || savingBasic.value) return
|
||||
await loadPageData()
|
||||
},
|
||||
{
|
||||
active: computed(() => props.active),
|
||||
},
|
||||
)
|
||||
|
||||
watch(currentLlmSnapshotKey, (snapshotKey, previousSnapshotKey) => {
|
||||
if (snapshotKey !== previousSnapshotKey) invalidateLlmTestState()
|
||||
})
|
||||
|
||||
@@ -231,6 +231,10 @@ onMounted(getModules)
|
||||
.system-health-check {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 auto;
|
||||
block-size: 100%;
|
||||
min-block-size: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
@@ -316,6 +320,7 @@ onMounted(getModules)
|
||||
flex: 1;
|
||||
min-block-size: 0;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
padding-block: 0 16px;
|
||||
padding-inline: 16px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user