Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reset of Training Data #36

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions CloudMaster/Features/Course/Views/CourseView.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import SwiftUI

struct CourseView: View {
@State private var isLoading = false
@State private var downloadProgress: [Course: Progress] = [:]
@State private var userTrainingData = UserTrainingData()

@State private var showingNotificationSettings = false
@State private var notificationsEnabled = false
@State private var showingInfoPopup = false

@StateObject private var viewModel = DownloadViewModel()
@StateObject private var questionLoader: QuestionLoader

@ObservedObject var userTrainingStore = UserTrainingStore.shared

@Environment(\.colorScheme) var colorScheme

let course: Course
Expand Down Expand Up @@ -37,7 +40,7 @@ struct CourseView: View {
HStack {
Image(systemName: "clock")
.foregroundColor(.blue)
Text(formatTimeSpent(userTrainingData.timeSpent))
Text(formatTimeSpent(userTrainingStore.trainingData[course.shortName]?.timeSpent ?? 0))
.font(.subheadline)
}
.padding(.top, 20)
Expand Down Expand Up @@ -101,7 +104,7 @@ struct CourseView: View {
}
}
.onAppear {
loadUserTrainingData(for: course)
loadUserTrainingData()
checkNotificationSettings()
if questionLoader.questions.isEmpty {
downloadCourse()
Expand Down Expand Up @@ -154,12 +157,8 @@ struct CourseView: View {
}
}

func loadUserTrainingData(for course: Course) {
if let data = UserDefaults.standard.data(forKey: course.shortName) {
if let decodedData = try? JSONDecoder().decode(UserTrainingData.self, from: data) {
userTrainingData = decodedData
}
}
func loadUserTrainingData() {
_ = userTrainingStore.loadTrainingData(forCourse: course.shortName)
}

func formatTimeSpent(_ time: TimeInterval) -> String {
Expand Down Expand Up @@ -234,5 +233,4 @@ struct CourseInformationPopup: View {
}
.padding()
}

}
2 changes: 1 addition & 1 deletion CloudMaster/Features/Settings/Views/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct SettingsView: View {
Section(header: Text("Training Data Management")) {
Button(action: {
showAlertWith(title: "Delete Trainingsdata", message: "Are you sure you want to delete all training data?", action: {
UserTrainingStore.shared.resetTrainingData()
UserTrainingStore.shared.deleteAllTrainingData()
})
}) {
Text("Delete Training data")
Expand Down
56 changes: 35 additions & 21 deletions CloudMaster/Features/Training/Models/UserTrainingData.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import Foundation
import SwiftUI

struct UserTrainingData: Codable {
struct UserTrainingData: Codable, Identifiable {
var id = UUID()
let shortName: String

var timeSpent: TimeInterval
var correctAnswers: Int
var wrongAnswers: Int
var questionAttempts: [UUID: Int] // Mapping question ID to the number of attempts
var questionStats: [UUID: QuestionStats] // Mapping question ID to the stats

init() {
init(shortName: String) {
self.shortName = shortName
self.timeSpent = 0
self.correctAnswers = 0
self.wrongAnswers = 0
Expand All @@ -16,6 +21,7 @@ struct UserTrainingData: Codable {
}

mutating func updateStats(for questionID: UUID, correctChoices: Set<UUID>, selectedChoices: Set<UUID>) {

// Update question attempts
if let attempts = questionAttempts[questionID] {
questionAttempts[questionID] = attempts + 1
Expand All @@ -38,7 +44,6 @@ struct UserTrainingData: Codable {
self.questionStats[questionID] = QuestionStats(timesViewed: 1, timesCorrect: timesCorrect, timesIncorrect: timesIncorrect)
}
}

}

struct QuestionStats: Codable {
Expand All @@ -47,33 +52,42 @@ struct QuestionStats: Codable {
var timesIncorrect: Int
}

class UserTrainingStore {
class UserTrainingStore: ObservableObject {
static let shared = UserTrainingStore()
private let userDefaultsKey = "userTrainingData"
private let userDefaultsKeyPrefix = "userTrainingData_"

private init() {
loadTrainingData()
}
private init() {}

var trainingData: UserTrainingData = UserTrainingData()
@Published var trainingData: [String: UserTrainingData] = [:]

func loadTrainingData() {
if let data = UserDefaults.standard.data(forKey: userDefaultsKey) {
if let decodedData = try? JSONDecoder().decode(UserTrainingData.self, from: data) {
trainingData = decodedData
}
func loadTrainingData(forCourse shortName: String) -> UserTrainingData {
if let data = UserDefaults.standard.data(forKey: userDefaultsKeyPrefix + shortName),
let decodedData = try? JSONDecoder().decode(UserTrainingData.self, from: data) {
trainingData[shortName] = decodedData
return decodedData
} else {
let newTrainingData = UserTrainingData(shortName: shortName)
trainingData[shortName] = newTrainingData
return newTrainingData
}
}

func saveTrainingData() {
if let data = try? JSONEncoder().encode(trainingData) {
UserDefaults.standard.set(data, forKey: userDefaultsKey)
func saveTrainingData(_ data: UserTrainingData) {
trainingData[data.shortName] = data
if let encoded = try? JSONEncoder().encode(data) {
UserDefaults.standard.set(encoded, forKey: userDefaultsKeyPrefix + data.shortName)
}
}

func resetTrainingData() {
trainingData = UserTrainingData()
saveTrainingData()
UserDefaults.standard.removeObject(forKey: userDefaultsKey)
func deleteTrainingData(forCourse shortName: String) {
trainingData.removeValue(forKey: shortName)
UserDefaults.standard.removeObject(forKey: userDefaultsKeyPrefix + shortName)
}

func deleteAllTrainingData() {
trainingData.keys.forEach { shortName in
UserDefaults.standard.removeObject(forKey: userDefaultsKeyPrefix + shortName)
}
trainingData.removeAll()
}
}
24 changes: 14 additions & 10 deletions CloudMaster/Features/Training/Views/TrainingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ struct TrainingView: View {
@State private var currentQuestionIndex = 0
@State private var selectedChoices: Set<UUID> = []
@State private var showResult = false
@State private var userTrainingData = UserTrainingStore.shared.trainingData
@State private var startTime: Date?
@State private var isBookmarked: Bool = false
@Environment(\.presentationMode) var presentationMode

@ObservedObject var userTrainingStore = UserTrainingStore.shared

let course: Course
@StateObject private var questionLoader: QuestionLoader

Expand Down Expand Up @@ -95,6 +96,7 @@ struct TrainingView: View {
.navigationBarHidden(true)
.onAppear {
startTime = Date()
loadUserTrainingData()
updateBookmarkState() // Ensure bookmark state is updated when the view appears
}
.onDisappear {
Expand Down Expand Up @@ -161,30 +163,32 @@ struct TrainingView: View {
}

func updateUserTrainingData(for question: Question) {
guard var userTrainingData = userTrainingStore.trainingData[course.shortName] else { return }

if let startTime = startTime {
userTrainingData.timeSpent += Date().timeIntervalSince(startTime)
}


print(userTrainingData.timeSpent)

let correctChoices = Set(question.choices.filter { $0.correct }.map { $0.id })
let userCorrectChoices = selectedChoices.intersection(correctChoices)

userTrainingData.correctAnswers += userCorrectChoices.count
userTrainingData.wrongAnswers += selectedChoices.subtracting(correctChoices).count

userTrainingData.updateStats(for: question.id, correctChoices: correctChoices, selectedChoices: selectedChoices)

userTrainingStore.saveTrainingData(userTrainingData)
}

func loadUserTrainingData(for course: Course) {
if let data = UserDefaults.standard.data(forKey: course.shortName) {
if let decodedData = try? JSONDecoder().decode(UserTrainingData.self, from: data) {
userTrainingData = decodedData
}
}
func loadUserTrainingData() {
_ = userTrainingStore.loadTrainingData(forCourse: course.shortName)
}

func saveUserTrainingData() {
if let data = try? JSONEncoder().encode(userTrainingData) {
UserDefaults.standard.set(data, forKey: course.shortName)
if let userTrainingData = userTrainingStore.trainingData[course.shortName] {
userTrainingStore.saveTrainingData(userTrainingData)
}
}
}
4 changes: 3 additions & 1 deletion CloudMaster/Utilities/QuestionLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ class QuestionLoader: ObservableObject {
}

private func reorderQuestions(_ questions: [Question]) -> [Question] {
let trainingData = UserTrainingStore.shared.trainingData
guard let trainingData = UserTrainingStore.shared.trainingData[questions.first?.id.uuidString ?? ""] else {
return questions
}

let newQuestions = questions.filter { trainingData.questionStats[$0.id] == nil }
let incorrectQuestions = questions.filter {
Expand Down
Loading