Commit Graph

141 Commits

Author SHA1 Message Date
kutesir
3592d2a9d8 Matrix: TickTick-style Priority×deadline view + Progress Dots widget (KC-21)
Matrix (KC-21): the Eisenhower Matrix is now a computed view of tasks.
Importance = Priority (High = top row), urgency = deadline proximity, so
tasks auto-place into Q1–Q4. Added a persisted `matrixOverride` so a manual
drag pins the task and syncs its Priority to that row (top → High, moving
down demotes High → Medium) and never gets forced back; editing Priority,
due date, or the editor clears the override to re-place live. New tasks get
KisaniCal priority defaults (birthday/domain/annual/exam/subscription → High,
workout → Medium). AddTaskSheet drops the manual quadrant picker for a
Priority menu (pick Priority + Date only).

Also includes in-progress Progress Dots widget work (day/week/month/custom
event modes, App-Group anchor, recurrence-aware spans).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 12:40:39 +03:00
kutesir
2b48509a35 Bars widget: recurrence-aware progress in ALL paths (KC-20 follow-up)
The real bug behind "Leona's Birthday, 5 days left" showing 0% filled:
Mode B (recurring span: previous -> next occurrence) only ran for
app-tracked events, while the upcoming-queue / picked-event paths still
anchored from first-seen (so a yearly birthday started at 0%).

- EventEntity now carries isRecurring/recurrenceLabel (populated from the
  shared task data) so the auto-select and picker paths know the rule.
- resolveSpan() centralizes the window: recurring -> prev/next occurrence
  everywhere; one-off -> explicit start / tracking date / first-seen.
- A yearly birthday 5 days away now reads ~98% (≈360/365 days elapsed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 23:20:46 +03:00
kutesir
b6eaba78ba Bars widget: app-driven "Track Countdown" with zero config (KC-20)
- Task long-press menu gains Track/Stop Tracking Countdown, storing the
  tracked event id + tracking date in the App Group (CountdownTracker)
  and reloading widget timelines.
- The widget reads the tracked event directly and bypasses its config:
  Mode A (one-off) = tracking date -> event date; Mode B (recurring) =
  previous occurrence -> next occurrence via the task's recurrence rule.
- WidgetTask decodes isRecurring/recurrenceLabel from the shared JSON.
- With nothing tracked, the configured modes remain the fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:05:33 +03:00
kutesir
a7639f6454 Widgets: align every widget to the exact logo palette (KC-19)
WidgetTheme now uses the true brand colors — accent RGB(232,98,42) on
the logo's dark RGB(26,29,34) — replacing a near-miss orange on slate.
Bars countdown, My Tasks, and Day Progress inherit it; Task Live
Activity drops its hardcoded accent/black tint for the theme; lock
screen rings tint brand orange.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 19:33:01 +03:00
kutesir
0606d9c3aa Bars widget: fix empty progress bar + dead-feeling date pickers (KC-18)
- Persist a per-event "first tracked" anchor in the App Group instead of
  resetting the progress start to now on every refresh (auto mode), so
  the bar actually fills toward the event. Explicit "Counting from" wins
  when it's before the event date.
- Make Event date / Counting from optional ("Choose") — the same-second
  defaults produced a zero-length span (always 0%) and looked broken.
- Pre-render timeline entries every 30 min (12h horizon) so the bar and
  time-left label move between refreshes instead of only at midnight.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 18:16:43 +03:00
kutesir
49b22b5f2f Widgets: remove Event Countdown (dots) + Tasks Done Today (KC-17)
Drop the dot-grid EventCountdownWidget and TasksCompleteWidget from the
gallery: widget structs, their views, the todayTaskCompletion() helper
(only consumer), and bundle registrations. Shared event plumbing
(EventConfigIntent/Provider/Entry, CycleCountdownUnitIntent) stays for
the surviving Event Countdown (Bars); DotGrid stays for Day Progress.
Remaining widgets untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 11:49:35 +03:00
kutesir
443fe8504f Workout check-in: missed state + rest-day compensation (KC-16)
- Notification actions on workout reminders/check-ins: "Yes, I completed
  it", "No, I didn't" (marks the day missed, then asks to compensate on a
  rest day), "Remind me in 1 hour" (snooze).
- VM: missedDates + compensations (persisted/synced), per-date
  markWorkoutDone/Missed, workoutStatus, upcomingRestDays,
  scheduleCompensation, promptCompensation, checkPendingMissed.
  program(for:) returns a compensation program on its rest day.
