Skip to main content

things3_cloud/commands/
upcoming.rs

1use crate::app::Cli;
2use crate::commands::{Command, DetailedArgs};
3use crate::ui::render_element_to_string;
4use crate::ui::views::upcoming::UpcomingView;
5use crate::wire::task::TaskStatus;
6use anyhow::Result;
7use clap::Args;
8use iocraft::prelude::*;
9use std::io::Write;
10use std::sync::Arc;
11
12#[derive(Debug, Default, Args)]
13pub struct UpcomingArgs {
14    #[command(flatten)]
15    pub detailed: DetailedArgs,
16}
17
18impl Command for UpcomingArgs {
19    fn run_with_ctx(
20        &self,
21        cli: &Cli,
22        out: &mut dyn Write,
23        ctx: &mut dyn crate::cmd_ctx::CmdCtx,
24    ) -> Result<()> {
25        let store = Arc::new(cli.load_store()?);
26        let today = ctx.today();
27        let now_ts = today.timestamp();
28
29        let mut tasks = Vec::new();
30        for t in store.tasks(Some(TaskStatus::Incomplete), Some(false), None) {
31            if t.in_someday() {
32                continue;
33            }
34            let Some(start_date) = t.start_date else {
35                continue;
36            };
37            if start_date.timestamp() > now_ts {
38                tasks.push(t);
39            }
40        }
41        tasks.sort_by_key(|t| t.start_date);
42
43        let mut ui = element! {
44            ContextProvider(value: Context::owned(store.clone())) {
45                ContextProvider(value: Context::owned(today)) {
46                    UpcomingView(
47                        items: &tasks,
48                        detailed: self.detailed.detailed,
49                    )
50                }
51            }
52        };
53
54        let rendered = render_element_to_string(&mut ui, cli.no_color);
55        writeln!(out, "{}", rendered)?;
56        Ok(())
57    }
58}