Skip to content

Bookmark count badge in Navigation Sidebar does not update in real time #613

Description

@haiphucnguyen

Summary

When a user bookmarks or un-bookmarks a message inside an active chat session, the bookmark count badge shown on that session's entry in the Navigation Sidebar does not reflect the change immediately. The badge only updates after the sidebar is explicitly reloaded (e.g. the app re-fetches sessions from the database)

Steps to Reproduce

  • Open any chat session that has at least one message.
  • Bookmark a message using the bookmark toggle button.
  • Observe the session's bookmark count badge in the Navigation Sidebar - it does not increment.
  • Un-bookmark the same message - the badge does not decrement.

Expected Behavior

The bookmark count badge in the Navigation Sidebar should update instantly and in real time as the user adds or removes bookmarks, consistent with the optimistic UI update already applied to the chat view itself.

Root Cause

The two components that need to stay in sync have no reactive link between them:

  • ChatViewModel performs an optimistic update on its local bookmarkedMessageIds state and persists the change to the database, but does not propagate the change to any shared state.
  • SessionsViewModel owns bookmarkCountsBySession - the map that drives the sidebar badge - and only populates it once on initial load via loadRecentSessions(). It is never updated when a bookmark action occurs in a session.
    NavigationSidebar reads bookmarkCountsBySession from SessionsViewModel and renders the badge, but since the map is never refreshed, the badge stays stale.

Proposed Solution

Introduce a shared reactive layer so that any bookmark change is automatically reflected in the sidebar without requiring a full reload.

  1. Create a shared BookmarkCountsStore (or extend an existing service layer)
    Introduce a lightweight shared observable - e.g. a StateFlow<Map<String, Int>> - that holds the current bookmark counts keyed by session ID. This can live in the service layer (ChatSessionService) or as a standalone in-memory store injected into both ViewModels.
  2. Update ChatViewModel to emit through the shared store
    After a successful toggleBookmark() call, ChatViewModel should update the shared StateFlow with the new count for the current session (either by applying a delta or re-querying the count for just that session). The existing optimistic update logic for bookmarkedMessageIds stays as-is.
  3. Update SessionsViewModel to collect from the shared store
    SessionsViewModel should collect the shared StateFlow and keep bookmarkCountsBySession in sync. On initial load it can seed the flow from the database as it does today; after that, updates flow automatically.
  4. Wire up in the app entry point
    In Main.kt / AskimoApp.kt, ensure both ChatViewModel and SessionsViewModel receive the same shared store instance so they operate on the same source of truth.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions