|
|
|
|
@ -7,6 +7,7 @@ |
|
|
|
|
|
|
|
|
|
import SwiftUI |
|
|
|
|
import CoreData |
|
|
|
|
import WidgetKit |
|
|
|
|
|
|
|
|
|
struct NewCountdownView : View { |
|
|
|
|
|
|
|
|
|
@ -15,8 +16,9 @@ struct NewCountdownView : View { |
|
|
|
|
@Binding var isPresented: Bool |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
CountdownEditView(countdown: Countdown(context: viewContext), isPresented: $isPresented) |
|
|
|
|
CountdownEditView(isPresented: $isPresented) |
|
|
|
|
.environment(\.managedObjectContext, viewContext) |
|
|
|
|
.navigationTitle("New countdown") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
@ -26,7 +28,7 @@ struct CountdownEditView : View { |
|
|
|
|
@Environment(\.managedObjectContext) private var viewContext |
|
|
|
|
@Environment(\.dismiss) private var dismiss |
|
|
|
|
|
|
|
|
|
var countdown: Countdown |
|
|
|
|
var countdown: Countdown? = nil |
|
|
|
|
|
|
|
|
|
@Binding var isPresented: Bool |
|
|
|
|
|
|
|
|
|
@ -44,6 +46,8 @@ struct CountdownEditView : View { |
|
|
|
|
@FetchRequest(sortDescriptors: []) |
|
|
|
|
private var countdowns: FetchedResults<Countdown> |
|
|
|
|
|
|
|
|
|
@State var _isAdding: Bool = false |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
NavigationStack { |
|
|
|
|
|
|
|
|
|
@ -66,7 +70,7 @@ struct CountdownEditView : View { |
|
|
|
|
Text("Sound") |
|
|
|
|
} |
|
|
|
|
}.onAppear { |
|
|
|
|
self._initDuration() |
|
|
|
|
self._onAppear() |
|
|
|
|
} |
|
|
|
|
.confirmationDialog("", isPresented: $deleteConfirmationShown, actions: { |
|
|
|
|
Button("Yes", role: .destructive) { |
|
|
|
|
@ -82,7 +86,7 @@ struct CountdownEditView : View { |
|
|
|
|
Text(error?.localizedDescription ?? "error") |
|
|
|
|
}) |
|
|
|
|
.toolbar { |
|
|
|
|
if self.countdown.isTemporary { |
|
|
|
|
if self._isAdding { |
|
|
|
|
ToolbarItem(placement: .navigationBarLeading) { |
|
|
|
|
Button("Cancel") { |
|
|
|
|
self._cancel() |
|
|
|
|
@ -94,11 +98,13 @@ struct CountdownEditView : View { |
|
|
|
|
self._save() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
ToolbarItem(placement: .bottomBar) { |
|
|
|
|
Button { |
|
|
|
|
self.deleteConfirmationShown = true |
|
|
|
|
} label: { |
|
|
|
|
Image(systemName: "trash") |
|
|
|
|
if !self._isAdding { |
|
|
|
|
ToolbarItem(placement: .bottomBar) { |
|
|
|
|
Button { |
|
|
|
|
self.deleteConfirmationShown = true |
|
|
|
|
} label: { |
|
|
|
|
Image(systemName: "trash") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
ToolbarItemGroup(placement: .keyboard) { |
|
|
|
|
@ -109,26 +115,31 @@ struct CountdownEditView : View { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
.navigationTitle("New countdown") |
|
|
|
|
.navigationTitle("Edit countdown") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _initDuration() { |
|
|
|
|
fileprivate func _onAppear() { |
|
|
|
|
|
|
|
|
|
let minutes = Int(self.countdown.duration / 60.0) |
|
|
|
|
let seconds = self.countdown.duration - Double(minutes * 60) |
|
|
|
|
self._isAdding = (self.countdown == nil) |
|
|
|
|
|
|
|
|
|
if minutes > 0 { |
|
|
|
|
self.minutesString = self._numberFormatter.string(from: NSNumber(value: minutes)) ?? "" |
|
|
|
|
} |
|
|
|
|
if let countdown { |
|
|
|
|
|
|
|
|
|
let minutes = Int(countdown.duration / 60.0) |
|
|
|
|
let seconds = countdown.duration - Double(minutes * 60) |
|
|
|
|
|
|
|
|
|
if minutes > 0 { |
|
|
|
|
self.minutesString = self._numberFormatter.string(from: NSNumber(value: minutes)) ?? "" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if seconds > 0 { |
|
|
|
|
self.secondsString = self._numberFormatter.string(from: NSNumber(value: seconds)) ?? "" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if let name = self.countdown.name, !name.isEmpty { |
|
|
|
|
self.nameString = name |
|
|
|
|
if seconds > 0 { |
|
|
|
|
self.secondsString = self._numberFormatter.string(from: NSNumber(value: seconds)) ?? "" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if let name = countdown.name, !name.isEmpty { |
|
|
|
|
self.nameString = name |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
@ -150,29 +161,45 @@ struct CountdownEditView : View { |
|
|
|
|
|
|
|
|
|
fileprivate func _save() { |
|
|
|
|
|
|
|
|
|
let temporary = self.countdown.isTemporary |
|
|
|
|
let cd: Countdown |
|
|
|
|
if let countdown { |
|
|
|
|
cd = countdown |
|
|
|
|
} else { |
|
|
|
|
cd = Countdown(context: viewContext) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
countdown.duration = self._minutes * 60.0 + self._seconds |
|
|
|
|
if temporary { |
|
|
|
|
countdown.order = Int16(self.countdowns.count) |
|
|
|
|
cd.duration = self._minutes * 60.0 + self._seconds |
|
|
|
|
if self._isAdding { |
|
|
|
|
cd.order = Int16(self.countdowns.count) |
|
|
|
|
} |
|
|
|
|
if !self.nameString.isEmpty { |
|
|
|
|
countdown.name = self.nameString |
|
|
|
|
cd.name = self.nameString |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
self._saveContext() |
|
|
|
|
|
|
|
|
|
if temporary { |
|
|
|
|
WidgetCenter.shared.reloadTimelines(ofKind: "com.staxriver.launch-widget") // refreshes the visual of existing widgets |
|
|
|
|
|
|
|
|
|
self._popOrDismiss() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _popOrDismiss() { |
|
|
|
|
if self._isAdding { |
|
|
|
|
self.isPresented = false |
|
|
|
|
} else { |
|
|
|
|
dismiss() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _delete() { |
|
|
|
|
viewContext.delete(self.countdown) |
|
|
|
|
|
|
|
|
|
guard let countdown else { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
viewContext.delete(countdown) |
|
|
|
|
self._saveContext() |
|
|
|
|
self._popOrDismiss() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _saveContext() { |
|
|
|
|
@ -189,5 +216,6 @@ struct CountdownEditView : View { |
|
|
|
|
struct NewCountdownView_Previews: PreviewProvider { |
|
|
|
|
static var previews: some View { |
|
|
|
|
NewCountdownView(isPresented: .constant(true)) |
|
|
|
|
.environment(\.managedObjectContext, PersistenceController.shared.container.viewContext) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|