You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
LeCountdown/LeCountdown/Views/DialView.swift

171 lines
5.4 KiB

//
// DialView.swift
// LeCountdown
//
// Created by Laurent Morvillier on 02/02/2023.
//
import SwiftUI
struct DialView: View {
@Environment(\.managedObjectContext) private var viewContext
@Environment(\.colorScheme) var colorScheme
@EnvironmentObject var boringContext: BoringContext
@EnvironmentObject var conductor: Conductor
@State var timer: AbstractTimer
var isLaunchable: Bool
var isEditingBinding: Binding<Bool>
@Binding var showSubscriptionSheet: Bool
var frameSize: CGFloat
var handler: ((AbstractTimer) -> ())? = nil
var body: some View {
ZStack {
switch self.isEditingBinding.wrappedValue {
case false:
Button {
if self.isLaunchable {
self._launchTimer()
} else {
self.showSubscriptionSheet = true
}
} label: {
ZStack {
VStack {
Spacer()
self._dialView().padding(.horizontal)
Spacer()
}
if !self.isLaunchable {
Group {
Image(systemName: "lock.circle").font(.title).foregroundColor(.white)
}.frame(maxWidth: .infinity, maxHeight: .infinity).background(Color(white: 0.0, opacity: 0.6))
}
}
}
case true:
NavigationLink {
self._editView(timer: timer, isPresented: $boringContext.isShowingNewData)
} label: {
VStack {
Spacer()
self._dialView().padding(.horizontal)
Spacer()
}
}
}
}
.background(self._dialBackgroundColor)
.frame(width: self.frameSize, height: self._height)
.cornerRadius(20.0)
}
fileprivate var _height: CGFloat {
return UIDevice.isPhoneIdiom ? 80.0 : 200.0
}
private var _dialBackgroundColor: Color {
let darkMode = self.colorScheme == .dark
let isEditing = self.isEditingBinding.wrappedValue
if darkMode {
if isEditing {
return Color.accentColor
} else {
return Color(white: 0.1)
}
} else {
return Color(white: isEditing ? 0.1 : 0.95)
}
}
@ViewBuilder
fileprivate func _dialView() -> some View {
Group {
switch self.timer {
case let countdown as Countdown:
CountdownDialView(countdown: countdown,
isEditing: self.isEditingBinding.wrappedValue)
.environmentObject(Conductor.maestro)
case let alarm as Alarm:
AlarmDialView(alarm: alarm)
.environmentObject(Conductor.maestro)
case let stopwatch as Stopwatch:
StopwatchDialView(stopwatch: stopwatch,
isEditing: self.isEditingBinding.wrappedValue)
.environmentObject(Conductor.maestro)
default:
Text("missing dial view")
}
}
.monospaced()
.font(.system(size: 16.0))
.foregroundColor(Color.white)
}
@ViewBuilder
fileprivate func _editView(timer: AbstractTimer, isPresented: Binding<Bool>) -> some View {
switch timer {
case let countdown as Countdown:
CountdownEditView(isPresented: isPresented, countdown: countdown)
.environment(\.managedObjectContext, viewContext)
case let alarm as Alarm:
AlarmEditView(alarm: alarm, isPresented: isPresented)
.environment(\.managedObjectContext, viewContext)
case let stopwatch as Stopwatch:
StopwatchEditView(isPresented: isPresented, stopwatch: stopwatch)
.environment(\.managedObjectContext, viewContext)
default:
Text("missing edit view")
}
}
fileprivate func _launchTimer() {
self.handler?(self.timer)
LeCountdownApp.askPermissions()
TimerRouter.performAction(timer: self.timer) { result in
switch result {
case .success:
break
case .failure(let failure):
switch failure {
case TimerRouterError.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),
isLaunchable: true,
isEditingBinding: .constant(false),
showSubscriptionSheet: .constant(false),
frameSize: 150.0)
.environmentObject(Conductor.maestro)
.environmentObject(BoringContext())
}
}