Created
March 8, 2025 00:06
-
-
Save jb55/cc570409ba2ec378ab276b6e7ec9496e to your computer and use it in GitHub Desktop.
Auto focus on navigate example in notedeck
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit d85c6043b700783d825f6e5971f976e198fde112 | |
Author: William Casarin <[email protected]> | |
Date: Fri Mar 7 16:01:55 2025 -0800 | |
search: auto-focus search field on navigate | |
I'm going to add a search changelog on this commit since I forgot | |
to do so previously. | |
Fixes: https://linear.app/damus/issue/DECK-538/auto-focus-search-field-on-search-view | |
Changelog-Added: Added fulltext search ui | |
Signed-off-by: William Casarin <[email protected]> | |
diff --git a/crates/notedeck_columns/src/nav.rs b/crates/notedeck_columns/src/nav.rs | |
index 72c84b3c0788..c7edd4a07155 100644 | |
--- a/crates/notedeck_columns/src/nav.rs | |
+++ b/crates/notedeck_columns/src/nav.rs | |
@@ -18,7 +18,7 @@ use crate::{ | |
edit_deck::{EditDeckResponse, EditDeckView}, | |
note::{PostAction, PostType}, | |
profile::EditProfileView, | |
- search::SearchView, | |
+ search::{FocusState, SearchView}, | |
support::SupportView, | |
RelayView, View, | |
}, | |
@@ -403,9 +403,23 @@ fn render_nav_body( | |
Route::Search => { | |
let id = ui.id().with(("search", depth, col)); | |
+ let navigating = app | |
+ .columns_mut(ctx.accounts) | |
+ .column(col) | |
+ .router() | |
+ .navigating; | |
let search_buffer = app.view_state.searches.entry(id).or_default(); | |
let txn = Transaction::new(ctx.ndb).expect("txn"); | |
+ if navigating { | |
+ search_buffer.focus_state = FocusState::Navigating | |
+ } else if search_buffer.focus_state == FocusState::Navigating { | |
+ // we're not navigating but our last search buffer state | |
+ // says we were navigating. This means that navigating has | |
+ // stopped. Let's make sure to focus the input field | |
+ search_buffer.focus_state = FocusState::ShouldRequestFocus; | |
+ } | |
+ | |
SearchView::new( | |
ctx.ndb, | |
&txn, | |
diff --git a/crates/notedeck_columns/src/route.rs b/crates/notedeck_columns/src/route.rs | |
index 460bdf933860..a7ab5732c143 100644 | |
--- a/crates/notedeck_columns/src/route.rs | |
+++ b/crates/notedeck_columns/src/route.rs | |
@@ -25,7 +25,6 @@ pub enum Route { | |
EditProfile(Pubkey), | |
Support, | |
NewDeck, | |
- /// Search screen | |
Search, | |
EditDeck(usize), | |
} | |
diff --git a/crates/notedeck_columns/src/ui/search/mod.rs b/crates/notedeck_columns/src/ui/search/mod.rs | |
index b557a34d1e53..9a7a06ac8805 100644 | |
--- a/crates/notedeck_columns/src/ui/search/mod.rs | |
+++ b/crates/notedeck_columns/src/ui/search/mod.rs | |
@@ -12,7 +12,7 @@ use tracing::{error, info, warn}; | |
mod state; | |
-pub use state::{SearchQueryState, SearchState}; | |
+pub use state::{FocusState, SearchQueryState, SearchState}; | |
pub struct SearchView<'a> { | |
query: &'a mut SearchQueryState, | |
@@ -57,7 +57,7 @@ impl<'a> SearchView<'a> { | |
} | |
match self.query.state { | |
- SearchState::New => None, | |
+ SearchState::New | SearchState::Navigating => None, | |
SearchState::Searched | SearchState::Typing => { | |
if self.query.state == SearchState::Typing { | |
@@ -163,7 +163,7 @@ fn search_box(query: &mut SearchQueryState, ui: &mut egui::Ui) -> bool { | |
// Search input field | |
//let font_size = notedeck::fonts::get_font_size(ui.ctx(), &NotedeckTextStyle::Body); | |
- ui.add_sized( | |
+ let response = ui.add_sized( | |
[ui.available_width(), search_height], | |
TextEdit::singleline(&mut query.string) | |
.hint_text(RichText::new("Search notes...").weak()) | |
@@ -173,6 +173,11 @@ fn search_box(query: &mut SearchQueryState, ui: &mut egui::Ui) -> bool { | |
.frame(false), | |
); | |
+ if query.focus_state == FocusState::ShouldRequestFocus { | |
+ response.request_focus(); | |
+ query.focus_state = FocusState::RequestedFocus; | |
+ } | |
+ | |
let after_len = query.string.len(); | |
let changed = before_len != after_len; | |
diff --git a/crates/notedeck_columns/src/ui/search/state.rs b/crates/notedeck_columns/src/ui/search/state.rs | |
index b5b40ee7bea8..42247a7d9909 100644 | |
--- a/crates/notedeck_columns/src/ui/search/state.rs | |
+++ b/crates/notedeck_columns/src/ui/search/state.rs | |
@@ -6,9 +6,22 @@ use std::time::Duration; | |
pub enum SearchState { | |
Typing, | |
Searched, | |
+ Navigating, | |
New, | |
} | |
+#[derive(Debug, Eq, PartialEq)] | |
+pub enum FocusState { | |
+ /// Get ready to focus | |
+ Navigating, | |
+ | |
+ /// We should request focus when we stop navigating | |
+ ShouldRequestFocus, | |
+ | |
+ /// We already focused, we don't need to do that again | |
+ RequestedFocus, | |
+} | |
+ | |
/// Search query state that exists between frames | |
#[derive(Debug)] | |
pub struct SearchQueryState { | |
@@ -20,6 +33,10 @@ pub struct SearchQueryState { | |
/// again next frames | |
pub state: SearchState, | |
+ /// A bit of context to know if we're navigating to the view. We | |
+ /// can use this to know when to request focus on the textedit | |
+ pub focus_state: FocusState, | |
+ | |
/// When was the input updated? We use this to debounce searches | |
pub debouncer: Debouncer, | |
@@ -39,6 +56,7 @@ impl SearchQueryState { | |
string: "".to_string(), | |
state: SearchState::New, | |
notes: TimelineTab::default(), | |
+ focus_state: FocusState::Navigating, | |
debouncer: Debouncer::new(Duration::from_millis(200)), | |
} | |
} | |
diff --git a/crates/notedeck_columns/src/ui/side_panel.rs b/crates/notedeck_columns/src/ui/side_panel.rs | |
index e1c31a0c0360..7519c64e9cb9 100644 | |
--- a/crates/notedeck_columns/src/ui/side_panel.rs | |
+++ b/crates/notedeck_columns/src/ui/side_panel.rs | |
@@ -324,7 +324,6 @@ impl<'a> DesktopSidePanel<'a> { | |
} | |
SidePanelAction::Search => { | |
// TODO | |
- info!("Clicked search button"); | |
if router.top() == &Route::Search { | |
router.go_back(); | |
} else { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment