Skip to content

30 keep displaying spinner when assets is downloaded after navigating #44

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

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
1 change: 1 addition & 0 deletions CloudMaster/Features/Common/DownloadOverlayView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
199 changes: 105 additions & 94 deletions CloudMaster/Features/Course/Views/CourseView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
}
}
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 0 additions & 2 deletions CloudMaster/Features/Training/Views/TrainingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
Loading