things3_cloud/commands/
today.rs1use std::{io::Write, sync::Arc};
2
3use anyhow::Result;
4use clap::Args;
5use iocraft::prelude::*;
6
7use crate::{
8 app::Cli,
9 commands::{Command, DetailedArgs, detailed_json_conflict, write_json},
10 ui::{
11 render_element_to_string,
12 views::{json::today::TodayJsonView, today::TodayView},
13 },
14 wire::task::TaskStatus,
15};
16
17#[derive(Debug, Default, Args)]
18pub struct TodayArgs {
19 #[command(flatten)]
20 pub detailed: DetailedArgs,
21}
22
23impl Command for TodayArgs {
24 fn run_with_ctx(
25 &self,
26 cli: &Cli,
27 out: &mut dyn Write,
28 ctx: &mut dyn crate::cmd_ctx::CmdCtx,
29 ) -> Result<()> {
30 let store = Arc::new(cli.load_store()?);
31 let today = ctx.today();
32
33 let mut today_items: Vec<_> = store
34 .tasks(Some(TaskStatus::Incomplete), Some(false), None)
35 .into_iter()
36 .filter(|t| {
37 !t.is_heading()
38 && !t.title.trim().is_empty()
39 && t.entity == "Task6"
40 && (t.is_today(&today) || t.evening)
41 })
42 .collect();
43
44 today_items.sort_by_key(|task| {
45 let tir = task.today_index_reference.unwrap_or(0);
46 (
47 std::cmp::Reverse(tir),
48 task.today_index,
49 std::cmp::Reverse(task.index),
50 )
51 });
52
53 let json = cli.json;
54 if json {
55 if detailed_json_conflict(json, self.detailed.detailed) {
56 return Ok(());
57 }
58 write_json(out, &TodayJsonView::build(&today_items, &store, &today))?;
59 return Ok(());
60 }
61
62 let mut ui = element! {
63 ContextProvider(value: Context::owned(store.clone())) {
64 ContextProvider(value: Context::owned(today)) {
65 TodayView(
66 items: &today_items,
67 detailed: self.detailed.detailed,
68 )
69 }
70 }
71 };
72 let rendered = render_element_to_string(&mut ui, cli.no_color);
73 writeln!(out, "{}", rendered)?;
74
75 Ok(())
76 }
77}