[fractal/split-async-state-ui-appop-mgmt: 4/13] Move some methods in appop::directory to UI




commit e00a5802f21908875256d5f40fbb4e97b86c9359
Author: Alejandro Domínguez <adomu net-c com>
Date:   Thu Dec 3 15:46:07 2020 +0100

    Move some methods in appop::directory to UI

 fractal-gtk/src/appop/directory.rs |  83 +++-------------
 fractal-gtk/src/meson.build        |   2 +-
 fractal-gtk/src/ui/directory.rs    | 196 +++++++++++++++++++++++++++++++++++++
 fractal-gtk/src/ui/mod.rs          |   1 +
 fractal-gtk/src/widgets/mod.rs     |   2 -
 fractal-gtk/src/widgets/room.rs    | 153 -----------------------------
 6 files changed, 209 insertions(+), 228 deletions(-)
---
diff --git a/fractal-gtk/src/appop/directory.rs b/fractal-gtk/src/appop/directory.rs
index fcbf3405..638f7d1e 100644
--- a/fractal-gtk/src/appop/directory.rs
+++ b/fractal-gtk/src/appop/directory.rs
@@ -1,14 +1,9 @@
-use gtk::prelude::*;
-
-use crate::backend::{directory, HandleError};
-
+use super::RoomSearchPagination;
 use crate::app::RUNTIME;
 use crate::appop::AppOp;
-
-use crate::widgets;
-
-use super::RoomSearchPagination;
+use crate::backend::{directory, HandleError};
 use crate::model::room::Room;
+use gtk::prelude::*;
 use matrix_sdk::directory::RoomNetwork;
 use matrix_sdk::thirdparty::ProtocolInstance;
 
