Rewrote the app to use Core Data, some features not working fully

This commit is contained in:
2024-04-08 20:18:49 +02:00
parent 1512053e34
commit 24fb236f6b
14 changed files with 218 additions and 40 deletions

View File

@@ -16,6 +16,10 @@
6C81850A2B8BA5740033CF46 /* FlashCardListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185092B8BA5740033CF46 /* FlashCardListView.swift */; }; 6C81850A2B8BA5740033CF46 /* FlashCardListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185092B8BA5740033CF46 /* FlashCardListView.swift */; };
6C81850C2B8BA6BC0033CF46 /* FlashCardListRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C81850B2B8BA6BC0033CF46 /* FlashCardListRowView.swift */; }; 6C81850C2B8BA6BC0033CF46 /* FlashCardListRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C81850B2B8BA6BC0033CF46 /* FlashCardListRowView.swift */; };
6CEF7F522BC2DBF800E205F6 /* AddFlashCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEF7F512BC2DBF800E205F6 /* AddFlashCard.swift */; }; 6CEF7F522BC2DBF800E205F6 /* AddFlashCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEF7F512BC2DBF800E205F6 /* AddFlashCard.swift */; };
6CEF7F7D2BC457E600E205F6 /* DataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEF7F7C2BC457E600E205F6 /* DataController.swift */; };
6CEF7F812BC4694900E205F6 /* WordAXCD.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 6CEF7F7F2BC4694900E205F6 /* WordAXCD.xcdatamodeld */; };
6CEF7F842BC46B5900E205F6 /* Flashcard+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEF7F822BC46B5900E205F6 /* Flashcard+CoreDataClass.swift */; };
6CEF7F852BC46B5900E205F6 /* Flashcard+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEF7F832BC46B5900E205F6 /* Flashcard+CoreDataProperties.swift */; };
6CF439522B83541D004C3543 /* WordAXApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF439512B83541D004C3543 /* WordAXApp.swift */; }; 6CF439522B83541D004C3543 /* WordAXApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF439512B83541D004C3543 /* WordAXApp.swift */; };
6CF439542B83541D004C3543 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF439532B83541D004C3543 /* MainView.swift */; }; 6CF439542B83541D004C3543 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF439532B83541D004C3543 /* MainView.swift */; };
6CF439562B83541E004C3543 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF439552B83541E004C3543 /* Assets.xcassets */; }; 6CF439562B83541E004C3543 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF439552B83541E004C3543 /* Assets.xcassets */; };
@@ -32,6 +36,10 @@
6C8185092B8BA5740033CF46 /* FlashCardListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardListView.swift; sourceTree = "<group>"; }; 6C8185092B8BA5740033CF46 /* FlashCardListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardListView.swift; sourceTree = "<group>"; };
6C81850B2B8BA6BC0033CF46 /* FlashCardListRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardListRowView.swift; sourceTree = "<group>"; }; 6C81850B2B8BA6BC0033CF46 /* FlashCardListRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardListRowView.swift; sourceTree = "<group>"; };
6CEF7F512BC2DBF800E205F6 /* AddFlashCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFlashCard.swift; sourceTree = "<group>"; }; 6CEF7F512BC2DBF800E205F6 /* AddFlashCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddFlashCard.swift; sourceTree = "<group>"; };
6CEF7F7C2BC457E600E205F6 /* DataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DataController.swift; path = WordAX/Model/DataController.swift; sourceTree = "<group>"; };
6CEF7F802BC4694900E205F6 /* WordAX.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WordAX.xcdatamodel; sourceTree = "<group>"; };
6CEF7F822BC46B5900E205F6 /* Flashcard+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Flashcard+CoreDataClass.swift"; sourceTree = "<group>"; };
6CEF7F832BC46B5900E205F6 /* Flashcard+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Flashcard+CoreDataProperties.swift"; sourceTree = "<group>"; };
6CF4394E2B83541D004C3543 /* WordAX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WordAX.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6CF4394E2B83541D004C3543 /* WordAX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WordAX.app; sourceTree = BUILT_PRODUCTS_DIR; };
6CF439512B83541D004C3543 /* WordAXApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordAXApp.swift; sourceTree = "<group>"; }; 6CF439512B83541D004C3543 /* WordAXApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordAXApp.swift; sourceTree = "<group>"; };
6CF439532B83541D004C3543 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; }; 6CF439532B83541D004C3543 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
@@ -53,6 +61,7 @@
6C4632342BC2D99E003ED0E9 /* Views */ = { 6C4632342BC2D99E003ED0E9 /* Views */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
6C8185072B8B523D0033CF46 /* NextRepetitionButtonView.swift */,
6CEF7F512BC2DBF800E205F6 /* AddFlashCard.swift */, 6CEF7F512BC2DBF800E205F6 /* AddFlashCard.swift */,
6CF439532B83541D004C3543 /* MainView.swift */, 6CF439532B83541D004C3543 /* MainView.swift */,
6C8185092B8BA5740033CF46 /* FlashCardListView.swift */, 6C8185092B8BA5740033CF46 /* FlashCardListView.swift */,
@@ -64,9 +73,20 @@
path = Views; path = Views;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
6CEF7F7B2BC456A100E205F6 /* Model */ = {
isa = PBXGroup;
children = (
6CEF7F822BC46B5900E205F6 /* Flashcard+CoreDataClass.swift */,
6CEF7F832BC46B5900E205F6 /* Flashcard+CoreDataProperties.swift */,
);
path = Model;
sourceTree = "<group>";
};
6CF439452B83541D004C3543 = { 6CF439452B83541D004C3543 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
6CEF7F7F2BC4694900E205F6 /* WordAXCD.xcdatamodeld */,
6CEF7F7C2BC457E600E205F6 /* DataController.swift */,
6CF439502B83541D004C3543 /* WordAX */, 6CF439502B83541D004C3543 /* WordAX */,
6CF4394F2B83541D004C3543 /* Products */, 6CF4394F2B83541D004C3543 /* Products */,
); );
@@ -83,9 +103,9 @@
6CF439502B83541D004C3543 /* WordAX */ = { 6CF439502B83541D004C3543 /* WordAX */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
6CEF7F7B2BC456A100E205F6 /* Model */,
6CF439512B83541D004C3543 /* WordAXApp.swift */, 6CF439512B83541D004C3543 /* WordAXApp.swift */,
6C4632342BC2D99E003ED0E9 /* Views */, 6C4632342BC2D99E003ED0E9 /* Views */,
6C8185072B8B523D0033CF46 /* NextRepetitionButtonView.swift */,
6C8184FD2B88C9580033CF46 /* WordAX.swift */, 6C8184FD2B88C9580033CF46 /* WordAX.swift */,
6C8184FF2B88C9660033CF46 /* WordAXModelView.swift */, 6C8184FF2B88C9660033CF46 /* WordAXModelView.swift */,
6CF439552B83541E004C3543 /* Assets.xcassets */, 6CF439552B83541E004C3543 /* Assets.xcassets */,
@@ -179,10 +199,14 @@
6C81850A2B8BA5740033CF46 /* FlashCardListView.swift in Sources */, 6C81850A2B8BA5740033CF46 /* FlashCardListView.swift in Sources */,
6C8185002B88C9660033CF46 /* WordAXModelView.swift in Sources */, 6C8185002B88C9660033CF46 /* WordAXModelView.swift in Sources */,
6C8185042B88CA210033CF46 /* AnkiView.swift in Sources */, 6C8185042B88CA210033CF46 /* AnkiView.swift in Sources */,
6CEF7F7D2BC457E600E205F6 /* DataController.swift in Sources */,
6CF439522B83541D004C3543 /* WordAXApp.swift in Sources */, 6CF439522B83541D004C3543 /* WordAXApp.swift in Sources */,
6CEF7F522BC2DBF800E205F6 /* AddFlashCard.swift in Sources */, 6CEF7F522BC2DBF800E205F6 /* AddFlashCard.swift in Sources */,
6C8184FE2B88C9580033CF46 /* WordAX.swift in Sources */, 6C8184FE2B88C9580033CF46 /* WordAX.swift in Sources */,
6CEF7F812BC4694900E205F6 /* WordAXCD.xcdatamodeld in Sources */,
6C81850C2B8BA6BC0033CF46 /* FlashCardListRowView.swift in Sources */, 6C81850C2B8BA6BC0033CF46 /* FlashCardListRowView.swift in Sources */,
6CEF7F842BC46B5900E205F6 /* Flashcard+CoreDataClass.swift in Sources */,
6CEF7F852BC46B5900E205F6 /* Flashcard+CoreDataProperties.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -388,6 +412,20 @@
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCVersionGroup section */
6CEF7F7F2BC4694900E205F6 /* WordAXCD.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
6CEF7F802BC4694900E205F6 /* WordAX.xcdatamodel */,
);
currentVersion = 6CEF7F802BC4694900E205F6 /* WordAX.xcdatamodel */;
name = WordAXCD.xcdatamodeld;
path = WordAX/Model/WordAXCD.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
}; };
rootObject = 6CF439462B83541D004C3543 /* Project object */; rootObject = 6CF439462B83541D004C3543 /* Project object */;
} }

