use crate::render::option::option_display;
use crate::render::ui::fuzzy_select_with_key;
use crate::types::context::BergContext;
use crate::{actions::GeneralArgs, render::datetime::render_datetime_and_info};
use anyhow::Context;
use forgejo_api::structs::{NotificationThread, NotifyGetListQuery};
use clap::Parser;
#[derive(Debug, Parser)]
pub struct ViewNotificationArgs {
pub id: Option<u64>,
#[arg(short, long)]
pub all: bool,
}
impl ViewNotificationArgs {
pub async fn run(self, general_args: GeneralArgs) -> anyhow::Result<()> {
let _ = general_args;
let ctx = BergContext::new(self).await?;
let thread_id = if let Some(id) = ctx.args.id {
id
} else {
fuzzy_select_with_key(
&ctx.client
.notify_get_list(NotifyGetListQuery {
..Default::default()
})
.await?
.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.to_string().as_str())
.await?;
present_notification_thread_details(&ctx, selected_notification_thread);
Ok(())
}
}
fn present_notification_thread_details(
ctx: &BergContext<ViewNotificationArgs>,
notification_thread: NotificationThread,
) {
let mut table = ctx.make_table();
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.as_ref()),
),
])
.add_row(vec![
String::from("State"),
option_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}");
}