@@ -29,16 +24,7 @@ impl AppOp {
     }
 
     pub fn set_protocols(&self, protocols: Vec<ProtocolInstance>) {
-        let combo = self
-            .ui
-            .builder
-            .get_object::<gtk::ListStore>("protocol_model")
-            .expect("Can't find protocol_model in ui file.");
-        combo.clear();
-
-        for p in protocols {
-            combo.insert_with_values(None, &[0, 1], &[&p.desc, &p.network_id]);
-        }
+        self.ui.set_protocols(protocols);
     }
 
     pub fn search_rooms(&mut self) {
@@ -158,66 +144,19 @@ impl AppOp {
         self.search_rooms();
     }
 
-    pub fn append_directory_rooms(&mut self, rooms: Vec<Room>, rooms_since: Option<String>) {
+    pub fn append_directory_rooms(&mut self, mut rooms: Vec<Room>, rooms_since: Option<String>) {
+        let session_client =
+            unwrap_or_unit_return!(self.login_data.as_ref().map(|ld| ld.session_client.clone()));
+        rooms.sort_by_key(|a| -i128::from(a.n_members));
+        self.directory.extend(rooms.clone());
         self.directory_pagination = rooms_since
             .map(RoomSearchPagination::Next)
             .unwrap_or(RoomSearchPagination::NoMorePages);
 
-        let directory = self
-            .ui
-            .builder
-            .get_object::<gtk::ListBox>("directory_room_list")
-            .expect("Can't find directory_room_list in ui file.");
-        directory.get_style_context().add_class("room-directory");
-
-        let directory_stack = self
-            .ui
-            .builder
-            .get_object::<gtk::Stack>("directory_stack")
-            .expect("Can't find directory_stack in ui file.");
-        let directory_clamp = self
-            .ui
-            .builder
-            .get_object::<libhandy::Clamp>("directory_clamp")
-            .expect("Can't find directory_clamp in ui file.");
-        directory_stack.set_visible_child(&directory_clamp);
-
-        let mut sorted_rooms = rooms;
-        sorted_rooms.sort_by_key(|a| -i128::from(a.n_members));
-
-        for r in sorted_rooms.iter() {
-            self.directory.push(r.clone());
-            let rb = widgets::RoomBox::new(&r, &self);
-            let room_widget = rb.widget();
-            directory.add(&room_widget);
-        }
-
-        let q = self
-            .ui
-            .builder
-            .get_object::<gtk::Entry>("directory_search_entry")
-            .expect("Can't find directory_search_entry in ui file.");
-        q.set_sensitive(true);
+        self.ui.append_directory_rooms(rooms, session_client);
     }
 
     pub fn reset_directory_state(&self) {
-        let q = self
-            .ui
-            .builder
-            .get_object::<gtk::Entry>("directory_search_entry")
-            .expect("Can't find directory_search_entry in ui file.");
-        q.set_sensitive(true);
-
-        let directory_stack = self
-            .ui
-            .builder
-            .get_object::<gtk::Stack>("directory_stack")
-            .expect("Can't find directory_stack in ui file.");
-        let directory_clamp = self
-            .ui
-            .builder
-            .get_object::<libhandy::Clamp>("directory_clamp")
-            .expect("Can't find directory_clamp in ui file.");
-        directory_stack.set_visible_child(&directory_clamp);
+        self.ui.reset_directory_state();
     }
 }
diff --git a/fractal-gtk/src/meson.build b/fractal-gtk/src/meson.build
index 27e8867b..c9ef03b3 100644
--- a/fractal-gtk/src/meson.build
+++ b/fractal-gtk/src/meson.build
@@ -101,6 +101,7 @@ app_sources = files(
   'ui/connect/swipeable_widgets.rs',
   'ui/about.rs',
   'ui/attach.rs',
+  'ui/directory.rs',
   'ui/mod.rs',
   'util/i18n.rs',
   'util/mod.rs',
@@ -124,7 +125,6 @@ app_sources = files(
   'widgets/room_history.rs',
   'widgets/roomlist.rs',
   'widgets/roomrow.rs',
-  'widgets/room.rs',
   'widgets/room_settings.rs',
   'widgets/scroll_widget.rs',
   'widgets/source_dialog.rs',
diff --git a/fractal-gtk/src/ui/directory.rs b/fractal-gtk/src/ui/directory.rs
new file mode 100644
index 00000000..21f2ef6b
--- /dev/null
+++ b/fractal-gtk/src/ui/directory.rs
@@ -0,0 +1,196 @@
+use super::UI;
+use crate::app::RUNTIME;
+use crate::backend::room;
+use crate::backend::HandleError;
+use crate::model::room::Room;
+use crate::util::i18n::i18n;
+use crate::util::markup_text;
+use crate::widgets::{self, AvatarExt};
+use crate::APPOP;
+use gtk::prelude::*;
+use gtk::WidgetExt;
+use matrix_sdk::identifiers::{RoomAliasId, RoomIdOrAliasId};
+use matrix_sdk::thirdparty::ProtocolInstance;
+use matrix_sdk::Client as MatrixClient;
+
+const AVATAR_SIZE: i32 = 60;
+const JOIN_BUTTON_WIDTH: i32 = 84;
+
+impl UI {
+    pub fn set_protocols(&self, protocols: Vec<ProtocolInstance>) {
+        let combo = self
+            .builder
+            .get_object::<gtk::ListStore>("protocol_model")
+            .expect("Can't find protocol_model in ui file.");
+        combo.clear();
+
+        for p in protocols {
+            combo.insert_with_values(None, &[0, 1], &[&p.desc, &p.network_id]);
+        }
+    }
+
+    pub fn append_directory_rooms(&mut self, rooms: Vec<Room>, session_client: MatrixClient) {
+        let directory = self
+            .builder
+            .get_object::<gtk::ListBox>("directory_room_list")
+            .expect("Can't find directory_room_list in ui file.");
+        directory.get_style_context().add_class("room-directory");
+
+        let directory_stack = self
+            .builder
+            .get_object::<gtk::Stack>("directory_stack")
+            .expect("Can't find directory_stack in ui file.");
+        let directory_clamp = self
+            .builder
+            .get_object::<libhandy::Clamp>("directory_clamp")
+            .expect("Can't find directory_clamp in ui file.");
+        directory_stack.set_visible_child(&directory_clamp);
+
+        for r in rooms.iter() {
+            let room_widget = build_room_box_widget(&r, session_client.clone());
+            directory.add(&room_widget);
+        }
+
+        let q = self
+            .builder
+            .get_object::<gtk::Entry>("directory_search_entry")
+            .expect("Can't find directory_search_entry in ui file.");
+        q.set_sensitive(true);
+    }
+
+    pub fn reset_directory_state(&self) {
+        let q = self
+            .builder
+            .get_object::<gtk::Entry>("directory_search_entry")
+            .expect("Can't find directory_search_entry in ui file.");
+        q.set_sensitive(true);
+
+        let directory_stack = self
+            .builder
+            .get_object::<gtk::Stack>("directory_stack")
+            .expect("Can't find directory_stack in ui file.");
+        let directory_clamp = self
+            .builder
+            .get_object::<libhandy::Clamp>("directory_clamp")
+            .expect("Can't find directory_clamp in ui file.");
+        directory_stack.set_visible_child(&directory_clamp);
+    }
+}
+
+fn build_room_box_widget(room: &Room, session_client: MatrixClient) -> gtk::ListBoxRow {
+    let row = gtk::ListBoxRow::new();
+    let room_box = build_room_box(room, session_client);
+
+    row.set_selectable(false);
+    row.add(&room_box);
+    row.show_all();
+
+    row
+}
+
+fn build_room_box(room: &Room, session_client: MatrixClient) -> gtk::Box {
+    let widget_box = gtk::Box::new(gtk::Orientation::Horizontal, 0);
+
+    let avatar = widgets::Avatar::avatar_new(Some(AVATAR_SIZE));
+    avatar.circle(
+        room.id.to_string(),
+        room.name.clone(),
+        AVATAR_SIZE,
+        None,
+        None,
+    );
+    widget_box.pack_start(&avatar, false, false, 18);
+
+    let details_box = gtk::Box::new(gtk::Orientation::Vertical, 6);
+
+    let name = room
+        .name
+        .as_ref()
+        .filter(|n| !n.is_empty())
+        .map(String::as_str)
+        .or(room.alias.as_ref().map(RoomAliasId::as_str))
+        .unwrap_or_default();
+
+    let name_label = gtk::Label::new(None);
+    name_label.set_line_wrap(true);
+    name_label.set_line_wrap_mode(pango::WrapMode::WordChar);
+    name_label.set_markup(&format!("<b>{}</b>", markup_text(name)));
+    name_label.set_justify(gtk::Justification::Left);
+    name_label.set_halign(gtk::Align::Start);
+    name_label.set_valign(gtk::Align::Start);
+    name_label.set_xalign(0.0);
+
+    let topic_label = gtk::Label::new(None);
+    if !room.topic.clone().unwrap_or_default().is_empty() {
+        topic_label.set_line_wrap(true);
+        topic_label.set_line_wrap_mode(pango::WrapMode::WordChar);
+        topic_label.set_lines(2);
+        topic_label.set_ellipsize(pango::EllipsizeMode::End);
+        topic_label.set_markup(&markup_text(&room.topic.clone().unwrap_or_default()));
+        topic_label.set_justify(gtk::Justification::Left);
+        topic_label.set_halign(gtk::Align::Start);
+        topic_label.set_valign(gtk::Align::Start);
+        topic_label.set_xalign(0.0);
+    }
+
+    let alias_label = gtk::Label::new(None);
+    alias_label.set_line_wrap(true);
+    alias_label.set_line_wrap_mode(pango::WrapMode::WordChar);
+    alias_label.set_markup(&format!(
+        "<span alpha=\"60%\">{}</span>",
+        room.alias
+            .as_ref()
+            .map(RoomAliasId::as_str)
+            .unwrap_or_default()
+    ));
+    alias_label.set_justify(gtk::Justification::Left);
+    alias_label.set_halign(gtk::Align::Start);
+    alias_label.set_valign(gtk::Align::Start);
+    alias_label.set_xalign(0.0);
+
+    details_box.add(&name_label);
+    if !topic_label.get_text().to_string().is_empty() {
+        details_box.add(&topic_label);
+    }
+    details_box.add(&alias_label);
+
+    let membership_grid = gtk::Grid::new();
+    membership_grid.set_column_spacing(6);
+
+    let members_icon =
+        gtk::Image::from_icon_name(Some("system-users-symbolic"), gtk::IconSize::Menu);
+    members_icon.get_style_context().add_class("dim-label");
+
+    let members_count = gtk::Label::new(Some(&format!("{}", room.n_members)[..]));
+    members_count.get_style_context().add_class("dim-label");
+
+    let join_button = gtk::Button::with_label(i18n("Join").as_str());
+    let room_id_or_alias: RoomIdOrAliasId = room.id.clone().into();
+    join_button.connect_clicked(move |_| {
+        let session_client = session_client.clone();
+        let room_id_or_alias = room_id_or_alias.clone();
+        RUNTIME.spawn(async move {
+            match room::join_room(session_client, &room_id_or_alias).await {
+                Ok(jtr) => {
+                    let jtr = Some(jtr);
+                    APPOP!(set_join_to_room, (jtr));
+                    APPOP!(reload_rooms);
+                }
+                Err(err) => err.handle_error(),
+            }
+        });
+    });
+    join_button.set_property_width_request(JOIN_BUTTON_WIDTH);
+
+    membership_grid.attach(&join_button, 0, 0, 4, 1);
+    membership_grid.attach(&members_icon, 5, 0, 1, 1);
+    membership_grid.attach(&members_count, 6, 0, 1, 1);
+
+    details_box.add(&membership_grid);
+
+    widget_box.pack_start(&details_box, true, true, 0);
+
+    widget_box.show_all();
+
+    widget_box
+}
diff --git a/fractal-gtk/src/ui/mod.rs b/fractal-gtk/src/ui/mod.rs
index 98313440..9968b1b9 100644
--- a/fractal-gtk/src/ui/mod.rs
+++ b/fractal-gtk/src/ui/mod.rs
@@ -11,6 +11,7 @@ use url::Url;
 pub mod about;
 pub mod attach;
 pub mod connect;
+pub mod directory;
 
 pub struct UI {
     pub builder: gtk::Builder,
diff --git a/fractal-gtk/src/widgets/mod.rs b/fractal-gtk/src/widgets/mod.rs
index 85572beb..2d8709a5 100644
--- a/fractal-gtk/src/widgets/mod.rs
+++ b/fractal-gtk/src/widgets/mod.rs
@@ -16,7 +16,6 @@ mod member;
 pub mod members_list;
 mod message;
 pub mod message_menu;
-mod room;
 pub mod room_history;
 pub mod room_settings;
 mod roomlist;
@@ -46,7 +45,6 @@ pub use self::media_viewer::MediaViewer;
 pub use self::member::MemberBox;
 pub use self::members_list::MembersList;
 pub use self::message::MessageBox;
-pub use self::room::RoomBox;
 pub use self::room_history::RoomHistory;
 pub use self::room_settings::RoomSettings;
 pub use self::roomlist::RoomList;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]