Fixed manually widget timeline refresh

Also fixes widgets displaying locations open until midnight
This commit is contained in:
Campbell 2026-01-13 18:13:27 -05:00
parent 26e419a41b
commit f78de2f6ff
Signed by: NinjaCheetah
GPG Key ID: 39C2500E1778B156
3 changed files with 21 additions and 12 deletions

View File

@ -289,7 +289,7 @@
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements; CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 26; CURRENT_PROJECT_VERSION = 27;
DEVELOPMENT_TEAM = 5GF7GKNTK4; DEVELOPMENT_TEAM = 5GF7GKNTK4;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = TigerDineWidgets/Info.plist; INFOPLIST_FILE = TigerDineWidgets/Info.plist;
@ -322,7 +322,7 @@
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements; CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 26; CURRENT_PROJECT_VERSION = 27;
DEVELOPMENT_TEAM = 5GF7GKNTK4; DEVELOPMENT_TEAM = 5GF7GKNTK4;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = TigerDineWidgets/Info.plist; INFOPLIST_FILE = TigerDineWidgets/Info.plist;
@ -478,7 +478,7 @@
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements; CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 26; CURRENT_PROJECT_VERSION = 27;
DEVELOPMENT_TEAM = 5GF7GKNTK4; DEVELOPMENT_TEAM = 5GF7GKNTK4;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@ -515,7 +515,7 @@
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements; CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 26; CURRENT_PROJECT_VERSION = 27;
DEVELOPMENT_TEAM = 5GF7GKNTK4; DEVELOPMENT_TEAM = 5GF7GKNTK4;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;

View File

@ -6,6 +6,7 @@
// //
import SwiftUI import SwiftUI
import WidgetKit
@Observable @Observable
class DiningModel { class DiningModel {
@ -74,6 +75,9 @@ class DiningModel {
// And then schedule push notifications. // And then schedule push notifications.
await scheduleAllPushes() await scheduleAllPushes()
// Then refresh widget timelines with the new data.
WidgetCenter.shared.reloadAllTimelines()
// And finally schedule a background refresh 6 hours from now. // And finally schedule a background refresh 6 hours from now.
scheduleNextRefresh() scheduleNextRefresh()
} }
@ -88,7 +92,6 @@ class DiningModel {
await getDaysRepresented() await getDaysRepresented()
let decoder = JSONDecoder() let decoder = JSONDecoder()
let cachedLocationsByDay = try decoder.decode([[DiningLocation]].self, from: (UserDefaults(suiteName: "group.dev.ninjacheetah.RIT-Dining")!.data(forKey: "cachedLocationsByDay")!)) let cachedLocationsByDay = try decoder.decode([[DiningLocation]].self, from: (UserDefaults(suiteName: "group.dev.ninjacheetah.RIT-Dining")!.data(forKey: "cachedLocationsByDay")!))
print(cachedLocationsByDay)
// Load cache, update open status, do a notification cleanup, and return. We only need to clean up because loading // Load cache, update open status, do a notification cleanup, and return. We only need to clean up because loading
// cache means that there can't be any new notifications to schedule since the last real data refresh. // cache means that there can't be any new notifications to schedule since the last real data refresh.

View File

@ -41,7 +41,10 @@ struct OpeningHoursGauge: View {
let width = geometry.size.width let width = geometry.size.width
let barHeight: CGFloat = 16 let barHeight: CGFloat = 16
let nowX = position(for: now, width: width) let startOfToday = Calendar.current.startOfDay(for: now)
let startOfTomorrow = Calendar.current.date(byAdding: .day, value: 1, to: startOfToday)!
let nowX = position(for: now, start: startOfToday, width: width)
ZStack(alignment: .leading) { ZStack(alignment: .leading) {
Capsule() Capsule()
@ -51,8 +54,12 @@ struct OpeningHoursGauge: View {
// We can skip drawing this entire capsule if the location is never open, since there would be no opening period // We can skip drawing this entire capsule if the location is never open, since there would be no opening period
// to draw. // to draw.
if let openTime = openTime, let closeTime = closeTime { if let openTime = openTime, let closeTime = closeTime {
let openX = position(for: openTime, width: width) let openX = position(for: openTime, start: startOfToday, width: width)
let closeX = position(for: closeTime, width: width) let closeX = position(
for: closeTime,
start: closeTime < openTime ? startOfTomorrow : startOfToday,
width: width
)
Capsule() Capsule()
.fill( .fill(
@ -77,10 +84,9 @@ struct OpeningHoursGauge: View {
.frame(height: 20) .frame(height: 20)
} }
private func position(for date: Date, width: CGFloat) -> CGFloat { private func position(for date: Date, start: Date, width: CGFloat) -> CGFloat {
let startOfDay = Calendar.current.startOfDay(for: date) let seconds = date.timeIntervalSince(start)
let seconds = date.timeIntervalSince(startOfDay) let normalized = seconds / dayDuration
let normalized = min(max(seconds / dayDuration, 0), 1)
return normalized * width return normalized * width
} }
} }