Something went wrong. Try again.
forked from evanpurkhiser/things3-cloud
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130use iocraft::prelude::*;
use crate::{ common::{ICONS, note_lines}, store::Task, ui::components::{ checklist::CheckList, details_container::DetailsContainer, id::Id, task_line::TaskLine, tasks::TaskOptions, },};
#[derive(Default, Props)]pub struct TaskItemProps<'a> { pub task: Option<&'a Task>, pub options: TaskOptions, pub id_prefix_len: usize,}
#[component]pub fn TaskItem<'a>(props: &TaskItemProps<'a>) -> impl Into<AnyElement<'a>> { let Some(task) = props.task else { return element!(Fragment).into_any(); };
let details = if props.options.detailed { element! { TaskDetails(task: task, id_prefix_len: props.id_prefix_len) } .into_any() } else { element!(Fragment).into_any() };
element! { View(flex_direction: FlexDirection::Row, gap: 1) { Id(id: &task.uuid, length: props.id_prefix_len) View(flex_direction: FlexDirection::Column) { TaskText(task: task, options: props.options) #(details) } } } .into_any()}
#[derive(Default, Props)]struct TaskTextProps<'a> { pub task: Option<&'a Task>, pub options: TaskOptions,}
#[component]fn TaskText<'a>(props: &TaskTextProps<'a>) -> impl Into<AnyElement<'a>> { let Some(task) = props.task else { return element!(Fragment).into_any(); };
element! { View(flex_direction: FlexDirection::Row, gap: 1) { Text(content: checkbox_str(task), color: Color::DarkGrey) TaskLine( task: task, show_today_markers: props.options.show_today_markers, show_staged_today_marker: props.options.show_staged_today_marker, show_tags: true, show_project: props.options.show_project, show_area: props.options.show_area, ) } } .into_any()}
#[derive(Default, Props)]struct TaskDetailProps<'a> { pub task: Option<&'a Task>, pub id_prefix_len: usize,}
#[component]fn TaskDetails<'a>(props: &TaskDetailProps<'a>) -> impl Into<AnyElement<'a>> { let Some(task) = props.task else { return element!(Fragment).into_any(); };
let show_ids = props.id_prefix_len > 0; let note_text = task.notes.as_deref().unwrap_or("").trim();
let checklist_items = if task.checklist_items.is_empty() { None } else { Some(task.checklist_items.as_slice()) };
if note_text.is_empty() && checklist_items.is_none() { return element!(Fragment).into_any(); }
let note_text = if note_text.is_empty() { element!(Fragment).into_any() } else { element!(Text(content: note_lines(note_text), color: Color::DarkGrey)).into_any() };
element! { DetailsContainer { View(flex_direction: FlexDirection::Column, gap: 1) { #(note_text) CheckList(items: checklist_items, show_ids, shift_left: true) } }
} .into_any()}
fn checkbox_str(task: &Task) -> &'static str { if task.is_recurrence_template() { ICONS.repeat } else if task.is_completed() { ICONS.task_done } else if task.is_canceled() { ICONS.task_canceled } else if task.in_someday() { ICONS.task_someday } else { ICONS.task_open }}