Commit Graph

22 Commits

Author SHA1 Message Date
Scarriffle
6881c68935 iOS drawer: flat reorderable calendars, long-press menu, left-swipe close, header actions
Testing feedback:
- calendars are now one flat, drag-reorderable list (no per-source grouping);
  order is device-local (CalendarStore.calendarOrder, mirrors the web cal_order).
  Reordering is done via a 'Sort' toggle (native edit mode with drag handles).
- banish + reminder-mute moved from row swipe actions to a long-press context
  menu, which frees the horizontal swipe: swiping the drawer left closes it.
- the hamburger moved to the LEFT (drawer opens left); new device-local setting
  'Hide menu button' (open via edge-swipe only), not synced.
- the settings entry moved from the footer into the header as an icon, next to a
  restored manual-sync icon and the close button; the footer button is gone.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 16:19:29 +02:00
Scarriffle
108503ad53 iOS: month-switching setting as a named dropdown (parity with web)
Replace the boolean "month view as pages" toggle with a Monatswechsel dropdown:
Continuous scroll vs. Page by page — same names/format as the web client.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 06:45:22 +02:00
Scarriffle
d90a1a552c iOS: left side drawer (calendars + groups + nav) and opt-in top-bar colour
Replace the top-bar menu popup with an off-canvas left drawer, opened by the
hamburger or a narrow left-edge swipe (kept off the content area so month/week
swipe stay free). The drawer hosts the calendar visibility list, a view
switcher, group switching, and quick access to Settings/Accounts/Profile/
Groups/Server plus sync and logout.

- extract the filter list into reusable CalendarFilterContent (shared by the
  drawer and the still-present CalendarFilterSheet); the sheet is now a thin
  wrapper
- new CalendarDrawer view; CalendarHostView hosts it as a ZStack overlay with a
  scrim and edge-swipe gesture, and presents drawer destinations as sheets
- opt-in surface colour: surfaceColor (device-local) tints the flat top bar;
  empty keeps the translucent .bar material. Settings row with an Auto reset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 22:24:24 +02:00
Scarriffle
9a50f25f57 iOS: per-setting sync table with sync icons, dropdowns, colour resets
Generalise the two-tier SettingsSync into a server-driven flag map: each
syncable key has an account-wide flag (fetched from the server); pull applies
only on-flagged keys, push (read-modify-write) sends only on-flagged keys plus
the flag map. Per-row link icon toggles a setting's sync; a global switch flips
all. Enabling a flag adopts this device's current value as the shared one.

- AppSettings: fix bg_color mapping (was background_color), add cache_months,
  month_view_paged, sync_flags
- SettingsView: uniform rows (sync icon | name | value), ContrastSelector and
  the button pickers replaced by menu dropdowns, every colour gets a reset to a
  canonical default, global "sync all" toggle; account settings (privacy,
  group calendar, hide profile) kept in their own block; language and text/line
  contrast kept device-local (iOS-specific)
- unify default line colour to #3A3A52 across views

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 21:31:16 +02:00
Scarriffle
d4fd7beaf7 Birthdays: explicit calendar creation, sync never auto-creates (iOS)
- Contacts sync fills only an EXISTING birthday calendar (birthdayCalendar),
  never auto-creates it — deleting it no longer resurrects it on sync
- Accounts + menu gains "Geburtstagskalender" (only when none exists) to create
  the single birthday calendar explicitly
- the Birthdays-from-Contacts section shows a "create one first" hint when there
  is no birthday calendar; enabling sync only requests Contacts access

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 21:25:06 +02:00
Scarriffle
69ed8bf67d Birthdays: single calendar model + sync on server-sync (iOS)
- one birthday calendar per user; BirthdaysImporter auto-creates/targets it
  (no picker) and reconciles per-device (external_uid contact:<deviceId>:<id>)
  so multiple devices don't clash
- Contacts birthday sync now runs on every "Sync with server" (syncFromServer),
  not just app launch and the manual button
- report the device after each sync (POST /api/birthdays/sync-report) for the
  web device list
- Accounts: Birthdays-from-Contacts section drops the target picker, keeps the
  reminder picker; removed the birthday toggle from the generic new-calendar sheet
- New-birthday sheet targets the single calendar, offers activation if none
- exclude the birthday calendar from the group-visible ("shared calendar") picker

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 19:07:46 +02:00
Scarriffle
cf990e4279 Add birthday feature (iOS)
- LocalCalendar/CalEvent gain is_birthday + birthday fields; API sends
  rrule/external_uid/birth_year and can create/update birthday calendars
- BirthdaysImporter: mirrors Contacts birthdays into a chosen birthday
  calendar, reconciling by external_uid (leaves manual entries untouched)
