[fractal/split-appop-ui: 5/5] Clean MessageContent




commit 60e81c4a7b101a98244cb36f3929244c56cdbb9a
Author: Alejandro Domínguez <adomu net-c com>
Date:   Fri Jan 15 18:16:23 2021 +0100

    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<MessageContent> {
+    pub fn create_new_room_message(&self, msg: Message) -> Option<MessageContent> {
         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<String>,
-    t: RowType,
-    highlights: Vec<String>,
-    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<Local>> {
+        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<EventId>,
-    pub sender: UserId,
+    pub msg: Message,
     pub sender_name: Option<String>,
     pub mtype: RowType,
-    pub body: String,
-    pub date: DateTime<Local>,
-    pub replace_date: Option<DateTime<Local>>,
-    pub thumb: Option<Url>,
-    pub url: Option<Url>,
-    pub local_path: Option<PathBuf>,
-    pub formatted_body: Option<String>,
-    pub format: Option<String>,
-    /* in some places we still need the backend message type (e.g. media viewer) */
-    pub msg: Message,
     pub highlights: Vec<String>,
     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::<gtk::Widget>()
         };
 
-        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!("<b>{}</b>", msg.body)));
+    let file_name = gtk::Label::new(Some(&format!("<b>{}</b>", 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<Rc<VideoPlayerWidget>>) {
     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!("<b>{}</b> {}", 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 {


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