diff --git a/WordAX/Model/DataController.swift b/WordAX/Model/DataController.swift index ffd8b6e..512672f 100644 --- a/WordAX/Model/DataController.swift +++ b/WordAX/Model/DataController.swift @@ -29,11 +29,10 @@ class DataController: ObservableObject { "This is a very short description", "This is a medium length description that should be long enough to cover all cases" ].randomElement()! - flashcard.nextSpacedRepetitionMilestone = SpacedRepetitionMilestoneEnum.OneYear.rawValue - flashcard.lastSeenOn = [Date().addingTimeInterval([86400, 24000, 100000].randomElement()!)].randomElement()! + flashcard.nextSpacedRepetitionMilestone = SpacedRepetitionMilestoneEnum.allCases.randomElement()!.rawValue + flashcard.lastSeenOn = [nil, Date(), Date().addingTimeInterval([-86400, -24000, -100000].randomElement()!)].randomElement()! flashcard.shownCount = [0, 1, 2, 3, 4, 5].randomElement()! flashcard.dateAdded = [Date(), Date().addingTimeInterval(-86400), Date().addingTimeInterval(-172800)].randomElement()! -// flashcard.calculatedNextRepetition = flashcard.lastSeenOn ?? Date() + TimeInterval(flashcard.nextSpacedRepetitionMilestone) } do { try viewContext.save() diff --git a/WordAX/Views/AnkiView.swift b/WordAX/Views/AnkiView.swift index dfe9f56..9bf1ff5 100644 --- a/WordAX/Views/AnkiView.swift +++ b/WordAX/Views/AnkiView.swift @@ -11,6 +11,8 @@ import CoreData struct AnkiView: View { @EnvironmentObject var model: WordAXModelView @Environment(\.managedObjectContext) var moc + + // get flashcards to display @FetchRequest(sortDescriptors: [ NSSortDescriptor(key: "nextSpacedRepetitionMilestone", ascending: false), NSSortDescriptor(key: "lastSeenOn", ascending: true) @@ -22,19 +24,16 @@ struct AnkiView: View { NSPredicate(format: "lastSeenOn == nil") ])) var flashcards: FetchedResults + // get the most recent flashcard + @FetchRequest(sortDescriptors: [], + predicate: NSPredicate(format: "%K != nil", "lastSeenOn")) var soonestFlashcard: FetchedResults + @State private var timeRemaining = 10 let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() @State var sortedFlashcards: [Flashcard] = [] + @State var showDescription = false @Environment(\.colorScheme) var colorScheme - - - // get the most recent flashcard - @FetchRequest(sortDescriptors: [], - predicate: NSPredicate(format: "%K != nil", "lastSeenOn")) var soonestFlashcard: FetchedResults - - - @State var showDescription = false var body: some View { if !flashcards.isEmpty && flashcards.first != nil { @@ -47,67 +46,39 @@ struct AnkiView: View { // Text("How did you do?") // .font(.subheadline) // .foregroundStyle(.gray) - 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: 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]) + ButtonHStackView(flashcard: flashcards.first!, geometry: geometry, showDescription: $showDescription) + .padding([.bottom, .trailing, .leading]) } } } } else { if !soonestFlashcard.isEmpty { - Text("Next flashcard in: \(timeRemaining.convertDurationSecondsToCountdown())") - .foregroundStyle(.black) - .padding() - .background(.yellow) - .clipShape(.buttonBorder) - .padding(.vertical, 50) - .padding(.horizontal) - .background(.gray.opacity(0.3)) - .clipShape(.buttonBorder) - .onAppear { - if !soonestFlashcard.isEmpty { - sortedFlashcards = soonestFlashcard.sorted(by: { - ($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) + Group { + Text("Next flashcard in: \(timeRemaining.convertDurationSecondsToCountdown())") + .foregroundStyle(.black) + .padding() + .frame(maxWidth: .infinity - 50) + .background(.yellow) + .clipShape(.buttonBorder) + .padding(.vertical, 50) + .padding(.horizontal) + .onAppear { + if !soonestFlashcard.isEmpty { + sortedFlashcards = soonestFlashcard.sorted(by: { + ($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) + } } - } - .onReceive(timer) { time in - if timeRemaining > 0 { - timeRemaining -= 1 + .onReceive(timer) { time in + if timeRemaining > 0 { + timeRemaining -= 1 + } } - } + .background(.gray.opacity(0.3)) + .clipShape(.buttonBorder) + .padding(.horizontal) + } } } } diff --git a/WordAX/Views/ButtonHStackView.swift b/WordAX/Views/ButtonHStackView.swift new file mode 100644 index 0000000..68c14bd --- /dev/null +++ b/WordAX/Views/ButtonHStackView.swift @@ -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() +//} diff --git a/WordAX/Views/NextRepetitionButtonView.swift b/WordAX/Views/NextRepetitionButtonView.swift index 254977b..4d23249 100644 --- a/WordAX/Views/NextRepetitionButtonView.swift +++ b/WordAX/Views/NextRepetitionButtonView.swift @@ -12,7 +12,6 @@ struct NextRepetitionButtonView: View { let buttonText: String let nextMilestone: Flashcard.SpacedRepetitionMilestoneEnum? let flashcardId: UUID - let width: CGFloat let color: Color let geometry: GeometryProxy let timeText: String @@ -45,7 +44,7 @@ struct NextRepetitionButtonView: View { } .padding(.vertical, geometry.size.height / 80) .foregroundColor(.black) - .frame(maxWidth: width) + .frame(maxWidth: geometry.size.width) } .background(color) .buttonStyle(.plain)