Skip to main content

mneme/tui/
app.rs

1use crate::config::settings::Settings;
2use crate::store::db::Database;
3use crate::store::memory::{Memory, MemoryStats, ProjectSummary, SearchQuery, Session};
4use std::sync::Arc;
5
6pub struct App {
7    pub db: Arc<Database>,
8    pub screen: Screen,
9    // Project list
10    pub projects: Vec<ProjectSummary>,
11    pub proj_sel: usize,
12    // Memory list
13    pub project: String,
14    pub memories: Vec<Memory>,
15    pub mem_sel: usize,
16    pub mem_scroll: usize,
17    pub stats: Option<MemoryStats>,
18    // Detail
19    pub detail: Option<Memory>,
20    pub detail_scroll: usize,
21    // Sessions
22    pub sessions: Vec<Session>,
23    // Search
24    pub search: String,
25    pub searching: bool,
26    // UI
27    pub quit: bool,
28    pub msg: String,
29    pub total_mems: u32,
30}
31
32#[derive(Clone, Copy, PartialEq)]
33pub enum Screen {
34    Projects,
35    Memories,
36    Detail,
37    Sessions,
38    Help,
39}
40
41impl App {
42    pub fn new(db: Arc<Database>, _settings: Arc<Settings>) -> Self {
43        let projects = db.memories().list_projects().unwrap_or_default();
44        let total: u32 = projects.iter().map(|p| p.memory_count).sum();
45        Self {
46            db,
47            screen: Screen::Projects,
48            projects,
49            proj_sel: 0,
50            project: String::new(),
51            memories: vec![],
52            mem_sel: 0,
53            mem_scroll: 0,
54            stats: None,
55            detail: None,
56            detail_scroll: 0,
57            sessions: vec![],
58            search: String::new(),
59            searching: false,
60            quit: false,
61            msg: String::new(),
62            total_mems: total,
63        }
64    }
65    pub fn load_projects(&mut self) {
66        self.projects = self.db.memories().list_projects().unwrap_or_default();
67        self.total_mems = self.projects.iter().map(|p| p.memory_count).sum();
68    }
69    pub fn load_memories(&mut self) {
70        self.memories = self
71            .db
72            .memories()
73            .list(&self.project, None, None, None, 500, 0)
74            .unwrap_or_default();
75        self.stats = self.db.memories().stats(&self.project).ok();
76        self.mem_sel = 0;
77        self.mem_scroll = 0;
78    }
79    pub fn load_sessions(&mut self) {
80        self.sessions = self
81            .db
82            .sessions()
83            .list(&self.project, 100)
84            .unwrap_or_default();
85    }
86    pub fn search_all(&mut self) {
87        if self.search.is_empty() {
88            self.load_projects();
89            return;
90        }
91        let q = SearchQuery {
92            text: self.search.clone(),
93            project: None,
94            scope: None,
95            memory_type: None,
96            importance: None,
97            tags: vec![],
98            limit: 200,
99            include_snippet: true,
100            all_projects: true,
101        };
102        self.memories = self
103            .db
104            .memories()
105            .search(&q, &crate::store::search::SearchWeights::default(), None)
106            .unwrap_or_default()
107            .into_iter()
108            .map(|r| r.memory)
109            .collect();
110        self.screen = Screen::Memories;
111        self.project = format!("search: {}", self.search);
112    }
113    pub fn load(&mut self) {
114        self.load_projects();
115    }
116    pub fn delete_sel(&mut self) {
117        if let Some(m) = self.detail.clone() {
118            let _ = self.db.memories().delete(m.id, false);
119            self.msg = format!("Deleted: {}", m.title);
120            self.detail = None;
121            self.screen = Screen::Memories;
122            self.load_memories();
123        }
124    }
125}