From: Olaf Wintermann Date: Thu, 30 Jul 2026 17:54:22 +0000 (+0200) Subject: implement menu item for deleting notes X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;ds=sidebyside;p=note.git implement menu item for deleting notes --- diff --git a/application/backend/src/backend.rs b/application/backend/src/backend.rs index edde6d5..5faf642 100644 --- a/application/backend/src/backend.rs +++ b/application/backend/src/backend.rs @@ -89,6 +89,7 @@ pub enum BroadcastMessage { NotebookStructureUpdate(Vec), NoteTitleUpdate(NoteTitleUpdate), NoteUpdate(NoteUpdate), + NoteMoved(NoteMoved), Notify(Event) } @@ -124,6 +125,13 @@ pub struct NoteUpdate { pub model: note::Model } +#[derive(Clone)] +pub struct NoteMoved { + pub note_id: i32, + pub from_collection_id: i32, + pub to_collection_id: i32, +} + impl Backend { pub fn new(db_file: String, profile: Option, host: &str, user: &str) -> Result { @@ -765,7 +773,7 @@ impl BackendHandle { let _ = self.tx.send(cmd); } - pub fn move_note_to_trash(&self, note_id: i32, callback: F) + pub fn move_note_to_trash(&self, from_collection_id: i32, note_id: i32, callback: F) where F: FnOnce(Result<(), DbErr>) + Send + 'static { let backend = self.backend.clone(); let cmd = Box::pin(async move { @@ -800,7 +808,14 @@ impl BackendHandle { return Err(DbErr::Custom(format!("rename failed: {}", e))); } } - + + let event = NoteMoved { + note_id, + from_collection_id, + to_collection_id: trash_id + }; + backend.send_broadcast(BroadcastMessage::NoteMoved(event)); + Ok(()) } else { Err(DbErr::Custom("unexpected number of affected rows".into())) @@ -815,6 +830,7 @@ impl BackendHandle { async fn get_trash_id(db: &DatabaseConnection, profile_id: i32) -> Result, DbErr> { Collection::find() .filter(collection::Column::ProfileId.eq(profile_id)) + .filter(collection::Column::Kind.eq(CollectionType::Trash)) .select_only() .column(collection::Column::CollectionId) .into_tuple::() diff --git a/application/note/src/main.rs b/application/note/src/main.rs index 7c6d926..7d695b4 100644 --- a/application/note/src/main.rs +++ b/application/note/src/main.rs @@ -143,6 +143,8 @@ fn create_menubar(app: &AppContext) { app.menu("File", |menu| { menu.item("New").action("new_note").create(); menu.item("New Window").onclick(|_| new_app_window() ).create(); + menu.separator(); + menu.item("Delete").action("note_delete").create(); }); } @@ -167,6 +169,8 @@ fn create_toolbar(app: &AppContext) { app.toolbar_appmenu(|menu|{ menu.item("New Window").onclick(|_| new_app_window() ).create(); + menu.separator(); + menu.item("Delete").action("delete_note").create(); }); } diff --git a/application/note/src/notebook.rs b/application/note/src/notebook.rs index b9b969a..9590fb9 100644 --- a/application/note/src/notebook.rs +++ b/application/note/src/notebook.rs @@ -81,9 +81,50 @@ impl Notebook { pub fn into_doc(self) -> UiDoc { UiDoc::new2(self, |notebook, doc| { notebook.doc_ref = doc.doc_ref(); - doc.ctx.on_attach_action("notebook_on_attach") + doc.ctx.on_attach_action("notebook_on_attach"); + + // get notebook fs path + let proxy = doc.doc_proxy(); + notebook.backend.get_notebook_local_path(notebook.collection_id, |result|{ + proxy.call_mainthread(|_n, nb| { + match result { + Ok(pathstr) => { + if let Some(pathstr) = pathstr { + let path = Path::new(&pathstr); + nb.fswatch.watch(&path); + } + }, + Err(err) => { + eprintln!("get_notebook_local_path failed: {}", err); + } + } + }); + }); + + // load list of notes + notebook.load_notes(); }) } + + pub fn load_notes(&mut self) { + let Some(doc) = self.doc_ref.get_doc() else { + return; + }; + + let proxy = doc.doc_proxy(); + self.backend.get_notes(self.collection_id, |result|{ + proxy.call_mainthread(|_, nb| { + match result { + Ok(notes) => { + nb.set_notes(notes); + }, + Err(err) => { + eprintln!("get_notes failed: {}", err); + } + } + }); + }); + } #[action] pub fn notebook_on_attach(&mut self, event: &mut ActionEvent) { @@ -345,6 +386,11 @@ impl Notebook { self.update_note(update); } }, + BroadcastMessage::NoteMoved(update) => { + if self.collection_id == update.from_collection_id || self.collection_id == update.to_collection_id { + self.load_notes(); + } + }, BroadcastMessage::Notify(event) => { if let Some(note) = &self.selected_note { let arg: Box = Box::new(event); @@ -357,6 +403,37 @@ impl Notebook { } } } + + #[action] + pub fn delete_note(&mut self, _event: &ActionEvent) { + let Some(mut doc) = self.doc_ref.get_doc() else { + return; + }; + let Some(note) = &self.selected_note.take() else { + return; + }; + + doc.ctx.detach(¬e.doc); + + match note.id { + NoteId::Id(id) => { + let proxy = doc.doc_proxy(); + self.backend.move_note_to_trash(self.collection_id, id, |result| { + proxy.call_mainthread(|_doc, nb| { + // in case the deletion was successful, a NoteMoved event is sent to + // all notebooks + if let Err(e) = result { + eprintln!("cannot move note to trash: {}", e); + } + }); + }); + }, + NoteId::TmpId(_tmp) => { + self.notes.data_mut().retain(|item| item.id != note.id); + self.notes.update(); + } + } + } } pub fn notelist_getvalue<'a>(elm: &NoteItem, col: i32, _row: i32) -> ListValue<'a> { @@ -396,38 +473,6 @@ impl NotebookItem { // Create Notebook UI model let notebook = Notebook::new(self.data.collection_id, backend); let doc = notebook.into_doc(); - - // Load notes - let proxy = doc.doc_proxy(); - backend.get_notes(self.data.collection_id, |result|{ - proxy.call_mainthread(|_, nb| { - match result { - Ok(notes) => { - nb.set_notes(notes); - }, - Err(err) => { - eprintln!("get_notes failed: {}", err); - } - } - }); - }); - - let proxy = doc.doc_proxy(); - backend.get_notebook_local_path(self.data.collection_id, |result|{ - proxy.call_mainthread(|_n, nb| { - match result { - Ok(pathstr) => { - if let Some(pathstr) = pathstr { - let path = Path::new(&pathstr); - nb.fswatch.watch(&path); - } - }, - Err(err) => { - eprintln!("get_notebook_local_path failed: {}", err); - } - } - }); - }); self.model = Some(doc.clone());