-
Notifications
You must be signed in to change notification settings - Fork 2
/
InfectedWidget.swift
110 lines (89 loc) · 3.4 KB
/
InfectedWidget.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//
// InfectedWidget.swift
// InfectedWidget
//
// Created by marko on 9/20/20.
//
import WidgetKit
import SwiftUI
import Combine
final class Provider: TimelineProvider {
private var cancellables = Set<AnyCancellable>()
private let api = CoronaWatchNLAPI()
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), numbers: .demo)
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(), numbers: .demo)
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
api.load()
.sink { completion in
print(completion)
} receiveValue: { numbers in
let now = Date()
let entry = SimpleEntry(date: now, numbers: numbers)
let after1Hour = Calendar.current.date(byAdding: .hour, value: 1, to: now)!
let timeline = Timeline(entries: [entry], policy: .after(after1Hour))
completion(timeline)
}.store(in: &cancellables)
}
}
struct SimpleEntry: TimelineEntry {
let date: Date
let numbers: LatestNumbers
}
struct InfectedWidgetEntryView : View {
private static let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
formatter.doesRelativeDateFormatting = true
return formatter
}()
var entry: Provider.Entry
var body: some View {
HStack {
VStack(alignment: .leading, spacing: 4) {
Text(Self.dateFormatter.string(from: entry.numbers.date))
.font(Font.system(size: 16, weight: .semibold))
.foregroundColor(.secondary)
RowView(captionText: "New Cases",
value: entry.numbers.cases,
diffValue: entry.numbers.casesDifference)
RowView(captionText: "Hospitalizations",
value: entry.numbers.hospitalizations,
diffValue: entry.numbers.hospitalizationsDifference)
RowView(captionText: "Deaths",
value: entry.numbers.deaths,
diffValue: entry.numbers.deathsDifference)
}
}
.padding([.vertical, .leading])
.padding(.trailing, 8)
}
}
@main
struct InfectedWidget: Widget {
let kind: String = "InfectedWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
InfectedWidgetEntryView(entry: entry)
}
.configurationDisplayName("Latest Numbers")
.description("Displays latest infection numbers in the Netherlands.")
.supportedFamilies([.systemSmall])
}
}
struct InfectedWidget_Previews: PreviewProvider {
static var previews: some View {
Group {
InfectedWidgetEntryView(entry: SimpleEntry(date: Date(), numbers: .demo))
.previewContext(WidgetPreviewContext(family: .systemSmall))
InfectedWidgetEntryView(entry: SimpleEntry(date: Date(), numbers: .demo))
.previewContext(WidgetPreviewContext(family: .systemSmall))
.environment(\.colorScheme, .dark)
}
}
}