Skip to main content

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::GlobalArgs, render::datetime::render_datetime_and_info};
7use forgejo_api::structs::{NotificationThread, NotifyGetListQuery};
8use miette::{Context, IntoDiagnostic};
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, global_args: GlobalArgs) -> miette::Result<()> {
23        let ctx = BergContext::new(self, global_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                .into_diagnostic()?;
35            fuzzy_select_with_key(
36                &notification_threads
37                    .iter()
38                    .filter(|thread| thread.id.is_some())
39                    .collect::<Vec<_>>(),
40                "notification thread",
41                |thread| {
42                    option_display(
43                        &thread
44                            .subject
45                            .as_ref()
46                            .and_then(|subject| subject.title.as_ref()),
47                    )
48                },
49            )
50            .and_then(|thread| thread.id.context("No ID on selected thread"))?
51        };
52
53        let selected_notification_thread = ctx
54            .client
55            .notify_get_thread(thread_id)
56            .await
57            .into_diagnostic()?;
58
59        match ctx.global_args.output_mode {
60            OutputMode::Pretty => {
61                present_notification_thread_details(&ctx, selected_notification_thread);
62            }
63            OutputMode::Json => selected_notification_thread.print_json()?,
64        }
65
66        Ok(())
67    }
68}
69
70fn present_notification_thread_details(
71    ctx: &BergContext<ViewNotificationArgs>,
72    notification_thread: NotificationThread,
73) {
74    let table = ctx
75        .make_table()
76        .add_row(vec![
77            String::from("Title"),
78            option_display(
79                &notification_thread
80                    .subject
81                    .as_ref()
82                    .and_then(|subject| subject.title.as_ref()),
83            ),
84        ])
85        .add_row(vec![
86            String::from("URL"),
87            option_display(
88                &notification_thread
89                    .subject
90                    .as_ref()
91                    .and_then(|subject| subject.html_url.as_ref()),
92            ),
93        ])
94        .add_row(vec![
95            String::from("Type"),
96            option_display(
97                &notification_thread
98                    .subject
99                    .as_ref()
100                    .and_then(|subject| subject.r#type)
101                    .and_then(|subject| serde_json::to_string(&subject).ok()),
102            ),
103        ])
104        .add_row(vec![
105            String::from("State"),
106            option_debug_display(
107                &notification_thread
108                    .subject
109                    .as_ref()
110                    .and_then(|subject| subject.state.as_ref()),
111            ),
112        ])
113        .add_row(vec![
114            "Unread",
115            if notification_thread.unread.is_some_and(|is_true| is_true) {
116                "Yes"
117            } else {
118                "No"
119            },
120        ])
121        .add_row(vec![
122            "Pinned",
123            if notification_thread.pinned.is_some_and(|is_true| is_true) {
124                "Yes"
125            } else {
126                "No"
127            },
128        ])
129        .add_row(vec![
130            String::from("Last updated"),
131            option_display(
132                &notification_thread
133                    .updated_at
134                    .as_ref()
135                    .map(render_datetime_and_info),
136            ),
137        ]);
138
139    println!("{table}", table = table.show());
140}