Skip to content

Conversation

TGlide
Copy link
Member

@TGlide TGlide commented Oct 6, 2025

Here’s a clear, comprehensive set of changes you can paste into your PR description.


Summary

  • Introduce runed for scroll state & UI reactivity.
  • Stabilize message IDs across client/server (pre-seeded UUIDs) to avoid flicker/mismatch during optimistic updates.
  • UI/UX polish across chat, navigation, and settings; better hover states, empty states, and smoother scrolling.
  • Refactors to remove manual event listeners/observers, reduce DOM juggling, and simplify animations.

What changed

Dependencies

  • Add runed@^0.34.0 to app dependencies (package.json / package-lock.json).

    • runed peer deps: svelte ^5.7.0, optional @sveltejs/kit ^2.21.0.
    • Brings dequal, esm-env, and lz-string as deps.
  • Lockfile flags: several packages switched from "dev": true to "devOptional": true in package-lock.json (e.g., @sveltejs/kit, @sveltejs/vite-plugin-svelte, inspector, cookie, deepmerge, devalue, kleur, mri, sade, set-cookie-parser, vitefu).

  • Lockfile cleanups: removed some "peer": true" markers (dequal, lz-string).

Chat UI & interactions

CopyToClipBoardBtn.svelte

  • Visual feedback: shows a checkmark icon (~icons/carbon/checkmark) when copy succeeds.
  • Uses a derived Icon that toggles between copy and checkmark based on isSuccess.
  • No need for parent components to manage a transient “copied” state.

ChatMessage.svelte

  • Edit flow:

    • Replace DOM-level textarea management with a reactive editedContent binding.
    • On submit, retry uses editedContent directly.
  • Copy button: remove component-local isCopied wiring—now relies on CopyToClipBoardBtn’s internal success feedback.

  • Avatar:

    • MessageAvatar becomes sticky (sticky top-4), slightly larger (size-5) to improve alignment during streaming.
  • Edit chip:

    • Always present in layout, uses opacity transitions (opacity-0 group-hover:opacity-100) instead of toggling display to avoid layout shift.
  • Minor import tidy-ups & derived values (hasClientThink, etc.).

MessageAvatar.svelte

  • Animation refactor:

    • Start animation once and unpause when animating is true; pause on cleanup.
    • Switch <animate> fill to freeze for consistent frame retention.
    • Replace SVG <filter> blur with CSS blur (blur-[1.2px]) for simpler, faster rendering.
    • Remove explicit width/height attributes; sizing via class.

Scrolling controls (moved to runed)

ScrollToBottomBtn.svelte and ScrollToPreviousBtn.svelte

  • Replace manual ResizeObserver + scroll listeners with runed’s ScrollState.

  • Visibility now derived from arrival state:

    • Bottom button: !scrollState.arrived.bottom (offset 200).
    • Previous button: !scrollState.arrived.top (offset 100).
  • Removes custom cleanup logic and reduces event wiring.

Navigation & layout

NavMenu.svelte

  • Add empty-state copy: “No conversations yet.” when conversations.length === 0.

ExpandNavigation.svelte

  • Adjust alignment from items-centeritems-end to better line up with sidebar edge.

routes/+layout.svelte

  • Grid class cleanup; fix text-smdtext-sm.
  • Reposition ExpandNavigation inside a relative container next to the nav (absolute … -right-2), rather than offsetting from grid columns—prevents overlap and improves responsiveness.
  • Use an array-based class expression for readability and fewer string interpolations.

Settings: models list UX

routes/settings/(nav)/+layout.svelte

  • Change model entries from clickable <button> with goto() to <a href> anchors—improves semantics and supports open-in-new-tab.

  • Introduce masked, fading scroll container (.masked-overflow) for the models list:

    • Gradient masks at top/bottom to hint overflow.
    • Thin, themed scrollbars; overflow handling moved to inner container.
  • Minor spacing tweaks (e.g., input wrapper padding) and containment (overflow-hidden on outer, scroll on inner).

Conversation data flow & API

Client-side IDs & tree utilities

  • Pre-seed UUIDs on the client and send them to the server:

    • Generate userMessageId and/or assistantMessageId via v4() in routes/conversation/[id]/+page.svelte.
    • Pass these IDs down to creation helpers and request payload.
  • Tree helpers (addChildren, addSibling):

    • Now accept optional id on new nodes; otherwise still generate via v4().
    • Type change: NewNode<T> now allows an object with id (Omit<TreeNode<T>, "id"> | TreeNode<T>).

