diff --git a/fractal-gtk/src/widgets/divider.rs b/fractal-gtk/src/widgets/divider.rs index 863059eb..67ff03be 100644 --- a/fractal-gtk/src/widgets/divider.rs +++ b/fractal-gtk/src/widgets/divider.rs @@ -9,7 +9,7 @@ pub struct NewMessageDivider { } impl NewMessageDivider { - pub fn new(text: &str) -> NewMessageDivider { + pub fn new(text: &str, remove_divider: F) -> NewMessageDivider { let row = gtk::ListBoxRow::new(); row.set_selectable(false); @@ -43,30 +43,25 @@ impl NewMessageDivider { * destroy the NewMessageDivider after it's added to the History with a couple of * secounds delay */ let revealer_weak = revealer.downgrade(); - row.connect_parent_set(move |w, _| { - || -> Option<()> { - let revealer = revealer_weak.upgrade()?; + row.connect_parent_set(move |_, _| { + revealer_weak.upgrade().map(|revealer| { let revealer_weak = revealer.downgrade(); gtk::timeout_add(5000, move || { /* when the user closes the room the divider gets destroyed and this tiemout * does nothing, but that's fine */ - || -> Option<()> { - let r = revealer_weak.upgrade()?; + revealer_weak.upgrade().map(|r| { r.set_reveal_child(false); - None - }(); + }); glib::Continue(false) }); - let row_weak = w.downgrade(); - revealer.connect_property_child_revealed_notify(move |_| { - || -> Option<()> { - let r = row_weak.upgrade()?; - r.destroy(); - None - }(); - }); - None - }(); + }); + }); + let row_weak = row.downgrade(); + revealer.connect_property_child_revealed_notify(move |_| { + row_weak.upgrade().map(|r| { + r.destroy(); + remove_divider(); + }); }); NewMessageDivider { revealer: revealer, diff --git a/fractal-gtk/src/widgets/room_history.rs b/fractal-gtk/src/widgets/room_history.rs index 8ab88ece..83c02f3e 100644 --- a/fractal-gtk/src/widgets/room_history.rs +++ b/fractal-gtk/src/widgets/room_history.rs @@ -24,6 +24,7 @@ use url::Url; struct List { list: VecDeque, + new_divider_index: Option, listbox: gtk::ListBox, view: widgets::ScrollWidget, } @@ -32,6 +33,7 @@ impl List { pub fn new(view: widgets::ScrollWidget, listbox: gtk::ListBox) -> List { List { list: VecDeque::new(), + new_divider_index: None, listbox, view, } @@ -72,9 +74,27 @@ impl List { self.listbox.insert(divider, -1); } } + if let Some(index) = self.new_divider_index { + self.new_divider_index = Some(index + 1); + } self.list.push_front(element); None } + + fn create_new_message_divider(rows: Rc>) -> widgets::NewMessageDivider { + let rows_weak = Rc::downgrade(&rows); + let remove_divider = move || { + rows_weak.upgrade().map(|rows| { + let new_divider_index = rows + .borrow_mut() + .new_divider_index + .take() + .expect("The new divider index must exist, since there is a new divider"); + rows.borrow_mut().list.remove(new_divider_index); + }); + }; + widgets::NewMessageDivider::new(i18n("New Messages").as_str(), remove_divider) + } } /* These Enum contains all differnet types of rows the room history can have, e.g room message, new @@ -190,8 +210,11 @@ impl RoomHistory { rows.borrow_mut().add_top(prev_day_divider); } if item.last_viewed && !rows.borrow().list.is_empty() { - let divider = Element::NewDivider(create_new_message_divider()); + let divider = + Element::NewDivider(List::create_new_message_divider(rows.clone())); rows.borrow_mut().add_top(divider); + let new_divider_index = rows.borrow().list.len() - 1; + rows.borrow_mut().new_divider_index = Some(new_divider_index); } item.widget = Some(create_row( item.clone(), @@ -249,8 +272,10 @@ impl RoomHistory { }; if item.last_viewed { - let divider = Element::NewDivider(create_new_message_divider()); + let divider = Element::NewDivider(List::create_new_message_divider(self.rows.clone())); rows.add_bottom(divider); + let new_divider_index = rows.list.len() - 1; + rows.new_divider_index = Some(new_divider_index); } if let Some(day_divider) = day_divider { rows.add_bottom(day_divider); @@ -411,7 +436,3 @@ fn create_day_divider(date: DateTime) -> gtk::ListBoxRow { row.show_all(); row } - -fn create_new_message_divider() -> widgets::NewMessageDivider { - widgets::NewMessageDivider::new(i18n("New Messages").as_str()) -}