@@ -2,12 +2,18 @@ import SwiftUI
2
2
3
3
struct CourseView : View {
4
4
@State private var isLoading = false
5
- @State private var downloadProgress : [ Course : Progress ] = [ : ]
6
5
7
6
@State private var showingNotificationSettings = false
8
7
@State private var notificationsEnabled = false
9
8
@State private var showingInfoPopup = false
10
9
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
+
11
17
@StateObject private var viewModel = DownloadViewModel ( )
12
18
@StateObject private var questionLoader : QuestionLoader
13
19
@@ -25,89 +31,91 @@ struct CourseView: View {
25
31
var body : some View {
26
32
VStack {
27
33
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 ( )
59
38
. 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)
62
52
}
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 )
72
97
}
73
- . padding ( )
74
- . background ( LinearGradient ( gradient: Gradient ( colors: [ Color . training, Color . exam] ) , startPoint: . leading, endPoint: . trailing) )
75
- . cornerRadius ( 10 )
76
98
}
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)
86
109
}
87
- . padding ( )
88
- . background ( LinearGradient ( gradient: Gradient ( colors: [ Color . exam, Color . customPrimary] ) , startPoint: . leading, endPoint: . trailing) )
89
110
. cornerRadius ( 10 )
90
111
}
91
112
}
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
- }
105
113
}
106
114
. onAppear {
107
115
loadUserTrainingData ( )
108
116
checkNotificationSettings ( )
109
117
if questionLoader. questions. isEmpty {
110
- downloadCourse ( )
118
+ showDownloadAlert = true
111
119
}
112
120
}
113
121
}
@@ -132,11 +140,34 @@ struct CourseView: View {
132
140
viewModel: viewModel
133
141
)
134
142
)
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
+ }
137
169
}
138
170
}
139
-
140
171
private var notificationButton : some View {
141
172
Button ( action: {
142
173
if notificationsEnabled {
@@ -178,26 +209,6 @@ struct CourseView: View {
178
209
notificationsEnabled = false
179
210
}
180
211
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
- }
201
212
}
202
213
203
214
struct CourseInformationPopup : View {
0 commit comments