Commit 50979314 authored by Julian Sparber's avatar Julian Sparber

roomsettings: request avatar when entering the room settings

* make a request to get the avatar and username before entering the room
settings, so that the content for each row is avabile once the user
scrolls to the members list.

* run rustfmt

https://gitlab.gnome.org/World/fractal/issues/19
parent 0244a23d
......@@ -9,7 +9,12 @@ use backend::BKCommand;
use fractal_api::types::Member;
use cache::download_to_cache;
use std::sync::mpsc::channel;
use std::sync::mpsc::TryRecvError;
use std::sync::mpsc::{Receiver, Sender};
use widgets;
use widgets::members_list::MembersList;
use widgets::AvatarExt;
impl AppOp {
......@@ -20,10 +25,12 @@ impl AppOp {
}
pub fn close_room_settings(&mut self) {
let scroll = self.ui.builder
let scroll = self.ui
.builder
.get_object::<gtk::ScrolledWindow>("room_settings_scroll")
.expect("Can't find room_settings_scroll in ui file.");
let b = self.ui.builder
let b = self.ui
.builder
.get_object::<gtk::Frame>("room_settings_members_list")
.expect("Can't find room_settings_members_list in ui file.");
for w in b.get_children().iter() {
......@@ -86,16 +93,20 @@ impl AppOp {
}
pub fn room_settings_show_room_name(&self, text: Option<String>, edit: bool) -> Option<()> {
let label = self.ui.builder
let label = self.ui
.builder
.get_object::<gtk::Label>("room_settings_room_name")
.expect("Can't find room_settings_room_name in ui file.");
let b = self.ui.builder
let b = self.ui
.builder
.get_object::<gtk::Box>("room_settings_room_name_box")
.expect("Can't find room_settings_room_topic_entry in ui file.");
let entry = self.ui.builder
let entry = self.ui
.builder
.get_object::<gtk::Entry>("room_settings_room_name_entry")
.expect("Can't find room_settings_room_name_entry in ui file.");
let button = self.ui.builder
let button = self.ui
.builder
.get_object::<gtk::Button>("room_settings_room_name_button")
.expect("Can't find room_settings_room_name_button in ui file.");
......@@ -127,17 +138,26 @@ impl AppOp {
button.set_sensitive(true);
}
pub fn room_settings_show_room_topic(&self, text: Option<String>, is_room: bool, edit: bool) -> Option<()> {
let label = self.ui.builder
pub fn room_settings_show_room_topic(
&self,
text: Option<String>,
is_room: bool,
edit: bool,
) -> Option<()> {
let label = self.ui
.builder
.get_object::<gtk::Label>("room_settings_room_topic")
.expect("Can't find room_settings_room_topic in ui file.");
let b = self.ui.builder
let b = self.ui
.builder
.get_object::<gtk::Box>("room_settings_room_topic_box")
.expect("Can't find room_settings_room_topic_entry in ui file.");
let entry = self.ui.builder
let entry = self.ui
.builder
.get_object::<gtk::Entry>("room_settings_room_topic_entry")
.expect("Can't find room_settings_room_topic_entry in ui file.");
let button = self.ui.builder
let button = self.ui
.builder
.get_object::<gtk::Button>("room_settings_room_topic_button")
.expect("Can't find room_settings_room_topic_button in ui file.");
......@@ -170,10 +190,12 @@ impl AppOp {
}
pub fn room_settings_show_group_room(&self, show: bool) -> Option<()> {
let notify = self.ui.builder
let notify = self.ui
.builder
.get_object::<gtk::Frame>("room_settings_notification_sounds")
.expect("Can't find room_settings_notification_sounds in ui file.");
let invite = self.ui.builder
let invite = self.ui
.builder
.get_object::<gtk::Button>("room_settings_invite")
.expect("Can't find room_settings_invite in ui file.");
......@@ -189,7 +211,8 @@ impl AppOp {
}
pub fn room_settings_show_admin_groupe(&self, show: bool) -> Option<()> {
let history = self.ui.builder
let history = self.ui
.builder
.get_object::<gtk::Frame>("room_settings_history_visibility")
.expect("Can't find room_settings_history_visibility in ui file.");
......@@ -203,10 +226,12 @@ impl AppOp {
}
pub fn room_settings_show_admin_room(&self, show: bool) -> Option<()> {
let room = self.ui.builder
let room = self.ui
.builder
.get_object::<gtk::Frame>("room_settings_room_visibility")
.expect("Can't find room_settings_room_visibility in ui file.");
let join = self.ui.builder
let join = self.ui
.builder
.get_object::<gtk::Frame>("room_settings_join")
.expect("Can't find room_settings_join in ui file.");
......@@ -222,7 +247,8 @@ impl AppOp {
}
pub fn room_settings_show_room_type(&self, text: Option<String>) -> Option<()> {
let label = self.ui.builder
let label = self.ui
.builder
.get_object::<gtk::Label>("room_settings_room_description")
.expect("Can't find room_settings_room_name in ui file.");
......@@ -239,7 +265,8 @@ impl AppOp {
let container = self.ui.builder
.get_object::<gtk::Box>("room_settings_avatar_box")
.expect("Can't find room_settings_avatar_box in ui file.");
let avatar_btn = self.ui.builder
let avatar_btn = self.ui
.builder
.get_object::<gtk::Button>("room_settings_avatar_button")
.expect("Can't find room_settings_avatar_button in ui file.");
......@@ -254,13 +281,16 @@ impl AppOp {
image.circle(self.uid.clone().unwrap_or_default(), self.username.clone(), 100);
if edit {
let overlay = self.ui.builder
let overlay = self.ui
.builder
.get_object::<gtk::Overlay>("room_settings_avatar_overlay")
.expect("Can't find room_settings_avatar_overlay in ui file.");
let overlay_box = self.ui.builder
let overlay_box = self.ui
.builder
.get_object::<gtk::Box>("room_settings_avatar")
.expect("Can't find room_settings_avatar in ui file.");
let avatar_spinner = self.ui.builder
let avatar_spinner = self.ui
.builder
.get_object::<gtk::Spinner>("room_settings_avatar_spinner")
.expect("Can't find room_settings_avatar_spinner in ui file.");
/* remove all old avatar */
......@@ -279,14 +309,16 @@ impl AppOp {
container.add(&image);
}
return None
return None;
}
pub fn update_room_avatar(&mut self, file: String) -> Option<()> {
let avatar_spinner = self.ui.builder
let avatar_spinner = self.ui
.builder
.get_object::<gtk::Spinner>("room_settings_avatar_spinner")
.expect("Can't find room_settings_avatar_spinner in ui file.");
let avatar_btn = self.ui.builder
let avatar_btn = self.ui
.builder
.get_object::<gtk::Button>("room_settings_avatar_button")
.expect("Can't find room_settings_avatar_button in ui file.");
let room = self.rooms.get(&self.active_room.clone()?)?;
......@@ -299,10 +331,12 @@ impl AppOp {
}
pub fn update_room_name(&mut self) -> Option<()> {
let entry = self.ui.builder
let entry = self.ui
.builder
.get_object::<gtk::Entry>("room_settings_room_name_entry")
.expect("Can't find room_settings_name_entry in ui file.");
let button = self.ui.builder
let button = self.ui
.builder
.get_object::<gtk::Button>("room_settings_room_name_button")
.expect("Can't find room_settings_name_button in ui file.");
......@@ -326,7 +360,7 @@ impl AppOp {
let old_name = room.name.clone()?;
let new_name = new_name?;
if new_name != "" && new_name != old_name {
return Some(new_name)
return Some(new_name);
}
None
......@@ -337,17 +371,19 @@ impl AppOp {
let old_name = room.topic.clone()?;
let new_name = new_name?;
if new_name != "" && new_name != old_name {
return Some(new_name)
return Some(new_name);
}
None
}
pub fn update_room_topic(&mut self) -> Option<()> {
let name = self.ui.builder
let name = self.ui
.builder
.get_object::<gtk::Entry>("room_settings_room_topic_entry")
.expect("Can't find room_settings_topic in ui file.");
let button = self.ui.builder
let button = self.ui
.builder
.get_object::<gtk::Button>("room_settings_room_topic_button")
.expect("Can't find room_settings_topic_button in ui file.");
let topic = name.get_text()?;
......@@ -367,10 +403,12 @@ impl AppOp {
}
pub fn show_new_room_avatar(&self) {
let avatar_spinner = self.ui.builder
let avatar_spinner = self.ui
.builder
.get_object::<gtk::Spinner>("room_settings_avatar_spinner")
.expect("Can't find room_settings_avatar_spinner in ui file.");
let avatar_btn = self.ui.builder
let avatar_btn = self.ui
.builder
.get_object::<gtk::Button>("room_settings_avatar_button")
.expect("Can't find room_settings_avatar_button in ui file.");
......@@ -381,10 +419,12 @@ impl AppOp {
}
pub fn show_new_room_name(&self) {
let entry = self.ui.builder
let entry = self.ui
.builder
.get_object::<gtk::Entry>("room_settings_room_name_entry")
.expect("Can't find room_settings_room_name_entry in ui file.");
let button = self.ui.builder
let button = self.ui
.builder
.get_object::<gtk::Button>("room_settings_room_name_button")
.expect("Can't find room_settings_name_button in ui file.");
button.hide();
......@@ -393,10 +433,12 @@ impl AppOp {
}
pub fn show_new_room_topic(&self) {
let entry = self.ui.builder
let entry = self.ui
.builder
.get_object::<gtk::Entry>("room_settings_room_topic_entry")
.expect("Can't find room_settings_room_topic_entry in ui file.");
let button = self.ui.builder
let button = self.ui
.builder
.get_object::<gtk::Button>("room_settings_room_topic_button")
.expect("Can't find room_settings_topic_button in ui file.");
button.hide();
......@@ -405,23 +447,58 @@ impl AppOp {
}
fn room_settings_show_members(&self, members: Vec<Member>) -> Option<()> {
let entry = self.ui.builder
let entry = self.ui
.builder
.get_object::<gtk::SearchEntry>("room_settings_members_search")
.expect("Can't find room_settings_members_search in ui file.");
let b = self.ui.builder
let b = self.ui
.builder
.get_object::<gtk::Frame>("room_settings_members_list")
.expect("Can't find room_settings_members_list in ui file.");
let label = self.ui.builder
let label = self.ui
.builder
.get_object::<gtk::Label>("room_settings_member_list_title")
.expect("Can't find room_settings_member_list_title in ui file.");
for w in b.get_children().iter() {
b.remove(w);
}
label.set_text(&format!("{} members", members.len()));
let list = widgets::MembersList::new(members, entry);
let list = widgets::MembersList::new(members.clone(), entry);
let w = list.create()?;
/* ask for all avatars */
for (i, member) in members.iter().enumerate() {
account_settings_get_member_info(
self.backend.clone(),
member.uid.clone(),
i,
list.clone(),
);
}
b.add(&w);
None
}
}
/* this funtion should be moved to the backend */
pub fn account_settings_get_member_info(
backend: Sender<BKCommand>,
sender: String,
index: usize,
list: MembersList,
) {
let (tx, rx): (Sender<(String, String)>, Receiver<(String, String)>) = channel();
backend
.send(BKCommand::GetUserInfoAsync(sender.clone(), Some(tx)))
.unwrap();
gtk::timeout_add(100, move || match rx.try_recv() {
Err(TryRecvError::Empty) => gtk::Continue(true),
Err(TryRecvError::Disconnected) => gtk::Continue(false),
Ok((_name, _avatar)) => {
/* update UI */
/*println!("Update user {} with {}", sender, avatar); */
list.update(index);
gtk::Continue(false)
}
});
}
......@@ -6,10 +6,9 @@ use std::rc::Rc;
use self::gtk::prelude::*;
use glib::signal;
use fractal_api::util::cache_path;
use types::Member;
use widgets;
use widgets::avatar::AvatarExt;
use types::Member;
#[derive(Debug, Clone)]
pub struct MembersList {
......@@ -29,12 +28,16 @@ impl MembersList {
}
}
/* creates a empty list with members.len() rows, the content will be loaded when the row is
* drawn */
pub fn create(&self) -> Option<gtk::Box> {
let b = gtk::Box::new(gtk::Orientation::Vertical, 0);
b.set_hexpand(true);
b.pack_start(&self.container, true, true, 0);
add_rows(self.container.clone(), self.members.clone());
self.error.get_style_context()?.add_class("no_member_search");
self.error
.get_style_context()?
.add_class("no_member_search");
self.error.set_text("Nothing found");
b.pack_start(&self.error, true, true, 0);
self.connect();
......@@ -43,12 +46,28 @@ impl MembersList {
Some(b)
}
/* removes the content of the row with index i */
pub fn update(&self, i: usize) -> Option<()> {
let widget = self.container.get_row_at_index(i as i32)?;
let child = widget.get_child()?;
widget.remove(&child);
/* We don't need to create a new widget because the draw signal
* will handle the creation */
None
}
pub fn connect(&self) {
let container = self.container.clone();
let members = self.members.clone();
let error = self.error.clone();
let id = self.search_entry.connect_search_changed(move |w| {
filter_rows(container.clone(), members.clone(), error.clone(), w.get_text());
filter_rows(
container.clone(),
members.clone(),
error.clone(),
w.get_text(),
);
});
/* we need to remove the handler when the member list is destroyed */
let id: Rc<RefCell<Option<signal::SignalHandlerId>>> = Rc::new(RefCell::new(Some(id)));
......@@ -59,7 +78,7 @@ impl MembersList {
signal::signal_handler_disconnect(&search_entry, id);
}
});
/* slowly load members when the main thread is idle */
/* we could slowly load members when the main thread is idle */
/*
let container = self.container.clone();
let members = self.members.clone();
......@@ -94,8 +113,8 @@ fn create_row(member: Member) -> Option<gtk::ListBoxRow> {
/* creating the row is quite slow, therefore we have a small delay when scrolling the members list */
fn load_row_content(member: Member) -> gtk::Box {
let b = gtk::Box::new(gtk::Orientation::Horizontal, 12);
let avatar_path = cache_path(&member.uid).unwrap_or(String::from(""));
let avatar = widgets::Avatar::circle_avatar(avatar_path, Some(40));
let avatar = widgets::Avatar::avatar_new(Some(40));
avatar.circle(member.uid.clone(), member.alias.clone(), 40);
let user_box = gtk::Box::new(gtk::Orientation::Vertical, 0);
let username = gtk::Label::new(Some(member.get_alias().as_str()));
b.set_margin_start(12);
......@@ -120,7 +139,12 @@ fn add_rows(container: gtk::ListBox, members: Vec<Member>) -> Option<usize> {
None
}
fn filter_rows(container: gtk::ListBox, members: Vec<Member>, label: gtk::Label, search: Option<String>) -> Option<usize> {
fn filter_rows(
container: gtk::ListBox,
members: Vec<Member>,
label: gtk::Label,
search: Option<String>,
) -> Option<usize> {
/* Load just enough members to fill atleast the visible list */
let search = search?;
let search = search.as_str();
......
......@@ -6,7 +6,7 @@ mod roomlist;
pub mod avatar;
mod autocomplete;
mod address;
mod members_list;
pub mod members_list;
pub mod divider;
pub mod image;
mod inline_player;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment