use crate::render::json::JsonToStdout;
use crate::render::option::{option_debug_display, option_display};
use crate::render::ui::fuzzy_select_with_key;
use crate::types::context::BergContext;
use crate::types::output::OutputMode;
use crate::{actions::GlobalArgs, render::datetime::render_datetime_and_info};
use forgejo_api::structs::{NotificationThread, NotifyGetListQuery};
use miette::{Context, IntoDiagnostic};
use clap::Parser;
#[derive(Debug, Parser)]
pub struct ViewNotificationArgs {
pub id: Option<i64>,
#[arg(short, long)]
pub all: bool,
}
impl ViewNotificationArgs {
pub async fn run(self, global_args: GlobalArgs) -> miette::Result<()> {
let ctx = BergContext::new(self, global_args).await?;
let thread_id = if let Some(id) = ctx.args.id {
id
} else {
let (_, notification_threads) = ctx
.client
.notify_get_list(NotifyGetListQuery {
..Default::default()
})
.await
.into_diagnostic()?;
fuzzy_select_with_key(
¬ification_threads
.iter()
.filter(|thread| thread.id.is_some())
.collect::<Vec<_>>(),
"notification thread",
|thread| {
option_display(
&thread
.subject
.as_ref()
.and_then(|subject| subject.title.as_ref()),
)
},
)
.and_then(|thread| thread.id.context("No ID on selected thread"))?
};
let selected_notification_thread = ctx
.client
.notify_get_thread(thread_id)
.await
.into_diagnostic()?;
match ctx.global_args.output_mode {
OutputMode::Pretty => {
present_notification_thread_details(&ctx, selected_notification_thread);
}
OutputMode::Json => selected_notification_thread.print_json()?,
}
Ok(())
}
}
fn present_notification_thread_details(
ctx: &BergContext<ViewNotificationArgs>,
notification_thread: NotificationThread,
) {
let table = ctx
.make_table()
.add_row(vec![
String::from("Title"),
option_display(
¬ification_thread
.subject
.as_ref()
.and_then(|subject| subject.title.as_ref()),
),
])
.add_row(vec![
String::from("URL"),
option_display(
¬ification_thread
.subject
.as_ref()
.and_then(|subject| subject.html_url.as_ref()),
),
])
.add_row(vec![
String::from("Type"),
option_display(
¬ification_thread
.subject
.as_ref()
.and_then(|subject| subject.r#type)
.and_then(|subject| serde_json::to_string(&subject).ok()),
),
])
.add_row(vec![
String::from("State"),
option_debug_display(
¬ification_thread
.subject
.as_ref()
.and_then(|subject| subject.state.as_ref()),
),
])
.add_row(vec![
"Unread",
if notification_thread.unread.is_some_and(|is_true| is_true) {
"Yes"
} else {
"No"
},
])
.add_row(vec![
"Pinned",
if notification_thread.pinned.is_some_and(|is_true| is_true) {
"Yes"
} else {
"No"
},
])
.add_row(vec![
String::from("Last updated"),
option_display(
¬ification_thread
.updated_at
.as_ref()
.map(render_datetime_and_info),
),
]);
println!("{table}", table = table.show());
}