tasks: replace category text pill with TickTick-style icon glyphs (KC-62)
Every task row was tagging itself "Reminder" via a text badge for the default category, adding no information. Swapped for icon-only glyphs (nil for the generic .reminder case) folded into the existing alarm/ repeat indicator row; countdown/date info was already present or redundant with the leading time-track, so no separate countdown text was added. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
parens confirmed per-file. `StopCountdownIntent` needs to land in the
|
||||||
KisaniCalWidgets target (already covered by `project.yml`'s `sources: -path:
|
KisaniCalWidgets target (already covered by `project.yml`'s `sources: -path:
|
||||||
KisaniCalWidgets` glob — no project.yml change needed).
|
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 domain = "Domain"
|
||||||
case annual = "Annual"
|
case annual = "Annual"
|
||||||
case custom = "Custom"
|
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 {
|
enum TaskColor: String, Codable {
|
||||||
|
|||||||
@@ -564,11 +564,25 @@ private struct TodayTLRow: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(minLength: 0)
|
Spacer(minLength: 0)
|
||||||
TagChip(
|
// TickTick-style — icon only, no text badge; date/time already
|
||||||
text: entry.task.category.rawValue,
|
// shown in the leading time-track column for this row.
|
||||||
color: entry.color,
|
HStack(spacing: 5) {
|
||||||
bg: entry.task.quadrant.softColor
|
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) {
|
Button(action: onToggle) {
|
||||||
ZStack {
|
ZStack {
|
||||||
RoundedRectangle(cornerRadius: 5, style: .continuous)
|
RoundedRectangle(cornerRadius: 5, style: .continuous)
|
||||||
@@ -1357,8 +1371,13 @@ struct TaskRowView: View {
|
|||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
// ⏰ reminder · 🔁 recurring indicators
|
// ⏰ reminder · 🔁 recurring · tag icon indicators (TickTick-style — icon only, no text badge)
|
||||||
HStack(spacing: 5) {
|
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 {
|
if task.reminderDate != nil || task.constantReminder {
|
||||||
Image(systemName: "alarm")
|
Image(systemName: "alarm")
|
||||||
.font(.system(size: 11))
|
.font(.system(size: 11))
|
||||||
@@ -1370,12 +1389,6 @@ struct TaskRowView: View {
|
|||||||
.foregroundColor(AppColors.text3(cs))
|
.foregroundColor(AppColors.text3(cs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TagChip(
|
|
||||||
text: task.category.rawValue,
|
|
||||||
color: task.quadrant.color,
|
|
||||||
bg: task.quadrant.softColor
|
|
||||||
)
|
|
||||||
.padding(.trailing, 9)
|
.padding(.trailing, 9)
|
||||||
}
|
}
|
||||||
.frame(minHeight: 48)
|
.frame(minHeight: 48)
|
||||||
|
|||||||
Reference in New Issue
Block a user