import WidgetKit import SwiftUI import AppIntents // MARK: - Shared Entry struct KisaniEntry: TimelineEntry { let date: Date let task: WidgetTask? let allTasks: [WidgetTask] let streak: Int } // MARK: - Shared Provider struct KisaniProvider: TimelineProvider { func placeholder(in context: Context) -> KisaniEntry { let sample = WidgetTask(id: UUID(), title: "Mums Birthday", dueDate: Date().addingTimeInterval(86400 * 60), isComplete: false, quadrant: "Urgent + Important", category: "birthday") return KisaniEntry(date: .now, task: sample, allTasks: [sample], streak: 7) } func getSnapshot(in context: Context, completion: @escaping (KisaniEntry) -> Void) { let tasks = loadWidgetTasks() completion(KisaniEntry(date: .now, task: nextDueTask(from: tasks), allTasks: tasks, streak: loadWorkoutStreak())) } func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { let tasks = loadWidgetTasks() let entry = KisaniEntry(date: .now, task: nextDueTask(from: tasks), allTasks: tasks, streak: loadWorkoutStreak()) // Refresh every 30 minutes or when app triggers WidgetCenter.reloadAllTimelines() let next = Calendar.current.date(byAdding: .minute, value: 30, to: .now)! completion(Timeline(entries: [entry], policy: .after(next))) } } // MARK: - Day Progress Widget ("Day done %") struct DayProgressWidget: Widget { let kind = "KisaniDayProgress" var body: some WidgetConfiguration { StaticConfiguration(kind: kind, provider: KisaniProvider()) { _ in ProgressDotView(period: .day, accent: WidgetTheme.accent) } .configurationDisplayName("Day Progress") .description("How much of today has elapsed, as a dot grid.") .supportedFamilies([.systemSmall, .systemMedium]) } } // MARK: - Lock Screen Widgets struct LockScreenWidget: Widget { let kind = "KisaniLockScreen" var body: some WidgetConfiguration { StaticConfiguration(kind: kind, provider: KisaniProvider()) { entry in if let task = entry.task { LockScreenRectView(task: task) } else { LockScreenRectView(task: WidgetTask(id: UUID(), title: "No tasks", dueDate: nil, isComplete: false, quadrant: "Urgent + Important", category: "reminder")) } } .configurationDisplayName("Task (Lock Screen)") .description("Glass countdown on your lock screen.") .supportedFamilies([.accessoryRectangular]) } } struct LockScreenCircularWidget: Widget { let kind = "KisaniLockCircle" var body: some WidgetConfiguration { StaticConfiguration(kind: kind, provider: KisaniProvider()) { entry in if let task = entry.task { LockScreenCircularView(task: task) } else { LockScreenCircularView(task: WidgetTask(id: UUID(), title: "–", dueDate: nil, isComplete: false, quadrant: "Urgent + Important", category: "reminder")) } } .configurationDisplayName("Days Left (Lock Screen)") .description("Circular countdown on your lock screen.") .supportedFamilies([.accessoryCircular]) } } // MARK: - Widget Bundle @main struct KisaniWidgetBundle: WidgetBundle { var body: some Widget { EventBarsWidget() MyTasksWidget() DayProgressWidget() LockScreenWidget() LockScreenCircularWidget() TaskLiveActivity() } }