@@ -2,12 +2,18 @@ import SwiftUI
22
33struct CourseView : View {
44 @State private var isLoading = false
5- @State private var downloadProgress : [ Course : Progress ] = [ : ]
65
76 @State private var showingNotificationSettings = false
87 @State private var notificationsEnabled = false
98 @State private var showingInfoPopup = false
109
10+ @State private var showDownloadAlert = false
11+ @State private var showDownloadOverlay = false
12+ @StateObject private var downloadViewModel = DownloadViewModel ( )
13+ @Environment ( \. presentationMode) var presentationMode
14+
15+
16+
1117 @StateObject private var viewModel = DownloadViewModel ( )
1218 @StateObject private var questionLoader : QuestionLoader
1319
@@ -25,89 +31,91 @@ struct CourseView: View {
2531 var body : some View {
2632 VStack {
2733 VStack {
28- Text ( course. fullName)
29- . font ( . title)
30- . bold ( )
31- . padding ( )
32- . frame ( alignment: . leading)
33- . multilineTextAlignment ( . center)
34- Text ( course. description)
35- . font ( . caption)
36- . frame ( alignment: . leading)
37- . multilineTextAlignment ( . center)
38- . padding ( . horizontal)
39-
40- HStack {
41- Image ( systemName: " clock " )
42- . foregroundColor ( . blue)
43- Text ( formatTimeSpent ( userTrainingStore. trainingData [ course. shortName] ? . timeSpent ?? 0 ) )
44- . font ( . subheadline)
45- }
46- . padding ( . top, 20 )
47-
48- Spacer ( )
49- VStack ( spacing: 20 ) {
50- NavigationLink ( destination: TrainingView ( course: course) ) {
51- VStack {
52- Text ( " Training " )
53- . font ( . title)
54- . foregroundColor ( . white)
55- Text ( " Practice and learn random questions " )
56- . font ( . subheadline)
57- . foregroundColor ( . white)
58- }
34+ if !questionLoader. questions. isEmpty {
35+ Text ( course. fullName)
36+ . font ( . title)
37+ . bold ( )
5938 . padding ( )
60- . background ( LinearGradient ( gradient: Gradient ( colors: [ Color . customAccent, Color . training] ) , startPoint: . leading, endPoint: . trailing) )
61- . cornerRadius ( 10 )
39+ . frame ( alignment: . leading)
40+ . multilineTextAlignment ( . center)
41+ Text ( course. description)
42+ . font ( . caption)
43+ . frame ( alignment: . leading)
44+ . multilineTextAlignment ( . center)
45+ . padding ( . horizontal)
46+
47+ HStack {
48+ Image ( systemName: " clock " )
49+ . foregroundColor ( . blue)
50+ Text ( formatTimeSpent ( userTrainingStore. trainingData [ course. shortName] ? . timeSpent ?? 0 ) )
51+ . font ( . subheadline)
6252 }
63-
64- NavigationLink ( destination: TrainingView ( course: course) ) {
65- VStack {
66- Text ( " Intelligent Training " )
67- . font ( . title)
68- . foregroundColor ( . white)
69- Text ( " Train based on your learning history " )
70- . font ( . subheadline)
71- . foregroundColor ( . white)
53+ . padding ( . top, 20 )
54+
55+ Spacer ( )
56+ VStack ( spacing: 20 ) {
57+ NavigationLink ( destination: TrainingView ( course: course) ) {
58+ VStack {
59+ Text ( " Training " )
60+ . font ( . title)
61+ . foregroundColor ( . white)
62+ Text ( " Practice and learn random questions " )
63+ . font ( . subheadline)
64+ . foregroundColor ( . white)
65+ }
66+ . padding ( )
67+ . background ( LinearGradient ( gradient: Gradient ( colors: [ Color . customAccent, Color . training] ) , startPoint: . leading, endPoint: . trailing) )
68+ . cornerRadius ( 10 )
69+ }
70+
71+ NavigationLink ( destination: TrainingView ( course: course) ) {
72+ VStack {
73+ Text ( " Intelligent Training " )
74+ . font ( . title)
75+ . foregroundColor ( . white)
76+ Text ( " Train based on your learning history " )
77+ . font ( . subheadline)
78+ . foregroundColor ( . white)
79+ }
80+ . padding ( )
81+ . background ( LinearGradient ( gradient: Gradient ( colors: [ Color . training, Color . exam] ) , startPoint: . leading, endPoint: . trailing) )
82+ . cornerRadius ( 10 )
83+ }
84+
85+ NavigationLink ( destination: ExamModeView ( course: course) ) {
86+ VStack {
87+ Text ( " Exam " )
88+ . font ( . title)
89+ . foregroundColor ( . white)
90+ Text ( " Challenge yourself with timed exams " )
91+ . font ( . subheadline)
92+ . foregroundColor ( . white)
93+ }
94+ . padding ( )
95+ . background ( LinearGradient ( gradient: Gradient ( colors: [ Color . exam, Color . customPrimary] ) , startPoint: . leading, endPoint: . trailing) )
96+ . cornerRadius ( 10 )
7297 }
73- . padding ( )
74- . background ( LinearGradient ( gradient: Gradient ( colors: [ Color . training, Color . exam] ) , startPoint: . leading, endPoint: . trailing) )
75- . cornerRadius ( 10 )
7698 }
77-
78- NavigationLink ( destination: ExamModeView ( course: course) ) {
79- VStack {
80- Text ( " Exam " )
81- . font ( . title)
82- . foregroundColor ( . white)
83- Text ( " Challenge yourself with timed exams " )
84- . font ( . subheadline)
85- . foregroundColor ( . white)
99+ Spacer ( )
100+
101+ NavigationLink ( destination: BookmarksView ( ) ) {
102+ HStack {
103+ Image ( systemName: " bookmark " )
104+ . font ( . title3)
105+ . foregroundColor ( colorScheme == . dark ? . white : . black)
106+ Text ( " Bookmarks " )
107+ . font ( . title3)
108+ . foregroundColor ( colorScheme == . dark ? . white : . black)
86109 }
87- . padding ( )
88- . background ( LinearGradient ( gradient: Gradient ( colors: [ Color . exam, Color . customPrimary] ) , startPoint: . leading, endPoint: . trailing) )
89110 . cornerRadius ( 10 )
90111 }
91112 }
92- Spacer ( )
93-
94- NavigationLink ( destination: BookmarksView ( ) ) {
95- HStack {
96- Image ( systemName: " bookmark " )
97- . font ( . title3)
98- . foregroundColor ( colorScheme == . dark ? . white : . black)
99- Text ( " Bookmarks " )
100- . font ( . title3)
101- . foregroundColor ( colorScheme == . dark ? . white : . black)
102- }
103- . cornerRadius ( 10 )
104- }
105113 }
106114 . onAppear {
107115 loadUserTrainingData ( )
108116 checkNotificationSettings ( )
109117 if questionLoader. questions. isEmpty {
110- downloadCourse ( )
118+ showDownloadAlert = true
111119 }
112120 }
113121 }
@@ -132,11 +140,34 @@ struct CourseView: View {
132140 viewModel: viewModel
133141 )
134142 )
135- . alert ( isPresented: $viewModel. showAlert) {
136- Alert ( title: Text ( " Download Error " ) , message: Text ( viewModel. alertMessage) , dismissButton: . default( Text ( " OK " ) ) )
143+ . fullScreenCover ( isPresented: $showDownloadOverlay) {
144+ DownloadOverlayView (
145+ isShowing: $showDownloadOverlay,
146+ viewModel: downloadViewModel
147+ )
148+ . onAppear {
149+ downloadViewModel. downloadCourses ( [ course] )
150+ }
151+ }
152+ . alert ( isPresented: $showDownloadAlert) {
153+ Alert (
154+ title: Text ( " Download Course " ) ,
155+ message: Text ( " Would you like to download this course now? " ) ,
156+ primaryButton: . default( Text ( " Yes " ) ) {
157+ showDownloadOverlay = true
158+ } ,
159+ secondaryButton: . cancel( Text ( " Cancel " ) ) {
160+ presentationMode. wrappedValue. dismiss ( )
161+ }
162+ )
163+ }
164+ . onChange ( of: downloadViewModel. downloadCompleted) { completed in
165+ if completed {
166+ showDownloadOverlay = false
167+ questionLoader. reloadQuestions ( from: course. shortName + " .json " )
168+ }
137169 }
138170 }
139-
140171 private var notificationButton : some View {
141172 Button ( action: {
142173 if notificationsEnabled {
@@ -178,26 +209,6 @@ struct CourseView: View {
178209 notificationsEnabled = false
179210 }
180211
181- func downloadCourse( ) {
182- viewModel. downloadCourse ( course)
183- viewModel. $isDownloading. sink { isDownloading in
184- if ( !isDownloading) {
185- DispatchQueue . main. async {
186- questionLoader. reloadQuestions ( from: course. shortName + " .json " )
187- }
188- }
189- }
190- . store ( in: & viewModel. cancellables)
191-
192- viewModel. $showAlert. sink { showAlert in
193- if showAlert {
194- DispatchQueue . main. asyncAfter ( deadline: . now( ) + 2 ) { // Adjust the delay as needed
195- // Handle dismissal if needed
196- }
197- }
198- }
199- . store ( in: & viewModel. cancellables)
200- }
201212}
202213
203214struct CourseInformationPopup : View {
0 commit comments