Merge develop -> main: full session (KC-51 through KC-71) #28
@@ -1987,3 +1987,45 @@ editable custom slot)
|
|||||||
custom reminder still reads sensibly if enabled.
|
custom reminder still reads sensibly if enabled.
|
||||||
|
|
||||||
Files: `SettingsView.swift`, `NotificationManager.swift`.
|
Files: `SettingsView.swift`, `NotificationManager.swift`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## KC-59 — "Complete & Stop Series" for recurring tasks (distinct from Delete)
|
||||||
|
|
||||||
|
**Status:** Implemented (not build-verified)
|
||||||
|
**Reported by:** User: "for any reoccurring tasks in calendar and tasks view
|
||||||
|
can we put a complete and also stop series and not delete — for example if i
|
||||||
|
want to complete and stop a series from running"
|
||||||
|
|
||||||
|
### Description
|
||||||
|
Recurring tasks previously had only two menu actions relevant here: toggle
|
||||||
|
today's occurrence (series continues forever), or **Delete** (erases the task
|
||||||
|
and its entire `completedOccurrences` history — no way to "wind down" a
|
||||||
|
series while keeping its record).
|
||||||
|
|
||||||
|
### Change
|
||||||
|
- `TaskViewModel.completeAndStopSeries(_:on:)`: marks the given occurrence
|
||||||
|
(default: today) complete, then sets `recurrenceEnd` to that day — which
|
||||||
|
`isOccurrence` already respects (a field that existed in the model but had
|
||||||
|
no UI to set it). The task itself, its title, and its full
|
||||||
|
`completedOccurrences` history are all preserved — only future occurrences
|
||||||
|
stop generating. Genuinely different from `delete(_:)`.
|
||||||
|
- New "Complete & Stop Series" item in the shared `TaskMenuItems` (used by
|
||||||
|
Today, Matrix, and Calendar's day/week/3-day timelines) — shown only when
|
||||||
|
`task.isRecurring`.
|
||||||
|
- Wired through **all 8** `TaskMenuItems` call sites across `TodayView`
|
||||||
|
(`OverdueCard`, `UpcomingSection`), `MatrixView` (`QuadrantCard`,
|
||||||
|
`QuadrantDetailView` ×3), and `CalendarView` (main view, `DayTimelineView`,
|
||||||
|
the timeline-block context menu) — some needed a new optional closure
|
||||||
|
threaded through an intermediate wrapper view, others had `taskVM` directly.
|
||||||
|
|
||||||
|
Files: `TaskItem.swift`, `TaskContextMenu.swift`, `TodayView.swift`,
|
||||||
|
`MatrixView.swift`, `CalendarView.swift`.
|
||||||
|
|
||||||
|
### Note
|
||||||
|
Not build-verified (no iOS runtime here). Self-reviewed: balanced braces/
|
||||||
|
parens confirmed per-file via `git diff` (one file had a pre-existing +1 paren
|
||||||
|
offset from an unrelated comment, verified via stash — not introduced by this
|
||||||
|
change). `OverdueCard`'s wiring is technically unreachable today since
|
||||||
|
`overdueTasks` already excludes recurring tasks by design — wired anyway for
|
||||||
|
consistency in case that changes.
|
||||||
|
|||||||
@@ -405,6 +405,21 @@ class TaskViewModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Complete a recurring task's occurrence AND stop the series — distinct
|
||||||
|
/// from Delete, which erases the task (and every past completion) outright.
|
||||||
|
/// The task, its title, and its full completedOccurrences history stay
|
||||||
|
/// intact; only occurrences after `date` stop being generated (via
|
||||||
|
/// `recurrenceEnd`, which `isOccurrence` already respects).
|
||||||
|
func completeAndStopSeries(_ t: TaskItem, on date: Date = Date()) {
|
||||||
|
guard let idx = tasks.firstIndex(where: { $0.id == t.id }) else { return }
|
||||||
|
let key = occurrenceKey(date)
|
||||||
|
var set = Set(tasks[idx].completedOccurrences ?? [])
|
||||||
|
set.insert(key) // ensure done — never toggles off
|
||||||
|
tasks[idx].completedOccurrences = Array(set)
|
||||||
|
tasks[idx].recurrenceEnd = Calendar.current.startOfDay(for: date)
|
||||||
|
save()
|
||||||
|
}
|
||||||
|
|
||||||
/// A display copy of a recurring task pinned to one occurrence date, with that
|
/// A display copy of a recurring task pinned to one occurrence date, with that
|
||||||
/// occurrence's completion baked into `isComplete` (so existing rows just work).
|
/// occurrence's completion baked into `isComplete` (so existing rows just work).
|
||||||
func occurrenceCopy(_ t: TaskItem, on date: Date) -> TaskItem {
|
func occurrenceCopy(_ t: TaskItem, on date: Date) -> TaskItem {
|
||||||
|
|||||||
@@ -615,6 +615,7 @@ struct CalendarView: View {
|
|||||||
onPin: { taskVM.pin($0) },
|
onPin: { taskVM.pin($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onSetDate: { taskVM.setDate($0, date: $1) },
|
onSetDate: { taskVM.setDate($0, date: $1) },
|
||||||
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
||||||
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
||||||
@@ -1081,7 +1082,8 @@ struct CalendarView: View {
|
|||||||
onSetPriority: { taskVM.setPriority($0, priority: $1) },
|
onSetPriority: { taskVM.setPriority($0, priority: $1) },
|
||||||
onSetCategory: { taskVM.setCategory($0, category: $1) },
|
onSetCategory: { taskVM.setCategory($0, category: $1) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) }
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1807,6 +1809,7 @@ struct DayTimelineView: View {
|
|||||||
var onPostpone: ((TaskItem) -> Void)? = nil
|
var onPostpone: ((TaskItem) -> Void)? = nil
|
||||||
var onEdit: ((TaskItem) -> Void)? = nil
|
var onEdit: ((TaskItem) -> Void)? = nil
|
||||||
var onDelete: ((TaskItem) -> Void)? = nil
|
var onDelete: ((TaskItem) -> Void)? = nil
|
||||||
|
var onCompleteAndStopSeries: ((TaskItem) -> Void)? = nil
|
||||||
var onSetDate: ((TaskItem, Date?) -> Void)? = nil
|
var onSetDate: ((TaskItem, Date?) -> Void)? = nil
|
||||||
var onPostponeMinutes: ((TaskItem, Int) -> Void)? = nil
|
var onPostponeMinutes: ((TaskItem, Int) -> Void)? = nil
|
||||||
var onMove: ((TaskItem, Quadrant) -> Void)? = nil
|
var onMove: ((TaskItem, Quadrant) -> Void)? = nil
|
||||||
@@ -1979,7 +1982,8 @@ struct DayTimelineView: View {
|
|||||||
onResetMatrixUrgency: onResetMatrixUrgency,
|
onResetMatrixUrgency: onResetMatrixUrgency,
|
||||||
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
||||||
onEdit: onEdit,
|
onEdit: onEdit,
|
||||||
onDelete: { onDelete?($0) }
|
onDelete: { onDelete?($0) },
|
||||||
|
onCompleteAndStopSeries: { onCompleteAndStopSeries?($0) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ struct MatrixView: View {
|
|||||||
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onTapHeader: { drillQuadrant = .urgent; showDrill = true }
|
onTapHeader: { drillQuadrant = .urgent; showDrill = true }
|
||||||
)
|
)
|
||||||
QuadrantCard(
|
QuadrantCard(
|
||||||
@@ -93,6 +94,7 @@ struct MatrixView: View {
|
|||||||
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onTapHeader: { drillQuadrant = .schedule; showDrill = true }
|
onTapHeader: { drillQuadrant = .schedule; showDrill = true }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -118,6 +120,7 @@ struct MatrixView: View {
|
|||||||
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onTapHeader: { drillQuadrant = .delegate_; showDrill = true }
|
onTapHeader: { drillQuadrant = .delegate_; showDrill = true }
|
||||||
)
|
)
|
||||||
QuadrantCard(
|
QuadrantCard(
|
||||||
@@ -139,6 +142,7 @@ struct MatrixView: View {
|
|||||||
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onTapHeader: { drillQuadrant = .eliminate; showDrill = true }
|
onTapHeader: { drillQuadrant = .eliminate; showDrill = true }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -211,6 +215,7 @@ struct QuadrantCard: View {
|
|||||||
var onResetMatrixUrgency: ((TaskItem) -> Void)? = nil
|
var onResetMatrixUrgency: ((TaskItem) -> Void)? = nil
|
||||||
var onEdit: ((TaskItem) -> Void)? = nil
|
var onEdit: ((TaskItem) -> Void)? = nil
|
||||||
var onDelete: ((TaskItem) -> Void)? = nil
|
var onDelete: ((TaskItem) -> Void)? = nil
|
||||||
|
var onCompleteAndStopSeries: ((TaskItem) -> Void)? = nil
|
||||||
var onTapHeader: (() -> Void)? = nil
|
var onTapHeader: (() -> Void)? = nil
|
||||||
|
|
||||||
private let shortFmt: DateFormatter = {
|
private let shortFmt: DateFormatter = {
|
||||||
@@ -326,7 +331,8 @@ struct QuadrantCard: View {
|
|||||||
onResetMatrixUrgency: { t in withAnimation(KisaniSpring.snappy) { onResetMatrixUrgency?(t) } },
|
onResetMatrixUrgency: { t in withAnimation(KisaniSpring.snappy) { onResetMatrixUrgency?(t) } },
|
||||||
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
||||||
onEdit: onEdit.map { cb in { cb($0) } },
|
onEdit: onEdit.map { cb in { cb($0) } },
|
||||||
onDelete: { t in withAnimation(KisaniSpring.snappy) { onDelete?(t) } }
|
onDelete: { t in withAnimation(KisaniSpring.snappy) { onDelete?(t) } },
|
||||||
|
onCompleteAndStopSeries: { t in withAnimation(KisaniSpring.snappy) { onCompleteAndStopSeries?(t) } }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -487,7 +493,8 @@ struct QuadrantDetailView: View {
|
|||||||
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
||||||
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) }
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if task.id != overdueTasks.last?.id { Divider().padding(.leading, 46) }
|
if task.id != overdueTasks.last?.id { Divider().padding(.leading, 46) }
|
||||||
@@ -514,7 +521,8 @@ struct QuadrantDetailView: View {
|
|||||||
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
||||||
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) }
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if task.id != laterTasks.last?.id { Divider().padding(.leading, 46) }
|
if task.id != laterTasks.last?.id { Divider().padding(.leading, 46) }
|
||||||
@@ -542,7 +550,8 @@ struct QuadrantDetailView: View {
|
|||||||
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
onResetMatrixUrgency: { taskVM.resetMatrixUrgencyOverride($0) },
|
||||||
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
onLiveActivity:{ LiveActivityManager.toggle(for: $0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) }
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if task.id != displayed.last?.id { Divider().padding(.leading, 46) }
|
if task.id != displayed.last?.id { Divider().padding(.leading, 46) }
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ struct TaskMenuItems: View {
|
|||||||
var onLiveActivity:(TaskItem) -> Void = { LiveActivityManager.toggle(for: $0) }
|
var onLiveActivity:(TaskItem) -> Void = { LiveActivityManager.toggle(for: $0) }
|
||||||
var onEdit: ((TaskItem) -> Void)? = nil
|
var onEdit: ((TaskItem) -> Void)? = nil
|
||||||
var onDelete: (TaskItem) -> Void = { _ in }
|
var onDelete: (TaskItem) -> Void = { _ in }
|
||||||
|
/// Complete today's occurrence AND stop the series — keeps the task and its
|
||||||
|
/// full completion history (unlike Delete, which erases both).
|
||||||
|
var onCompleteAndStopSeries: (TaskItem) -> Void = { _ in }
|
||||||
|
|
||||||
private var cal: Calendar { .current }
|
private var cal: Calendar { .current }
|
||||||
|
|
||||||
@@ -132,6 +135,12 @@ struct TaskMenuItems: View {
|
|||||||
Button { onEdit(task) } label: { Label("Edit", systemImage: "pencil") }
|
Button { onEdit(task) } label: { Label("Edit", systemImage: "pencil") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if task.isRecurring {
|
||||||
|
Button { onCompleteAndStopSeries(task) } label: {
|
||||||
|
Label("Complete & Stop Series", systemImage: "checkmark.circle.badge.xmark")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
Button(role: .destructive) { onDelete(task) } label: {
|
Button(role: .destructive) { onDelete(task) } label: {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ struct TodayView: View {
|
|||||||
onPin: { taskVM.pin($0) },
|
onPin: { taskVM.pin($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onSetDate: { taskVM.setDate($0, date: $1) },
|
onSetDate: { taskVM.setDate($0, date: $1) },
|
||||||
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
||||||
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
||||||
@@ -159,6 +160,7 @@ struct TodayView: View {
|
|||||||
onPin: { taskVM.pin($0) },
|
onPin: { taskVM.pin($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onSetDate: { taskVM.setDate($0, date: $1) },
|
onSetDate: { taskVM.setDate($0, date: $1) },
|
||||||
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
||||||
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
||||||
@@ -180,6 +182,7 @@ struct TodayView: View {
|
|||||||
onPin: { taskVM.pin($0) },
|
onPin: { taskVM.pin($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onSetDate: { taskVM.setDate($0, date: $1) },
|
onSetDate: { taskVM.setDate($0, date: $1) },
|
||||||
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
||||||
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
||||||
@@ -199,6 +202,7 @@ struct TodayView: View {
|
|||||||
onPin: { taskVM.pin($0) },
|
onPin: { taskVM.pin($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onSetDate: { taskVM.setDate($0, date: $1) },
|
onSetDate: { taskVM.setDate($0, date: $1) },
|
||||||
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
||||||
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
||||||
@@ -218,6 +222,7 @@ struct TodayView: View {
|
|||||||
onPin: { taskVM.pin($0) },
|
onPin: { taskVM.pin($0) },
|
||||||
onEdit: { editingTask = $0 },
|
onEdit: { editingTask = $0 },
|
||||||
onDelete: { taskVM.delete($0) },
|
onDelete: { taskVM.delete($0) },
|
||||||
|
onCompleteAndStopSeries: { taskVM.completeAndStopSeries($0) },
|
||||||
onSetDate: { taskVM.setDate($0, date: $1) },
|
onSetDate: { taskVM.setDate($0, date: $1) },
|
||||||
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
onPostponeMinutes: { taskVM.postpone($0, minutes: $1) },
|
||||||
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
onMove: { taskVM.moveToQuadrant(taskID: $0.id, quadrant: $1) },
|
||||||
@@ -601,6 +606,7 @@ struct OverdueCard: View {
|
|||||||
var onPin: (TaskItem) -> Void = { _ in }
|
var onPin: (TaskItem) -> Void = { _ in }
|
||||||
var onEdit: (TaskItem) -> Void = { _ in }
|
var onEdit: (TaskItem) -> Void = { _ in }
|
||||||
var onDelete: (TaskItem) -> Void = { _ in }
|
var onDelete: (TaskItem) -> Void = { _ in }
|
||||||
|
var onCompleteAndStopSeries: (TaskItem) -> Void = { _ in }
|
||||||
var onSetDate: (TaskItem, Date?) -> Void = { _, _ in }
|
var onSetDate: (TaskItem, Date?) -> Void = { _, _ in }
|
||||||
var onPostponeMinutes: (TaskItem, Int) -> Void = { _, _ in }
|
var onPostponeMinutes: (TaskItem, Int) -> Void = { _, _ in }
|
||||||
var onMove: (TaskItem, Quadrant) -> Void = { _, _ in }
|
var onMove: (TaskItem, Quadrant) -> Void = { _, _ in }
|
||||||
@@ -712,7 +718,8 @@ struct OverdueCard: View {
|
|||||||
onResetMatrixUrgency: onResetMatrixUrgency,
|
onResetMatrixUrgency: onResetMatrixUrgency,
|
||||||
onLiveActivity: { LiveActivityManager.toggle(for: $0) },
|
onLiveActivity: { LiveActivityManager.toggle(for: $0) },
|
||||||
onEdit: onEdit,
|
onEdit: onEdit,
|
||||||
onDelete: onDelete
|
onDelete: onDelete,
|
||||||
|
onCompleteAndStopSeries: onCompleteAndStopSeries
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1018,6 +1025,7 @@ struct UpcomingSection: View {
|
|||||||
var onPin: (TaskItem) -> Void = { _ in }
|
var onPin: (TaskItem) -> Void = { _ in }
|
||||||
var onEdit: (TaskItem) -> Void = { _ in }
|
var onEdit: (TaskItem) -> Void = { _ in }
|
||||||
let onDelete: (TaskItem) -> Void
|
let onDelete: (TaskItem) -> Void
|
||||||
|
var onCompleteAndStopSeries: (TaskItem) -> Void = { _ in }
|
||||||
var onSetDate: (TaskItem, Date?) -> Void = { _, _ in }
|
var onSetDate: (TaskItem, Date?) -> Void = { _, _ in }
|
||||||
var onPostponeMinutes: (TaskItem, Int) -> Void = { _, _ in }
|
var onPostponeMinutes: (TaskItem, Int) -> Void = { _, _ in }
|
||||||
var onMove: (TaskItem, Quadrant) -> Void = { _, _ in }
|
var onMove: (TaskItem, Quadrant) -> Void = { _, _ in }
|
||||||
@@ -1091,7 +1099,8 @@ struct UpcomingSection: View {
|
|||||||
onResetMatrixUrgency: onResetMatrixUrgency,
|
onResetMatrixUrgency: onResetMatrixUrgency,
|
||||||
onLiveActivity: { LiveActivityManager.toggle(for: $0) },
|
onLiveActivity: { LiveActivityManager.toggle(for: $0) },
|
||||||
onEdit: onEdit,
|
onEdit: onEdit,
|
||||||
onDelete: { task in withAnimation(KisaniSpring.snappy) { onDelete(task) } }
|
onDelete: { task in withAnimation(KisaniSpring.snappy) { onDelete(task) } },
|
||||||
|
onCompleteAndStopSeries: { task in withAnimation(KisaniSpring.snappy) { onCompleteAndStopSeries(task) } }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 18)
|
.padding(.horizontal, 18)
|
||||||
|
|||||||
Reference in New Issue
Block a user