@ -70,14 +70,18 @@ struct CountdownEditView : View {
// @ F o c u s S t a t e p r i v a t e v a r t e x t F i e l d I s F o c u s e d : B o o l
// @ F o c u s S t a t e p r i v a t e v a r t e x t F i e l d I s F o c u s e d : B o o l
@ FetchRequest ( sortDescriptors : [ ] )
// @ F e t c h R e q u e s t ( s o r t D e s c r i p t o r s : [ ] )
private var timers : FetchedResults < AbstractTimer >
// p r i v a t e v a r t i m e r s : F e t c h e d R e s u l t s < A b s t r a c t T i m e r >
@ State var _isNewCountdown : Bool = false // f a l s e i f e d i t i n g a n e x i s t i n g c o u n t d o w n
@ State var _isNewCountdown : Bool = false // f a l s e i f e d i t i n g a n e x i s t i n g c o u n t d o w n
@ State var _hasLoaded = false
@ State var _hasLoaded = false
@ Environment ( \ . isPresented ) var envIsPresented
@ Environment ( \ . isPresented ) var envIsPresented
@ State var shouldScrollToTop : Bool = false
@ FocusState private var focusedField : CountdownField ?
init ( isPresented : Binding < Bool > , countdown : Countdown ? = nil , tabSelection : Binding < Int > ? = nil ) {
init ( isPresented : Binding < Bool > , countdown : Countdown ? = nil , tabSelection : Binding < Int > ? = nil ) {
_isPresented = isPresented
_isPresented = isPresented
self . countdown = countdown
self . countdown = countdown
@ -90,8 +94,13 @@ struct CountdownEditView : View {
self . tabSelection = tabSelection
self . tabSelection = tabSelection
}
}
fileprivate var _formId = " formId "
var body : some View {
var body : some View {
NavigationStack {
NavigationStack {
ScrollViewReader { reader in
Rectangle ( )
Rectangle ( )
. frame ( width : 0.0 , height : 0.0 )
. frame ( width : 0.0 , height : 0.0 )
. onChange ( of : envIsPresented ) { newValue in
. onChange ( of : envIsPresented ) { newValue in
@ -99,13 +108,53 @@ struct CountdownEditView : View {
self . _save ( ) // s a v e w h e n l e a v i n g a n e d i t s c r e e n
self . _save ( ) // s a v e w h e n l e a v i n g a n e d i t s c r e e n
}
}
}
}
Form {
EmptyView ( ) . id ( " anchor " )
CountdownFormView (
CountdownFormView (
focusedField : _focusedField ,
secondsBinding : $ secondsString ,
secondsBinding : $ secondsString ,
minutesBinding : $ minutesString ,
minutesBinding : $ minutesString ,
nameBinding : $ nameString ,
nameBinding : $ nameString ,
imageBinding : $ image ,
imageBinding : $ image ,
repeatCountBinding : $ soundRepeatCount )
repeatCountBinding : $ soundRepeatCount )
. environmentObject ( self . model )
. environmentObject ( self . model )
BasePresetsView { preset in
self . _loadPreset ( preset )
}
} . toolbar {
ToolbarItemGroup ( placement : . keyboard ) {
Button {
self . focusedField = nil
} label : {
Image ( systemName : " keyboard.chevron.compact.down " )
}
Spacer ( )
Button {
self . focusPreviousField ( $ focusedField )
} label : {
Image ( systemName : " chevron.up " )
}
Button {
self . focusNextField ( $ focusedField )
} label : {
Image ( systemName : " chevron.down " )
}
}
}
. onChange ( of : self . shouldScrollToTop ) { newValue in
withAnimation {
reader . scrollTo ( " anchor " )
}
}
}
. navigationTitle ( " Edit countdown " )
}
. onAppear {
. onAppear {
self . _onAppear ( )
self . _onAppear ( )
}
}
@ -157,8 +206,6 @@ struct CountdownEditView : View {
}
}
}
}
}
}
. navigationTitle ( " Edit countdown " )
}
}
}
@ -185,16 +232,20 @@ struct CountdownEditView : View {
let minutes = Int ( preset . duration / 60.0 )
let minutes = Int ( preset . duration / 60.0 )
if minutes > 0 {
if minutes > 0 {
self . minutesString = nf . string ( from : NSNumber ( value : minutes ) ) ? ? " "
self . minutesString = nf . string ( from : NSNumber ( value : minutes ) ) ? ? " "
} else {
self . minutesString = " "
}
}
let seconds = Int ( preset . duration ) - minutes * 60
let seconds = Int ( preset . duration ) - minutes * 60
if seconds > 0 {
if seconds > 0 {
self . secondsString = nf . string ( from : NSNumber ( value : seconds ) ) ? ? " "
self . secondsString = nf . string ( from : NSNumber ( value : seconds ) ) ? ? " "
} else {
self . secondsString = " "
}
}
self . model . group = preset . intervalGroup
self . model . group = preset . intervalGroup
self . model . soundModel . sounds = preset . sound
self . model . soundModel . loadPreset ( preset )
self . shouldScrollToTop . toggle ( )
}
}
fileprivate func _loadCountdown ( _ countdown : Countdown ) {
fileprivate func _loadCountdown ( _ countdown : Countdown ) {
@ -235,7 +286,7 @@ struct CountdownEditView : View {
}
}
fileprivate func _cancel ( ) {
fileprivate func _cancel ( ) {
viewContext . rollback ( )
self . viewContext . rollback ( )
self . isPresented = false
self . isPresented = false
}
}
@ -251,11 +302,20 @@ struct CountdownEditView : View {
cd . duration = self . _minutes * 60.0 + self . _seconds
cd . duration = self . _minutes * 60.0 + self . _seconds
if self . _isNewCountdown {
if self . _isNewCountdown {
let max : Int16
let max : Int16
if let maxOrder = self . timers . map ( { $0 . order } ) . max ( ) {
do {
let request = AbstractTimer . fetchRequest ( )
let timers = try viewContext . fetch ( request )
if let maxOrder = timers . map ( { $0 . order } ) . max ( ) {
max = maxOrder + 1
max = maxOrder + 1
} else {
} else {
max = 0
max = 0
}
}
} catch {
max = 0
}
cd . order = max
cd . order = max
}
}
@ -303,9 +363,7 @@ struct CountdownEditView : View {
dismiss ( )
dismiss ( )
}
}
// i f s e l f . p r e s e t ! = n i l {
self . tabSelection ? . wrappedValue = 1
self . tabSelection ? . wrappedValue = 1
// }
}
}
@ -340,7 +398,8 @@ struct CountdownEditView : View {
struct NewCountdownView_Previews : PreviewProvider {
struct NewCountdownView_Previews : PreviewProvider {
static var previews : some View {
static var previews : some View {
NewCountdownView ( isPresented : . constant ( true ) , tabSelection : . constant ( 0 ) )
NewCountdownView ( isPresented : . constant ( true ) ,
tabSelection : . constant ( 0 ) )
. environment ( \ . managedObjectContext , PersistenceController . preview . container . viewContext )
. environment ( \ . managedObjectContext , PersistenceController . preview . container . viewContext )
}
}
}
}