From a0a9cf8e548d06cd8038f836a287c9fcfb3f3a9a Mon Sep 17 00:00:00 2001 From: Dorian Date: Wed, 4 Mar 2026 20:50:06 +0000 Subject: [PATCH] =?UTF-8?q?feat(app):=20mobile=20improvements=20=E2=80=94?= =?UTF-8?q?=20native-feel=20viewport,=20keyboard,=20HIG=20tabs,=20PWA=20fi?= =?UTF-8?q?x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Lock viewport: position:fixed on html/body prevents iOS bounce scroll - No zoom on input focus: maximum-scale=1, user-scalable=no - Keyboard-responsive chat: visualViewport API detects keyboard, hides tab bar, scrolls chat to bottom, scrollIntoView on input focus - iOS HIG tab bar: 49pt height, vertical icon+label, safe-area-inset-bottom - PWA fix: manifest start_url/scope/id changed from '/' to './' for subpath deployment compatibility - PlayerBar: variant prop (fixed/inline), inline on mobile above tab bar, fixed on desktop. No more overlap with tab bar. Co-Authored-By: Claude Opus 4.6 --- packages/app/index.html | 6 +- packages/app/src/App.vue | 10 +- .../app/src/components/chat/ChatInput.vue | 9 +- .../app/src/components/chat/ChatWindow.vue | 7 ++ .../app/src/components/player/PlayerBar.vue | 11 +- .../app/src/composables/useVisualViewport.ts | 40 +++++++ packages/app/src/pages/ChatPage.vue | 104 ++++++++++-------- packages/app/src/styles/main.css | 6 + packages/app/vite.config.ts | 6 +- 9 files changed, 142 insertions(+), 57 deletions(-) create mode 100644 packages/app/src/composables/useVisualViewport.ts diff --git a/packages/app/index.html b/packages/app/index.html index 0ac43e97..6145c0c5 100644 --- a/packages/app/index.html +++ b/packages/app/index.html @@ -1,8 +1,8 @@ - + - + @@ -13,7 +13,7 @@ AIUI - +
diff --git a/packages/app/src/App.vue b/packages/app/src/App.vue index 282b100b..0d820eb5 100644 --- a/packages/app/src/App.vue +++ b/packages/app/src/App.vue @@ -2,7 +2,7 @@
- + diff --git a/packages/app/src/components/chat/ChatInput.vue b/packages/app/src/components/chat/ChatInput.vue index 01f6bab5..e9d7596f 100644 --- a/packages/app/src/components/chat/ChatInput.vue +++ b/packages/app/src/components/chat/ChatInput.vue @@ -106,7 +106,7 @@ @keydown="handleKeydown" @input="autoResize" @paste="onPaste" - @focus="focused = true" + @focus="onInputFocus" @blur="focused = false" /> - - +
+ + + +
@@ -367,12 +374,14 @@ import { useChatStore } from '@/stores/chat' import { useTheme } from '@/composables/useTheme' import { useAI } from '@/composables/useAI' import { useContentPanel, type ContentTab } from '@/composables/useContentPanel' +import { useVisualViewport } from '@/composables/useVisualViewport' import ChatWindow from '@/components/chat/ChatWindow.vue' import ContentGridView from '@/components/content/ContentGridView.vue' import DetailView from '@/components/content/DetailView.vue' import CloseButton from '@/components/content/CloseButton.vue' import ContextLoader from '@/components/content/ContextLoader.vue' import ErrorBoundary from '@/components/ui/ErrorBoundary.vue' +import PlayerBar from '@/components/player/PlayerBar.vue' import { useCodeContext } from '@/composables/useCodeContext' const chatStore = useChatStore() @@ -446,6 +455,7 @@ const windowWidth = ref(window.innerWidth) const isMobile = computed(() => windowWidth.value < 1024) const isWideDesktop = computed(() => windowWidth.value >= 1440) const mobileTab = ref<'chat' | 'content' | 'context'>('chat') +const { isKeyboardOpen } = useVisualViewport() function onResize() { windowWidth.value = window.innerWidth } diff --git a/packages/app/src/styles/main.css b/packages/app/src/styles/main.css index 3a76b3d2..05c1f8a6 100644 --- a/packages/app/src/styles/main.css +++ b/packages/app/src/styles/main.css @@ -28,12 +28,18 @@ html { -webkit-tap-highlight-color: transparent; + height: 100%; + overflow: hidden; } body { overscroll-behavior: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + position: fixed; + width: 100%; + height: 100%; + overflow: hidden; } /* ===== DARK MODE GLASSMORPHISM — from Archy ===== */ diff --git a/packages/app/vite.config.ts b/packages/app/vite.config.ts index 57a89021..c4052b83 100644 --- a/packages/app/vite.config.ts +++ b/packages/app/vite.config.ts @@ -25,7 +25,7 @@ export default defineConfig({ registerType: 'autoUpdate', includeAssets: ['favicon.svg', 'icon.svg', 'apple-touch-icon-180x180.png'], manifest: { - id: '/', + id: './', name: 'AIUI', short_name: 'AIUI', description: 'AI chat interface with rich content surfaces', @@ -34,8 +34,8 @@ export default defineConfig({ display: 'standalone', display_override: ['standalone', 'minimal-ui'], orientation: 'any', - start_url: '/', - scope: '/', + start_url: './', + scope: './', icons: [ { src: 'pwa-192x192.png',