diff --git a/frontend/src/App.vue b/frontend/src/App.vue index cfa3bbc..ed1aed5 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -84,6 +84,7 @@ const awaitingPermission = ref(false) // Waiting for user permission (highest pr const showSessionStart = ref(false) // Session start animation (3s) const showNotification = ref(false) // Notification pulse (2s) const showToolFlash = ref(false) // Tool use flash (500ms) +const keyboardVisible = ref(false) // Virtual keyboard visible let statusWs: WebSocket | null = null let statusReconnectTimeout: number | null = null @@ -311,6 +312,16 @@ onMounted(async () => { } }) + // Detect virtual keyboard on mobile + if (window.visualViewport) { + const initialHeight = window.visualViewport.height + window.visualViewport.addEventListener('resize', () => { + const currentHeight = window.visualViewport!.height + // If viewport shrinks significantly, keyboard is likely open + keyboardVisible.value = currentHeight < initialHeight * 0.75 + }) + } + // Start polling for token if not connected const webmcp = getWebMCP() if (!webmcp?.isConnected) { @@ -387,7 +398,8 @@ watch(() => route.name, (newPage) => { 'session-start': showSessionStart, notification: showNotification, 'tool-flash': showToolFlash, - 'sheet-open': showTerminal || showVoice + 'sheet-open': showTerminal || showVoice, + 'keyboard-visible': keyboardVisible }" @click="showTerminal = !showTerminal" :title="awaitingPermission ? `Permiso requerido: ${claudeTool || 'herramienta'}` : isProcessing ? `Claude: ${claudeTool || 'processing'}` : 'Toggle Terminal'" @@ -460,7 +472,7 @@ watch(() => route.name, (newPage) => {