Files
desktop-planer/README.md
2026-09-19 20:59:47 +02:00

111 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Desktop
GNOME-Shell-Extension (GNOME 46, Ubuntu 24.04): Kalender, Todos und Notizen direkt auf dem Desktop,
unter allen Fenstern, über dem Wallpaper.
## Bedienung
- **Termin anlegen:** in der Wochenansicht auf eine Stunde drücken und bis zur Endstunde ziehen,
auch über mehrere Tage. Klick ohne Ziehen = eine Stunde. Ziehen in der Zeile „ganz“ = ganztägig.
Oder Rechtsklick auf einen Tag (Monat), eine Stunde (Woche) oder die Tagesfläche: „Termin erstellen“.
Popover: Titel, Von und Bis je mit Datum und Uhrzeit. Ohne Ende gilt eine Stunde, ohne Uhrzeit ganztägig.
- **Todo anlegen:** Rechtsklick ins Todo-Panel oder in den Kalender, „Todo erstellen“. Text plus Datum und Uhrzeit.
- **Notiz:** Rechtsklick irgendwo im Notiz-Panel, „Notiz erstellen“ fragt den Namen und öffnet den Editor.
Klick in die Notizfläche bearbeitet. Mit Fokus steht der rohe Markdown-Text, ohne Fokus die formatierte Ansicht.
Gespeichert wird alle paar Sekunden und beim Klick woanders hin.
- **Bearbeiten:** Linksklick auf Termin, Todo oder Notiz.
- **Rechtsklick auf freie Fläche:** Erstellen (Todos, Tagesansicht, Notizbaum im Wurzelordner).
- **Rechtsklick auf Ordner:** Notiz oder Unterordner darin erstellen, Umbenennen, Löschen.
- **Rechtsklick auf Eintrag:** Umbenennen, Löschen.
- Popover: Enter speichert, Esc oder Klick daneben bricht ab. Keine Buttons.
## Aufbau
- `desktop@marha.de/` – die Extension
- `extension.js` – Layout auf dem Arbeitsbereich, Stapelung über Desktop-Icons
- `calendar.js` – Monat, Woche (Drag), Tag, Termin-Popover
- `todos.js` – Todo-Liste, Todo-Popover
- `notes.js` – Ordnerbaum, Markdown-Anzeige, Inline-Editor, Kontextmenü
- `widgets.js` – Popover (Grab, Esc, Tab, Klick daneben), Kontextmenü, Datums- und Zeitauswahl
- `markdown.js`, `dates.js` – reine Logik, ohne Shell testbar
- `store.js` – Ablage, Tombstones, Übernahme vom Server
- `sync.js` – Abgleich mit dem Server (Soup, Timer)
- `backend/` – Sync-Server (FastAPI, SQLite), `Dockerfile`, `docker-compose.yml`
- `dev/` – Test-Werkzeuge
## Daten
`~/.local/share/desktop-app/`
- `events.json` – Termine
- `todos.json` – Todos
- `notes/` – Notizen als `.md`, Ordner beliebig verschachtelt (Obsidian kann den Ordner öffnen)
- `deleted-notes.json` – gelöschte Notizen mit Zeitpunkt, damit der Sync sie auch woanders löscht
- `sync.json` – Server-Zugang, siehe Sync
- `sync-state.json` – letzter Server-Stand
Gelöschte Termine und Todos bleiben mit `deleted: true` in der Datei und werden nur ausgeblendet.
## Sync
Der Server (`backend/`, FastAPI + SQLite) hält den Kern. Jedes Gerät gleicht alle paar Sekunden ab:
eigene Änderungen hoch, fremde Änderungen runter. Bei Konflikten gewinnt der Eintrag mit dem
neueren `updated` (Notizen: Änderungszeit der Datei, ganze Datei). Offline geht weiter, beim
Wiederverbinden wird nachgeliefert. Eine gerade offene Notiz wird nicht von außen überschrieben.
Zugang auf jedem Gerät in `~/.local/share/desktop-app/sync.json`:
```
{"url": "https://planer.marha.de", "token": "<SYNC_TOKEN aus .env>", "interval": 5}
```
Ohne diese Datei läuft die Extension rein lokal.
Server-API (alle Aufrufe mit `Authorization: Bearer <SYNC_TOKEN>`):
- `POST /api/sync` – `{"since": <cursor>, "events": [...], "todos": [...], "notes": [...]}`; Antwort: Änderungen seit `since` plus neuer `cursor`
- `GET /api/events`, `/api/todos`, `/api/notes` – aktueller Stand ohne Gelöschte, für andere Anwendungen
### Server starten
```
cp .env.example .env # SYNC_TOKEN setzen
make dev # lokal, http://localhost:8040 (anderer Port: make dev PORT=8050)
make prod # auf dem Server: Docker Compose hinter Traefik, https://planer.marha.de
make stop | make logs | make down
make test # Server-Tests
```
## Installation
```
make install # kopiert die Extension nach ~/.local/share/gnome-shell/extensions und aktiviert sie
make update # überschreibt eine installierte Extension mit dem Stand aus diesem Ordner
```
Danach ab- und wieder anmelden. Unter Wayland lädt die Shell neuen Code erst nach einem neuen Login.
Voraussetzung: GNOME 46 (Ubuntu 24.04).
## Entwicklung
```
gjs -m dev/tests/run.js # Unit-Tests für dates.js und markdown.js
dev/restart.sh # Test-Shell als Fenster starten (zum Selbst-Ausprobieren)
dev/restart.sh headless # Test-Shell unsichtbar, für simulierte Eingaben
dev/tests/input.sh # Ablauf-Tests mit echter Maus und Tastatur (headless)
dev/tests/sync.sh # Sync-Test: lokaler Server plus headless Shell, beide Richtungen
dev/eval.sh dev/seed.js # Testdaten einspielen
dev/eval.sh 'js' # JavaScript in der Test-Shell ausführen (oder Dateipfad)
dev/shot.sh [datei.png] # Screenshot der Test-Shell
dev/input.sh click X Y # Maus und Tastatur simulieren (nur headless gefahrlos)
dev/press.sh "Text" # Button mit diesem Text direkt auslösen
dev/stop.sh # Test-Shell beenden
```
Die Test-Shell läuft mit `GSETTINGS_BACKEND=keyfile` und eigenem `XDG_DATA_HOME`
unter `/tmp/desktop-app-nested/`. Die echte Session bleibt unberührt.
Im Fenstermodus (nested, X11-Backend) würden virtuelle Eingabegeräte auf dem echten Desktop
landen. Deshalb nutzt `dev/input.sh` nur den headless Modus (natives Backend).
`dev/fake-ding.py` startet ein Fenster wie Desktop Icons, um die Stapelung zu prüfen.