Commit Graph

22 Commits

Author SHA1 Message Date
kutesir
c992554f99 tasks: add "every N weeks/months/days/years" recurrence (KC-70)
Some checks failed
CI / build-and-test (push) Has been cancelled
Recurrence previously only supported 5 fixed rules with no interval.
Adds TaskItem.recurrenceInterval (optional, nil = 1, so every existing
task is unaffected), a stepper in the shared create/edit sheet, quick-add
NLP for phrases like "every 2 weeks"/"biweekly"/"fortnightly", and
threads the interval through both countdown widgets so their progress
bars size correctly for biweekly/etc tasks too.

Built on KC-69's consolidated RecurrenceRule engine. Verified two things
by actually compiling and running standalone swiftc drivers rather than
just reading: the core interval math (44/44, unchanged from KC-69) and
the new quick-add regex patterns against realistic phrases including
"look into tru housing options every two weeks" (11/11 passing).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 00:15:45 +03:00
kutesir
6915e64b67 recurrence: consolidate 3 duplicate implementations into one shared, tested engine (KC-69)
Some checks failed
CI / build-and-test (push) Has been cancelled
Before adding "every N weeks/months" support, found the recurrence
window math was independently hand-written in three places (main app's
TaskItem.isOccurrence, and two separate widget extensions' countdown
progress calculations) with no shared code to keep them in sync.

Extracted the math into Shared/RecurrenceRule.swift (pure Foundation,
no framework deps) compiled into both the app and widget extension
targets via a new project.yml Shared/ source path, and pointed all
three call sites at it. Verified every case is identical to prior
behavior at interval==1 by compiling and running a standalone test
driver directly against the real file with swiftc - 38/38 passing,
including Jan-31-monthly and Feb-29-leap-year-yearly edge cases.

Groundwork only - no recurrenceInterval field on TaskItem yet, the
actual interval feature comes next on top of this.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 23:56:58 +03:00
kutesir
3512d55503 liveactivity+widgets: fix iOS 16.2 build error, extend createdAt to Bars widget (KC-66)
Some checks failed
CI / build-and-test (push) Has been cancelled
end(_:dismissalPolicy:) requires iOS 16.2 but LiveActivityManager.end
only gated to 16.1 (Live Activities' own minimum) - branch on
#available with the deprecated overload as fallback. Separately,
auditing all countdown widgets per user request found the "Event
Countdown (Bars)" widget family had its own independent start-date
resolution that never considered the task's real creation date at
all - EventEntity now carries createdAt and resolveSpan prefers it
the same way KC-65 already does for the dot-grid widget.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 22:52:12 +03:00
kutesir
3c71a233d7 liveactivity: fix deprecated end(using:dismissalPolicy:) warning (KC-64)
Some checks failed
CI / build-and-test (push) Has been cancelled
Omitting the content argument on activity.end(dismissalPolicy:)
resolved to the deprecated iOS 16.1 overload. Pass nil explicitly to
bind to end(content:dismissalPolicy:) instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 22:43:06 +03:00
kutesir
9723775cb6 onboarding+liveactivity+habits: 3 fixes from device feedback (KC-61)
Some checks failed
CI / build-and-test (push) Has been cancelled
1. Onboarding Habits caption now explicitly mentions the toggles are
   changeable in Settings, not just times/custom reminder.

2. TaskLiveActivity: removed the checkbox-look circle glyph (hourglass
   instead). iOS has no API for an app to block the system's swipe/dismiss
   gesture on a Live Activity -- not attempted. Added a real Stop control via
   a new StopCountdownIntent (LiveActivityIntent, iOS 17+) embedded directly
   in the card (lock screen '×' + Dynamic Island 'Stop Countdown' button) --
   the actual iOS-supported equivalent of 'long press for options', since
   Live Activities don't support notification-style long-press menus.

3. Habit notifications gain 'Not Today' (dismiss only, intentional no-op --
   the lifetime-tally philosophy has no concept of a logged miss) and 'Stop
   Tracking' (destructive-styled; flips the habit's master toggle off and
   cancels every pending notification for that type across all its slots).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 13:33:32 +03:00