View File

@@ -0,0 +1,50 @@
//
// DataController.swift
// WordAX
//
// Created by Oliver Hnát on 08.04.2024.
//
import Foundation
import CoreData
class DataController: ObservableObject {
let container = NSPersistentContainer(name: "WordAXCD")
static let shared = DataController()
var viewContext: NSManagedObjectContext {
container.viewContext
}
init() {
container.loadPersistentStores { description, error in
if let error = error {
print("Core data failed to load: \(error.localizedDescription)")
}
}
}
public func addFlashcard(name: String, description: String) {
let flashcard = Flashcard(context: viewContext)
flashcard.id = UUID()
flashcard.name = name
flashcard.desc = description
flashcard.shown = false
flashcard.nextSpacedRepetitionMilestone = 0
flashcard.lastSeenOn = nil
flashcard.shownCount = 0
flashcard.dateAdded = Date()
try? viewContext.save()
}
public func getAllFlashcards() -> [Flashcard]{
let request = NSFetchRequest<Flashcard>(entityName: "Flashcard")
do {
return try viewContext.fetch(request)
} catch {
return []
}
}
}

View File

@@ -0,0 +1,19 @@
//
// Flashcard+CoreDataClass.swift
// WordAX
//
// Created by Oliver Hnát on 08.04.2024.
//
//
import Foundation
import CoreData
@objc(Flashcard)
public class Flashcard: NSManagedObject {
typealias SpacedRepetitionMilestoneEnum = WordAX.SpacedRepetitionMilestoneEnum
func getSpacedRepetitionMilestone() -> SpacedRepetitionMilestoneEnum {
return SpacedRepetitionMilestoneEnum.getMilestoneFromInt(value: self.nextSpacedRepetitionMilestone)
}
}

