diff --git a/src/composables/useDashboardMediaGridCapacity.ts b/src/composables/useDashboardMediaGridCapacity.ts index 4c8bb5db..910e6531 100644 --- a/src/composables/useDashboardMediaGridCapacity.ts +++ b/src/composables/useDashboardMediaGridCapacity.ts @@ -1,4 +1,16 @@ -import { computed, nextTick, onActivated, onMounted, onUnmounted, ref, watch, type ComputedRef, type Ref } from 'vue' +import { + computed, + nextTick, + onActivated, + onMounted, + onUnmounted, + ref, + toValue, + watch, + type ComputedRef, + type MaybeRefOrGetter, + type Ref, +} from 'vue' interface DashboardMediaGridCapacityOptions { contentSelector?: string @@ -6,7 +18,7 @@ interface DashboardMediaGridCapacityOptions { horizontalPadding?: number maxCount?: number minItemWidth: number - rows?: number + rows?: MaybeRefOrGetter } interface DashboardMediaGridCapacityState { @@ -20,7 +32,7 @@ const DEFAULT_DASHBOARD_MEDIA_GRID_GAP = 16 const DEFAULT_DASHBOARD_MEDIA_GRID_ROWS = 2 /** - * 根据仪表盘媒体卡片容器宽度计算可铺满指定行数的请求数量。 + * 根据仪表盘媒体卡片容器宽度和响应式行数计算请求数量。 * * @param options 网格尺寸参数,需要与实际 ProgressiveCardGrid 参数保持一致 * @returns 容器引用、列数、请求数量和手动刷新方法 @@ -36,7 +48,11 @@ export function useDashboardMediaGridCapacity(options: DashboardMediaGridCapacit const safeHorizontalPadding = computed(() => Math.max(0, options.horizontalPadding ?? 0)) const safeMaxCount = computed(() => Math.max(0, Math.floor(options.maxCount ?? Number.POSITIVE_INFINITY))) const safeMinItemWidth = computed(() => Math.max(1, options.minItemWidth)) - const safeRows = computed(() => Math.max(1, Math.floor(options.rows ?? DEFAULT_DASHBOARD_MEDIA_GRID_ROWS))) + const safeRows = computed(() => { + const rows = options.rows === undefined ? DEFAULT_DASHBOARD_MEDIA_GRID_ROWS : toValue(options.rows) + + return Math.max(1, Math.floor(rows)) + }) const columnCount = computed(() => { if (measuredWidth.value <= 0) return 0 diff --git a/src/views/dashboard/MediaServerLatest.vue b/src/views/dashboard/MediaServerLatest.vue index 28a4f669..4d6e7a8e 100644 --- a/src/views/dashboard/MediaServerLatest.vue +++ b/src/views/dashboard/MediaServerLatest.vue @@ -5,9 +5,11 @@ import PosterCard from '@/components/cards/PosterCard.vue' import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue' import { useDashboardMediaGridCapacity } from '@/composables/useDashboardMediaGridCapacity' import { useI18n } from 'vue-i18n' +import { useDisplay } from 'vuetify' // 国际化 const { t } = useI18n() +const display = useDisplay() const LATEST_CARD_MIN_WIDTH = 144 const MEDIA_GRID_HORIZONTAL_PADDING = 40 @@ -18,7 +20,10 @@ const latestList = ref<{ [key: string]: MediaServerPlayItem[] }>({}) // 所有媒体服务器设置 const mediaServers = ref([]) -// 最近入库两行网格容量 +// 小屏幕纵向空间更紧凑,展示三行;桌面端保持两行横向铺满。 +const mediaGridRows = computed(() => (display.smAndDown.value ? 3 : 2)) + +// 最近入库网格容量 const { containerRef: mediaGridContainerRef, itemCount: latestItemCount, @@ -27,6 +32,7 @@ const { contentSelector: '.dashboard-media-content', horizontalPadding: MEDIA_GRID_HORIZONTAL_PADDING, minItemWidth: LATEST_CARD_MIN_WIDTH, + rows: mediaGridRows, }) let latestLoadId = 0 diff --git a/src/views/dashboard/MediaServerPlaying.vue b/src/views/dashboard/MediaServerPlaying.vue index ba5021c0..41f5ba0c 100644 --- a/src/views/dashboard/MediaServerPlaying.vue +++ b/src/views/dashboard/MediaServerPlaying.vue @@ -5,9 +5,11 @@ import PlayingBackdropCard from '@/components/cards/PlayingBackdropCard.vue' import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue' import { useDashboardMediaGridCapacity } from '@/composables/useDashboardMediaGridCapacity' import { useI18n } from 'vue-i18n' +import { useDisplay } from 'vuetify' // 国际化 const { t } = useI18n() +const display = useDisplay() const PLAYING_CARD_MIN_WIDTH = 240 const MEDIA_GRID_HORIZONTAL_PADDING = 40 @@ -18,7 +20,10 @@ const playingList = ref([]) // 所有媒体服务器设置 const mediaServers = ref([]) -// 继续观看两行网格容量 +// 小屏幕纵向空间更紧凑,展示三行;桌面端保持两行横向铺满。 +const mediaGridRows = computed(() => (display.smAndDown.value ? 3 : 2)) + +// 继续观看网格容量 const { containerRef: mediaGridContainerRef, itemCount: playingItemCount, @@ -27,6 +32,7 @@ const { contentSelector: '.dashboard-media-content', horizontalPadding: MEDIA_GRID_HORIZONTAL_PADDING, minItemWidth: PLAYING_CARD_MIN_WIDTH, + rows: mediaGridRows, }) const displayedPlayingList = computed(() => playingList.value.slice(0, playingItemCount.value))