diff --git a/Cargo.lock b/Cargo.lock index cd184e6f..9c902e73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -289,6 +289,11 @@ name = "dtoa" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "either" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "encoding_rs" version = "0.7.2" @@ -373,6 +378,7 @@ dependencies = [ "gstreamer-player 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "gtk 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "html2pango 0.1.0 (git+https://gitlab.gnome.org/World/html2pango)", + "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "letter-avatar 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "notify-rust 3.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -897,6 +903,14 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itertools" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.2" @@ -2301,6 +2315,7 @@ dependencies = [ "checksum dbus 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4a0c10ea61042b7555729ab0608727bbbb06ce709c11e6047cfa4e10f6d052d" "checksum dbus 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "58ec7b4cac6f79f36af1cd9cfdb9b935fc5a4e899f494ee03a3a6165f7d10b4b" "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" +"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d" "checksum entities 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" @@ -2348,6 +2363,7 @@ dependencies = [ "checksum hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a5aa51f6ae9842239b0fac14af5f22123b8432b4cc774a44ff059fcba0f675ca" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" diff --git a/fractal-gtk/Cargo.toml b/fractal-gtk/Cargo.toml index 332e8a28..77a3023a 100644 --- a/fractal-gtk/Cargo.toml +++ b/fractal-gtk/Cargo.toml @@ -33,6 +33,7 @@ log = "0.4.3" fragile = "0.2.1" letter-avatar = "0.1.1" sourceview = "0.4.0" +itertools = "0.7.8" [dependencies.cairo-rs] features = ["png"] diff --git a/fractal-gtk/src/main.rs b/fractal-gtk/src/main.rs index bb0719f5..c1e920b4 100644 --- a/fractal-gtk/src/main.rs +++ b/fractal-gtk/src/main.rs @@ -5,6 +5,7 @@ extern crate gtk; extern crate gdk; extern crate rand; +extern crate itertools; extern crate gstreamer as gst; extern crate gstreamer_player as gst_player; diff --git a/fractal-gtk/src/widgets/message.rs b/fractal-gtk/src/widgets/message.rs index 3545882a..a23f0efa 100644 --- a/fractal-gtk/src/widgets/message.rs +++ b/fractal-gtk/src/widgets/message.rs @@ -3,6 +3,7 @@ extern crate chrono; extern crate pango; extern crate glib; +use itertools::Itertools; use app::App; use i18n::i18n; @@ -285,61 +286,17 @@ impl<'a> MessageBox<'a> { fn calculate_msg_parts(&self, body: &str) -> Vec { let mut parts_labels: Vec = vec![]; - let lines: Vec<&str> = body.lines().map(|l| l.trim()).collect(); - let mut lines_read: usize = 0; - let mut parts_lines: Vec<(Vec<&str>, bool)> = vec![]; - - while lines_read < lines.len() { - if let Some(line) = lines.get(lines_read) { - let is_quote = line.starts_with(">"); - - let part_lines: Vec<&str> = if is_quote { - lines.iter().skip(lines_read).take_while(|line| { - if line.starts_with(">") { - lines_read += 1; - true - } else { - false - } - }).map(|line| *line).collect() - } else { - lines.iter().skip(lines_read).take_while(|line| { - if !line.starts_with(">") { - lines_read += 1; - true - } else { - false - } - }).map(|line| *line).collect() - }; - - parts_lines.push((part_lines, is_quote)); - } - } - - for (lines, is_quote) in parts_lines.iter_mut() { - for line in lines { - if *is_quote { - *line = line.trim_left_matches(">").trim_left(); - } - } - } - - let parts: Vec<(String, bool)> = parts_lines.iter() - .map(|(part_lines, is_quote)| - (part_lines.join("\n").trim().to_string(), *is_quote) - ).collect(); - - for (part, is_quote) in parts { + for (part, kind) in split_msg(body) { let msg_part = gtk::Label::new(""); self.connect_right_click_menu(msg_part.clone().upcast::()); msg_part.set_markup(&markup_text(&part)); self.set_label_styles(&msg_part); - if is_quote { - if let Some(style) = msg_part.get_style_context() { - style.add_class("quote"); + match kind { + MsgPartType::Quote => { + msg_part.get_style_context().map(|s| s.add_class("quote")); } + _ => {} } parts_labels.push(msg_part); @@ -691,3 +648,36 @@ fn set_username_async(backend: Sender, } }); } + +#[derive(PartialEq)] +enum MsgPartType { + Normal, + Quote, +} + +fn kind_of_line(line: &&str) -> MsgPartType { + match line { + l if l.starts_with(">") => MsgPartType::Quote, + _ => MsgPartType::Normal, + } +} + +/// Split a message into parts depending on the kind +/// Currently supported types: +/// * Normal +/// * Quote +fn split_msg(body: &str) -> Vec<(String, MsgPartType)> { + let mut parts: Vec<(String, MsgPartType)> = vec![]; + + for (k, group) in body.lines() + .map(|l| l.trim()) + .group_by(kind_of_line).into_iter() { + let v: Vec<&str> = group + .map(|l| l.trim_left_matches(">").trim_left()) + .collect(); + let s = v.join("\n").to_string(); + parts.push((s, k)); + } + + parts +}