- AccountsView: "birthday calendar" toggle + notify-days when creating a
  calendar, and a "Birthdays from Contacts" section (enable + target + sync now)
- FAB long-press menu -> "New birthday" opens a minimal name+date mask
  (BirthdayEditorSheet) targeting birthday calendars, with year-unknown option
- Event bars render display_title (age) and a cake icon via EventLabel
- NSContactsUsageDescription added to both app build configs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 21:58:31 +02:00
Scarriffle
e55e6c7c92 feat(ios): toggle month view between scroll feed and paged swipe
New device-local setting "Monatsansicht seitenweise wischen" (@AppStorage, no
server sync). Off keeps the continuous vertical scroll feed; on switches the
month view to a paged TabView — one month per screen, six height-filling week
rows, swipe left/right to change month (bounded ±monthsBack/Ahead range to keep
the TabView light). WeekRow gains a fillHeight flag so the same row renders at a
fixed height (scroll) or fills the page evenly (paged); its inner cells/divider
now size to the actual geometry. Paged selection is two-way bound to the store's
current date so prev/next/today and the title stay in sync.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 05:15:58 +02:00
Scarriffle
32cb8e1689 feat(sharing): hidden-profile toggle + hide non-sharing group members
- UserProfile decodes directory_hidden; updateProfile() sends it; Settings has
  a "hide my profile" toggle (excludes you from share/group pickers).
- GroupMember decodes shares_calendar; the group filter list now only shows
  members who actually share a calendar (no phantom empty rows).
- Robust custom decoders (decodeIfPresent) for the new fields.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 18:45:49 +02:00
Scarriffle
cc3d16ddce feat: custom reminder picker, muted-calendar hint, synced default duration
- Reminder editor: presets + custom number+unit (minutes/hours/days/weeks)
- Grey out + footer hint when the selected calendar's reminders are muted;
  reminders are kept, scheduler already skips them
- New synced setting defaultEventDurationMinutes for new events

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 10:03:24 +02:00
Scarriffle
c0edca338e iOS: localization fixes, per-calendar reminders, widget polish
C1 — Localization: route the remaining hardcoded German strings through
L10n (LoginView, ServerSetupView, SettingsView email, EventDetailSheet) so
"System Default" + English device language shows fully English text.

C2 — Per-calendar reminders: parse the new reminders_enabled flag on every
calendar type; CalendarStore persists a reminderDisabledKeys set and passes
it to NotificationScheduler, which skips events of muted calendars (default
and per-event reminders). Filter sheet gains a per-calendar reminder toggle
(leading swipe + bell.slash indicator), reconciled from the server and
synced back via PUT.

C3 — Widgets:
- Shared WidgetTime.range helper; Today / Today & Tomorrow / Three Days /
  Up Next now show start–end instead of only the start time.
- This Week: show up to 6 events per day (was 3) to use the height.
- Two Weeks: mini event-title pills instead of bare dots.
- Two Months: weeks expand to fill the column (no more empty lower third).
- Day & Events: smaller header/strip/rows so content stops clipping.
- Next 5 days → Next 7 days (range + labels), higher row cap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 20:14:39 +02:00
Scarriffle
b61a90d960 feat: hide individual member calendars in the group view (iOS)
The calendar filter, when a group overlay is active, now lists the group's
members (+ the shared group calendar) and lets you hide each one individually
(Outlook-style). Filtering is client-side via CalendarStore.hiddenGroupKeys
(per-member gm:<id> / group-calendar gc keys), reset when switching groups.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 18:00:30 +02:00
Scarriffle
6dc8724a9a feat: iOS Gruppenansicht direkt im Kalender (Umschalter + Banner)
Gruppen sind nicht mehr nur im Menü versteckt: im Top-Bar gibt es einen
Gruppen-Umschalter (Persönlich / <Gruppe>). Beim Wählen einer Gruppe zeigt
der echte Monats-/Wochen-/Tagesansicht die kombinierte Überlagerung
(GET /groups/{id}/combined) mit server-definierten Farben und
Besitzer-Präfix; ein Banner "Gruppenansicht: <Name>" mit "Verlassen".
CalendarStore.activeGroup steuert den Modus.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 20:55:28 +02:00
Scarriffle
c9803d80a3 fix: doppelter L10n-Key "settings.saved" entfernt (Runtime-Crash beim Start)
Ein doppelter Dictionary-Key liess die App beim Start abstürzen
("Dictionary literal contains duplicate keys"). Meine Dublette entfernt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 20:35:04 +02:00
Scarriffle
9fac13f99c feat: iOS Gruppen – Liste, Erstellen/Verwalten, kombinierte Ansicht
- Menü-Eintrag "Gruppen" -> GroupsView (Liste, Erstellen mit Icon-Auswahl +
  Mitglieder, Verwalten: umbenennen/Icon/Mitglieder/Mitglieder-Farben/löschen).
