优化可用高度计算

This commit is contained in:
jxxghp
2025-07-11 15:14:16 +08:00
parent 79d203470a
commit e409dbd5b8
6 changed files with 109 additions and 50 deletions

View File

@@ -12,6 +12,7 @@ import { useDisplay } from 'vuetify'
import MediaInfoDialog from '../dialog/MediaInfoDialog.vue'
import { useI18n } from 'vue-i18n'
import { useBackgroundOptimization } from '@/composables/useBackgroundOptimization'
import { usePWA } from '@/composables/usePWA'
// 国际化
const { t } = useI18n()
@@ -20,6 +21,8 @@ const { useProgressSSE } = useBackgroundOptimization()
// 显示器宽度
const display = useDisplay()
const { appMode } = usePWA()
// 输入参数
const inProps = defineProps({
icons: Object,
@@ -35,7 +38,6 @@ const inProps = defineProps({
required: true,
},
sort: String,
listStyle: String,
showTree: Boolean,
})
@@ -125,6 +127,30 @@ const transferItems = ref<FileItem[]>([])
// 当前图片地址
const currentImgLink = ref('')
// 计算列表可用高度
const listAvailableHeight = computed(() => {
// 获取视口高度
const viewportHeight = window.innerHeight || document.documentElement.clientHeight
// navbar高度
const navbarHeight = 72
// 工具栏高度(包含搜索框和按钮)
const toolbarHeight = 64
// 底部导航栏高度
const footerHeight = appMode.value ? 80 : 16
// 安全区域高度
const safeAreaHeight =
parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--safe-area-inset-bottom')) ||
parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--safe-area-inset-top')) ||
0
// 计算可用高度,预留一些边距
const availableHeight = viewportHeight - navbarHeight - toolbarHeight - footerHeight - safeAreaHeight - 40
// 确保最小高度
return Math.max(availableHeight, 300)
})
// 是否为图片文件
const isImage = computed(() => {
const ext = inProps.item.path?.split('.').pop()?.toLowerCase()
@@ -546,7 +572,7 @@ const progressSSE = useProgressSSE(
`${import.meta.env.VITE_API_BASE_URL}system/progress/batchrename`,
handleProgressMessage,
'file-batch-rename-progress',
progressActive
progressActive,
)
// 使用SSE监听加载进度
@@ -567,6 +593,14 @@ onMounted(() => {
})
</script>
<style scoped>
.file-list-container {
overflow: hidden auto;
block-size: 100%;
max-block-size: 100%;
}
</style>
<template>
<div>
<VCard class="d-flex flex-column w-full h-full rounded-t-0" :class="{ 'rounded-s-0': showTree }">
@@ -635,9 +669,12 @@ onMounted(() => {
<VImg :src="currentImgLink" max-width="100%" max-height="100%" />
</VCardText>
<!-- 目录和文件列表 -->
<VCardText v-else-if="dirs.length || files.length" class="p-0">
<VList class="text-high-emphasis">
<VVirtualScroll :items="[...dirs, ...files]" :style="listStyle">
<VCardText v-else-if="dirs.length || files.length" class="p-0 flex-grow-1 overflow-hidden">
<VList
class="text-high-emphasis file-list-container"
:style="{ height: `${listAvailableHeight}px`, maxHeight: `${listAvailableHeight}px` }"
>
<VVirtualScroll :items="[...dirs, ...files]" style="block-size: 100%">
<template #default="{ item }">
<VHover>
<template #default="hover">

View File

@@ -4,6 +4,7 @@ import type { FileItem } from '@/api/types'
import { useDisplay } from 'vuetify'
import type { AxiosRequestConfig } from 'axios'
import { useI18n } from 'vue-i18n'
import { usePWA } from '@/composables/usePWA'
// 国际化
const { t } = useI18n()
@@ -11,6 +12,32 @@ const { t } = useI18n()
// 显示器宽度
const display = useDisplay()
const { appMode } = usePWA()
// 计算列表可用高度
const availableHeight = computed(() => {
// 获取视口高度
const viewportHeight = window.innerHeight || document.documentElement.clientHeight
// navbar高度
const navbarHeight = 72
// 工具栏高度
const toolbarHeight = 25
// 底部导航栏高度
const footerHeight = appMode.value ? 80 : 16
// 安全区域高度
const safeAreaHeight =
parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--safe-area-inset-bottom')) ||
parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--safe-area-inset-top')) ||
0
// 计算可用高度,预留一些边距
const availableHeight = viewportHeight - navbarHeight - toolbarHeight - footerHeight - safeAreaHeight - 40
// 确保最小高度
return Math.max(availableHeight, 300)
})
// 输入参数
const props = defineProps({
storage: {
@@ -125,11 +152,6 @@ async function loadRootDirectories() {
await loadSubdirectories('/')
}
// 获取目录层级深度
function getDirectoryDepth(path: string) {
return path.split('/').filter(p => p).length
}
// 检索所有目录节点
function getAllDirectories() {
const allDirs: { dir: FileItem; level: number; parentPath: string }[] = []
@@ -227,11 +249,6 @@ const flattenedDirectories = computed(() => {
return getAllDirectories()
})
// 组件挂载时初始加载
onMounted(async () => {
await loadRootDirectories()
})
// 检查路径是否为指定目录的子目录或后代
function isChildOrDescendant(path: string, ancestorPath: string) {
if (!path || !ancestorPath) return false
@@ -260,10 +277,19 @@ function getIndentLevel(path: string, ancestorPath: string) {
return pathParts - ancestorParts
}
// 组件挂载时初始加载
onMounted(async () => {
await loadRootDirectories()
})
onActivated(() => {
updateHeight()
})
</script>
<template>
<VCard class="file-navigator rounded-e-0 rounded-t-0" v-if="!isMobile">
<VCard class="file-navigator rounded-e-0 rounded-t-0" v-if="!isMobile" :height="`${availableHeight}px`">
<div class="tree-container">
<!-- 根目录项 -->
<div