Update Neon colors and show color circles in theme picker

- Update NeonMoodTint to use synthwave colors matching Neon voting style
  (cyan, lime, yellow, orange, magenta)
- Replace text label with 5 color circles in theme preview Colors row
- Remove unused textColor customization code and picker views
- Add .id(moodTint) to Month/Year views for color refresh
- Clean up various unused color-related code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-30 00:08:01 -06:00
parent 51c5777c03
commit bea2d3bbc9
58 changed files with 1142 additions and 967 deletions

View File

@@ -18,87 +18,92 @@ protocol ChartDataBuildable {
extension ChartDataBuildable {
public func buildGridData(withData data: [MoodEntryModel]) -> [Year: [Month: [ChartType]]] {
var returnData = [Int: [Int: [ChartType]]]()
if let earliestEntry = data.first,
let lastEntry = data.last {
let calendar = Calendar.current
let components = calendar.dateComponents([.year], from: earliestEntry.forDate)
let earliestYear = components.year!
let latestComponents = calendar.dateComponents([.year], from: lastEntry.forDate)
let latestYear = latestComponents.year!
for year in earliestYear...latestYear {
var allMonths = [Int: [ChartType]]()
// add back in if months header has leading (-1, ""),
// and add back gridItem
// var dayViews = [DayChartView]()
// for day in 0...32 {
// let view = DayChartView(color: Mood.missing.color,
// weekDay: 2,
// viewType: .text(String(day+1)))
// dayViews.append(view)
// }
// allMonths[0] = dayViews
for month in (1...12) {
var components = DateComponents()
components.month = month
components.year = year
let startDateOfMonth = Calendar.current.date(from: components)!
let items = data.filter({ entry in
let components = calendar.dateComponents([.month, .year], from: startDateOfMonth)
let entryComponents = calendar.dateComponents([.month, .year], from: entry.forDate)
return (components.month == entryComponents.month && components.year == entryComponents.year)
})
allMonths[month] = createViewFor(monthEntries: items, forMonth: startDateOfMonth)
}
returnData[year] = allMonths
}
}
return returnData
}
private func createViewFor(monthEntries: [MoodEntryModel], forMonth month: Date) -> [ChartType] {
var filledOutArray = [ChartType]()
guard let earliestEntry = data.first,
let lastEntry = data.last else { return [:] }
let calendar = Calendar.current
let range = calendar.range(of: .day, in: .month, for: month)!
// Pre-group entries by year/month/day in a single pass - O(n) instead of O(n*m)
// Key: "year-month-day" -> entry
var entriesByDate = [String: MoodEntryModel]()
for entry in data {
let components = calendar.dateComponents([.year, .month, .day], from: entry.forDate)
let key = "\(components.year!)-\(components.month!)-\(components.day!)"
entriesByDate[key] = entry
}
let earliestYear = calendar.component(.year, from: earliestEntry.forDate)
let latestYear = calendar.component(.year, from: lastEntry.forDate)
// Cache expensive lookups
let moodTint: MoodTintable.Type = UserDefaultsStore.moodTintable()
let shape = UserDefaultsStore.getCustomBGShape()
var returnData = [Int: [Int: [ChartType]]]()
for year in earliestYear...latestYear {
var allMonths = [Int: [ChartType]]()
for month in 1...12 {
var components = DateComponents()
components.month = month
components.year = year
guard let startDateOfMonth = calendar.date(from: components) else { continue }
allMonths[month] = createViewFor(
year: year,
month: month,
forMonth: startDateOfMonth,
entriesByDate: entriesByDate,
moodTint: moodTint,
shape: shape,
calendar: calendar
)
}
returnData[year] = allMonths
}
return returnData
}
private func createViewFor(
year: Int,
month: Int,
forMonth monthDate: Date,
entriesByDate: [String: MoodEntryModel],
moodTint: MoodTintable.Type,
shape: BGShape,
calendar: Calendar
) -> [ChartType] {
var filledOutArray = [ChartType]()
let range = calendar.range(of: .day, in: .month, for: monthDate)!
let numDays = range.count
for day in 1...numDays {
if let item = monthEntries.filter({ entry in
let components = calendar.dateComponents([.day], from: entry.forDate)
let date = components.day
return day == date
}).first {
let moodTint: MoodTintable.Type = UserDefaultsStore.moodTintable()
let key = "\(year)-\(month)-\(day)"
if let item = entriesByDate[key] {
// O(1) dictionary lookup instead of O(n) filter
let view = ChartType(color: moodTint.color(forMood: item.mood),
weekDay: Int(item.weekDay),
shape: UserDefaultsStore.getCustomBGShape())
shape: shape)
filledOutArray.append(view)
} else {
let thisDate = Calendar.current.date(bySetting: .day, value: day, of: month)!
let thisDate = calendar.date(bySetting: .day, value: day, of: monthDate)!
let view = ChartType(color: Mood.placeholder.color,
weekDay: Calendar.current.component(.weekday, from: thisDate),
shape: UserDefaultsStore.getCustomBGShape())
weekDay: calendar.component(.weekday, from: thisDate),
shape: shape)
filledOutArray.append(view)
}
}
for _ in filledOutArray.count...32 {
let view = ChartType(color: Mood.placeholder.color,
weekDay: 2,
shape: UserDefaultsStore.getCustomBGShape())
shape: shape)
filledOutArray.append(view)
}
return filledOutArray
}
}