mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-06-19 06:30:35 +08:00
fix: stabilize mobile panel height
This commit is contained in:
@@ -107,7 +107,6 @@ const HISTORY_TITLE_LENGTH = 36
|
||||
const HISTORY_PREVIEW_LENGTH = 72
|
||||
|
||||
const drawer = ref(false)
|
||||
const drawerViewportHeight = ref('100dvh')
|
||||
const inputText = ref('')
|
||||
const messages = ref<AgentChatMessage[]>([])
|
||||
const historySessions = ref<AgentSessionHistoryItem[]>([])
|
||||
@@ -144,7 +143,6 @@ const hasMessages = computed(() => messages.value.length > 0)
|
||||
const hasHistorySessions = computed(() => historySessions.value.length > 0)
|
||||
const currentUserName = computed(() => userStore.getUserName || t('common.user'))
|
||||
const drawerStyle = computed(() => ({
|
||||
'--agent-assistant-viewport-height': drawerViewportHeight.value,
|
||||
'--agent-assistant-panel-width': drawerWidth.value,
|
||||
}))
|
||||
|
||||
@@ -626,19 +624,6 @@ async function prepareAgentAttachments(items: AgentPendingAttachment[]): Promise
|
||||
return { images, files, userAttachments }
|
||||
}
|
||||
|
||||
function getVisibleViewportHeight() {
|
||||
if (typeof window === 'undefined') return '100dvh'
|
||||
|
||||
const height = window.visualViewport?.height || window.innerHeight || document.documentElement.clientHeight
|
||||
|
||||
return height > 0 ? `${Math.round(height)}px` : '100dvh'
|
||||
}
|
||||
|
||||
// iOS 独立模式和地址栏收起时可见高度会变化,抽屉需要跟随真实 viewport。
|
||||
function syncDrawerViewportHeight() {
|
||||
drawerViewportHeight.value = getVisibleViewportHeight()
|
||||
}
|
||||
|
||||
async function streamAgentMessage(
|
||||
text: string,
|
||||
images: string[] = [],
|
||||
@@ -874,13 +859,8 @@ watch(drawerWidth, () => {
|
||||
onMounted(() => {
|
||||
restoreHistorySessions()
|
||||
restoreState()
|
||||
syncDrawerViewportHeight()
|
||||
syncInputHeight()
|
||||
window.addEventListener('resize', syncDrawerViewportHeight)
|
||||
window.addEventListener('orientationchange', syncDrawerViewportHeight)
|
||||
window.addEventListener('keydown', handleGlobalKeydown)
|
||||
window.visualViewport?.addEventListener('resize', syncDrawerViewportHeight)
|
||||
window.visualViewport?.addEventListener('scroll', syncDrawerViewportHeight)
|
||||
})
|
||||
|
||||
onScopeDispose(clearAgentAssistantOpenState)
|
||||
@@ -888,11 +868,7 @@ onScopeDispose(clearPendingAttachments)
|
||||
onScopeDispose(() => {
|
||||
if (typeof window === 'undefined') return
|
||||
|
||||
window.removeEventListener('resize', syncDrawerViewportHeight)
|
||||
window.removeEventListener('orientationchange', syncDrawerViewportHeight)
|
||||
window.removeEventListener('keydown', handleGlobalKeydown)
|
||||
window.visualViewport?.removeEventListener('resize', syncDrawerViewportHeight)
|
||||
window.visualViewport?.removeEventListener('scroll', syncDrawerViewportHeight)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1269,16 +1245,26 @@ onScopeDispose(() => {
|
||||
z-index: 2101;
|
||||
overflow: hidden;
|
||||
background: rgb(var(--v-theme-surface));
|
||||
block-size: var(--agent-assistant-viewport-height, 100dvh) !important;
|
||||
|
||||
/* 背景层必须覆盖完整视口,不能跟随 iOS 键盘后的 visual viewport 缩短。 */
|
||||
block-size: 100vh !important;
|
||||
border-inline-start: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||
box-shadow: var(--app-surface-shadow);
|
||||
inline-size: var(--agent-assistant-panel-width, 30rem);
|
||||
inset-block-start: 0;
|
||||
inset-inline-end: 0;
|
||||
max-block-size: var(--agent-assistant-viewport-height, 100dvh) !important;
|
||||
max-block-size: none !important;
|
||||
min-block-size: 100vh !important;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
@supports (block-size: 100lvh) {
|
||||
.agent-assistant-panel {
|
||||
block-size: 100lvh !important;
|
||||
min-block-size: 100lvh !important;
|
||||
}
|
||||
}
|
||||
|
||||
.agent-assistant-shell {
|
||||
position: relative;
|
||||
display: grid;
|
||||
@@ -1345,7 +1331,7 @@ onScopeDispose(() => {
|
||||
}
|
||||
|
||||
.agent-assistant-history-list {
|
||||
max-block-size: min(26rem, calc(var(--agent-assistant-viewport-height, 100dvh) - 7rem));
|
||||
max-block-size: min(26rem, calc(100vh - 7rem));
|
||||
overscroll-behavior: contain;
|
||||
padding-block: 0.35rem;
|
||||
|
||||
@@ -1355,6 +1341,12 @@ onScopeDispose(() => {
|
||||
}
|
||||
}
|
||||
|
||||
@supports (block-size: 100lvh) {
|
||||
.agent-assistant-history-list {
|
||||
max-block-size: min(26rem, calc(100lvh - 7rem));
|
||||
}
|
||||
}
|
||||
|
||||
.agent-assistant-history-empty {
|
||||
color: rgba(var(--v-theme-on-surface), 0.58);
|
||||
font-size: 0.85rem;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
import type { CSSProperties } from 'vue'
|
||||
import {
|
||||
themeCustomizerPrimaryColors,
|
||||
useThemeCustomizer,
|
||||
@@ -35,20 +34,6 @@ const { appMode } = usePWA()
|
||||
const { t } = useI18n()
|
||||
const { global: globalTheme } = useTheme()
|
||||
const defaultPrimaryColor = themeCustomizerPrimaryColors[0].value
|
||||
const customizerViewportHeight = ref('100dvh')
|
||||
|
||||
function getVisibleViewportHeight() {
|
||||
if (typeof window === 'undefined') return '100dvh'
|
||||
|
||||
const height = window.visualViewport?.height || window.innerHeight || document.documentElement.clientHeight
|
||||
|
||||
return height > 0 ? `${Math.round(height)}px` : '100dvh'
|
||||
}
|
||||
|
||||
// iOS 小屏的可见视口会随地址栏和独立模式 safe area 变化,面板高度需要跟随真实可见高度。
|
||||
function syncCustomizerViewportHeight() {
|
||||
customizerViewportHeight.value = getVisibleViewportHeight()
|
||||
}
|
||||
|
||||
// 将主题定制器打开状态同步到根节点,供全局悬浮按钮避让右侧面板。
|
||||
function syncThemeCustomizerOpenState(isOpen: boolean) {
|
||||
@@ -76,12 +61,7 @@ function handleGlobalKeydown(event: KeyboardEvent) {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
syncCustomizerViewportHeight()
|
||||
window.addEventListener('keydown', handleGlobalKeydown)
|
||||
window.addEventListener('resize', syncCustomizerViewportHeight)
|
||||
window.addEventListener('orientationchange', syncCustomizerViewportHeight)
|
||||
window.visualViewport?.addEventListener('resize', syncCustomizerViewportHeight)
|
||||
window.visualViewport?.addEventListener('scroll', syncCustomizerViewportHeight)
|
||||
})
|
||||
|
||||
onScopeDispose(clearThemeCustomizerOpenState)
|
||||
@@ -89,16 +69,8 @@ onScopeDispose(() => {
|
||||
if (typeof window === 'undefined') return
|
||||
|
||||
window.removeEventListener('keydown', handleGlobalKeydown)
|
||||
window.removeEventListener('resize', syncCustomizerViewportHeight)
|
||||
window.removeEventListener('orientationchange', syncCustomizerViewportHeight)
|
||||
window.visualViewport?.removeEventListener('resize', syncCustomizerViewportHeight)
|
||||
window.visualViewport?.removeEventListener('scroll', syncCustomizerViewportHeight)
|
||||
})
|
||||
|
||||
const customizerContainerStyle = computed<CSSProperties>(() => ({
|
||||
'--theme-customizer-viewport-height': customizerViewportHeight.value,
|
||||
}))
|
||||
|
||||
const themeOptions = computed<Array<{ icon: string; title: string; value: ThemeCustomizerTheme }>>(() => [
|
||||
{ title: t('theme.light'), value: 'light', icon: 'mdi-white-balance-sunny' },
|
||||
{ title: t('theme.dark'), value: 'dark', icon: 'mdi-weather-night' },
|
||||
@@ -234,7 +206,6 @@ async function handleResetSettings() {
|
||||
<template>
|
||||
<aside
|
||||
class="theme-customizer-panel-host"
|
||||
:style="customizerContainerStyle"
|
||||
role="dialog"
|
||||
:aria-label="t('theme.customizer.title')"
|
||||
>
|
||||
@@ -443,13 +414,23 @@ async function handleResetSettings() {
|
||||
overflow: hidden;
|
||||
border-radius: 0;
|
||||
background: rgb(var(--v-theme-surface));
|
||||
block-size: var(--theme-customizer-viewport-height, 100dvh) !important;
|
||||
|
||||
/* 背景层保持完整视口高度,避免 iOS 键盘触发 visual viewport resize 后露出底层页面。 */
|
||||
block-size: 100vh !important;
|
||||
border-inline-start: 1px solid rgba(var(--v-theme-on-surface), 0.08) !important;
|
||||
box-shadow: var(--app-surface-shadow) !important;
|
||||
inline-size: 420px !important;
|
||||
inset-block-start: 0 !important;
|
||||
inset-inline-end: 0 !important;
|
||||
max-block-size: var(--theme-customizer-viewport-height, 100dvh) !important;
|
||||
max-block-size: none !important;
|
||||
min-block-size: 100vh !important;
|
||||
}
|
||||
|
||||
@supports (block-size: 100lvh) {
|
||||
.theme-customizer-panel-host {
|
||||
block-size: 100lvh !important;
|
||||
min-block-size: 100lvh !important;
|
||||
}
|
||||
}
|
||||
|
||||
.theme-customizer-panel {
|
||||
@@ -467,12 +448,12 @@ async function handleResetSettings() {
|
||||
max-block-size: 100%;
|
||||
|
||||
/* 独立 App 模式会贴近 viewport-fit=cover 顶部,面板内部需要避开 iOS 状态栏。 */
|
||||
padding-block-start: env(safe-area-inset-top);
|
||||
padding-block-start: env(safe-area-inset-top, 0px);
|
||||
}
|
||||
|
||||
.theme-customizer-panel--dialog .theme-customizer-body {
|
||||
block-size: auto;
|
||||
padding-block-end: env(safe-area-inset-bottom);
|
||||
padding-block-end: env(safe-area-inset-bottom, 0px);
|
||||
}
|
||||
|
||||
@media (width <= 600px) {
|
||||
|
||||
Reference in New Issue
Block a user