Make dashboard media grids responsive to screen size

This commit is contained in:
jxxghp
2026-06-29 22:20:31 +08:00
parent 4492e211bb
commit 79bc9f0ff0
3 changed files with 34 additions and 6 deletions

View File

@@ -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<number>
}
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

View File

@@ -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<MediaServerConf[]>([])
// 最近入库两行网格容量
// 小屏幕纵向空间更紧凑,展示三行;桌面端保持两行横向铺满。
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

View File

@@ -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<MediaServerPlayItem[]>([])
// 所有媒体服务器设置
const mediaServers = ref<MediaServerConf[]>([])
// 继续观看两行网格容量
// 小屏幕纵向空间更紧凑,展示三行;桌面端保持两行横向铺满。
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))