From 8a3bef0addb305154aff69b08fa4f0aff247f20b Mon Sep 17 00:00:00 2001 From: Martin Dvorak Date: Sun, 11 Oct 2026 20:11:11 +0000 Subject: [PATCH] Chat layout: history in the main sidebar, consistent header, cleaner icon - Desktop: on /chat the main sidebar shows the chat list (search, New chat, items with rename/delete, active highlight) in place of the deck navigation; the separate second column is gone and the chat uses the full width. The expand/collapse chevron sits outside the swappable section and a collapsed rail stays clean (the highlighted Chat row already opens a new chat). Active conversation travels via a tiny store (lib/chat-active) so the sidebar needs no useSearchParams and pages stay static. - Header (phones): history, theme and New chat are now identical chips - same 44px hit area, rounded-2xl, border/surface tokens, size-5 icons, even spacing; the title block truncates cleanly. ThemeToggle gained a 'plain' variant so the header styles it without touching other pages. - ChatIcon redrawn (clean message-circle, no inner lines) and the empty state uses the app's icon-chip pattern (size-12 chip, accent-600/200) instead of the bare oversized glyph; the model chip icon follows. - Also fixed a pre-existing dev-only breakage found while verifying: the tab-bar bounce animated three keyframes with a spring, which framer motion's dev build throws on - breaking client updates in the dev instance (library tab switching, sheet Escape). It now uses a tween. - Dev metadata keeps the Apple icons in both branches. - SW -> freezmo-v35. --- app/layout.tsx | 22 +++--- components/Sidebar.tsx | 38 +++++++--- components/TabBar.tsx | 5 +- components/ThemeToggle.tsx | 9 ++- components/chat/ChatScreen.tsx | 100 ++++++++++++++----------- components/chat/SidebarChatSection.tsx | 59 +++++++++++++++ components/icons.tsx | 3 +- lib/chat-active.ts | 29 +++++++ public/sw.js | 2 +- 9 files changed, 192 insertions(+), 75 deletions(-) create mode 100644 components/chat/SidebarChatSection.tsx create mode 100644 lib/chat-active.ts diff --git a/app/layout.tsx b/app/layout.tsx index 1343f4e..e25fc1e 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -36,18 +36,16 @@ export const metadata: Metadata = { { url: "/icons/splash-1668x2388.png", media: "(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)" }, ], }, - icons: IS_DEV_INSTANCE - ? { - // Dev wears its own favicon so the two instances are never confused. - icon: [{ url: "/icons/dev-favicon.svg", type: "image/svg+xml" }], - } - : { - icon: [ - // ?v=2 busts browser favicon caches after the icon redesign. - { url: "/icons/favicon-32.png?v=2", sizes: "32x32", type: "image/png" }, - { url: "/icons/icon-192.png?v=2", sizes: "192x192", type: "image/png" }, - { url: "/icons/icon-512.png?v=2", sizes: "512x512", type: "image/png" }, - ], + icons: { + icon: IS_DEV_INSTANCE + ? // Dev wears its own favicon so the two instances are never confused. + [{ url: "/icons/dev-favicon.svg", type: "image/svg+xml" }] + : [ + // ?v=2 busts browser favicon caches after the icon redesign. + { url: "/icons/favicon-32.png?v=2", sizes: "32x32", type: "image/png" }, + { url: "/icons/icon-192.png?v=2", sizes: "192x192", type: "image/png" }, + { url: "/icons/icon-512.png?v=2", sizes: "512x512", type: "image/png" }, + ], apple: [ { url: "/icons/apple-touch-icon.png?v=2", sizes: "180x180" }, { url: "/icons/apple-touch-icon-167.png?v=2", sizes: "167x167" }, diff --git a/components/Sidebar.tsx b/components/Sidebar.tsx index ee89d08..8f74d0e 100644 --- a/components/Sidebar.tsx +++ b/components/Sidebar.tsx @@ -1,8 +1,11 @@ "use client"; import Link from "next/link"; +import { usePathname } from "next/navigation"; import { useMemo, useState, useSyncExternalStore, type ReactNode } from "react"; +import { SidebarChatSection } from "@/components/chat/SidebarChatSection"; + import { ChatIcon, ChevronLeftIcon, @@ -35,6 +38,8 @@ const COLLAPSE_KEY = "freezmo.sidebarCollapsed"; * there is no drawer any more, so this is the only consumer of the rail. */ function NavContent({ collapsed = false }: { collapsed?: boolean }) { + const pathname = usePathname(); + const onChat = pathname === "/chat"; const decks = useSyncExternalStore(deckStore.subscribe, deckStore.getSnapshot, deckStore.getServerSnapshot); const folders = useSyncExternalStore( folderStore.subscribe, @@ -149,6 +154,7 @@ function NavContent({ collapsed = false }: { collapsed?: boolean }) { {/* chat with your notes --------------------------------------------- */} @@ -156,19 +162,27 @@ function NavContent({ collapsed = false }: { collapsed?: boolean }) { {!collapsed ? {t("chat.nav")} : null} -