From c4f54dcddc3158abaf3cbaeb359fa184fc668507 Mon Sep 17 00:00:00 2001 From: madrays Date: Sun, 30 Mar 2025 17:25:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=90=9C=E7=B4=A2=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E5=8D=A1=E7=89=87=E8=A7=86=E5=9B=BE=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E5=8F=AF=E8=A7=86=E6=80=A7=EF=BC=8C=E4=BC=98=E5=8C=96=E5=AD=A3?= =?UTF-8?q?=E9=9B=86=E6=98=BE=E7=A4=BA=E4=BD=8D=E7=BD=AE=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E6=9E=84nodatafound=E6=83=85=E5=BD=A2ui=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E6=96=87=E4=BB=B6=E7=AE=A1=E7=90=86=E5=99=A8ui?= =?UTF-8?q?=E5=B9=B6=E5=A2=9E=E5=8A=A0=E6=96=87=E4=BB=B6=E6=A0=91=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E4=BC=98=E5=8C=96=E4=BE=A7=E8=BE=B9=E6=A0=8F?= =?UTF-8?q?=E9=AB=98=E5=BA=A6=E8=A7=84=E9=81=BF=E7=AB=96=E5=90=91=E6=BB=91?= =?UTF-8?q?=E5=8A=A8=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@layouts/components/VerticalNav.vue | 24 +- src/@layouts/components/VerticalNavLayout.vue | 2 +- src/@layouts/components/VerticalNavLink.vue | 66 ++- .../components/VerticalNavSectionTitle.vue | 20 +- src/components/FileBrowser.vue | 175 ++++++- src/components/NoDataFound.vue | 254 +++++++-- src/components/cards/TorrentCard.vue | 21 +- src/components/cards/TorrentItem.vue | 80 +-- src/components/filebrowser/FileList.vue | 463 ++++++++++++----- src/components/filebrowser/FileNavigator.vue | 491 ++++++++++++++++++ src/components/filebrowser/FileToolbar.vue | 341 +++++++++--- src/views/reorganize/FileBrowserView.vue | 9 +- src/views/torrent/TorrentCardListView.vue | 12 + src/views/torrent/TorrentRowListView.vue | 12 + 14 files changed, 1627 insertions(+), 343 deletions(-) create mode 100644 src/components/filebrowser/FileNavigator.vue diff --git a/src/@layouts/components/VerticalNav.vue b/src/@layouts/components/VerticalNav.vue index c7ccc76a..762ad98c 100644 --- a/src/@layouts/components/VerticalNav.vue +++ b/src/@layouts/components/VerticalNav.vue @@ -117,13 +117,23 @@ function handleNavScroll(evt: Event) { } .nav-items { + overflow-x: hidden; + overflow-y: auto; block-size: 100%; - - // ℹ️ We no loner needs this overflow styles as perfect scrollbar applies it - // overflow-x: hidden; - - // // ℹ️ We used `overflow-y` instead of `overflow` to mitigate overflow x. Revert back if any issue found. - // overflow-y: auto; + display: flex; + flex-direction: column; + padding: 0 0 16px 0; + + /* 完全隐藏滚动条 */ + &::-webkit-scrollbar { + display: none; + } + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE and Edge */ + + > li { + margin-block-end: 2px; + } } .nav-item-title { @@ -151,4 +161,4 @@ function handleNavScroll(evt: Event) { } } } - + \ No newline at end of file diff --git a/src/@layouts/components/VerticalNavLayout.vue b/src/@layouts/components/VerticalNavLayout.vue index 070a2df2..6d6c8ce3 100644 --- a/src/@layouts/components/VerticalNavLayout.vue +++ b/src/@layouts/components/VerticalNavLayout.vue @@ -206,4 +206,4 @@ export default defineComponent({ width: 100%; } } - + \ No newline at end of file diff --git a/src/@layouts/components/VerticalNavLink.vue b/src/@layouts/components/VerticalNavLink.vue index b45ab283..7113052c 100644 --- a/src/@layouts/components/VerticalNavLink.vue +++ b/src/@layouts/components/VerticalNavLink.vue @@ -1,7 +1,8 @@ @@ -15,12 +16,14 @@ defineProps<{ :is="item.to ? 'RouterLink' : 'a'" :to="item.to" :href="item.href" + class="link-wrapper" > - {{ item.title }} @@ -30,13 +33,54 @@ defineProps<{ + \ No newline at end of file diff --git a/src/@layouts/components/VerticalNavSectionTitle.vue b/src/@layouts/components/VerticalNavSectionTitle.vue index 61716773..39c6959f 100644 --- a/src/@layouts/components/VerticalNavSectionTitle.vue +++ b/src/@layouts/components/VerticalNavSectionTitle.vue @@ -8,22 +8,22 @@ defineProps<{ diff --git a/src/components/FileBrowser.vue b/src/components/FileBrowser.vue index 7ed0ade9..0a2bf87a 100644 --- a/src/components/FileBrowser.vue +++ b/src/components/FileBrowser.vue @@ -2,6 +2,7 @@ import type { Axios } from 'axios' import FileList from './filebrowser/FileList.vue' import FileToolbar from './filebrowser/FileToolbar.vue' +import FileNavigator from './filebrowser/FileNavigator.vue' import type { EndPoints, FileItem, StorageConf } from '@/api/types' import { storageOptions } from '@/api/constants' @@ -144,21 +145,82 @@ async function storageChanged(storage: string) { emit('pathchanged', { storage: storage, path: '/', fileid: 'root' }) } +// 文件列表 +const fileListItems = ref([]) + // 路径变化 function pathChanged(item: FileItem) { emit('pathchanged', item) } +// 文件列表数据更新 +function fileListUpdated(items: FileItem[]) { + fileListItems.value = items +} + // 排序变化 function sortChanged(s: string) { sort.value = s refreshPending.value = true } + +// 刷新浏览器 +function refreshBrowser() { + refreshPending.value = true +} + + diff --git a/src/components/NoDataFound.vue b/src/components/NoDataFound.vue index 483db36d..41bf211e 100644 --- a/src/components/NoDataFound.vue +++ b/src/components/NoDataFound.vue @@ -1,67 +1,239 @@ diff --git a/src/components/cards/TorrentCard.vue b/src/components/cards/TorrentCard.vue index 52d35d44..1baee669 100644 --- a/src/components/cards/TorrentCard.vue +++ b/src/components/cards/TorrentCard.vue @@ -126,7 +126,6 @@ onMounted(() => {

{{ media?.title ?? meta?.name }} - {{ meta?.season_episode }}

@@ -136,6 +135,7 @@ onMounted(() => { {{ torrent?.site_name?.substring(0, 1) }} {{ torrent?.site_name }} + {{ meta?.season_episode }}
@@ -232,6 +232,7 @@ onMounted(() => { /> {{ item.torrent_info?.site_name?.substring(0, 1) }} {{ item.torrent_info.site_name }} + {{ item.meta_info.season_episode }} { .season-tag { font-size: 0.875rem; - background-color: rgba(var(--v-theme-primary), 0.08); - color: rgb(var(--v-theme-primary)); - padding: 2px 8px; + background-color: #5c6bc0; + color: white; + padding: 2px 6px; border-radius: 4px; margin-left: 8px; font-weight: 600; + display: inline-flex; + align-items: center; + justify-content: center; + z-index: 2; } .site-info { @@ -362,6 +367,7 @@ onMounted(() => { justify-content: space-between; align-items: center; margin-bottom: 12px; + flex-wrap: wrap; } .site-icon { @@ -562,6 +568,13 @@ onMounted(() => { font-weight: 600; } +.source-season-tag { + font-size: 0.75rem; + padding: 1px 4px; + margin-left: 4px; + background-color: #5c6bc0; +} + .source-discount { font-weight: 700; font-size: 0.8rem; diff --git a/src/components/cards/TorrentItem.vue b/src/components/cards/TorrentItem.vue index 6efd4665..2aaeb366 100644 --- a/src/components/cards/TorrentItem.vue +++ b/src/components/cards/TorrentItem.vue @@ -154,6 +154,7 @@ onMounted(() => { {{ torrent?.site_name?.substring(0, 1) }}
{{ torrent?.site_name }}
+ {{ meta?.season_episode }} {
{{ media?.title ?? meta?.name }} - {{ meta?.season_episode }}
@@ -255,44 +255,52 @@ onMounted(() => { } .site-wrapper { - position: relative; display: flex; - flex-direction: column; align-items: center; - width: 50px; - margin-right: 16px; + min-width: 140px; + flex-wrap: wrap; } .site-icon { - width: 32px; - height: 32px; - border-radius: 2px; - margin-bottom: 4px; + width: 24px; + height: 24px; + border-radius: 4px; + margin-right: 8px; } .site-fallback { - width: 32px; - height: 32px; - display: inline-flex; + width: 24px; + height: 24px; + display: flex; align-items: center; justify-content: center; - font-size: 1rem; + border-radius: 4px; + background-color: rgba(var(--v-theme-primary), 0.1); + color: rgb(var(--v-theme-primary)); font-weight: 700; - color: rgba(var(--v-theme-on-surface), 0.8); - background-color: rgba(var(--v-theme-on-surface), 0.1); - border-radius: 2px; - margin-bottom: 4px; + margin-right: 8px; + font-size: 0.8rem; } .site-name { - font-size: 0.8rem; + margin-right: 8px; font-weight: 600; - color: rgba(var(--v-theme-on-surface), 0.85); - text-align: center; - max-width: 100%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + color: rgba(var(--v-theme-on-surface), 0.8); + font-size: 0.9rem; +} + +.season-tag { + font-size: 0.875rem; + background-color: #5c6bc0; + color: white; + padding: 2px 6px; + border-radius: 4px; + margin-right: 8px; + font-weight: 600; + display: inline-flex; + align-items: center; + justify-content: center; + z-index: 2; } .free-tag { @@ -347,16 +355,6 @@ onMounted(() => { color: rgba(var(--v-theme-on-surface), 0.87); } -.season-tag { - font-size: 0.9rem; - background-color: rgba(var(--v-theme-primary), 0.08); - color: rgb(var(--v-theme-primary)); - padding: 2px 8px; - border-radius: 4px; - margin-left: 4px; - font-weight: 600; -} - .item-actions { display: flex; flex-direction: column; @@ -501,10 +499,22 @@ onMounted(() => { } .site-wrapper { - width: 40px; + min-width: 100px; + flex-wrap: wrap; margin-right: 10px; } + .site-name { + font-size: 0.8rem; + margin-right: 4px; + } + + .season-tag { + font-size: 0.75rem; + padding: 1px 4px; + margin-right: 4px; + } + .resource-tag { font-size: 0.75rem; padding: 2px 6px; diff --git a/src/components/filebrowser/FileList.vue b/src/components/filebrowser/FileList.vue index b7980749..4787507d 100644 --- a/src/components/filebrowser/FileList.vue +++ b/src/components/filebrowser/FileList.vue @@ -35,7 +35,7 @@ const inProps = defineProps({ }) // 对外事件 -const emit = defineEmits(['loading', 'pathchanged', 'refreshed', 'filedeleted', 'renamed']) +const emit = defineEmits(['loading', 'pathchanged', 'refreshed', 'filedeleted', 'renamed', 'items-updated']) // 确认框 const createConfirm = useConfirm() @@ -125,6 +125,11 @@ const isImage = computed(() => { return ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'].includes(ext ?? '') }) +// 创建一个计算属性用于设置虚拟滚动的高度 +const fileListStyle = computed(() => { + return 'height: 100%'; +}) + // 调整选择模式 function changeSelectMode() { selectMode.value = !selectMode.value @@ -149,6 +154,9 @@ async function list_files() { items.value = (await inProps.axios.request(config)) ?? [] emit('loading', false) loading.value = false + + // 通知父组件文件列表更新 + emit('items-updated', items.value) } // 删除项目 @@ -539,8 +547,8 @@ onMounted(() => {