Skip to content

Add Sync Status Icon to the Sidebar: Idle, Syncing, and Error States #28

@TheZupZup

Description

@TheZupZup

Overview

Context: Sync feedback is currently buried in two places:

  1. SettingsScreen shows the last sync report (notes pulled/pushed, conflicts, duration)
  2. NotebookSidebar has a sync button with no feedback at all — tapping it calls triggerSync() but nothing visually changes

There is no persistent sync status visible in the main app. A user who just synced has no way to know whether it succeeded without opening Settings.

This issue adds a small sync status icon to the NotebookSidebar header that reflects the current state.

What needs to be done

Step 1 — State in AppState

  • Add a SyncState enum with three values: idle, syncing, error
  • Add SyncState _syncState = SyncState.idle to AppState with a public getter
  • In AppState.triggerSync():
    • Set _syncState = SyncState.syncing and notifyListeners() before the API call
    • Set _syncState = SyncState.idle on success
    • Set _syncState = SyncState.error on failure
  • Add String? _lastSyncError to store the error message when _syncState == SyncState.error

Step 2 — Icon in NotebookSidebar

  • In notebook_sidebar.dart, replace the current plain IconButton sync button with a widget that reads AppState.syncState:
    • idle → cloud-done icon (Icons.cloud_done_outlined), grey tint
    • syncing → a small CircularProgressIndicator (size ~16px) in place of the icon
    • error → cloud-error icon (Icons.cloud_off_outlined), red tint
  • Add a Tooltip on the icon showing the last sync time (from getSyncStatus()) or the error message

Step 3 — Last sync time

  • After a successful triggerSync(), call ApiClient.getSyncStatus() and store _lastSyncTime in AppState
  • Display it in the tooltip: e.g., "Last synced: 2 minutes ago"

Goal

The user can glance at the sync icon in the sidebar and immediately know: is sync idle, currently running, or broken? Hovering/long-pressing shows the last sync time or error. No need to open Settings for basic sync health.

Where to look

  • app/lib/widgets/notebook_sidebar.dart — the sync IconButton in the header
  • app/lib/services/app_state.darttriggerSync(), add SyncState enum and fields
  • app/lib/services/api_client.dartgetSyncStatus() already returns notes_pulled, notes_pushed, duration_seconds

Testing steps

  • Tap sync — verify the icon shows a spinner while running, then returns to the done icon
  • Configure invalid WebDAV credentials and tap sync — verify the icon turns red
  • Hover over the icon after a successful sync — verify the tooltip shows the last sync time
  • Restart the app — verify the icon starts in idle state (not error)

Related to: #17, #25, #26

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions