Fix mobile keyboard hiding chat input

Use visualViewport API to dynamically resize the app container when the
virtual keyboard opens, ensuring the input bar stays visible above the
keyboard instead of being hidden behind it.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-20 20:11:35 -05:00
parent c26dd4ae19
commit 3d121c2e08
2 changed files with 24 additions and 3 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, interactive-widget=resizes-content" />
<meta name="theme-color" content="#f97316" />
<meta name="description" content="Spiceflow - AI Session Orchestration" />
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
+23 -2
View File
@@ -1,9 +1,18 @@
<script lang="ts">
import '../app.css';
import { onMount } from 'svelte';
import { onMount, onDestroy } from 'svelte';
import { sessions } from '$lib/stores/sessions';
import { pushStore } from '$lib/stores/push';
let containerHeight = '100dvh';
function updateHeight() {
if (typeof window !== 'undefined' && window.visualViewport) {
// Use the visual viewport height to account for keyboard
containerHeight = `${window.visualViewport.height}px`;
}
}
onMount(() => {
sessions.load();
pushStore.init();
@@ -16,9 +25,21 @@
}
});
}
// Track visual viewport for keyboard handling
if (typeof window !== 'undefined' && window.visualViewport) {
updateHeight();
window.visualViewport.addEventListener('resize', updateHeight);
}
});
onDestroy(() => {
if (typeof window !== 'undefined' && window.visualViewport) {
window.visualViewport.removeEventListener('resize', updateHeight);
}
});
</script>
<div class="h-dvh flex flex-col bg-zinc-900 text-zinc-100 safe-top">
<div class="flex flex-col bg-zinc-900 text-zinc-100 safe-top overflow-hidden" style="height: {containerHeight};">
<slot />
</div>