diff --git a/index.html b/index.html
index a58a3af..92fb1b4 100644
--- a/index.html
+++ b/index.html
@@ -37,7 +37,9 @@
- - one
+ -
+ one
+
- two
- three
- four
@@ -50,6 +52,8 @@
+
+
diff --git a/js/components.js b/js/components.js
index 11421a6..041fae4 100644
--- a/js/components.js
+++ b/js/components.js
@@ -83,13 +83,13 @@ class EditableArea extends HTMLElement {
}
#sync() {
- this.displayElement.innerHTML = render(this.inputElement.value);
+ this.displayElement.innerHTML = renderText(this.inputElement.value);
this.inputElement.style.height = this.displayElement.scrollHeight + "px";
this.inputElement.style.width = this.displayElement.scrollWidth + "px";
}
}
-function render(text) {
+export function renderText(text) {
return text.replace(/(?:\r\n|\r|\n)/g, "
") + "
";
}
diff --git a/js/jenot.js b/js/jenot.js
index 7109664..b1c5ce3 100644
--- a/js/jenot.js
+++ b/js/jenot.js
@@ -1 +1,58 @@
-import "./components.js";
+import { renderText } from "./components.js";
+import { NoteStore } from "./store.js";
+
+const Notes = new NoteStore("jenot-app");
+
+Notes.addEventListener("save", render.bind(this));
+
+Notes.reset();
+
+Notes.add({
+ type: "note",
+ content: "This is a test note",
+});
+
+Notes.add({
+ type: "tasklist",
+ content: [
+ { checked: false, content: "First item" },
+ { checked: true, content: "Second item" },
+ { checked: false, content: "Third item" },
+ ],
+});
+
+Notes.saveStorage();
+
+function render() {
+ const notes = Notes.all();
+ const notesContainer = document.querySelector("#notes");
+ notesContainer.textContent = "";
+
+ notes.forEach((note) => {
+ const container = document.createElement("div");
+ container.id = note.id;
+ container.classList.add("note");
+ container.classList.add("readonly");
+
+ if (note.type === "note") {
+ container.innerHTML = renderText(note.content);
+ } else if (note.type === "tasklist") {
+ const list = document.createElement("ul");
+
+ note.content.forEach((task) => {
+ const item = document.createElement("li");
+ const check = document.createElement("p");
+ check.textContent = task.checked ? "☑" : "☐";
+ item.appendChild(check);
+ const itemContent = document.createElement("p");
+ itemContent.innerHTML = renderText(task.content);
+ item.appendChild(itemContent);
+ list.append(item);
+ });
+
+ container.appendChild(list);
+ }
+
+ notesContainer.appendChild(container);
+ });
+}
diff --git a/js/store.js b/js/store.js
new file mode 100644
index 0000000..5bb8208
--- /dev/null
+++ b/js/store.js
@@ -0,0 +1,81 @@
+export class NoteStore extends EventTarget {
+ localStorageKey;
+ notes = [];
+ editedNoteId = "none";
+
+ /*
+ Note structure:
+
+ - id - unique note ID
+ - type - either `note` or `tasklist`
+ - content - note's content
+ - created - timestamp
+ */
+
+ constructor(localStorageKey) {
+ super();
+ this.localStorageKey = localStorageKey;
+
+ this.#readStorage();
+
+ // handle notes edited in another window
+ window.addEventListener(
+ "storage",
+ () => {
+ this.#readStorage();
+ this.saveStorage();
+ },
+ false,
+ );
+ }
+
+ all = () => this.notes;
+ get = () => this.notes.find((note) => note.id === id);
+ getEditedNoteId = () => this.editedNoteId;
+
+ add(note) {
+ this.notes.unshift({
+ id: "id_" + Date.now(),
+ type: note.type,
+ content: note.content,
+ created: new Date(),
+ });
+ }
+
+ reset() {
+ this.notes = [];
+ }
+
+ remove({ id }) {
+ this.notes = this.notes.filter((note) => note.id !== id);
+ }
+
+ update(note) {
+ this.notes = this.notes.map((n) => (n.id === note.id ? note : n));
+ }
+
+ setEditedNoteId(id) {
+ this.editedNoteId = id;
+ }
+
+ saveStorage() {
+ window.localStorage.setItem(
+ this.localStorageKey + "_notes",
+ JSON.stringify(this.notes),
+ );
+ window.localStorage.setItem(
+ this.localStorageKey + "_editedNoteId",
+ this.editedNoteId,
+ );
+ this.dispatchEvent(new CustomEvent("save"));
+ }
+
+ #readStorage() {
+ this.notes = JSON.parse(
+ window.localStorage.getItem(this.localStorageKey + "_notes") || "[]",
+ );
+ this.editedNoteId =
+ window.localStorage.getItem(this.localStorageKey + "_editedNoteId") ||
+ "none";
+ }
+}
diff --git a/style.css b/style.css
index f841642..aec4c26 100644
--- a/style.css
+++ b/style.css
@@ -167,3 +167,17 @@ div#content {
padding: 4px 8px;
margin-bottom: 20px;
}
+
+.note.readonly ul {
+ wdith: 100%;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+.note.readonly ul li {
+ display: flex;
+ gap: 6px;
+ align-items: baseline;
+ margin-bottom: 4px;
+}