You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(ux-nav): close out spec — flip [active]→[landed], refresh sections 1/4/5 to match realised UX (#655)
Audit-and-align pass surfaced 5 findings against
docs/specs/2026-03-25-ux-navigation-improvements-design.md:
1. SettingsTab enum has 5 variants in code (Profile, Server, Roles,
Presence, Notifications); spec listed only the original 3.
Presence + Notifications were added by Phase 1e/1f. Updated the
enum example + tab listing to match.
2. Server context menu has 2 items in code (Server Settings, Leave Server),
not the 3 the spec listed. The standalone "Invite" entry was dropped
because invite generation is reachable from the Server settings tab.
Documented the dropped item with the rationale.
3. Quick Peer ID Copy lives in the profile-card popover, not as a sidebar
icon. Phase 2c consolidated all self-profile actions into the popover
to keep the always-visible sidebar uncluttered. Rewrote §5 to describe
the realised shape and note the supersession.
4. `ServerList` was renamed to `GroveRail` during the Phase 1a desktop-shell
refactor. Updated §4 implementation note.
5. `leave_server` is now actor-based (mutates `server_registry_addr` via
`willow_actor::state::mutate`); the spec described direct SharedState
mutation + explicit storage calls. Rewrote the `leave_server()` block
to describe the actor-pipeline shape and added a migration note.
Added Date/Status/Implementation plan header per the docs-organization
convention (PR #653). README master index flipped [active] → [landed].
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/specs/2026-03-25-ux-navigation-improvements-design.md
+31-8Lines changed: 31 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,9 @@
1
1
# UX Navigation Improvements Design
2
2
3
+
**Date:** 2026-03-25
4
+
**Status:** landed — unified settings panel, confirmation dialogs, breadcrumbs, server context menu, peer-ID copy affordance (relocated to profile card), and Ctrl+K palette all shipped via [`docs/plans/2026-03-25-ux-navigation-improvements.md`](../plans/2026-03-25-ux-navigation-improvements.md). Spec sections 1, 4, 5 below were refreshed after a 2026-05 audit to match the realised UX (extra Presence/Notifications tabs, GroveRail rename, actor-based `leave_server`, peer-ID copy via profile card).
The Willow web UI has several navigation and UX friction points:
@@ -26,6 +30,8 @@ Replace the three separate panels (`SettingsPanel`, `ServerSettingsPanel`, `Role
26
30
-**Profile** — display name, peer ID copy (current SettingsPanel content)
27
31
-**Server** — server name, description, invite generation (current ServerSettingsPanel content minus roles)
28
32
-**Roles** — role CRUD, permission toggles, assignment (current RoleManager content)
33
+
-**Presence** — self-presence override menu and 7-state catalog (added by Phase 1e)
34
+
-**Notifications** — per-surface mute overrides and OS push contract (added by Phase 1f)
29
35
30
36
**State changes:**
31
37
- Remove `show_server_settings` signal entirely from `UiState`/`UiWriteSignals`.
@@ -39,6 +45,8 @@ pub enum SettingsTab {
39
45
Profile,
40
46
Server,
41
47
Roles,
48
+
Presence,
49
+
Notifications,
42
50
}
43
51
```
44
52
@@ -99,27 +107,42 @@ Right-click (desktop) or long-press (mobile) on a server icon shows a popup menu
99
107
100
108
**Menu items:**
101
109
-**Server Settings** — opens settings panel to "server" tab
102
-
-**Invite** — opens settings panel to "server" tab
103
110
-**Leave Server** — with confirmation dialog (destructive)
104
111
112
+
(A standalone "Invite" item was considered and dropped — invite generation is
113
+
reachable from the Server settings tab, so a separate menu entry would be
114
+
redundant.)
115
+
105
116
**Implementation:**
106
117
- New `components/context_menu.rs` — reusable positioned popup rendering at cursor/touch position.
107
-
- Context menu state is local to the `ServerList` component (not in global `UiState`), since it doesn't need to be shared. Uses local signals: `show_context_menu`, `menu_position` (x/y), `context_server_id`.
118
+
- Context menu state is local to the `GroveRail` component (formerly `ServerList`; renamed during the Phase 1a desktop-shell refactor and now the canonical name for the leftmost server-list rail). Uses local signals: `show_context_menu`, `menu_position` (x/y), `context_server_id`.
108
119
- Desktop: `on:contextmenu` on `.server-icon`, prevent default, show menu at mouse position.
109
120
- Mobile: reuse the same long-press pattern from `message.rs` (500ms timer, touchstart/touchend, haptic feedback) for consistency. Extract the long-press detection into a shared utility if practical, or duplicate the pattern with a comment noting the shared approach.
110
121
- Click outside or Escape dismisses.
111
122
112
-
**`leave_server()` in client:** This is a **local-only** operation (no P2P event, no state machine change). It removes the server from `SharedState.state.servers`, removes associated data from persistence (`storage::save_server_list`, `storage::save_server_by_id`), and switches to the next available server or clears `active_server` (returning to welcome if no servers remain). The event history for the left server is retained in storage (not purged).
123
+
**`leave_server()` in client:** This is a **local-only** operation (no P2P event, no state machine change). It mutates the `server_registry_addr` actor (via `willow_actor::state::mutate`) to remove the server from the registry, and switches to the next available server or clears `active_server` (returning to welcome if no servers remain). Persistence flows through the actor pipeline rather than direct `storage::save_*` calls — see `crates/client/src/servers.rs::leave_server`. The event history for the left server is retained in storage (not purged).
124
+
125
+
> Note on migration shape: the design originally sketched direct `SharedState.state.servers` mutation + explicit `storage::save_server_list`/`save_server_by_id` calls. The client was migrated to the actor model after this spec landed, so the post-migration shape (mutate the registry actor, let persistence flow through it) replaces the original sketch. Observable behaviour is unchanged.
113
126
114
127
**Files:** Modify `crates/client/src/lib.rs` to add `leave_server()` on `ClientHandle`.
115
128
116
129
### 5. Quick Peer ID Copy
117
130
118
-
Add a copy icon button in the sidebar user area (next to display name) that copies the user's peer ID to clipboard with a brief "Copied!" tooltip.
119
-
120
-
Both sides of the invite flow need to share peer IDs. Having it one click away in the always-visible sidebar eliminates navigating to settings just to copy your ID.
121
-
122
-
**Implementation:** Small copy icon button in the sidebar user area. `on:click` copies `handle.peer_id()` to clipboard via `navigator.clipboard.writeText()`. Shows "Copied!" tooltip briefly (CSS animation, auto-hides after 1.5s). The `peer_id` is available via `ClientHandle` from context — no new props needed on `Sidebar`.
131
+
Provide a single-click affordance to copy the user's peer ID for sharing in invite flows, without making the user navigate to settings.
132
+
133
+
**Realised shape (post-migration):** The me-strip in the channel sidebar
134
+
(`crates/web/src/components/channel_sidebar.rs`) is a single profile-open
135
+
button. Clicking it opens the profile card popover
136
+
(`crates/web/src/components/profile_card.rs`), which surfaces the peer-ID
137
+
fingerprint plus copy affordance. This is one extra click compared to the
138
+
original "icon button directly in the sidebar" sketch, but it intentionally
139
+
keeps the always-visible sidebar uncluttered and consolidates all self-
140
+
profile actions in a single popover. The peer-ID copy lives next to the
141
+
trust fingerprint, the display-name editor, and other profile-card content.
142
+
143
+
(The original design sketched a copy icon button next to the display name
144
+
in the sidebar with a `"Copied!"` tooltip. That UX was superseded by the
0 commit comments