Files
Reflect/Shared/ShowBasedOnVoteLogics.swift
Trey t f822927e98 Add interactive widget voting and fix warnings/bugs
Widget Features:
- Add inline voting to timeline widget when no entry exists for today
- Show random prompt from notification strings in voting mode
- Update vote widget to use simple icon style for selection
- Make stats bar full width in voted state view
- Add Localizable.strings to widget extension target

Bug Fixes:
- Fix inverted date calculation in InsightsViewModel streak logic
- Replace force unwraps with safe optional handling in widgets
- Replace fatalError calls with graceful error handling
- Fix CSV import safety in SettingsView

Warning Fixes:
- Add @retroactive to Color and Date extension conformances
- Update deprecated onChange(of:perform:) to new syntax
- Replace deprecated applicationIconBadgeNumber with setBadgeCount
- Replace deprecated UIApplication.shared.windows API
- Add @preconcurrency for Swift 6 protocol conformances
- Add missing widget family cases to switch statement
- Remove unused variables and #warning directives

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 16:23:12 -06:00

112 lines
4.3 KiB
Swift

//
// ShowBasedOnVoteLogics.swift
// Feels (iOS)
//
// Created by Trey Tartt on 2/17/22.
//
import SwiftUI
import SwiftData
/*
current day 3/5/22
..... before time | after time .....
day option = .today
-------
voting for 3/4 | voting for 3/5
------------------------*-------------------------
db should contain 3/3 | db should contain 3/4
----------------------------------------------------------------------------
day option = .yesterday
--------
voting for 3/3 | voting for 3/4
------------------------*-------------------------
db should contain 3/2 | db should contain 3/3
*/
@MainActor
class ShowBasedOnVoteLogics {
static private func returnCurrentVoteStatus(onboardingData: OnboardingData) -> (passedTimeToVote: Bool, inputDay: DayOptions) {
let passedTimeToVote = ShowBasedOnVoteLogics.passedTodaysVotingUnlock(voteDate: onboardingData.date)
let inputDay: DayOptions = onboardingData.inputDay
return (passedTimeToVote, inputDay)
}
static public func passedTodaysVotingUnlock(voteDate: Date) -> Bool {
let currentDateComp = Calendar.current.dateComponents([.hour, .minute], from: Date())
let savedDateComp = Calendar.current.dateComponents([.hour, .minute], from: voteDate)
if let currentHour = currentDateComp.hour,
let currentMin = currentDateComp.minute,
let savedHour = savedDateComp.hour,
let savedMin = savedDateComp.minute {
if currentHour > savedHour {
return true
}
if currentHour == savedHour {
return currentMin >= savedMin
}
}
return false
}
static public func isMissingCurrentVote(onboardingData: OnboardingData) -> Bool {
let startDate = ShowBasedOnVoteLogics.getCurrentVotingDate(onboardingData: onboardingData).startOfDay
let entry = DataController.shared.getEntry(byDate: startDate)
return entry == nil || entry?.mood == .missing
}
static public func getCurrentVotingDate(onboardingData: OnboardingData) -> Date {
var date: Date?
let currentVoteStatus = ShowBasedOnVoteLogics.returnCurrentVoteStatus(onboardingData: onboardingData)
// note to future self, this should account for midnight until next voting unlock
// the vote at 12:03 am will not be passed time, and will be for yesterday
switch (currentVoteStatus.passedTimeToVote, currentVoteStatus.inputDay) {
case (false, .Today):
// if we're passed time to vote and the voting type is previous - last vote should be -1
date = Calendar.current.date(byAdding: .day, value: -1, to: Date())
case (true, .Today):
// if we're passed time to vote and the voting type is previous - last vote should be today
date = Date()
case (false, .Previous):
// if we're passed time to vote and the voting type is previous - last vote should be -2
date = Calendar.current.date(byAdding: .day, value: -2, to: Date())
case (true, .Previous):
// if we're passed time to vote and the voting type is previous - last vote should be -1
date = Calendar.current.date(byAdding: .day, value: -1, to: Date())
}
guard let date = date else {
fatalError("missing getCurrentVotingDate")
}
return date
}
static public func getVotingTitle(onboardingData: OnboardingData) -> String {
let currentVoteStatus = ShowBasedOnVoteLogics.returnCurrentVoteStatus(onboardingData: onboardingData)
switch (currentVoteStatus.passedTimeToVote, currentVoteStatus.inputDay) {
case (false, .Today):
return String(localized: "add_mood_header_view_title_yesterday")
case (true, .Today):
return String(localized: "add_mood_header_view_title_today")
case (false, .Previous):
let date = Calendar.current.date(byAdding: .day, value: -2, to: Date())!
return String(format: String(localized: "add_mood_header_view_title"), Random.weekdayName(fromDate: date))
case (true, .Previous):
return String(localized: "add_mood_header_view_title_yesterday")
}
}
}