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 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, global_args: GlobalArgs) -> anyhow::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            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.client.notify_get_thread(thread_id).await?;
53
54        match ctx.global_args.output_mode {
55            OutputMode::Pretty => {
56                present_notification_thread_details(&ctx, selected_notification_thread);
57            }
58            OutputMode::Json => selected_notification_thread.print_json()?,
59        }
60
61        Ok(())
62    }
63}
64
65fn present_notification_thread_details(
66    ctx: &BergContext<ViewNotificationArgs>,
67    notification_thread: NotificationThread,
68) {
69    let mut table = ctx.make_table();
70
71    table
72        .add_row(vec![
73            String::from("Title"),
74            option_display(
75                &notification_thread
76                    .subject
77                    .as_ref()
78                    .and_then(|subject| subject.title.as_ref()),
79            ),
80        ])
81        .add_row(vec![
82            String::from("URL"),
83            option_display(
84                &notification_thread
85                    .subject
86                    .as_ref()
87                    .and_then(|subject| subject.html_url.as_ref()),
88            ),
89        ])
90        .add_row(vec![
91            String::from("Type"),
92            option_display(
93                &notification_thread
94                    .subject
95                    .as_ref()
96                    .and_then(|subject| subject.r#type)
97                    .and_then(|subject| serde_json::to_string(&subject).ok()),
98            ),
99        ])
100        .add_row(vec![
101            String::from("State"),
102            option_debug_display(
103                &notification_thread
104                    .subject
105                    .as_ref()
106                    .and_then(|subject| subject.state.as_ref()),
107            ),
108        ])
109        .add_row(vec![
110            "Unread",
111            if notification_thread.unread.is_some_and(|is_true| is_true) {
112                "Yes"
113            } else {
114                "No"
115            },
116        ])
117        .add_row(vec![
118            "Pinned",
119            if notification_thread.pinned.is_some_and(|is_true| is_true) {
120                "Yes"
121            } else {
122                "No"
123            },
124        ])
125        .add_row(vec![
126            String::from("Last updated"),
127            option_display(
128                &notification_thread
129                    .updated_at
130                    .as_ref()
131                    .map(render_datetime_and_info),
132            ),
133        ]);
134
135    println!("{table}", table = table.show());
136}