[fractal/split-async-state-ui-appop-mgmt: 7/12] Move stuff in member from AppOp to UI
- From: Alejandro Domínguez <aledomu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/split-async-state-ui-appop-mgmt: 7/12] Move stuff in member from AppOp to UI
- Date: Tue, 8 Dec 2020 19:38:07 +0000 (UTC)
commit c606ed939623b30ba24ef7943d9df4b09700cf14
Author: Alejandro Domínguez <adomu net-c com>
Date: Sat Dec 5 10:38:37 2020 +0100
Move stuff in member from AppOp to UI
fractal-gtk/src/appop/invite.rs | 30 ++---
fractal-gtk/src/appop/member.rs | 156 ++++-------------------
fractal-gtk/src/appop/mod.rs | 2 +-
fractal-gtk/src/meson.build | 2 +-
fractal-gtk/src/ui/member.rs | 211 ++++++++++++++++++++++++++++++++
fractal-gtk/src/ui/mod.rs | 1 +
fractal-gtk/src/widgets/autocomplete.rs | 33 +++--
fractal-gtk/src/widgets/member.rs | 128 -------------------
fractal-gtk/src/widgets/mod.rs | 2 -
9 files changed, 272 insertions(+), 293 deletions(-)
---
diff --git a/fractal-gtk/src/appop/invite.rs b/fractal-gtk/src/appop/invite.rs
index 425fe3da..e681c68e 100644
--- a/fractal-gtk/src/appop/invite.rs
+++ b/fractal-gtk/src/appop/invite.rs
@@ -1,23 +1,23 @@
use crate::util::i18n::{i18n, i18n_k};
-use crate::backend::room;
-use gtk::prelude::*;
-use matrix_sdk::identifiers::{RoomId, UserId};
-
use crate::app::RUNTIME;
use crate::appop::member::SearchType;
use crate::appop::AppOp;
+use crate::backend::room;
use crate::backend::HandleError;
-
use crate::globals;
-
-use crate::widgets;
-
use crate::model::member::Member;
+use crate::ui::member::build_memberbox_pill;
+use gtk::prelude::*;
+use matrix_sdk::identifiers::{RoomId, UserId};
impl AppOp {
- pub fn add_to_invite(&mut self, u: Member) {
- if self.ui.invite_list.iter().any(|(mem, _)| *mem == u) {
+ pub fn add_to_invite(&mut self, member: Member) {
+ let session_client =
+ unwrap_or_unit_return!(self.login_data.as_ref().map(|ld| ld.session_client.clone()));
+ let user_info_cache = self.user_info_cache.clone();
+
+ if self.ui.invite_list.iter().any(|(mem, _)| *mem == member) {
return;
}
@@ -69,15 +69,9 @@ impl AppOp {
buffer.delete(&mut start_word, &mut end_word);
if let Some(anchor) = buffer.create_child_anchor(&mut end_word) {
- let w;
- {
- let mb = widgets::MemberBox::new(&u, &self);
- w = mb.pill();
- }
-
+ let w = build_memberbox_pill(session_client, user_info_cache, member.clone());
invite_entry.add_child_at_anchor(&w, &anchor);
-
- self.ui.invite_list.push((u, anchor));
+ self.ui.invite_list.push((member, anchor));
}
}
}
diff --git a/fractal-gtk/src/appop/member.rs b/fractal-gtk/src/appop/member.rs
index 42b8d1d4..1a6b3d35 100644
--- a/fractal-gtk/src/appop/member.rs
+++ b/fractal-gtk/src/appop/member.rs
@@ -1,7 +1,10 @@
+use crate::actions::AppState;
+use crate::app::RUNTIME;
+use crate::appop::AppOp;
use crate::backend::{user, HandleError};
+use crate::model::member::Member;
+use crate::model::room::RoomList;
use either::Either;
-use glib::clone;
-use gtk::prelude::*;
use matrix_sdk::{
events::{
room::member::{MemberEventContent, MembershipState},
@@ -11,37 +14,16 @@ use matrix_sdk::{
};
use url::Url;
-use std::collections::HashMap;
-use std::convert::TryFrom;
-
-use crate::actions::AppState;
-use crate::app::RUNTIME;
-use crate::appop::AppOp;
-use crate::widgets;
-
-use crate::model::member::Member;
-
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Copy)]
pub enum SearchType {
Invite,
DirectChat,
}
impl AppOp {
- pub fn member_level(&self, member: &Member) -> i64 {
- self.active_room
- .as_ref()
- .and_then(|a_room| self.rooms.get(a_room)?.admins.get(&member.uid))
- .copied()
- .unwrap_or(0)
- }
-
pub fn set_room_members(&mut self, room_id: RoomId, members: Vec<Member>) {
if let Some(r) = self.rooms.get_mut(&room_id) {
- r.members = HashMap::new();
- for m in members {
- r.members.insert(m.uid.clone(), m);
- }
+ r.members = members.into_iter().map(|m| (m.uid.clone(), m)).collect();
}
self.recalculate_room_name(room_id);
@@ -83,114 +65,17 @@ impl AppOp {
}
pub fn user_search_finished(&self, users: Vec<Member>) {
- match self.search_type {
- SearchType::Invite => {
- let entry = self
- .ui
- .builder
- .get_object::<gtk::TextView>("invite_entry")
- .expect("Can't find invite_entry in ui file.");
- let listbox = self
- .ui
- .builder
- .get_object::<gtk::ListBox>("user_search_box")
- .expect("Can't find user_search_box in ui file.");
- let scroll = self
- .ui
- .builder
- .get_object::<gtk::Widget>("user_search_scroll")
- .expect("Can't find user_search_scroll in ui file.");
-
- if let Some(buffer) = entry.get_buffer() {
- let start = buffer.get_start_iter();
- let end = buffer.get_end_iter();
-
- self.search_finished(
- users,
- listbox,
- scroll,
- buffer
- .get_text(&start, &end, false)
- .map(|gstr| gstr.to_string()),
- );
- }
- }
- SearchType::DirectChat => {
- let entry = self
- .ui
- .builder
- .get_object::<gtk::TextView>("to_chat_entry")
- .expect("Can't find to_chat_entry in ui file.");
- let listbox = self
- .ui
- .builder
- .get_object::<gtk::ListBox>("direct_chat_search_box")
- .expect("Can't find direct_chat_search_box in ui file.");
- let scroll = self
- .ui
- .builder
- .get_object::<gtk::Widget>("direct_chat_search_scroll")
- .expect("Can't find direct_chat_search_scroll in ui file.");
-
- if let Some(buffer) = entry.get_buffer() {
- let start = buffer.get_start_iter();
- let end = buffer.get_end_iter();
-
- self.search_finished(
- users,
- listbox,
- scroll,
- buffer
- .get_text(&start, &end, false)
- .map(|gstr| gstr.to_string()),
- );
- }
- }
- }
- }
-
- pub fn search_finished(
- &self,
- mut users: Vec<Member>,
- listbox: gtk::ListBox,
- scroll: gtk::Widget,
- term: Option<String>,
- ) {
- for ch in listbox.get_children().iter() {
- listbox.remove(ch);
- }
- scroll.hide();
-
- let uid_term = term.and_then(|t| UserId::try_from(t.as_str()).ok());
- // Adding a new user if the user
- if let Some(uid) = uid_term {
- if users.iter().find(|u| u.uid == uid).is_none() {
- let member = Member {
- avatar: None,
- alias: None,
- uid,
- };
- users.insert(0, member);
- }
- }
-
- for (i, u) in users.iter().enumerate() {
- let w;
- {
- let mb = widgets::MemberBox::new(u, &self);
- w = mb.widget(true);
- }
-
- w.connect_button_press_event(clone!(@strong u => move |_, _| {
- /* FIXME: Create Action */
- let u = u.clone();
- APPOP!(add_to_invite, (u));
- glib::signal::Inhibit(true)
- }));
+ let session_client =
+ unwrap_or_unit_return!(self.login_data.as_ref().map(|ld| ld.session_client.clone()));
- listbox.insert(&w, i as i32);
- scroll.show();
- }
+ self.ui.user_search_finished(
+ session_client,
+ self.user_info_cache.clone(),
+ self.active_room.as_ref(),
+ &self.rooms,
+ users,
+ self.search_type,
+ );
}
pub fn search_invite_user(&self, term: String) {
@@ -208,3 +93,10 @@ impl AppOp {
});
}
}
+
+pub fn member_level(active_room: Option<&RoomId>, rooms: &RoomList, member_uid: &UserId) -> i64 {
+ active_room
+ .and_then(|a_room| rooms.get(a_room)?.admins.get(member_uid))
+ .copied()
+ .unwrap_or(0)
+}
diff --git a/fractal-gtk/src/appop/mod.rs b/fractal-gtk/src/appop/mod.rs
index 77fe3739..fdf51fe5 100644
--- a/fractal-gtk/src/appop/mod.rs
+++ b/fractal-gtk/src/appop/mod.rs
@@ -26,7 +26,7 @@ mod directory;
mod invite;
mod login;
mod media_viewer;
-mod member;
+pub mod member;
mod message;
mod notifications;
mod notify;
diff --git a/fractal-gtk/src/meson.build b/fractal-gtk/src/meson.build
index 4d53f52c..14bfc92b 100644
--- a/fractal-gtk/src/meson.build
+++ b/fractal-gtk/src/meson.build
@@ -102,6 +102,7 @@ app_sources = files(
'ui/about.rs',
'ui/attach.rs',
'ui/directory.rs',
+ 'ui/member.rs',
'ui/mod.rs',
'ui/start_chat.rs',
'util/i18n.rs',
@@ -118,7 +119,6 @@ app_sources = files(
'widgets/kicked_dialog.rs',
'widgets/login.rs',
'widgets/media_viewer.rs',
- 'widgets/member.rs',
'widgets/members_list.rs',
'widgets/message_menu.rs',
'widgets/message.rs',
diff --git a/fractal-gtk/src/ui/member.rs b/fractal-gtk/src/ui/member.rs
new file mode 100644
index 00000000..77711365
--- /dev/null
+++ b/fractal-gtk/src/ui/member.rs
@@ -0,0 +1,211 @@
+use super::UI;
+use crate::appop::member::member_level;
+use crate::appop::member::SearchType;
+use crate::appop::UserInfoCache;
+use crate::cache::download_to_cache;
+use crate::globals;
+use crate::model::member::Member;
+use crate::model::room::RoomList;
+use crate::widgets;
+use crate::widgets::AvatarExt;
+use crate::APPOP;
+use gtk::prelude::*;
+use matrix_sdk::identifiers::{RoomId, UserId};
+use matrix_sdk::Client as MatrixClient;
+use std::convert::TryFrom;
+
+impl UI {
+ pub fn user_search_finished(
+ &self,
+ session_client: MatrixClient,
+ user_info_cache: UserInfoCache,
+ active_room: Option<&RoomId>,
+ rooms: &RoomList,
+ users: Vec<Member>,
+ search_type: SearchType,
+ ) {
+ let (entry_label, listbox_label, scroll_label) = match search_type {
+ SearchType::Invite => ("invite_entry", "user_search_box", "user_search_scroll"),
+ SearchType::DirectChat => (
+ "to_chat_entry",
+ "direct_chat_search_box",
+ "direct_chat_search_scroll",
+ ),
+ };
+
+ let entry = self
+ .builder
+ .get_object::<gtk::TextView>(entry_label)
+ .expect("Can't find invite_entry in ui file.");
+ let listbox = self
+ .builder
+ .get_object::<gtk::ListBox>(listbox_label)
+ .expect("Can't find user_search_box in ui file.");
+ let scroll = self
+ .builder
+ .get_object::<gtk::Widget>(scroll_label)
+ .expect("Can't find user_search_scroll in ui file.");
+
+ if let Some(buffer) = entry.get_buffer() {
+ let start = buffer.get_start_iter();
+ let end = buffer.get_end_iter();
+
+ search_finished(
+ session_client,
+ user_info_cache,
+ active_room,
+ rooms,
+ users,
+ listbox,
+ scroll,
+ buffer
+ .get_text(&start, &end, false)
+ .map(|gstr| gstr.to_string()),
+ );
+ }
+ }
+}
+
+fn search_finished(
+ session_client: MatrixClient,
+ user_info_cache: UserInfoCache,
+ active_room: Option<&RoomId>,
+ rooms: &RoomList,
+ mut users: Vec<Member>,
+ listbox: gtk::ListBox,
+ scroll: gtk::Widget,
+ term: Option<String>,
+) {
+ for ch in listbox.get_children().iter() {
+ listbox.remove(ch);
+ }
+ scroll.hide();
+
+ let uid_term = term.and_then(|t| UserId::try_from(t.as_str()).ok());
+ // Adding a new user if the user
+ if let Some(uid) = uid_term {
+ if users.iter().find(|u| u.uid == uid).is_none() {
+ let member = Member {
+ avatar: None,
+ alias: None,
+ uid,
+ };
+ users.insert(0, member);
+ }
+ }
+
+ for (i, member) in users.into_iter().enumerate() {
+ let member_level = member_level(active_room, rooms, &member.uid);
+ let w = build_memberbox_widget(
+ session_client.clone(),
+ user_info_cache.clone(),
+ member.clone(),
+ member_level,
+ true,
+ );
+
+ w.connect_button_press_event(move |_, _| {
+ /* FIXME: Create Action */
+ let member = member.clone();
+ APPOP!(add_to_invite, (member));
+ glib::signal::Inhibit(true)
+ });
+
+ listbox.insert(&w, i as i32);
+ scroll.show();
+ }
+}
+
+pub fn build_memberbox_widget(
+ session_client: MatrixClient,
+ user_info_cache: UserInfoCache,
+ member: Member,
+ member_level: i64,
+ show_uid: bool,
+) -> gtk::EventBox {
+ let username = gtk::Label::new(None);
+ let uid = gtk::Label::new(None);
+ let event_box = gtk::EventBox::new();
+ let w = gtk::Box::new(gtk::Orientation::Horizontal, 5);
+ let v = gtk::Box::new(gtk::Orientation::Vertical, 0);
+
+ uid.set_text(&member.uid.to_string());
+ uid.set_valign(gtk::Align::Start);
+ uid.set_halign(gtk::Align::Start);
+ uid.get_style_context().add_class("member-uid");
+
+ username.set_text(&member.get_alias());
+ let mut alias = member.get_alias();
+ alias.push_str("\n");
+ alias.push_str(&member.uid.to_string());
+ username.set_tooltip_text(Some(&alias[..]));
+ username.set_margin_end(5);
+ username.set_ellipsize(pango::EllipsizeMode::End);
+ username.set_valign(gtk::Align::Center);
+ username.set_halign(gtk::Align::Start);
+ username.get_style_context().add_class("member");
+
+ let avatar = widgets::Avatar::avatar_new(Some(globals::USERLIST_ICON_SIZE));
+ let badge = match member_level {
+ 0..=49 => None,
+ 50..=99 => Some(widgets::AvatarBadgeColor::Silver),
+ _ => Some(widgets::AvatarBadgeColor::Gold),
+ };
+ let data = avatar.circle(
+ member.uid.to_string(),
+ Some(alias),
+ globals::USERLIST_ICON_SIZE,
+ badge,
+ None,
+ );
+
+ download_to_cache(session_client, user_info_cache, member.uid, data);
+
+ avatar.set_margin_start(3);
+ avatar.set_valign(gtk::Align::Center);
+
+ v.set_margin_start(3);
+ v.pack_start(&username, true, true, 0);
+ if show_uid {
+ v.pack_start(&uid, true, true, 0);
+ }
+
+ w.add(&avatar);
+ w.add(&v);
+
+ event_box.add(&w);
+ event_box.show_all();
+ event_box
+}
+
+pub fn build_memberbox_pill(
+ session_client: MatrixClient,
+ user_info_cache: UserInfoCache,
+ member: Member,
+) -> gtk::Box {
+ let pill = gtk::Box::new(gtk::Orientation::Horizontal, 3);
+
+ let username = gtk::Label::new(None);
+
+ username.set_text(&member.get_alias());
+ username.set_margin_end(3);
+ username.get_style_context().add_class("msg-highlighted");
+
+ let avatar = widgets::Avatar::avatar_new(Some(globals::PILL_ICON_SIZE));
+ let data = avatar.circle(
+ member.uid.to_string(),
+ Some(member.get_alias()),
+ globals::PILL_ICON_SIZE,
+ None,
+ None,
+ );
+
+ download_to_cache(session_client, user_info_cache, member.uid, data);
+
+ avatar.set_margin_start(3);
+
+ pill.pack_start(&avatar, true, true, 0);
+ pill.pack_start(&username, true, true, 0);
+ pill.show_all();
+ pill
+}
diff --git a/fractal-gtk/src/ui/mod.rs b/fractal-gtk/src/ui/mod.rs
index 2915829c..b353c9b7 100644
--- a/fractal-gtk/src/ui/mod.rs
+++ b/fractal-gtk/src/ui/mod.rs
@@ -12,6 +12,7 @@ pub mod about;
pub mod attach;
pub mod connect;
pub mod directory;
+pub mod member;
pub mod start_chat;
pub struct UI {
diff --git a/fractal-gtk/src/widgets/autocomplete.rs b/fractal-gtk/src/widgets/autocomplete.rs
index 29b8a499..fb03b955 100644
--- a/fractal-gtk/src/widgets/autocomplete.rs
+++ b/fractal-gtk/src/widgets/autocomplete.rs
@@ -1,18 +1,15 @@
+use crate::app::AppRuntime;
+use crate::appop::{member::member_level, AppOp};
+use crate::model::member::Member;
+use crate::ui::member::build_memberbox_widget;
use glib::clone;
+use gtk::prelude::*;
+use gtk::TextTag;
use log::info;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
-use gtk::prelude::*;
-use gtk::TextTag;
-
-use crate::model::member::Member;
-
-use crate::app::AppRuntime;
-use crate::appop::AppOp;
-use crate::widgets;
-
pub struct Autocomplete {
app_runtime: AppRuntime,
entry: sourceview4::View,
@@ -425,12 +422,19 @@ impl Autocomplete {
list: Vec<Member>,
op: &AppOp,
) -> HashMap<String, gtk::EventBox> {
+ let session_client = op
+ .login_data
+ .as_ref()
+ .map(|ld| ld.session_client.clone())
+ .expect("The client is not logged in");
+ let user_info_cache = op.user_info_cache.clone();
+
for ch in self.listbox.get_children().iter() {
self.listbox.remove(ch);
}
let widget_list: HashMap<String, gtk::EventBox> = list
- .iter()
+ .into_iter()
.map(|member| {
let alias = member
.alias
@@ -438,7 +442,14 @@ impl Autocomplete {
.unwrap_or_default()
.trim_end_matches(" (IRC)")
.to_owned();
- let widget = widgets::MemberBox::new(&member, op).widget(true);
+ let member_level = member_level(op.active_room.as_ref(), &op.rooms, &member.uid);
+ let widget = build_memberbox_widget(
+ session_client.clone(),
+ user_info_cache.clone(),
+ member,
+ member_level,
+ true,
+ );
(alias, widget)
})
diff --git a/fractal-gtk/src/widgets/mod.rs b/fractal-gtk/src/widgets/mod.rs
index 2d8709a5..e88a8dec 100644
--- a/fractal-gtk/src/widgets/mod.rs
+++ b/fractal-gtk/src/widgets/mod.rs
@@ -12,7 +12,6 @@ pub mod inline_player;
mod kicked_dialog;
mod login;
pub mod media_viewer;
-mod member;
pub mod members_list;
mod message;
pub mod message_menu;
@@ -42,7 +41,6 @@ pub use self::inline_player::VideoPlayerWidget;
pub use self::kicked_dialog::KickedDialog;
pub use self::login::LoginWidget;
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_history::RoomHistory;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]