View File

@@ -0,0 +1,32 @@
//
// Flashcard+CoreDataProperties.swift
// WordAX
//
// Created by Oliver Hnát on 08.04.2024.
//
//
import Foundation
import CoreData
extension Flashcard {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Flashcard> {
return NSFetchRequest<Flashcard>(entityName: "Flashcard")
}
@NSManaged public var name: String?
@NSManaged public var desc: String?
@NSManaged public var id: UUID?
@NSManaged public var shown: Bool
@NSManaged public var nextSpacedRepetitionMilestone: Int64
@NSManaged public var lastSeenOn: Date?
@NSManaged public var dateAdded: Date?
@NSManaged public var shownCount: Int64
}
extension Flashcard : Identifiable {
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>WordAX.xcdatamodel</string>
</dict>
</plist>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22757" systemVersion="23D60" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithSwiftData="YES" userDefinedModelVersionIdentifier="">
<entity name="Flashcard" representedClassName="Flashcard" syncable="YES">
<attribute name="dateAdded" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="desc" optional="YES" attributeType="String"/>
<attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
<attribute name="lastSeenOn" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="name" optional="YES" attributeType="String"/>
<attribute name="nextSpacedRepetitionMilestone" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="shown" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="shownCount" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
</entity>
</model>

View File

@@ -10,7 +10,7 @@ import SwiftUI
struct AnkiView: View { struct AnkiView: View {
@EnvironmentObject var model: WordAXModelView @EnvironmentObject var model: WordAXModelView
@State var showDescription = false @State var showDescription = false
var flashcard: WordAX.FlashCard? { var flashcard: Flashcard? {
model.getFlashCardsToDisplay() model.getFlashCardsToDisplay()
} }
var body: some View { var body: some View {
@@ -25,8 +25,8 @@ struct AnkiView: View {
HStack(alignment: .center) { HStack(alignment: .center) {
NextRepetitionButtonView( NextRepetitionButtonView(
buttonText: "Wrong", buttonText: "Wrong",
nextMilestone: flashcard!.nextSpacedRepetitionMilestone, nextMilestone: flashcard!.getSpacedRepetitionMilestone(),
flashcardId: flashcard!.id, flashcardId: flashcard!.id!,
width: geometry.size.width, width: geometry.size.width,
color: .red, color: .red,
geometry: geometry, geometry: geometry,
@@ -35,8 +35,8 @@ struct AnkiView: View {
) )
NextRepetitionButtonView( NextRepetitionButtonView(
buttonText: "Correct", buttonText: "Correct",
nextMilestone: WordAX.SpacedRepetitionMilestoneEnum.getNext(milestone: flashcard!.nextSpacedRepetitionMilestone), nextMilestone: WordAX.SpacedRepetitionMilestoneEnum.getNext(milestone: flashcard!.getSpacedRepetitionMilestone()),
flashcardId: flashcard!.id, flashcardId: flashcard!.id!,
width:geometry.size.width, width:geometry.size.width,
color: .orange, color: .orange,
geometry: geometry, geometry: geometry,
@@ -45,8 +45,8 @@ struct AnkiView: View {
) )
NextRepetitionButtonView( NextRepetitionButtonView(
buttonText: "Easy", buttonText: "Easy",
nextMilestone: WordAX.SpacedRepetitionMilestoneEnum.getNext(milestone: WordAX.SpacedRepetitionMilestoneEnum.getNext(milestone: flashcard!.nextSpacedRepetitionMilestone)), nextMilestone: WordAX.SpacedRepetitionMilestoneEnum.getNext(milestone: WordAX.SpacedRepetitionMilestoneEnum.getNext(milestone: flashcard!.getSpacedRepetitionMilestone())),
flashcardId: flashcard!.id, flashcardId: flashcard!.id!,
width: geometry.size.width, width: geometry.size.width,
color: .green, color: .green,
geometry: geometry, geometry: geometry,

View File

@@ -9,7 +9,7 @@ import SwiftUI
struct FlashCardListRowView: View { struct FlashCardListRowView: View {
@EnvironmentObject var model: WordAXModelView @EnvironmentObject var model: WordAXModelView
var flashcard: WordAX.FlashCard var flashcard: Flashcard
@State var favorite = true @State var favorite = true
var body: some View { var body: some View {
HStack { HStack {
@@ -30,12 +30,12 @@ struct FlashCardListRowView: View {
} }
.padding(.trailing) .padding(.trailing)
VStack { VStack {
Text(flashcard.name) Text(flashcard.name ?? "Unknown")
.bold() .bold()
.font(.system(size: 19)) .font(.system(size: 19))
.multilineTextAlignment(.leading) .multilineTextAlignment(.leading)
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
Text(flashcard.description) Text(flashcard.desc ?? "Unknown")
.multilineTextAlignment(.leading) .multilineTextAlignment(.leading)
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(1) .lineLimit(1)
@@ -46,12 +46,16 @@ struct FlashCardListRowView: View {
} }
#Preview { #Preview {
Group { let fc = Flashcard()
FlashCardListRowView(flashcard: WordAX.FlashCard(id: 0, name: "Mesmerizing", description: "Some very long description like Lorem Ipsum which I'm to lazy to copy", shown: false, nextSpacedRepetitionMilestone: WordAX.SpacedRepetitionMilestoneEnum.OneDay, lastSeenOn: Date(), shownCount: 1)) fc.id = UUID()
fc.name = "Mesmerizing"
fc.desc = "Some very long description like Lorem Ipsum which I'm to lazy to copy"
return Group {
FlashCardListRowView(flashcard: fc)
.environmentObject(WordAXModelView()) .environmentObject(WordAXModelView())
FlashCardListRowView(flashcard: WordAX.FlashCard(id: 0, name: "Mesmerizing", description: "Some very long description like Lorem Ipsum which I'm to lazy to copy", shown: false, nextSpacedRepetitionMilestone: WordAX.SpacedRepetitionMilestoneEnum.OneDay, lastSeenOn: Date(), shownCount: 1)) FlashCardListRowView(flashcard: fc)
.environmentObject(WordAXModelView()) .environmentObject(WordAXModelView())
FlashCardListRowView(flashcard: WordAX.FlashCard(id: 0, name: "Mesmerizing", description: "Some very long description like Lorem Ipsum which I'm to lazy to copy", shown: false, nextSpacedRepetitionMilestone: WordAX.SpacedRepetitionMilestoneEnum.OneDay, lastSeenOn: Date(), shownCount: 1)) FlashCardListRowView(flashcard: fc)
.environmentObject(WordAXModelView()) .environmentObject(WordAXModelView())
} }
} }

View File

@@ -15,12 +15,12 @@ struct FlashCardListView: View {
GeometryReader { geometry in GeometryReader { geometry in
NavigationSplitView { NavigationSplitView {
Group { Group {
if !model.flashcards.isEmpty { if !DataController.shared.getAllFlashcards().isEmpty {
List(model.flashcards) { word in List(DataController.shared.getAllFlashcards()) { flashcard in
NavigationLink { NavigationLink {
FlashCardView(flashcard: word, showDescription: $showDescription) FlashCardView(flashcard: flashcard, showDescription: $showDescription)
} label: { } label: {
FlashCardListRowView(flashcard: word) FlashCardListRowView(flashcard: flashcard)
} }
} }
} }
@@ -32,7 +32,7 @@ struct FlashCardListView: View {
.frame(maxWidth: geometry.size.width - 30) .frame(maxWidth: geometry.size.width - 30)
} }
} }
.navigationTitle("Word List") .navigationTitle("All Flashcards")
.toolbar { .toolbar {
Button(action: { Button(action: {
self.addFlashcard = true self.addFlashcard = true

View File

@@ -9,14 +9,14 @@ import SwiftUI
import UIKit import UIKit
struct FlashCardView: View { struct FlashCardView: View {
var flashcard: WordAX.FlashCard var flashcard: Flashcard
@Binding var showDescription: Bool @Binding var showDescription: Bool
@EnvironmentObject var model: WordAXModelView @EnvironmentObject var model: WordAXModelView
@Environment(\.colorScheme) var colorScheme @Environment(\.colorScheme) var colorScheme
var body: some View { var body: some View {
let flashcardText = Text(flashcard.name) let flashcardText = Text(flashcard.name ?? "Unknown")
.font(.title) .font(.title)
.bold() .bold()
VStack { VStack {
@@ -30,7 +30,7 @@ struct FlashCardView: View {
Divider() Divider()
.background(colorScheme == .light ? Color.black : Color.white) .background(colorScheme == .light ? Color.black : Color.white)
.padding(.horizontal) .padding(.horizontal)
Text(flashcard.description) Text(flashcard.desc ?? "No description added")
.multilineTextAlignment(.center) .multilineTextAlignment(.center)
} else { } else {
flashcardText flashcardText
@@ -47,6 +47,6 @@ struct FlashCardView: View {
#Preview { #Preview {
@State var showDescription = false @State var showDescription = false
return FlashCardView(flashcard: WordAXModelView().getFlashCardsToDisplay()!, showDescription: $showDescription) return FlashCardView(flashcard: DataController.shared.getAllFlashcards()[0], showDescription: $showDescription)
.environmentObject(WordAXModelView()) .environmentObject(WordAXModelView())
} }

View File

@@ -10,7 +10,7 @@ import SwiftUI
struct NextRepetitionButtonView: View { struct NextRepetitionButtonView: View {
let buttonText: String let buttonText: String
let nextMilestone: WordAX.SpacedRepetitionMilestoneEnum? let nextMilestone: WordAX.SpacedRepetitionMilestoneEnum?
let flashcardId: Int let flashcardId: UUID
let width: CGFloat let width: CGFloat
let color: Color let color: Color
let geometry: GeometryProxy let geometry: GeometryProxy

View File

@@ -6,6 +6,7 @@
// //
import Foundation import Foundation
import SwiftUI
struct WordAX { struct WordAX {
struct FlashCard: Identifiable, Hashable { struct FlashCard: Identifiable, Hashable {
@@ -25,7 +26,14 @@ struct WordAX {
case Monthly = 30 case Monthly = 30
} }
enum SpacedRepetitionMilestoneEnum: Int, CaseIterable {
public mutating func add(flashcard: FlashCard) {
self.flashcards.append(flashcard)
}
@objc enum SpacedRepetitionMilestoneEnum: Int64, CaseIterable {
case Now = 0 // starting value
case OneMinute = 60 // 60 * 1 case OneMinute = 60 // 60 * 1
case TenMinutes = 600 // 60 * 10 case TenMinutes = 600 // 60 * 10
case OneHour = 3600 // 60 * 60 case OneHour = 3600 // 60 * 60
@@ -52,6 +60,11 @@ struct WordAX {
} }
return nil return nil
} }
static func getMilestoneFromInt(value: Int64) -> SpacedRepetitionMilestoneEnum {
return SpacedRepetitionMilestoneEnum.allCasesSorted.first(where: {$0.rawValue == value}) ?? SpacedRepetitionMilestoneEnum.Now
}
} }
struct Settings { struct Settings {
@@ -94,10 +107,6 @@ struct WordAX {
var flashcards: [FlashCard] = [] var flashcards: [FlashCard] = []
var settings: Settings var settings: Settings
public mutating func add(flashcard: FlashCard) {
self.flashcards.append(flashcard)
}
init() { init() {
self.flashcards = [] self.flashcards = []
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()

View File

@@ -9,11 +9,13 @@ import SwiftUI
@main @main
struct WordAXApp: App { struct WordAXApp: App {
@StateObject var model = WordAXModelView() @StateObject private var model = WordAXModelView()
@StateObject private var dataControler = DataController()
var body: some Scene { var body: some Scene {
WindowGroup { WindowGroup {
MainView() MainView()
.environmentObject(model) .environmentObject(model)
.environment(\.managedObjectContext, dataControler.container.viewContext)
} }
} }
} }

View File

@@ -10,20 +10,21 @@ import Foundation
class WordAXModelView: ObservableObject { class WordAXModelView: ObservableObject {
@Published private var model: WordAX @Published private var model: WordAX
typealias FlashCard = WordAX.FlashCard typealias FlashCard = WordAX.FlashCard
typealias SpacedRepetitionMilestoneEnum = WordAX.SpacedRepetitionMilestoneEnum
init() { init() {
model = WordAX() model = WordAX()
} }
public var flashcards: [FlashCard] { public var flashcards: [Flashcard] {
model.flashcards DataController.shared.getAllFlashcards()
} }
public func getDateFormatter() -> DateFormatter { public func getDateFormatter() -> DateFormatter {
model.settings.dateFormatter model.settings.dateFormatter
} }
public func getFlashCardsToDisplay() -> FlashCard? { public func getFlashCardsToDisplay() -> Flashcard? {
let flashcards = model.flashcards let flashcards = self.flashcards
if flashcards.count > 0 { if flashcards.count > 0 {
let notShownFlashCards = flashcards.filter({!$0.shown}) let notShownFlashCards = flashcards.filter({!$0.shown})
@@ -32,7 +33,7 @@ class WordAXModelView: ObservableObject {
} }
// if today is the date they're supposed to be shown // if today is the date they're supposed to be shown
let displayToday = flashcards.filter({ $0.lastSeenOn != nil && $0.lastSeenOn!.addSpacedRepetitionMilestone(milestone: $0.nextSpacedRepetitionMilestone).isBeforeTodayOrToday()}) let displayToday = flashcards.filter({ $0.lastSeenOn != nil && $0.lastSeenOn!.addSpacedRepetitionMilestone(milestone: SpacedRepetitionMilestoneEnum.getMilestoneFromInt(value: $0.nextSpacedRepetitionMilestone)).isBeforeTodayOrToday()})
if displayToday.count > 0 { if displayToday.count > 0 {
return displayToday.first! return displayToday.first!
} }
@@ -53,13 +54,15 @@ class WordAXModelView: ObservableObject {
return nil return nil
} }
public func ankiButtonClicked(flashcardId: Int, milestone: WordAX.SpacedRepetitionMilestoneEnum?) { public func ankiButtonClicked(flashcardId: UUID, milestone: WordAX.SpacedRepetitionMilestoneEnum?) {
model.setSpacedRepetitionMilestone(flashcardId: flashcardId, milestone: milestone) // TODO: Fix this with Core Data
model.flashcardShown(flashcardId: flashcardId) // model.setSpacedRepetitionMilestone(flashcardId: flashcardId, milestone: milestone)
// model.flashcardShown(flashcardId: flashcardId)
} }
public func addFlashCard(name: String, description: String) { public func addFlashCard(name: String, description: String) {
self.model.add(flashcard: FlashCard(id: (self.flashcards.map{$0.id}.max() ?? -1) + 1, name: name, description: description)) // self.model.add(flashcard: FlashCard(id: (self.flashcards.map{$0.id}.max() ?? -1) + 1, name: name, description: description))
DataController.shared.addFlashcard(name: name, description: description)
} }
} }