diff --git a/src/Application.vala b/src/Application.vala index a54bbbbc..78e0f8b0 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -50,6 +50,7 @@ public class Jorts.Application : Gtk.Application { public static bool new_from_clipboard = false; public static bool show_pref = false; public static bool reset_settings = false; + public static bool dump_storage = false; public const string ACTION_PREFIX = "app."; public const string ACTION_QUIT = "action_quit"; @@ -164,16 +165,17 @@ Please wait while the app remembers all the things... /* Either we show all sticky notes, or we load everything lol */ if (manager.open_notes.size > 0) { foreach (var window in manager.open_notes) { - if (window.visible) { window.present ();} + if (window.visible) {window.present ();} } } else { - manager.init_all_notes (); + manager.init (); } if (new_note) {manager.create_note (); new_note = false;} if (new_from_clipboard) {manager.from_clipboard (); new_from_clipboard = false;} if (show_pref) {action_show_preferences (); show_pref = false;} if (reset_settings) {action_reset_settings (); reset_settings = false;} + if (dump_storage) {manager.dump (); dump_storage = false;} } public static int main (string[] args) { @@ -205,7 +207,7 @@ Please wait while the app remembers all the things... private void action_save () { debug ("[ACTION] Saving..."); - manager.save_to_stash (); + manager.save_all.begin (); } private void action_reset_settings () { @@ -233,7 +235,8 @@ Please wait while the app remembers all the things... {"new-note", 'n', OptionFlags.NONE, OptionArg.NONE, ref new_note, "Create a new note", null}, {"new-from-clipboard", 'c', OptionFlags.NONE, OptionArg.NONE, ref new_from_clipboard, "Create a note then paste from clipboard", null}, {"preferences", 'p', OptionFlags.NONE, OptionArg.NONE, ref show_pref, "Show preferences", null}, - {"reset-settings", 'r', OptionFlags.NONE, OptionArg.NONE, ref reset_settings, "Reset all settings", null} + {"reset-settings", 'r', OptionFlags.NONE, OptionArg.NONE, ref reset_settings, "Reset all settings", null}, + {"dump", 'd', OptionFlags.NONE, OptionArg.NONE, ref dump_storage, "Dump the content of the storage as a pretty JSON", null} }; // We have to make an extra copy of the array, since .parse assumes diff --git a/src/Objects/NoteData.vala b/src/Objects/NoteData.vala index ccd17eb4..a0166d38 100644 --- a/src/Objects/NoteData.vala +++ b/src/Objects/NoteData.vala @@ -6,18 +6,17 @@ */ - /* Creation methods: -vanilla -from_json (); -from_random (); - -Helper: -to_json (); - - - */ +/*************************************************/ +/** +* An object used to package all data conveniently as needed. +*/ public class Jorts.NoteData : Object { + // Will determine properties (or lack thereof) for any new note + public static string? latest_theme = Jorts.Constants.DEFAULT_THEME; + public static int? latest_zoom = Jorts.Constants.DEFAULT_ZOOM; + public static bool latest_mono = Jorts.Constants.DEFAULT_MONO; + public string title; public string theme; public string content; @@ -26,6 +25,10 @@ public class Jorts.NoteData : Object { public int width; public int height; + /*************************************************/ + /** + * Convert into a Json.Object() + */ public NoteData (string? title = null, string? theme = null, string? content = null, bool? monospace = null, int? zoom = null, int? width = null, int? height = null) { @@ -39,6 +42,10 @@ public class Jorts.NoteData : Object { this.height = height ?? Jorts.Constants.DEFAULT_HEIGHT; } + /*************************************************/ + /** + * Parse a node to create an associated NoteData object + */ public NoteData.from_json (Json.Object node) { title = node.get_string_member_with_default ("title",(_("Forgot title!"))); theme = node.get_string_member_with_default ("theme",Jorts.Utils.random_theme (null)); @@ -48,12 +55,31 @@ public class Jorts.NoteData : Object { // Make sure the values are nothing crazy if (zoom < Jorts.Constants.ZOOM_MIN) { zoom = Jorts.Constants.ZOOM_MIN;} - else if (zoom > Jorts.Constants.ZOOM_MAX) { zoom = Jorts.Constants.ZOOM_MAX;} + else if (zoom > Jorts.Constants.ZOOM_MAX) { zoom = Jorts.Constants.ZOOM_MAX;} width = (int)node.get_int_member_with_default ("width",Jorts.Constants.DEFAULT_WIDTH); height = (int)node.get_int_member_with_default ("height",Jorts.Constants.DEFAULT_HEIGHT); } + /*************************************************/ + /** + * Parse a node to create an associated NoteData object + * We skip last chosen theme, and reuse latest set zoom and whether user prefers monospace + */ + public NoteData.from_random () { + title = title ?? Jorts.Utils.random_title (); + theme = theme ?? Jorts.Utils.random_theme (latest_theme); + content = content ?? ""; + monospace = latest_mono; + zoom = latest_zoom; + width = Jorts.Constants.DEFAULT_WIDTH; + height = Jorts.Constants.DEFAULT_HEIGHT; + } + + /*************************************************/ + /** + * Used for storing NoteData inside disk storage + */ public Json.Object to_json () { var builder = new Json.Builder (); diff --git a/src/Objects/Themes.vala b/src/Objects/Themes.vala index dc0bdc30..5e5b9c01 100644 --- a/src/Objects/Themes.vala +++ b/src/Objects/Themes.vala @@ -5,6 +5,10 @@ * 2025 Contributions from the ellie_Commons community (github.com/ellie-commons/) */ +/*************************************************/ +/** +* A register of all themes we have +*/ public enum Jorts.Themes { BLUEBERRY, MINT, @@ -33,6 +37,22 @@ public enum Jorts.Themes { } } + public Themes from_string (string wtf_is_this) { + switch (wtf_is_this.ascii_up ()) { + case "BLUEBERRY": return BLUEBERRY; + case "MINT": return MINT; + case "LIME": return LIME; + case "BANANA": return BANANA; + case "ORANGE": return ORANGE; + case "STRAWBERRY": return STRAWBERRY; + case "BUBBLEGUM": return BUBBLEGUM; + case "GRAPE": return GRAPE; + case "COCOA": return COCOA; + case "SLATE": return SLATE; + default: assert_not_reached (); + } + } + public static Themes[] all () { return {BLUEBERRY, MINT, LIME, BANANA, ORANGE, STRAWBERRY, BUBBLEGUM, GRAPE, COCOA, SLATE}; } diff --git a/src/Services/Constants.vala b/src/Services/Constants.vala index 03469e71..b47c1a07 100644 --- a/src/Services/Constants.vala +++ b/src/Services/Constants.vala @@ -20,8 +20,8 @@ namespace Jorts.Constants { // signature theme const string DEFAULT_THEME = "BLUEBERRY"; const int DAYS_BETWEEN_BACKUPS = 30; - const string FILENAME_STASH = "saved_state.json"; - const string FILENAME_BACKUP = "backup_state.json"; + + // in ms const int DEBOUNCE = 1000; diff --git a/src/Services/Jason.vala b/src/Services/Jason.vala deleted file mode 100644 index 1aa00cc3..00000000 --- a/src/Services/Jason.vala +++ /dev/null @@ -1,109 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-3.0-or-later - * SPDX-FileCopyrightText: 2017-2024 Lains - * 2025 Stella & Charlie (teamcons.carrd.co) - * 2025 Contributions from the ellie_Commons community (github.com/ellie-commons/) - */ - -/* - -load_node ---> Json.Object representing a NoteData, that we convert into one -TODO: move this shit into Objects - -jsonify ---> Convert an array of windows into a long json string -Used by the main application to get everything in a convenient form for storage - -load_parser ---> takes the loaded content from storage, spits an array with sticky notes data -used by the stash upon loading a storage file, passed on to Application to start new windows -*/ - -namespace Jorts.Jason { - - /*************************************************/ - // Takes a single node, tries its best to get its content. - // Does not fail if something is missing or unreadable, go to fallback for the element instead - public Jorts.NoteData load_node (Json.Object node) { - - string title = node.get_string_member_with_default ("title",(_("Forgot title!"))); - string theme = node.get_string_member_with_default ("theme",Jorts.Utils.random_theme (null)); - string content = node.get_string_member_with_default ("content",""); - bool monospace = node.get_boolean_member_with_default ("monospace",Jorts.Constants.DEFAULT_MONO); - - // TODO: If this one fails, whole note fails... - int64 zoom = node.get_int_member_with_default ("zoom",Jorts.Constants.DEFAULT_ZOOM); - - if (zoom < Jorts.Constants.ZOOM_MIN) { - zoom = Jorts.Constants.ZOOM_MIN; - } else if (zoom > Jorts.Constants.ZOOM_MAX) { - zoom = Jorts.Constants.ZOOM_MAX; - } - - int64 width = node.get_int_member_with_default ("width",Jorts.Constants.DEFAULT_WIDTH); - int64 height = node.get_int_member_with_default ("height",Jorts.Constants.DEFAULT_HEIGHT); - - Jorts.NoteData loaded_note = new Jorts.NoteData ( - title, - theme, - content, - monospace, - (int)zoom, - (int)width, - (int)height); - - return loaded_note; - } - - /*************************************************/ - // Loop through the list of windows and convert it into a giant json string - public string jsonify (Gee.ArrayList notes) { - Json.Builder builder = new Json.Builder (); - builder.begin_array (); - foreach (Jorts.StickyNoteWindow note in notes) { - Jorts.NoteData data = note.packaged (); - //print("saving " + note.title_name + "\n"); - - // Lets fkin gooo - builder.begin_object (); - builder.set_member_name ("title"); - builder.add_string_value (data.title); - builder.set_member_name ("theme"); - builder.add_string_value (data.theme); - builder.set_member_name ("content"); - builder.add_string_value (data.content); - builder.set_member_name ("monospace"); - builder.add_boolean_value (data.monospace); - builder.set_member_name ("zoom"); - builder.add_int_value (data.zoom); - builder.set_member_name ("height"); - builder.add_int_value (data.height); - builder.set_member_name ("width"); - builder.add_int_value (data.width); - builder.end_object (); - }; - builder.end_array (); - - Json.Generator generator = new Json.Generator (); - Json.Node root = builder.get_root (); - generator.set_root (root); - string str = generator.to_data (null); - return str; - } - - /*************************************************/ - public Gee.ArrayList load_parser (Json.Parser parser) { - Gee.ArrayList loaded_data = new Gee.ArrayList(); - - var root = parser.get_root (); - var array = root.get_array (); - - foreach (var item in array.get_elements()) { - var stored_note = Jorts.Jason.load_node(item.get_object()); - loaded_data.add (stored_note); - } - - return loaded_data; - } -} diff --git a/src/Services/NoteManager.vala b/src/Services/NoteManager.vala index d380da7f..308c9cd4 100644 --- a/src/Services/NoteManager.vala +++ b/src/Services/NoteManager.vala @@ -5,75 +5,88 @@ * 2025 Contributions from the ellie_Commons community (github.com/ellie-commons/) */ -// The NoteData object is just packaging to pass off data from and to storage +/** +* Responsible for keeping track of various Sticky Notes windows +* It does its thing on its own. Make sure to call init() to summon all notes from storage +*/ public class Jorts.NoteManager : Object { - public Gee.ArrayList open_notes = new Gee.ArrayList (); - public Gtk.Application application; - - public static int latest_zoom; - public static bool latest_mono; - public static string latest_theme; + private Jorts.Application application; + public Gee.ArrayList open_notes; + public Jorts.Storage storage; public NoteManager (Jorts.Application app) { this.application = app; } - public void init_all_notes () { - debug ("[MANAGER] Opening all sticky notes now!"); - Gee.ArrayList loaded_data = Jorts.Stash.load_from_stash(); + construct { + open_notes = new Gee.ArrayList (); + storage = new Jorts.Storage (); + } - // Load everything we have - foreach (NoteData data in loaded_data) { - debug ("[MANAGER] Loaded: " + data.title + "\n"); - this.create_note (data); - } + /*************************************************/ + /** + * Retrieve data from storage, and loop through it to create notes + * Keep an active list of Windows. + * We do not do this at construct time so we stay flexible whenever we want to init + * NoteManager is also created too early by the app for new windows + */ + public void init () { + debug ("[MANAGER] Opening all sticky notes now!"); + Json.Array loaded_data = storage.load (); - if (Jorts.Stash.need_backup (Application.gsettings.get_string ("last-backup"))) { - print ("[MANAGER] Doing a backup! :)"); + if (loaded_data.get_length () == 0) { + var note_data = new NoteData.from_random (); + note_data.theme = "BLUEBERRY"; + create_note (note_data); - Jorts.Stash.check_if_stash (); - string json_data = Jorts.Jason.jsonify (open_notes); - Jorts.Stash.overwrite_stash (json_data, Jorts.Constants.FILENAME_BACKUP); + } else { + foreach (var json_data in loaded_data.get_elements()) { + var json_obj = json_data.dup_object (); + var note_data = new NoteData.from_json (json_obj); - var now = new DateTime.now_utc ().to_string () ; - Application.gsettings.set_string ("last-backup", now); + print ("\nLoaded: " + note_data.title); + create_note (note_data); + } } on_reduceanimation_changed (); Gtk.Settings.get_default ().notify["enable-animations"].connect (on_reduceanimation_changed); } - // Create new instances of StickyNoteWindow - // If we have data, nice, just load it into a new instance - // Else we do a lil new note - public void create_note (NoteData? data = null) { + /*************************************************/ + /** + * Create new instances of StickyNoteWindow + * Should we have data, we can pass it off, else create from random data + * If we have data, nice, just load it into a new instance. Else we do a lil new note + */ + public void create_note (NoteData? data = null) { debug ("[MANAGER] Lets do a note"); + Jorts.StickyNoteWindow note; - StickyNoteWindow note; if (data != null) { note = new StickyNoteWindow (application, data); } else { - - // Skip theme from previous window, but use same text zoom - StickyNoteWindow last_note = open_notes.last (); - string skip_theme = last_note.theme; - var random_data = Jorts.Utils.random_note (skip_theme); - + var random_data = new NoteData.from_random (); + + // One chance at the golden sticky random_data = Jorts.Utils.golden_sticky (random_data); - - random_data.zoom = latest_zoom; note = new StickyNoteWindow (application, random_data); } /* LETSGO */ open_notes.add (note); + note.show (); note.present (); - save_to_stash (); + note.changed.connect (save_all); + } - // When user asked for a new note and for it to be pasted in + /*************************************************/ + /** + * When user asked for a new note and for it to be pasted in + */ public void from_clipboard () { debug ("[MANAGER] Creating and loading from clipboard…"); print ("clipboard!"); @@ -87,43 +100,51 @@ public class Jorts.NoteManager : Object { } else { // Skip theme from previous window, but use same text zoom - StickyNoteWindow last_note = open_notes.last (); - string skip_theme = last_note.theme; - var random_data = Jorts.Utils.random_note (skip_theme); - random_data.zoom = latest_zoom; + var random_data = new NoteData.from_random (); note = new StickyNoteWindow (application, random_data); open_notes.add (note); - print ("new"); + print ("new"); } - - note.show (); note.present (); note.textview.paste (); - - save_to_stash (); } - - // Simply remove from the list of things to save, and close + /*************************************************/ + /** + * Delete a note by remove it from the active list and closing its window + */ public void delete_note (StickyNoteWindow note) { - debug ("[MANAGER] Removing a note…"); - open_notes.remove (note); - note.close (); - this.save_to_stash (); + debug ("[MANAGER] Removing a note…"); + + open_notes.remove (note); + note.close (); + save_all.begin (); } - public void save_to_stash () { + /*************************************************/ + /** + * Cue to immediately write from the active list to the storage + */ + public async void save_all () { debug ("[MANAGER] Save the stickies!"); - Jorts.Stash.check_if_stash (); - string json_data = Jorts.Jason.jsonify (open_notes); - Jorts.Stash.overwrite_stash (json_data, Jorts.Constants.FILENAME_STASH); - //print ("\nSaved " + open_notes.size.to_string () + "!"); + var array = new Json.Array (); + + foreach (Jorts.StickyNoteWindow note in open_notes) { + var data = note.packaged (); + var object = data.to_json (); + array.add_object_element (object); + }; + + storage.save (array); } - // Called when the window is-active property changes + /*************************************************/ + /** + * Handler to add or remove CSS animations from all active notes + */ public void on_reduceanimation_changed () { debug ("[MANAGER] Reduce animation changed!"); @@ -141,4 +162,8 @@ public class Jorts.NoteManager : Object { } } } + + + /*************************************************/ + public void dump () {storage.dump ();} } diff --git a/src/Services/Stash.vala b/src/Services/Stash.vala deleted file mode 100644 index 1b276104..00000000 --- a/src/Services/Stash.vala +++ /dev/null @@ -1,152 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-3.0-or-later - * SPDX-FileCopyrightText: 2017-2024 Lains - * 2025 Stella & Charlie (teamcons.carrd.co) - * 2025 Contributions from the ellie_Commons community (github.com/ellie-commons/) - */ - -/* -check_if_stash() ---> Check if we have a data directory. If not create one. - -jsonify(Gee.ArrayList) ---> take all note instances, and gulps back a giant json string - -overwrite_stash(json_string) ---> Dump all it has in a saved_state.json - -save_to_stash(Note) ---> Dump all it has in a saved_state.json - -load_from_stash() ---> loads the json file and parse it into a list of NoteData - -*/ - -namespace Jorts.Stash { - - /*************************************************/ - // Ok first check if we have a directory to store data - public void check_if_stash () { - debug ("do we have a data directory?"); - - var data_directory = File.new_for_path (Environment.get_user_data_dir ()); - try { - if (!data_directory.query_exists ()) { - data_directory.make_directory (); - print("Prepared target data directory"); - } - } catch (Error e) { - warning ("Failed to prepare target data directory %s\n", e.message); - } - } - - - /*************************************************/ - // Just slams a json in the storage file - // TODO: Simplify this - public void overwrite_stash(string json_data, string file_overwrite) { - debug("writing to stash..."); - string data_directory = Environment.get_user_data_dir (); - string storage_path = data_directory + "/" + file_overwrite; - - var dir = File.new_for_path(data_directory); - var file = File.new_for_path (storage_path); - - try { - if (!dir.query_exists ()) { - dir.make_directory (); - } - if (file.query_exists ()) { - file.delete (); - } - var file_stream = file.create (FileCreateFlags.REPLACE_DESTINATION); - var data_stream = new DataOutputStream (file_stream); - data_stream.put_string (json_data); - - } catch (Error e) { - warning ("Failed to save notes %s\n", e.message); - } - } - - /*************************************************/ - // Handles the whole loading. If there is nothing, just start with a blue one - // We first try from main storage - // If that fails, we go for backup - // Still failing ? Start anew - public Gee.ArrayList load_from_stash () { - debug("loading from stash…"); - - Gee.ArrayList loaded_data = new Gee.ArrayList(); - string data_directory = Environment.get_user_data_dir (); - string storage_path = data_directory + "/" + Jorts.Constants.FILENAME_STASH; - string backup_path = data_directory + "/" + Jorts.Constants.FILENAME_BACKUP; - - var parser = new Json.Parser(); - - // Try standard storage - try { - parser.load_from_mapped_file (storage_path); - loaded_data = Jorts.Jason.load_parser (parser); - - } catch (Error e) { - print("[WARNING] Failed to load from main storage! " + e.message.to_string() + "\n"); - debug("Trying backup"); - // Try backup file - try { - parser.load_from_mapped_file (backup_path); - loaded_data = Jorts.Jason.load_parser(parser); - - } catch (Error e) { - - // Nothing works - print("[WARNING] Failed to load from BACKUP!!! " + e.message.to_string() + "\n"); - - } - - - } - print("\nLoaded " + loaded_data.size.to_string() + "!"); - - // If we load nothing: Fallback to a random with blue theme as first - if (loaded_data.size == 0 ) { - debug ("nothing loaded"); - NoteData blank_slate = Jorts.Utils.random_note (null); - blank_slate.theme = Jorts.Constants.DEFAULT_THEME ; - - loaded_data.add (blank_slate); - } - - debug ("I used the Json to destroy the Json"); - return loaded_data; - - } - - - - /*************************************************/ - // We first check if we have a backup or a last saved date - // if none of those two, tell we need immediate backup - // else, then depending how old we know the backup to be - public bool need_backup (string last_backup) { - debug ("lets check if we need to backup"); - - string data_directory = Environment.get_user_data_dir (); - string backup_path = data_directory + "/" + Jorts.Constants.FILENAME_BACKUP; - var file = File.new_for_path (backup_path); - - if ((last_backup == "") || (file.query_exists() == false)) { - - return true; - - } else { - debug ("We need backup!"); - - var now = new DateTime.now_utc () ; - var date_last_backup = new DateTime.from_iso8601 (last_backup, null); - TimeSpan date_diff = now.difference (date_last_backup); - var days_in_micro = Jorts.Constants.DAYS_BETWEEN_BACKUPS * TimeSpan.DAY; - return (date_diff > days_in_micro); - } - } -} diff --git a/src/Services/Storage.vala b/src/Services/Storage.vala index 0ef3b686..aeae14fd 100644 --- a/src/Services/Storage.vala +++ b/src/Services/Storage.vala @@ -5,33 +5,46 @@ * 2025 Contributions from the ellie_Commons community (github.com/ellie-commons/) */ -/* -void check_if_stash() --> Make sure we can save -Gee.ArrayList load () --> get -void save (string json_data) --> slam in +/** +* Represents the file on-disk, and takes care of the annoying +* +* void save (Json.Array) --> Save to the storage file data +* Json.Array load () --> Load and return +* +* save() takes a Json.Node instead of an NoteData[] so we avoid looping twice through all notes +* It is agressively persistent in */ +public class Jorts.Storage : Object { -public class Jorts.Storage { + private const string FILENAME = "saved_state.json"; + private const string FILENAME_BACKUP = "backup_state.json"; + private const uint8 TRIES = 3; private string data_directory; private string storage_path; - private File save_file; - construct { - data_directory = Environment.get_user_data_dir (); - storage_path = data_directory + "/" + Jorts.Constants.FILENAME_STASH; - save_file = File.new_for_path (storage_path); + /** + * Convenience property wrapping load() and save() + */ + public Json.Array content { + owned get {return load ();} + set {save (value);} + } + /*************************************************/ + construct { + data_directory = Environment.get_user_data_dir (); + storage_path = data_directory + "/" + FILENAME; check_if_stash (); } - - /*************************************************/ - // Ok first check if we have a directory to store data + /** + * Persistently check for the data directory and create if there is none + */ private void check_if_stash () { debug ("[STORAGE] do we have a data directory?"); - var dir = File.new_for_path(data_directory); + var dir = File.new_for_path (data_directory); try { if (!dir.query_exists ()) { @@ -43,80 +56,63 @@ public class Jorts.Storage { } } - /*************************************************/ - // Just slams a json in the storage file - // TODO: Simplify this - public void save (string json_data) { - debug("writing to stash..."); + /** + * Converts a Json.Node into a string and take care of saving it + */ + public void save (Json.Array json_data) { + debug("[STORAGE] Writing..."); check_if_stash (); try { - if (save_file.query_exists ()) { - save_file.delete (); - } - var file_stream = save_file.create (FileCreateFlags.REPLACE_DESTINATION); - var data_stream = new DataOutputStream (file_stream); - data_stream.put_string (json_data); + var generator = new Json.Generator (); + var node = new Json.Node (Json.NodeType.ARRAY); + node.set_array (json_data); + generator.set_root (node); + generator.to_file (storage_path); } catch (Error e) { - warning ("Failed to save notes %s\n", e.message); + warning ("[STORAGE] Failed to save notes %s", e.message); } } /*************************************************/ - // Handles the whole loading. If there is nothing, just start with a blue one - // We first try from main storage - // If that fails, we go for backup - // Still failing ? Start anew - public Gee.ArrayList load () { - debug("loading from stash…"); - - Gee.ArrayList loaded_data = new Gee.ArrayList(); - var parser = new Json.Parser(); + /** + * Grab from storage, into a Json.Node we can parse. Insist if necessary + */ + public Json.Array? load () { + debug("[STORAGE] Loading from storage letsgo"); + check_if_stash (); + var parser = new Json.Parser (); + var array = new Json.Array (); - // Try standard storage try { - check_if_stash (); parser.load_from_mapped_file (storage_path); - loaded_data = Jorts.Jason.load_parser (parser); + var node = parser.get_root (); + array = node.get_array (); } catch (Error e) { - print("[WARNING] Failed to load from storage (Attempt 1)! " + e.message.to_string() + "\n"); - - // Try backup file - try { - check_if_stash (); - parser.load_from_mapped_file (storage_path); - loaded_data = Jorts.Jason.load_parser(parser); - - } catch (Error e) { - print("[WARNING] Failed to load from storage (Attempt 2)!!! " + e.message.to_string() + "\n"); - - try { - check_if_stash (); - parser.load_from_mapped_file (storage_path); - loaded_data = Jorts.Jason.load_parser(parser); - - } catch (Error e) { - critical ("[WARNING] Failed to load from storage (Attempt 3)!!! " + e.message.to_string() + "\n"); - } - } - - - } - print("\nLoaded " + loaded_data.size.to_string() + "!"); - - // If we load nothing: Fallback to a random with blue theme as first - if (loaded_data.size == 0 ) { - debug ("nothing loaded"); - NoteData blank_slate = Jorts.Utils.random_note (null); - blank_slate.theme = Jorts.Constants.DEFAULT_THEME ; - - loaded_data.add (blank_slate); + warning ("Failed to load from storage " + e.message.to_string()); } + + return array; + } - debug ("I used the Json to destroy the Json"); - return loaded_data; + /*************************************************/ + /** + * Like it says on the tin + */ + public void dump () { + debug("[STORAGE] DROP TABLE Students;--"); + + var everything = load (); + var generator = new Json.Generator () { + pretty = true + }; + + var node = new Json.Node (Json.NodeType.ARRAY); + node.set_array (everything); + generator.set_root (node); + print (generator.to_data (null)); } } diff --git a/src/Services/Themer.vala b/src/Services/Themer.vala index 8bc07889..69e6e849 100644 --- a/src/Services/Themer.vala +++ b/src/Services/Themer.vala @@ -127,7 +127,7 @@ namespace Jorts.Themer { // Called once, at the start of the app // Loads the standard sheet, then do all the different themes public static void init_all_themes () { - debug ("Init all themes"); + debug ("[THEMER] Init all themes"); // Use standard sheet var app_provider = new Gtk.CssProvider (); diff --git a/src/Services/Utils.vala b/src/Services/Utils.vala index 11e920fa..750d536a 100644 --- a/src/Services/Utils.vala +++ b/src/Services/Utils.vala @@ -182,25 +182,4 @@ Have a great day!🎇 return blank_slate; } - - - /*************************************************/ - // Spits out a fresh new note - public NoteData random_note (string? skip_theme = null) { - debug ("Generating random note... Skip:" + skip_theme); - var randtitle = Jorts.Utils.random_title (); - string randtheme = Jorts.Utils.random_theme (skip_theme); - - NoteData randnote = new NoteData ( - randtitle, - randtheme, - "", - false, - Jorts.Constants.DEFAULT_ZOOM, - Jorts.Constants.DEFAULT_WIDTH, - Jorts.Constants.DEFAULT_HEIGHT - ); - - return randnote; - } } diff --git a/src/Windows/StickyNoteWindow.vala b/src/Windows/StickyNoteWindow.vala index f571fda6..299fd612 100644 --- a/src/Windows/StickyNoteWindow.vala +++ b/src/Windows/StickyNoteWindow.vala @@ -40,7 +40,6 @@ public class Jorts.StickyNoteWindow : Gtk.ApplicationWindow { set {on_theme_changed (value);} } - public bool monospace { get { return view.textview.monospace;} set {on_monospace_changed (value);} @@ -55,6 +54,9 @@ public class Jorts.StickyNoteWindow : Gtk.ApplicationWindow { private static uint debounce_timer_id; + // Connected to by the NoteManager to know it is time to save + public signal void changed (); + private const string ACTION_PREFIX = "app."; private const string ACTION_DELETE = "action_delete"; private const string ACTION_SHOW_EMOJI = "action_show_emoji"; @@ -153,7 +155,7 @@ public class Jorts.StickyNoteWindow : Gtk.ApplicationWindow { // Save when title or text have changed editableheader.changed.connect (on_editable_changed); - view.textview.buffer.changed.connect (on_buffer_changed); + view.textview.buffer.changed.connect (debounce_save); // The settings popover tells us a new theme has been chosen! popover.theme_changed.connect (on_theme_changed); @@ -178,8 +180,8 @@ public class Jorts.StickyNoteWindow : Gtk.ApplicationWindow { /********************************************/ // Add a debounce so we aren't writing the entire buffer every character input - private void on_buffer_changed () { - debug ("Buffer changed!"); + private void debounce_save () { + debug ("Changed! Timer: %s".printf (debounce_timer_id.to_string ())); if (debounce_timer_id != 0) { GLib.Source.remove (debounce_timer_id); @@ -187,14 +189,14 @@ public class Jorts.StickyNoteWindow : Gtk.ApplicationWindow { debounce_timer_id = Timeout.add (Jorts.Constants.DEBOUNCE, () => { debounce_timer_id = 0; - ((Application)this.application).manager.save_to_stash (); + changed (); return GLib.Source.REMOVE; }); } private void on_editable_changed () { title = editableheader.text + _(" - Jorts"); - on_buffer_changed (); + debounce_save (); } // Called when a change in settings is detected @@ -271,8 +273,8 @@ public class Jorts.StickyNoteWindow : Gtk.ApplicationWindow { _theme = new_theme; add_css_class (new_theme); - NoteManager.latest_theme = new_theme; - ((Application)this.application).manager.save_to_stash (); + NoteData.latest_theme = new_theme; + changed (); } @@ -291,8 +293,8 @@ public class Jorts.StickyNoteWindow : Gtk.ApplicationWindow { } view.textview.monospace = monospace; popover.monospace_box.monospace = monospace; - NoteManager.latest_mono = monospace; - ((Application)this.application).manager.save_to_stash (); + Jorts.NoteData.latest_mono = monospace; + changed (); } @@ -310,7 +312,7 @@ public class Jorts.StickyNoteWindow : Gtk.ApplicationWindow { case Zoomkind.ZOOM_OUT: zoom_out (); break; default: zoom = 100; break; } - ((Jorts.Application)this.application).manager.save_to_stash (); + ((Jorts.Application)this.application).manager.save_all.begin (); } // First check an increase doesnt go above limit @@ -347,7 +349,7 @@ public class Jorts.StickyNoteWindow : Gtk.ApplicationWindow { // Keep it for next new notes //((Application)this.application).latest_zoom = zoom; - NoteManager.latest_zoom = zoom; + NoteData.latest_zoom = zoom; } private void action_focus_title () {set_focus (editableheader); editableheader.editing = true;} diff --git a/src/meson.build b/src/meson.build index 20ab5075..ade26b58 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,11 +3,9 @@ sources = files ( 'Objects' / 'Themes.vala', 'Objects' / 'NoteData.vala', + 'Services' / 'Constants.vala', 'Services' / 'Storage.vala', 'Services' / 'NoteManager.vala', - 'Services' / 'Constants.vala', - 'Services' / 'Jason.vala', - 'Services' / 'Stash.vala', 'Services' / 'Themer.vala', 'Services' / 'Utils.vala',