From 5a0cc611e0ce629139842ee6d22b9d919321db40 Mon Sep 17 00:00:00 2001 From: Tyrese Luo Date: Mon, 4 Nov 2024 16:40:38 +0800 Subject: [PATCH 1/3] WIP search bar --- src/home/rooms_list.rs | 37 +++++++++++++++++++++++- src/home/rooms_sidebar.rs | 60 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/home/rooms_list.rs b/src/home/rooms_list.rs index ac061054..6d9593fb 100644 --- a/src/home/rooms_list.rs +++ b/src/home/rooms_list.rs @@ -5,7 +5,7 @@ use matrix_sdk::ruma::{MilliSecondsSinceUnixEpoch, OwnedRoomId}; use crate::{app::AppState, sliding_sync::{submit_async_request, MatrixRequest, PaginationDirection}}; -use super::room_preview::RoomPreviewAction; +use super::{room_preview::RoomPreviewAction, rooms_sidebar::{RoomsSideBarAction, RoomsSideBarFilter}}; /// Whether to pre-paginate visible rooms at least once in order to /// be able to display the latest message in the room preview, @@ -231,6 +231,25 @@ impl RoomsList { format!("Loaded {} rooms.", self.all_rooms.len()) }; } + fn filter_rooms(&mut self, keywords: &str) { + let keywords = keywords.to_lowercase(); + + if keywords.is_empty() { + self.display_filter = RoomDisplayFilter::default(); + self.displayed_rooms = self.all_rooms.keys().cloned().collect(); + return; + } + + self.display_filter = RoomDisplayFilter(Box::new(move |room| { + let room_name = room.room_name.as_ref().map(|n| n.to_lowercase()); + room_name.as_ref().map_or(false, |n| n.contains(&keywords)) + })); + + self.displayed_rooms = self.all_rooms.iter() + .filter(|(_, room)| (self.display_filter)(&room)) + .map(|(room_id, _)| room_id.clone()) + .collect(); + } } impl Widget for RoomsList { @@ -361,6 +380,7 @@ impl Widget for RoomsList { self.redraw(cx); } } + self.widget_match_event(cx, event, scope); } @@ -376,6 +396,7 @@ impl Widget for RoomsList { } let count = self.displayed_rooms.len(); + log!("Drawing {count} rooms in the list of all rooms"); let status_label_id = count; // Start the actual drawing procedure. @@ -390,6 +411,8 @@ impl Widget for RoomsList { while let Some(item_id) = list.next_visible_item(cx) { let mut scope = Scope::empty(); + log!("Drawing room at index {item_id}"); + // Draw the room preview for each room in the `displayed_rooms` list. let room_to_draw = self.displayed_rooms .get(item_id) @@ -435,3 +458,15 @@ impl Widget for RoomsList { } } + +impl WidgetMatchEvent for RoomsList { + fn handle_actions(&mut self, cx: &mut Cx, actions:&Actions, _scope: &mut Scope) { + for action in actions { + if let RoomsSideBarAction::Filter { keywords, filter } = action.as_widget_action().cast() { + if filter == RoomsSideBarFilter::Rooms { + self.filter_rooms(&keywords); + } + } + } + } +} \ No newline at end of file diff --git a/src/home/rooms_sidebar.rs b/src/home/rooms_sidebar.rs index f7213eb1..88691741 100644 --- a/src/home/rooms_sidebar.rs +++ b/src/home/rooms_sidebar.rs @@ -1,5 +1,7 @@ use makepad_widgets::*; +use crate::shared::search_bar::SearchBarAction; + live_design! { import makepad_widgets::base::*; import makepad_widgets::theme_desktop_dark::*; @@ -11,6 +13,7 @@ live_design! { import crate::home::rooms_list::RoomsList; import crate::shared::cached_widget::CachedWidget; + import crate::shared::search_bar::SearchBar; ICON_COLLAPSE = dep("crate://self/resources/icons/collapse.svg") ICON_ADD = dep("crate://self/resources/icons/add.svg") @@ -113,6 +116,11 @@ live_design! { text_style: {} } } + { + input = { + empty_message: "Search by room name" + } + } { flow: Down, spacing: 20 padding: {top: 20} @@ -167,6 +175,25 @@ live_design! { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum RoomsSideBarFilter { + /// Filter all + All, + /// Filter people + People, + /// Filter rooms + Rooms, +} + +#[derive(Debug, Clone, DefaultNone)] +pub enum RoomsSideBarAction { + /// Filter + Filter { + keywords: String, + filter: RoomsSideBarFilter, + }, + None +} #[derive(Widget, Live, LiveHook)] pub struct RoomsView { #[deref] @@ -176,9 +203,42 @@ pub struct RoomsView { impl Widget for RoomsView { fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) { self.view.handle_event(cx, event, scope); + self.widget_match_event(cx, event, scope); } fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep { self.view.draw_walk(cx, scope, walk) } } + +impl WidgetMatchEvent for RoomsView { + fn handle_actions(&mut self, cx: &mut Cx, actions:&Actions, scope: &mut Scope) { + let widget_uid = self.widget_uid(); + + for action in actions.iter() { + match action.as_widget_action().cast() { + SearchBarAction::Search(keywords) => { + cx.widget_action( + widget_uid, + &scope.path, + RoomsSideBarAction::Filter { + keywords: keywords.clone(), + filter: RoomsSideBarFilter::Rooms, + } + ); + }, + SearchBarAction::ResetSearch => { + cx.widget_action( + widget_uid, + &scope.path, + RoomsSideBarAction::Filter { + keywords: "".to_string(), + filter: RoomsSideBarFilter::Rooms, + } + ); + } + _ => {} + } + } + } +} \ No newline at end of file From 55b3b2053264c3372f4f7fb064827b0e11caa170 Mon Sep 17 00:00:00 2001 From: Tyrese Luo Date: Tue, 5 Nov 2024 15:57:35 +0800 Subject: [PATCH 2/3] finish basic search bar function --- src/home/room_preview.rs | 1 + src/home/rooms_list.rs | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/home/room_preview.rs b/src/home/room_preview.rs index 4d0f6d2a..d87f1024 100644 --- a/src/home/room_preview.rs +++ b/src/home/room_preview.rs @@ -104,6 +104,7 @@ live_design! { } RoomPreview = {{RoomPreview}} { + height: 65. // Wraps the RoomPreviewContent in an AdaptiveView // to change the displayed content (and its layout) based on the available space in the sidebar. adaptive_preview = { diff --git a/src/home/rooms_list.rs b/src/home/rooms_list.rs index c5debf66..022e2c06 100644 --- a/src/home/rooms_list.rs +++ b/src/home/rooms_list.rs @@ -395,7 +395,6 @@ impl Widget for RoomsList { } let count = self.displayed_rooms.len(); - log!("Drawing {count} rooms in the list of all rooms"); let status_label_id = count; // Start the actual drawing procedure. @@ -409,9 +408,6 @@ impl Widget for RoomsList { while let Some(item_id) = list.next_visible_item(cx) { let mut scope = Scope::empty(); - - log!("Drawing room at index {item_id}"); - // Draw the room preview for each room in the `displayed_rooms` list. let room_to_draw = self.displayed_rooms .get(item_id) From 369e0ede731c957d431b080b1055d5a54aefab80 Mon Sep 17 00:00:00 2001 From: Tyrese Luo <150460738+tyreseluo@users.noreply.github.com> Date: Thu, 7 Nov 2024 13:49:13 +0800 Subject: [PATCH 3/3] Update src/home/rooms_sidebar.rs Co-authored-by: Kevin Boos <1139460+kevinaboos@users.noreply.github.com> --- src/home/rooms_sidebar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/home/rooms_sidebar.rs b/src/home/rooms_sidebar.rs index 88691741..e7541a0a 100644 --- a/src/home/rooms_sidebar.rs +++ b/src/home/rooms_sidebar.rs @@ -118,7 +118,7 @@ live_design! { } { input = { - empty_message: "Search by room name" + empty_message: "Search for rooms..." } } {