Skip to main content

things3_cloud/ui/views/
inbox.rs

1use std::sync::Arc;
2
3use iocraft::prelude::*;
4
5use crate::{
6    common::ICONS,
7    store::{Task, ThingsStore},
8    ui::components::{
9        empty_text::EmptyText,
10        tasks::{TaskList, TaskOptions},
11    },
12};
13
14const LIST_INDENT: u32 = 2;
15
16fn id_prefix_len(store: &ThingsStore, items: &[Task]) -> usize {
17    let ids = items
18        .iter()
19        .map(|task| task.uuid.clone())
20        .collect::<Vec<_>>();
21    store.unique_prefix_length(&ids)
22}
23
24#[derive(Default, Props)]
25pub struct InboxViewProps<'a> {
26    pub items: Option<&'a Vec<Task>>,
27    pub detailed: bool,
28}
29
30#[component]
31pub fn InboxView<'a>(hooks: Hooks, props: &InboxViewProps<'a>) -> impl Into<AnyElement<'a>> {
32    let store = hooks.use_context::<Arc<ThingsStore>>().clone();
33    let Some(items) = props.items else {
34        return element!(Text(content: "")).into_any();
35    };
36
37    let content: AnyElement<'a> = {
38        if items.is_empty() {
39            element! { EmptyText(content: "Inbox is empty.") }.into_any()
40        } else {
41            let prefix_len = id_prefix_len(store.as_ref(), items);
42            let refs = items.iter().collect::<Vec<_>>();
43            element! {
44                View(flex_direction: FlexDirection::Column, gap: 1) {
45                    Text(
46                        content: format!("{} Inbox  ({} tasks)", ICONS.inbox, items.len()),
47                        wrap: TextWrap::NoWrap,
48                        color: Color::Blue,
49                        weight: Weight::Bold,
50                    )
51                    View(flex_direction: FlexDirection::Column, padding_left: LIST_INDENT) {
52                        TaskList(
53                            items: refs,
54                            id_prefix_len: prefix_len,
55                            options: TaskOptions {
56                                detailed: props.detailed,
57                                show_project: false,
58                                show_area: false,
59                                show_today_markers: true,
60                                show_staged_today_marker: false,
61                            },
62                        )
63                    }
64                }
65            }
66            .into_any()
67        }
68    };
69
70    content
71}