notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 14b295c077173c9acea2fd0fe293ef7732943c57
parent ed31aa61534a66de02d6bb4c06b6fa4edcdb5af1
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 21 Feb 2026 20:04:55 -0800

clippy: fix collapsible_if and too_many_arguments

- nostrverse: collapse nested if-let into single let-chain
- columns: group cur_account and to_response into SelectionHandler struct

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
M.beads/issues.jsonl | 28++++++++++++++--------------
Mcrates/notedeck_columns/src/ui/add_column.rs | 22+++++++++++++++++-----
Mcrates/notedeck_dave/src/git_status.rs | 3+--
Mcrates/notedeck_nostrverse/src/lib.rs | 8++++----
4 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl @@ -1,24 +1,24 @@ {"id":"notedeck-0mh","title":"Remote NIP-50 search","description":"GitHub #1110: Implement remote search using NIP-50 protocol. See https://github.com/damus-io/notedeck/issues/1110","status":"open","priority":2,"issue_type":"feature","owner":"jb55@jb55.com","created_at":"2026-01-30T12:50:41.013086749-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:50:41.013086749-08:00","labels":["columns"]} {"id":"notedeck-27x","title":"Auto-steal focus should return to original session","description":"In crates/notedeck_dave, when an agent steals focus from another agent to ask a question, I want it to focus back to where it was after the interaction completes.","status":"closed","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:38:44.526107651-08:00","created_by":"William Casarin","updated_at":"2026-01-30T22:35:00.825936422-08:00","closed_at":"2026-01-30T22:35:00.825936422-08:00","close_reason":"Auto-steal focus now returns to original session after interaction completes","labels":["dave"]} {"id":"notedeck-2yj","title":"Profile search","description":"GitHub #1111: Extend search functionality to include profile lookups. See https://github.com/damus-io/notedeck/issues/1111","status":"open","priority":2,"issue_type":"feature","owner":"jb55@jb55.com","created_at":"2026-01-30T12:50:36.780164431-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:50:36.780164431-08:00","labels":["columns"]} -{"id":"notedeck-3ns","title":"Approve/deny view text not wrapping - goes off screen","description":"The approve/deny view for tool calls doesn't wrap text properly. Long descriptions go all the way off the screen, making them unreadable.","status":"open","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:52:24.878602874-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:52:24.878602874-08:00","labels":["dave"]} -{"id":"notedeck-4no","title":"Follow packs show blank profiles","description":"GitHub #1107: Some profiles in follow packs display blank. See https://github.com/damus-io/notedeck/issues/1107","status":"open","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:46:44.374295002-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:46:44.374295002-08:00","labels":["columns"]} +{"id":"notedeck-3ns","title":"Approve/deny view text not wrapping - goes off screen","description":"The approve/deny view for tool calls doesn't wrap text properly. Long descriptions go all the way off the screen, making them unreadable.","status":"closed","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:52:24.878602874-08:00","created_by":"William Casarin","updated_at":"2026-02-19T08:32:39.395960931-08:00","closed_at":"2026-02-19T08:32:39.395960931-08:00","close_reason":"Fixed by making handle_new_chat() check ai_mode - in chat mode, sessions are created directly without the directory picker overlay","labels":["dave"]} +{"id":"notedeck-4no","title":"Follow packs show blank profiles","description":"GitHub #1107: Some profiles in follow packs display blank. See https://github.com/damus-io/notedeck/issues/1107","status":"closed","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:46:44.374295002-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:19:08.222622866-08:00","closed_at":"2026-02-18T16:19:08.222622866-08:00","close_reason":"Closing - not a priority right now","labels":["columns"]} {"id":"notedeck-84e","title":"Link previews (OpenGraph)","description":"GitHub #992: Display link previews using OpenGraph metadata. See https://github.com/damus-io/notedeck/issues/992","status":"open","priority":3,"issue_type":"feature","owner":"jb55@jb55.com","created_at":"2026-01-30T12:51:46.117752018-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:51:46.117752018-08:00","labels":["columns"]} {"id":"notedeck-ajn","title":"Contact lists aren't updated periodically","description":"GitHub #575: Contact lists don't refresh periodically as they should. See https://github.com/damus-io/notedeck/issues/575","status":"open","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:49:46.741346469-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:49:46.741346469-08:00","labels":["columns"]} -{"id":"notedeck-azp","title":"Column requires opening app twice to show new notes","description":"GitHub #780: Columns require opening notedeck twice to display new notes on initial launch. See https://github.com/damus-io/notedeck/issues/780","status":"open","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:49:39.093911034-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:49:39.093911034-08:00","labels":["columns"]} +{"id":"notedeck-azp","title":"Column requires opening app twice to show new notes","description":"GitHub #780: Columns require opening notedeck twice to display new notes on initial launch. See https://github.com/damus-io/notedeck/issues/780","status":"closed","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:49:39.093911034-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:07:26.357794127-08:00","closed_at":"2026-02-18T16:07:26.357794127-08:00","close_reason":"Closing - not a priority right now","labels":["columns"]} {"id":"notedeck-bce","title":"Handle ExitPlanMode tool call","description":"Handle ExitPlanMode which simply exits plan mode. Claude-code sends this when it's done its planning phase.","status":"closed","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:40:17.311242243-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:38:19.839039601-08:00","closed_at":"2026-01-30T12:38:19.839039601-08:00","close_reason":"Implemented ExitPlanMode UI with Approve/Reject buttons. When approved, exits plan mode and allows the tool call. UI shows PLAN badge with 'Plan ready for approval' message.","labels":["dave"]} {"id":"notedeck-c3p","title":"Implement multiline message composer (Signal-style)","description":"Replaced singleline TextEdit with multiline, using Signal-style keybindings: Enter to send, Shift+Enter for newline. Based on existing dave.rs implementation.","status":"closed","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T12:32:45.563930191-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:33:07.061369966-08:00","closed_at":"2026-01-30T12:33:07.061369966-08:00","close_reason":"Implemented: Changed TextEdit from singleline to multiline with Signal-style keybindings (Enter=send, Shift+Enter=newline) in convo.rs"} -{"id":"notedeck-cf0","title":"Preserve edit view after approval/denial","description":"When approving or denying an edit, keep the diff visible instead of making it disappear. Allows reviewing what was changed even after responding.","status":"open","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:41:04.789975491-08:00","created_by":"William Casarin","updated_at":"2026-01-30T11:41:04.789975491-08:00","labels":["dave"]} -{"id":"notedeck-dx2","title":"Multi column image reply bug","description":"GitHub #1104: Images in multi-column replies appear in wrong column. See https://github.com/damus-io/notedeck/issues/1104","status":"open","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:47:15.806023697-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:47:15.806023697-08:00","labels":["columns"]} +{"id":"notedeck-cf0","title":"Preserve edit view after approval/denial","description":"When approving or denying an edit, keep the diff visible instead of making it disappear. Allows reviewing what was changed even after responding.","status":"closed","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:41:04.789975491-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:19:07.895887047-08:00","closed_at":"2026-02-18T16:19:07.895887047-08:00","close_reason":"Closing - not a priority right now","labels":["dave"]} +{"id":"notedeck-dx2","title":"Multi column image reply bug","description":"GitHub #1104: Images in multi-column replies appear in wrong column. See https://github.com/damus-io/notedeck/issues/1104","status":"closed","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:47:15.806023697-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:19:08.325125975-08:00","closed_at":"2026-02-18T16:19:08.325125975-08:00","close_reason":"Closing - not a priority right now","labels":["columns"]} {"id":"notedeck-fs8","title":"Ctrl+P not dropping from NeedsInput to Done","description":"Commit c6a96d8dbfef is supposed to enable dropping from NeedsInput to Done with Ctrl+P, but it's not working. The commit message says Ctrl+P should navigate backward within a priority group and drop to the next lower priority level when at the first item (NeedsInput → Error → Done).","status":"closed","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:42:27.63658035-08:00","created_by":"William Casarin","updated_at":"2026-01-30T11:57:51.25992885-08:00","closed_at":"2026-01-30T11:57:51.25992885-08:00","close_reason":"Fixed swapped keybindings in keybindings.rs:82-90 - Ctrl+N now returns FocusQueueNext (higher priority) and Ctrl+P returns FocusQueuePrev (lower priority)","labels":["dave"]} -{"id":"notedeck-gj0","title":"Timeline carousel does not work","description":"GitHub #1006: Image carousel swiping functionality needs implementation or repair for navigating images. See https://github.com/damus-io/notedeck/issues/1006","status":"open","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:47:49.42410683-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:47:49.42410683-08:00","labels":["columns"]} -{"id":"notedeck-h9s","title":"Note not ingesting when sending locally (offline)","description":"GitHub #1050: Offline notes fail to sync when device reconnects; messages aren't appearing even after network restored. See https://github.com/damus-io/notedeck/issues/1050","status":"open","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:47:34.188084601-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:47:34.188084601-08:00","labels":["columns"]} -{"id":"notedeck-hav","title":"Add auto-accept mode for agent tool calls","description":"Add a toggle that automatically approves agent tool calls without requiring manual confirmation. Useful for trusted tasks or batch mode. Could be global or per-agent.","status":"open","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:40:00.952701242-08:00","created_by":"William Casarin","updated_at":"2026-01-30T11:40:00.952701242-08:00","labels":["dave"]} -{"id":"notedeck-i40","title":"Quoted note target changes depending on wide or selected mode","description":"GitHub #1117: Quoted note references inconsistent based on view mode. See https://github.com/damus-io/notedeck/issues/1117","status":"open","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:45:42.264025111-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:45:42.264025111-08:00","labels":["columns"]} -{"id":"notedeck-j8c","title":"Chat sidebar should show last message from user or AI","description":"Chat sidebar text should show the user's or AI's last message, not our last message.","status":"open","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:39:11.482262998-08:00","created_by":"William Casarin","updated_at":"2026-01-30T11:39:11.482262998-08:00","labels":["dave"]} -{"id":"notedeck-kpa","title":"Zap notification","description":"GitHub #1037: Notify users when zapped, showing zap amount, sender, and zapped content details. See https://github.com/damus-io/notedeck/issues/1037","status":"open","priority":3,"issue_type":"feature","owner":"jb55@jb55.com","created_at":"2026-01-30T12:51:29.181749931-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:51:29.181749931-08:00","labels":["columns"]} -{"id":"notedeck-p1n","title":"NIP-05 validation not working as intended","description":"GitHub #1274: NIP-05 validation feature is malfunctioning. See https://github.com/damus-io/notedeck/issues/1274","status":"open","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:38:30.276030933-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:38:30.276030933-08:00","labels":["columns"]} +{"id":"notedeck-gj0","title":"Timeline carousel does not work","description":"GitHub #1006: Image carousel swiping functionality needs implementation or repair for navigating images. See https://github.com/damus-io/notedeck/issues/1006","status":"closed","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:47:49.42410683-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:19:08.434225926-08:00","closed_at":"2026-02-18T16:19:08.434225926-08:00","close_reason":"Closing - not a priority right now","labels":["columns"]} +{"id":"notedeck-h9s","title":"Note not ingesting when sending locally (offline)","description":"GitHub #1050: Offline notes fail to sync when device reconnects; messages aren't appearing even after network restored. See https://github.com/damus-io/notedeck/issues/1050","status":"closed","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:47:34.188084601-08:00","created_by":"William Casarin","updated_at":"2026-02-17T17:11:00.7604656-08:00","closed_at":"2026-02-17T17:11:00.7604656-08:00","close_reason":"Added local ndb ingestion in post.rs execute(). Notes are now ingested into the local database before sending to relays, so they appear immediately even when offline. Commit: baa1655c55ce","labels":["columns"]} +{"id":"notedeck-hav","title":"Add auto-accept mode for agent tool calls","description":"Add a toggle that automatically approves agent tool calls without requiring manual confirmation. Useful for trusted tasks or batch mode. Could be global or per-agent.","status":"closed","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:40:00.952701242-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:19:07.675673345-08:00","closed_at":"2026-02-18T16:19:07.675673345-08:00","close_reason":"Closing - not a priority right now","labels":["dave"]} +{"id":"notedeck-i40","title":"Quoted note target changes depending on wide or selected mode","description":"GitHub #1117: Quoted note references inconsistent based on view mode. See https://github.com/damus-io/notedeck/issues/1117","status":"closed","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:45:42.264025111-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:19:08.112313115-08:00","closed_at":"2026-02-18T16:19:08.112313115-08:00","close_reason":"Closing - not a priority right now","labels":["columns"]} +{"id":"notedeck-j8c","title":"Chat sidebar should show last message from user or AI","description":"Chat sidebar text should show the user's or AI's last message, not our last message.","status":"closed","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:39:11.482262998-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:19:07.562465153-08:00","closed_at":"2026-02-18T16:19:07.562465153-08:00","close_reason":"Closing - not a priority right now","labels":["dave"]} +{"id":"notedeck-kpa","title":"Zap notification","description":"GitHub #1037: Notify users when zapped, showing zap amount, sender, and zapped content details. See https://github.com/damus-io/notedeck/issues/1037","status":"in_progress","priority":3,"issue_type":"feature","owner":"jb55@jb55.com","created_at":"2026-01-30T12:51:29.181749931-08:00","created_by":"William Casarin","updated_at":"2026-02-19T08:33:39.25553682-08:00","labels":["columns"]} +{"id":"notedeck-p1n","title":"NIP-05 validation not working as intended","description":"GitHub #1274: NIP-05 validation feature is malfunctioning. See https://github.com/damus-io/notedeck/issues/1274","status":"closed","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:38:30.276030933-08:00","created_by":"William Casarin","updated_at":"2026-02-18T14:45:59.805875423-08:00","closed_at":"2026-02-18T14:45:59.805875423-08:00","close_reason":"Already fixed","labels":["columns"]} {"id":"notedeck-pj7","title":"Like button not visible in light theme","description":"GitHub #1246: Like button rendering visibility issue when switching to light theme mode. See https://github.com/damus-io/notedeck/issues/1246","status":"closed","priority":2,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:41:16.601075159-08:00","created_by":"William Casarin","updated_at":"2026-01-30T13:38:50.529278612-08:00","closed_at":"2026-01-30T13:38:50.529278612-08:00","close_reason":"Fixed by applying text color tint unconditionally in like_button()","labels":["columns"]} -{"id":"notedeck-war","title":"MacOS crash on PFP → Side menu Accounts","description":"GitHub #1270: Application crashes when navigating to Accounts via profile picture menu due to 'layer_id change panic'. See https://github.com/damus-io/notedeck/issues/1270","status":"open","priority":1,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:41:09.082890703-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:41:09.082890703-08:00","labels":["columns"]} -{"id":"notedeck-xer","title":"Persist conversation across app restarts","description":"Save and restore conversation state so it survives app restarts.","status":"open","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:40:11.196068397-08:00","created_by":"William Casarin","updated_at":"2026-01-30T11:40:11.196068397-08:00","labels":["dave"]} +{"id":"notedeck-war","title":"MacOS crash on PFP → Side menu Accounts","description":"GitHub #1270: Application crashes when navigating to Accounts via profile picture menu due to 'layer_id change panic'. See https://github.com/damus-io/notedeck/issues/1270","status":"closed","priority":1,"issue_type":"bug","owner":"jb55@jb55.com","created_at":"2026-01-30T12:41:09.082890703-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:19:08.002872446-08:00","closed_at":"2026-02-18T16:19:08.002872446-08:00","close_reason":"Closing - not a priority right now","labels":["columns"]} +{"id":"notedeck-xer","title":"Persist conversation across app restarts","description":"Save and restore conversation state so it survives app restarts.","status":"closed","priority":2,"issue_type":"task","owner":"jb55@jb55.com","created_at":"2026-01-30T11:40:11.196068397-08:00","created_by":"William Casarin","updated_at":"2026-02-18T16:19:07.782704625-08:00","closed_at":"2026-02-18T16:19:07.782704625-08:00","close_reason":"Closing - not a priority right now","labels":["dave"]} {"id":"notedeck-zg7","title":"Quote notification","description":"GitHub #1041: Implement notifications when users' posts are quoted by others. See https://github.com/damus-io/notedeck/issues/1041","status":"open","priority":3,"issue_type":"feature","owner":"jb55@jb55.com","created_at":"2026-01-30T12:50:58.370192754-08:00","created_by":"William Casarin","updated_at":"2026-01-30T12:50:58.370192754-08:00","labels":["columns"]} diff --git a/crates/notedeck_columns/src/ui/add_column.rs b/crates/notedeck_columns/src/ui/add_column.rs @@ -40,6 +40,17 @@ pub enum AddColumnResponse { ExternalIndividual, } +struct SelectionHandler<'a> { + cur_account: &'a UserAccount, + to_response: fn(Pubkey, &UserAccount) -> AddColumnResponse, +} + +impl<'a> SelectionHandler<'a> { + fn response(&self, pubkey: Pubkey) -> AddColumnResponse { + (self.to_response)(pubkey, self.cur_account) + } +} + pub enum NotificationColumnType { Contacts, External, @@ -354,8 +365,10 @@ impl<'a> AddColumnView<'a> { self.ndb, self.img_cache, self.i18n, - self.cur_account, - to_response, + &SelectionHandler { + cur_account: self.cur_account, + to_response, + }, ) } else { self.key_state_map.remove(&id); @@ -688,8 +701,7 @@ fn contacts_list_column_ui( ndb: &Ndb, img_cache: &mut Images, i18n: &mut Localization, - cur_account: &UserAccount, - to_response: fn(Pubkey, &UserAccount) -> AddColumnResponse, + handler: &SelectionHandler<'_>, ) -> Option<AddColumnResponse> { let ContactState::Received { contacts: contact_set, @@ -703,7 +715,7 @@ fn contacts_list_column_ui( let resp = ContactsListView::new(contact_set, jobs, ndb, img_cache, &txn, i18n).ui(ui); resp.output.map(|a| match a { - notedeck_ui::ContactsListAction::Select(pubkey) => to_response(pubkey, cur_account), + notedeck_ui::ContactsListAction::Select(pubkey) => handler.response(pubkey), }) } diff --git a/crates/notedeck_dave/src/git_status.rs b/crates/notedeck_dave/src/git_status.rs @@ -185,8 +185,7 @@ fn parse_git_status(output: &str) -> GitStatusData { fn run_git_status(cwd: &Path) -> GitStatusResult { let mut cmd = std::process::Command::new("git"); - cmd.args(["status", "--short", "--branch"]) - .current_dir(cwd); + cmd.args(["status", "--short", "--branch"]).current_dir(cwd); #[cfg(target_os = "windows")] { diff --git a/crates/notedeck_nostrverse/src/lib.rs b/crates/notedeck_nostrverse/src/lib.rs @@ -243,10 +243,10 @@ impl NostrverseApp { let avatar_yaw = r.avatar_yaw(); // Update self-user's position from the controller - if let Some(pos) = avatar_pos { - if let Some(self_user) = self.state.users.iter_mut().find(|u| u.is_self) { - self_user.position = pos; - } + if let Some(pos) = avatar_pos + && let Some(self_user) = self.state.users.iter_mut().find(|u| u.is_self) + { + self_user.position = pos; } // Sync all user avatars to the scene