From 9bb6e824cbb183c4c1c593a5b8f6d2d333449a0d Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 11 Apr 2023 15:38:10 +0200 Subject: [PATCH] Adds cancel sheet for countdowns --- LeCountdown/Conductor.swift | 4 ++ LeCountdown/Sound/DelaySoundPlayer.swift | 3 - LeCountdown/Views/ContentView.swift | 5 -- LeCountdown/Views/LiveTimerListView.swift | 79 +++++++++++++++++++---- LeCountdown/fr.lproj/Localizable.strings | 1 + 5 files changed, 73 insertions(+), 19 deletions(-) diff --git a/LeCountdown/Conductor.swift b/LeCountdown/Conductor.swift index be0f326..19c90c3 100644 --- a/LeCountdown/Conductor.swift +++ b/LeCountdown/Conductor.swift @@ -108,6 +108,10 @@ class Conductor: ObservableObject { } + func isCountdownCancelled(_ countdown: Countdown) -> Bool { + return self.cancelledCountdowns.contains(where: { $0 == countdown.stringId }) + } + func notifyUser(countdownId: String) { // self._playSound(timerId: countdownId) self._endCountdown(countdownId: countdownId, cancel: false) diff --git a/LeCountdown/Sound/DelaySoundPlayer.swift b/LeCountdown/Sound/DelaySoundPlayer.swift index 75b41a8..7efdf66 100644 --- a/LeCountdown/Sound/DelaySoundPlayer.swift +++ b/LeCountdown/Sound/DelaySoundPlayer.swift @@ -14,14 +14,11 @@ import AVFoundation fileprivate var _timerID: TimerID -// fileprivate var _soundDuration: TimeInterval? - fileprivate var _timer: Timer? = nil init(timerID: TimerID, sound: Sound) throws { self._timerID = timerID -// self._soundDuration = Preferences.soundDurations[sound.fileName] let soundFile = try sound.soundFile() guard let url = soundFile.url else { diff --git a/LeCountdown/Views/ContentView.swift b/LeCountdown/Views/ContentView.swift index e6b343f..9e916ec 100644 --- a/LeCountdown/Views/ContentView.swift +++ b/LeCountdown/Views/ContentView.swift @@ -17,11 +17,6 @@ class BoringContext : ObservableObject { @Published var siriTimer: AbstractTimer? = nil } -//enum TimerType { -// case timer -// case stopwatch -//} - struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext diff --git a/LeCountdown/Views/LiveTimerListView.swift b/LeCountdown/Views/LiveTimerListView.swift index 2e71917..4d84140 100644 --- a/LeCountdown/Views/LiveTimerListView.swift +++ b/LeCountdown/Views/LiveTimerListView.swift @@ -82,7 +82,6 @@ struct LiveTimerView: View { struct LiveStopwatchView: View { @Environment(\.managedObjectContext) private var viewContext - @EnvironmentObject var conductor: Conductor @State var stopwatch: Stopwatch @@ -138,7 +137,7 @@ struct LiveStopwatchView: View { } fileprivate func _dismiss() { - conductor.removeLiveTimer(id: self.stopwatch.stringId) + Conductor.maestro.removeLiveTimer(id: self.stopwatch.stringId) } fileprivate func _formattedDuration(date: Date) -> String { @@ -154,19 +153,21 @@ struct LiveStopwatchView: View { struct LiveCountdownView: View { @Environment(\.managedObjectContext) private var viewContext - @EnvironmentObject var conductor: Conductor @State var countdown: Countdown var date: Date + @State var showConfirmationPopup: Bool = false + var body: some View { TimelineView(.periodic(from: self.date, by: 0.01)) { context in + + let cancelled = Conductor.maestro.isCountdownCancelled(self.countdown) HStack { let running = self.date > context.date - let cancelled = self.conductor.cancelledCountdowns.contains(where: { $0 == self.countdown.stringId }) VStack(alignment: .leading) { @@ -197,26 +198,71 @@ struct LiveCountdownView: View { } .contentShape(Rectangle()) .onTapGesture { - self._actionHandler() + + if Conductor.maestro.isCountdownCancelled(self.countdown) { + self._dismiss() + } else { + self.showConfirmationPopup = true + } } .frame(height: liveViewSize) .monospaced() + .fullScreenCover(isPresented: self.$showConfirmationPopup) { + + ZStack { + Color.black.opacity(0.1) + .edgesIgnoringSafeArea(.all) + + let name = self.countdown.displayName + + Button(String(format: NSLocalizedString("Cancel %@", comment: ""), name)) { + self._cancelCountdown() + self.showConfirmationPopup = false + } + .padding() + .foregroundColor(.white) + .background(Color.accentColor) + .cornerRadius(8.0) + .font(.title) + +// Button { +// self._actionHandler() +// self.showConfirmationPopup = false +// } label: { +// Image(systemName: "xmark.circle") +// .font(.system(size: 48.0)).foregroundColor(.accentColor) +// } + }.onTapGesture { + self.showConfirmationPopup = false + } + .background(BackgroundBlurView()) + +// VStack { +// Button { +// self._actionHandler() +// self.showConfirmationPopup = false +// } label: { +// Image(systemName: "xmark.circle") +// .font(.title).foregroundColor(.accentColor) +// } +// }.background(BlurView()) + } } fileprivate func _actionHandler() { FileLogger.log("countdown _actionHandler") - withAnimation { - if conductor.currentCountdowns[self.countdown.stringId] != nil { + if Conductor.maestro.currentCountdowns[self.countdown.stringId] != nil { self._cancelCountdown() } else { self._dismiss() } - } } fileprivate func _dismiss() { - conductor.removeLiveTimer(id: self.countdown.stringId) + withAnimation { + Conductor.maestro.removeLiveTimer(id: self.countdown.stringId) + } } fileprivate func _formattedDuration(date: Date) -> String { @@ -225,12 +271,23 @@ struct LiveCountdownView: View { } fileprivate func _cancelCountdown() { - Conductor.maestro.cancelCountdown(id: self.countdown.stringId) + withAnimation { + Conductor.maestro.cancelCountdown(id: self.countdown.stringId) + } } } +struct BackgroundBlurView: UIViewRepresentable { + func makeUIView(context: Context) -> UIView { + let view = UIVisualEffectView(effect: UIBlurEffect(style: .light)) + DispatchQueue.main.async { + view.superview?.superview?.backgroundColor = .clear + } + return view + } - + func updateUIView(_ uiView: UIView, context: Context) {} +} struct LiveTimerView_Previews: PreviewProvider { static var previews: some View { diff --git a/LeCountdown/fr.lproj/Localizable.strings b/LeCountdown/fr.lproj/Localizable.strings index 3ae3144..7cf9e0a 100644 --- a/LeCountdown/fr.lproj/Localizable.strings +++ b/LeCountdown/fr.lproj/Localizable.strings @@ -263,3 +263,4 @@ "Name" = "Nom"; "Hours" = "Heures"; "Default Volume" = "Volume par défaut"; +"Cancel %@" = "Annuler %@";