Skip to main content

things3_cloud/ui/views/
inbox.rs

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