- GroupCombinedView: monatsweise Agenda der überlagerten Mitglieder-Kalender
  + Gruppenkalender; Termine mit Besitzer-Vorname bzw. 👥 + Ersteller,
  server-definierte Farben (display_color).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 20:08:53 +02:00
Scarriffle
da2e39911c feat: iOS Sharing + iCal Import/Export für lokale Kalender
Kalenderverwaltung: pro lokalem Kalender ein Menü mit Teilen (SharingView:
Benutzer aus Verzeichnis, read/read_write, entfernbar), Importieren
(.ics File Picker) und Exportieren (Share Sheet). Geteilte Kalender mit
"geteilt von"-Badge; Gruppenkalender markiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 19:40:41 +02:00
Scarriffle
023f90be3b feat: iOS Einstellungen – Profil, Privatsphäre, geteilter Kalender
Neue Settings-Sektionen: Anzeigename + E-Mail ändern (Login-Name read-only),
Private-Termine-Sichtbarkeit (busy/hidden) und Auswahl des für Gruppen
sichtbaren Kalenders. Gezielte API-PUTs, damit nicht die ganze AppSettings
überschrieben wird.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 19:35:22 +02:00
Scarriffle
e7e4998fb9 feat: iOS Datenebene + Ersteller-Anzeige + Privat-Flag
- Modelle: CalEvent (creator, isPrivate, owner, isGroupEvent, displayColor),
  LocalCalendar (owned/sharedBy/permission/group), AppSettings
  (privateEventVisibility, groupVisibleCalendarId), UserProfile (displayName);
  neue Modelle CalGroup/GroupMember/DirectoryUser/CalendarShare.
- API: Profil-Update (Name/Login), Sharing-CRUD, Gruppen-CRUD + combined,
  Mitglieder-Farbe, iCal Import (multipart) & Export, private-Flag bei Events.
- Event-Detail zeigt "Erstellt von" (wenn != ich) + Privat-Hinweis;
  Editor hat Privat-Toggle (nur lokale Kalender). Login speichert userId.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 19:32:31 +02:00
Scarriffle
b1e0cf1fdc WIP: Widget-, Sync- & Event-Editor-Änderungen
Zwischenstand vor den Sharing/Gruppen/Import-Export-Features (gesichert,
damit die neuen Features sauber darauf aufbauen).
2026-05-31 19:22:12 +02:00
Scarriffle
4125bfc728 Settings sync, calendar visibility sync, event refresh & week-view fixes
- Add two-way settings sync (SettingsSync) with toggle, app-start/foreground/
  10-min pull and debounced push; server wins; view/week-start/dim-past always
  sync. Wire previously-ignored settings (hour height, contrasts, week start,
  default view, dim past) into the actual UI.
- Make AppSettings decoding resilient (decodeIfPresent) so getSettings no longer
  fails on iOS-only fields the server omits; keep text/bg/line colors local-only;
  month divider/label colors now sync.
- Auto-refresh after create/edit (cache-busting) and optimistic removal on
  delete; switch delete confirm to a centered alert. Add HA event deletion.
- Calendar visibility: fix inverted hide/show toggle; normalize calendar keys so
  local filtering works for all sources; sync banish with server sidebar_hidden
  (CalDAV/Google/HA), refetch on un-banish.
- Manual "sync with server" button in the menu.
- Upcoming widget shows next 5 days (renamed).
- Week/Day view: route multi-day timed events to the all-day strip so they no
  longer render as a full-height block.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 20:44:14 +02:00
Scarriffle
6c506770ba Widget anpassung vorbereitung 2026-05-25 11:53:02 +02:00
Scarriffle
8b3cc11e25 Add localization (DE/EN), vertical-scroll month view, context menus, custom colors
- Vertical-scroll month view with multi-day event spans, zig-zag month
  divider, CW number per week, on-demand event loading while scrolling
- Top bar redesign: icon-only view picker on right, month title centered
- Long-press context menus on day cells (month) and hour slots (week/day)
  for "New event", "Open in week view", "Open in day view", "Open in month view"
- Localization system with system/de/en switch covering top bar, view picker,
  settings, menu, profile, server, accounts, event editor, agenda
- Three new color pickers (text/background/line) + today-marker color
  applied in calendar views; current-time line now uses today color
- App icon: removed alpha channel, accent color set to icon green (#20A050)
- TestFlight: ITSAppUsesNonExemptEncryption=NO baked into Info.plist keys

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 22:00:49 +02:00