codeberg_cli/actions/notification/
view.rs1use 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 pub id: Option<i64>,
15
16 #[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 ¬ification_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 ¬ification_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 ¬ification_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 ¬ification_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 ¬ification_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 ¬ification_thread
133 .updated_at
134 .as_ref()
135 .map(render_datetime_and_info),
136 ),
137 ]);
138
139 println!("{table}", table = table.show());
140}