From 6137196be7dabb65527c07a59c25ca53c43b9106 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 3 Feb 2023 12:31:23 +0100 Subject: [PATCH] Make stopwatch work + UI --- LeCountdown/Conductor.swift | 29 ++++++++++++------- LeCountdown/Model/CoreDataRequests.swift | 4 +-- LeCountdown/TimerRouter.swift | 14 ++++++++- LeCountdown/Views/Alarm/AlarmDialView.swift | 4 --- LeCountdown/Views/ContentView.swift | 2 +- .../Views/Countdown/CountdownDialView.swift | 5 +--- LeCountdown/Views/DialView.swift | 26 +++++++++++------ .../Views/Stopwatch/StopwatchDialView.swift | 19 +++++++----- 8 files changed, 64 insertions(+), 39 deletions(-) diff --git a/LeCountdown/Conductor.swift b/LeCountdown/Conductor.swift index 7fe589b..3c51af1 100644 --- a/LeCountdown/Conductor.swift +++ b/LeCountdown/Conductor.swift @@ -16,25 +16,34 @@ class Conductor : ObservableObject { @Published var soundPlayer: SoundPlayer? = nil @UserDefault(Key.dates.rawValue, defaultValue: [:]) static var savedDates: [String : DateInterval] - + @UserDefault(Key.stopwatch.rawValue, defaultValue: [:]) static var savedStopwatches: [String : Date] + init() { - self.notificationDates = Conductor.savedDates + self.timerDates = Conductor.savedDates + self.stopwatchIntervals = Conductor.savedStopwatches + } + + @Published var timerDates: [String : DateInterval] = [:] { + didSet { + Conductor.savedDates = timerDates + } } - @Published var notificationDates: [String : DateInterval] = [:] { + @Published var stopwatchIntervals: [String : Date] = [:] { didSet { - Conductor.savedDates = notificationDates + Conductor.savedStopwatches = stopwatchIntervals } } enum Key : String { case dates + case stopwatch } func startCountdown(_ date: Date, countdown: Countdown) { DispatchQueue.main.async { let dateInterval = DateInterval(start: Date(), end: date) - self.notificationDates[countdown.stringId] = dateInterval + self.timerDates[countdown.stringId] = dateInterval self._launchLiveActivity(countdown: countdown, endDate: date) } @@ -51,7 +60,7 @@ class Conductor : ObservableObject { self._recordActivity(countdownId: countdownId) } - if self.notificationDates.removeValue(forKey: countdownId) != nil { + if self.timerDates.removeValue(forKey: countdownId) != nil { self._endLiveActivity(countdownId: countdownId) } } @@ -59,7 +68,7 @@ class Conductor : ObservableObject { func cleanup() { let now = Date() - for (key, value) in self.notificationDates { + for (key, value) in self.timerDates { if value.end < now { self.endCountdown(countdownId: key, cancel: false) } @@ -69,9 +78,9 @@ class Conductor : ObservableObject { fileprivate func _recordActivity(countdownId: String) { let context = PersistenceController.shared.container.viewContext if let countdown = context.object(stringId: countdownId) as? Countdown, - let dateInterval = self.notificationDates[countdownId] { + let dateInterval = self.timerDates[countdownId] { do { - try CoreDataRequests.recordActivity(countdown: countdown, dateInterval: dateInterval) + try CoreDataRequests.recordActivity(timer: countdown, dateInterval: dateInterval) } catch { print("Could not record activity = \(error)") // TODO: show error to user @@ -145,7 +154,7 @@ class Conductor : ObservableObject { func updateLiveActivities() { print("update live activity...") - for (countdownId, interval) in self.notificationDates { + for (countdownId, interval) in self.timerDates { if interval.end < Date() { self._endLiveActivity(countdownId: countdownId) diff --git a/LeCountdown/Model/CoreDataRequests.swift b/LeCountdown/Model/CoreDataRequests.swift index fe38f78..d111d3e 100644 --- a/LeCountdown/Model/CoreDataRequests.swift +++ b/LeCountdown/Model/CoreDataRequests.swift @@ -42,9 +42,9 @@ class CoreDataRequests { return activity } - static func recordActivity(countdown: Countdown, dateInterval: DateInterval) throws { + static func recordActivity(timer: AbstractTimer, dateInterval: DateInterval) throws { - guard let activity = countdown.activity else { + guard let activity = timer.activity else { return } diff --git a/LeCountdown/TimerRouter.swift b/LeCountdown/TimerRouter.swift index dc68e9a..db14bf3 100644 --- a/LeCountdown/TimerRouter.swift +++ b/LeCountdown/TimerRouter.swift @@ -50,7 +50,19 @@ class TimerRouter { fileprivate static func _startStopwatch(_ stopwatch: Stopwatch, handler: @escaping (Result) -> Void) { + if let start = Conductor.maestro.stopwatchIntervals[stopwatch.stringId] { + + Conductor.maestro.stopwatchIntervals.removeValue(forKey: stopwatch.stringId) + do { + try CoreDataRequests.recordActivity(timer: stopwatch, dateInterval: DateInterval(start: start, end: Date())) + } catch { + handler(.failure(error)) + } + + } else { + Conductor.maestro.stopwatchIntervals[stopwatch.stringId] = Date() + } + } - } diff --git a/LeCountdown/Views/Alarm/AlarmDialView.swift b/LeCountdown/Views/Alarm/AlarmDialView.swift index 78f395a..aa62a3a 100644 --- a/LeCountdown/Views/Alarm/AlarmDialView.swift +++ b/LeCountdown/Views/Alarm/AlarmDialView.swift @@ -28,10 +28,6 @@ struct AlarmDialView: View { Spacer() } - .padding(24.0) - .monospaced() - .font(Font.system(size: 16.0, weight: .semibold)) - .foregroundColor(Color.white) } } diff --git a/LeCountdown/Views/ContentView.swift b/LeCountdown/Views/ContentView.swift index 56152a4..89e9ad9 100644 --- a/LeCountdown/Views/ContentView.swift +++ b/LeCountdown/Views/ContentView.swift @@ -231,7 +231,7 @@ struct MainToolbarView: View { fileprivate extension Countdown { var endDate: Date? { - return Conductor.maestro.notificationDates[self.stringId]?.end + return Conductor.maestro.timerDates[self.stringId]?.end } var isLive: Bool { diff --git a/LeCountdown/Views/Countdown/CountdownDialView.swift b/LeCountdown/Views/Countdown/CountdownDialView.swift index bd44c7f..1ec8629 100644 --- a/LeCountdown/Views/Countdown/CountdownDialView.swift +++ b/LeCountdown/Views/Countdown/CountdownDialView.swift @@ -19,7 +19,7 @@ struct CountdownDialView: View { VStack(alignment: .leading) { Text(countdown.activity?.name?.uppercased() ?? "") // let dateInterval = DateInterval(start: Date(), end: Date()) - if let dateInterval = conductor.notificationDates[countdown.stringId] { + if let dateInterval = conductor.timerDates[countdown.stringId] { Text(dateInterval.end, style: .timer) Spacer() HStack { @@ -40,9 +40,6 @@ struct CountdownDialView: View { } Spacer() } - .monospaced() - .font(Font.system(size: 16.0, weight: .semibold)) - .foregroundColor(Color.white) } } diff --git a/LeCountdown/Views/DialView.swift b/LeCountdown/Views/DialView.swift index ff2406e..2e89f55 100644 --- a/LeCountdown/Views/DialView.swift +++ b/LeCountdown/Views/DialView.swift @@ -47,16 +47,24 @@ struct DialView: View { @ViewBuilder fileprivate func _dialView(timer: AbstractTimer) -> some View { - switch timer { - case let countdown as Countdown: - CountdownDialView(countdown: countdown) .environmentObject(Conductor.maestro) - case let alarm as Alarm: - AlarmDialView(alarm: alarm) .environmentObject(Conductor.maestro) - case let stopwatch as Stopwatch: - StopwatchDialView(stopwatch: stopwatch) .environmentObject(Conductor.maestro) - default: - Text("missing dial view") + Group { + switch timer { + case let countdown as Countdown: + CountdownDialView(countdown: countdown) + .environmentObject(Conductor.maestro) + case let alarm as Alarm: + AlarmDialView(alarm: alarm) + .environmentObject(Conductor.maestro) + case let stopwatch as Stopwatch: + StopwatchDialView(stopwatch: stopwatch) + .environmentObject(Conductor.maestro) + default: + Text("missing dial view") + } } + .monospaced() + .font(Font.system(size: 16.0, weight: .semibold)) + .foregroundColor(Color.white) } @ViewBuilder diff --git a/LeCountdown/Views/Stopwatch/StopwatchDialView.swift b/LeCountdown/Views/Stopwatch/StopwatchDialView.swift index 04549da..74c4a09 100644 --- a/LeCountdown/Views/Stopwatch/StopwatchDialView.swift +++ b/LeCountdown/Views/Stopwatch/StopwatchDialView.swift @@ -9,22 +9,23 @@ import SwiftUI struct StopwatchDialView: View { + @EnvironmentObject var conductor: Conductor + @ObservedObject var stopwatch: Stopwatch var body: some View { - VStack { - - HStack { + HStack { + VStack(alignment: .leading) { + Text(stopwatch.activity?.name?.uppercased() ?? "") + if let start = conductor.stopwatchIntervals[stopwatch.stringId] { + Text(start, style: .timer) + } + Spacer() } - Spacer() } - .padding(24.0) - .monospaced() - .font(Font.system(size: 16.0, weight: .semibold)) - .foregroundColor(Color.white) } } @@ -32,5 +33,7 @@ struct StopwatchDialView: View { struct StopwatchDialView_Previews: PreviewProvider { static var previews: some View { StopwatchDialView(stopwatch: Stopwatch.fake(context: PersistenceController.preview.container.viewContext)) + .environmentObject(Conductor.maestro) + .background(.cyan) } }