Secretary

Apps/tasks/changelog
Login

Apps/tasks/changelog

Secretary Tasks (Android) - Changelog

Every released version of the Secretary Tasks app, newest first.

App documentation: Apps/tasks

Status 2026-08-22 (versionCode 22)

Status 2026-10-13 (64)

Secretary Tasks 64 (versionCode 64): Ordner und ihre Einträge sind jetzt sichtbar ineinander verschachtelt. Die gemeinsame FolderRow (common/ui/FolderRow.kt) unterschied sich bisher nicht von den Eintragskarten: Ordner-Kopfzeile und Einträge lagen als gleich aussehende Karten in einer flachen LazyColumn, die Zugehörigkeit der Einträge zum Ordner war nicht zu erkennen. Die Kopfzeile ist jetzt eine getönte, abgerundete Zeile mit Ordner-Glyphe, Name, Anzahl und rotierendem Chevron in der Akzentfarbe; jeder Eintrag eines aufgeklappten Ordners ist über die neue Composable FolderChild eingerückt und links mit einer dünnen Führungslinie an die Kopfzeile gebunden. Die Linie wird in den Kartenabstand hinein verlängert und läuft dadurch über die Einträge eines Ordners durchgehend. Das trifft alle vier Listen-Clients (Notizen, Aufgaben, Links, Kontakte). versionCode 63 -> 64.

Tests: :common:compileDebugKotlin, :notes:compileDebugKotlin, :tasks:compileDebugKotlin, :links:compileDebugKotlin, :contacts:compileDebugKotlin grün.

Status 2026-10-09 (62)

Secretary Tasks 62 (versionCode 62): Ordner-Gruppierungen starten eingeklappt, mit gemeinsamer Einstellung Ordner eingeklappt.

(1) Eingeklappt per Vorgabe. Die Liste gruppiert nach Ordnern (erster TAG: = Ordner) mit einer Kopfzeile pro Ordner; deren Startzustand ist jetzt eingeklappt, ein Tipp auf die Kopfzeile klappt den Ordner auf/zu (FolderExpansionState/rememberFolderExpansion in common/ui/FolderRow.kt). Eine Liste mit nur einem Ordner zeichnet weder Kopfzeile noch Umschalter.

