Skip to main content

moltbook_cli/display/
utils.rs

1use chrono::{DateTime, Utc};
2use colored::*;
3use terminal_size::{Width, terminal_size};
4
5/// Detects the available terminal width for responsive layout.
6///
7/// Priority:
8/// 1. `COLUMNS` environment variable.
9/// 2. `terminal_size` system call.
10/// 3. Default fallback of 80 characters.
11pub fn get_term_width() -> usize {
12    if let Some(width) = std::env::var("COLUMNS")
13        .ok()
14        .and_then(|c| c.parse::<usize>().ok())
15    {
16        return width.saturating_sub(2).max(40);
17    }
18
19    if let Some((Width(w), _)) = terminal_size() {
20        (w as usize).saturating_sub(2).max(40)
21    } else {
22        80
23    }
24}
25
26/// Formats a UTC timestamp into a human-readable relative string (e.g., "2h ago").
27///
28/// Supports: "just now", minutes, hours, days, or YYYY-MM-DD for older items.
29pub fn relative_time(timestamp: &str) -> String {
30    if let Ok(dt) = DateTime::parse_from_rfc3339(timestamp) {
31        let now = Utc::now();
32        let diff = now.signed_duration_since(dt);
33
34        if diff.num_seconds() < 60 {
35            "just now".to_string()
36        } else if diff.num_minutes() < 60 {
37            format!("{}m ago", diff.num_minutes())
38        } else if diff.num_hours() < 24 {
39            format!("{}h ago", diff.num_hours())
40        } else if diff.num_days() < 7 {
41            format!("{}d ago", diff.num_days())
42        } else {
43            dt.format("%Y-%m-%d").to_string()
44        }
45    } else {
46        timestamp.to_string()
47    }
48}
49
50/// Prints a success message with a green checkmark.
51pub fn success(msg: &str) {
52    println!("{} {}", "✅".green(), msg.bright_green());
53}
54
55/// Prints an error message with a red cross.
56pub fn error(msg: &str) {
57    eprintln!("{} {}", "❌".red().bold(), msg.bright_red());
58}
59
60/// Prints an informational message with a cyan icon.
61pub fn info(msg: &str) {
62    println!("{} {}", "ℹ️ ".cyan(), msg.bright_cyan());
63}
64
65/// Prints a warning message with a yellow triangle.
66pub fn warn(msg: &str) {
67    println!("{} {}", "⚠️ ".yellow(), msg.bright_yellow());
68}