From 60e81c4a7b101a98244cb36f3929244c56cdbb9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Dom=C3=ADnguez?= Date: Fri, 15 Jan 2021 18:16:23 +0100 Subject: [PATCH] Clean MessageContent --- fractal-gtk/src/appop/message.rs | 63 ++++++------------------- fractal-gtk/src/appop/room.rs | 2 +- fractal-gtk/src/model/message.rs | 8 ++++ fractal-gtk/src/ui/mod.rs | 17 +------ fractal-gtk/src/widgets/message.rs | 47 ++++++++++-------- fractal-gtk/src/widgets/room_history.rs | 34 +++++++------ 6 files changed, 71 insertions(+), 100 deletions(-) diff --git a/fractal-gtk/src/appop/message.rs b/fractal-gtk/src/appop/message.rs index 3a780c99..cd51cf77 100644 --- a/fractal-gtk/src/appop/message.rs +++ b/fractal-gtk/src/appop/message.rs @@ -45,7 +45,7 @@ impl AppOp { self.mark_last_message_as_read(Force(true)); } - pub fn add_room_message(&mut self, msg: &Message) -> Option<()> { + pub fn add_room_message(&mut self, msg: Message) -> Option<()> { let session_client = self.login_data.as_ref()?.session_client.clone(); if let Some(ui_msg) = self.create_new_room_message(msg) { if let Some(ref mut history) = self.ui.history { @@ -55,7 +55,7 @@ impl AppOp { None } - pub fn remove_room_message(&mut self, msg: &Message) { + pub fn remove_room_message(&mut self, msg: Message) { let session_client = unwrap_or_unit_return!(self.login_data.as_ref().map(|ld| ld.session_client.clone())); if let Some(ui_msg) = self.create_new_room_message(msg) { @@ -68,7 +68,7 @@ impl AppOp { pub fn add_tmp_room_message(&mut self, msg: Message) -> Option<()> { let login_data = self.login_data.clone()?; let messages = self.ui.history.as_ref()?.get_listbox(); - if let Some(ui_msg) = self.create_new_room_message(&msg) { + if let Some(ui_msg) = self.create_new_room_message(msg.clone()) { let mb = widgets::MessageBox::tmpwidget( login_data.session_client.clone(), self.user_info_cache.clone(), @@ -108,7 +108,7 @@ impl AppOp { let r = self.rooms.get(self.active_room.as_ref()?)?; let mut widgets = vec![]; for t in self.msg_queue.iter().rev().filter(|m| m.msg.room == r.id) { - if let Some(ui_msg) = self.create_new_room_message(&t.msg) { + if let Some(ui_msg) = self.create_new_room_message(t.msg.clone()) { let mb = widgets::MessageBox::tmpwidget( login_data.session_client.clone(), self.user_info_cache.clone(), @@ -365,7 +365,7 @@ impl AppOp { let uid = login_data.uid; for msg in msgs.iter() { if !msg.redacted && self.active_room.as_ref().map_or(false, |x| x == &msg.room) { - self.add_room_message(&msg); + self.add_room_message(msg.clone()); msg_in_active = true; } @@ -415,7 +415,7 @@ impl AppOp { for item in msgs.iter().rev() { /* create a list of new messages to load to the history */ if active_room.map_or(false, |a_room| item.room == *a_room) && !item.redacted { - if let Some(ui_msg) = self.create_new_room_message(item) { + if let Some(ui_msg) = self.create_new_room_message(item.clone()) { list.push(ui_msg); } } @@ -434,7 +434,7 @@ impl AppOp { let message = self.get_message_by_id(&room_id, &id); if let Some(msg) = message { - self.remove_room_message(&msg); + self.remove_room_message(msg.clone()); if let Some(ref mut room) = self.rooms.get_mut(&msg.room) { if let Some(ref mut message) = room.messages.iter_mut().find(|e| e.id == msg.id) { message.redacted = true; @@ -445,7 +445,7 @@ impl AppOp { } /* parese a backend Message into a Message for the UI */ - pub fn create_new_room_message(&self, msg: &Message) -> Option { + pub fn create_new_room_message(&self, msg: Message) -> Option { let login_data = self.login_data.clone()?; let mut highlights = vec![]; lazy_static! { @@ -506,48 +506,15 @@ impl AppOp { let redactable = admin != 0 || login_data.uid == msg.sender; let is_last_viewed = msg.receipt.contains_key(&login_data.uid); - Some(create_ui_message( - msg.clone(), - name, - t, + Some(MessageContent { + msg, + sender_name: name, + mtype: t, highlights, redactable, - is_last_viewed, - )) - } -} - -/* FIXME: don't convert msg to ui messages here, we should later get a ui message from storage */ -fn create_ui_message( - msg: Message, - name: Option, - t: RowType, - highlights: Vec, - redactable: bool, - last_viewed: bool, -) -> MessageContent { - MessageContent { - msg: msg.clone(), - id: msg.id, - sender: msg.sender, - sender_name: name, - mtype: t, - body: msg.body, - date: msg.date, - replace_date: if msg.replace.is_some() { - Some(msg.date) - } else { - None - }, - thumb: msg.thumb, - url: msg.url, - local_path: msg.local_path, - formatted_body: msg.formatted_body, - format: msg.format, - last_viewed, - highlights, - redactable, - widget: None, + last_viewed: is_last_viewed, + widget: None, + }) } } diff --git a/fractal-gtk/src/appop/room.rs b/fractal-gtk/src/appop/room.rs index 2e6780e5..9002b821 100644 --- a/fractal-gtk/src/appop/room.rs +++ b/fractal-gtk/src/appop/room.rs @@ -275,7 +275,7 @@ impl AppOp { /* create the intitial list of messages to fill the new room history */ let mut messages = vec![]; if let Some(room) = self.rooms.get(&active_room) { - for msg in room.messages.iter() { + for msg in room.messages.iter().cloned() { /* Make sure the message is from this room and not redacted */ if msg.room == active_room && !msg.redacted { let row = self.create_new_room_message(msg); diff --git a/fractal-gtk/src/model/message.rs b/fractal-gtk/src/model/message.rs index 552d1bf7..4b689097 100644 --- a/fractal-gtk/src/model/message.rs +++ b/fractal-gtk/src/model/message.rs @@ -400,6 +400,14 @@ impl Message { } } + pub const fn replace_date(&self) -> Option<&DateTime> { + if self.replace.is_some() { + Some(&self.date) + } else { + None + } + } + /// Generates an unique transaction id for this message /// The txn_id is generated using the md5sum of a concatenation of the message room id, the /// message body and the date. diff --git a/fractal-gtk/src/ui/mod.rs b/fractal-gtk/src/ui/mod.rs index ae34796f..678eef3b 100644 --- a/fractal-gtk/src/ui/mod.rs +++ b/fractal-gtk/src/ui/mod.rs @@ -2,11 +2,7 @@ use crate::actions::AppState; use crate::model::{member::Member, message::Message}; use crate::util::i18n::i18n; use crate::widgets::{self, SVEntry}; -use chrono::prelude::{DateTime, Local}; use gtk::prelude::*; -use matrix_sdk::identifiers::{EventId, UserId}; -use std::path::PathBuf; -use url::Url; pub mod about; pub mod account; @@ -171,20 +167,9 @@ impl UI { * To-Do: this should be moved to a file collecting all structs used in the UI */ #[derive(Debug, Clone)] pub struct MessageContent { - pub id: Option, - pub sender: UserId, + pub msg: Message, pub sender_name: Option, pub mtype: RowType, - pub body: String, - pub date: DateTime, - pub replace_date: Option>, - pub thumb: Option, - pub url: Option, - pub local_path: Option, - pub formatted_body: Option, - pub format: Option, - /* in some places we still need the backend message type (e.g. media viewer) */ - pub msg: Message, pub highlights: Vec, pub redactable: bool, pub last_viewed: bool, diff --git a/fractal-gtk/src/widgets/message.rs b/fractal-gtk/src/widgets/message.rs index 766f72f5..f40a0c6f 100644 --- a/fractal-gtk/src/widgets/message.rs +++ b/fractal-gtk/src/widgets/message.rs @@ -261,7 +261,7 @@ impl MessageBox { body_bx.pack_start(&body, true, true, 0); - if let Some(replace_date) = msg.replace_date { + if let Some(replace_date) = msg.msg.replace_date() { let edit_mark = gtk::Image::from_icon_name(Some("document-edit-symbolic"), gtk::IconSize::Button); edit_mark.get_style_context().add_class("edit-mark"); @@ -290,7 +290,7 @@ impl MessageBox { fn build_room_msg_body(&self, msg: &Message) -> gtk::Box { let bx = gtk::Box::new(gtk::Orientation::Vertical, 6); - let msgs_by_kind_of_line = msg.body.lines().group_by(|&line| kind_of_line(line)); + let msgs_by_kind_of_line = msg.msg.body.lines().group_by(|&line| kind_of_line(line)); let msg_parts = msgs_by_kind_of_line.into_iter().map(|(k, group)| { let mut v: Vec<&str> = if k == MsgPartType::Quote { group.map(trim_start_quote).collect() @@ -360,7 +360,7 @@ impl MessageBox { self.eventbox.upcast_ref::() }; - let id = msg.id.clone(); + let id = msg.msg.id.clone(); widget.connect_button_press_event(move |w, e| { if e.triggers_context_menu() { let menu = MessageMenu::new(id.as_ref(), &mtype, &redactable, Some(w)); @@ -372,7 +372,7 @@ impl MessageBox { } }); - let id = msg.id.clone(); + let id = msg.msg.id.clone(); self.gesture .connect_pressed(clone!(@weak widget => move |_, x, y| { let menu = MessageMenu::new(id.as_ref(), &mtype, &redactable, Some(&widget)); @@ -382,7 +382,7 @@ impl MessageBox { } fn connect_media_viewer(&self, msg: &Message) -> Option<()> { - let evid = msg.id.as_ref()?.to_string(); + let evid = msg.msg.id.as_ref()?.to_string(); let data = glib::Variant::from(evid); self.root.set_action_name(Some("app.open-media-viewer")); self.root.set_action_target_value(Some(&data)); @@ -395,7 +395,7 @@ fn build_room_msg_avatar( user_info_cache: UserInfoCache, msg: &Message, ) -> widgets::Avatar { - let uid = msg.sender.clone(); + let uid = msg.msg.sender.clone(); let alias = msg.sender_name.clone(); let avatar = widgets::Avatar::avatar_new(Some(globals::MSG_ICON_SIZE)); avatar.set_valign(gtk::Align::Start); @@ -420,11 +420,11 @@ fn build_room_msg_avatar( fn build_room_msg_sticker(session_client: MatrixClient, msg: &Message) -> gtk::Box { let bx = gtk::Box::new(gtk::Orientation::Horizontal, 0); - if let Some(url) = msg.url.clone() { + if let Some(url) = msg.msg.url.clone() { let image = widgets::image::Image::new(Either::Left(url)) .size(Some(globals::MAX_STICKER_SIZE)) .build(session_client); - image.widget.set_tooltip_text(Some(&msg.body[..])); + image.widget.set_tooltip_text(Some(&msg.msg.body[..])); bx.add(&image.widget); } @@ -435,7 +435,7 @@ fn build_room_msg_sticker(session_client: MatrixClient, msg: &Message) -> gtk::B fn build_room_audio_player(session_client: MatrixClient, msg: &Message) -> gtk::Box { let bx = gtk::Box::new(gtk::Orientation::Horizontal, 6); - if let Some(url) = msg.url.clone() { + if let Some(url) = msg.msg.url.clone() { let player = AudioPlayerWidget::new(); let start_playing = false; PlayerExt::initialize_stream( @@ -456,6 +456,7 @@ fn build_room_audio_player(session_client: MatrixClient, msg: &Message) -> gtk:: download_btn.set_tooltip_text(Some(i18n("Save").as_str())); let evid = msg + .msg .id .as_ref() .map(|evid| evid.to_string()) @@ -466,7 +467,7 @@ fn build_room_audio_player(session_client: MatrixClient, msg: &Message) -> gtk:: bx.pack_start(&download_btn, false, false, 3); let outer_box = gtk::Box::new(gtk::Orientation::Vertical, 6); - let file_name = gtk::Label::new(Some(&format!("{}", msg.body))); + let file_name = gtk::Label::new(Some(&format!("{}", msg.msg.body))); file_name.set_use_markup(true); file_name.set_xalign(0.0); file_name.set_line_wrap(true); @@ -481,7 +482,7 @@ fn build_room_msg_file(msg: &Message) -> gtk::Box { let bx = gtk::Box::new(gtk::Orientation::Horizontal, 12); let btn_bx = gtk::Box::new(gtk::Orientation::Horizontal, 0); - let name = msg.body.as_str(); + let name = msg.msg.body.as_str(); let name_lbl = gtk::Label::new(Some(name)); name_lbl.set_tooltip_text(Some(name)); name_lbl.set_ellipsize(pango::EllipsizeMode::End); @@ -493,6 +494,7 @@ fn build_room_msg_file(msg: &Message) -> gtk::Box { download_btn.set_tooltip_text(Some(i18n("Save").as_str())); let evid = msg + .msg .id .as_ref() .map(|evid| evid.to_string()) @@ -527,12 +529,13 @@ fn build_room_msg_image( // If the thumbnail is not a valid URL we use the msg.url let img = msg + .msg .thumb .clone() .filter(|m| m.scheme() == "mxc" || m.scheme().starts_with("http")) - .or_else(|| msg.url.clone()) + .or_else(|| msg.msg.url.clone()) .map(Either::Left) - .or_else(|| Some(Either::Right(msg.local_path.clone()?))); + .or_else(|| Some(Either::Right(msg.msg.local_path.clone()?))); let image = if let Some(img_path) = img { let image = widgets::image::Image::new(img_path) @@ -558,7 +561,7 @@ fn build_room_video_player( ) -> (gtk::Box, Option>) { let bx = gtk::Box::new(gtk::Orientation::Vertical, 6); - let player = if let Some(url) = msg.url.clone() { + let player = if let Some(url) = msg.msg.url.clone() { let with_controls = false; let player = VideoPlayerWidget::new(with_controls); let start_playing = false; @@ -588,6 +591,7 @@ fn build_room_video_player( play_button.get_style_context().add_class("play-icon"); play_button.get_style_context().add_class("flat"); let evid = msg + .msg .id .as_ref() .map(|evid| evid.to_string()) @@ -615,7 +619,7 @@ fn build_room_video_player( }); overlay.add_overlay(&menu_button); - let evid = msg.id.as_ref(); + let evid = msg.msg.id.as_ref(); let redactable = msg.redactable; let menu = MessageMenu::new(evid, &RowType::Video, &redactable, None); menu_button.set_popover(Some(&menu.get_popover())); @@ -639,9 +643,9 @@ fn build_room_msg_emote(msg: &Message) -> (gtk::Box, gtk::Label) { let sname = msg .sender_name .clone() - .unwrap_or_else(|| msg.sender.to_string()); + .unwrap_or_else(|| msg.msg.sender.to_string()); let msg_label = gtk::Label::new(None); - let markup = markup_text(&msg.body); + let markup = markup_text(&msg.msg.body); msg_label.set_markup(&format!("{} {}", sname, markup)); set_label_styles(&msg_label); @@ -750,9 +754,12 @@ impl From<&Message> for MessageBoxInfoHeader { // +----------+------+ let root = gtk::Box::new(gtk::Orientation::Horizontal, 0); - let username = - build_room_msg_username(msg.sender_name.as_deref().unwrap_or(msg.sender.as_str())); - let date = build_room_msg_date(&msg.date); + let username = build_room_msg_username( + msg.sender_name + .as_deref() + .unwrap_or(msg.msg.sender.as_str()), + ); + let date = build_room_msg_date(&msg.msg.date); let username_event_box = gtk::EventBox::new(); username_event_box.add(&username); diff --git a/fractal-gtk/src/widgets/room_history.rs b/fractal-gtk/src/widgets/room_history.rs index 34b6135f..6083686e 100644 --- a/fractal-gtk/src/widgets/room_history.rs +++ b/fractal-gtk/src/widgets/room_history.rs @@ -471,8 +471,11 @@ impl RoomHistory { } return Continue(true); } - if let Some(pos) = edits.iter().position(|edit| item.id == edit.msg.replace) { - edits[pos].date = item.date; + if let Some(pos) = edits + .iter() + .position(|edit| item.msg.id == edit.msg.replace) + { + edits[pos].msg.date = item.msg.date; item = edits.remove(pos).unwrap(); } @@ -482,17 +485,17 @@ impl RoomHistory { if let Some(first) = rows.borrow().list.back() { if let Element::Message(ref message) = first { - if item.date.day() != message.date.day() { + if item.msg.date.day() != message.msg.date.day() { prev_day_divider = - Some(Element::DayDivider(create_day_divider(message.date))); + Some(Element::DayDivider(create_day_divider(message.msg.date))); } } }; let has_header = { if let Some(last) = last { - if item.date.day() != last.date.day() { + if item.msg.date.day() != last.msg.date.day() { day_divider = - Some(Element::DayDivider(create_day_divider(item.date))); + Some(Element::DayDivider(create_day_divider(item.msg.date))); } last.mtype == RowType::Emote || !should_group_message(&item, &last) } else { @@ -562,8 +565,9 @@ impl RoomHistory { if let Some(last) = last { match last { Element::Message(ref message) => { - if item.date.day() != message.date.day() { - day_divider = Some(Element::DayDivider(create_day_divider(item.date))); + if item.msg.date.day() != message.msg.date.day() { + day_divider = + Some(Element::DayDivider(create_day_divider(item.msg.date))); } message.mtype == RowType::Emote || !should_group_message(&item, &message) } @@ -610,14 +614,14 @@ impl RoomHistory { .enumerate() .find_map(|(i, e)| match e { Element::Message(ref mut itermessage) - if itermessage.id == item.msg.replace + if itermessage.msg.id == item.msg.replace || itermessage.msg.replace == item.msg.replace => { Some((i, itermessage)) } _ => None, })?; - item.date = msg.date; + item.msg.date = msg.msg.date; let msg_widget = msg.widget.clone()?; item.widget = Some(create_row( @@ -643,14 +647,14 @@ impl RoomHistory { .iter_mut() .enumerate() .find_map(|(i, e)| match e { - Element::Message(ref mut itermessage) if itermessage.id == item.id => { + Element::Message(ref mut itermessage) if itermessage.msg.id == item.msg.id => { Some((i, itermessage)) } _ => None, })?; let msg_widget = msg.widget.clone()?; - let msg_sender = msg.sender.clone(); + let msg_sender = msg.msg.sender.clone(); msg.msg.redacted = true; rows.remove_item(i); @@ -676,7 +680,7 @@ impl RoomHistory { }) .next() .filter(|(msg_next_cloned, _)| { - msg_next_cloned.redactable && msg_next_cloned.sender == msg_sender + msg_next_cloned.redactable && msg_next_cloned.msg.sender == msg_sender }) { msg_widget.update_header(session_client, user_info_cache, msg_next_cloned, true); @@ -769,8 +773,8 @@ fn create_row( /* returns if two messages should have only a single header or not */ fn should_group_message(msg: &MessageContent, prev: &MessageContent) -> bool { - if msg.sender == prev.sender && !prev.msg.redacted { - let diff = msg.date.signed_duration_since(prev.date); + if msg.msg.sender == prev.msg.sender && !prev.msg.redacted { + let diff = msg.msg.date.signed_duration_since(prev.msg.date); let minutes = diff.num_minutes(); minutes < globals::MINUTES_TO_SPLIT_MSGS } else {