(2) Gemeinsame Einstellung. Der Startwert kommt aus der gemeinsamen UiPreferences.folders_collapsed (Default true = eingeklappt; SRS/common 1.6.0, FR-C-70..72) und liegt im Einstellungs-Screen in der neuen Sektion Ordner: Checkbox Ordner eingeklappt („Listen starten mit geschlossenen Ordnern"), gerendert von FolderSettingsSection. SecretarySettingsScreen traegt dafuer showFolderSettings – true bei Notizen, Aufgaben, Links und Kontakten, alle übrigen Clients bleiben beim Default false.

Tests: compileDebugKotlin (common + alle Module) und testDebugUnitTest (common + die vier Ordner-Clients) gruen; keine JVM-Verhaltensaenderung, keine neuen Unit-Tests. versionCode 61 -> 62.

Status 2026-10-01 (58)

Secretary Tasks 58 (versionCode 58): die Sync-Aktion ist ohne Konto weg, Passwortfelder zeigen Klartext. Beides sitzt im gemeinsamen Code und trifft damit alle acht Clients.

(1) Keine Sync-Aktion ohne Konto. AppHeader (Kit.kt) blendet die Sync-Aktion bereits aus, wenn onSync null ist - das war die vorhandene Konvention, nur wurde sie an keiner Stelle benutzt. OfflineBanner (StatusBanners.kt) verlangte dagegen einen nicht-nullbaren onSync und zeichnete den Refresh-Button bedingungslos; der Parameter ist jetzt (() -> Unit)?, und ohne Konto fehlt der Knopf (die Meldung "offline" bleibt stehen). Alle Aufrufstellen reichen den Callback nur noch durch, wenn wirklich ein Konto existiert: loggedIn der jeweiligen ViewModel, im Kalender der collected isLoggedIn-StateFlow. Das Journal ist der einzige Client, bei dem das sichtbar war - es hat keine Login-Sperre und laeuft im lokalen Modus (localMode = !repo.isConfigured()) ohne Konto weiter, zeigte den Sync-Knopf aber trotzdem. Beim Secrets-Tresor war der Knopf vorhanden und nur deaktiviert (enabled = state.connected); er wird jetzt gar nicht erst gezeichnet, der Spinner waehrend state.syncing bleibt. Am Launcher aendert sich nichts: die Server-Sync-Sektion im Settings-Screen war schon an account != null gehaengt.

(2) Passwortfelder zeigen Klartext. Alle Eingabefelder fuer Passwoerter nehmen VisualTransformation.None; die Tastatur bleibt KeyboardType.Password. Betroffen sind der gemeinsame Login-Screen (SecretaryLoginScreen), die Journal-Passwortdialoge (PasswordDialogs: Setzen, Aendern, Abfragen) und das Entschperren (UnlockScreen) sowie im Tresor die Felder fuer Recovery-Passphrase, Entschperr-Passphrase, KDBX-Import und KDBX-Export (SecretsApp) und das Passwortfeld im Eintrags-Editor (Browse). Anlass war die Darstellung, nicht die Sicherheit: die Maske besteht aus U+25CF (●), und die gebundelte Typewriter-Schrift Special Elite deckt dieses Zeichen nicht ab - die Felder zeigten unlesbare Ersatzglyphen. In den Tresor-Dialogen ist der Sichtbarkeits-Umschalter damit ueberfluessig und mit ihm die Felder passwordVisible/visible, der Eye-Button bzw. der Textbutton Anzeigen/Verbergen und die Visibility/VisibilityOff-Imports weg. Der Reveal-Pfad fuer gespeicherte Secrets in Browse (FieldRow) bleibt unberuehrt: das ist eine Anzeige, keine Eingabe.

Tests: keine neuen, kein JVM-Verhalten geaendert. 662 Tests gruen (Kalender 55, common 100, Kontakte 44, Launcher 12, Secrets 405, Tasks 46), verifiziert ueber gradle test; alle neun Module kompilieren (compileDebugKotlin, offline), und die Neuuebersetzung meldet in keiner der geaenderten Dateien eine Warnung. versionCode 57 -> 58.

Status 2026-09-30 (57)

Secretary Tasks 57 (versionCode 57): die Namensraum-Karte im Einstellungs-Screen ist weg, die Version steht jetzt unten. Beides steckt im gemeinsamen SecretarySettingsScreen in common (SRS common 1.3.0), trifft also alle acht Clients. Der Parameter collectionNamespace und die Karte Namensraum sind raus - sie zeigte eine Konstante, die der Nutzer ohnehin in der Collection-Liste sieht. Die Konstante TasksRepository.NAMESPACE bleibt als CalDAV-Basispfad, wird aber nicht mehr angezeigt. Neu ist die letzte Zeile des Screens: die Version der jeweils laufenden App aus der PackageInfo des eigenen Pakets, jede App zeigt so ihre eigene Nummer, ohne sie durchzureichen. versionCode 56 -> 57.

Status 2026-09-30 (56)

Secretary Tasks 56 (versionCode 56): keine Code-Aenderung - der Quelltext ist derselbe wie bei 55. Veraendert wurde in diesem Zug nur der Launcher (Korrektur am Konfigurations-Sync, dort 460). Die Nummer geht trotzdem hoch, weil ein Release alle acht Clients und beide Serverpakete zusammen ausliefert: das Buildsystem ueberspringt einen Lauf, dessen Zieldateinamen alle bereits im Archiv liegen, und ein gleichnamiges Paket mit gleichem Inhalt waere auf dem Geraet nicht von 55 zu unterscheiden - bei einer APK zusaetzlich ein versionCode, den ein Geraet nicht neu installiert. Server und check-links gehen mit auf 0.24.0. versionCode 55 -> 56.

Status 2026-09-29 (55)

Secretary Tasks 55 (versionCode 55): Abschluss des Release-Zugs, der Signiermaterial aus einer Umgebungsvariablen in eine Datei verlagert hat (siehe 54). Der Sprung ist der von 4d6b02eee5 für alle acht Module gemeinsam gesetzte: BuildManager vergleicht Dateinamen statt Inhalte, also liefert derselbe Code ohne neue versionCode denselben Namen und der Build wird als „bereits im Repo“ abgewiesen. An Tasks änderte sich in diesem Schritt kein Funktionscode. versionCode 54 -> 55.

Status 2026-09-29 (54)

Secretary Tasks 54 (versionCode 54): alle acht Clients signieren ihre Release-APKs, nicht nur der Launcher. Vorher hatte nur der Launcher ein signingConfig; die sieben anderen Module bauten *-unsigned.apk und konnten kein signiertes Release liefern. Zwei Nacharbeiten blieben in derselben Version: der Default-Pfad für das Keystore war um eine Ebene zu kurz, und die Zugangsdaten wurden aus dem Prozess-Environment in eine Datei verlagert, damit ein Release nicht von einer in keinem --help genannten Umgebungsvariable abhängt. versionCode 53 -> 54.

Status 2026-09-29 (53)

Secretary Tasks 53 (versionCode 53): Signiermaterial in ein eigenes Fossil- Repository signing-certs ausgelagert (vorher lag es im Secretary-Repository selbst). An Tasks änderte das keine Zeile Funktionscode; die Version trägt die neue Signierkonfiguration. versionCode 52 -> 53.

Status 2026-09-29 (52)

Secretary Tasks 52 (versionCode 52): Konto, gemeinsamer Einstellungs-Screen und Konfigurations-Sync für den Launcher. Der Commit hielt die versionCode aller acht Module gleichzeitig fest. An Tasks änderte sich dabei keine Zeile; die Funktionsänderung betraf ausschließlich den Launcher. Die Nummer 51 wurde nie vergeben — dieser Commit sprang von 50 auf 52. versionCode 50 -> 52.

Status 2026-09-24 (50)

Secretary Tasks 50 (versionCode 50): neue Typewriter-Launcher-Icons für alle Secretary-Apps. Das Schema ist die Glyphe als [glyph] in der Typewriter- Schrift Special Elite, weiß auf einem app-spezifischen Akzent; die Icon- Erzeugung (tools/generate-icons.sh) bekam dazu eine Option, weil Special Elite U+263A nicht abdeckt. versionCode 49 -> 50.

Status 2026-09-19 (49)

Secretary Tasks 49 (versionCode 49): Eigener Namespace-Root /tasks/ statt /calendars/tasks-* (Namespace-Migration, server 0.16.0). Die Sammlungen liegen jetzt unpräfixiert unter /tasks/ (zuvor /calendars/tasks-*). TasksRepository nutzt baseCollectionPath = "/tasks/" (neue CaldavClient.collectionRoot), TasksCodec default collectionBasePath = "/tasks/", die Sync-Sektion zeigt „Namensraum" statt „Sammlungspräfix". Der Offline-Cache wird beim ersten Lesen via GOfflineStore.legacyPrefix = "tasks-" automatisch migriert (/calendars/tasks-* → /tasks/…, idempotent) – auch in den Benachrichtigungs-/System-Sync-Pfaden (NotificationScheduler, TaskReminderReceiver, TaskSystemSyncAdapter). runServerSync filtert zusätzlich /tasks/ (Legacy-/calendars/, /addressbooks/ bleiben im Filter); createTasksCollection vergibt IDs unpräfixiert (sanitizeId(name)). Deployment-Reihenfolge: erst Server auf 0.16.0 updaten + migrate-namespaces.sh, dann die App ausrollen. versionCode 48 -> 49. CONTEXT.md updated.

Status 2026-09-16 (48)

Secretary Tasks 48 (versionCode 48): Sync-Härtung: kein Endlos-Sync, kein Sync-Dienst-400 (gleiche Muster wie Journal v119/v120). runServerSync() konnte syncStatus bei leerer Collection-/Job-Liste endgültig auf RUNNING stehen lassen (der Guard if (syncStatus?.state == RUNNING) return blockierte danach jede weitere Synchronisation für die Sitzung) und pollte Server-Jobs unbegrenzt. Neu: leere Collections bzw. leere Jobs brechen sauber ab (syncStatus = null), der Poll-Loop ist hart begrenzt (maxPolls = 200 ≈ 100 s bei 500 ms; sonst FAILED „Sync timed out"), und es werden nur echte Server- Collections übertragen (href unter /calendars/ oder /addressbooks/ – eine lokale Pseudo-Collection wie /local/ wird niemals an /sync/start gereicht). versionCode 47 -> 48.

Status 2026-09-16 (47)

Secretary Tasks 47 (versionCode 47): Offline-Sync-Engine (secretary-common-android v0.30.0). loadTasksInternal nutzt jetzt die gemeinsame OfflineSyncEngine (CrudItemRemote + GOfflineStore + TasksCodec): Server-Abruf, Rehome-Upload lokaler UIDs, Pending-Delete-Filter, Prepare-Null-Erhalt und Cache-Ersatz liegen in common; die lokale mergeWithPending-Logik wurde entfernt. Offline-Verhalten (goOffline + Cache-Anzeige bei IOException, DavException als echter Fehler) ist unverändert; nach dem Merge laufen flushPending(), NotificationScheduler.scheduleAll und mirrorSystem() weiter wie zuvor. View bleibt beim Sync stabil (kein Leeren/Neubau). versionCode 46 -> 47.

Status 2026-09-13 (46)

Secretary Tasks 46 (versionCode 46): Kategorie-Parsing-Fehler behoben (secretary-common-android v0.26.0). VTodo.parse zerlegte die CATEGORIES-Liste bisher mit .split(',') bei jedem Komma, obwohl serializeTask die Kategorie-Werte bereits mit escapeText escaped – eine Aufgaben-Kategorie, deren Value ein Komma enthält (z. B. eine Wiederholungs-Regel RRULE:FREQ=WEEKLY;BYDAY=MO\,WE\,FR als Kategorie), wurde beim Laden also in mehrere Kategorien zerrissen. Neu wird die Liste nur an unescaped-gespeicherten Kommas gesplittet und jedes Token per unescapeText dekodiert (gleicher Fix wie für VJOURNAL in v0.25.0, hier verallgemeinert über das gemeinsame IcsText-Helper). versionCode 45 -> 46.

Status 2026-09-09 (45)

Secretary Tasks 45 (versionCode 45): Sammlungen: einheitliches Langdruck-Kontextmenü + Kopieren (secretary-common-android v0.19.0). Die Sammlungsübersicht nutzt jetzt das gemeinsame CollectionContextMenu (statt der Icon-Buttons): langer Druck auf eine Sammlungskarte öffnet Umbenennen / Kopieren / Löschen. Kopieren legt eine Duplikat-Sammlung mit allen enthaltenen Aufgaben an (CrudManager.copyCollection, Name „<Name> (Kopie)", neue UIDs/hrefs, offline via Write-Behind-Queue). Umbenennen/Anlegen laufen über die gemeinsamen RenameCollectionDialog/ CreateCollectionDialog. versionCode 45 == versionName 45.

Status 2026-09-09 (44)

Secretary Tasks 44 (versionCode 44): Rebuild auf secretary-common-android v0.18.0. Kein App-Code geändert; der APK enthält jetzt die 412-Auto-Recovery (bedingte PUTs mit veraltetem If-Match-ETag holen einmalig die aktuelle Server-ETag und wiederholen den Schreibvorgang statt des „Notiz wurde auf dem Server geaendert"-Fehlers). versionCode 44 == versionName 44.

Status 2026-09-09 (43)

Secretary Tasks 43 (versionCode 43): Sammlungs-Handling in secretary-common-android + Pending-Marker. Das Sammlungs-Handling (Offline-Merge neu angelegter/gelöschter Sammlungen und die „wartet auf Synchronisierung"-Marker) lebt jetzt gemeinsam in PendingSync (secretary-common-android v0.17.0). TasksViewModel merged Server- und lokale Sammlungen über PendingSync.mergeCollections (neu angelegte Sammlungen erscheinen sofort, pending-gelöschte verschwinden sofort) und berechnet pendingCollectionIds/pendingItemHrefs aus der Write-Behind-Queue (PendingSync.snapshotState); die Aufgabe-Liste und die Sammlungsübersicht zeigen dafür das gemeinsame PendingBadge (SyncProblem-Icon). versionCode 43 == versionName 43.

Status 2026-09-08 (42)

Secretary Tasks 42 (versionCode 42): Konfigurierbares Kontextmenü. Die Aktionen Teilen / Kopieren / Verschieben / Löschen des Langdruck-Menüs lassen sich in den Einstellungen (gemeinsame Sektion „Langdruck-Kontextmenü" aus secretary-common-android v0.16.0) per Checkbox aktivieren/deaktivieren (UiPreferences, Default: alle aktiv). ItemContextMenu blendet deaktivierte Aktionen aus und sperrt das Menü komplett, wenn alle vier aus sind (dann verhält sich die Karte wie eine gewöhnliche klickbare Karte). versionCode 42 == versionName 42.

Status 2026-09-08 (41)

Secretary Tasks 41 (versionCode 41): Einheitliches Langdruck- Kontextmenü. Die Aufgabenkarten nutzen jetzt das gemeinsame ItemContextMenu (secretary-common-android): langer Druck auf eine Karte öffnet ein Menü mit Bearbeiten / Teilen (als .ics via FileProvider) / Kopieren / Verschieben… / Löschen (statt des bisherigen ⋮-Overflow-Menüs mit nur „Verschieben…"). Kopieren legt ein Duplikat in derselben Sammlung an (neue UID + href, CrudManager.copyItem, offline via Write-Behind-Queue, inkl. erneuter NotificationScheduler/System-Kalender-Sync). Verschieben/Löschen laufen über die gemeinsamen MoveCollectionDialog/ConfirmDeleteDialog. Der Langdruck wird per combinedClickable auf der gesamten Karte ausgelöst. versionCode 41 == versionName 41.

Status 2026-09-07 (38)

Secretary Tasks 38 (versionCode 38): Aufgeräumter Header ohne Status-Chip. Der moderne Haupt-Header (ModernAppHeader in secretary-common-android) zeigt keinen Online-Status-Chip mehr; die Aktionsleiste (Sync, Sammlungen, Einstellungen) sitzt jetzt rechts oben direkt im Hero-Header. Die Sammlungen-Schaltfläche erscheint nur, wenn mehrere Sammlungen vorhanden sind. Alle Überschriften verwenden die neue Typewriter-Schrift Special Elite (gebündelt in secretary-common-android, res/font/special_elite.ttf, Apache 2.0). versionCode 38 == versionName 38.

Status 2026-09-07 (37)

Secretary Tasks 37 (versionCode 37): System-Kalender-Spiegel + Teilen/ Importieren. Fällige Aufgaben werden automatisch als Ereignisse (inkl. Terminerinnerung über System-Reminder, sofern Benachrichtigungen aktiv) in den Android-Kalender gespiegelt – in den geschützten Spiegel-Kalender secretary-tasks (Constants in SystemCalendarMirror, nicht löschbar durch das Spiegel-Modul der Kalender-App). Auslöser: Login, Laden/Refresh, jede Änderung/Offline-Sync, App-Start/onResume, Boot und der neue Button „Jetzt in System-Kalender synchronisieren" in den Einstellungen (Abschnitt „Systemkalender"). Der Editor teilt Aufgaben als .ics (VTodo, FileProvider), der App-Start übernimmt empfangene .ics-Dateien (ACTION_VIEW / ACTION_SEND) und öffnet den Editor (TaskSystemSyncAdapter/ TaskSystemScheduler). versionCode 37 == versionName 37.

Status 2026-09-01 (36)

Secretary Tasks 36 (versionCode 36): Einheitlicher Moderner Header – alle secretary-Apps teilen jetzt denselben modernen Haupt-Header (ModernAppHeader in secretary-common-android): Hero mit Monogramm + Status-Chip und darunter die identische Aktionsleiste (Sync, Sammlungen, Einstellungen). Die Aufgabenliste hat damit wieder wie im klassischen Design Sync- und Einstellungen-Buttons direkt im Kopfbereich. versionCode 36 == versionName 36.

Status 2026-09-01 (35)

Secretary Tasks 35 (versionCode 35): Komplett modernisierte Oberfläche (Moderner Stil). Liste, Editor, Sammlungen und Einstellungen haben jetzt einen vollständigen „Moderner Stil"-Zweig nach dem gemeinsamen Editorial-Ledger- Design (secretary-common-android): Serifen-Display-Typo, Pill-artige Karten, Hero-Header mit Monogramm, Status-Chips (ONLINE/OFFLINE/SYNC), Pill-Suchfeld, Pill-FAB, moderne Leerszustände; der klassische Stil bleibt unverändert erhalten. Umschaltung über den globalen Schalter „Moderner Stil"; das Theme liefert im modernen Modus die secretaryModernTypography. versionCode 35 == versionName 35.

Status 2026-08-29 (32)

Secretary Tasks 32 (versionCode 32): Sync-Fortschritt: kein Endlos-Spinner mehr nach Abschluss/Fehler – Fix im gemeinsamen SyncProgressUi (secretary-common-android): sobald ein Sync-Job beendet ist (DONE/FAILED), wird der Spinner/Progressbar nicht mehr gezeichnet – es erscheint nur noch der einmalige Toast. Vorher blieb der Status gesetzt und die Inline-SyncProgressUi zeigte bei beendetem/fehlgeschlagenem Sync dauerhaft einen Spinner bei 0/0. Server-Init-Sync läuft jetzt gegen den aktualisierten secretary-server 0.10.0 mit den /sync/*-Endpunkten. versionCode 32 == versionName.

Status 2026-08-29 (31)

Secretary Tasks 31 (versionCode 31): Server-gesteuerter Sync mit Fortschritt – über den gemeinsamen SyncJobClient (secretary-common-android, POST /sync/start + GET /sync/status/{id}) startet TasksViewModel.runServerSync() beim manuellen Refresh (loadCollections/refresh) für jedes Aufgaben-Collection einen Server-Sync-Job und pollt den aggregierten Fortschritt in [syncStatus]. TaskListScreen zeigt über das gemeinsame SyncProgressUi während des Syncs einen Spinner + Determinat-Progressbar (processed / total) und einmalig einen Toast („Sync abgeschlossen"/„fehlgeschlagen"). versionCode 31 == versionName.

Move between collections: CaldavClient.moveTask(task, targetHref) verschiebt eine Aufgabe per PUT an neuer Stelle (gleicher Dateiname, ohne If-Match) + DELETE an alter. TasksViewModel.moveTask: online mit Cache-Update (upsertTask Ziel / removeTask Quelle) und Listen-Refresh; offline wird der Zug als PutTask (neue href, etag="") + DeleteTask (alte href) in die Pending-Queue eingereiht – mergeWithPending blendet den Alt-Eintrag dank pendingDeletes korrekt aus. UI: Overflow-Menü (⋮) auf jeder Aufgabenkarte mit „Verschieben…“ → Sammlungs-Auswahl-Dialog (nur wenn >1 Collection). versionCode 22.