diff options
Diffstat (limited to 'src/comments/display.rs')
-rw-r--r-- | src/comments/display.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/comments/display.rs b/src/comments/display.rs new file mode 100644 index 0000000..7000063 --- /dev/null +++ b/src/comments/display.rs @@ -0,0 +1,117 @@ +// yt - A fully featured command line YouTube client +// +// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This file is part of Yt. +// +// You should have received a copy of the License along with this program. +// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. + +use std::fmt::Write; + +use chrono::{Local, TimeZone}; +use chrono_humanize::{Accuracy, HumanTime, Tense}; + +use crate::comments::comment::CommentExt; + +use super::comment::Comments; + +impl Comments { + pub fn render(&self, color: bool) -> String { + self.render_help(color).expect("This should never fail.") + } + + fn render_help(&self, color: bool) -> Result<String, std::fmt::Error> { + let mut f = String::new(); + + macro_rules! c { + ($color_str:expr, $write:ident, $color:expr) => { + if $color { + $write.write_str(concat!("\x1b[", $color_str, "m"))? + } + }; + } + + fn format( + comment: &CommentExt, + f: &mut String, + ident_count: u32, + color: bool, + ) -> std::fmt::Result { + let ident = &(0..ident_count).map(|_| " ").collect::<String>(); + let value = &comment.value; + + f.write_str(ident)?; + + if value.author_is_uploader { + c!("91;1", f, color); + } else { + c!("35", f, color); + } + + f.write_str(&value.author)?; + c!("0", f, color); + if value.edited || value.is_favorited { + f.write_str("[")?; + if value.edited { + f.write_str("")?; + } + if value.edited && value.is_favorited { + f.write_str(" ")?; + } + if value.is_favorited { + f.write_str("")?; + } + f.write_str("]")?; + } + + c!("36;1", f, color); + write!( + f, + " {}", + HumanTime::from( + Local + .timestamp_opt(value.timestamp, 0) + .single() + .expect("This should be valid") + ) + .to_text_en(Accuracy::Rough, Tense::Past) + )?; + c!("0", f, color); + + // c!("31;1", f); + // f.write_fmt(format_args!(" [{}]", comment.value.like_count))?; + // c!("0", f); + + f.write_str(":\n")?; + f.write_str(ident)?; + + f.write_str(&value.text.replace('\n', &format!("\n{}", ident)))?; + f.write_str("\n")?; + + if !comment.replies.is_empty() { + let mut children = comment.replies.clone(); + children.sort_by(|a, b| a.value.timestamp.cmp(&b.value.timestamp)); + + for child in children { + format(&child, f, ident_count + 4, color)?; + } + } else { + f.write_str("\n")?; + } + + Ok(()) + } + + if !&self.vec.is_empty() { + let mut children = self.vec.clone(); + children.sort_by(|a, b| b.value.like_count.cmp(&a.value.like_count)); + + for child in children { + format(&child, &mut f, 0, color)? + } + } + Ok(f) + } +} |