round65: Android-Startbildschirm nur mit Favoriten, echtes Drag-and-Drop per Pointer-Events, selbst erstellbare Ordner

This commit is contained in:
2026-07-26 18:34:46 +02:00
parent 538fba5fc3
commit ff87f9812c
6 changed files with 590 additions and 263 deletions

View File

@@ -16,10 +16,14 @@ function serializeSettings() {
// Einstellungen statt nur im sessionStorage/localStorage des jeweiligen
// Browsers, damit die Wahl wirklich app-weit gilt, nicht nur pro Gerät.
mobileHomeStyle: all.mobileHomeStyle === "android" ? "android" : "classic",
// Nur relevant, wenn mobileHomeStyle "android" ist: Kategorien als
// antippbare "Ordner" (wie ein Android-Ordner mit Mini-Vorschau) oder
// alles auf einer durchgehend scrollbaren Seite mit Abschnitts-Überschriften.
mobileHomeFolderMode: all.mobileHomeFolderMode === "scroll" ? "scroll" : "folders",
// NEU (round65): Frei angeordnetes Layout des Android-Startbildschirms
// (welche Favoriten wo liegen, selbst angelegte Ordner, Aufteilung
// zwischen Hauptbereich und angehefteter Dock-Leiste unten) - als JSON
// gespeichert, roh durchgereicht. Der genaue Aufbau ist reine
// Frontend-Angelegenheit (siehe useHomeLayout.ts) - das Backend
// validiert hier nur, dass es sich überhaupt um ein Objekt mit den
// erwarteten Top-Level-Schlüsseln handelt, nicht den vollen Inhalt.
mobileHomeLayout: all.mobileHomeLayout || null,
};
}
@@ -37,7 +41,7 @@ export async function settingsRoutes(app: FastifyInstance): Promise<void> {
liveStatusEnabled?: boolean;
liveStatusIntervalMinutes?: number;
mobileHomeStyle?: string;
mobileHomeFolderMode?: string;
mobileHomeLayout?: unknown;
}
| undefined;
@@ -84,11 +88,20 @@ export async function settingsRoutes(app: FastifyInstance): Promise<void> {
settingsRepo.setSetting("mobileHomeStyle", body.mobileHomeStyle);
}
if (body?.mobileHomeFolderMode !== undefined) {
if (body.mobileHomeFolderMode !== "folders" && body.mobileHomeFolderMode !== "scroll") {
return reply.code(400).send({ error: "mobileHomeFolderMode muss 'folders' oder 'scroll' sein" });
if (body?.mobileHomeLayout !== undefined) {
const layout = body.mobileHomeLayout;
const looksValid =
layout === null ||
(typeof layout === "object" &&
layout !== null &&
Array.isArray((layout as Record<string, unknown>).grid) &&
Array.isArray((layout as Record<string, unknown>).dock));
if (!looksValid) {
return reply
.code(400)
.send({ error: "mobileHomeLayout muss null oder ein Objekt mit 'grid' und 'dock' als Arrays sein" });
}
settingsRepo.setSetting("mobileHomeFolderMode", body.mobileHomeFolderMode);
settingsRepo.setSetting("mobileHomeLayout", layout === null ? "" : JSON.stringify(layout));
}
return serializeSettings();