fix: lifecycle ribbon always visible at bottom, slides up on hover/focus

This commit is contained in:
2026-02-24 11:19:50 -06:00
parent 3112c53d86
commit 6fabf37196

View File

@@ -7,6 +7,7 @@ import { useSessionState } from '@/stores/session-state'
import { ChatContainer, AquaticBackground, AgentBadge, NewSessionModal } from '@/components/transcript-debug'
import type { AgentName } from '@/types/transcript-debug'
import { isTauri, isMobileTauri, getTauriWindow } from '@/lib/tauri'
import { usePipWindow } from '@/composables/usePipWindow'
const route = useRoute()
const router = useRouter()
@@ -163,7 +164,12 @@ watch(() => sessionState.terminalRegistry.length, () => {
})
const isAndroid = isMobileTauri()
const pipOpen = ref(false)
const { openPip, closePip, isPipOpen } = usePipWindow()
const currentTerminalIndex = computed(() => {
return parseInt(route.params.terminalIndex as string) || 1
})
const pipOpen = computed(() => isPipOpen(currentTerminalIndex.value))
async function closePipWindow() {
try {
@@ -197,47 +203,16 @@ async function enterPip() {
return
}
// Desktop Tauri: toggle pip window
// Desktop Tauri: toggle pip window using shared composable
if (!isTauri) return
const idx = currentTerminalIndex.value
if (pipOpen.value) {
try {
const { WebviewWindow } = await import('@tauri-apps/api/webviewWindow')
const existing = await WebviewWindow.getByLabel('pip-terminal')
if (existing) await existing.close()
} catch {}
pipOpen.value = false
await closePip(idx)
return
}
try {
const { WebviewWindow } = await import('@tauri-apps/api/webviewWindow')
// Build the URL for the pip window — same transcript page with terminal index
const terminalIdx = route.params.terminalIndex || '1'
const pipUrl = `/transcript-debug/${terminalIdx}?pip=1`
const pip = new WebviewWindow('pip-terminal', {
url: pipUrl,
title: 'Agent UI',
width: 380,
height: 620,
x: window.screen.width - 400,
y: 60,
alwaysOnTop: false,
decorations: false,
resizable: true,
focus: true,
})
pipOpen.value = true
pip.onCloseRequested(() => {
pipOpen.value = false
})
} catch (e) {
console.warn('Failed to open PiP window:', e)
pipOpen.value = false
}
await openPip(idx)
}
onMounted(async () => {
@@ -755,18 +730,21 @@ onBeforeUnmount(() => {
backdrop-filter: blur(8px) !important;
-webkit-backdrop-filter: blur(8px) !important;
border-top: 1px solid rgba(255, 255, 255, 0.06) !important;
/* Auto-hide: fade out when idle */
opacity: 0;
transform: translateY(100%);
transition: opacity 0.3s ease, transform 0.3s ease;
/* Idle: slide down but keep lifecycle ribbon visible at bottom */
transform: translateY(calc(100% - 26px));
transition: transform 0.3s ease;
pointer-events: none;
}
/* Lifecycle ribbon always interactive even when idle */
.content-area :deep(.lifecycle-ribbon) {
pointer-events: auto !important;
}
/* Show on hover anywhere in the content area or when input is focused */
.content-area:hover :deep(.bottom-overlay),
.content-area:has(:focus-within) :deep(.bottom-overlay),
.content-area :deep(.bottom-overlay:focus-within) {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
@@ -819,7 +797,6 @@ onBeforeUnmount(() => {
/* Lifecycle ribbon */
.content-area :deep(.lifecycle-ribbon) {
background: transparent !important;
pointer-events: none !important;
}
/* Input container */