Merge develop -> main: full session (KC-51 through KC-71) #28
@@ -2118,3 +2118,50 @@ Not build-verified (no iOS runtime here). Self-reviewed: balanced braces/
|
||||
parens confirmed per-file. `StopCountdownIntent` needs to land in the
|
||||
KisaniCalWidgets target (already covered by `project.yml`'s `sources: -path:
|
||||
KisaniCalWidgets` glob — no project.yml change needed).
|
||||
|
||||
## KC-62 — Task row category pill replaced with TickTick-style icon glyphs
|
||||
|
||||
Status: Implemented (not build-verified — no iOS runtime here)
|
||||
Reported by: User, from device screenshots ("reminder labeling a bit too
|
||||
much, let's do it just like TickTick... show countdown info too")
|
||||
Area: Today (task rows, both the top mini-timeline and the Tomorrow/Next 7
|
||||
Days/Later list)
|
||||
|
||||
### Description
|
||||
Every task row rendered a `TagChip` text badge showing `task.category
|
||||
.rawValue` — for the vast majority of tasks (the default `.reminder`
|
||||
category) this just says "Reminder" on nearly every row, adding no real
|
||||
information. Confirmed only 2 call sites exist app-wide (`grep -rn
|
||||
"TagChip(" KisaniCal/Views/*.swift`), both in `TodayView.swift` — Matrix and
|
||||
Calendar don't render this pill at all, so "everywhere" (user's chosen
|
||||
scope) resolves to these two.
|
||||
|
||||
### Change
|
||||
- Added `TaskCategory.glyph: String?` (`TaskItem.swift`) — maps each
|
||||
category to a small SF Symbol, `nil` for `.reminder` (the generic default
|
||||
stays unmarked, matching TickTick's "no badge unless it says something"
|
||||
density): `.birthday → gift.fill`, `.domain → briefcase.fill`, `.annual →
|
||||
calendar`, `.custom → tag.fill`.
|
||||
- **`TaskRowView`** (Tomorrow/Next 7 Days/Later rows — matches the user's
|
||||
screenshot exactly): removed the `TagChip` call outright and folded the
|
||||
category glyph into the row's existing ⏰/↻ icon `HStack`. This row
|
||||
already carried a countdown (`countdownLabel(to:)`) next to the due date,
|
||||
so "show countdown info too" was already satisfied — no countdown change
|
||||
needed here.
|
||||
- **`TodayTLRow`** (top mini-timeline — Overdue/Today/Next 3 Days/Upcoming):
|
||||
same glyph swap, and while in there also added the ⏰/↻ indicators this
|
||||
row was missing (it only had the category pill before). No standalone
|
||||
countdown text added here — the leading time-track column already shows
|
||||
either the time-of-day or the short date (`MMM d`) for non-today entries,
|
||||
so a duplicate "in X days" string would be redundant clutter in an already
|
||||
dense timeline row.
|
||||
|
||||
Files: `KisaniCal/Models/TaskItem.swift`, `KisaniCal/Views/TodayView.swift`.
|
||||
|
||||
### Note
|
||||
Not build-verified (no iOS runtime here). Self-reviewed: balanced braces/
|
||||
parens confirmed per-file (`TaskItem.swift` has one pre-existing stray `(`
|
||||
imbalance confirmed via `git stash` to predate this change — a comment
|
||||
artifact, not introduced here). `TagChip` itself is left intact in
|
||||
`SharedComponents.swift` since it's a generic shared component, just no
|
||||
longer called from these two sites.
|
||||
|
||||
@@ -104,6 +104,18 @@ enum TaskCategory: String, Codable {
|
||||
case domain = "Domain"
|
||||
case annual = "Annual"
|
||||
case custom = "Custom"
|
||||
|
||||
/// Icon-only glyph for task rows — `.reminder` is the generic default
|
||||
/// and stays unmarked so the badge only appears when it adds information.
|
||||
var glyph: String? {
|
||||
switch self {
|
||||
case .reminder: return nil
|
||||
case .birthday: return "gift.fill"
|
||||
case .domain: return "briefcase.fill"
|
||||
case .annual: return "calendar"
|
||||
case .custom: return "tag.fill"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TaskColor: String, Codable {
|
||||
|
||||
@@ -564,11 +564,25 @@ private struct TodayTLRow: View {
|
||||
}
|
||||
}
|
||||
Spacer(minLength: 0)
|
||||
TagChip(
|
||||
text: entry.task.category.rawValue,
|
||||
color: entry.color,
|
||||
bg: entry.task.quadrant.softColor
|
||||
)
|
||||
// TickTick-style — icon only, no text badge; date/time already
|
||||
// shown in the leading time-track column for this row.
|
||||
HStack(spacing: 5) {
|
||||
if let glyph = entry.task.category.glyph {
|
||||
Image(systemName: glyph)
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(entry.color)
|
||||
}
|
||||
if entry.task.reminderDate != nil || entry.task.constantReminder {
|
||||
Image(systemName: "alarm")
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(AppColors.text3(cs))
|
||||
}
|
||||
if entry.task.isRecurring {
|
||||
Image(systemName: "repeat")
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(AppColors.text3(cs))
|
||||
}
|
||||
}
|
||||
Button(action: onToggle) {
|
||||
ZStack {
|
||||
RoundedRectangle(cornerRadius: 5, style: .continuous)
|
||||
@@ -1357,8 +1371,13 @@ struct TaskRowView: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
// ⏰ reminder · 🔁 recurring indicators
|
||||
// ⏰ reminder · 🔁 recurring · tag icon indicators (TickTick-style — icon only, no text badge)
|
||||
HStack(spacing: 5) {
|
||||
if let glyph = task.category.glyph {
|
||||
Image(systemName: glyph)
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(task.quadrant.color)
|
||||
}
|
||||
if task.reminderDate != nil || task.constantReminder {
|
||||
Image(systemName: "alarm")
|
||||
.font(.system(size: 11))
|
||||
@@ -1370,12 +1389,6 @@ struct TaskRowView: View {
|
||||
.foregroundColor(AppColors.text3(cs))
|
||||
}
|
||||
}
|
||||
|
||||
TagChip(
|
||||
text: task.category.rawValue,
|
||||
color: task.quadrant.color,
|
||||
bg: task.quadrant.softColor
|
||||
)
|
||||
.padding(.trailing, 9)
|
||||
}
|
||||
.frame(minHeight: 48)
|
||||
|
||||
Reference in New Issue
Block a user