From 8d9774e3642e119e3e9e479c7cefec0bc9e60da0 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Tue, 21 Jul 2026 21:29:55 +0200 Subject: [PATCH] implement save_note for file notes --- application/backend/src/backend.rs | 39 +++++++++++++++++++++++++++++- application/note/src/file.rs | 35 ++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/application/backend/src/backend.rs b/application/backend/src/backend.rs index 4b81ae6..2375dbf 100644 --- a/application/backend/src/backend.rs +++ b/application/backend/src/backend.rs @@ -30,7 +30,7 @@ use std::future::Future; use std::io::Error; use std::path::{Path, PathBuf}; use std::pin::Pin; -use sea_orm::{ActiveModelTrait, Database, DatabaseConnection, EntityTrait, QueryFilter, ColumnTrait, Set, QueryOrder, DbErr, ExprTrait}; +use sea_orm::{ActiveModelTrait, Database, DatabaseConnection, EntityTrait, QueryFilter, ColumnTrait, Set, QueryOrder, DbErr, ExprTrait, UpdateResult}; use tokio::runtime::Runtime; use std::sync::{Arc}; use std::thread::JoinHandle; @@ -660,6 +660,43 @@ impl BackendHandle { let _ = self.tx.send(cmd); } + pub fn rename_note(&self, note_id: i32, nodename: String, callback: F) + where F: FnOnce(Result) + Send + 'static { + let bhandle = self.clone(); + let cmd = Box::pin(async move { + let local_path_res = get_note_storage_path(&bhandle.backend.db, note_id).await; + let local_path = match local_path_res { + Ok(path) => path, + Err(e) => { + callback(Err(e)); + return; + } + }; + + let result = Note::update_many() + .col_expr(Column::Nodename, Expr::value(nodename.clone())) + .filter(Column::NoteId.eq(note_id)) + .exec(&bhandle.backend.db).await; + + if let Some(path_str) = local_path { + let path = Path::new(&path_str); + let parent = path.parent(); + if let Some(parent) = parent { + let new_path = parent.join(nodename); + let result = fs::rename(path, &new_path).await; + if let Err(e) = result { + callback(Err(DbErr::Custom(format!("rename failed: {}", e)))); + // TODO: rollback nodename update + return; + } + } // else: should not happen + } + + callback(result); + }); + let _ = self.tx.send(cmd); + } + pub fn get_file_metadata(&self, path: &Path, callback: F) where F: FnOnce(std::io::Result) + Send + 'static { let p = PathBuf::from(path); diff --git a/application/note/src/file.rs b/application/note/src/file.rs index d2c1df9..5f02f53 100644 --- a/application/note/src/file.rs +++ b/application/note/src/file.rs @@ -25,6 +25,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +use std::mem; use std::path::PathBuf; use std::rc::Rc; use backend::backend::{BackendHandle, NoteId, OpenExternResult}; @@ -126,10 +127,6 @@ impl FileNote { self.save_note(); } - pub fn save_note(&mut self) { - // TODO - } - #[action] pub fn notebook_view_changed(&mut self, event: &mut ActionEvent) { // TODO: duplicated code in note.rs @@ -152,6 +149,36 @@ impl FileNote { impl NoteViewModel for FileNote { fn save_note(&mut self) { + let Some(doc) = self.doc.get_doc() else { + return; // should not happen + }; + let NoteId::Id(note_id) = self.id else { + return; // should not happen + }; + + let mut nodename = self.note_nodename.get(); + if self.nodename == nodename { + // nothing has changed + return; + } + mem::swap(&mut self.nodename, &mut nodename); + + let proxy = doc.doc_proxy(); + self.backend.rename_note(note_id, self.nodename.clone(), |result|{ + proxy.call_mainthread(move |_doc, note|{ + match result { + Ok(updated) => { + if updated.rows_affected != 1 { + println!("rename_note: unexpected number of rows affected"); + } + }, + Err(e) => { + println!("note update failed: {:?}", e); + note.nodename = nodename; // restore previous nodename + } + } + }); + }); } } \ No newline at end of file -- 2.52.0