kutesir
7bfa16aec4 widgets: add 'This Year' mode to Progress Dots (KC-53)
Some checks failed
CI / build-and-test (push) Has been cancelled
The Progress Dots lock-screen widget already supports Day/Week/Month via its
configuration picker — no code needed for those. Year was the only mode
missing. Added ProgressDotMode.year, a matching provider branch
(Calendar.dateInterval(of: .year)), and yearTitle(for:), mirroring the
existing day/week/month pattern exactly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 22:59:23 +03:00
kutesir
23d3d201f7 Settings/widget: drop decorative emoji; show real bundle version
- Remove 🎉 from the My Tasks widget empty state.
- Remove 𝕏 👾 📸 from Settings → Follow Us row.
- About row and About sheet now read the version from the bundle
  (new Bundle.marketingVersion / buildNumber / versionDisplay helpers)
  instead of a hardcoded "v1.0.0", so it always tracks the real build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 20:35:41 +03:00
kutesir
48e2f4fc10 Widgets/notifications: tracked-event auto-advance, lock-screen dots, Snooze labels, period milestones
- Bars widget: tracked ("Track Countdown") events now also advance — a completed
  or past (non-recurring) tracked event falls through to the next-nearest, and the
  refresh boundary covers the tracked event's expiry. Recurring tracked events
  still roll forward. Completes the KC-26 auto-advance for all paths.
- Progress Dots on the lock screen (accessoryRectangular): show 28 larger dots
  instead of 100 tiny ones, render with .primary for the vibrant tint, and use
  AccessoryWidgetBackground so it's legible (Home Screen keeps the 100-dot grid).
- Notifications: snooze action labels now read "Snooze 15 min/30 min/1 hour/
  2 hours" (lock screen) and "Snooze 15 Minutes…" (in-app Postpone menu).
- New period milestone notifications: recurring "One more week/month/year passed"
  at end of week (Sun 20:00), month (1st 09:00), and year (Jan 1 09:00); gated by
  a kisani.periodMilestones flag, scheduled via the existing reschedule path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 02:12:52 +03:00
kutesir
87c999c676 Today menu features, Matrix Move trim, widget auto-advance, Wenza logo (KC-23–26)
- Today ⋯ menu: implemented the placeholder actions.
  - Background: 5 selectable themes (Default/Warm/Cool/Mono/Paper), persisted.
  - Group & Sort: group by Date (default)/Priority/Category/Quadrant and sort by
    Smart/Due/Priority/Title; non-date groupings render via UpcomingSection.
  - Select: multi-select sheet with Select All/Deselect All and bulk
    Complete/Priority/Move/Delete.
  New isolated file TodayMenuFeatures.swift; added TaskViewModel.allActiveRows.
- Matrix "Move" submenu now lists only the other three quadrants (excludes the
  current one) using clear matrix labels.
- Event Countdown (Bars) widget auto-advances: each timeline entry re-resolves
  "nearest to finish" as of its own time and refreshes at the moment the current
  event expires, so it rolls to the next event on expiry/completion.
- Splash wordmark rebranded to "wenza." (regular-weight typewriter + orange dot).
- ISSUES.md: logged KC-23 (Pick Date + time-based reminders), KC-24 (Wenza
  rebrand), KC-25 (Move trim), KC-26 (widget auto-advance).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 19:53:14 +03:00
kutesir
81813530c8 Rebrand app to "Wenza" (display name + user-facing copy)
Renames the user-facing app to Wenza without changing identity:
- CFBundleDisplayName → "Wenza" (app) and "Wenza Widgets" (widget extension).
- Calendar/Health permission prompts now reference Wenza.
- In-app copy updated: sidebar title, Auth + Onboarding screens, Settings
  about/help rows, feedback email subject, tutorial text, widget description.

Bundle identifier, App Group, UserDefaults storage keys, team ID, and the
internal Xcode target/project names are intentionally unchanged, so this stays
the same App Store app with no user data loss. App Store listing name must be
changed separately in App Store Connect.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:31:51 +03:00
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
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
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
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
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