- CompensationSheet: pick a rest day or keep as missed; compensation days
  get a one-off "Missed workout recovery" reminder.
- Long-press menus: workout row (Done / Not Done / Compensate) in Today +
  Calendar; exercise cards (Mark as Done / Not Done). All actions are
  per-date — one occurrence never affects another.
- Workout row shows Pending / Done / Missed + "Compensation" label.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 23:06:58 +03:00
kutesir
f252fc7707 fix: remove unused 'cal' in statBuckets (warning)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 17:36:35 +03:00
kutesir
0362d586e5 Widgets: bars countdown widget + unified slate/orange theme (KC-15)
- New EventBarsWidget ("Event Countdown (Bars)") using BarGrid + EventBarsView,
  with a fine "X hr, Y min left" label; registered in the bundle.
- Re-themed every home-screen widget to the shared WidgetTheme (dark slate
  background + brand orange): Day Progress, Tasks Done Today, Event Countdown
  (dots), My Tasks. Lock-screen widgets keep .thinMaterial (system-tinted).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 17:31:55 +03:00
kutesir
063df4ba03 Widgets: add shared WidgetTheme + BarGrid (foundation)
Groundwork for the slate-background / brand-orange widget re-theme and the
new bar-style event countdown:
- WidgetTheme (dark slate background, brand orange accent, text tones).
- BarGrid: vertical-bar (comb) progress view.

Re-theming the existing widgets and adding the bars widget follows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 17:18:52 +03:00
kutesir
a191cebeed chore: set version 2.0 (5) to match current uploads
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:29:17 +03:00
kutesir
9768af0017 Add Workout Stats screen (daily/weekly/monthly) — KC-14
Aggregate the per-day workout logs into performance stats:
- WorkoutDayLog.volume + StatPeriod/WorkoutStat/StatBucket.
- WorkoutViewModel.stat/statInterval/statBuckets (current vs previous).
- WorkoutStatsView: Day/Week/Month selector, Workouts/Sets/Volume cards
  with %-delta vs previous period, metric chooser, and a Swift Charts bar
  trend. Reached via a chart button in the Workout header.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:21:12 +03:00
kutesir
c0eb1ffa23 docs: log KC-13 (recurrence redesign + classic Matrix)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:09:55 +03:00
kutesir
2f1bc5d1c3 Matrix: classic Eisenhower — you set importance, deadline sets urgency
Quadrant is now computed (importance x urgency) instead of a fixed
assignment. Importance comes from the task's assigned row (Q1/Q2 vs
Q3/Q4); urgency is derived from the (next active) due date being within
urgentWindowDays (7). So important tasks slide Q2->Q1 as they near,
unimportant slide Q4->Q3, and recurring tasks roll forward (a completed
occurrence is replaced by the next, never piling up in a quadrant).

- VM: displayQuadrant/isUrgent/effectiveDue; matrixTasks groups by the
  computed quadrant and uses each recurring task's single next occurrence.
- MatrixView grid + drill-down (overdue/later/completed) group by it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:00:29 +03:00
kutesir
b4e36db763 Tasks: single-occurrence recurrence + Today/Tomorrow/Next 7/Later + icons
Switch lists from calendar-expansion (every occurrence in every section)
to the TickTick model: one task contributes ONE next-active occurrence.

- VM: nextActiveOccurrence + activeRows; replace todayTasks/next3/upcoming
  with todayTasks/tomorrowTasks/next7DaysTasks/laterTasks buckets. A
  recurring task shows a single row; completing it advances to the next.
- TodayView: sections are now Today / Tomorrow / Next 7 Days / Later
  (UpcomingSection gained a title param).
- TaskRowView: add  (reminder) and 🔁 (recurring) indicators on the right;
  fix the hardcoded "Annual" label to show the real frequency.