Message updates request

  • src/lib/utils/messageUpdates.ts:

    • MessageUpdateRequestOptions gets createdMessageIds.
    • Add created_message_ids to the request form data.

Server

  • routes/conversation/[id]/+server.ts:

    • Accept created_message_ids in request body (Zod schema).
    • When inserting user/assistant messages (including retry/continue paths), use provided IDs if present, otherwise generate.
    • Ensures client and server IDs match, preventing re-render churn after streaming begins.

UUID import fix

  • routes/conversation/[id]/+page.svelte: change import type { v4 }import { v4 } to actually call the function.

Rationale

  • Stability: Pre-seeded IDs keep optimistic UI in sync with server responses, eliminating node re-keying and content flicker.
  • Maintainability: runed replaces ad‑hoc scroll/observer code with declarative state—less code and fewer edge cases.
  • UX polish: clearer copy feedback, smooth hover exposure (no layout jumps), sticky avatar for reading continuity, better empty states, and a nicer settings scroller.
  • Semantics & accessibility: Use anchors for in-app links; improves keyboard and browser behaviors.

Testing / QA checklist

  • Copy to clipboard

    • Click copy on any message → icon changes to checkmark briefly, then returns to copy.
  • Edit flow

    • Click Edit on an assistant message → textarea shows existing content; submit triggers retry with edited content; no flashing or layout jump.
  • Scroll buttons

    • With long chat content:

      • Scroll up → “Scroll to previous” appears; clicking jumps to previous message anchor.
      • Scroll down a bit → “Scroll to bottom” appears; clicking jumps to bottom.
  • New conversation / empty state

    • When there are no conversations, the sidebar shows “No conversations yet.”.
  • Sidebar toggle

    • Toggle button aligns to the right edge of the sidebar; works collapsed/expanded without overlapping content.
  • Settings models list

    • List shows fade at top/bottom when overflowed; scrollbar is thin.
    • Each model row is an anchor that navigates (supports open in new tab).
    • “Active” badge still renders correctly.
  • Message ID stability

    • During normal send, retry (assistant), and retry with alternate prompt (user):

      • Inspect DOM keys or logs—IDs for the new user/assistant messages remain consistent between client creation and server acknowledgements (no re-keyed nodes).

Notes / Potential impacts

  • runed@0.34.0 expects svelte >= 5.7.0 and optionally @sveltejs/kit >= 2.21.0; our versions should satisfy this (verify in CI).
  • Lockfile flag changes (devOptional) came from resolver updates; they shouldn’t affect runtime, but call out in case your deploy pipeline treats optional dev deps differently.
  • CSS blur replacement in MessageAvatar slightly changes the glow; visually similar but less GPU work.

Files touched

  • Dependencies: package.json, package-lock.json

  • Chat UI:

    • src/lib/components/CopyToClipBoardBtn.svelte
    • src/lib/components/chat/ChatMessage.svelte
    • src/lib/components/chat/MessageAvatar.svelte
  • Scrolling:

    • src/lib/components/ScrollToBottomBtn.svelte
    • src/lib/components/ScrollToPreviousBtn.svelte
  • Navigation/Layout:

    • src/lib/components/ExpandNavigation.svelte
    • src/lib/components/NavMenu.svelte
    • src/routes/+layout.svelte
  • Settings:

    • src/routes/settings/(nav)/+layout.svelte (+ new masked overflow CSS)
  • Data model & API:

    • src/lib/utils/tree/addChildren.ts
    • src/lib/utils/tree/addSibling.ts
    • src/lib/utils/tree/tree.d.ts
    • src/lib/utils/messageUpdates.ts
    • src/routes/conversation/[id]/+page.svelte
    • src/routes/conversation/[id]/+server.ts

If you want, I can condense this into a shorter “Release notes” style section as well.

@TGlide TGlide self-assigned this Oct 6, 2025
@TGlide TGlide marked this pull request as ready for review October 8, 2025 19:04
@TGlide TGlide requested a review from gary149 October 8, 2025 19:04
TGlide and others added 3 commits October 8, 2025 20:17
Introduces a new favicon-dark.svg file in the static/huggingchat directory to support dark mode branding.
@TGlide TGlide closed this Oct 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants