diff --git a/frontend/src/lib/components/ChatInput.svelte b/frontend/src/lib/components/ChatInput.svelte index 2e64560..0bdbde1 100644 --- a/frontend/src/lib/components/ChatInput.svelte +++ b/frontend/src/lib/components/ChatInput.svelte @@ -17,19 +17,19 @@ } -
+
diff --git a/frontend/src/lib/convex-polling.svelte.ts b/frontend/src/lib/convex-polling.svelte.ts index da1fe96..627e4ae 100644 --- a/frontend/src/lib/convex-polling.svelte.ts +++ b/frontend/src/lib/convex-polling.svelte.ts @@ -12,17 +12,13 @@ type PollingContext = { export function hasWebSocketSupport(): boolean { if (typeof window === 'undefined') return true; try { - const hasWs = 'WebSocket' in window && typeof WebSocket !== 'undefined'; - console.log('[convex-polling] WebSocket check:', hasWs); - return hasWs; - } catch (e) { - console.log('[convex-polling] WebSocket check error:', e); + return 'WebSocket' in window && typeof WebSocket !== 'undefined'; + } catch { return false; } } export function setupPollingConvex(url: string): void { - console.log('[convex-polling] Setting up polling client with URL:', url); const client = new ConvexHttpClient(url); setContext(POLLING_CONTEXT_KEY, { client }); } @@ -67,27 +63,22 @@ export function usePollingQuery>( async function poll() { const args = argsGetter(); if (args === 'skip') { - console.log('[convex-polling] Skipping query (args=skip)'); state.isLoading = false; return; } const argsJson = JSON.stringify(args); if (argsJson !== lastArgsJson) { - console.log('[convex-polling] Args changed, setting loading'); state.isLoading = true; lastArgsJson = argsJson; } try { - console.log('[convex-polling] Polling query with args:', args); const result = await client.query(query, args); - console.log('[convex-polling] Query result:', result); state.data = result; state.error = null; state.isLoading = false; } catch (err) { - console.error('[convex-polling] Query error:', err); state.error = err instanceof Error ? err : new Error(String(err)); state.isLoading = false; } diff --git a/frontend/src/routes/[mnemonic]/+page.svelte b/frontend/src/routes/[mnemonic]/+page.svelte index e4aa5fe..d97f4ec 100644 --- a/frontend/src/routes/[mnemonic]/+page.svelte +++ b/frontend/src/routes/[mnemonic]/+page.svelte @@ -10,7 +10,6 @@ const usePolling = getContext('convex-use-polling') ?? false; let mnemonic = $derived(page.params.mnemonic); - let debugInfo = $state(''); const chatDataWs = usePolling ? null @@ -40,9 +39,11 @@ : [] ); + let messagesContainer = $state(null); + $effect(() => { - if (messages.length) { - window.scrollTo(0, document.body.scrollHeight); + if (messages.length && messagesContainer) { + messagesContainer.scrollTop = messagesContainer.scrollHeight; } }); @@ -94,34 +95,27 @@ Chat - + -
-
- mode: {usePolling ? 'polling' : 'websocket'}
- mnemonic: {mnemonic}
- loading: {chatData.isLoading}
- error: {chatData.error?.message ?? 'none'}
- data: {chatData.data ? 'yes' : 'no'} -
- +
{#if chatData.isLoading} -
- Loading... ({usePolling ? 'polling' : 'ws'}) -
+
Loading...
{:else if chatData.error} -
-
Error:
-
{chatData.error.message}
-
Mode: {usePolling ? 'polling' : 'websocket'}
+
+
Error
+
{chatData.error.message}
{:else if !chatData.data} -
Chat not found
+
Not found
{:else} -
+
{#each messages as message (message._id)} - {#if followUpOptions.length > 0} -
- +
+ {#if followUpOptions.length > 0} +
+ +
+ {/if} + +
+ +
+ +
- {/if} - -
- -
- -
-
{/if}
diff --git a/frontend/src/routes/layout.css b/frontend/src/routes/layout.css index 8aeca2d..9d12813 100644 --- a/frontend/src/routes/layout.css +++ b/frontend/src/routes/layout.css @@ -1,5 +1,22 @@ @import 'tailwindcss'; +html, +body { + background: black; + overflow: hidden; + overscroll-behavior: none; + -webkit-overflow-scrolling: touch; + touch-action: pan-y; + position: fixed; + inset: 0; + width: 100%; + height: 100%; +} + +* { + -webkit-tap-highlight-color: transparent; +} + .prose-mini h1, .prose-mini h2, .prose-mini h3,