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.