-
Notifications
You must be signed in to change notification settings - Fork 48
Feature/UI improvements #1194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Feature/UI improvements #1194
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request implements a comprehensive UI/UX overhaul including new navigation, search functionality, profile features, and settings redesign. The changes add clickable usernames, profile badges for followed users, recent search history, enhanced settings with nested routes, profile statistics, and mouse navigation support.
Key Changes
- Added clickable usernames and profile badges indicating followed users
- Implemented recent search history with keyboard navigation
- Redesigned settings UI with categorized sections and nested routing
- Added profile statistics (following count) and "View as" context menu option
- Implemented mouse back/forward button navigation for columns
Reviewed Changes
Copilot reviewed 34 out of 34 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/notedeck_ui/src/widgets.rs | Added new button widgets (rounded, segmented) and helper functions for side panel styling |
| crates/notedeck_ui/src/username.rs | Made usernames clickable and added unused helper function |
| crates/notedeck_ui/src/profile/picture.rs | Added badge display for followed users on profile pictures |
| crates/notedeck_ui/src/profile/mod.rs | Added expandable/truncatable about section variants |
| crates/notedeck_ui/src/note/mod.rs | Made note headers clickable to navigate to profiles |
| crates/notedeck_columns/src/ui/widgets.rs | Added UserRow widget for displaying user information |
| crates/notedeck_columns/src/ui/side_panel.rs | Major redesign with new navigation buttons and connectivity indicator |
| crates/notedeck_columns/src/ui/settings.rs | Complete settings UI redesign with nested routes and modern layout |
| crates/notedeck_columns/src/ui/search/mod.rs | Added recent search history, keyboard navigation, and user search suggestions |
| crates/notedeck_columns/src/ui/search/state.rs | Added Default derive for FocusState enum |
| crates/notedeck_columns/src/ui/profile/mod.rs | Added profile statistics display and contacts list view |
| crates/notedeck_columns/src/route.rs | Added SettingsRoute enum and Following/FollowedBy routes |
| crates/notedeck_columns/src/app.rs | Added mouse back/forward navigation and hovered column tracking |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| fn ui_abbreviate_name_clickable(ui: &mut egui::Ui, name: &str, len: usize, color: Option<Color32>) -> bool { | ||
| let should_abbrev = name.len() > len; | ||
| let name = if should_abbrev { | ||
| let closest = notedeck::abbrev::floor_char_boundary(name, len); | ||
| &name[..closest] | ||
| } else { | ||
| name | ||
| }; | ||
|
|
||
| let resp1 = ui.add(egui::Label::new(colored_name(name, color)).sense(egui::Sense::click())); | ||
|
|
||
| let resp2 = if should_abbrev { | ||
| ui.add(egui::Label::new(colored_name("..", color)).sense(egui::Sense::click())) | ||
| } else { | ||
| resp1.clone() | ||
| }; | ||
|
|
||
| resp1.clicked() || resp2.clicked() | ||
| } |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function ui_abbreviate_name_clickable is defined but never used in the codebase. This appears to be dead code that should either be removed or integrated into the username clickability implementation if it was intended to replace the current approach.
| mod state; | ||
|
|
||
| pub use state::{FocusState, SearchQueryState, SearchState}; | ||
| pub use state::{FocusState, RecentSearchItem, SearchQueryState, SearchState}; |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RecentSearchItem is exported from the state module but is not defined in state.rs. This will cause a compilation error. The type needs to be defined in the state module or the export should be removed.
| pub use state::{FocusState, RecentSearchItem, SearchQueryState, SearchState}; | |
| pub use state::{FocusState, SearchQueryState, SearchState}; |
| }) | ||
| SearchState::New | SearchState::Navigating | SearchState::Typing(TypingType::Mention(_)) => { | ||
| if !self.query.string.is_empty() && !self.query.string.starts_with('@') { | ||
| self.query.user_results = self.note_context.ndb.search_profile(self.txn, &self.query.string, 10) |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The field user_results is accessed on SearchQueryState but is not defined in the struct in state.rs. This field needs to be added to the SearchQueryState struct definition.
| self.handle_mention_search(ui, &mut search_action); | ||
| } else { | ||
| self.query.user_results.clear(); | ||
| self.query.selected_index = -1; |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The field selected_index is accessed on SearchQueryState but is not defined in the struct in state.rs. This field needs to be added to the SearchQueryState struct definition.
| } | ||
|
|
||
| fn show_recent_searches(&mut self, ui: &mut egui::Ui, keyboard_resp: KeyboardResponse) -> Option<SearchAction> { | ||
| if self.query.recent_searches.is_empty() { |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The field recent_searches is accessed on SearchQueryState but is not defined in the struct in state.rs. This field needs to be added to the SearchQueryState struct definition with an appropriate type (likely Vec<RecentSearchItem>).
| ui.label("Recent"); | ||
| ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { | ||
| if ui.button(RichText::new("Clear all").size(14.0)).clicked() { | ||
| self.query.clear_recent_searches(); |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method clear_recent_searches is called on SearchQueryState but is not defined. This method needs to be implemented on the SearchQueryState type.
| } | ||
|
|
||
| if resp.secondary_clicked() || (is_selected && ui.input(|i| i.key_pressed(Key::Delete))) { | ||
| self.query.remove_recent_search(i); |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method remove_recent_search is called on SearchQueryState but is not defined. This method needs to be implemented on the SearchQueryState type to handle removal of search history items by index.
| None | ||
| } | ||
| SearchAction::NavigateToProfile(pubkey) => { | ||
| state.add_recent_profile(pubkey, state.string.clone()); |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method add_recent_profile is called on SearchQueryState but is not defined. This method needs to be implemented on the SearchQueryState type to handle adding profiles to recent search history.
| state.state = SearchState::Searched; | ||
| state.selected_index = -1; | ||
| state.user_results.clear(); | ||
| state.add_recent_query(state.string.clone()); |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method add_recent_query is called on SearchQueryState but is not defined. This method needs to be implemented on the SearchQueryState type to handle adding queries to recent search history.
| Some(SidePanelResponse::new(SidePanelAction::Relays, connectivity_resp)) | ||
| } else if home_resp.clicked() { | ||
| Some(SidePanelResponse::new(SidePanelAction::Home, home_resp)) | ||
| } else if opt_messages_resp.as_ref().map_or(false, |r| r.clicked()) { |
Copilot
AI
Nov 7, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Messages route variant is referenced in the side panel action handling but Route::Messages is not defined in the Route enum in route.rs. This will cause a compilation error when trying to navigate to messages.
|
i cherry-picked everything that wasn't a conflict: i decided to not pick:
since it doesn't fit our theme. but maybe we can just make customizable themes in the future |

No description provided.