Resize countdown, refactor ButtonView
Countdown was resizing with bigger/smaller countdown left, so added a finite background Turn NextRepetitionButtonView from AnkiView into ButtonHStackView
This commit is contained in:
@@ -29,11 +29,10 @@ class DataController: ObservableObject {
|
|||||||
"This is a very short description",
|
"This is a very short description",
|
||||||
"This is a medium length description that should be long enough to cover all cases"
|
"This is a medium length description that should be long enough to cover all cases"
|
||||||
].randomElement()!
|
].randomElement()!
|
||||||
flashcard.nextSpacedRepetitionMilestone = SpacedRepetitionMilestoneEnum.OneYear.rawValue
|
flashcard.nextSpacedRepetitionMilestone = SpacedRepetitionMilestoneEnum.allCases.randomElement()!.rawValue
|
||||||
flashcard.lastSeenOn = [Date().addingTimeInterval([86400, 24000, 100000].randomElement()!)].randomElement()!
|
flashcard.lastSeenOn = [nil, Date(), Date().addingTimeInterval([-86400, -24000, -100000].randomElement()!)].randomElement()!
|
||||||
flashcard.shownCount = [0, 1, 2, 3, 4, 5].randomElement()!
|
flashcard.shownCount = [0, 1, 2, 3, 4, 5].randomElement()!
|
||||||
flashcard.dateAdded = [Date(), Date().addingTimeInterval(-86400), Date().addingTimeInterval(-172800)].randomElement()!
|
flashcard.dateAdded = [Date(), Date().addingTimeInterval(-86400), Date().addingTimeInterval(-172800)].randomElement()!
|
||||||
// flashcard.calculatedNextRepetition = flashcard.lastSeenOn ?? Date() + TimeInterval(flashcard.nextSpacedRepetitionMilestone)
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
try viewContext.save()
|
try viewContext.save()
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import CoreData
|
|||||||
struct AnkiView: View {
|
struct AnkiView: View {
|
||||||
@EnvironmentObject var model: WordAXModelView
|
@EnvironmentObject var model: WordAXModelView
|
||||||
@Environment(\.managedObjectContext) var moc
|
@Environment(\.managedObjectContext) var moc
|
||||||
|
|
||||||
|
// get flashcards to display
|
||||||
@FetchRequest(sortDescriptors: [
|
@FetchRequest(sortDescriptors: [
|
||||||
NSSortDescriptor(key: "nextSpacedRepetitionMilestone", ascending: false),
|
NSSortDescriptor(key: "nextSpacedRepetitionMilestone", ascending: false),
|
||||||
NSSortDescriptor(key: "lastSeenOn", ascending: true)
|
NSSortDescriptor(key: "lastSeenOn", ascending: true)
|
||||||
@@ -22,20 +24,17 @@ struct AnkiView: View {
|
|||||||
NSPredicate(format: "lastSeenOn == nil")
|
NSPredicate(format: "lastSeenOn == nil")
|
||||||
])) var flashcards: FetchedResults<Flashcard>
|
])) var flashcards: FetchedResults<Flashcard>
|
||||||
|
|
||||||
|
// get the most recent flashcard
|
||||||
|
@FetchRequest(sortDescriptors: [],
|
||||||
|
predicate: NSPredicate(format: "%K != nil", "lastSeenOn")) var soonestFlashcard: FetchedResults<Flashcard>
|
||||||
|
|
||||||
@State private var timeRemaining = 10
|
@State private var timeRemaining = 10
|
||||||
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
|
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
|
||||||
@State var sortedFlashcards: [Flashcard] = []
|
@State var sortedFlashcards: [Flashcard] = []
|
||||||
|
@State var showDescription = false
|
||||||
|
|
||||||
@Environment(\.colorScheme) var colorScheme
|
@Environment(\.colorScheme) var colorScheme
|
||||||
|
|
||||||
|
|
||||||
// get the most recent flashcard
|
|
||||||
@FetchRequest(sortDescriptors: [],
|
|
||||||
predicate: NSPredicate(format: "%K != nil", "lastSeenOn")) var soonestFlashcard: FetchedResults<Flashcard>
|
|
||||||
|
|
||||||
|
|
||||||
@State var showDescription = false
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if !flashcards.isEmpty && flashcards.first != nil {
|
if !flashcards.isEmpty && flashcards.first != nil {
|
||||||
GeometryReader { geometry in
|
GeometryReader { geometry in
|
||||||
@@ -47,67 +46,39 @@ struct AnkiView: View {
|
|||||||
// Text("How did you do?")
|
// Text("How did you do?")
|
||||||
// .font(.subheadline)
|
// .font(.subheadline)
|
||||||
// .foregroundStyle(.gray)
|
// .foregroundStyle(.gray)
|
||||||
HStack(alignment: .center) {
|
ButtonHStackView(flashcard: flashcards.first!, geometry: geometry, showDescription: $showDescription)
|
||||||
// TODO: Maybe create an algorithm to take into account the shownCount and not just always restart from 1 min?
|
.padding([.bottom, .trailing, .leading])
|
||||||
NextRepetitionButtonView(
|
|
||||||
buttonText: "Wrong",
|
|
||||||
nextMilestone: DataController.SpacedRepetitionMilestoneEnum.OneMinute,
|
|
||||||
flashcardId: flashcards.first!.id!,
|
|
||||||
width: geometry.size.width,
|
|
||||||
color: .red,
|
|
||||||
geometry: geometry,
|
|
||||||
timeText: DataController.SpacedRepetitionMilestoneEnum.OneMinute.rawValue.convertDurationSecondsToString(),
|
|
||||||
showDescription: $showDescription
|
|
||||||
)
|
|
||||||
NextRepetitionButtonView(
|
|
||||||
buttonText: "Correct",
|
|
||||||
nextMilestone: flashcards.first!.getSpacedRepetitionMilestone(),
|
|
||||||
flashcardId: flashcards.first!.id!,
|
|
||||||
width:geometry.size.width,
|
|
||||||
color: .orange,
|
|
||||||
geometry: geometry,
|
|
||||||
timeText: flashcards.first!.getSpacedRepetitionMilestone().rawValue.convertDurationSecondsToString(),
|
|
||||||
showDescription: $showDescription
|
|
||||||
)
|
|
||||||
NextRepetitionButtonView(
|
|
||||||
buttonText: "Easy",
|
|
||||||
nextMilestone: Flashcard.SpacedRepetitionMilestoneEnum.getNext(milestone: flashcards.first!.getSpacedRepetitionMilestone()),
|
|
||||||
flashcardId: flashcards.first!.id!,
|
|
||||||
width: geometry.size.width,
|
|
||||||
color: .green,
|
|
||||||
geometry: geometry,
|
|
||||||
timeText: Flashcard.SpacedRepetitionMilestoneEnum.getNext(milestone: flashcards.first!.getSpacedRepetitionMilestone()).rawValue.convertDurationSecondsToString(),
|
|
||||||
showDescription: $showDescription
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.padding([.bottom, .trailing, .leading])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !soonestFlashcard.isEmpty {
|
if !soonestFlashcard.isEmpty {
|
||||||
Text("Next flashcard in: \(timeRemaining.convertDurationSecondsToCountdown())")
|
Group {
|
||||||
.foregroundStyle(.black)
|
Text("Next flashcard in: \(timeRemaining.convertDurationSecondsToCountdown())")
|
||||||
.padding()
|
.foregroundStyle(.black)
|
||||||
.background(.yellow)
|
.padding()
|
||||||
.clipShape(.buttonBorder)
|
.frame(maxWidth: .infinity - 50)
|
||||||
.padding(.vertical, 50)
|
.background(.yellow)
|
||||||
.padding(.horizontal)
|
.clipShape(.buttonBorder)
|
||||||
.background(.gray.opacity(0.3))
|
.padding(.vertical, 50)
|
||||||
.clipShape(.buttonBorder)
|
.padding(.horizontal)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
if !soonestFlashcard.isEmpty {
|
if !soonestFlashcard.isEmpty {
|
||||||
sortedFlashcards = soonestFlashcard.sorted(by: {
|
sortedFlashcards = soonestFlashcard.sorted(by: {
|
||||||
($0.lastSeenOn!.addSpacedRepetitionMilestone(milestone:$0.getSpacedRepetitionMilestone()).timeIntervalSinceNow) < ($1.lastSeenOn!.addSpacedRepetitionMilestone(milestone: $1.getSpacedRepetitionMilestone()).timeIntervalSinceNow)
|
($0.lastSeenOn!.addSpacedRepetitionMilestone(milestone:$0.getSpacedRepetitionMilestone()).timeIntervalSinceNow) < ($1.lastSeenOn!.addSpacedRepetitionMilestone(milestone: $1.getSpacedRepetitionMilestone()).timeIntervalSinceNow)
|
||||||
})
|
})
|
||||||
timeRemaining = Int(sortedFlashcards.first!.lastSeenOn!.addSpacedRepetitionMilestone(milestone:sortedFlashcards.first!.getSpacedRepetitionMilestone()).timeIntervalSinceNow)
|
timeRemaining = Int(sortedFlashcards.first!.lastSeenOn!.addSpacedRepetitionMilestone(milestone:sortedFlashcards.first!.getSpacedRepetitionMilestone()).timeIntervalSinceNow)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.onReceive(timer) { time in
|
||||||
.onReceive(timer) { time in
|
if timeRemaining > 0 {
|
||||||
if timeRemaining > 0 {
|
timeRemaining -= 1
|
||||||
timeRemaining -= 1
|
}
|
||||||
}
|
}
|
||||||
}
|
.background(.gray.opacity(0.3))
|
||||||
|
.clipShape(.buttonBorder)
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
WordAX/Views/ButtonHStackView.swift
Normal file
50
WordAX/Views/ButtonHStackView.swift
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// ButtonHStackView.swift
|
||||||
|
// WordAX
|
||||||
|
//
|
||||||
|
// Created by Oliver Hnát on 12.04.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ButtonHStackView: View {
|
||||||
|
let flashcard: Flashcard
|
||||||
|
let geometry: GeometryProxy
|
||||||
|
@Binding var showDescription: Bool
|
||||||
|
var body: some View {
|
||||||
|
HStack(alignment: .center) {
|
||||||
|
// TODO: Maybe create an algorithm to take into account the shownCount and not just always restart from 1 min?
|
||||||
|
NextRepetitionButtonView(
|
||||||
|
buttonText: "Wrong",
|
||||||
|
nextMilestone: DataController.SpacedRepetitionMilestoneEnum.OneMinute,
|
||||||
|
flashcardId: flashcard.id!,
|
||||||
|
color: .red,
|
||||||
|
geometry: geometry,
|
||||||
|
timeText: DataController.SpacedRepetitionMilestoneEnum.OneMinute.rawValue.convertDurationSecondsToString(),
|
||||||
|
showDescription: $showDescription
|
||||||
|
)
|
||||||
|
NextRepetitionButtonView(
|
||||||
|
buttonText: "Correct",
|
||||||
|
nextMilestone: flashcard.getSpacedRepetitionMilestone(),
|
||||||
|
flashcardId: flashcard.id!,
|
||||||
|
color: .orange,
|
||||||
|
geometry: geometry,
|
||||||
|
timeText: flashcard.getSpacedRepetitionMilestone().rawValue.convertDurationSecondsToString(),
|
||||||
|
showDescription: $showDescription
|
||||||
|
)
|
||||||
|
NextRepetitionButtonView(
|
||||||
|
buttonText: "Easy",
|
||||||
|
nextMilestone: Flashcard.SpacedRepetitionMilestoneEnum.getNext(milestone: flashcard.getSpacedRepetitionMilestone()),
|
||||||
|
flashcardId: flashcard.id!,
|
||||||
|
color: .green,
|
||||||
|
geometry: geometry,
|
||||||
|
timeText: Flashcard.SpacedRepetitionMilestoneEnum.getNext(milestone: flashcard.getSpacedRepetitionMilestone()).rawValue.convertDurationSecondsToString(),
|
||||||
|
showDescription: $showDescription
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#Preview {
|
||||||
|
// ButtonHStackView()
|
||||||
|
//}
|
||||||
@@ -12,7 +12,6 @@ struct NextRepetitionButtonView: View {
|
|||||||
let buttonText: String
|
let buttonText: String
|
||||||
let nextMilestone: Flashcard.SpacedRepetitionMilestoneEnum?
|
let nextMilestone: Flashcard.SpacedRepetitionMilestoneEnum?
|
||||||
let flashcardId: UUID
|
let flashcardId: UUID
|
||||||
let width: CGFloat
|
|
||||||
let color: Color
|
let color: Color
|
||||||
let geometry: GeometryProxy
|
let geometry: GeometryProxy
|
||||||
let timeText: String
|
let timeText: String
|
||||||
@@ -45,7 +44,7 @@ struct NextRepetitionButtonView: View {
|
|||||||
}
|
}
|
||||||
.padding(.vertical, geometry.size.height / 80)
|
.padding(.vertical, geometry.size.height / 80)
|
||||||
.foregroundColor(.black)
|
.foregroundColor(.black)
|
||||||
.frame(maxWidth: width)
|
.frame(maxWidth: geometry.size.width)
|
||||||
}
|
}
|
||||||
.background(color)
|
.background(color)
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
|
|||||||
Reference in New Issue
Block a user