diff --git a/CloudMaster/Features/Common/DownloadOverlayView.swift b/CloudMaster/Features/Common/DownloadOverlayView.swift index fecc163..471ea98 100644 --- a/CloudMaster/Features/Common/DownloadOverlayView.swift +++ b/CloudMaster/Features/Common/DownloadOverlayView.swift @@ -50,6 +50,7 @@ struct DownloadOverlayView: View { Text(String(format: "%.0f %%", min(self.progress, 1.0) * 100.0)) .font(.largeTitle) .bold() + .foregroundColor(.white) } else { withAnimation(.spring()) { Image(systemName: "checkmark.circle.fill") diff --git a/CloudMaster/Features/Course/Views/CourseView.swift b/CloudMaster/Features/Course/Views/CourseView.swift index 6109303..6e27603 100644 --- a/CloudMaster/Features/Course/Views/CourseView.swift +++ b/CloudMaster/Features/Course/Views/CourseView.swift @@ -2,12 +2,18 @@ import SwiftUI struct CourseView: View { @State private var isLoading = false - @State private var downloadProgress: [Course: Progress] = [:] @State private var showingNotificationSettings = false @State private var notificationsEnabled = false @State private var showingInfoPopup = false + @State private var showDownloadAlert = false + @State private var showDownloadOverlay = false + @StateObject private var downloadViewModel = DownloadViewModel() + @Environment(\.presentationMode) var presentationMode + + + @StateObject private var viewModel = DownloadViewModel() @StateObject private var questionLoader: QuestionLoader @@ -25,89 +31,91 @@ struct CourseView: View { var body: some View { VStack { VStack { - Text(course.fullName) - .font(.title) - .bold() - .padding() - .frame(alignment: .leading) - .multilineTextAlignment(.center) - Text(course.description) - .font(.caption) - .frame(alignment: .leading) - .multilineTextAlignment(.center) - .padding(.horizontal) - - HStack { - Image(systemName: "clock") - .foregroundColor(.blue) - Text(formatTimeSpent(userTrainingStore.trainingData[course.shortName]?.timeSpent ?? 0)) - .font(.subheadline) - } - .padding(.top, 20) - - Spacer() - VStack(spacing: 20) { - NavigationLink(destination: TrainingView(course: course)) { - VStack { - Text("Training") - .font(.title) - .foregroundColor(.white) - Text("Practice and learn random questions") - .font(.subheadline) - .foregroundColor(.white) - } + if !questionLoader.questions.isEmpty { + Text(course.fullName) + .font(.title) + .bold() .padding() - .background(LinearGradient(gradient: Gradient(colors: [Color.customAccent, Color.training]), startPoint: .leading, endPoint: .trailing)) - .cornerRadius(10) + .frame(alignment: .leading) + .multilineTextAlignment(.center) + Text(course.description) + .font(.caption) + .frame(alignment: .leading) + .multilineTextAlignment(.center) + .padding(.horizontal) + + HStack { + Image(systemName: "clock") + .foregroundColor(.blue) + Text(formatTimeSpent(userTrainingStore.trainingData[course.shortName]?.timeSpent ?? 0)) + .font(.subheadline) } - - NavigationLink(destination: TrainingView(course: course)) { - VStack { - Text("Intelligent Training") - .font(.title) - .foregroundColor(.white) - Text("Train based on your learning history") - .font(.subheadline) - .foregroundColor(.white) + .padding(.top, 20) + + Spacer() + VStack(spacing: 20) { + NavigationLink(destination: TrainingView(course: course)) { + VStack { + Text("Training") + .font(.title) + .foregroundColor(.white) + Text("Practice and learn random questions") + .font(.subheadline) + .foregroundColor(.white) + } + .padding() + .background(LinearGradient(gradient: Gradient(colors: [Color.customAccent, Color.training]), startPoint: .leading, endPoint: .trailing)) + .cornerRadius(10) + } + + NavigationLink(destination: TrainingView(course: course)) { + VStack { + Text("Intelligent Training") + .font(.title) + .foregroundColor(.white) + Text("Train based on your learning history") + .font(.subheadline) + .foregroundColor(.white) + } + .padding() + .background(LinearGradient(gradient: Gradient(colors: [Color.training, Color.exam]), startPoint: .leading, endPoint: .trailing)) + .cornerRadius(10) + } + + NavigationLink(destination: ExamModeView(course: course)) { + VStack { + Text("Exam") + .font(.title) + .foregroundColor(.white) + Text("Challenge yourself with timed exams") + .font(.subheadline) + .foregroundColor(.white) + } + .padding() + .background(LinearGradient(gradient: Gradient(colors: [Color.exam, Color.customPrimary]), startPoint: .leading, endPoint: .trailing)) + .cornerRadius(10) } - .padding() - .background(LinearGradient(gradient: Gradient(colors: [Color.training, Color.exam]), startPoint: .leading, endPoint: .trailing)) - .cornerRadius(10) } - - NavigationLink(destination: ExamModeView(course: course)) { - VStack { - Text("Exam") - .font(.title) - .foregroundColor(.white) - Text("Challenge yourself with timed exams") - .font(.subheadline) - .foregroundColor(.white) + Spacer() + + NavigationLink(destination: BookmarksView()) { + HStack { + Image(systemName: "bookmark") + .font(.title3) + .foregroundColor(colorScheme == .dark ? .white : .black) + Text("Bookmarks") + .font(.title3) + .foregroundColor(colorScheme == .dark ? .white : .black) } - .padding() - .background(LinearGradient(gradient: Gradient(colors: [Color.exam, Color.customPrimary]), startPoint: .leading, endPoint: .trailing)) .cornerRadius(10) } } - Spacer() - - NavigationLink(destination: BookmarksView()) { - HStack { - Image(systemName: "bookmark") - .font(.title3) - .foregroundColor(colorScheme == .dark ? .white : .black) - Text("Bookmarks") - .font(.title3) - .foregroundColor(colorScheme == .dark ? .white : .black) - } - .cornerRadius(10) - } } .onAppear { loadUserTrainingData() checkNotificationSettings() if questionLoader.questions.isEmpty { - downloadCourse() + showDownloadAlert = true } } } @@ -132,11 +140,34 @@ struct CourseView: View { viewModel: viewModel ) ) - .alert(isPresented: $viewModel.showAlert) { - Alert(title: Text("Download Error"), message: Text(viewModel.alertMessage), dismissButton: .default(Text("OK"))) + .fullScreenCover(isPresented: $showDownloadOverlay) { + DownloadOverlayView( + isShowing: $showDownloadOverlay, + viewModel: downloadViewModel + ) + .onAppear { + downloadViewModel.downloadCourses([course]) + } + } + .alert(isPresented: $showDownloadAlert) { + Alert( + title: Text("Download Course"), + message: Text("Would you like to download this course now?"), + primaryButton: .default(Text("Yes")) { + showDownloadOverlay = true + }, + secondaryButton: .cancel(Text("Cancel")) { + presentationMode.wrappedValue.dismiss() + } + ) + } + .onChange(of: downloadViewModel.downloadCompleted) { completed in + if completed { + showDownloadOverlay = false + questionLoader.reloadQuestions(from: course.shortName + ".json") + } } } - private var notificationButton: some View { Button(action: { if notificationsEnabled { @@ -178,26 +209,6 @@ struct CourseView: View { notificationsEnabled = false } - func downloadCourse() { - viewModel.downloadCourse(course) - viewModel.$isDownloading.sink { isDownloading in - if (!isDownloading) { - DispatchQueue.main.async { - questionLoader.reloadQuestions(from: course.shortName + ".json") - } - } - } - .store(in: &viewModel.cancellables) - - viewModel.$showAlert.sink { showAlert in - if showAlert { - DispatchQueue.main.asyncAfter(deadline: .now() + 2) { // Adjust the delay as needed - // Handle dismissal if needed - } - } - } - .store(in: &viewModel.cancellables) - } } struct CourseInformationPopup: View { diff --git a/CloudMaster/Features/Training/Views/TrainingView.swift b/CloudMaster/Features/Training/Views/TrainingView.swift index 8a88a11..d1377b5 100644 --- a/CloudMaster/Features/Training/Views/TrainingView.swift +++ b/CloudMaster/Features/Training/Views/TrainingView.swift @@ -168,8 +168,6 @@ struct TrainingView: View { userTrainingData.timeSpent += Date().timeIntervalSince(startTime) } - print(userTrainingData.timeSpent) - let correctChoices = Set(question.choices.filter { $0.correct }.map { $0.id }) let userCorrectChoices = selectedChoices.intersection(correctChoices)