use crate::db::jira_inbox::JiraInbox;
use crate::db::tasks::Tasks;
use crate::libs::inbox_filter;
use crate::libs::task::{Task, TaskFilter};
use crate::libs::toast_action::{ToastAction, ToastRequest};
use anyhow::Result;
use chrono::{Local, NaiveDateTime};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Applied {
Taken,
AlreadyTaken(String),
Snoozed(NaiveDateTime),
Dismissed,
NotFound,
}
impl Applied {
pub fn summary(&self, key: &str) -> String {
match self {
Applied::Taken => format!("{key} is now a task"),
Applied::AlreadyTaken(name) => format!("{key} was already taken as '{name}'"),
Applied::Snoozed(until) => format!("{key} sleeps until {}", until.format("%b %-d %H:%M")),
Applied::Dismissed => format!("{key} dismissed"),
Applied::NotFound => format!("{key} is no longer in the inbox"),
}
}
pub fn settled(&self) -> bool {
!matches!(self, Applied::NotFound)
}
}
pub fn apply(request: &ToastRequest) -> Result<Applied> {
match request.action {
ToastAction::Take => take(&request.issue_key),
ToastAction::Snooze => {
let window = snooze_window();
snooze(&request.issue_key, window)
}
ToastAction::Dismiss => dismiss(&request.issue_key),
}
}
pub fn snooze_window() -> chrono::Duration {
let configured = crate::libs::config::Config::read().ok().and_then(|c| c.jira_inbox).map(|i| i.toast_snooze_for);
match configured.as_deref().map(inbox_filter::parse_window) {
Some(Ok(window)) => window,
_ => chrono::Duration::days(1),
}
}
pub fn take(key: &str) -> Result<Applied> {
let db = JiraInbox::new()?;
let Some(item) = db.get_by_key(key)? else {
return Ok(Applied::NotFound);
};
let mut tasks = Tasks::new()?;
if let Some(task) = tasks.fetch(TaskFilter::ByJiraKey(key.to_string()))?.first() {
if item.taken_at.is_none() {
let _ = db.set_taken(key, true)?;
}
return Ok(Applied::AlreadyTaken(task.name.clone()));
}
let name = format!("{} {}", item.issue_key, item.summary);
let task = Task::new(&name, "", Some(0)).from_jira(key);
tasks.insert(&task)?;
let _ = db.set_taken(key, true)?;
Ok(Applied::Taken)
}
pub fn snooze(key: &str, window: chrono::Duration) -> Result<Applied> {
let until = Local::now().naive_local() + window;
let db = JiraInbox::new()?;
if !db.set_snoozed(key, Some(until))? {
return Ok(Applied::NotFound);
}
Ok(Applied::Snoozed(until))
}
pub fn dismiss(key: &str) -> Result<Applied> {
let db = JiraInbox::new()?;
if !db.set_dismissed(key, true)? {
return Ok(Applied::NotFound);
}
Ok(Applied::Dismissed)
}