things3_cloud/ui/views/
inbox.rs1use 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}