This commit is contained in:
Adrian Gruntkowski 2025-08-29 20:28:16 +02:00
parent 2e0d7d044b
commit 909892ded9
5 changed files with 119 additions and 11 deletions

View file

@ -9,6 +9,38 @@ import {
} from "./notifications.js";
import "./components.js";
import { reminderLabel } from "./reminders.js";
import { Router } from "./router.js";
// Cookie presence determines login state
const isLoggedIn = !!document.cookie
.split("; ")
.find((row) => row.startsWith("jenot_pub="));
// Notes storage configuration.
// The storage is a combination of IndexedDB + network sync.
// Network sync is only enabled is user is logged in.
const endpoint = isLoggedIn ? "/" : null;
const Notes = new SyncedNoteStore("jenot-app", endpoint);
let view = "home";
const routes = [
{
path: "index.html#home",
callback: () => {
view = "home";
render();
},
},
{
path: "index.html#reminders",
callback: () => {
view = "reminders";
render();
},
},
{ path: "*", callback: (router) => router.redirect("index.html#home") },
];
async function resetApp() {
await window.navigator.serviceWorker
@ -24,16 +56,6 @@ document.querySelector("#reset-app").addEventListener("click", resetApp);
const URL_PARAMS = new URLSearchParams(window.location.search);
// Cookie presence determines login state
const isLoggedIn = !!document.cookie
.split("; ")
.find((row) => row.startsWith("jenot_pub="));
// Notes storage configuration.
// The storage is a combination of IndexedDB + network sync.
// Network sync is only enabled is user is logged in.
const endpoint = isLoggedIn ? "/" : null;
const Notes = new SyncedNoteStore("jenot-app", endpoint);
await Notes.init();
// Reset metadata to force full sync
@ -184,7 +206,16 @@ function notesEqual(note1, note2) {
return note1.id === note2.id && note1.updated === note2.updated;
}
async function render() {
async function renderReminders() {
const allNotes = await Notes.all();
const reminderNotes = allNotes.filter((n) => n.reminder?.enabled);
const notes = filterNotes(reminderNotes).toSorted(
(a, b) => b.reminder.date - a.reminder.date,
);
const notesContainer = document.querySelector("#reminders");
}
async function renderHome() {
const allNotes = await Notes.all();
const notes = filterNotes(allNotes);
const notesContainer = document.querySelector("#notes");
@ -234,6 +265,19 @@ async function render() {
notes.forEach((n) => (currentNotes[n.id] = structuredClone(n)));
}
async function render() {
switch (view) {
case "home":
renderHome();
break;
case "reminders":
renderReminders();
break;
default:
renderError();
}
}
function openModal(modal) {
document.body.style.top = `-${window.scrollY}px`;
document.body.style.position = "fixed";
@ -309,3 +353,5 @@ function renderNote(note) {
return container;
}
const router = Router.init(routes);

View file

@ -0,0 +1,7 @@
export async function mount() {
}
export async function render() {
}

View file

51
priv/static/js/router.js Normal file
View file

@ -0,0 +1,51 @@
export class Router {
constructor(routes) {
this.routes = routes;
window.addEventListener("popstate", () => {
this.loadInitialRoute();
});
}
static init(routes) {
const router = new Router(routes);
router.loadInitialRoute();
return router;
}
loadRoute(path) {
const matchedRoute = this.#matchURLToRoute(path);
if (!matchedRoute) {
throw new Error("Route not found!");
}
matchedRoute.callback(this);
}
navigateTo(path) {
window.history.pushState({}, "", path);
this.loadRoute(path);
}
redirect(path) {
this.loadRoute(path);
}
#matchURLToRoute(path) {
const found = this.routes.find((router) => router.path === path);
if (!found) {
return this.routes.find((router) => router.path === "*");
}
return found;
}
loadInitialRoute() {
const pathParts = window.location.pathname.split("/");
const path = pathParts.length > 1 ? pathParts[1] : "";
this.loadRoute(path);
}
}

View file

@ -53,6 +53,10 @@ dialog {
max-height: 90vh;
}
/* dialog[open] { */
/* oversrcoll-behavior-y: contain; */
/* } */
::backdrop {
background: var(--backdrop-background);
opacity: 0.75;