Add saving new note as draft, client-side only

This commit is contained in:
Adrian Gruntkowski 2025-02-08 17:27:36 +01:00
parent e1b8096447
commit b3ba84f54b
3 changed files with 63 additions and 15 deletions

View file

@ -553,6 +553,7 @@ class NoteForm extends HTMLElement {
this.note = { this.note = {
type: "note", type: "note",
content: "", content: "",
reminder: null,
}; };
} }
@ -590,28 +591,24 @@ class NoteForm extends HTMLElement {
this.tasklistModeButton.addEventListener("click", (e) => { this.tasklistModeButton.addEventListener("click", (e) => {
e.preventDefault(); e.preventDefault();
this.note.type = "tasklist"; this.#setNote("type", "tasklist");
this.#setContent();
this.#updateUI(); this.#updateUI();
}); });
this.noteModeButton.addEventListener("click", (e) => { this.noteModeButton.addEventListener("click", (e) => {
e.preventDefault(); e.preventDefault();
this.note.type = "note"; this.#setNote("type", "note");
this.#setContent();
this.#updateUI(); this.#updateUI();
}); });
this.removeButton.addEventListener("click", (e) => { this.removeButton.addEventListener("click", (e) => {
e.preventDefault(); e.preventDefault();
if (this.mode === "edit") { this.dispatchEvent(
this.dispatchEvent( new CustomEvent("deleteNote", {
new CustomEvent("deleteNote", { bubbles: true,
bubbles: true, detail: this.note,
detail: this.note, }),
}), );
);
}
this.#reset(); this.#reset();
}); });
@ -630,7 +627,7 @@ class NoteForm extends HTMLElement {
}); });
this.addEventListener("reminderUpdate", () => { this.addEventListener("reminderUpdate", () => {
this.note.reminder = this.reminderPicker.value; this.#setNote("reminder", this.reminderPicker.value);
this.#updateUI(); this.#updateUI();
}); });
@ -659,7 +656,7 @@ class NoteForm extends HTMLElement {
} }
this.addEventListener("contentChange", () => { this.addEventListener("contentChange", () => {
this.note.content = this.content.firstChild.value; this.#setNote("content", this.content.firstChild.value);
}); });
this.#updateUI(); this.#updateUI();
@ -686,6 +683,23 @@ class NoteForm extends HTMLElement {
this.#setContent(); this.#setContent();
} }
#setNote(field, value) {
this.note[field] = value;
if (field === "type") {
this.#setContent();
}
if (this.mode === "add") {
this.dispatchEvent(
new CustomEvent("updateDraft", {
bubbles: true,
detail: this.note,
}),
);
}
}
#updateUI() { #updateUI() {
if (this.note.reminder?.enabled) { if (this.note.reminder?.enabled) {
this.reminderButtonLabel.textContent = reminderLabel(this.note.reminder); this.reminderButtonLabel.textContent = reminderLabel(this.note.reminder);

View file

@ -47,7 +47,7 @@ if (URL_PARAMS.has("reset-meta")) {
} }
// Very rudimentary periodic sync. It will be refactored into a more real-time // Very rudimentary periodic sync. It will be refactored into a more real-time
// solution using either websocket of long-polling, so that server can notify about // solution using either websocket or long-polling, so that server can notify about
// new data to sync. // new data to sync.
const sync = async () => { const sync = async () => {
await Notes.sync(); await Notes.sync();
@ -99,6 +99,9 @@ const newNote = document.querySelector("#new-note");
const editNote = document.querySelector("#edit-note"); const editNote = document.querySelector("#edit-note");
const editNoteDialog = document.querySelector("#edit-note-dialog"); const editNoteDialog = document.querySelector("#edit-note-dialog");
// Load draft into new note
newNote.load(structuredClone(await Notes.getDraft()));
// Each save event originating from storage triggers a re-render // Each save event originating from storage triggers a re-render
// of notes list. // of notes list.
Notes.addEventListener("save", render.bind(this)); Notes.addEventListener("save", render.bind(this));
@ -112,9 +115,18 @@ if (isLoggedIn) {
// note-form component specific event handlers // note-form component specific event handlers
newNote.addEventListener("addNote", async (e) => { newNote.addEventListener("addNote", async (e) => {
await Notes.add(e.detail); await Notes.add(e.detail);
await Notes.clearDraft();
Notes.saveStorage(); Notes.saveStorage();
}); });
newNote.addEventListener("updateDraft", async (e) => {
await Notes.setDraft(e.detail);
});
newNote.addEventListener("deleteNote", async (e) => {
await Notes.clearDraft();
});
editNote.addEventListener("updateNote", async (e) => { editNote.addEventListener("updateNote", async (e) => {
await Notes.update(e.detail); await Notes.update(e.detail);
Notes.saveStorage(); Notes.saveStorage();

View file

@ -116,6 +116,13 @@ class WebNoteStore {
} }
} }
const draftTemplate = {
id: "draft",
type: "note",
content: "",
reminder: null,
};
export class SyncedNoteStore extends EventTarget { export class SyncedNoteStore extends EventTarget {
constructor(dbName, endpoint, webStore) { constructor(dbName, endpoint, webStore) {
super(); super();
@ -171,6 +178,21 @@ export class SyncedNoteStore extends EventTarget {
return memory[this.dbName][this.storeName][id]; return memory[this.dbName][this.storeName][id];
} }
async getDraft() {
return this.get("draft").then(
(draft) => draft || structuredClone(draftTemplate),
);
}
async setDraft(draft) {
draft.id = "draft";
return this.update(draft, true);
}
async clearDraft() {
return this.update(structuredClone(draftTemplate), true);
}
async getMeta() { async getMeta() {
return this.get("meta").then((meta) => meta || { lastSync: null }); return this.get("meta").then((meta) => meta || { lastSync: null });
} }