Flash Cards now used stored lesson information
This commit is contained in:
parent
287c9fb8ac
commit
1c928fa876
@ -19,6 +19,7 @@
|
||||
7E716B4027398ABD009E2CF6 /* toki-lessons.json in Resources */ = {isa = PBXBuildFile; fileRef = 7E716B3F27398ABD009E2CF6 /* toki-lessons.json */; };
|
||||
7E716B4227398CDF009E2CF6 /* FlashCardLessonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E716B4127398CDF009E2CF6 /* FlashCardLessonsView.swift */; };
|
||||
7E716B4427398D3D009E2CF6 /* FlashCardLessonsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E716B4327398D3D009E2CF6 /* FlashCardLessonsViewModel.swift */; };
|
||||
7E716B462739B968009E2CF6 /* FlashCardLessonResultsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E716B452739B968009E2CF6 /* FlashCardLessonResultsView.swift */; };
|
||||
7E71E6ED2735D70C007CFF72 /* FlashCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E71E6EC2735D70C007CFF72 /* FlashCardView.swift */; };
|
||||
7E71E6F12736DAE4007CFF72 /* FlashCardsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E71E6F02736DAE4007CFF72 /* FlashCardsViewModel.swift */; };
|
||||
7E943A21273211C200E7DDF4 /* Toki_TrainerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E943A20273211C200E7DDF4 /* Toki_TrainerApp.swift */; };
|
||||
@ -43,6 +44,7 @@
|
||||
7E716B3F27398ABD009E2CF6 /* toki-lessons.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = "toki-lessons.json"; path = "../../../../../Desktop/toki-pona-dict-json/output/toki-lessons.json"; sourceTree = "<group>"; };
|
||||
7E716B4127398CDF009E2CF6 /* FlashCardLessonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardLessonsView.swift; sourceTree = "<group>"; };
|
||||
7E716B4327398D3D009E2CF6 /* FlashCardLessonsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardLessonsViewModel.swift; sourceTree = "<group>"; };
|
||||
7E716B452739B968009E2CF6 /* FlashCardLessonResultsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardLessonResultsView.swift; sourceTree = "<group>"; };
|
||||
7E71E6EC2735D70C007CFF72 /* FlashCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardView.swift; sourceTree = "<group>"; };
|
||||
7E71E6F02736DAE4007CFF72 /* FlashCardsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardsViewModel.swift; sourceTree = "<group>"; };
|
||||
7E943A1D273211C200E7DDF4 /* Toki Trainer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Toki Trainer.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -86,6 +88,7 @@
|
||||
7E71E6EC2735D70C007CFF72 /* FlashCardView.swift */,
|
||||
7EF546152737B8FA00537AE6 /* FlashCardResultsView.swift */,
|
||||
7E716B4127398CDF009E2CF6 /* FlashCardLessonsView.swift */,
|
||||
7E716B452739B968009E2CF6 /* FlashCardLessonResultsView.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
@ -236,6 +239,7 @@
|
||||
7E2811172733027F0063DC78 /* TokiDictionary.swift in Sources */,
|
||||
7E71E6ED2735D70C007CFF72 /* FlashCardView.swift in Sources */,
|
||||
7E943A21273211C200E7DDF4 /* Toki_TrainerApp.swift in Sources */,
|
||||
7E716B462739B968009E2CF6 /* FlashCardLessonResultsView.swift in Sources */,
|
||||
7E2811182733027F0063DC78 /* TokiJSONLoader.swift in Sources */,
|
||||
7E716B3E273986E5009E2CF6 /* TokiLesson.swift in Sources */,
|
||||
7E28112227330DD30063DC78 /* Constants.swift in Sources */,
|
||||
|
@ -39,4 +39,11 @@ struct K {
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
static var getLessonAnswersFetchRequest: NSFetchRequest<LessonAnswer> {
|
||||
let request: NSFetchRequest<LessonAnswer> = LessonAnswer.fetchRequest()
|
||||
request.sortDescriptors = []
|
||||
|
||||
return request
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,14 @@
|
||||
<entity name="Item" representedClassName="Item" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="timestamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
</entity>
|
||||
<entity name="LessonAnswer" representedClassName="LessonAnswer" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="correctCount" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="lesson" optional="YES" attributeType="String"/>
|
||||
<attribute name="triesCount" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="FlashCardAnswer" positionX="-54" positionY="0" width="128" height="74"/>
|
||||
<element name="Item" positionX="-63" positionY="-18" width="128" height="44"/>
|
||||
<element name="LessonAnswer" positionX="-54" positionY="18" width="128" height="74"/>
|
||||
</elements>
|
||||
</model>
|
20
Toki Trainer/Views/FlashCardLessonResultsView.swift
Normal file
20
Toki Trainer/Views/FlashCardLessonResultsView.swift
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// FlashCardLessonsResultsView.swift
|
||||
// Toki Trainer
|
||||
//
|
||||
// Created by Avery Ada Pace on 11/8/21.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct FlashCardLessonsResultsView: View {
|
||||
var body: some View {
|
||||
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
||||
}
|
||||
}
|
||||
|
||||
struct FlashCardLessonsResultsView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
FlashCardLessonsResultsView()
|
||||
}
|
||||
}
|
@ -8,14 +8,76 @@
|
||||
import SwiftUI
|
||||
|
||||
struct FlashCardLessonsView: View {
|
||||
@Environment(\.managedObjectContext) private var viewContext
|
||||
|
||||
@FetchRequest(fetchRequest: K.getFlashCardAnswersFetchRequest) var answers: FetchedResults<FlashCardAnswer>
|
||||
@FetchRequest(fetchRequest: K.getLessonAnswersFetchRequest) var lessonAnswers: FetchedResults<LessonAnswer>
|
||||
|
||||
@ObservedObject var flashCardLessonsVM = FlashCardLessonsViewModel()
|
||||
|
||||
@State private var lessonStatistics: [String: Double] = [:]
|
||||
@State private var statisticsCalculated = false
|
||||
|
||||
func calculateStatistics(_ lesson: TokiLesson) {
|
||||
for lessonAnswer in lessonAnswers {
|
||||
if lessonAnswer.lesson == lesson.lesson {
|
||||
self.lessonStatistics[lesson.lesson] = (Double(lessonAnswer.correctCount) / Double(lessonAnswer.triesCount) * 100)
|
||||
}
|
||||
}
|
||||
self.statisticsCalculated = true
|
||||
}
|
||||
// func calculateStatistics(_ lesson: TokiLesson) {
|
||||
// for answer in answers {
|
||||
// wordStatistics[answer.word!] = (Double(answer.correctCount) / Double(answer.triesCount)) * 100
|
||||
// }
|
||||
//
|
||||
//
|
||||
// for word in lesson.words {
|
||||
// buildLessonStatistics[lesson.lesson] = []
|
||||
// buildLessonStatistics[lesson.lesson]?.append(wordStatistics[word.word]!)
|
||||
// }
|
||||
//
|
||||
// for (key, value) in buildLessonStatistics {
|
||||
// let sumArray = value.reduce(0, +)
|
||||
// let avgArrayValue = sumArray / Double(value.count)
|
||||
// lessonStatistics[key] = avgArrayValue
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// for word in lesson.words {
|
||||
//// for answer in answers {
|
||||
//// if answer.word == word.word {
|
||||
//// lessonStatistics[lesson.lesson] = (Double(answer.correctCount) / Double(answer.triesCount)) * 100
|
||||
//// }
|
||||
//// }
|
||||
//// }
|
||||
// self.statisticsCalculated = true
|
||||
// }
|
||||
|
||||
func calculateBackgroundColor(_ percent: Double) -> Color {
|
||||
if percent >= 80 {
|
||||
return Color.green
|
||||
} else if percent >= 40 {
|
||||
return Color.yellow
|
||||
} else {
|
||||
return Color.red
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
List(flashCardLessonsVM.lessons, id: \.lesson) { lesson in
|
||||
NavigationLink(destination: FlashCardView(lesson.words)) {
|
||||
NavigationLink(destination: FlashCardView(lesson: lesson.lesson, passedDictionary: lesson.words)) {
|
||||
Text(lesson.lesson)
|
||||
.bold()
|
||||
.onAppear {
|
||||
calculateStatistics(lesson)
|
||||
}
|
||||
Spacer()
|
||||
if statisticsCalculated && lessonStatistics[lesson.lesson] != 0.0 && lessonStatistics[lesson.lesson] != nil {
|
||||
Text("\(String(format: "%.0f", lessonStatistics[lesson.lesson]!)) %")
|
||||
.multilineTextAlignment(.leading)
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationBarTitle("Lessons")
|
||||
|
@ -16,7 +16,6 @@ struct FlashCardResultsView: View {
|
||||
|
||||
@State private var wordStatistics: [String: Double] = [:]
|
||||
@State private var sortedWordStatistics: [(String, Double)] = []
|
||||
@State private var statistics = 0.0
|
||||
|
||||
func calculateStatistics() {
|
||||
for answer in answers {
|
||||
@ -38,7 +37,6 @@ struct FlashCardResultsView: View {
|
||||
} else {
|
||||
return Color.red
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -57,13 +55,6 @@ struct FlashCardResultsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
extension Double {
|
||||
func formatAsPercent(places: Int) -> String {
|
||||
let formattedValue = String(format: "%.2f", self)
|
||||
return formattedValue
|
||||
}
|
||||
}
|
||||
|
||||
struct FlashCardResultView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
FlashCardResultsView()
|
||||
|
@ -18,30 +18,28 @@ struct FlashCardView: View {
|
||||
|
||||
@ObservedObject var flashCardsViewModel = FlashCardsViewModel()
|
||||
|
||||
@State var dictionary: [TokiDictEntry]?
|
||||
@State var currentLesson: String
|
||||
@State var dictionary: [TokiDictEntry]
|
||||
|
||||
init(_ passedDictionary: [TokiDictEntry]?) {
|
||||
if passedDictionary != nil {
|
||||
if let safePassedDictionary = passedDictionary {
|
||||
self.dictionary = safePassedDictionary
|
||||
}
|
||||
}
|
||||
init(lesson: String, passedDictionary: [TokiDictEntry]) {
|
||||
self.dictionary = passedDictionary
|
||||
currentLesson = lesson
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
FlashCardStack(dictionary: getDictionary())
|
||||
FlashCardStack(currentLesson: currentLesson, dictionary: dictionary)
|
||||
}
|
||||
}
|
||||
|
||||
func getDictionary() -> [TokiDictEntry] {
|
||||
if dictionary != nil {
|
||||
dictionary?.shuffle()
|
||||
return dictionary ?? []
|
||||
} else {
|
||||
return flashCardsViewModel.randomDictionary
|
||||
}
|
||||
}
|
||||
// func getDictionary() -> [TokiDictEntry] {
|
||||
// if dictionary != nil {
|
||||
// dictionary?.shuffle()
|
||||
// return dictionary ?? []
|
||||
// } else {
|
||||
// return flashCardsViewModel.randomDictionary
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
extension Binding {
|
||||
@ -59,7 +57,9 @@ struct FlashCardStack: View {
|
||||
@Environment(\.managedObjectContext) private var viewContext
|
||||
|
||||
@FetchRequest(fetchRequest: K.getFlashCardAnswersFetchRequest) var flashCardAnswers: FetchedResults<FlashCardAnswer>
|
||||
@FetchRequest(fetchRequest: K.getLessonAnswersFetchRequest) var lessonAnswers: FetchedResults<LessonAnswer>
|
||||
|
||||
var currentLesson: String
|
||||
var dictionary: [TokiDictEntry]
|
||||
@State private var flashCards: [FlashCard] = []
|
||||
@State private var topFlashCard: FlashCard? = nil
|
||||
@ -135,6 +135,28 @@ struct FlashCardStack: View {
|
||||
}
|
||||
}
|
||||
|
||||
var lessonInDatabase = false
|
||||
for lessonAnswer in lessonAnswers {
|
||||
if lessonAnswer.lesson == currentLesson {
|
||||
lessonInDatabase = true
|
||||
lessonAnswer.setValue((lessonAnswer.triesCount + 1), forKey: "triesCount")
|
||||
if correct {
|
||||
lessonAnswer.setValue((lessonAnswer.correctCount + 1), forKey: "correctCount")
|
||||
}
|
||||
print("lesson found in database")
|
||||
}
|
||||
}
|
||||
|
||||
if lessonInDatabase == false {
|
||||
let lessonAnswer = LessonAnswer(context: viewContext)
|
||||
lessonAnswer.lesson = currentLesson
|
||||
lessonAnswer.triesCount = 1
|
||||
if correct {
|
||||
lessonAnswer.correctCount = 1
|
||||
}
|
||||
print("lesson not found in database")
|
||||
}
|
||||
|
||||
if cardInDatabase == false {
|
||||
let answer = FlashCardAnswer(context: viewContext)
|
||||
answer.word = dictionary[currentFlashCard].word
|
||||
@ -145,15 +167,6 @@ struct FlashCardStack: View {
|
||||
print("answer not found in database")
|
||||
}
|
||||
|
||||
// for answer in flashCardAnswers {
|
||||
// if answer.word == dictionary[currentFlashCard].word {
|
||||
// flashCardAnswer.word = answer.word
|
||||
// flashCardAnswer.triesCount = answer.triesCount + 1
|
||||
// if correct {
|
||||
// flashCardAnswer.correctCount = answer.correctCount + 1
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
try? viewContext.save()
|
||||
}
|
||||
|
||||
@ -169,23 +182,27 @@ struct FlashCardStack: View {
|
||||
}
|
||||
|
||||
func nextFlashCard() {
|
||||
currentFlashCard += 1
|
||||
if(currentFlashCard > 0 ) {
|
||||
flashCardsVertOffset[currentFlashCard - 1] = -1000
|
||||
flashCardsVertOffset[currentFlashCard] = -1000
|
||||
if currentFlashCard == (flashCards.count - 1) {
|
||||
return
|
||||
}
|
||||
currentFlashCard += 1
|
||||
flashCardsVertOffset[currentFlashCard] = 50
|
||||
flashCardsAreInteractive[currentFlashCard] = true
|
||||
|
||||
|
||||
self.fadeOutOverlay = true
|
||||
|
||||
if flashCards.count - currentFlashCard >= 3 {
|
||||
if ((flashCards.count - 1) - currentFlashCard) > 3 {
|
||||
print("flashCards: \(flashCards.count)")
|
||||
print("currentFlashCard: \(currentFlashCard)")
|
||||
flashCardsVertOffset[currentFlashCard + 1] = 310
|
||||
flashCardsVertOffset[currentFlashCard + 2] = 340
|
||||
flashCardsVertOffset[currentFlashCard + 3] = 370
|
||||
} else if flashCards.count - currentFlashCard == 2 {
|
||||
} else if (flashCards.count - 1) - currentFlashCard > 2 {
|
||||
flashCardsVertOffset[currentFlashCard + 1] = 310
|
||||
flashCardsVertOffset[currentFlashCard + 2] = 340
|
||||
} else if flashCards.count - currentFlashCard == 1 {
|
||||
} else if (flashCards.count - 1) - currentFlashCard > 1 {
|
||||
flashCardsVertOffset[currentFlashCard + 1] = 310
|
||||
}
|
||||
}
|
||||
@ -317,7 +334,9 @@ struct CardFlipModifier: AnimatableModifier {
|
||||
}
|
||||
|
||||
struct FlashCardView_Previews: PreviewProvider {
|
||||
static var viewModel = TokiDictionaryViewModel()
|
||||
|
||||
static var previews: some View {
|
||||
FlashCardView(nil).environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
|
||||
FlashCardView(lesson: "Preview", passedDictionary: viewModel.dictionary).environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user