|
|
|
|
@ -11,33 +11,33 @@ import Intents |
|
|
|
|
|
|
|
|
|
struct Provider: IntentTimelineProvider { |
|
|
|
|
func placeholder(in context: Context) -> SimpleEntry { |
|
|
|
|
SimpleEntry(countdowns: [], date: Date(), configuration: SelectCountdownIntent()) |
|
|
|
|
SimpleEntry(timers: [], date: Date(), configuration: SelectTimerIntent()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getSnapshot(for configuration: SelectCountdownIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) { |
|
|
|
|
func getSnapshot(for configuration: SelectTimerIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) { |
|
|
|
|
|
|
|
|
|
guard let cp = configuration.countdown |
|
|
|
|
guard let cp = configuration.timer |
|
|
|
|
else { |
|
|
|
|
completion(placeholder(in: context)) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let countdowns: [Countdown] = cp.compactMap { |
|
|
|
|
let timers: [AbstractTimer] = cp.compactMap { |
|
|
|
|
if let id = $0.identifier { |
|
|
|
|
return IntentDataProvider.main.countdown(id: id) |
|
|
|
|
return IntentDataProvider.main.timer(id: id) |
|
|
|
|
} else { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let entry = SimpleEntry(countdowns: countdowns, |
|
|
|
|
let entry = SimpleEntry(timers: timers, |
|
|
|
|
date: Date(), |
|
|
|
|
configuration: configuration) |
|
|
|
|
completion(entry) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getTimeline(for configuration: SelectCountdownIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) { |
|
|
|
|
func getTimeline(for configuration: SelectTimerIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) { |
|
|
|
|
|
|
|
|
|
getSnapshot(for: configuration, in: context) { entry in |
|
|
|
|
let timeline = Timeline(entries: [entry], policy: .atEnd) |
|
|
|
|
@ -48,28 +48,28 @@ struct Provider: IntentTimelineProvider { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct SimpleEntry: TimelineEntry { |
|
|
|
|
let countdowns: [Countdown] |
|
|
|
|
let timers: [AbstractTimer] |
|
|
|
|
let date: Date |
|
|
|
|
let configuration: SelectCountdownIntent |
|
|
|
|
let configuration: SelectTimerIntent |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct CountdownSimpleWidgetView: View { |
|
|
|
|
|
|
|
|
|
let countdown: Countdown |
|
|
|
|
let timer: AbstractTimer |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
SingleCountdownView(countdown: countdown) |
|
|
|
|
.widgetURL(countdown.url) |
|
|
|
|
SingleTimerView(timer: timer) |
|
|
|
|
.widgetURL(timer.url) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct CountdownMultiWidgetView: View { |
|
|
|
|
|
|
|
|
|
let countdowns: [Countdown] |
|
|
|
|
let timers: [AbstractTimer] |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
MultiCountdownView(countdowns: countdowns) |
|
|
|
|
MultiCountdownView(timers: timers) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
@ -93,23 +93,23 @@ struct LaunchWidgetEntryView : View { |
|
|
|
|
var body: some View { |
|
|
|
|
switch family { |
|
|
|
|
case .systemSmall, .accessoryInline: |
|
|
|
|
if let countdown = entry.countdowns.first { |
|
|
|
|
CountdownSimpleWidgetView(countdown: countdown) |
|
|
|
|
.background(Image(countdown.imageName)) |
|
|
|
|
if let timer = entry.timers.first { |
|
|
|
|
CountdownSimpleWidgetView(timer: timer) |
|
|
|
|
.background(Image(timer.imageName)) |
|
|
|
|
} else { |
|
|
|
|
VoidView() |
|
|
|
|
} |
|
|
|
|
case .accessoryCircular: |
|
|
|
|
if let countdown = entry.countdowns.first { |
|
|
|
|
LockScreenCountdownView(countdown: countdown) |
|
|
|
|
if let countdown = entry.timers.first { |
|
|
|
|
LockScreenCountdownView(timer: countdown) |
|
|
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity) |
|
|
|
|
.background(Color.black) |
|
|
|
|
} else { |
|
|
|
|
VoidView() |
|
|
|
|
} |
|
|
|
|
case .accessoryRectangular: |
|
|
|
|
if let countdown = entry.countdowns.first { |
|
|
|
|
LockScreenCountdownView(countdown: countdown) |
|
|
|
|
if let timer = entry.timers.first { |
|
|
|
|
LockScreenCountdownView(timer: timer) |
|
|
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity) |
|
|
|
|
.background(Color.black) |
|
|
|
|
.cornerRadius(16.0) |
|
|
|
|
@ -117,7 +117,7 @@ struct LaunchWidgetEntryView : View { |
|
|
|
|
VoidView() |
|
|
|
|
} |
|
|
|
|
default: |
|
|
|
|
MultiCountdownView(countdowns: entry.countdowns) |
|
|
|
|
MultiCountdownView(timers: entry.timers) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -128,7 +128,7 @@ struct LaunchWidget: Widget { |
|
|
|
|
|
|
|
|
|
var body: some WidgetConfiguration { |
|
|
|
|
IntentConfiguration(kind: kind, |
|
|
|
|
intent: SelectCountdownIntent.self, |
|
|
|
|
intent: SelectTimerIntent.self, |
|
|
|
|
provider: Provider()) { entry in |
|
|
|
|
LaunchWidgetEntryView(entry: entry) |
|
|
|
|
} |
|
|
|
|
@ -143,11 +143,11 @@ struct LaunchWidget_Previews: PreviewProvider { |
|
|
|
|
|
|
|
|
|
let fake = Countdown.fake(context: PersistenceController.preview.container.viewContext) |
|
|
|
|
|
|
|
|
|
LaunchWidgetEntryView(entry: SimpleEntry(countdowns: [fake], date: Date(), configuration: SelectCountdownIntent())) |
|
|
|
|
LaunchWidgetEntryView(entry: SimpleEntry(timers: [fake], date: Date(), configuration: SelectTimerIntent())) |
|
|
|
|
.previewContext(WidgetPreviewContext(family: .systemSmall)) |
|
|
|
|
LaunchWidgetEntryView(entry: SimpleEntry(countdowns: [fake, fake, fake, fake], date: Date(), configuration: SelectCountdownIntent())) |
|
|
|
|
LaunchWidgetEntryView(entry: SimpleEntry(timers: [fake, fake, fake, fake], date: Date(), configuration: SelectTimerIntent())) |
|
|
|
|
.previewContext(WidgetPreviewContext(family: .systemMedium)) |
|
|
|
|
LaunchWidgetEntryView(entry: SimpleEntry(countdowns: [fake], date: Date(), configuration: SelectCountdownIntent())) |
|
|
|
|
LaunchWidgetEntryView(entry: SimpleEntry(timers: [fake], date: Date(), configuration: SelectTimerIntent())) |
|
|
|
|
.previewContext(WidgetPreviewContext(family: .accessoryRectangular)) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|