mirror of
https://github.com/zoldar/jenot.git
synced 2026-01-03 14:32:54 +00:00
Implement basic notes store and listing notes from it
This commit is contained in:
parent
935061e73b
commit
5706314451
5 changed files with 160 additions and 4 deletions
|
|
@ -37,7 +37,9 @@
|
|||
<div class="note">
|
||||
<task-list>
|
||||
<ul>
|
||||
<li draggable="true"><task-list-item checked>one</task-list-item></li>
|
||||
<li draggable="true">
|
||||
<task-list-item checked>one</task-list-item>
|
||||
</li>
|
||||
<li draggable="true"><task-list-item>two</task-list-item></li>
|
||||
<li draggable="true"><task-list-item>three</task-list-item></li>
|
||||
<li draggable="true"><task-list-item>four</task-list-item></li>
|
||||
|
|
@ -50,6 +52,8 @@
|
|||
</ul>
|
||||
</task-list>
|
||||
</div>
|
||||
|
||||
<div id="notes"></div>
|
||||
</div>
|
||||
|
||||
<template id="task-list-item">
|
||||
|
|
|
|||
|
|
@ -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, "<br>") + "<br>";
|
||||
}
|
||||
|
||||
|
|
|
|||
59
js/jenot.js
59
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);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
81
js/store.js
Normal file
81
js/store.js
Normal file
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
14
style.css
14
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue