From f01971ee3a05203e75ac718e86cc4d472021aa7f Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 17 May 2026 11:01:47 +0800 Subject: [PATCH] refactor: migrate page-specific action buttons to dynamic FABs for PWA mode compatibility --- src/locales/en-US.ts | 4 +- src/locales/zh-CN.ts | 4 +- src/locales/zh-TW.ts | 4 +- src/pages/recommend.vue | 38 +++++++++---- src/pages/resource.vue | 120 +++++++++++----------------------------- 5 files changed, 63 insertions(+), 107 deletions(-) diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts index 5091dbee..5af9f6ca 100644 --- a/src/locales/en-US.ts +++ b/src/locales/en-US.ts @@ -1031,7 +1031,7 @@ export default { doubanGlobalTVRankings: 'Douban Global TV Rankings', noCategoryContent: 'No content to display in current category', configureContent: 'Configure Display Content', - customizeContent: 'Customize Content', + customizeContent: 'Customize Recommendations', selectContentToDisplay: 'Select content you want to display on the page', selectAll: 'Select All', selectNone: 'Select None', @@ -2959,7 +2959,7 @@ export default { }, transferHistory: { title: 'Transfer History', - searchPlaceholder: 'Search transfer records', + searchPlaceholder: 'Search (supports * ? wildcards)', titleColumn: 'Title', pathColumn: 'Path', modeColumn: 'Mode', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 1d0eaa1b..20338cbc 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -1025,7 +1025,7 @@ export default { doubanGlobalTVRankings: '豆瓣全球剧集榜', noCategoryContent: '当前分类下没有可显示的内容', configureContent: '设置显示内容', - customizeContent: '自定义内容', + customizeContent: '自定义推荐', selectContentToDisplay: '选择您想在页面显示的内容', selectAll: '全选', selectNone: '全不选', @@ -2904,7 +2904,7 @@ export default { }, transferHistory: { title: '转移历史', - searchPlaceholder: '搜索转移记录', + searchPlaceholder: '搜索(支持 * ? 通配符)', titleColumn: '标题', pathColumn: '路径', modeColumn: '转移方式', diff --git a/src/locales/zh-TW.ts b/src/locales/zh-TW.ts index 0a57712b..5d441fea 100644 --- a/src/locales/zh-TW.ts +++ b/src/locales/zh-TW.ts @@ -1026,7 +1026,7 @@ export default { doubanGlobalTVRankings: '豆瓣全球劇集榜', noCategoryContent: '當前分類下沒有可顯示的內容', configureContent: '設置顯示內容', - customizeContent: '自定義內容', + customizeContent: '自定義推薦', selectContentToDisplay: '選擇您想在頁面顯示的內容', selectAll: '全選', selectNone: '全不選', @@ -2906,7 +2906,7 @@ export default { }, transferHistory: { title: '轉移歷史', - searchPlaceholder: '搜索轉移記錄', + searchPlaceholder: '搜索(支援 * ? 萬用字元)', titleColumn: '標題', pathColumn: '路徑', modeColumn: '轉移方式', diff --git a/src/pages/recommend.vue b/src/pages/recommend.vue index 45e04032..c9a3d32a 100644 --- a/src/pages/recommend.vue +++ b/src/pages/recommend.vue @@ -5,9 +5,12 @@ import MediaCardSlideView from '@/views/discover/MediaCardSlideView.vue' import { useI18n } from 'vue-i18n' import { useDisplay } from 'vuetify' import { useDynamicHeaderTab } from '@/composables/useDynamicHeaderTab' +import { useDynamicButton } from '@/composables/useDynamicButton' +import { usePWA } from '@/composables/usePWA' import { getItemColor, initializeItemColors } from '@/utils/colorUtils' const display = useDisplay() +const { appMode } = usePWA() // 国际化 const { t } = useI18n() @@ -21,6 +24,10 @@ const currentCategory = ref(t('recommend.all')) // 使用动态标签页 const { registerHeaderTab } = useDynamicHeaderTab() +function openRecommendSettings() { + dialog.value = true +} + const viewList = reactive<{ apipath: string; linkurl: string; title: string; type: string }[]>([ { apipath: 'recommend/tmdb_trending', @@ -218,17 +225,12 @@ const categoryItems = computed(() => [ registerHeaderTab({ items: categoryItems, modelValue: currentCategory, - appendButtons: [ - { - icon: 'mdi-tune', - variant: 'text', - color: 'grey', - class: 'settings-icon-button', - action: () => { - dialog.value = true - }, - }, - ], +}) + +useDynamicButton({ + icon: 'mdi-tune', + onClick: openRecommendSettings, + show: computed(() => appMode.value), }) // 页面是否准备就绪 @@ -346,7 +348,19 @@ onActivated(async () => { - +
+ +
+
+ + + diff --git a/src/pages/resource.vue b/src/pages/resource.vue index 3a1f4e9c..8d30329f 100644 --- a/src/pages/resource.vue +++ b/src/pages/resource.vue @@ -11,11 +11,15 @@ import TorrentFilterBar from '@/components/filter/TorrentFilterBar.vue' import { useI18n } from 'vue-i18n' import { useGlobalSettingsStore } from '@/stores/global' import { useTorrentFilter, type FilterState } from '@/composables/useTorrentFilter' +import { useDynamicButton } from '@/composables/useDynamicButton' +import { usePWA } from '@/composables/usePWA' import { useToast } from 'vue-toastification' // 国际化 const { t } = useI18n() +const { appMode } = usePWA() + // 提示框 const toast = useToast() @@ -225,6 +229,19 @@ const filteredCardDataList = ref>([]) // 是否刷新过 const isRefreshed = ref(false) +const viewToggleIcon = computed(() => (viewType.value === 'card' ? 'mdi-view-list-outline' : 'mdi-view-grid-outline')) + +// 搜索结果视图切换收纳到页面动态按钮中,和仪表盘的设置按钮保持一致。 +function toggleViewType() { + changeViewType(viewType.value === 'card' ? 'row' : 'card') +} + +useDynamicButton({ + icon: viewToggleIcon, + onClick: toggleViewType, + show: computed(() => appMode.value && isRefreshed.value), +}) + // 是否正在重新搜索 const isRefreshing = ref(false) @@ -1211,18 +1228,6 @@ onUnmounted(() => { - -
-
-
- - -
-
@@ -1328,9 +1333,22 @@ onUnmounted(() => { + + +
+ +
+
+ - + @@ -1465,58 +1483,6 @@ onUnmounted(() => { font-size: 0.75rem; } -/* 重新设计的视图切换按钮 */ -.view-toggle-container { - position: relative; -} - -.view-toggle-buttons { - position: relative; - display: flex; - padding: 4px; - border-radius: 8px; - background-color: rgba(var(--v-theme-surface-variant), 0.1); - isolation: isolate; /* Create new stacking context */ -} - -.active-indicator { - position: absolute; - z-index: 1; - border-radius: 6px; - background-color: rgb(var(--v-theme-surface)); - block-size: 36px; - box-shadow: - 0 1px 3px rgba(0, 0, 0, 12%), - 0 1px 2px rgba(0, 0, 0, 24%); - inline-size: 40px; - inset-block-start: 4px; - inset-inline-start: 4px; - transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); -} - -.active-indicator.row { - transform: translateX(40px); -} - -.view-toggle-btn { - position: relative; - z-index: 2; /* Sit on top of indicator */ - display: flex; - align-items: center; - justify-content: center; - border: none; - background: transparent; - block-size: 36px; - cursor: pointer; - inline-size: 40px; - transition: all 0.2s ease; -} - -.view-toggle-btn:hover:not(.active) { - border-radius: 6px; - background-color: rgba(var(--v-theme-primary), 0.05); -} - /* 重新搜索按钮 */ .refresh-search-btn { border-radius: 8px !important; @@ -1690,30 +1656,6 @@ onUnmounted(() => { grid-template-columns: 1fr; } - .view-toggle-container { - flex-shrink: 0; - } - - .view-toggle-buttons { - padding: 2px; - } - - .active-indicator { - block-size: 32px; - inline-size: 36px; - inset-block-start: 2px; - inset-inline-start: 2px; - } - - .active-indicator.row { - transform: translateX(36px); - } - - .view-toggle-btn { - block-size: 32px; - inline-size: 36px; - } - .refresh-search-btn { block-size: 36px !important; inline-size: 36px !important;