});
let _ = self.tx.send(cmd);
}
+
+ pub fn save_note<F>(&self, note: entity::note::ActiveModel, callback: F)
+ where F: FnOnce(Result<note::ActiveModel, DbErr>) + Send + 'static {
+ let backend = self.backend.clone();
+ let cmd = Box::pin(async move {
+ let result = note.save(&backend.db).await;
+ callback(result);
+ });
+ let _ = self.tx.send(cmd);
+ }
}
+use sea_orm::prelude::DateTimeWithTimeZone;
+use sea_orm::sea_query::prelude::Utc;
+use sea_orm::{NotSet, Set};
use entity::note::NoteType;
use ui_rs::{ui_actions, UiModel};
use ui_rs::ui::*;
+use crate::backend::BackendHandle;
use crate::window::NoteTypeTabView;
#[derive(UiModel, Default)]
pub struct Note {
pub note_id: i32,
+ pub kind: NoteType,
+ pub created: DateTimeWithTimeZone,
+
#[bind("note_type")]
pub note_type: UiInteger,
};
self.note_type.set(tab as i64);
}
+
+ pub fn save(&self, collection_id: i32, backend: &BackendHandle) {
+ let content = self.text.get();
+ let title = match generate_title(content.as_str()) {
+ Some(title) => title.to_string(),
+ None => "Note".to_string()
+ };
+
+ let note = entity::note::ActiveModel {
+ note_id: if self.note_id == 0 { NotSet } else { Set(self.note_id) },
+ collection_id: Set(collection_id),
+ kind: Set(self.kind.clone()),
+ title: Set(title),
+ content: Set(content),
+ lastmodified: Set(Utc::now().into()),
+ created: if self.note_id == 0 { Set(Utc::now().into()) } else { NotSet }
+ };
+
+ backend.save_note(note, |result|{
+ match result {
+ Ok(model) => {
+ println!("Note saved");
+ },
+ Err(error) => {
+ println!("Failed to save note: {}", error);
+ }
+ }
+ });
+ }
+}
+
+fn generate_title(s: &str) -> Option<&str> {
+ for line in s.lines() {
+ if !line.trim().is_empty() {
+ return Some(line);
+ }
+ }
+ None
}
\ No newline at end of file
use ui_rs::ui::*;
use entity::note::{Model as Note};
+use crate::backend::BackendHandle;
-#[derive(UiModel, Default)]
+#[derive(UiModel)]
pub struct Notebook {
pub doc_ref: UiDocRef<Notebook>,
+ pub backend: BackendHandle,
pub collection_id: i32,
pub selected_note: Option<UiDoc<crate::note::Note>>,
#[ui_actions]
impl Notebook {
- pub fn new(id: i32) -> Self {
+ pub fn new(id: i32, backend: &BackendHandle) -> Self {
Notebook {
- collection_id: id, ..Default::default()
+ doc_ref: Default::default(),
+ backend: backend.clone(),
+ collection_id: id,
+ selected_note: None,
+ notes: Default::default()
}
}
if let Some(note) = s.selected_element(self.notes.data()) {
// detach the current note
if let Some(current) = &self.selected_note {
- self.doc_ref.get_doc().unwrap().ctx.detach(current);
- self.selected_note = None;
+ // doc_ref.get_doc() should never fail here
+ if let Some(mut doc) = self.doc_ref.get_doc() {
+ // save the note
+ let note_proxy = current.doc_proxy();
+ let backend = self.backend.clone();
+ let collection_id = self.collection_id;
+ note_proxy.call_mainthread(move |doc, note|{
+ note.save(collection_id, &backend);
+ });
+
+ // detach the note
+ doc.ctx.detach(current);
+ self.selected_note = None;
+ }
}
// Create the new note
e.obj.ctx.detach(current);
}
- let notebook = Notebook::new(nb.collection_id);
+ let notebook = Notebook::new(nb.collection_id, &e.data.backend);
let doc = UiDoc::new2(notebook, |notebook, doc| {
notebook.doc_ref = doc.doc_ref();
});
pub created: DateTimeWithTimeZone,
}
-#[derive(EnumIter, DeriveActiveEnum, Clone, Debug, PartialEq)]
+#[derive(EnumIter, DeriveActiveEnum, Clone, Debug, PartialEq, Default)]
#[sea_orm(rs_type = "i32", db_type = "Integer")]
pub enum NoteType {
+ #[default]
PlainTextNote = 0,
MDTextNote = 1,
}