Add overlay to flash cards, add a debug window for statistics
This commit is contained in:
parent
76a6232d71
commit
7b6daef4c2
@ -23,6 +23,7 @@
|
|||||||
7E943A28273211C300E7DDF4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7E943A27273211C300E7DDF4 /* Preview Assets.xcassets */; };
|
7E943A28273211C300E7DDF4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7E943A27273211C300E7DDF4 /* Preview Assets.xcassets */; };
|
||||||
7E943A2A273211C300E7DDF4 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E943A29273211C300E7DDF4 /* Persistence.swift */; };
|
7E943A2A273211C300E7DDF4 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E943A29273211C300E7DDF4 /* Persistence.swift */; };
|
||||||
7E943A2D273211C300E7DDF4 /* Toki_Trainer.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 7E943A2B273211C300E7DDF4 /* Toki_Trainer.xcdatamodeld */; };
|
7E943A2D273211C300E7DDF4 /* Toki_Trainer.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 7E943A2B273211C300E7DDF4 /* Toki_Trainer.xcdatamodeld */; };
|
||||||
|
7EF546162737B8FB00537AE6 /* FlashCardResultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EF546152737B8FA00537AE6 /* FlashCardResultView.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@ -43,6 +44,7 @@
|
|||||||
7E943A27273211C300E7DDF4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
7E943A27273211C300E7DDF4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||||
7E943A29273211C300E7DDF4 /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
|
7E943A29273211C300E7DDF4 /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
|
||||||
7E943A2C273211C300E7DDF4 /* Toki_Trainer.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Toki_Trainer.xcdatamodel; sourceTree = "<group>"; };
|
7E943A2C273211C300E7DDF4 /* Toki_Trainer.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Toki_Trainer.xcdatamodel; sourceTree = "<group>"; };
|
||||||
|
7EF546152737B8FA00537AE6 /* FlashCardResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardResultView.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -73,6 +75,7 @@
|
|||||||
7E943A22273211C200E7DDF4 /* ContentView.swift */,
|
7E943A22273211C200E7DDF4 /* ContentView.swift */,
|
||||||
7E20D5FE2733AFE700D75B9A /* PartsOfSpeechView.swift */,
|
7E20D5FE2733AFE700D75B9A /* PartsOfSpeechView.swift */,
|
||||||
7E71E6EC2735D70C007CFF72 /* FlashCardView.swift */,
|
7E71E6EC2735D70C007CFF72 /* FlashCardView.swift */,
|
||||||
|
7EF546152737B8FA00537AE6 /* FlashCardResultView.swift */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -214,6 +217,7 @@
|
|||||||
7E20D6012734466800D75B9A /* TokiDictionaryViewModel.swift in Sources */,
|
7E20D6012734466800D75B9A /* TokiDictionaryViewModel.swift in Sources */,
|
||||||
7E2811192733027F0063DC78 /* TokiPartOfSpeech.swift in Sources */,
|
7E2811192733027F0063DC78 /* TokiPartOfSpeech.swift in Sources */,
|
||||||
7E943A23273211C200E7DDF4 /* ContentView.swift in Sources */,
|
7E943A23273211C200E7DDF4 /* ContentView.swift in Sources */,
|
||||||
|
7EF546162737B8FB00537AE6 /* FlashCardResultView.swift in Sources */,
|
||||||
7E2811172733027F0063DC78 /* TokiDictionary.swift in Sources */,
|
7E2811172733027F0063DC78 /* TokiDictionary.swift in Sources */,
|
||||||
7E71E6ED2735D70C007CFF72 /* FlashCardView.swift in Sources */,
|
7E71E6ED2735D70C007CFF72 /* FlashCardView.swift in Sources */,
|
||||||
7E943A21273211C200E7DDF4 /* Toki_TrainerApp.swift in Sources */,
|
7E943A21273211C200E7DDF4 /* Toki_TrainerApp.swift in Sources */,
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
filePath = "Toki Trainer/Views/FlashCardView.swift"
|
filePath = "Toki Trainer/Views/FlashCardView.swift"
|
||||||
startingColumnNumber = "9223372036854775807"
|
startingColumnNumber = "9223372036854775807"
|
||||||
endingColumnNumber = "9223372036854775807"
|
endingColumnNumber = "9223372036854775807"
|
||||||
startingLineNumber = "194"
|
startingLineNumber = "223"
|
||||||
endingLineNumber = "194"
|
endingLineNumber = "223"
|
||||||
landmarkName = "CardFlipModifier"
|
landmarkName = "init(isFaceDown:frontText:backText:)"
|
||||||
landmarkType = "14">
|
landmarkType = "7">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
</Breakpoints>
|
</Breakpoints>
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="false" userDefinedModelVersionIdentifier="">
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19461" systemVersion="21A5552a" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||||
|
<entity name="FlashCardAnswer" representedClassName="FlashCardAnswer" syncable="YES" codeGenerationType="class">
|
||||||
|
<attribute name="correct" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="word" optional="YES" attributeType="String"/>
|
||||||
|
</entity>
|
||||||
<entity name="Item" representedClassName="Item" syncable="YES" codeGenerationType="class">
|
<entity name="Item" representedClassName="Item" syncable="YES" codeGenerationType="class">
|
||||||
<attribute name="timestamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
<attribute name="timestamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
</entity>
|
</entity>
|
||||||
<elements>
|
<elements>
|
||||||
<element name="Item" positionX="-63" positionY="-18" width="128" height="44"/>
|
<element name="Item" positionX="-63" positionY="-18" width="128" height="44"/>
|
||||||
|
<element name="FlashCardAnswer" positionX="-54" positionY="0" width="128" height="59"/>
|
||||||
</elements>
|
</elements>
|
||||||
</model>
|
</model>
|
@ -29,6 +29,11 @@ struct ContentView: View {
|
|||||||
Image(systemName: "character.textbox")
|
Image(systemName: "character.textbox")
|
||||||
Text("Flash Cards")
|
Text("Flash Cards")
|
||||||
}
|
}
|
||||||
|
FlashCardResultView()
|
||||||
|
.tabItem {
|
||||||
|
Image(systemName: "phone.fill")
|
||||||
|
Text("Flash Card Results")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +91,6 @@ struct TranslatorView: View {
|
|||||||
|
|
||||||
struct ContentView_Previews: PreviewProvider {
|
struct ContentView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
ContentView()
|
ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
Toki Trainer/Views/FlashCardResultView.swift
Normal file
30
Toki Trainer/Views/FlashCardResultView.swift
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// FlashCardResultView.swift
|
||||||
|
// Toki Trainer
|
||||||
|
//
|
||||||
|
// Created by Avery Ada Pace on 11/7/21.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct FlashCardResultView: View {
|
||||||
|
@Environment(\.managedObjectContext) private var viewContext
|
||||||
|
|
||||||
|
@FetchRequest var flashCardAnswers: FetchedResults<FlashCardAnswer>
|
||||||
|
|
||||||
|
init() {
|
||||||
|
self._flashCardAnswers = FetchRequest(entity: FlashCardAnswer.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \FlashCardAnswer.word, ascending: true)], predicate: nil, animation: .none)
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
List(flashCardAnswers, id: \.self) { answer in
|
||||||
|
Text(answer.word ?? "Unknown")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FlashCardResultView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
FlashCardResultView()
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import CoreData
|
||||||
|
|
||||||
enum FlashCardResult {
|
enum FlashCardResult {
|
||||||
case Correct
|
case Correct
|
||||||
@ -36,6 +37,7 @@ extension Binding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct FlashCardStack: View {
|
struct FlashCardStack: View {
|
||||||
|
@Environment(\.managedObjectContext) private var viewContext
|
||||||
|
|
||||||
var dictionary: [TokiDictEntry]
|
var dictionary: [TokiDictEntry]
|
||||||
@State private var flashCards: [FlashCard] = []
|
@State private var flashCards: [FlashCard] = []
|
||||||
@ -44,6 +46,7 @@ struct FlashCardStack: View {
|
|||||||
@State private var flashCardsAreInteractive: [Bool] = []
|
@State private var flashCardsAreInteractive: [Bool] = []
|
||||||
@State private var flashCardsVertOffset: [CGFloat] = []
|
@State private var flashCardsVertOffset: [CGFloat] = []
|
||||||
@State private var flashCardsResults: [FlashCardResult] = []
|
@State private var flashCardsResults: [FlashCardResult] = []
|
||||||
|
@State private var fadeOutOverlay = false
|
||||||
|
|
||||||
@State private var currentFlashCard = 0
|
@State private var currentFlashCard = 0
|
||||||
|
|
||||||
@ -58,6 +61,13 @@ struct FlashCardStack: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.overlay(HStack {
|
||||||
|
Image(systemName: "arrow.backward")
|
||||||
|
Text("Incorrect")
|
||||||
|
Spacer()
|
||||||
|
Text("Correct")
|
||||||
|
Image(systemName: "arrow.right")
|
||||||
|
}.opacity(fadeOutOverlay ? 0.0 : 1.0), alignment: .top)
|
||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
.onAppear {
|
.onAppear {
|
||||||
@ -71,7 +81,7 @@ struct FlashCardStack: View {
|
|||||||
for index in dictionary.indices {
|
for index in dictionary.indices {
|
||||||
flashCardsAreInteractive.append(false)
|
flashCardsAreInteractive.append(false)
|
||||||
flashCardsResults.append(FlashCardResult.Unanswered)
|
flashCardsResults.append(FlashCardResult.Unanswered)
|
||||||
flashCards.append(FlashCard(isInteractive: $flashCardsAreInteractive[index], result: $flashCardsResults[index].onChange(nextFlashCard), dictionaryEntry: dictionary[index]))
|
flashCards.append(FlashCard(isInteractive: $flashCardsAreInteractive[index], result: $flashCardsResults[index].onChange(cardAnswerReceived), dictionaryEntry: dictionary[index]))
|
||||||
flashCardsVertOffset.append(470)
|
flashCardsVertOffset.append(470)
|
||||||
}
|
}
|
||||||
if flashCards.count - currentFlashCard >= 3 {
|
if flashCards.count - currentFlashCard >= 3 {
|
||||||
@ -89,6 +99,21 @@ struct FlashCardStack: View {
|
|||||||
flashCardsAreInteractive[currentFlashCard] = true
|
flashCardsAreInteractive[currentFlashCard] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cardAnswerReceived() {
|
||||||
|
let flashCardAnswer = FlashCardAnswer(context: viewContext)
|
||||||
|
flashCardAnswer.word = dictionary[currentFlashCard].word
|
||||||
|
if flashCardsResults[currentFlashCard] == FlashCardResult.Correct {
|
||||||
|
flashCardAnswer.correct = true
|
||||||
|
} else if flashCardsResults[currentFlashCard] == FlashCardResult.Incorrect {
|
||||||
|
flashCardAnswer.correct = false
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try? viewContext.save()
|
||||||
|
|
||||||
|
nextFlashCard()
|
||||||
|
}
|
||||||
|
|
||||||
func nextFlashCard() {
|
func nextFlashCard() {
|
||||||
currentFlashCard += 1
|
currentFlashCard += 1
|
||||||
if(currentFlashCard > 0 ) {
|
if(currentFlashCard > 0 ) {
|
||||||
@ -97,6 +122,8 @@ struct FlashCardStack: View {
|
|||||||
flashCardsVertOffset[currentFlashCard] = 100
|
flashCardsVertOffset[currentFlashCard] = 100
|
||||||
flashCardsAreInteractive[currentFlashCard] = true
|
flashCardsAreInteractive[currentFlashCard] = true
|
||||||
|
|
||||||
|
self.fadeOutOverlay = true
|
||||||
|
|
||||||
if flashCards.count - currentFlashCard >= 3 {
|
if flashCards.count - currentFlashCard >= 3 {
|
||||||
flashCardsVertOffset[currentFlashCard + 1] = 410
|
flashCardsVertOffset[currentFlashCard + 1] = 410
|
||||||
flashCardsVertOffset[currentFlashCard + 2] = 440
|
flashCardsVertOffset[currentFlashCard + 2] = 440
|
||||||
@ -146,6 +173,8 @@ struct FlashCard: View {
|
|||||||
} else if self.dragAmount > 20 {
|
} else if self.dragAmount > 20 {
|
||||||
self.dragAmount = 500
|
self.dragAmount = 500
|
||||||
self.result = FlashCardResult.Correct
|
self.result = FlashCardResult.Correct
|
||||||
|
} else {
|
||||||
|
self.dragAmount = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,6 +257,6 @@ struct CardFlipModifier: AnimatableModifier {
|
|||||||
|
|
||||||
struct FlashCardView_Previews: PreviewProvider {
|
struct FlashCardView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
FlashCardView()
|
FlashCardView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,6 @@ struct PartsOfSpeechView: View {
|
|||||||
|
|
||||||
var partsOfSpeech: [TokiPartOfSpeech]
|
var partsOfSpeech: [TokiPartOfSpeech]
|
||||||
|
|
||||||
// init(selectedPartOfSpeech: String) {
|
|
||||||
// _selectedPartOfSpeech = State(initialValue: selectedPartOfSpeech)
|
|
||||||
// }
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
Text("Parts of Speech")
|
Text("Parts of Speech")
|
||||||
|
Loading…
Reference in New Issue
Block a user