Calendar grid keeps per-date occurrences (it's a date grid, not a list).
Matrix dynamic promotion (Problem 4) handled separately.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 19:36:10 +03:00
kutesir
0870359ae8 Recurrence: add "repeat until" end date UI (KC-12)
Thread recurrenceEnd through NLParsed, TaskDatePickerSheet, the add/edit
sheets, and addTask/updateTask. The date picker now shows a "Repeat until"
row (graphical picker, default "Forever", with Clear) whenever a
recurrence is set; the engine already honored recurrenceEnd.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 10:47:13 +03:00
kutesir
6817d3e24a Recurring tasks: occurrence engine on calendar + lists (KC-12)
Recurring tasks only ever showed on their single dueDate. Add a
recurrence engine that expands occurrences per-date with independent
per-occurrence completion.

- TaskItem: recurrenceEnd + completedOccurrences (optional, safe decode).
- TaskViewModel: isOccurrence/occurrenceComplete/toggleOccurrence/
  occurrenceCopy/nextOccurrence/occurrences(on:); Daily/Weekly/Monthly/
  Yearly/Every-Weekday; respects recurrenceEnd; works across years.
- toggle() routes recurring rows to per-occurrence completion.
- Date filters re-inject per-date occurrence copies; recurring excluded
  from overdue. Calendar dots + day detail use occurrences(on:).

Also log KC-11 (year display) + KC-12.

Pending: "repeat until" date UI (engine already honors recurrenceEnd).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 01:41:15 +03:00
kutesir
7b2b61a228 Calendar: show the year (fix "can't navigate past 2026")
Navigation was unbounded, but headers only showed the month name so the
year change was invisible and future months felt unreachable.

- Main calendar header now shows "Month Year".
- Date-picker grid label shows the year.
- Year view gets a chevron year navigator (unbounded) + year label.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 00:48:17 +03:00
kutesir
d09a6c1fe3 Fix: per-date workout completion in calendar (KC-10)
The calendar marked every occurrence of a program complete once any one
was finished — including future dates — because DayTimelineView read the
program's live shared doneSets.

- Add WorkoutViewModel.isWorkoutComplete(on:) backed by workoutDates.
- DayTimelineView takes workoutDone and uses it instead of live sets;
  Calendar passes the selected date's state, Today passes today's.
- A date now shows complete only if that specific date was finished.

Log KC-10 in ISSUES.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 00:29:48 +03:00
kutesir
966c1b35e9 Workout: per-day history + log KC-8/KC-9
- Add per-day workout history: WorkoutDayLog/LoggedExercise/LoggedSet
  models stored at kisani.workout.history.<uid> (iCloud-synced).
- snapshotDay(_:) captures the active program's completed sets on full
  completion and before the daily reset; only days with >=1 done set.
- New WorkoutHistoryView (clock button in the Workout header) lists past
  days newest-first with per-exercise breakdown.
- Log KC-8 (auto-switch / Rest Day) and KC-9 (history) in ISSUES.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 23:12:46 +03:00
kutesir
2abb0c54e4 chore: stop tracking Xcode xcuserstate (UI-state noise)
The existing ignore rules were anchored to repo root, so the nested
*.xcodeproj/project.xcworkspace/xcuserdata/ never matched and kept
showing up as a change on every commit. Add **/xcuserdata/ and
*.xcuserstate and untrack the file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 23:06:05 +03:00
kutesir
f9081cfcf7 Workout: auto-switch to today's program + Rest Day state
The Workout tab kept showing the last-used program (with its old
completion) regardless of the weekly schedule, so a rest day still
displayed a stale, fully-checked workout.

- On a new day, the active program now follows the weekly schedule
  (applyScheduledProgramForToday in resetSetsForNewDayIfNeeded).
- Add isRestDayToday + a Rest Day card shown when today has no scheduled
  program, with a "Work out anyway" override. Header reads "Rest Day".
- Daily set reset (KC-1) unchanged — no day starts pre-checked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 15:47:49 +03:00
kutesir
8e4a42666c docs: log KC-7 (iPad launch-screen upload failure) + fast-fix checklist
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 14:11:26 +03:00
kutesir
345415ee7b Bump build number to 2 for re-upload
The previous App Store upload failed on the iPad launch-screen check
because it was a stale archive built before the LaunchScreen fix
(72f4566). Bump CURRENT_PROJECT_VERSION so a fresh archive uploads
cleanly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 14:07:55 +03:00
kutesir
af72c4cc4e docs: trim proxy-hosts table from Sanctum dual-WAN runbook
Removes the published Proxy Hosts / Services table from the Sanctum
Auto-FailOver + Uptime Kuma runbook.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 12:44:06 +03:00
kutesir
7b98be1d8d Event widget: upcoming-queue auto-select + cleaner config & preview
- Add "Upcoming queue" toggle to the Event Countdown widget. When on, it
  auto-tracks the Nth nearest upcoming event (Nearest / 2nd … 5th, new
  AutoSelectRank enum). When off, track a picked or fully custom event.
- parameterSummary now shows only the relevant fields per mode (toggle +
  auto-select, or event/name/date), so the date input only appears for
  custom events.
- Replace the dense 380-day placeholder with a ~90-day window so the
  gallery preview shows a legible dot grid.

(The interactive task-checkbox widget already exists as "My Tasks".)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 12:43:02 +03:00
kutesir
72f4566d91 Fix iPad launch-screen validation failure
App Store upload rejected the bundle: iPad-multitasking apps must declare
a launch screen, but project.yml set an empty UILaunchStoryboardName ("")
and provided no UILaunchScreen.

Add a minimal LaunchScreen.storyboard (blank, systemBackgroundColor) and
point INFOPLIST_KEY_UILaunchStoryboardName at it. Regenerated the project.
Bundle now ships UILaunchStoryboardName=LaunchScreen + compiled
LaunchScreen.storyboardc; builds clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 12:20:41 +03:00
kutesir
196dd7b78e Calendar: shared store reliability + event notifications
KC-5: Consolidate calendar access into CalendarStore.shared so Today,
Calendar, Onboarding, and Settings share one permission state and event
cache. requestAccess() debounces and reads authoritative status; turning
on "Show Calendar Events" while unauthorized now prompts. New Settings →
Data → Calendar row shows Connected/Connect/Denied.

KC-6: Add calendar-event notifications. CalendarStore.upcomingEventNotifs
snapshots visible events (next 7 days); NotificationManager schedules at
start time plus each event alarm (all-day at 9am), capped at ~20 to stay
under iOS's 64-notification limit. Wired into reschedule().

Log KC-5 and KC-6 in ISSUES.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 04:08:23 +03:00
kutesir
0a4545f042 Share a single CalendarStore for unified permission state
Introduce CalendarStore.shared so Today, Calendar, and Onboarding read
the same auth status and event cache instead of each spinning up its own
EKEventStore. Trust the system's authoritative authorization status over
the granted bool, debounce repeat permission requests, route denied users
to Settings, and prompt when enabling local calendars without access.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 03:27:24 +03:00
kutesir
c0e80ab4ce docs: add Sanctum dual-WAN failover + Uptime Kuma runbook
Omada policy-routing setup that pins each monitoring host to a specific
ISP (Canal+/Airtel) so Uptime Kuma surfaces per-link failures instead of
masking them behind WAN failover.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 03:27:17 +03:00
kutesir
6be52fdac1 docs: log KC-4 (task menu + Live Activity) with test steps
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 19:46:39 +03:00
kutesir
d0d982f4f5 Add unified task menu, Live Activity, and calendar event actions
Task context menu (new shared TaskMenuItems) consistent across Today,
Matrix, and Calendar: Pin · Date · Move · Priority · Tags · Add to Live
Activity · Delete. Adds TaskViewModel.setPriority.

Live Activity (ActivityKit):
- TaskActivityAttributes shared between app and widget targets
- LiveActivityManager (start/update/end/toggle, iOS 16.1+)
- TaskLiveActivity widget: lock-screen banner + Dynamic Island
- NSSupportsLiveActivities via project.yml; project regenerated

Calendar events (non-subscription, writable only):
- Edit via system EKEventEditViewController (EventEditView wrapper)
- Delete via new CalendarStore.deleteEvent

Also sweeps in prior in-progress edits already present in the working
tree (AuthManager, NotificationManager, TaskItem, task views) and the
updated ISSUES.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 19:29:25 +03:00
kutesir
a92e9d4c09 Today view: reorder sections + keep RSS feeds out of tasks
- Move the Overdue card to sit directly below today's active tasks
  (above Next 3 Days) so your real tasks stay at the top.
- Filter subscription/RSS calendar feeds (F1, TV shows, etc.) out of the
  Today/Tasks timeline; they remain in the Calendar tab. Birthdays and
  personal calendars are unaffected.

Note: also carries prior in-progress TodayView edits that were already
in the working tree before this session.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 19:29:25 +03:00
kutesir
800c7db76d fix: reset workout log each new day + new app logo
KC-1: Set completion was stored permanently on the program, so the same
program scheduled on back-to-back days (e.g. Shoulders Mon + Tue) kept
yesterday's checkmarks. Add resetSetsForNewDayIfNeeded() to clear every
set's isDone when the calendar day changes (cold launch, onAppear, and
scenePhase active). Streak history is untouched.

