158 lines
4.4 KiB
Rust
158 lines
4.4 KiB
Rust
use std::path::Path;
|
|
|
|
use egui::TextEdit;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::{
|
|
editors::tags::Tag,
|
|
filesystem::{FILESYSTEM, LegacyFileSystem},
|
|
util,
|
|
};
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
pub struct Note {
|
|
pub id: String,
|
|
pub name: String,
|
|
|
|
#[serde(default)]
|
|
pub content: String,
|
|
#[serde(default)]
|
|
pub subject: String,
|
|
|
|
#[serde(default)]
|
|
pub tags: Vec<String>,
|
|
|
|
#[serde(skip)]
|
|
#[serde(default = "default_saved")]
|
|
pub saved: bool,
|
|
}
|
|
|
|
pub fn default_saved() -> bool {
|
|
true
|
|
}
|
|
|
|
impl Default for Note {
|
|
fn default() -> Self {
|
|
Self {
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
name: "New Note".to_string(),
|
|
subject: "".to_string(),
|
|
content: "".to_string(),
|
|
tags: Vec::new(),
|
|
saved: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Note {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
id: uuid::Uuid::new_v4().to_string(),
|
|
name: "New Note".to_string(),
|
|
subject: "".to_string(),
|
|
content: "".to_string(),
|
|
tags: Vec::new(),
|
|
saved: false,
|
|
}
|
|
}
|
|
|
|
pub fn save(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
|
let id = &self.id;
|
|
FILESYSTEM.write(Path::new(&format!("notes/{id}.json")), self.clone())?;
|
|
self.saved = true;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn load(id: &str) -> Result<Self, Box<dyn std::error::Error>> {
|
|
let mut note: Self = FILESYSTEM.read(Path::new(&format!("notes/{id}.json")))?;
|
|
note.id = id.to_string();
|
|
note.saved = true;
|
|
Ok(note)
|
|
}
|
|
|
|
pub fn ui(&mut self, ui: &mut egui::Ui) {
|
|
if ui.input(|i| i.key_pressed(egui::Key::S) && i.modifiers.ctrl) {
|
|
if let Err(e) = self.save() {
|
|
eprintln!("Failed to save: {e}");
|
|
}
|
|
}
|
|
|
|
util::saved_status(ui, self.saved, &self.id, &self.name);
|
|
|
|
if ui.button("Save").clicked() {
|
|
if let Err(e) = self.save() {
|
|
eprintln!("Failed to save: {e}");
|
|
}
|
|
}
|
|
|
|
let id = ui.make_persistent_id("note_name");
|
|
egui::collapsing_header::CollapsingState::load_with_default_open(ui.ctx(), id, true)
|
|
.show_header(ui, |ui| {
|
|
ui.strong("Name");
|
|
})
|
|
.body(|ui| {
|
|
ui.separator();
|
|
if TextEdit::singleline(&mut self.name)
|
|
.desired_width(f32::INFINITY)
|
|
.frame(false)
|
|
.show(ui)
|
|
.response
|
|
.changed()
|
|
{
|
|
self.saved = false;
|
|
}
|
|
ui.separator();
|
|
});
|
|
|
|
let id = ui.make_persistent_id("note_tags");
|
|
egui::collapsing_header::CollapsingState::load_with_default_open(ui.ctx(), id, true)
|
|
.show_header(ui, |ui| {
|
|
ui.strong("Tags");
|
|
})
|
|
.body(|ui| {
|
|
ui.separator();
|
|
Tag::selector_ui(&mut self.tags, ui, Some(&mut self.saved));
|
|
ui.separator();
|
|
});
|
|
|
|
let id = ui.make_persistent_id("note_subject");
|
|
egui::collapsing_header::CollapsingState::load_with_default_open(ui.ctx(), id, true)
|
|
.show_header(ui, |ui| {
|
|
ui.strong("Subject");
|
|
})
|
|
.body(|ui| {
|
|
ui.separator();
|
|
if TextEdit::singleline(&mut self.subject)
|
|
.desired_width(f32::INFINITY)
|
|
.frame(false)
|
|
.show(ui)
|
|
.response
|
|
.changed()
|
|
{
|
|
self.saved = false;
|
|
}
|
|
ui.separator();
|
|
});
|
|
|
|
let id = ui.make_persistent_id("note_content");
|
|
egui::collapsing_header::CollapsingState::load_with_default_open(ui.ctx(), id, true)
|
|
.show_header(ui, |ui| {
|
|
ui.strong("Content");
|
|
})
|
|
.body(|ui| {
|
|
ui.separator();
|
|
if TextEdit::multiline(&mut self.content)
|
|
.desired_width(f32::INFINITY)
|
|
.desired_rows(5)
|
|
.frame(false)
|
|
.show(ui)
|
|
.response
|
|
.changed()
|
|
{
|
|
self.saved = false;
|
|
}
|
|
ui.separator();
|
|
});
|
|
}
|
|
}
|