Skip to content

Commit ff6166f

Browse files
committed
Data display cleanup
1 parent 5d81ea9 commit ff6166f

File tree

16 files changed

+231
-152
lines changed

16 files changed

+231
-152
lines changed

OneKDay.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@
509509
isa = XCBuildConfiguration;
510510
buildSettings = {
511511
ALWAYS_SEARCH_USER_PATHS = NO;
512-
BUILD_NUMBER = 10;
512+
BUILD_NUMBER = 11;
513513
BUILD_VERSION = 1.1.0;
514514
CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES;
515515
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
@@ -577,7 +577,7 @@
577577
isa = XCBuildConfiguration;
578578
buildSettings = {
579579
ALWAYS_SEARCH_USER_PATHS = NO;
580-
BUILD_NUMBER = 10;
580+
BUILD_NUMBER = 11;
581581
BUILD_VERSION = 1.1.0;
582582
CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES;
583583
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;

OneKDay/Views/AppIconSelectorView.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ struct AppIconSelector: View {
2626

2727
Spacer()
2828
Image(systemName: viewModel.selectedAppIcon == icon
29-
? "checkmark.circle.fill"
30-
: "circle"
29+
? "checkmark.circle.fill"
30+
: "circle"
3131
)
32-
.foregroundColor(
33-
viewModel.selectedAppIcon == icon ? .green : .gray
34-
)
35-
.font(.headline)
32+
.foregroundColor(
33+
viewModel.selectedAppIcon == icon ? .green : .gray
34+
)
35+
.font(.headline)
3636
}
3737
// Needed to allow for tapping on a spacer
3838
.contentShape(Rectangle())

OneKDay/Views/ContentView.swift

Lines changed: 106 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct ContentView: View {
1616

1717
private let userDefaults = UserDefaults()
1818

19+
@State private var loading = true
1920
@State private var currentMetricIndex: Int = 0
2021
@State private var metricTotals: [HKQuantityTypeIdentifier: Double] = [metricOptions[0]: 0.0]
2122
@State private var metricCounts: [HKQuantityTypeIdentifier: [MetricEntry]] = [
@@ -24,80 +25,101 @@ struct ContentView: View {
2425
@State private var showingSheet = false
2526
@State private var dataAnimationPower = 0.0
2627

28+
@State private var killDataTimer = Timer
29+
.publish(every: 3600, on: .current, in: .default)
30+
.autoconnect()
31+
2732
@AppStorage(STEP_GOAL_KEY) var stepGoal = 0
2833

2934
@ViewBuilder
3035
var body: some View {
3136
let metricID = metricOptions[currentMetricIndex]
3237
let currentMetricList = metricCounts[metricID, default: []]
33-
if !HKHealthStore.isHealthDataAvailable() {
34-
Text(
35-
NSLocalizedString(
36-
"no-health-access",
37-
comment: "Text for when the app does not have access to health data"
38+
if loading {
39+
NavigationView {
40+
ProgressView()
41+
}
42+
.onAppear {
43+
Task {
44+
onAppear()
45+
}
46+
}
47+
.navigationTitle("OneK Day")
48+
.navigationBarTitleDisplayMode(.inline)
49+
.toolbarBackground(Color.accentColor, for: .navigationBar)
50+
.toolbarBackground(.visible, for: .navigationBar)
51+
} else if !HKHealthStore.isHealthDataAvailable() || currentMetricList.isEmpty {
52+
NavigationView {
53+
Text(
54+
NSLocalizedString(
55+
"no-health-access",
56+
comment: "Text for when the app does not have access to health data"
57+
)
3858
)
39-
)
59+
}
60+
.navigationTitle("OneK Day")
61+
.navigationBarTitleDisplayMode(.inline)
62+
.toolbarBackground(Color.accentColor, for: .navigationBar)
63+
.toolbarBackground(.visible, for: .navigationBar)
4064
} else {
4165
NavigationView {
4266
VStack {
43-
if !currentMetricList.isEmpty {
44-
Chart(currentMetricList, id: \.startDate) {
45-
BarMark(
46-
x: .value(
47-
NSLocalizedString(
48-
"time-value-label",
49-
comment: "The lael for the time axis of the graph"
67+
Chart(currentMetricList, id: \.startDate) {
68+
BarMark(
69+
x: .value(
70+
NSLocalizedString(
71+
"time-value-label",
72+
comment: "The label for the time axis of the graph"
73+
),
74+
$0.startDate,
75+
unit: .hour,
76+
calendar: Calendar.current
77+
),
78+
y: .value(
79+
getUnitSuffix(
80+
for: preferredUnit(
81+
for: metricID
5082
),
51-
$0.startDate,
52-
unit: .hour,
53-
calendar: Calendar.current
83+
with: $0.metric
84+
)?.capitalized(with: Locale.current) ??
85+
NSLocalizedString(
86+
"unknown-measurement-unit",
87+
comment: "Default measurement unit if the real one is unknown"
5488
),
89+
max(pow($0.metric, dataAnimationPower), 0)
90+
)
91+
)
92+
.foregroundStyle(getBarGraphStyle(for: $0.metric))
93+
.accessibilityLabel(formatDate($0.startDate))
94+
.accessibilityValue(formattedValue(
95+
$0.metric,
96+
typeIdentifier: metricID
97+
) ?? "X")
98+
if currentMetricIndex == 0 {
99+
RuleMark(
55100
y: .value(
56-
getUnitSuffix(
57-
for: preferredUnit(
58-
for: metricID
59-
),
60-
with: $0.metric
61-
)?.capitalized(with: Locale.current) ??
62101
NSLocalizedString(
63-
"unknown-measurement-unit",
64-
comment: "Default measurement unit if the real one is unknown"
102+
"goal-a11y-label",
103+
comment: "A11y label for the goal line"
65104
),
66-
max(pow($0.metric, dataAnimationPower), 0)
105+
stepGoal
106+
)
107+
)
108+
.accessibilityLabel(
109+
NSLocalizedString(
110+
"goal-a11y-label",
111+
comment: "A11y label for the goal line"
67112
)
68113
)
69-
.foregroundStyle(getBarGraphStyle(for: $0.metric))
70-
.accessibilityLabel(formatDate($0.startDate))
71114
.accessibilityValue(formattedValue(
72-
$0.metric,
115+
Double(stepGoal),
73116
typeIdentifier: metricID
74117
) ?? "X")
75-
if currentMetricIndex == 0 {
76-
RuleMark(
77-
y: .value(
78-
NSLocalizedString(
79-
"goal-a11y-label",
80-
comment: "A11y label for the goal line"
81-
),
82-
stepGoal
83-
)
84-
)
85-
.accessibilityLabel(
86-
NSLocalizedString(
87-
"goal-a11y-label",
88-
comment: "A11y label for the goal line"
89-
)
90-
)
91-
.accessibilityValue(formattedValue(
92-
Double(stepGoal),
93-
typeIdentifier: metricID
94-
) ?? "X")
95-
}
96118
}
97-
.padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
98-
99-
subtitle
100119
}
120+
.padding(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 16))
121+
122+
subtitle
101123
}
102124
.padding(EdgeInsets(top: 16, leading: 0, bottom: 16, trailing: 0))
103125
.navigationTitle("OneK Day")
@@ -112,7 +134,6 @@ struct ContentView: View {
112134
}
113135
.toolbarBackground(Color.accentColor, for: .navigationBar)
114136
.toolbarBackground(.visible, for: .navigationBar)
115-
.onAppear(perform: onAppear)
116137
.onChange(of: scenePhase) { newPhase in
117138
if newPhase == .active {
118139
loadMetrics(for: metricOptions[currentMetricIndex])
@@ -121,6 +142,9 @@ struct ContentView: View {
121142
.sheet(isPresented: $showingSheet, onDismiss: setValuesFromDefault) {
122143
SettingsSheet()
123144
}
145+
.onReceive(killDataTimer) { _ in
146+
loadMetrics(for: metricOptions[currentMetricIndex])
147+
}
124148
}
125149
}
126150
}
@@ -131,8 +155,9 @@ struct ContentView: View {
131155
let currentMetricList = metricCounts[metricID, default: []]
132156
Button {
133157
currentMetricIndex = (currentMetricIndex + 1) % metricOptions.count
134-
loadMetrics(for: metricOptions[currentMetricIndex])
135-
animateData()
158+
Task {
159+
loadMetrics(for: metricOptions[currentMetricIndex])
160+
}
136161
} label: {
137162
VStack(alignment: .center) {
138163
let metricStringOpt = formattedValue(
@@ -160,8 +185,8 @@ struct ContentView: View {
160185
lastHourMetricString
161186
)
162187
)
163-
.multilineTextAlignment(.center)
164-
.font(.title2)
188+
.multilineTextAlignment(.center)
189+
.font(.title2)
165190
}
166191
}
167192
}
@@ -212,13 +237,13 @@ struct ContentView: View {
212237
}
213238

214239
func loadMetrics(for identifier: HKQuantityTypeIdentifier) {
240+
loading = true
215241
#if DEBUG
216242
let components = Calendar.current.dateComponents([.hour, .day, .month, .year], from: Date(timeIntervalSinceNow: 3600))
217243
var result: [MetricEntry] = []
218244
for i in (1...24).reversed() {
219245
let startDate = Date(timeInterval: -3600 * Double(i), since: Calendar.current.date(from: components)!)
220246
let testComponents = Calendar.current.dateComponents([.hour], from: startDate)
221-
print(testComponents.hour!)
222247
var stepCount = Double.random(in: 800...1500)
223248
if testComponents.hour! == 7 || testComponents.hour! == 21 || testComponents.hour! == 22 {
224249
stepCount = Double.random(in: 200...500)
@@ -245,24 +270,38 @@ struct ContentView: View {
245270
return acc
246271
}
247272
}
273+
loading = false
248274
animateData()
249275
#else
250276
if metricTotals[identifier, default: 0].isZero {
251277
let components = Calendar.current.dateComponents([.day, .month, .year], from: Date())
252278
HealthData.getHourlyMetricCount(for: identifier) { result in
253-
metricCounts[identifier] = result
254-
metricTotals[identifier] = result.reduce(0.0) { acc, item in
255-
let testComponents = Calendar.current.dateComponents([.day, .month, .year], from: item.endDate)
256-
if testComponents.day! == components.day! &&
257-
testComponents.month! == components.month! &&
258-
testComponents.year! == components.year! {
259-
return acc + item.metric
279+
if result.count > 0 {
280+
metricCounts[identifier] = result
281+
metricTotals[identifier] = result.reduce(0.0) { acc, item in
282+
let testComponents = Calendar.current.dateComponents([.day, .month, .year], from: item.endDate)
283+
if testComponents.day! == components.day! &&
284+
testComponents.month! == components.month! &&
285+
testComponents.year! == components.year! {
286+
return acc + item.metric
287+
} else {
288+
return acc
289+
}
290+
}
291+
loading = false
292+
animateData()
293+
} else {
294+
currentMetricIndex = (currentMetricIndex + 1) % metricOptions.count
295+
if currentMetricIndex > 0 {
296+
// Only load if you haven't cycled around to the start
297+
loadMetrics(for: metricOptions[currentMetricIndex])
260298
} else {
261-
return acc
299+
loading = false
262300
}
263301
}
264-
animateData()
265302
}
303+
} else {
304+
loading = false
266305
}
267306
#endif
268307
}

OneKDay/Views/OneKDayApp.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ struct OneKDayApp: App {
2727
comment: "Text to prevent iPads from erroring"
2828
)
2929
)
30-
.font(.largeTitle)
30+
.font(.largeTitle)
3131
} else if canReadHealthData {
3232
ContentView()
3333
} else if hasCheckedHealthAccess {
@@ -39,7 +39,7 @@ struct OneKDayApp: App {
3939
)
4040
} else {
4141
VStack {
42-
Button{
42+
Button {
4343
requestHealthAccess()
4444
} label: {
4545
Text(
@@ -48,15 +48,15 @@ struct OneKDayApp: App {
4848
comment: "Button to enable health data access"
4949
)
5050
)
51-
.foregroundColor(.white)
51+
.foregroundColor(.white)
5252
}
5353
.padding()
5454
.background(Color.green)
5555
.clipShape(Capsule())
5656
}
57-
.onAppear {
58-
requestHealthAccess()
59-
}
57+
.onAppear {
58+
requestHealthAccess()
59+
}
6060
}
6161
}
6262
}

OneKDayUITests/OneKDayUITests.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ class OneKDayUITests: XCTestCase {
3131
// swiftlint:enable function_body_length
3232

3333
// Uncomment when not using as a snapshot scheme
34-
// func testLaunchPerformance() throws {
35-
// if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
36-
// // This measures how long it takes to launch your application.
37-
// measure(metrics: [XCTApplicationLaunchMetric()]) {
38-
// XCUIApplication().launch()
39-
// }
40-
// }
41-
// }
34+
// func testLaunchPerformance() throws {
35+
// if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
36+
// // This measures how long it takes to launch your application.
37+
// measure(metrics: [XCTApplicationLaunchMetric()]) {
38+
// XCUIApplication().launch()
39+
// }
40+
// }
41+
// }
4242
}

0 commit comments

Comments
 (0)