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 anyhow::Context;
8use forgejo_api::structs::{NotificationThread, NotifyGetListQuery};
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) -> 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 ¬ification_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 ¬ification_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 ¬ification_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 ¬ification_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 ¬ification_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 ¬ification_thread
129 .updated_at
130 .as_ref()
131 .map(render_datetime_and_info),
132 ),
133 ]);
134
135 println!("{table}", table = table.show());
136}