You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.5 KiB
154 lines
4.5 KiB
//
|
|
// LaunchWidget.swift
|
|
// LaunchWidget
|
|
//
|
|
// Created by Laurent Morvillier on 25/01/2023.
|
|
//
|
|
|
|
import WidgetKit
|
|
import SwiftUI
|
|
import Intents
|
|
|
|
struct Provider: IntentTimelineProvider {
|
|
func placeholder(in context: Context) -> SimpleEntry {
|
|
SimpleEntry(timers: [], date: Date(), configuration: SelectTimerIntent())
|
|
}
|
|
|
|
func getSnapshot(for configuration: SelectTimerIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
|
|
|
|
guard let cp = configuration.timer
|
|
else {
|
|
completion(placeholder(in: context))
|
|
return
|
|
}
|
|
|
|
let timers: [AbstractTimer] = cp.compactMap {
|
|
if let id = $0.identifier {
|
|
return IntentDataProvider.main.timer(id: id)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
let entry = SimpleEntry(timers: timers,
|
|
date: Date(),
|
|
configuration: configuration)
|
|
completion(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)
|
|
completion(timeline)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
struct SimpleEntry: TimelineEntry {
|
|
let timers: [AbstractTimer]
|
|
let date: Date
|
|
let configuration: SelectTimerIntent
|
|
}
|
|
|
|
struct CountdownSimpleWidgetView: View {
|
|
|
|
let timer: AbstractTimer
|
|
|
|
var body: some View {
|
|
SingleTimerView(timer: timer)
|
|
.widgetURL(timer.url)
|
|
}
|
|
|
|
}
|
|
|
|
struct CountdownMultiWidgetView: View {
|
|
|
|
let timers: [AbstractTimer]
|
|
|
|
var body: some View {
|
|
MultiCountdownView(timers: timers)
|
|
}
|
|
|
|
}
|
|
|
|
struct VoidView : View {
|
|
var body: some View {
|
|
VStack {
|
|
Text("Tea!")
|
|
Text("4:00")
|
|
}
|
|
}
|
|
}
|
|
|
|
struct LaunchWidgetEntryView : View {
|
|
|
|
@Environment(\.widgetFamily) var family: WidgetFamily
|
|
|
|
var entry: Provider.Entry
|
|
|
|
@ViewBuilder
|
|
var body: some View {
|
|
switch family {
|
|
case .systemSmall, .accessoryInline:
|
|
if let timer = entry.timers.first {
|
|
CountdownSimpleWidgetView(timer: timer)
|
|
.background(Image(timer.imageName))
|
|
} else {
|
|
VoidView()
|
|
}
|
|
case .accessoryCircular:
|
|
if let countdown = entry.timers.first {
|
|
LockScreenCountdownView(timer: countdown)
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
.background(Color.black)
|
|
} else {
|
|
VoidView()
|
|
}
|
|
case .accessoryRectangular:
|
|
if let timer = entry.timers.first {
|
|
LockScreenCountdownView(timer: timer)
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
.background(Color.black)
|
|
.cornerRadius(16.0)
|
|
} else {
|
|
VoidView()
|
|
}
|
|
default:
|
|
MultiCountdownView(timers: entry.timers)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
struct LaunchWidget: Widget {
|
|
let kind: String = "com.staxriver.launch-widget"
|
|
|
|
var body: some WidgetConfiguration {
|
|
IntentConfiguration(kind: kind,
|
|
intent: SelectTimerIntent.self,
|
|
provider: Provider()) { entry in
|
|
LaunchWidgetEntryView(entry: entry)
|
|
}
|
|
.configurationDisplayName("Launch Widget")
|
|
.description("Select and launch your timers")
|
|
.supportedFamilies([.systemSmall, .systemMedium, .systemLarge, .accessoryRectangular, .accessoryCircular])
|
|
}
|
|
}
|
|
|
|
struct LaunchWidget_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
|
|
let fake = Countdown.fake(context: PersistenceController.preview.container.viewContext)
|
|
|
|
LaunchWidgetEntryView(entry: SimpleEntry(timers: [fake], date: Date(), configuration: SelectTimerIntent()))
|
|
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
|
LaunchWidgetEntryView(entry: SimpleEntry(timers: [fake, fake, fake, fake], date: Date(), configuration: SelectTimerIntent()))
|
|
.previewContext(WidgetPreviewContext(family: .systemMedium))
|
|
LaunchWidgetEntryView(entry: SimpleEntry(timers: [fake], date: Date(), configuration: SelectTimerIntent()))
|
|
.previewContext(WidgetPreviewContext(family: .accessoryRectangular))
|
|
|
|
}
|
|
}
|
|
|