kimun_notes/components/note_browser/
search_provider.rs1use std::sync::Arc;
2
3use async_trait::async_trait;
4use kimun_core::NoteVault;
5use kimun_core::nfs::{NoteEntryData, VaultPath};
6use kimun_core::note::NoteContentData;
7
8use super::{NoteBrowserProvider, format_journal_date};
9use crate::components::file_list::FileListEntry;
10
11pub struct SearchNotesProvider {
12 vault: Arc<NoteVault>,
13 last_paths: Vec<VaultPath>,
14}
15
16impl SearchNotesProvider {
17 pub fn new(vault: Arc<NoteVault>, last_paths: Vec<VaultPath>) -> Self {
18 Self { vault, last_paths }
19 }
20
21 fn to_entry(&self, entry: NoteEntryData, content: NoteContentData) -> FileListEntry {
22 let filename = entry.path.get_parent_path().1;
23 let title = if content.title.trim().is_empty() {
24 "<no title>".to_string()
25 } else {
26 content.title
27 };
28 let journal_date = self
29 .vault
30 .journal_date(&entry.path)
31 .map(format_journal_date);
32 FileListEntry::Note {
33 path: entry.path,
34 title,
35 filename,
36 journal_date,
37 }
38 }
39}
40
41#[async_trait]
42impl NoteBrowserProvider for SearchNotesProvider {
43 async fn load(&self, query: &str) -> Vec<FileListEntry> {
44 if query.is_empty() {
45 let all_notes = self.vault.get_all_notes().await.unwrap_or_default();
48 let mut by_path: std::collections::HashMap<_, _> = all_notes
49 .into_iter()
50 .map(|(entry, content)| (entry.path.clone(), (entry, content)))
51 .collect();
52
53 self.last_paths
55 .iter()
56 .filter_map(|path| by_path.remove(path))
57 .map(|(entry, content)| self.to_entry(entry, content))
58 .collect()
59 } else {
60 self.vault
61 .search_notes(query)
62 .await
63 .unwrap_or_default()
64 .into_iter()
65 .map(|(entry, content)| self.to_entry(entry, content))
66 .collect()
67 }
68 }
69}