Skip to content

Commit

Permalink
Merge pull request #36 from Ditectrev/29-deleting-training-data-in-se…
Browse files Browse the repository at this point in the history
…ttings-doesnt-work

Fix reset of Training Data
  • Loading branch information
danieldanielecki authored Jun 22, 2024
2 parents 5417542 + b332019 commit 535d231
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 43 deletions.
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 @@ -94,6 +95,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 @@ -160,30 +162,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

0 comments on commit 535d231

Please sign in to comment.