diff --git a/Cargo.toml b/Cargo.toml index 46ac351..154f694 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,4 +19,5 @@ native-dialog = "0.6" hex = "0.4" sha2 = "0.10" argon2 = "0.5" -fs_extra = "1.3" \ No newline at end of file +fs_extra = "1.3" +rfd = "0.11" \ No newline at end of file diff --git a/README.md b/README.md index 87328dc..d6322d9 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ This is a simple and experimental password-based note-taking app with built-in ## To-Do list - [x] Improve password checking - [x] Allow the addition of arbitrary metadata when creating a note +- [ ] Add basic settings (export and import notes, change data directory, etc) - [ ] Add basic markdown support (bold, italics, underline) - [ ] Improve performance (duplicate decryption operations, tons of copying/cloning, etc) diff --git a/src/main.rs b/src/main.rs index 110bd57..2418075 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,7 @@ enum CurrentMode { View, Compose, PasswordInput, + Settings, } struct App { @@ -159,6 +160,9 @@ impl eframe::App for App { if ui.button("want to add one note?").clicked() { self.mode = CurrentMode::Compose; } + if ui.button("settings").clicked() { + self.mode = CurrentMode::Settings; + } }); ui.separator(); @@ -316,6 +320,51 @@ impl eframe::App for App { } }); } + CurrentMode::Settings => { + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("settings"); + ui.horizontal(|ui| { + ui.label("manage encryption, export your notes, and other settings"); + ui.add_space(7.5); + if ui.button("return to view mode?").clicked() { + self.mode = CurrentMode::View; + } + }); + ui.separator(); + + if let Some(password) = &self.password { + ui.label(RichText::new("export notes").size(14.0)); + ui.label("decrypt your notes and export them in a portable JSON format."); + ui.label("note: this action may take a while to finish!"); + ui.add_space(5.0); + if ui.button("export decrypted notes").clicked() { + let current_date = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_millis() + .to_string(); + + let save_path = rfd::FileDialog::new() + .add_filter("JSON", &["json"]) + .set_title("where to save the decrypted notes") + .set_file_name(&format!("note_export_{}.json", current_date)) + .save_file(); + + if let Some(save_path) = save_path { + let notes: Vec = self.notes.clone() + .iter() + .map(|note| note.decrypt(password).expect("failed to decrypt note")) + .collect(); + + let json_notes = serde_json::to_string(¬es).unwrap(); + + fs::write(save_path, json_notes) + .expect("failed to save decrypted notes") + } + } + } + }); + } } } } \ No newline at end of file