fix(web): 修复控制台布局动态切换残留问题

This commit is contained in:
mofeng-git
2026-09-26 00:57:16 +08:00
parent 83cbfb6924
commit 0a041c2caa
2 changed files with 87 additions and 31 deletions

View File

@@ -257,6 +257,18 @@ watch(locale, () => {
}) })
watch([() => props.layout, () => props.showComputerUse, floatingCollapsed, minimalDisplayControls], () => { watch([() => props.layout, () => props.showComputerUse, floatingCollapsed, minimalDisplayControls], () => {
// Layout changes can move this bar while its portal based controls are open.
// Close every transient surface first so no old portal remains attached to
// the document after the new layout is painted.
overflowMenuOpen.value = false
pasteOpen.value = false
atxOpen.value = false
videoPopoverOpen.value = false
hidPopoverOpen.value = false
audioPopoverOpen.value = false
msdDialogOpen.value = false
mobileAtxOpen.value = false
mobilePasteOpen.value = false
void observeLayout() void observeLayout()
}) })

View File

@@ -3263,7 +3263,6 @@ onUnmounted(() => {
/> />
</div> </div>
</div> </div>
<div v-if="consoleLayout === 'floating'" id="console-header-toolbar" class="console-header__toolbar" />
<div class="console-header__account flex shrink-0 items-center gap-1 sm:gap-2"> <div class="console-header__account flex shrink-0 items-center gap-1 sm:gap-2">
<ConsoleHeaderActions <ConsoleHeaderActions
v-if="consoleLayout === 'floating'" v-if="consoleLayout === 'floating'"
@@ -3355,7 +3354,10 @@ onUnmounted(() => {
</div> </div>
</div> </div>
</header> </header>
<Teleport :key="consoleLayout" defer :to="consoleLayout === 'floating' ? '#console-header-toolbar' : 'body'" :disabled="consoleLayout !== 'floating'"> <div
class="console-actionbar-host"
:class="`console-actionbar-host--${consoleLayout}`"
>
<ActionBar <ActionBar
:layout="consoleLayout" :layout="consoleLayout"
:mouse-mode="mouseMode" :mouse-mode="mouseMode"
@@ -3384,7 +3386,7 @@ onUnmounted(() => {
@open-terminal="openTerminal" @open-terminal="openTerminal"
@open-computer-use="openComputerUse" @open-computer-use="openComputerUse"
/> />
</Teleport> </div>
<div <div
class="flex-1 overflow-hidden relative transition-[padding] duration-300" class="flex-1 overflow-hidden relative transition-[padding] duration-300"
:class="consoleLayout === 'sidebar' && 'pl-14 sm:pl-16'" :class="consoleLayout === 'sidebar' && 'pl-14 sm:pl-16'"
@@ -3704,6 +3706,48 @@ onUnmounted(() => {
</template> </template>
<style scoped> <style scoped>
/* Keep the action bar in one DOM location while changing only its placement.
Moving a live Teleport target during a layout switch can leave stale portal
nodes behind when the target is conditionally rendered. */
.console-actionbar-host {
position: relative;
z-index: 40;
}
.console-actionbar-host--floating {
position: absolute;
inset: 0 0 auto;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
}
.console-actionbar-host--floating :deep(.console-action-bar) {
pointer-events: auto;
}
.console-actionbar-host--sidebar :deep(.console-action-bar--sidebar) {
position: relative;
inset: auto;
width: 100%;
height: 100%;
}
.console-actionbar-host--sidebar {
position: absolute;
inset: 3.5rem auto 1.75rem 0;
width: 4rem;
}
@media (max-width: 639px) {
.console-actionbar-host--sidebar {
inset: 2.5rem auto 1.75rem 0;
width: 3.5rem;
}
}
/* Expanded controls may overlap header actions, but stay outside the video stage. */ /* Expanded controls may overlap header actions, but stay outside the video stage. */
.console-header--floating .console-header__row { .console-header--floating .console-header__row {
position: relative; position: relative;