* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-
+use std::fs::Metadata;
use std::future::Future;
use std::io::Error;
use std::path::{Path, PathBuf};
use migration::prelude::Utc;
use crate::lockmanager::LockManager;
use crate::note::{create_nodename, randomize_nodename};
-use crate::storage::{get_collection_storage_path, get_file_content, get_last_modified, get_note_storage_path, write_file, write_tmp_file};
+use crate::storage::{*};
pub struct Backend {
rt: Arc<Runtime>,
let fs_result = write_file(path.as_path(), note_content.as_ref()).await;
match fs_result {
Ok(_) => {
- result = SaveNoteResult::Ok((note.clone(), 0));
+ let lastmodified = get_last_modified(path.as_path()).await;
+ let ret = SaveNoteRet {
+ model: note.clone(),
+ content_id: 0,
+ local_path: Some(path),
+ local_lastmodified: lastmodified
+ };
+ result = SaveNoteResult::Ok(ret);
},
Err(e) => {
result = SaveNoteResult::FileError(e);
match result2 {
Ok(ctn) => {
- result = SaveNoteResult::Ok((note.clone(), ctn.id));
+ let ret = SaveNoteRet {
+ model: note.clone(),
+ content_id: ctn.id,
+ local_path: None,
+ local_lastmodified: None
+ };
+ result = SaveNoteResult::Ok(ret);
}
Err(e) => {
result = SaveNoteResult::Error(e);
}
}
} else {
- result = SaveNoteResult::Ok((note.clone(), 0));
+ let ret = SaveNoteRet {
+ model: note.clone(),
+ content_id: 0,
+ local_path: None,
+ local_lastmodified: None
+ };
+ result = SaveNoteResult::Ok(ret);
}
if result.is_ok() {
let _ = self.tx.send(cmd);
}
+ pub fn get_file_metadata<F>(&self, path: &Path, callback: F)
+ where F: FnOnce(std::io::Result<Metadata>) + Send + 'static {
+ let p = PathBuf::from(path);
+ let cmd = Box::pin(async move {
+ let result = tokio::fs::metadata(p.as_path()).await;
+ callback(result);
+ });
+ let _ = self.tx.send(cmd);
+ }
+
pub fn open_extern<F>(&self, note_id: i32, callback: F)
where F: FnOnce(OpenExternResult) + Send + 'static {
let backend = self.backend.clone();
pub enum SaveNoteResult {
- Ok((entity::note::Model, i32)),
+ Ok(SaveNoteRet),
VersionConflict,
FileAlreadyExists(PathBuf),
Error(DbErr),
ValidationError(&'static str)
}
+pub struct SaveNoteRet {
+ pub model: entity::note::Model,
+ pub content_id: i32,
+ pub local_path: Option<PathBuf>,
+ pub local_lastmodified: Option<SystemTime>
+}
+
pub enum OpenExternResult {
Ok((PathBuf, bool)), // path, istmp
DbErr(DbErr),
/// Handles any attachment status change, which includes if this note is
/// directly attached or detached, but also if any parent attachment status changes
#[action]
- pub fn attachment_status_changed(&mut self, _event: &mut ActionEvent) -> Option<()>{
+ pub fn attachment_status_changed(&mut self, _event: &mut ActionEvent) -> Option<()> {
let doc = self.doc.get_doc()?;
if doc.ctx.is_attached_to_obj() {
doc.ctx.unset_state(AppStates::NoteShowInfo as i32);
}
}
+
+ self.check_lastmodified();
} else {
self.lock = None;
self.text.set_readonly(false);
Some(())
}
+ fn check_lastmodified(&mut self) {
+ let Some(doc) = self.doc.get_doc() else {
+ return;
+ };
+
+ if let Some(path) = &self.local_path && let Some(lastmodified) = self.local_lastmodified {
+ let proxy = doc.doc_proxy();
+ self.backend.get_file_metadata(path.as_path(), |result| {
+ proxy.call_mainthread(|doc, note| {
+ match result {
+ Ok(metadata) => {
+ if let Ok(lm) = metadata.modified() && let Some(lastmodified) = note.local_lastmodified {
+ if lastmodified != lm {
+ println!("note was changed");
+ }
+ } else {
+ println!("no last_modified available");
+ }
+ },
+ Err(e) => {
+ println!("cannot get metadata: {}", e);
+ }
+ }
+ });
+ });
+ }
+ }
+
pub fn init_from_model(&mut self, model: &entity::note::Model) {
self.id = NoteId::Id(model.note_id);
self.nodename = Some(model.nodename.clone());
self.backend.save_note(self.notebook_instance_id, self.id.clone(), note, Some(notecontent), |result|{
proxy.call_mainthread(move |doc, note|{
match result {
- SaveNoteResult::Ok((notemodel, content_id)) => {
- note.id = NoteId::Id(notemodel.note_id);
- note.content_id = content_id;
- note.version = notemodel.version;
- println!("Note saved: note_id: {}, content_id: {}, version: {}", notemodel.note_id, content_id, note.version);
+ SaveNoteResult::Ok(ret) => {
+ note.id = NoteId::Id(ret.model.note_id);
+ note.content_id = ret.content_id;
+ note.version = ret.model.version;
+ note.local_path = ret.local_path;
+ note.local_lastmodified = ret.local_lastmodified;
+ println!("Note saved: note_id: {}, content_id: {}, version: {}", ret.model.note_id, ret.content_id, note.version);
// make sure the "new note" button is always enabled within this note
doc.ctx.unsuppress_state(AppStates::NoteEnableNew as i32);