Secretary Calendar (Android) - Changelog
Every released version of the Secretary Calendar app, newest first.
App documentation: Apps/calendar
Status
Status 2026-10-01 (100)
Secretary Calendar 100 (versionCode 100): 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 99 -> 100.
Status 2026-09-30 (99)
Secretary Calendar 99 (versionCode 99): keine Code-Aenderung - der
Quelltext ist derselbe wie bei 98. Veraendert wurde in diesem Zug nur der
gemeinsame SecretarySettingsScreen in common (SRS common 1.3.0), den auch
Calendar traegt: neue Versionszeile am Ende (aus der PackageInfo des eigenen
Pakets) und die Namensraum-Karte raus, die hier ohnehin nie benutzt wurde -
die Karte Sammlungspräfix bleibt, weil der Wert dort konfigurierbar ist. Am
Calendar-Code aendert sich keine Zeile. 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 98 zu unterscheiden - bei einer APK zusaetzlich ein
versionCode, den ein Geraet nicht neu installiert. versionCode 98 -> 99.
Status 2026-09-30 (98)
Secretary Calendar 98 (versionCode 98): keine Code-Aenderung - der
Quelltext ist derselbe wie bei 97. 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 97 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 97 -> 98.
Status 2026-09-29 (97)
Secretary Calendar 97 (versionCode 97): Statisches App-Symbol + Header
ohne Doppel-Inset. Das Launcher-Symbol ist jetzt ein normales
Adaptive-Icon wie bei den übrigen sieben Apps: [##] in Special Elite, weiß
auf der Kalender-Akzentfarbe #1A6B52 (drawable/ic_launcher_background.xml
mipmap-anydpi-v26/ic_launcher.xml+ generiertemipmap-*/ic_launcher_foreground.png). Das bisherige dynamische Symbol (CalendarDayIconalsdrawable/ic_launcher_foreground.xml, das nachts um Mitternacht die aktuelle Tageszahl als[TT]neu zeichnete) ist entfernt — ein Symbol, das sich täglich ändert, ist in einem Launcher voller fester Symbole nicht wiedererkennbar. Die Vorschau-/Generierungsquelletools/generate-icons.shführtcalendarjetzt als regulären Eintrag statt eines Sonderfalls. Dascalendar_icons_dynamic-Array bleibt unverändert (zeigt das gemeinsame Symbol statt echter Tages-Monogramme). Außerdem sitzt derAppHeaderjetzt imtopBar-Slot desScaffoldstatt als erstes Kind der Inhalts-Column: dadurch wurde der Statusleisten-Inset doppelt angewandt (einmal überScaffold-Content-Padding, einmal überstatusBarsPadding()imHeroHeader) und über dem Header stand mehr Platz als in den anderen Apps. versionCode 96 -> 97.
Status 2026-09-16 (89)
Secretary Calendar 89 (versionCode 89): Monats-Raster entfernt – die
fortlaufende Tagesliste ist jetzt die einzige Hauptansicht. Das zwischen
Liste und Monats-Raster umschaltbare Raster (Hoch-Wischen) ist vollständig
entfernt: showGrid-Zustand und der Wisch-Geste-Toggle (CalendarListScreen),
die bedingte Raster-Renderung mit CalendarMonthGrid, die Komponenten
CalendarMonthGrid/DayCell (GRID_ROWS/GRID_COLS-Konstanten) sowie die
zugehörigen Raster-Einstellungen: Sektion „Raster" im SettingsScreen
(ColorSelect für Heute/Auswahl, Titelgröße, Zeilenumbruch) und
CalendarRepository.gridTodayColor/gridSelectedColor/gridTitleSize/
gridLineBreak + save*-Setter. Die Horizontal-Wisch-Navigation
(previousMonth/nextMonth) bleibt erhalten (verschiebt das Listenfenster um
den Monat ±12 Monate) und der Monogramm-Tipp scrollt weiterhin zur heutigen
Zeile; die nicht mehr benötigten Imports (sp, luminance, TextAlign,
KeyboardArrowLeft/Right, DateRange, Tune, Switch,
CalendarRepository in CalendarListScreen) sind entfernt, der Übersichts-
und Listenaufbau ist unverändert. versionCode 88 -> 89.
Status 2026-09-16 (88)
Secretary Calendar 88 (versionCode 88): Offline-Sync-Engine
(secretary-common-android v0.30.0). backgroundSync und refreshFromServer
nutzen jetzt pro Kalender die gemeinsame OfflineSyncEngine (CrudItemRemote
GOfflineStore+CalendarCodec) stattcrud.listItemsRemote+store.setItems: Server-Abruf, Rehome-Upload lokaler UIDs, Pending-Delete-Filter, Prepare-Null-Erhalt und Cache-Ersatz liegen in common. Die inkrementelle Übersichtsaktualisierung bleibt erhalten (je KalenderremoveAll+addAlldesSynced-Ergebnisses,setEventsnach jedem Kalender – Termine laufender Fetches bleiben sichtbar, kein „Termine verschwinden beim Öffnen" [v68]). BeimOffline-Ergebnis (Einzel-Kalender) bleibt der Cache-Stand stehen und der Sync bricht wie bisher mit_isOffline=trueab; in der Übersicht wird ein nicht erreichbarer Kalender weiterhin übersprungen (DavException),_isOfflinewird danach wie bisher gesetzt. Recurrence-Cache-Prune,saveLastSyncTimestamp,flushPending,recomputePendingundCalendarSystemScheduler.ensureSyncinglaufen unverändert. View stabil beim Sync (kein Leeren/Neubau). versionCode 87 -> 88.
Status 2026-09-13 (87)
Secretary Calendar 87 (versionCode 87): Kategorie-Parsing gehärtet
(secretary-common-android v0.26.0). VEventParser schreibt CATEGORIES
jetzt RFC-5545-escaped (Komma in einem Kategorie-Wert als \,) und liest die
Liste nur noch an unescaped-gespeicherten Kommas; jedes Token wird dabei
dekodiert. Vorher wurde bei jedem Komma geschnitten – eine Kategorie, deren
Value ein Komma enthielt (z. B. RFC-escapte \,-Werte aus importierten
.ics-Dateien), wurde also in zwei Kategorien zerrissen. Bestehende, von den
alten Writern nie escapte Daten werden identisch gelesen. versionCode 86 -> 87.
Status 2026-09-12 (83)
Secretary Calendar 83 (versionCode 83): Terminliste als fortlaufende,
typografische Tagesliste (Standardansicht) – mit Vergangenheit, Wortumbruch
und „heute"-Navigation. Die Hauptansicht startet jetzt in der Liste
statt im Monats-Raster (Hoch-Wischen togglet weiterhin zwischen Liste und
Raster). Die Liste ist eine kontinuierliche Tagesliste im list.txt-Format:
Wochentag TT\tTermin…, sie beginnt am ersten Tag des 12. Vormonats des
angezeigten Monats und läuft bis zum Ende des 12. Folgemonats – Scrollen in
Vergangenheit und Zukunft funktioniert frei. Monatsnamen erscheinen
natürlich in der Liste und bleiben beim Scrollen oben pinnen
(stickyHeader). Jedes Monatsband ist halbton-verschattet (alternierende
ISO-Wochen, Wochenende-Stempel in Fehlerfarbe, Heute mit *-Marker +
Unterstreichung in Akzentfarbe). Termine: Wortumbruch mit automatischen
Zeilenumbrüchen (keine Ellipsen mehr); mehrere Termine pro Tag liegen als
mehrere Zeilen untereinander, der Tages-Stempel („Sa 12") erscheint nur
einmal pro Tag (oben, auf Höhe der ersten Eintragszeile); der Farbbalken
zieht sich über die volle Eintragszeile (IntrinsicSize). Beim Öffnen und
bei jedem Tipp auf das Monogramm (Tageszahl) im Header scrollt die Liste
programmatisch zur heutigen Zeile (rememberLazyListState#scrollToItem,
Index = vergangene Tage + Monatsköpfe). Monats-Köpfe und Tagesstempel nutzen
die Typewriter-Schrift Special Elite. Umsetzung im CalendarViewModel:
listEventsByDay (Occurrence-Expansion über das ganze Listenfenster inkl.
Serien/All-Tag-Terminen), listStart/listEnd (Monat ± 12 Monate,
LIST_PAST_MONTHS/LIST_MONTHS_AHEAD); CalendarListScreen rendert pro Tag
eine Zeile (leere Tage nur Stempel) mit dem bestehenden Langdruck-Kontextmenü,
Antippen des Tages öffnet die Tagesansicht. versionCode 83 == versionName 83.
Status 2026-09-12 (85)
Secretary Calendar 85 (versionCode 85): System-Integration wie der
LineageOS-Kalender: "Termin hinzufügen"-Intents + Terminerinnerungen
(EVENT_REMINDER + Benachrichtigungen). Der Kalender beantwortet jetzt die
Standard-Kalender-Intents, die andere Apps (und die System-Kalender-App)
senden, und zeigt Terminerinnerungen als Benachrichtigung. Intents
(analog zum Etar-Manifest des LineageOS-Kalenders): neue Filter auf
MainActivity + neuer Dispatcher handleCalendarIntent – ACTION_INSERT/
ACTION_EDIT auf vnd.android.cursor.dir/event und vnd.android.cursor.item/event
("Termin hinzufügen" aus Drittanbieter-Apps mit Titel/Ort/Beschreibung/
BeginTime/EndTime/allDay; bei item-URIs wird der vorhandene Termin im Cache
aufgelöst und geöffnet), ACTION_VIEW auf vnd.android.cursor.item/event
(Termin aus einer URI öffnen, z. B. Tipp auf eine Erinnerung), ACTION_VIEW
auf time/epoch (content://com.android.calendar/time/<epoch> springt zur
Tagesansicht des Datums), zusätzliche ICS-Mime-Typen text/x-vcalendar +
application/ics, Kategorie APP_CALENDAR auf dem Launcher-Intent.
Umsetzung: MainActivity (createEventFromInsert/openEventFromUri –
ContentUris.parseId, resolve über CALENDAR_ID→NAME→Cache),
CalendarViewModel (pendingEditorEvent/pendingFocusDate-Endpunkte,
requestNewEventFromInsert, openEventFromExternal, consume…), NavGraph
(Login-geschützte LaunchedEffects navigieren zu EDIT bzw. day/{date}).
Terminerinnerungen: der Sync-Adapter spiegelt die VALARM-Erinnerungen als
CalendarContract.Reminders-Zeilen (mit caller_is_syncadapter, da Konto-
Zeilen schreibgeschützt sind; Mapping NOTIFICATION→METHOD_ALERT, EMAIL→
METHOD_EMAIL, SMS→METHOD_SMS) und setzt Events.HAS_ALARM; der neue
system/AlertReceiver (exportiert, Filter EVENT_REMINDER +
BOOT_COMPLETED + MY_PACKAGE_REPLACED) zeigt die fällige Erinnerung als
Benachrichtigung (Channel event_reminders, Kalenderfarbe, Zeit/Ort;
Tipp öffnet den Termin via item/event-Intent) und stößt nach Boot den
System-Sync neu an (der Provider plant die Wecker selbst neu). Neue
Berechtigungen POST_NOTIFICATIONS (wird zur Laufzeit zusammen mit den
Kalender-Berechtigungen erfragt), RECEIVE_BOOT_COMPLETED, VIBRATE.
Weiterhin bewusst nicht übernommen (Out-of-Scope): Google-
event-Deeplinks, Widgets, globale Suche und PROVIDER_CHANGED-Receiver
(Schleifen-Risiko mit dem eigenen Sync-Adapter). versionCode 85 ==
versionName 85.
Status 2026-09-12 (86)
Secretary Calendar 86 (versionCode 86): Alle verbliebenen Etar-/LineageOS-
Integrationen – exakte Wecker, Schummern + Schnellantwort, globale Suche,
App-Widget, App-Shortcuts + dynamische Icons, Batterie-Optimierungs-Ausnahme
(alles aus dem Etar-Manifest außer Google-Calendar-Deeplinks). Exakte
Wecker: neuer system/AlarmScheduler plant die VALARM-Erinnerungen als
setExactAndAllowWhileIdle-Wecker (bei entzogener SCHEDULE_EXACT_ALARM-
Berechtigung API 31+ Fallback auf 10-Minuten-setWindow); Wiederholungen
über Recurrence.nextAfter, UID→System-_id per SYNC_DATA3; Re-Arm bei
jedem Sync, nach BOOT_COMPLETED/MY_PACKAGE_REPLACED/TIME_SET/
LOCALE_CHANGED und nach jedem Auslösen; Cancel/Re-Arm über eine
alarm_schedule-Präferenz (JSON) mit RequestCode-Mapping. Schummern +
Schnellantwort: AlertReceiver beantwortet zusätzlich ACTION_FIRE
(intern) und ACTION_SNOOZE; die Benachrichtigung hat jetzt die Aktionen
Schummern (10 min, eigener Wecker) und Antworten →
alerts/QuickResponseActivity (Dialog mit Teilnehmer-E-Mail-Adressen, Tipp
versendet die Einladung als .ics per E-Mail über den FileProvider).
Globale Suche: search/SearchActivity (per android.app.default_searchable
ACTION_SEARCHregistriert, durchsucht den Offline-Cache nach Titel/Ort/ Beschreibung/Kategorien/Teilnehmern, Treffer öffnen den Termin im Editor) mitCalendarRecentSuggestionsProvider– eigene Implementierung (MatrixCursor + SharedPreferences), daSearchRecentSuggestions(Provider)in der reduzierten SDK-Jar der Debian-Builds fehlt;searchable.xmlmit Recent-Suggestions. App-Widget:widget/CalendarAppWidgetProvider+CalendarAppWidgetService(RemoteViews-Factory, nächste 12 Termine inkl. nächster Serien-Occurrence, Farbbalken je Kalender); Tipp auf eine Zeile springt percontent://com.android.calendar/time/<epoch>-Fill-In zur Tagesansicht (time/epoch-Intent wird jetzt auch ohne MIME-Typ erkannt, Epoch ≤ 0 = „heute"), Tipp auf den Kopf öffnet die App; Widget-Update nach jedem Sync. App-Shortcuts:@xml/shortcutsmit „Neuer Termin" (INSERT) und „Heute" (time/0); dazu das dynamische Kalender-Icon-Array (org.beowulf.secretary.calendar.dynamic_icons+com.teslacoilsw.launcher.calendarIconArray, 31 Einträge aufs bestehende Symbol). Batterie-Optimierung: Einstellungen-Sektion „Alarme" mit Button „Battery optimization…" (ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Fallback auf die Optimierungs-Einstellungen; StatusisIgnoringBatteryOptimizationswird angezeigt). Der Sync-Adapter re-armiert die Wecker und aktualisiert das Widget nach jedem Spiegel-Durchlauf. Bewusst nicht übernommen (Abweichungen, die über „alle außer Google-Deeplinks" hinausgehen):USE_EXACT_ALARMfehlt (Play-Policy, nur Wecker-Apps zulässig),READ_CONTACTSbleibt ungenutzt und ungedeclared, kein Foreground-Service nötig, EtarsAlertActivityist durch die Heads-up-Benachrichtigung des bestehenden Channels ersetzt, und die dynamischen Kalender-Icons zeigen das bestehende Symbol statt echter Tages-Monogramme. versionCode 86 == versionName 86.
Status 2026-09-09 (80)
Secretary Calendar 80 (versionCode 80): Alte Kalender-Aktivierung entfernt
(kein doppelter Übersichts-Bereich mehr). Die Einstellungen hatten nach v79 zwei
Listen, die sich auf der Übersicht überlagerten: der alte „Kalender"-Block
(aktivieren/deaktivieren, welche Sammlungen die App überhaupt übernimmt) und der
neue „Übersicht"-Block („In Übersicht anzeigen"). Die alte Sammlungs-
Aktivierung ist obsolet (die Übersicht steuert jetzt per Kalender, was
eingemischt wird; deaktivieren hieße nur noch „nicht angezeigt"). Entfernt:
CalendarChecklistSection aus dem SettingsScreen, im CalendarViewModel die
Zustände _disabledCalendarIds/disabledCalendarIds, toggleCalendarEnabled
und die Disabled-Logik in deleteCalendar, sowie
CalendarRepository.enabledCalendarIds/saveEnabledCalendarIds
(Präferenzschlüssel enabled_calendars wird nicht mehr gelesen; vorhandene
Einträge sind wirkungslos). applyEnabledFilter übernimmt jetzt einfach alle
bekannten Kalender; enabled-Flag der Collections bleibt (System-Sync
VISIBLE/SYNC_EVENTS) immer aktiv. Die Einstellungen zeigen nur noch die Sektion
„Übersicht". versionCode 80 == versionName 80.
Status 2026-09-09 (79)
Secretary Calendar 79 (versionCode 79): Übersicht-Filter + Kalender-
Farben + Spezialsammlungen in secretary-common-android v0.20.0. In den
Einstellungen gibt es jetzt eine neue Sektion „Übersicht": pro aktivem
Kalender eine Checkbox „In Übersicht anzeigen" (overview_excluded_calendars
-CalendarRepository, _overviewExcludedIds im CalendarViewModel,
toggleIncludeInOverview). Ausgeschaltete Kalender bleiben im Kalender-Editor
und in der Synchronisation, werden aber nicht mehr in die zusammengefügte
Übersicht gemischt (loadEvents, backgroundSync und refreshFromServer
nutzen das neue overviewCalendars()-Filter). Kalender-Farben: die
Kalenderlisten-Karte hat jetzt im Langdruck-Menü den Eintrag Farbe
(ergänzt um den gemeinsamen onColor-CollectionContextMenu-Parameter), der
den gemeinsamen ColorSelectDialog öffnet (Palette + „Keine Farbe");
setCalendarColor setzt die Farbe via CrudManager.setCollectionColor
(PROPPATCH calendar-color, Apple-Namespace) mit Offline-Fallback
(setCollectionColorOffline → GAction.SetCollectionColor in der
Write-Behind-Queue). PROPFIND liefert calendar-color jetzt mit und
färbt die Kalender-Akzentfarbe + Termin-Balken entsprechend. Der
Übersicht-Eintrag nutzt SpecialCollections.OVERVIEW_LABEL aus dem
gemeinsamen Code. versionCode 79 == versionName 79.
Status 2026-09-09 (78)
Secretary Calendar 78 (versionCode 78): Fix: Start-Crash (NullPointerException). Beim
App-Start stürzt die App sofort mit NullPointerException: Attempt to invoke interface
method 'void MutableStateFlow.setValue(Object)' on a null object reference in
CalendarViewModel.recomputePending (Zeile 323) ab. Ursache: Der init-Block startet
viewModelScope.launch { loadStartupCache() }, das auf dem Main-Thread (Dispatchers.Main.immediate)
synchron innerhalb des Konstruktors ausgeführt wird; loadStartupCache →
recomputePending schrieb in _pendingCollectionIds, das erst unterhalb des
init-Blocks deklariert war und zu diesem Zeitpunkt noch null ist. Fix: Die
_pendingCollectionIds-/pendingCollectionIds-Deklaration in den View-State-Block
vor dem init-Block verschoben (alle übrigen StateFlows, die der Startpfad
berührt, liegen darunter — scan der nachfolgenden Felder ergab keine weiteren
Kandidaten). versionCode 78 == versionName 78.
Status 2026-09-09 (77)
Secretary Calendar 77 (versionCode 77): Kalender-Sammlungen: Langdruck-
Kontextmenü + Anlegen (secretary-common-android v0.19.0). Die
Kalender-Auswahl (CollectionsScreen) zeigt alle aktiven Kalender als
Karten mit Long-Press-Kontextmenü (CollectionContextMenu):
Umbenennen / Kopieren / Löschen. Neue CalendarViewModel-Aktionen
createCalendar/renameCalendar/copyCalendar/deleteCalendar über den
gemeinsamen CrudManager (offline via Write-Behind-Queue, „<Name>
(Kopie)" inkl. aller Termine), dazu pendingCollectionIds-Marker
(PendingSync.snapshotState) und collectionBusy-Guard gegen
überlappende Operationen. Neuer FAB „Kalender" legt eine neue
Kalender-Sammlung an (CreateCollectionDialog); umbenennen/löschen über
die gemeinsamen Dialoge. Die Übersicht-Zeile („Übersicht", Anzahl der
Ereignisse) bleibt ohne Kontextmenü wie bisher. versionCode 77 ==
versionName 77.
Status 2026-09-09 (76)
Secretary Calendar 76 (versionCode 76): 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 76 == versionName 76.
Status 2026-09-08 (75)
Secretary Calendar 75 (versionCode 75): 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 75 == versionName 75.
Status 2026-09-08 (74)
Secretary Calendar 74 (versionCode 74): Gemeinsames Kontextmenü für
Termine (Kopieren/Verschieben/Teilen/Löschen). Termine in der Terminliste
(AppointmentList, CalendarListScreen) und der Tagesansicht (DayScreen)
haben jetzt das gemeinsame Langdruck-Kontextmenü (ItemContextMenu aus
secretary-common-android v0.15.0) statt des einzelnen Kopier-Icons:
Bearbeiten (Editor), Teilen (ICS via Share-Sheet, bestehende
shareEventAsIcs), Kopieren (sofortiges Duplikat in derselben
Kalender-Collection via CrudManager.copyItem/copyItemOffline – neue UID +
neuer href), Verschieben… (MoveCollectionDialog, nur bei mehreren
Kalendern; CrudManager.moveItem/moveItemOffline mit Recurrence-Cache- und
System-Sync-Refresh) und Löschen (ConfirmDeleteDialog). Kopfzeile und
FAB bleiben unverändert. Version 74, versionCode 74 == versionName 74.
Status 2026-09-08 (73)
Secretary Calendar 73 (versionCode 73): Fix: Übersicht leert sich nach
Sync (calendarId war immer leer). CalendarCodec.decodeItem
(secretary-common-android) setzte die calendarId von geladenen Terminen nie
– alle Events liefen mit calendarId="". Damit greifen in der Übersicht beide
Filter der Refresh-Schleife ins Leere: removeAll { calendarId == cal.id }
entfernt nichts (Termine werden doppelt eingefügt, 1220 → 2409/2440),
und das Abschluss-Pruning filter { calendarId in known } verwirft alles
(Übersicht springt auf 0 Termine, ohne laufende Berechnung zu zeigen –
genau der gemeldete Effekt „nach Sync 0 Termine, kein Rechen-Hinweis"). Fix:
CalendarCodec.decodeItem leitet die calendarId jetzt aus dem Resource-Href
ab (/calendars/calendar-main/x.ics → calendar-main); damit matchen
Dedupe und Pruning korrekt, die Übersicht bleibt gefüllt und heilt sich beim
nächsten Sync (Cache-Einträge mit leerer calendarId werden durch getaggte
ersetzt). Zusätzlich bekam der Unit-Test VEventTest die fehlenden Imports
(Attendee, Reminder, ReminderMethod, EventStatus, BusyFree – die
Tests kompilierten deshalb nie) plus Regressionstest
decodeItemSetsCalendarIdFromHref. Alle 55 Unit-Tests grün.
versionCode 73 == versionName 73.
Status 2026-09-07 (70)
Secretary Calendar 70 (versionCode 70): Aufgeräumter Header ohne
Status-Chip. Der moderne Haupt-Header (ModernAppHeader in
secretary-common-android) zeigt keinen Online-Status-Chip mehr; die
Aktionsleiste (Sync, Kalender, Einstellungen) sitzt jetzt rechts oben
direkt im Hero-Header. Die Kalender-Schaltfläche erscheint nur, wenn mehrere
Kalender 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 70 == versionName 70.
Status 2026-09-07 (69)
Secretary Calendar 69 (versionCode 69): Kalender-Auswahl in den
Einstellungen. Unter Einstellungen gibt es jetzt eine Checkliste aller auf
dem Server gefundenen Kalender-Sammlungen. Jede Sammlung kann per Checkbox
aktiviert/deaktiviert werden: aktive Kalender erscheinen in der
Kalenderliste (CollectionsScreen) und werden in die „Übersicht" gemischt,
deaktivierte werden aus Liste und Übersicht ausgeblendet und nicht mehr
synchronisiert. Umsetzung: CalendarRepository persistiert die deaktivierten
Ids (enabled_calendars), der CalendarViewModel führt die gefundenen Sammlungen
als allCalendars und die aktivierten als calendars (applyEnabledFilter),
nur aktive Kalender werden geladen/abgefragt (backgroundSync,
refreshFromServer); neue toggleCalendarEnabled(calendarId, enabled) ist für
die UI gedacht; wird der aktuell gewählte Kalender deaktiviert, springt die
Ansicht zur Übersicht zurück. Neue CalendarChecklistSection in SettingsScreen
(klassisch + modern). versionCode 69 == versionName 69.
Status 2026-09-07 (68)
Secretary Calendar 68 (versionCode 68): Fix: Termine verschwinden beim
Öffnen und kommen ~30 s später wieder. Beim App-Start lief backgroundSync()
(bzw. bei manueller Aktualisierung refreshFromServer()) in der
Übersichtsansicht: die kombinierte Event-Liste wurde in jedem
Durchlauf mit leerer Liste neu aufgebaut und nach jedem abgeschlossenen
Kalender-Einzelfetch als setEvents(all) veröffentlicht. Dadurch ersetzte der
erste Kalender die vollständig geladene Cache-Ansicht, und alle Termine der
noch nicht gefetchten Kalender verschwanden, bis deren Fetch (≈30 s) fertig
war – „mehr als die Hälfte der Einträge verschwindet beim Öffnen und kommt
später wieder, ohne Info was die App macht". Fix in CalendarViewModel: Die
aktuelle Liste wird als Basis übernommen (statt leere Liste) und die frisch
geladenen Termine je Kalender in-place ersetzt bzw. ergänzt
(removeAll { calendarId == cal.id } + addAll), sodass Einträge laufender
Fetches sichtbar bleiben; nach dem Durchlauf werden nur noch verwaiste Termine
nicht mehr vorhandener Kalender entfernt. Zusätzlich setzt backgroundSync()
jetzt _isLoading, sodass der Banner „Kalender werden synchronisiert…"
angezeigt wird (vorher kein Hinweis, dass ein Hintergrund-Sync läuft).
versionCode 68 == versionName 68.
Status 2026-09-07 (67)
Secretary Calendar 67 (versionCode 67): Spiegel-Kalender geschützt.
Der Sync-Adapter löscht Kalender nicht mehr, die den geschützten Namen der
Spiegel-Kalender secretary-tasks / secretary-journal tragen
(SystemCalendarMirror.PROTECTED_NAMES in secretary-common-android). Damit
werden die von den Apps Secretary Tasks und Secretary Journal automatisch
gepflegten Kalender nie fälschlich mit entfernt. versionCode 67 ==
versionName 67.
Status 2026-09-03 (66)
Secretary Calendar 66 (versionCode 66): Monats-Raster ohne experimentelle
Karussell-Navigation. Der zwischenzeitlich ausgebaute experimentelle
Karussell-Code wurde wieder entfernt – die Dateien CalendarCarousel.kt und
HorizontalDayTimeline.kt wurden gelöscht und alle betroffenen Quelldateien auf
den Monats-Raster-Stand von v56 zurückgesetzt (echtes Revert, kein Rebuild):
CalendarListScreen.kt (Monats-Raster mit CalendarMonthGrid/DayCell,
6×7-Tage-Gitter Mo–So, heute/ausgewählt hervorgehoben, Raster-Farben/Textumbruch
aus den Einstellungen, Quer-Wischen blättert den Monat), SettingsScreen.kt,
CalendarRepository.kt und CalendarViewModel.kt – also die klassische
Kalender-Rasteransicht wie im LineageOS-Kalender. Die experimentellen
Karussell-Zustände (CarouselLevel, CalendarNavigatorState,
CarouselTileSettings) und die carousel_*/compress_night_hours/
work_start_hour/work_end_hour-Einstellungen entfallen wieder. versionCode 66
== versionName 66.
Status 2026-09-02 (56)
Secretary Calendar 56 (versionCode 56): Zurück zum modernen
Monats-Raster (echtes Revert der v54-v55-Timeline/Gantt). Die vier von der
Timeline-Umstellung (v54/v55) betroffenen Quelldateien wurden auf den Stand
von v53 zurückgesetzt – also dem letzten Release mit Monats-Raster und
mit modernem Stil (modernes UI seit v51): CalendarListScreen.kt
(Monats-Raster mit CalendarMonthGrid/DayCell, 6×7-Tage-Gitter Mo–So,
heute/ausgewählt hervorgehoben, Raster-Farben/Textumbruch/Schriftgröße aus den
Einstellungen, Quer-Wischen blättert den Monat, Hoch-Wischen togglet zwischen
Raster und Terminliste), SettingsScreen.kt (Raster-Einstellungen wieder
eingeführt), CalendarRepository.kt (gridTodayColor, gridSelectedColor,
gridTitleSize, gridLineBreak) und CalendarViewModel.kt (ohne die
Timeline-Zustände timelineDays/timelineToday). Timeline/Gantt-Komponenten
(WeekTimeline, TimelineDayRow, WeekGanttTimeline), die Timeline-
Einstellungen (Tag-/Freizeit-/Eintrags-Höhe, Eintrags-Schriftgröße) und der
timeline_*-Zustand im ViewModel entfallen wieder. versionCode 56 ==
versionName 56.
Status 2026-09-02 (55)
Secretary Calendar 55 (versionCode 55): Timeline umgebaut zu einer
sanft scrollenden Tagesliste (auf Wunsch statt Wochen-Paging). Die
Hauptansicht zeigt jetzt eine LazyColumn mit einer fortlaufenden
Tagesliste (Tag-Zeile in vorgegebener Höhe, heute hervorgehoben, initial
auf heute gescrollt), eine Woche passt ohne Wischen auf den Bildschirm.
Jede Tageszeile hat links die Tageskennung (Wochentag + Tag) und rechts eine
horizontale 24-h-Timeline: eine dünne, mittige Freizeit-Linie über die
ganze Breite; reservierte Zeiten erscheinen als dicke, farbige Balken an
der echten Uhrzeit (Start–Dauer, Endzeit-Clipping auf 0–24 h) mit dem
Termin-Titel im Balken (Schriftgröße konfigurierbar). Ganztags-Termine
als Balken über die volle Zeile. Navigation: Antippen eines Balkens öffnet
den Termin, Antippen einer Tageszeile öffnet die Tagesansicht, „Heute"
springt zur heutigen Zeile; hoch-Wischen toggelt zwischen Timeline und der
bestehenden Terminliste. Neu konfigurierbar in den Einstellungen („Timeline"):
Tag-Höhe, Freizeit-Höhe, Eintrags-Höhe und Eintrags-Schriftgröße
(SharedPreferences in CalendarRepository, Werte timeline_day_height,
timeline_free_height, timeline_entry_height, timeline_entry_font_size).
Die alten Raster-Einstellungen entfallen. CalendarViewModel liefert dazu
timelineDays (Termine für ±180 Tage um timelineToday) mit refreshTimeline()
(expandiert Wiederholungen, refresht nach Laden/Speichern/Löschen) und
goToToday(). Zusätzlich .fossil-settings/ignore-glob um */build/ und
app/build/ ergänzt (Build-Artefakte). versionCode 55 == versionName 55.
Status 2026-09-02 (54)
Secretary Calendar 54 (versionCode 54): Wochen-Gantt/Timeline-Ansicht –
die Monats-/Listenansicht hat ein neues Raster-Layout: statt des
Monats-Rasters zeigt die Hauptansicht (Timeline-Modus) jetzt eine
vertikale Wochen-Gantt – horizontale Achse = 7 Wochentage (Start montags,
Tageskopf mit Wochentag + Datum, Wochenende/Farbe hervorgehoben), vertikale
Achse = Stunden von 06:00–22:00 mit Stundenlineal links und Stundenlinien.
Termine werden als farbige Gantt-Balken an ihrer echten Startzeit/Dauer
positioniert (Endzeit-Clipping auf das sichtbare Fenster); Ganztags-Termine
als Balken über die volle Spaltenhöhe. Navigation: Pfeiltasten/Quer-Wischen
blättern die Woche, „Heute" springt zur aktuellen Woche; Antippen eines
Balkens öffnet den Termin, Antippen eines leeren Slots öffnet die Tagesansicht.
Hoch-Wischen toggelt zwischen Timeline und der bestehenden Terminliste (die
Monats-/Listenansicht bleibt als Listen-Modus erhalten). Umsetzung: neues
WeekGanttTimeline + DayGanttColumn in CalendarListScreen.kt; im
CalendarViewModel neue Zustände selectedWeekStart/weekEvents/
isWeekLoading und Methoden navigateWeek, goToWeekOf, goToTodayWeek,
refreshWeek (expandiert Wiederholungen über recurrenceCache.occurrences);
setEvents refresht die Woche nach jedem Laden/Speichern/Löschen. Das
Monats-Raster (CalendarMonthGrid/DayCell) wurde entfernt; die
Raster-Einstellungen (Farben/Wortumbruch/Schriftgröße) entfallen.
versionCode 54 == versionName 54.
Status 2026-09-02 (53)
Secretary Calendar 53 (versionCode 53): Termin teilen (ICS) – der
Termin-Editor hat jetzt für bestehende Termine ein Teilen-Icon (klassische
TopAppBar und moderner Header), das den Termin als .ics über das
Android-Share-Sheet versendet. Umsetzung: neue
CalendarViewModel.shareEventAsIcs(event) serialisiert den Termin über
VEventParser.serialize in eine Datei unter cacheDir/exports/ und liefert
eine FileProvider-Content-URI; die UI startet einen ACTION_SEND-Intent mit
MIME text/calendar und FLAG_GRANT_READ_URI_PERMISSION. Der ICS-Import
(ACTION_VIEW/SEND) bleibt unverändert erhalten. versionCode 53 ==
versionName 53.
Status 2026-09-01 (52)
Secretary Calendar 52 (versionCode 52): 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, Kalender,
Einstellungen). Die Monats-/Listenansicht behält ihren gewohnten
Sync/Kalender/Einstellungen-Block, jetzt aus der gemeinsamen Komponente.
versionCode 52 == versionName 52.
Status 2026-09-01 (51)
Secretary Calendar 51 (versionCode 51): Komplett modernisierte Oberfläche (Moderner Stil). Monats-/Listenansicht, Tagesansicht, Termin-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), Kalender-Raster im Karten-Container, Pill-Termin-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 51 == versionName 51.
Status 2026-08-31 (47)
Secretary Calendar 47 (versionCode 47): Tagesansicht: neuer Termin startet
auf dem gewählten Tag + Endzeit folgt automatisch. Der FAB der Tagesansicht
legt den neuen Termin jetzt mit Startdatum auf dem ausgewählten Tag an
(createNewEvent(date)), statt auf dem heutigen Datum – Zeit default 09:00,
Dauer gemäß Einstellung. Im Editor wird das Enddatum/die Endzeit automatisch
auf den korrekten Abstand zum Start gesetzt, sobald das Startdatum oder die
Startzeit geändert, eingegeben oder vorbefüllt wird: Der ursprüngliche
Zeitabstand (baseIntervalMinutes) bzw. die Tagesdifferenz (baseAllDayDays)
wird einmal aus dem vorbefüllten Termin erfasst und auf jede Start-Änderung
angewendet (LaunchedEffect), ohne eine explizite End-Änderung zu
überschreiben. Version 47, versionCode 47 (VersionName und versionCode immer
identisch).
Status 2026-08-31 (46)
Secretary Calendar 46 (versionCode 46): Tagesansicht-FAB + ICS-Import aus
E-Mails. Die Tagesansicht (DayScreen) hat jetzt wie die Monats-/Listenansicht
einen Floating-Action-Button zum Anlegen eines neuen Termins
(onNewEvent → createNewEvent → Editor). Außerdem funktioniert das Hinzufügen
eines Termins aus einer E-Mail-Anlage: die App deklariert schon
ACTION_VIEW/text/calendar; MainActivity liest jetzt die eingegangene
.ics-Anlage (onNewIntent/onCreate, contentResolver.openInputStream)
und übergibt sie an das neue CalendarViewModel.importFromIcs(), das den
VEVENT per VEventParser.parseMultiple parst, dem resolved Kalender zuordnet,
neue UID vergibt und den ersten Termin im Editor öffnet – Speichern persistiert
ihn über den normalen saveEvent-PUT-Pfad. Zusätzlich der determinat
Recurrence-Fortschrittsbalken, der sauber bis 100% füllt
(recurrenceProgress, Float) statt endlos zu schleifen. Version 46,
versionCode 46 (VersionName und versionCode immer identisch).
Status 2026-08-30 (45)
Secretary Calendar 45 (versionCode 45): Termin-Editor: Kalender-Auswahl,
gültige Zeitspannen, Editor-Settings; Recurrence-Berechnung beschleunigt +
mit Fortschrittsanzeige. Der Edit-Dialog hat jetzt ein Kalender-Dropdown –
neue Termine landen nicht mehr „im Leeren" (vorher wurde ohne
Kalender-Auswahl eine PUT auf /calendars/<uid>.ics gesendet, die der Server
als verwaiste Datei am Storage-Root ablegte; solche Termine waren in keiner
Kollektions-Liste sichtbar). Zusätzlich greift eine Fallback-Logik im
CalendarViewModel (resolveCalId): fehlende Kalender-ID → aktueller
Kalender → erster Kalender, für alle Save/Delete/Recurrence-Pfade. Ende-vor-
Anfang-Spannen werden abgefangen: wenn das Enddatum vor dem Anfangsdatum liegt,
wird die Dauer automatisch auf die Standardlänge gesetzt; das Startdatum-
Picker rückt das Enddatum mit. Neue Einstellung „Standardlänge (Minuten)"
(default 60) steuert die Länge neuer Termine (createNewEvent, Edit-Dialog,
Auto-Korrektur). Die Recurrence-Wiederberechnung läuft jetzt auf
Dispatchers.Default statt auf dem Main-Thread (kein UI-Freeze mehr beim
Monatswechsel/Refresh) und zeigt in der Monatsansicht eine
„Wiederholungen werden berechnet…"-Progressbar (isComputingRecurrences).
Der RecurrenceCache verlängert Serien nun inkrementell ab der letzten
berechneten Occurrence (lastOccurrenceInstant) statt jede Serien-Wand von
DTSTART neu zu laufen. Version 45, versionCode 45 (VersionName und versionCode
immer identisch).
Status 2026-08-30 (44)
Secretary Calendar 44 (versionCode 44): Termin kopieren – neue
Kopier-Funktion für Termine. Jede Termin-Zeile in der Tagesansicht
(DayScreen) und der Terminliste (CalendarListScreen) hat jetzt ein
Kopier-Icon, das den Edit-Dialog (EventEditScreen) vorbefüllt als neuen
Termin öffnet: neue UID, leere href/etag, alle übrigen Felder (Titel, Ort,
Beschreibung, Zeiten, Wiederholung, Status, …) übernommen. Speichern legt ein
Duplikat an ohne das Original anzufassen. Umsetzung: neue copyEvent(event)
im CalendarViewModel (erzeugt die Kopie und selektiert sie), Callbacks
onCopyEvent in Tages- und Monats-Listen-Ansicht, Verdrahtung im NavGraph.
Version 44, versionCode 44 (VersionName und versionCode immer identisch).
Status 2026-08-30 (43)
Secretary Calendar 43 (versionCode 43): System-Kalender zeigt Termine
weiterhin 2–3fach – Wurzelursache: sich überlappende Sync-Läufe. Jeder
ensureSyncing()-Aufruf startet einen direkten Background-Thread-Mirror
und einen Framework-requestSync; mehrere Trigger feuern kurz
hintereinander (Kaltstart, Login, backgroundSync, refreshFromServer,
Berechtigungs-Grant, Settings-Button). Zwei Runs fragten gleichzeitig
denselben „existing"-Zustand ab, bevor einer committet hatte, und insertierten
dadurch dasselbe Event – die v39-Orphan-Bereinigung entfernt nur Zeilen mit
leerem SYNC_DATA3, nicht Duplikate mit identischem UID. Fix in
CalendarSystemSyncAdapter: (1) gemeinsames ReentrantLock serialisiert alle
System-Syncs (direkter Thread + onPerformSync), überlappende Runs werden so
zu sequenziellen idempotenten Upserts; (2) reconcileEvents sammelt jetzt
Zeilen pro UID und löscht bei mehreren Treffern alle bis auf die niedrigste
_id – damit werden auch bereits angelegte Duplikate beim nächsten Sync
bereinigt. Version 43, versionCode 43 (VersionName und versionCode immer
identisch).
Secretary Calendar 41 (versionCode 41): 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 („Sync abgeschlossen"/
„fehlgeschlagen"). Vorher blieb der Status gesetzt und der Inline-SyncProgressUi
zeigte bei einem beendeten oder fehlgeschlagenen Sync (z. B. wenn der vorherige
Server /sync/* mit 404 beantwortete) dauerhaft einen Spinner bei 0/0.
Außerdem läuft der Server-Init-Sync jetzt gegen den aktualisierten
secretary-server 0.10.0 mit den /sync/*-Endpunkten. Version 41,
versionCode 41 (VersionName und versionCode immer identisch).
Status 2026-08-29 (40)
Secretary Calendar 40 (versionCode 40): Server-gesteuerter Sync mit
Fortschritt – über den gemeinsamen SyncJobClient (secretary-common-android,
POST /sync/start + GET /sync/status/{id}) startet
CalendarViewModel.runServerSync() beim manuellen Refresh (forceRefresh)
für jeden Kalender einen Server-Sync-Job und pollt den aggregierten Fortschritt
in [syncStatus]. CalendarListScreen zeigt über das gemeinsame SyncProgressUi
während des Syncs einen Spinner + Determinat-Progressbar (processed / total)
und einmalig einen Toast („Sync abgeschlossen"/„fehlgeschlagen").
Version 40, versionCode 40 (VersionName und versionCode immer identisch).
Status 2026-08-29 (39)
Secretary Calendar 39 (versionCode 39): System-Kalender zeigt Termine
doppelt – Regression-Bugfix. Der System-Provider-Sync legte pro UID/NAME
zwei Kalender- bzw. Event-Zeilen an. Fix in CalendarSystemSyncAdapter: (1)
reconcileEvents sammelt Zeilen mit leerem SYNC_DATA3 in orphanIds und
löscht sie via asSyncAdapter+ContentUris.withAppendedId; (2) neue
dedupeCalendars(resolver, account) löscht Duplikate (gleicher NAME, höhere
_id behalten die niedrigste); calendarIdsByHref behält außerdem nur die
erste Id pro NAME. Version 39, versionCode 39 (VersionName und versionCode
immer identisch).
Status 2026-08-29 (38)
Secretary Calendar 38 (versionCode 38): Einstellungen-Screen an Kontakte-App
angeglichen – Kalender und Kontakte schreiben beide in System-Collections
(System-Kalender- bzw. System-Kontakte-Provider). Der Kalender-
SettingsScreen hat jetzt die gleiche Struktur und den gleichen Sync-Block wie
der Kontakte-Screen: Überschrift „Systemkalender" mit Beschreibung, Button
„Jetzt in System-Kalender synchronisieren" (analog „…Systemkontakte…"), Hinweis
über vm.systemSyncEnabled() (kein Konto → Meldung), danach Abmelden, dann
Konto. Die kalenderspezifischen Raster-Einstellungen bleiben als Extra-Block
erhalten. Neue ViewModel-Methode systemSyncEnabled() (analog Kontakte).
Version 38, versionCode 38 (VersionName und versionCode immer identisch).
Status 2026-08-29 (37)
Secretary Calendar 37 (versionCode 37): System-Kalender jetzt voll
befüllt + manueller Sync-Button – nach dem Berechtigungs-Fix (34) und
caller_is_syncadapter (35) schlug der updateCalendar-Pfad (Kalender
existierten bereits) mit For input string: "? AND …" fehl, weil im
Sync-Adapter-Modus die Zeilen-_id aus dem URI-Pfad
(ContentUris.withAppendedId) statt aus der Selection gelesen wird. Fix:
Update/Delete von Kalendern und Events verwenden jetzt withAppendedId
mit caller_is_syncadapter-Paramentern. Außerdem gibt es jetzt unter
Einstellungen einen Button „Jetzt in System-Kalender synchronisieren"
(vm.mirrorToSystem()), analog zum Kontakte-App-Button
„Jetzt in Systemkontakte synchronisieren". Version 37, versionCode 37
(VersionName und versionCode immer identisch).
Status 2026-08-29 (36)
Secretary Calendar 36 (versionCode 36): Events landen nicht im
System-Provider – nach dem caller_is_syncadapter-Fix (35) wurden die
Kalender angelegt, aber jede Event-Insert schlug mit Only the provider may
write to account_name fehl: eventValues schrieb account_name/account_type
selbst mit. Beim Events-Insert leitet der CalendarProvider2 das Konto aus der
CALENDAR_ID (Kalenderzeile) ab; die Spalten dürfen dort nicht explizit
geschrieben werden. Fix: beide Spalten aus eventValues entfernt.
Version 36, versionCode 36 (VersionName und versionCode immer identisch).
Status 2026-08-29 (35)
Secretary Calendar 35 (versionCode 35): Systemkalender bleibt leer
(nach Berechtigungs-Fix) – nachdem die fehlende Runtime-Berechtigung
(34) erteilt war, schlug der Sync trotzdem mit Only sync adapters may
write to account_name fehl: CalendarSystemSyncAdapter schrieb auf die
nackte Calendars/Events-URI, ohne den caller_is_syncadapter=true +
account_name + account_type-Query-Parameter, den der
CalendarProvider2 verlangt, um account-gebundene Zeilen zu schreiben
(DAVx5/Exchange-Muster). Fix: asSyncAdapter(uri, accountType, accountName)
und Verwendung für alle Insert/Update/Delete von Kalendern und Events.
Version 35, versionCode 35 (VersionName und versionCode immer identisch).
Status 2026-08-29 (34)
Secretary Calendar 34 (versionCode 34): Systemmonat in LineageOS-Kalender
leer – die eingebaute Android-Kalender-App zeigte keine secretary-Termine.
Ursache: die App deklariert zwar READ_CALENDAR/WRITE_CALENDAR im Manifest,
fragte die Runtime-Berechtigung aber nie an (targetSdk 36, API 26+). Dadurch
blieb granted=false und der System-Provider-Sync
(CalendarSystemScheduler.ensureSyncing → CalendarSystemSyncAdapter) schlug
immer mit SecurityException: requires android.permission.READ_CALENDAR or
WRITE_CALENDAR fehl — die Fehler wurden nur geloggt, daher wirkte alles
normal, es kam aber nie etwas in com.android.calendar an. Fix:
MainActivity fragt die Calendar-Berechtigung zur Laufzeit (Activity-Result-
API, RequestMultiplePermissions) an; nach Gewährung wird vm.mirrorToSystem()
aufgerufen, um den Cache sofort zu spiegeln. Version 34, versionCode 34
(VersionName und versionCode immer identisch).
Status 2026-08-29 (33)
Secretary Calendar 33 (versionCode 33): Diagnose leerer Monatsansicht –
auch nach dem mehrwöchigen-Wochen-Fix im common-Recurrence meldete der User
eine komplett leere Monatsansicht (keine Termine). Der End-to-End-Pfad
(VEventParser + common Recurrence, Test RecurrenceDisplayTest) liefert die
September-Occurrences korrekt, daher ist die Ursache in Datenladen/Anzeige
(oder einer einzelnen Event-Ausnahme). Maßnahmen: recomputeEventsForMonth ist
jetzt je Event mit try/catch abgesichert (ein kaputtes Event kann den Monat
nicht mehr leeren) und loadEvents/recomputeEventsForMonth loggen Zähler
(Tag CalendarVM) zur Diagnose. Version 33, versionCode 33 (VersionName und
versionCode immer identisch).
Status 2026-08-29 (31)
Secretary Calendar 31 (versionCode 32): Fix für mehrwöchige Wochen-
Wiederholungen – ein Bug in Recurrence.nextWeeklyByDay
(secretary-common-android) ließ bei FREQ=WEEKLY;INTERVAL>1 mit BYDAY
(für z. B. „alle 2 Wochen am Dienstag" erzeugt der Dialog BYDAY=TU)
aufeinanderfolgende Occurrences weg (das 4. Vorkommen war übersprungen,
Monatsansicht zeigte z. B. „Selbsthilfegruppe" im August, aber nicht mehr
im September). Die Wochen-Berechnung zählte die absolute Wochenanzahl als
Intervall-Woche und sprang dadurch um einen ganzen Zyklus zu weit. Fix:
k zählt jetzt die Intervall-Wochen ab der Basiswoche. Regressionstest
weeklyIntervalTwoByDayDoesNotSkipWeeks. Version 31, versionCode 32.
Status 2026-08-28 (30)
Secretary Calendar 30 (versionCode 31): Systemkalender-Sync – die
App spiegelt ihren Offline-Cache (Kalender + Events) jetzt über einen
SyncAdapter (system/CalendarSystemSyncAdapter.kt, Service
CalendarSystemSyncService) für com.android.calendar in den System-
Kalender-Provider, damit die Termine in der eingebauten Kalender-App und
anderen Consumer-Apps sichtbar sind (analog zum Contacts-System-Provider-Sync;
ersetzt DAVx5). CalendarStore.snapshot() liest synchron Kalender + Events
je Kalender; der Adapter gleicht Kalender (per Calendars.NAME=href) und
Events (per SYNC_DATA3=UID) ab, fügt ein/aktualisiert und löscht
überschüssige Zeilen. Integration: CalendarViewModel ruft
CalendarSystemScheduler.ensureSyncing() nach Login, beim Kaltstart mit
Cache und nach jedem backgroundSync/refreshFromServer. Version 30,
versionCode 31.