Implement round timer functionality and add a deck reset button
This commit is contained in:
parent
65b99570dc
commit
b5cd26488c
|
@ -40,9 +40,10 @@ extension CardDeckContainerView {
|
|||
@Published var cards: [Card] = []
|
||||
@Published var timeRemaining: TimeInterval
|
||||
|
||||
|
||||
// MARK: - Init
|
||||
init(
|
||||
roundDuration: TimeInterval = 10.0
|
||||
roundDuration: TimeInterval = 100.0
|
||||
) {
|
||||
self.roundDuration = roundDuration
|
||||
self.timeRemaining = roundDuration
|
||||
|
@ -80,10 +81,11 @@ extension CardDeckContainerView.ViewModel {
|
|||
|
||||
// MARK: - Computeds
|
||||
extension CardDeckContainerView.ViewModel {
|
||||
|
||||
var timeRemainingText: String {
|
||||
NumberFormatters.cardCountdown.string(for: timeRemaining) ?? ""
|
||||
}
|
||||
|
||||
var isDeckEmpty: Bool { cards.isEmpty }
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,6 +97,18 @@ extension CardDeckContainerView.ViewModel {
|
|||
try? fetchedResultsController.performFetch()
|
||||
cards = extractResults(from: fetchedResultsController)
|
||||
}
|
||||
|
||||
|
||||
func resetDeck() {
|
||||
fetchCards()
|
||||
self.timeRemaining = roundDuration
|
||||
self.isTimerActive = true
|
||||
}
|
||||
|
||||
|
||||
func pauseRound() {
|
||||
isTimerActive = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,7 +130,7 @@ private extension CardDeckContainerView.ViewModel {
|
|||
|
||||
CurrentApp.notificationCenter
|
||||
.publisher(for: UIApplication.willEnterForegroundNotification)
|
||||
.map { _ in true }
|
||||
.map { _ in self.isDeckEmpty == false }
|
||||
.assign(to: \.isTimerActive, on: self)
|
||||
.store(in: &subscriptions)
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ import CypherPoetSwiftUIKit
|
|||
|
||||
|
||||
struct CardDeckContainerView {
|
||||
@Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor
|
||||
|
||||
@ObservedObject var viewModel: ViewModel = .init()
|
||||
}
|
||||
|
||||
|
@ -23,8 +21,8 @@ extension CardDeckContainerView: View {
|
|||
var body: some View {
|
||||
GeometryReader { geometry in
|
||||
ZStack {
|
||||
VStack {
|
||||
Text("Time Remaining: \(self.viewModel.timeRemaining)")
|
||||
VStack(spacing: 22) {
|
||||
Text("Time Remaining: \(self.viewModel.timeRemainingText)")
|
||||
.font(.largeTitle)
|
||||
.foregroundColor(Color.yellow)
|
||||
.padding(.horizontal)
|
||||
|
@ -39,19 +37,22 @@ extension CardDeckContainerView: View {
|
|||
onRemove: { (card, index) in self.cardRemoved(at: index) }
|
||||
)
|
||||
.allowsHitTesting(self.viewModel.timeRemaining > 0)
|
||||
.padding()
|
||||
}
|
||||
|
||||
|
||||
if self.differentiateWithoutColor {
|
||||
if self.viewModel.isDeckEmpty {
|
||||
VStack {
|
||||
Spacer()
|
||||
|
||||
self.swipeDirectionIndicators
|
||||
HStack {
|
||||
Spacer()
|
||||
self.resetButton
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.padding()
|
||||
.background(Color("CardDeckBackground"))
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
}
|
||||
|
@ -66,24 +67,12 @@ extension CardDeckContainerView {
|
|||
// MARK: - View Variables
|
||||
extension CardDeckContainerView {
|
||||
|
||||
private var swipeDirectionIndicators: some View {
|
||||
HStack {
|
||||
Image(systemName: "xmark.circle")
|
||||
.padding()
|
||||
.background(Color.black.opacity(0.7))
|
||||
.clipShape(Circle())
|
||||
|
||||
Spacer()
|
||||
|
||||
|
||||
Image(systemName: "checkmark.circle")
|
||||
.padding()
|
||||
.background(Color.black.opacity(0.7))
|
||||
.clipShape(Circle())
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.font(.largeTitle)
|
||||
|
||||
private var resetButton: some View {
|
||||
Button("Start Again", action: viewModel.resetDeck)
|
||||
.padding()
|
||||
.background(Color.white)
|
||||
.foregroundColor(.black)
|
||||
.clipShape(Capsule())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +83,10 @@ extension CardDeckContainerView {
|
|||
private extension CardDeckContainerView {
|
||||
func cardRemoved(at index: Int) {
|
||||
viewModel.cards.remove(at: index)
|
||||
|
||||
if viewModel.isDeckEmpty {
|
||||
viewModel.pauseRound()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +98,6 @@ struct CardDeckContainerView_Previews: PreviewProvider {
|
|||
static var previews: some View {
|
||||
CardDeckContainerView()
|
||||
.environment(\.managedObjectContext, CurrentApp.coreDataManager.mainContext)
|
||||
// .environment(\.accessibilityDifferentiateWithoutColor, .constant(true))
|
||||
.previewLayout(PreviewLayout.iPhone11Landscape)
|
||||
// .previewLayout(PreviewLayout.iPhone11Landscape)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import SwiftUI
|
|||
|
||||
|
||||
struct CardDeckView {
|
||||
@Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor
|
||||
|
||||
var width: CGFloat
|
||||
var height: CGFloat
|
||||
|
||||
|
@ -33,7 +35,36 @@ extension CardDeckView: View {
|
|||
)
|
||||
.stacked(at: index + 1, outOf: deckSize, offsetMultiple: CGFloat(30 / deckSize))
|
||||
}
|
||||
|
||||
|
||||
if self.differentiateWithoutColor {
|
||||
VStack {
|
||||
Spacer()
|
||||
|
||||
self.swipeDirectionIndicators
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(width: width, height: height)
|
||||
}
|
||||
|
||||
|
||||
private var swipeDirectionIndicators: some View {
|
||||
HStack {
|
||||
Image(systemName: "xmark.circle")
|
||||
.padding()
|
||||
.background(Color.black.opacity(0.7))
|
||||
.clipShape(Circle())
|
||||
|
||||
Spacer()
|
||||
|
||||
|
||||
Image(systemName: "checkmark.circle")
|
||||
.padding()
|
||||
.background(Color.black.opacity(0.7))
|
||||
.clipShape(Circle())
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.font(.largeTitle)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue