state.rs (3115B)
1 use crate::timeline::TimelineTab; 2 use enostr::Pubkey; 3 4 use super::SearchType; 5 6 #[derive(Debug, Eq, PartialEq)] 7 pub enum SearchState { 8 Typing(TypingType), 9 PerformSearch(SearchType), 10 Searched, 11 Navigating, 12 New, 13 } 14 15 #[derive(Debug, Eq, PartialEq)] 16 pub enum TypingType { 17 Mention(String), 18 } 19 20 #[derive(Debug, Clone)] 21 pub enum RecentSearchItem { 22 Query(String), 23 Profile { pubkey: Pubkey, query: String }, 24 } 25 26 #[derive(Debug, Eq, PartialEq, Clone, Default)] 27 pub enum FocusState { 28 /// Get ready to focus 29 Navigating, 30 31 /// We should request focus when we stop navigating 32 ShouldRequestFocus, 33 34 /// We already focused, we don't need to do that again 35 #[default] 36 RequestedFocus, 37 } 38 39 /// Search query state that exists between frames 40 #[derive(Debug)] 41 pub struct SearchQueryState { 42 /// This holds our search query while we're updating it 43 pub string: String, 44 45 /// Current search state 46 pub state: SearchState, 47 48 /// A bit of context to know if we're navigating to the view. We 49 /// can use this to know when to request focus on the textedit 50 pub focus_state: FocusState, 51 52 /// The search results 53 pub notes: TimelineTab, 54 55 /// Currently selected item index in search results (-1 = none, 0 = "search posts", 1+ = users) 56 pub selected_index: i32, 57 58 /// Cached user search results for the current query 59 pub user_results: Vec<Vec<u8>>, 60 61 /// Recent search history (most recent first, max 10) 62 pub recent_searches: Vec<RecentSearchItem>, 63 } 64 65 impl Default for SearchQueryState { 66 fn default() -> Self { 67 SearchQueryState::new() 68 } 69 } 70 71 impl SearchQueryState { 72 pub fn new() -> Self { 73 Self { 74 string: "".to_string(), 75 state: SearchState::New, 76 notes: TimelineTab::default(), 77 focus_state: FocusState::Navigating, 78 selected_index: -1, 79 user_results: Vec::new(), 80 recent_searches: Vec::new(), 81 } 82 } 83 84 pub fn add_recent_query(&mut self, query: String) { 85 if query.is_empty() { 86 return; 87 } 88 89 let item = RecentSearchItem::Query(query.clone()); 90 self.recent_searches 91 .retain(|s| !matches!(s, RecentSearchItem::Query(q) if q == &query)); 92 self.recent_searches.insert(0, item); 93 self.recent_searches.truncate(10); 94 } 95 96 pub fn add_recent_profile(&mut self, pubkey: Pubkey, query: String) { 97 if query.is_empty() { 98 return; 99 } 100 101 let item = RecentSearchItem::Profile { 102 pubkey, 103 query: query.clone(), 104 }; 105 self.recent_searches.retain( 106 |s| !matches!(s, RecentSearchItem::Profile { pubkey: pk, .. } if pk == &pubkey), 107 ); 108 self.recent_searches.insert(0, item); 109 self.recent_searches.truncate(10); 110 } 111 112 pub fn remove_recent_search(&mut self, index: usize) { 113 if index < self.recent_searches.len() { 114 self.recent_searches.remove(index); 115 } 116 } 117 118 pub fn clear_recent_searches(&mut self) { 119 self.recent_searches.clear(); 120 } 121 }