parent
d0b31d2c3e
commit
04cc931ce8
@ -0,0 +1,40 @@ |
||||
// |
||||
// SiriTimerView.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 10/03/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
import _AppIntents_SwiftUI |
||||
|
||||
struct SiriTimerView: View { |
||||
|
||||
var timer: AbstractTimer? = nil |
||||
|
||||
@State var isVisible = true |
||||
|
||||
var body: some View { |
||||
if self.timer != nil { |
||||
SiriTipView(intent: self.intent(), isVisible: self.$isVisible) |
||||
.siriTipViewStyle(SiriTipViewStyle.dark).padding() |
||||
} else { |
||||
Text("no siri view") |
||||
} |
||||
} |
||||
|
||||
fileprivate func intent() -> StartTimerIntent { |
||||
let intent = StartTimerIntent() |
||||
if let timer { |
||||
intent.timer = TimerIdentifierAppEntity(id: timer.stringId, displayString: timer.displayName) |
||||
} |
||||
return intent |
||||
} |
||||
|
||||
} |
||||
|
||||
struct SiriTimerView_Previews: PreviewProvider { |
||||
static var previews: some View { |
||||
SiriTimerView() |
||||
} |
||||
} |
||||
@ -0,0 +1,107 @@ |
||||
// |
||||
// TimersView.swift |
||||
// LeCountdown |
||||
// |
||||
// Created by Laurent Morvillier on 10/03/2023. |
||||
// |
||||
|
||||
import SwiftUI |
||||
|
||||
struct TimersView: View { |
||||
|
||||
@EnvironmentObject var boringContext: BoringContext |
||||
|
||||
@Environment(\.managedObjectContext) private var viewContext |
||||
|
||||
@Binding var isEditing: Bool |
||||
|
||||
@FetchRequest( |
||||
sortDescriptors: [NSSortDescriptor(keyPath: \AbstractTimer.order, ascending: true)], |
||||
animation: .default) |
||||
private var timers: FetchedResults<AbstractTimer> |
||||
|
||||
fileprivate let itemSpacing: CGFloat = 10.0 |
||||
|
||||
var body: some View { |
||||
|
||||
GeometryReader { reader in |
||||
|
||||
let columns: [GridItem] = self._columns() |
||||
let width: CGFloat = reader.size.width / CGFloat(columns.count) - 15.0 |
||||
let abstractTimers: [AbstractTimer] = Array(self.timers) |
||||
|
||||
if abstractTimers.count > 0 { |
||||
|
||||
ScrollView { |
||||
|
||||
LazyVGrid( |
||||
columns: columns, |
||||
spacing: itemSpacing |
||||
) { |
||||
|
||||
ReorderableForEach(items: abstractTimers) { timer in |
||||
|
||||
DialView(timer: timer, isEditingBinding: self.$isEditing, frameSize: width, handler: { timer in |
||||
self._handleSiriTips(timer: timer) |
||||
}) |
||||
.environment(\.managedObjectContext, viewContext) |
||||
.environmentObject(Conductor.maestro) |
||||
.environmentObject(boringContext) |
||||
} moveAction: { from, to in |
||||
self._reorder(from: from, to: to) |
||||
} |
||||
|
||||
} |
||||
} |
||||
} else { |
||||
Text("You'll find your timers here. Start by creating them on the left screen") |
||||
} |
||||
}.padding(.horizontal, itemSpacing) |
||||
|
||||
} |
||||
|
||||
fileprivate func _reorder(from: IndexSet, to: Int) { |
||||
var timers: [AbstractTimer] = Array(self.timers) |
||||
timers.move(fromOffsets: from, toOffset: to) |
||||
for (i, countdown) in timers.enumerated() { |
||||
countdown.order = Int16(i) |
||||
} |
||||
do { |
||||
try viewContext.save() |
||||
} catch { |
||||
Logger.error(error) |
||||
self.boringContext.error = error |
||||
} |
||||
} |
||||
|
||||
fileprivate func _handleSiriTips(timer: AbstractTimer) { |
||||
let timerId = timer.stringId |
||||
if !Preferences.timerSiriTips.contains(timerId) { |
||||
self.boringContext.siriTimer = timer |
||||
Preferences.timerSiriTips.insert(timerId) |
||||
} |
||||
} |
||||
|
||||
fileprivate func _columnCount() -> Int { |
||||
#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) } |
||||
} |
||||
|
||||
} |
||||
|
||||
struct TimersView_Previews: PreviewProvider { |
||||
static var previews: some View { |
||||
TimersView(isEditing: .constant(false)) |
||||
} |
||||
} |
||||
Loading…
Reference in new issue