|
|
|
|
@ -7,6 +7,140 @@ |
|
|
|
|
|
|
|
|
|
import SwiftUI |
|
|
|
|
|
|
|
|
|
class PresetModel : ObservableObject { |
|
|
|
|
|
|
|
|
|
@Published var selectedPreset: Preset = Preset.hardBoiledEggs |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct PresetsView: View { |
|
|
|
|
|
|
|
|
|
@Environment(\.managedObjectContext) private var viewContext |
|
|
|
|
|
|
|
|
|
@StateObject var model: PresetModel = PresetModel() |
|
|
|
|
|
|
|
|
|
@State var isPresented: Bool = false |
|
|
|
|
|
|
|
|
|
@State var isShowingNewCountdown = false |
|
|
|
|
@State var isShowingNewStopwatch = false |
|
|
|
|
|
|
|
|
|
var tabSelection: Binding<Int> |
|
|
|
|
|
|
|
|
|
fileprivate func _columnCount() -> Int { |
|
|
|
|
return 2 |
|
|
|
|
|
|
|
|
|
// #if os(iOS) |
|
|
|
|
// if UIDevice.isPhoneIdiom { |
|
|
|
|
// return 2 |
|
|
|
|
// } else { |
|
|
|
|
// return 3 |
|
|
|
|
// } |
|
|
|
|
// #else |
|
|
|
|
// return 3 |
|
|
|
|
// #endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _columns() -> [GridItem] { |
|
|
|
|
return (0..<self._columnCount()).map { _ in GridItem(spacing: 10.0) } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
|
|
|
|
|
ScrollView { |
|
|
|
|
|
|
|
|
|
VStack(alignment: .leading, spacing: 10.0) { |
|
|
|
|
Button { |
|
|
|
|
self.isShowingNewCountdown = true |
|
|
|
|
} label: { |
|
|
|
|
Text("Create countdown".uppercased()) |
|
|
|
|
.frame(maxWidth: .infinity) |
|
|
|
|
.frame(height: 40.0) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Button { |
|
|
|
|
self.isShowingNewStopwatch = true |
|
|
|
|
} label: { |
|
|
|
|
Text("Create stopwatch".uppercased()) |
|
|
|
|
.frame(maxWidth: .infinity) |
|
|
|
|
.frame(height: 40.0) |
|
|
|
|
} |
|
|
|
|
}.padding(.horizontal).monospaced().buttonStyle(.bordered) |
|
|
|
|
|
|
|
|
|
VStack(alignment: .leading) { |
|
|
|
|
SeparatorView() |
|
|
|
|
|
|
|
|
|
Text("Presets") |
|
|
|
|
.font(.system(.title, weight: .heavy)) |
|
|
|
|
|
|
|
|
|
Text("You can edit the duration, sound and label before adding") |
|
|
|
|
.foregroundColor(.gray) |
|
|
|
|
.font(.callout) |
|
|
|
|
|
|
|
|
|
}.padding(.horizontal) |
|
|
|
|
|
|
|
|
|
LazyVGrid( |
|
|
|
|
columns: self._columns(), |
|
|
|
|
alignment: .leading, |
|
|
|
|
spacing: 10.0 |
|
|
|
|
) { |
|
|
|
|
|
|
|
|
|
ForEach(PresetSection.allCases) { section in |
|
|
|
|
Section(section.localizedName.uppercased()) { |
|
|
|
|
ForEach(section.presets) { preset in |
|
|
|
|
|
|
|
|
|
Button { |
|
|
|
|
self.model.selectedPreset = preset |
|
|
|
|
self.isPresented = true |
|
|
|
|
} label: { |
|
|
|
|
TimerItemView(name: preset.localizedName, duration: preset.formattedDuration, sound: preset.soundTitle) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}.padding(.horizontal) |
|
|
|
|
|
|
|
|
|
Spacer() |
|
|
|
|
} |
|
|
|
|
.sheet(isPresented: $isShowingNewStopwatch, content: { |
|
|
|
|
NewStopwatchView(isPresented: $isShowingNewStopwatch, tabSelection: self.tabSelection) |
|
|
|
|
.environment(\.managedObjectContext, viewContext) |
|
|
|
|
}) |
|
|
|
|
.sheet(isPresented: $isShowingNewCountdown, content: { |
|
|
|
|
NewCountdownView(isPresented: $isShowingNewCountdown, tabSelection: self.tabSelection) |
|
|
|
|
.environment(\.managedObjectContext, viewContext) |
|
|
|
|
}) |
|
|
|
|
.sheet(isPresented: $isPresented, content: { |
|
|
|
|
CountdownEditView(isPresented: $isPresented, preset: self.model.selectedPreset, tabSelection: self.tabSelection) |
|
|
|
|
.environment(\.managedObjectContext, viewContext) |
|
|
|
|
}) |
|
|
|
|
.navigationTitle("Create") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct TimerItemView: View { |
|
|
|
|
|
|
|
|
|
var name: String |
|
|
|
|
var duration: String |
|
|
|
|
var sound: String |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
HStack { |
|
|
|
|
VStack(alignment: .leading) { |
|
|
|
|
Text(self.name.uppercased()) |
|
|
|
|
Text(self.duration) |
|
|
|
|
Text(self.sound.uppercased()).foregroundColor(Color(white: 0.7)) |
|
|
|
|
}.padding() |
|
|
|
|
.multilineTextAlignment(.leading) |
|
|
|
|
Spacer() |
|
|
|
|
}.background(Color(white: 0.1)) |
|
|
|
|
.cornerRadius(16.0) |
|
|
|
|
.monospaced() |
|
|
|
|
.font(Font.system(size: 16.0, weight: .semibold)) |
|
|
|
|
.foregroundColor(Color.white) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum PresetSection: Int, Identifiable, CaseIterable { |
|
|
|
|
var id: Int { return self.rawValue } |
|
|
|
|
|
|
|
|
|
@ -135,144 +269,6 @@ enum Preset: Int, Identifiable, CaseIterable { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class PresetModel : ObservableObject { |
|
|
|
|
|
|
|
|
|
@Published var selectedPreset: Preset = Preset.hardBoiledEggs |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct PresetsView: View { |
|
|
|
|
|
|
|
|
|
@Environment(\.managedObjectContext) private var viewContext |
|
|
|
|
|
|
|
|
|
@StateObject var model: PresetModel = PresetModel() |
|
|
|
|
|
|
|
|
|
@State var isPresented: Bool = false |
|
|
|
|
|
|
|
|
|
@State var isShowingNewCountdown = false |
|
|
|
|
@State var isShowingNewStopwatch = false |
|
|
|
|
|
|
|
|
|
var tabSelection: Binding<Int> |
|
|
|
|
|
|
|
|
|
fileprivate func _columnCount() -> Int { |
|
|
|
|
return 2 |
|
|
|
|
|
|
|
|
|
// #if os(iOS) |
|
|
|
|
// if UIDevice.isPhoneIdiom { |
|
|
|
|
// return 2 |
|
|
|
|
// } else { |
|
|
|
|
// return 3 |
|
|
|
|
// } |
|
|
|
|
// #else |
|
|
|
|
// return 3 |
|
|
|
|
// #endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _columns() -> [GridItem] { |
|
|
|
|
return (0..<self._columnCount()).map { _ in GridItem(spacing: 10.0) } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
|
|
|
|
|
ScrollView { |
|
|
|
|
|
|
|
|
|
VStack(alignment: .leading, spacing: 0.0) { |
|
|
|
|
Button { |
|
|
|
|
self.isShowingNewCountdown = true |
|
|
|
|
} label: { |
|
|
|
|
Text(".create countdown") |
|
|
|
|
.font(.system(.title, weight: .heavy)) |
|
|
|
|
Spacer() |
|
|
|
|
}.frame(height: 40.0) |
|
|
|
|
|
|
|
|
|
Button { |
|
|
|
|
self.isShowingNewStopwatch = true |
|
|
|
|
} label: { |
|
|
|
|
Text(".create stopwatch") |
|
|
|
|
.font(.system(.title, weight: .heavy)) |
|
|
|
|
Spacer() |
|
|
|
|
}.frame(height: 40.0) |
|
|
|
|
SeparatorView() |
|
|
|
|
|
|
|
|
|
Text("Presets") |
|
|
|
|
.font(.system(.title, weight: .heavy)) |
|
|
|
|
|
|
|
|
|
Text("You can edit the duration, sound and label before adding") |
|
|
|
|
.font(.callout) |
|
|
|
|
|
|
|
|
|
}.padding(.horizontal) |
|
|
|
|
|
|
|
|
|
LazyVGrid( |
|
|
|
|
columns: self._columns(), |
|
|
|
|
spacing: 10.0 |
|
|
|
|
) { |
|
|
|
|
|
|
|
|
|
ForEach(PresetSection.allCases) { section in |
|
|
|
|
Section { |
|
|
|
|
ForEach(section.presets) { preset in |
|
|
|
|
|
|
|
|
|
Button { |
|
|
|
|
self.model.selectedPreset = preset |
|
|
|
|
self.isPresented = true |
|
|
|
|
} label: { |
|
|
|
|
|
|
|
|
|
TimerItemView(name: preset.localizedName, duration: preset.formattedDuration, sound: preset.soundTitle) |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} header: { |
|
|
|
|
HStack { |
|
|
|
|
Text(section.localizedName.uppercased()) |
|
|
|
|
Spacer() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}.padding(.horizontal) |
|
|
|
|
|
|
|
|
|
Spacer() |
|
|
|
|
} |
|
|
|
|
.sheet(isPresented: $isShowingNewStopwatch, content: { |
|
|
|
|
NewStopwatchView(isPresented: $isShowingNewStopwatch, tabSelection: self.tabSelection) |
|
|
|
|
.environment(\.managedObjectContext, viewContext) |
|
|
|
|
}) |
|
|
|
|
.sheet(isPresented: $isShowingNewCountdown, content: { |
|
|
|
|
NewCountdownView(isPresented: $isShowingNewCountdown, tabSelection: self.tabSelection) |
|
|
|
|
.environment(\.managedObjectContext, viewContext) |
|
|
|
|
}) |
|
|
|
|
.sheet(isPresented: $isPresented, content: { |
|
|
|
|
CountdownEditView(isPresented: $isPresented, preset: self.model.selectedPreset, tabSelection: self.tabSelection) |
|
|
|
|
.environment(\.managedObjectContext, viewContext) |
|
|
|
|
}) |
|
|
|
|
.navigationTitle("Create") |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct TimerItemView: View { |
|
|
|
|
|
|
|
|
|
var name: String |
|
|
|
|
var duration: String |
|
|
|
|
var sound: String |
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
HStack { |
|
|
|
|
VStack(alignment: .leading) { |
|
|
|
|
Text(self.name.uppercased()) |
|
|
|
|
Text(self.duration) |
|
|
|
|
Text(self.sound.uppercased()).foregroundColor(Color(white: 0.7)) |
|
|
|
|
}.padding() |
|
|
|
|
.multilineTextAlignment(.leading) |
|
|
|
|
Spacer() |
|
|
|
|
}.background(Color(white: 0.1)) |
|
|
|
|
.cornerRadius(16.0) |
|
|
|
|
.monospaced() |
|
|
|
|
.font(Font.system(size: 16.0, weight: .semibold)) |
|
|
|
|
.foregroundColor(Color.white) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct PresetsView_Previews: PreviewProvider { |
|
|
|
|
static var previews: some View { |
|
|
|
|
PresetsView(tabSelection: .constant(0)) |
|
|
|
|
|