parent
676c813bab
commit
1a8bcf6a4d
@ -0,0 +1,56 @@ |
||||
// |
||||
// TimerRouter.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 02/02/2023. |
||||
// |
||||
|
||||
import Foundation |
||||
import NotificationCenter |
||||
|
||||
class TimerRouter { |
||||
|
||||
static func performAction(timer: AbstractTimer, handler: @escaping (Result<Bool, Error>) -> Void) { |
||||
switch timer { |
||||
case let countdown as Countdown: |
||||
self._launchCountdown(countdown, handler: handler) |
||||
case let alarm as Alarm: |
||||
self._scheduleAlarm(alarm, handler: handler) |
||||
case let stopwatch as Stopwatch: |
||||
self._startStopwatch(stopwatch, handler: handler) |
||||
default: |
||||
print("missing launcher for \(self)") |
||||
} |
||||
|
||||
} |
||||
|
||||
fileprivate static func _launchCountdown(_ countdown: Countdown, handler: @escaping (Result<Bool, Error>) -> Void) { |
||||
UNUserNotificationCenter.current().getNotificationSettings { settings in |
||||
|
||||
switch settings.authorizationStatus { |
||||
case .notDetermined, .denied: |
||||
handler(.failure(TimerError.notificationAuthorizationMissing)) |
||||
default: |
||||
CountdownScheduler.master.scheduleIfPossible(countdown: countdown) { result in |
||||
switch result { |
||||
case .success(_): |
||||
handler(.success(true)) |
||||
case .failure(let failure): |
||||
handler(.failure(failure)) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
fileprivate static func _scheduleAlarm(_ alarm: Alarm, handler: @escaping (Result<Bool, Error>) -> Void) { |
||||
|
||||
} |
||||
|
||||
fileprivate static func _startStopwatch(_ stopwatch: Stopwatch, handler: @escaping (Result<Bool, Error>) -> Void) { |
||||
|
||||
} |
||||
|
||||
|
||||
} |
||||
@ -0,0 +1,31 @@ |
||||
// |
||||
// PermissionAlertView.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 02/02/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct PermissionAlertView: View { |
||||
|
||||
var body: some View { |
||||
Button("Show permissions") { |
||||
self._showPermissionSettings() |
||||
} |
||||
Button("OK", role: .cancel) { } |
||||
} |
||||
|
||||
fileprivate func _showPermissionSettings() { |
||||
if let url = URL(string: UIApplication.openNotificationSettingsURLString) { |
||||
UIApplication.shared.open(url) |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
struct PermissionAlertView_Previews: PreviewProvider { |
||||
static var previews: some View { |
||||
PermissionAlertView() |
||||
} |
||||
} |
||||
@ -0,0 +1,98 @@ |
||||
// |
||||
// DialView.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 02/02/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct DialView: View { |
||||
|
||||
@Environment(\.managedObjectContext) private var viewContext |
||||
|
||||
@EnvironmentObject var boringContext: BoringContext |
||||
|
||||
@State var timer: AbstractTimer |
||||
|
||||
var frameSize: CGFloat |
||||
|
||||
var body: some View { |
||||
ZStack(alignment: .topTrailing) { |
||||
|
||||
Image(timer.imageName).resizable() |
||||
|
||||
Button { |
||||
self._launchTimer(timer) |
||||
} label: { |
||||
self._dialView(timer: timer) |
||||
} |
||||
|
||||
NavigationLink { |
||||
self._editView(timer: timer, isPresented: $boringContext.isShowingNewData) |
||||
} label: { |
||||
Image(systemName: "gearshape.fill") |
||||
.font(.system(size: 24, weight: .light)) |
||||
.padding() |
||||
.foregroundColor(Color.white) |
||||
} |
||||
|
||||
} |
||||
.frame(width: frameSize, height: frameSize) |
||||
.cornerRadius(40.0) |
||||
} |
||||
|
||||
@ViewBuilder |
||||
fileprivate func _dialView(timer: AbstractTimer) -> some View { |
||||
switch timer { |
||||
case let countdown as Countdown: |
||||
CountdownDialView(countdown: countdown) |
||||
case let alarm as Alarm: |
||||
AlarmDialView(alarm: alarm) |
||||
case let stopwatch as Stopwatch: |
||||
StopwatchDialView(stopwatch: stopwatch) |
||||
default: |
||||
Text("missing dial view") |
||||
} |
||||
} |
||||
|
||||
@ViewBuilder |
||||
fileprivate func _editView(timer: AbstractTimer, isPresented: Binding<Bool>) -> some View { |
||||
switch timer { |
||||
case let countdown as Countdown: |
||||
CountdownEditView(countdown: countdown, isPresented: isPresented) |
||||
case let alarm as Alarm: |
||||
AlarmEditView(alarm: alarm, isPresented: isPresented) |
||||
case let stopwatch as Stopwatch: |
||||
StopwatchEditView(stopwatch: stopwatch, isPresented: isPresented) |
||||
default: |
||||
Text("missing edit view") |
||||
} |
||||
} |
||||
|
||||
fileprivate func _launchTimer(_ timer: AbstractTimer) { |
||||
|
||||
TimerRouter.performAction(timer: timer) { result in |
||||
switch result { |
||||
case .success: |
||||
break |
||||
case .failure(let failure): |
||||
switch failure { |
||||
case TimerError.notificationAuthorizationMissing: |
||||
self.boringContext.showPermissionAlert = true |
||||
default: |
||||
self.boringContext.error = failure |
||||
self.boringContext.showDefaultAlert = true |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
struct DialView_Previews: PreviewProvider { |
||||
static var previews: some View { |
||||
DialView(timer: Countdown.fake(context: PersistenceController.preview.container.viewContext), frameSize: 150.0) |
||||
} |
||||
} |
||||
Loading…
Reference in new issue