When countdown finishes, fetch requests reload
This commit is contained in:
@@ -56,6 +56,7 @@ Why settle for pricey apps when you can have WordAX? We're here to prove that ef
|
||||
|
||||
## Roadmap
|
||||
- [ ] Anki card "store" - download any anki flashcards you want from the online store that already exists somewhere
|
||||
- [ ] Export your anki to the store?
|
||||
- [ ] Import anki cards in the .anki format
|
||||
- [x] Create flashcards
|
||||
- [ ] Add tags to cards
|
||||
@@ -65,8 +66,7 @@ Why settle for pricey apps when you can have WordAX? We're here to prove that ef
|
||||
- [x] For start store them on the phone - stored using Core Data
|
||||
- [ ] Maybe later add a storage in cloud, so that you can sync with other devices if the app is multi-platform?
|
||||
- [ ] Add some animations?
|
||||
- [ ] Implement logic
|
||||
- [ ] Export your anki to the store?
|
||||
- [x] Implement logic
|
||||
- [ ] Make an apple watch version of the app
|
||||
|
||||
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
||||
|
||||
@@ -30,7 +30,7 @@ class DataController: ObservableObject {
|
||||
"This is a medium length description that should be long enough to cover all cases"
|
||||
].randomElement()!
|
||||
flashcard.nextSpacedRepetitionMilestone = SpacedRepetitionMilestoneEnum.allCases.randomElement()!.rawValue
|
||||
flashcard.lastSeenOn = [nil, Date(), 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.dateAdded = [Date(), Date().addingTimeInterval(-86400), Date().addingTimeInterval(-172800)].randomElement()!
|
||||
}
|
||||
@@ -120,6 +120,9 @@ extension Int {
|
||||
// else {
|
||||
// result = "\(self)"
|
||||
// }
|
||||
if days == 0 && hours == 0 && minutes == 0 {
|
||||
return "\(seconds)s"
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ public class Flashcard: NSManagedObject {
|
||||
}
|
||||
let milestoneIndex = sorted.firstIndex(where: {$0.rawValue == milestone!.rawValue})!
|
||||
if milestoneIndex < sorted.count {
|
||||
// 1 minute is only if answer was wrong, so 10 minutes is the first valid milestone
|
||||
return sorted[milestoneIndex + 1] == .OneMinute ? .TenMinutes : sorted[milestoneIndex + 1]
|
||||
}
|
||||
return .OneYear
|
||||
@@ -47,7 +48,6 @@ public class Flashcard: NSManagedObject {
|
||||
}
|
||||
|
||||
func getSpacedRepetitionMilestone() -> SpacedRepetitionMilestoneEnum {
|
||||
let milestone = SpacedRepetitionMilestoneEnum.getMilestoneFromInt(value: self.nextSpacedRepetitionMilestone)
|
||||
return milestone == .OneMinute ? .TenMinutes : milestone
|
||||
SpacedRepetitionMilestoneEnum.getMilestoneFromInt(value: self.nextSpacedRepetitionMilestone)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,30 +9,12 @@ import SwiftUI
|
||||
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)
|
||||
// ], predicate: NSCompoundPredicate(type: .or, subpredicates: [
|
||||
// NSCompoundPredicate(type: .and, subpredicates: [
|
||||
// NSPredicate(format: "%K != nil", "lastSeenOn"),
|
||||
// NSPredicate(format: "lastSeenOn + nextSpacedRepetitionMilestone < %@", Date() as CVarArg)
|
||||
// ]),
|
||||
// NSPredicate(format: "lastSeenOn == nil")
|
||||
// ])) 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
|
||||
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
|
||||
@State var flashcards: [Flashcard] = []
|
||||
@State var sortedFlashcards: [Flashcard] = []
|
||||
@State var soonestFlashcard: [Flashcard] = []
|
||||
@State var soonestFlashcards: [Flashcard] = []
|
||||
@State var showDescription = false
|
||||
|
||||
var body: some View {
|
||||
@@ -47,13 +29,13 @@ struct AnkiView: View {
|
||||
// Text("How did you do?")
|
||||
// .font(.subheadline)
|
||||
// .foregroundStyle(.gray)
|
||||
ButtonHStackView(flashcard: flashcards.first!, geometry: geometry, showDescription: $showDescription)
|
||||
ButtonHStackView(flashcard: flashcards.first!, geometry: geometry, reload: refreshFlashcards, showDescription: $showDescription)
|
||||
.padding([.bottom, .trailing, .leading])
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if !soonestFlashcard.isEmpty {
|
||||
if !soonestFlashcards.isEmpty {
|
||||
Group {
|
||||
Text("Next flashcard in: \(timeRemaining.convertDurationSecondsToCountdown())")
|
||||
.foregroundStyle(.black)
|
||||
@@ -63,15 +45,6 @@ struct AnkiView: View {
|
||||
.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)
|
||||
}
|
||||
refreshFlashcards()
|
||||
}
|
||||
.onReceive(timer) { time in
|
||||
if timeRemaining > 1 {
|
||||
timeRemaining -= 1
|
||||
@@ -103,32 +76,50 @@ struct AnkiView: View {
|
||||
}
|
||||
|
||||
func refreshFlashcards() {
|
||||
let request = NSFetchRequest<Flashcard>(entityName: "Flashcard")
|
||||
request.predicate = NSCompoundPredicate(type: .or, subpredicates: [
|
||||
let requestAllFlashcards = NSFetchRequest<Flashcard>(entityName: "Flashcard")
|
||||
requestAllFlashcards.predicate = NSCompoundPredicate(type: .or, subpredicates: [
|
||||
NSCompoundPredicate(type: .and, subpredicates: [
|
||||
NSPredicate(format: "%K != nil", "lastSeenOn"),
|
||||
NSPredicate(format: "lastSeenOn + nextSpacedRepetitionMilestone < %@", Date() as CVarArg)
|
||||
]),
|
||||
NSPredicate(format: "lastSeenOn == nil")
|
||||
])
|
||||
request.sortDescriptors = [
|
||||
requestAllFlashcards.sortDescriptors = [
|
||||
NSSortDescriptor(key: "nextSpacedRepetitionMilestone", ascending: false),
|
||||
NSSortDescriptor(key: "lastSeenOn", ascending: true)
|
||||
]
|
||||
do {
|
||||
flashcards = try moc.fetch(request)
|
||||
flashcards = try moc.fetch(requestAllFlashcards)
|
||||
} catch {
|
||||
print("Something went wroooong")
|
||||
print("Something went wrong while fetching available flashcards")
|
||||
}
|
||||
|
||||
|
||||
|
||||
let req = NSFetchRequest<Flashcard>(entityName: "Flashcard")
|
||||
req.predicate = NSPredicate(format: "%K != nil", "lastSeenOn")
|
||||
let requestSoonestFlashcards = NSFetchRequest<Flashcard>(entityName: "Flashcard")
|
||||
requestSoonestFlashcards.predicate = NSPredicate(format: "%K != nil", "lastSeenOn")
|
||||
do {
|
||||
soonestFlashcard = try moc.fetch(request)
|
||||
soonestFlashcards = try moc.fetch(requestSoonestFlashcards)
|
||||
// print("This is soonest flashcards")
|
||||
// for flashcard in soonestFlashcards {
|
||||
// print("\(flashcard.name ?? "") is \(Int(flashcard.lastSeenOn!.addSpacedRepetitionMilestone(milestone:flashcard.getSpacedRepetitionMilestone()).timeIntervalSinceNow.rounded()))")
|
||||
// }
|
||||
} catch {
|
||||
print("Something went bum")
|
||||
print("Something went wrong while fetching latest flashcard")
|
||||
}
|
||||
if !soonestFlashcards.isEmpty {
|
||||
soonestFlashcards = soonestFlashcards.sorted {
|
||||
if $0.lastSeenOn != nil && $1.lastSeenOn != nil {
|
||||
return $0.lastSeenOn!.addSpacedRepetitionMilestone(milestone:$0.getSpacedRepetitionMilestone()).timeIntervalSinceNow < $1.lastSeenOn!.addSpacedRepetitionMilestone(milestone: $1.getSpacedRepetitionMilestone()).timeIntervalSinceNow
|
||||
} else {
|
||||
return $0.lastSeenOn != nil
|
||||
}
|
||||
}
|
||||
if soonestFlashcards.first!.lastSeenOn != nil {
|
||||
timeRemaining = Int(soonestFlashcards.first!.lastSeenOn!.addSpacedRepetitionMilestone(milestone:soonestFlashcards.first!.getSpacedRepetitionMilestone()).timeIntervalSinceNow.rounded())
|
||||
} else {
|
||||
print("Something went wrong while getting latest flashcard")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import SwiftUI
|
||||
struct ButtonHStackView: View {
|
||||
let flashcard: Flashcard
|
||||
let geometry: GeometryProxy
|
||||
let reload: () -> Void
|
||||
@Binding var showDescription: Bool
|
||||
var body: some View {
|
||||
HStack(alignment: .center) {
|
||||
@@ -21,6 +22,7 @@ struct ButtonHStackView: View {
|
||||
color: .red,
|
||||
geometry: geometry,
|
||||
timeText: DataController.SpacedRepetitionMilestoneEnum.OneMinute.rawValue.convertDurationSecondsToString(),
|
||||
reload: reload,
|
||||
showDescription: $showDescription
|
||||
)
|
||||
NextRepetitionButtonView(
|
||||
@@ -30,6 +32,7 @@ struct ButtonHStackView: View {
|
||||
color: .orange,
|
||||
geometry: geometry,
|
||||
timeText: flashcard.getSpacedRepetitionMilestone().rawValue.convertDurationSecondsToString(),
|
||||
reload: reload,
|
||||
showDescription: $showDescription
|
||||
)
|
||||
NextRepetitionButtonView(
|
||||
@@ -39,6 +42,7 @@ struct ButtonHStackView: View {
|
||||
color: .green,
|
||||
geometry: geometry,
|
||||
timeText: Flashcard.SpacedRepetitionMilestoneEnum.getNext(milestone: flashcard.getSpacedRepetitionMilestone()).rawValue.convertDurationSecondsToString(),
|
||||
reload: reload,
|
||||
showDescription: $showDescription
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ struct NextRepetitionButtonView: View {
|
||||
let color: Color
|
||||
let geometry: GeometryProxy
|
||||
let timeText: String
|
||||
let reload: () -> Void
|
||||
@Environment(\.managedObjectContext) var moc
|
||||
// { colorScheme == .light ? .cyan : .darkCyan }
|
||||
@Binding var showDescription: Bool
|
||||
@@ -34,6 +35,7 @@ struct NextRepetitionButtonView: View {
|
||||
print("Something went wrong while saving the flashcard info: \(error.localizedDescription)")
|
||||
}
|
||||
self.showDescription = false
|
||||
reload()
|
||||
}) {
|
||||
VStack {
|
||||
Text(buttonText)
|
||||
|
||||
Reference in New Issue
Block a user