codeberg_cli/actions/notification/
view.rs

1use crate::render::json::JsonToStdout;
2use crate::render::option::{option_debug_display, option_display};
3use crate::render::ui::fuzzy_select_with_key;
4use crate::types::context::BergContext;
5use crate::types::output::OutputMode;
6use crate::{actions::GeneralArgs, render::datetime::render_datetime_and_info};
7use anyhow::Context;
8use forgejo_api::structs::{NotificationThread, NotifyGetListQuery};
9
10use clap::Parser;
11#[derive(Debug, Parser)]
12pub struct ViewNotificationArgs {
13    /// view specific notification if available
14    pub id: Option<i64>,
15
16    /// show everything about the notification if available
17    #[arg(short, long)]
18    pub all: bool,
19}
20
21impl ViewNotificationArgs {
22    pub async fn run(self, general_args: GeneralArgs) -> anyhow::Result<()> {
23        let ctx = BergContext::new(self, general_args).await?;
24
25        let thread_id = if let Some(id) = ctx.args.id {
26            id
27        } else {
28            let (_, notification_threads) = ctx
29                .client
30                .notify_get_list(NotifyGetListQuery {
31                    ..Default::default()
32                })
33                .await?;
34            fuzzy_select_with_key(
35                &notification_threads
36                    .iter()
37                    .filter(|thread| thread.id.is_some())
38                    .collect::<Vec<_>>(),
39                "notification thread",
40                |thread| {
41                    option_display(
42                        &thread
43                            .subject
44                            .as_ref()
45                            .and_then(|subject| subject.title.as_ref()),
46                    )
47                },
48            )
49            .and_then(|thread| thread.id.context("No ID on selected thread"))?
50        };
51
52        let selected_notification_thread = ctx
53            .client
54            .notify_get_thread(thread_id.to_string().as_str())
55            .await?;
56
57        match general_args.output_mode {
58            OutputMode::Pretty => {
59                present_notification_thread_details(&ctx, selected_notification_thread);
60            }
61            OutputMode::Json => selected_notification_thread.print_json()?,
62        }
63
64        Ok(())
65    }
66}
67
68fn present_notification_thread_details(
69    ctx: &BergContext<ViewNotificationArgs>,
70    notification_thread: NotificationThread,
71) {
72    let mut table = ctx.make_table();
73
74    table
75        .add_row(vec![
76            String::from("Title"),
77            option_display(
78                &notification_thread
79                    .subject
80                    .as_ref()
81                    .and_then(|subject| subject.title.as_ref()),
82            ),
83        ])
84        .add_row(vec![
85            String::from("URL"),
86            option_display(
87                &notification_thread
88                    .subject
89                    .as_ref()
90                    .and_then(|subject| subject.html_url.as_ref()),
91            ),
92        ])
93        .add_row(vec![
94            String::from("Type"),
95            option_display(
96                &notification_thread
97                    .subject
98                    .as_ref()
99                    .and_then(|subject| subject.r#type.as_ref()),
100            ),
101        ])
102        .add_row(vec![
103            String::from("State"),
104            option_debug_display(
105                &notification_thread
106                    .subject
107                    .as_ref()
108                    .and_then(|subject| subject.state.as_ref()),
109            ),
110        ])
111        .add_row(vec![
112            "Unread",
113            if notification_thread.unread.is_some_and(|is_true| is_true) {
114                "Yes"
115            } else {
116                "No"
117            },
118        ])
119        .add_row(vec![
120            "Pinned",
121            if notification_thread.pinned.is_some_and(|is_true| is_true) {
122                "Yes"
123            } else {
124                "No"
125            },
126        ])
127        .add_row(vec![
128            String::from("Last updated"),
129            option_display(
130                &notification_thread
131                    .updated_at
132                    .as_ref()
133                    .map(render_datetime_and_info),
134            ),
135        ]);
136
137    println!("{table}", table = table.show());
138}