KC-2: Replace all 12 AppIcon sizes with the new KisaniCal mark, alpha
flattened onto RGB(26,29,34) so the 1024 App Store icon is fully opaque.

Add KisaniCal/ISSUES.md tracker (KC-1, KC-2: In Progress).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 19:29:25 +03:00
Robin Kutesa
324ddf9b0a feat: overdue tasks in red with quick postpone + task context menu
- Overdue card: red task titles, per-row "+1d" postpone, tappable complete.
- Task rows (overdue + day timeline) gain a press menu: Complete, Postpone,
  Pin/Unpin, Edit, Share, Delete.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 13:51:33 +03:00
Robin Kutesa
646cdf6a9b feat: My Tasks widget, event countdown redesign, completed section
- My Tasks widget: today's tasks with interactive check-off (ToggleTaskIntent)
  and a "+" that opens the app's add-task sheet; writes preserve all task
  fields and sync via the App Group.
- Event Countdown: AZURE/AWS-style header (accent name + countdown label +
  percent); tap the label to cycle days → weeks → time remaining.
- Today: collapsible "Completed" archive section below Upcoming.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 13:31:04 +03:00
Robin Kutesa
8b094691f5 feat: home/lock widgets, Health-aware streaks, workout editor, and entitlement fixes
Widgets (new KisaniCalWidgets extension)
- Event Countdown widget: configurable via AppIntent, pick from your events
  or set a custom name/date; dot-grid progress toward the event.
- Day Progress and Tasks-Done-Today widgets; lock screen widgets.
- Shared dot grid sizes circles to fill the widget evenly at any count.
- Tasks/calendar prefs now persist to the App Group so widgets read live data.

Health & streaks
- Persist HealthKit authorization and re-establish on launch (fixes the
  Today dashboard and streak sync disappearing after relaunch).
- Add a Health permission toggle to onboarding; unify Settings/Profile on the
  manager's state.
- Day streak counts from a logged Health workout OR marking all exercises
  complete; nudge to mark exercises complete even when Health logged the workout.

Workout editor
- Drag to reorder exercises and move them across sections (drag-and-drop);
  swipe to delete.
- Add-exercise sheet: global search and keep-adding-multiple with a running count.

Fixes
- Restore app entitlements link (Sign in with Apple, HealthKit, App Group, iCloud).
- Add HealthKit usage strings; widget Info.plist NSExtension + nested bundle id.
- Calendar "Connect" routes to Settings when access was denied.
- Bake DEVELOPMENT_TEAM and shared versions into project.yml.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 12:27:45 +03:00
Robin Kutesa
e5bd739499 feat: HealthKit workout sync, confirmation notification, health stats on Today dashboard
- HealthKitManager: add fetchWorkoutDates(from:to:) to read past workouts from Apple Health
- WorkoutViewModel: syncFromHealthKit() merges HealthKit workout dates into streak (runs on every foreground); checkPendingHealthConfirm() picks up confirmed workouts from notification action
- NotificationManager: WORKOUT_CONFIRM category with 'Yes, log it' action; scheduleWorkoutConfirm() fires weekly on scheduled workout days at configurable time (default 8pm); LOG_WORKOUT action writes pendingConfirm to UserDefaults
- SettingsView (Workout Settings): new HEALTH SYNC section with 'Sync now' button and 'Workout confirmation reminder' toggle + time picker
- TodayView: TodayHealthStrip shows steps, active calories, resting HR, and workout streak in a 4-pill row below the date header (only shown when HealthKit is authorized); refreshes on appear and foreground
- FAB: Matrix FAB padding fixed to match Today/Calendar position (.bottom 10)

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-02 13:10:32 +03:00
Robin Kutesa
0647583036 feat: iCloud KV Store sync for tasks, workout data, and settings
- Add NSUbiquitousKeyValueStore entitlement to KisaniCal.entitlements
- New CloudSyncManager: mirrors UserDefaults to iCloud KV Store on every save; restores to UserDefaults on fresh install when local data is missing; observes external changes to pull updates in real-time; guards against 1 MB limit
- TaskViewModel: restore from iCloud on init, push to iCloud on every save
- WorkoutViewModel: restore programs/schedule/activePid/completedDates from iCloud on init, push all four keys on every save
- ContentView: restoreSettings() + backupSettings() on appear and foreground — syncs ~18 small settings keys (appearance, tabs, tutorial flags, calendar prefs, workout notifications)

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 20:45:26 +03:00
Robin Kutesa
070dd77b4e feat: page tutorials for Today & Workout, FAB fix, quadrant color consistency
- Add first-visit tutorial cards for TodayView (3 steps) and WorkoutView (3 steps) using new InViewTutorialCard component; each has independent AppStorage completion flag
- Fix FAB hidden behind custom tab bar in MatrixView by moving NavigationStack inside outer ZStack so FAB sits at the correct safe area level
- Fix task colors throughout app to use quadrant.color/softColor instead of taskColor — tasks now consistently show orange/yellow/blue/green matching their matrix quadrant in Today timeline, calendar dots, and day view
- Fix WorkoutView background (move ignoresSafeArea out of ZStack children into .background modifier)

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 19:40:00 +03:00
Robin Kutesa
f96f09ec29 feat: calendar settings, matrix drill-down, FAB fix, in-app add calendar
- Calendar: redesign connect sheet with Local Calendars grouped view (Default/Other/Subscribed), per-calendar Show/Hide toggle, master enabled toggle, Do Not Disturb toggle; Add Calendar now in-app with Google/Outlook/iCloud/CalDAV/Exchange/Holidays/URL flows instead of opening iOS Calendar app
- Calendar: fix toggle icon (calendar.day.timeline.left / list.bullet.below.rectangle), maintain full month view when switching to task list mode
- Matrix: quadrant header tap drills into detail view (Overdue/Later/Completed sections), task tap opens edit sheet; fix navigationDestination iOS 16 compat
- Tasks: functional reminder picker in date sheet with inline time wheel; birthday NLP detection sets yearly recurrence; dynamic repeat option labels; quadrant badge picker replaces priority flags
- Notifications: fix actor isolation crash in mark-complete handler; per-task reminder scheduling uses reminderDate field; evening check-in notification
- FAB: fix + button hidden behind custom tab bar in TodayView, CalendarView, MatrixView — move background out of ZStack children into .background() modifier
- TaskItem: add reminderDate, recurrenceLabel, endDate, isAllDay fields; Quadrant adds roman/matrixLabel/color/softColor; TaskViewModel adds updateTask/pin/setDate/setCategory

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 13:14:14 +03:00
Robin Kutesa
8bf4d91053 Fix priority menu icons: use UIImage.withTintColor for exact colored flags
foregroundStyle is overridden by Menu tint; baking color into UIImage
with .alwaysOriginal rendering mode is the only reliable approach.

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 04:01:03 +03:00
Robin Kutesa
8f041c69f3 Add task priority (High/Medium/Low/None) with colored flag picker
Priority stored on TaskItem, shown as colored flag in add sheet toolbar
and as a small flag indicator on each task row.

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 03:57:48 +03:00
Robin Kutesa
0483bc04ea Rename 'Today' shortcut to 'Tasks', move to first position
Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 03:54:58 +03:00
Robin Kutesa
0c48ca888b Fix: tapping task notification now marks it complete
Tap body → marks complete + navigates to tasks.
Swipe action 'Mark Complete' → marks complete without opening app.
TaskViewModel.reload() called on foreground to sync UserDefaults changes
made while app was backgrounded.

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 03:52:10 +03:00
Robin Kutesa
12e3cfdd13 Revert app icon to original dark design, keep explicit size entries
Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 03:43:14 +03:00
Robin Kutesa
ff7800588e Fix notification icon: add all explicit iOS icon sizes to asset catalog
Single-size universal entry was not generating 20pt notification sizes.
Added all traditional sizes (20/29/40/60/76/83.5pt) so iOS notification
center finds the pre-baked icon directly.

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 03:40:00 +03:00
Robin Kutesa
228607fde6 Add rest timer with toggle — auto-starts after each set when enabled
Floating banner shows circular progress + MM:SS countdown with skip button.
Haptic + system sound fires when timer reaches zero. Duration and on/off
toggle live in Settings → Rest Timer sheet.

Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 03:30:00 +03:00
Robin Kutesa
0e085f7fec Fix app icon: full orange fill so it's visible in lock screen notifications
Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 03:20:32 +03:00
Robin Kutesa
5596bcbe6f Fix app icon background to orange so it's visible on lock screen notifications
Co-Authored-By: Kutesir <tqwyy79vzn@privaterelay.appleid.com>
2026-06-01 03:00:18 +03:00