From 8ef7710a7299686926ea8afee3a344da2bfa933e Mon Sep 17 00:00:00 2001 From: AnnaDluzhinskaya Date: Mon, 4 Jul 2022 13:41:09 +0300 Subject: [PATCH] add LessonKit, CourseCompletionKit --- ReusEd.xcodeproj/project.pbxproj | 34 ++ ReusEd/Models/ViewAssetsModel.swift | 21 +- ReusEd/Resources/courses.json | 2 +- ReusEd/Resources/lessons.json | 2 +- .../CompleteCourseView.swift | 335 +++++++------- .../CourseDetailSectionCellView.swift | 14 +- .../CourseContentViews/CourseDetailView.swift | 17 +- .../QuizLessons/QuizAlertView.swift | 104 ++--- .../QuizLessons/QuizQuestionView.swift | 432 +++++++++--------- .../QuizLessons/QuizView.swift | 234 +++++----- .../TextImageLessonSectionView.swift | 46 +- .../TextImageLessonView.swift | 250 +++++----- .../TextImageLessons/TextImageView.swift | 56 +-- .../AutoRotateVideoPlayerView.swift | 140 +++--- .../VideoLessons/VideoDescriptionView.swift | 64 +-- .../VideoLessons/VideoLessonView.swift | 132 +++--- .../VideoLessons/VideoStampsIView.swift | 90 ++-- .../MainPage/Notifications/ListView.swift | 1 + 18 files changed, 1002 insertions(+), 972 deletions(-) diff --git a/ReusEd.xcodeproj/project.pbxproj b/ReusEd.xcodeproj/project.pbxproj index a413dc5..c188cea 100644 --- a/ReusEd.xcodeproj/project.pbxproj +++ b/ReusEd.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 2A105B0B2851DCF100DB971B /* TabBarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A105B0A2851DCF100DB971B /* TabBarModel.swift */; }; + 2A1506A92872EB790029DD9A /* LessonKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2A1506A82872EB790029DD9A /* LessonKit */; }; + 2A1506AC2872F6E90029DD9A /* CourseCompletionKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2A1506AB2872F6E90029DD9A /* CourseCompletionKit */; }; 2A1B302C2860595500A2F20D /* ViewAssetsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1B302B2860595500A2F20D /* ViewAssetsModel.swift */; }; 2A5A80E9285B2C8E00809CB2 /* AutoRotateVideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5A80E8285B2C8E00809CB2 /* AutoRotateVideoPlayerView.swift */; }; 2A5A80EB285B5CC500809CB2 /* VideoDescriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5A80EA285B5CC500809CB2 /* VideoDescriptionView.swift */; }; @@ -220,7 +222,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 2A1506A92872EB790029DD9A /* LessonKit in Frameworks */, 7A08F099286DEF9B006442BF /* OnBoardingKit in Frameworks */, + 2A1506AC2872F6E90029DD9A /* CourseCompletionKit in Frameworks */, F889E44EEDB64B288FE6FEE7 /* Pods_ReusEd.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -606,6 +610,8 @@ name = ReusEd; packageProductDependencies = ( 7A08F098286DEF9B006442BF /* OnBoardingKit */, + 2A1506A82872EB790029DD9A /* LessonKit */, + 2A1506AB2872F6E90029DD9A /* CourseCompletionKit */, ); productName = ReusEd; productReference = 7A038BFF284F324300B1376F /* ReusEd.app */; @@ -637,6 +643,8 @@ mainGroup = 7A038BF6284F324300B1376F; packageReferences = ( 7A08F097286DEF9B006442BF /* XCRemoteSwiftPackageReference "OnBoardingKit" */, + 2A1506A72872EB790029DD9A /* XCRemoteSwiftPackageReference "LessonKit" */, + 2A1506AA2872F6E90029DD9A /* XCRemoteSwiftPackageReference "CourseCompletionKit" */, ); productRefGroup = 7A038C00284F324300B1376F /* Products */; projectDirPath = ""; @@ -1036,6 +1044,22 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + 2A1506A72872EB790029DD9A /* XCRemoteSwiftPackageReference "LessonKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/iOSerler/LessonKit.git"; + requirement = { + branch = main; + kind = branch; + }; + }; + 2A1506AA2872F6E90029DD9A /* XCRemoteSwiftPackageReference "CourseCompletionKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/iOSerler/CourseCompletionKit.git"; + requirement = { + branch = main; + kind = branch; + }; + }; 7A08F097286DEF9B006442BF /* XCRemoteSwiftPackageReference "OnBoardingKit" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/iOSerler/OnBoardingKit"; @@ -1047,6 +1071,16 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 2A1506A82872EB790029DD9A /* LessonKit */ = { + isa = XCSwiftPackageProductDependency; + package = 2A1506A72872EB790029DD9A /* XCRemoteSwiftPackageReference "LessonKit" */; + productName = LessonKit; + }; + 2A1506AB2872F6E90029DD9A /* CourseCompletionKit */ = { + isa = XCSwiftPackageProductDependency; + package = 2A1506AA2872F6E90029DD9A /* XCRemoteSwiftPackageReference "CourseCompletionKit" */; + productName = CourseCompletionKit; + }; 7A08F098286DEF9B006442BF /* OnBoardingKit */ = { isa = XCSwiftPackageProductDependency; package = 7A08F097286DEF9B006442BF /* XCRemoteSwiftPackageReference "OnBoardingKit" */; diff --git a/ReusEd/Models/ViewAssetsModel.swift b/ReusEd/Models/ViewAssetsModel.swift index 475c04e..cc57f6a 100644 --- a/ReusEd/Models/ViewAssetsModel.swift +++ b/ReusEd/Models/ViewAssetsModel.swift @@ -9,7 +9,10 @@ import Foundation import SwiftUI import PersonalizationKit import OnBoardingKit -struct ViewAssets: PersonalizationAssets, OnBoardingAssets { +import LessonKit +import CourseCompletionKit + +struct ViewAssets: PersonalizationAssets, OnBoardingAssets, VideoLessonAssets, TextLessonAssets, QuizLessonAssets, CourseCompletionAssets { var titleFont: String var descriptionFont: String var mainTextColor: UIColor @@ -24,10 +27,10 @@ struct ViewAssets: PersonalizationAssets, OnBoardingAssets { var borderColor: UIColor var completeProgressColor: UIColor var pinkAccentColor: UIColor - var successMain: Color - var successLighter: Color - var errorMain: Color - var errorLighter: Color + var successMain: UIColor + var successLighter: UIColor + var errorMain: UIColor + var errorLighter: UIColor /// icons var timeImage: String var filterButtonImage: String @@ -75,10 +78,10 @@ var viewAssets = ViewAssets( borderColor: #colorLiteral(red: 0.9450980392, green: 0.9450980392, blue: 0.9529411765, alpha: 1), completeProgressColor: #colorLiteral(red: 0.1254901961, green: 0.7490196078, blue: 0.3333333333, alpha: 1), pinkAccentColor: #colorLiteral(red: 0.8784313725, green: 0.4470588235, blue: 0.6431372549, alpha: 1), - successMain: Color(#colorLiteral(red: 0.09219645709, green: 0.7787792087, blue: 0.4071886837, alpha: 1)), - successLighter: Color(#colorLiteral(red: 0.8235294118, green: 0.9490196078, blue: 0.8666666667, alpha: 1)), - errorMain: Color(#colorLiteral(red: 0.8392156863, green: 0.2509803922, blue: 0.2705882353, alpha: 1)), - errorLighter: Color(#colorLiteral(red: 0.968627451, green: 0.8509803922, blue: 0.8549019608, alpha: 1)), + successMain: #colorLiteral(red: 0.09219645709, green: 0.7787792087, blue: 0.4071886837, alpha: 1), + successLighter: #colorLiteral(red: 0.8235294118, green: 0.9490196078, blue: 0.8666666667, alpha: 1), + errorMain: #colorLiteral(red: 0.8392156863, green: 0.2509803922, blue: 0.2705882353, alpha: 1), + errorLighter: #colorLiteral(red: 0.968627451, green: 0.8509803922, blue: 0.8549019608, alpha: 1), timeImage: "timer", filterButtonImage: "filter", authorIcon: "author", diff --git a/ReusEd/Resources/courses.json b/ReusEd/Resources/courses.json index e97918f..128bef2 100644 --- a/ReusEd/Resources/courses.json +++ b/ReusEd/Resources/courses.json @@ -44,7 +44,7 @@ "id": 4, "title": "Section 4 - Final Quiz", "lessons": [ - 6,5 + 5 ] } ] diff --git a/ReusEd/Resources/lessons.json b/ReusEd/Resources/lessons.json index 0377cbc..72af7f8 100644 --- a/ReusEd/Resources/lessons.json +++ b/ReusEd/Resources/lessons.json @@ -235,7 +235,7 @@ }, { "id": 6, - "type": "quiz", + "type": "finalQuiz", "title": "Quiz", "description": "Solve the quiz to test your knowledge!", "quizData": { diff --git a/ReusEd/Views/Home/CourseContentViews/CompleteCourseView.swift b/ReusEd/Views/Home/CourseContentViews/CompleteCourseView.swift index 2f80e39..5157936 100644 --- a/ReusEd/Views/Home/CourseContentViews/CompleteCourseView.swift +++ b/ReusEd/Views/Home/CourseContentViews/CompleteCourseView.swift @@ -1,171 +1,172 @@ +//// +//// CompleteCourseView.swift +//// ReusEd +//// +//// Created by Anna Dluzhinskaya on 21.06.2022. +//// // -// CompleteCourseView.swift -// ReusEd +//import SwiftUI +// +//struct CompleteCourseView: View { +// var settings: ViewAssets +// var courseTitle: String +// var completionRate: Double +// var numPoints: Int +// +// var body: some View { +// VStack(alignment: .center, spacing: 30) { +// +// Image(viewAssets.completeCourseIcon) +// .padding(.top, 30) +// +// Text("Congratulations!") +// .font(.custom(settings.titleFont, size: 20)) +// .foregroundColor(Color(settings.mainTextColor)) +// +// Group { +// Text("You have successfully complete ") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.descriptionTextColor)) + +// +// Text(String(courseTitle)) +// .font(.custom(settings.titleFont, size: 14)) +// .foregroundColor(Color(settings.primaryColor)) + +// +// Text(". Complete more course like this to earn more points.") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.descriptionTextColor)) +// }.multilineTextAlignment(.center) +// .fixedSize(horizontal: false, vertical: true) +// .padding(.horizontal, 20) +// +// +// +// HStack { +// VStack(alignment: .leading, spacing: 10) { +// +// HStack(alignment: .firstTextBaseline) { +// StarsView(color: Color(viewAssets.primaryColor), rating: Float(completionRate)) +// Text(String(completionRate)) +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.primaryColor)) +// } +// +// Text("Completion Rate") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.mainTextColor)) +// +// }.frame(width: UIScreen.main.bounds.width/2 - 10, height: UIScreen.main.bounds.height/8) +// +// Divider() +// .frame(height: UIScreen.main.bounds.height/20) +// +// VStack(alignment: .leading, spacing: 10) { +// +// Text(String(numPoints) + " Points") +// .font(.custom(settings.titleFont, size: 20)) +// .foregroundColor(Color(settings.primaryColor)) +// +// Text("Scores Earned") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.mainTextColor)) +// +// }.frame(width: UIScreen.main.bounds.width/2 - 10, height: UIScreen.main.bounds.height/8) +// }.fixedSize() +// +// Spacer() +// +// Button( +// action: { +// NavigationUtil.popToRootView() +// }, label: { +// Text("Done") +// .font(Font.custom(settings.titleFont, size: 16)) +// .frame(width: UIScreen.main.bounds.width - 60, height: 50, alignment: .center) +// .background(Color(settings.primaryColor)) +// .accentColor(Color(settings.buttonTextColor)) +// .cornerRadius(UIScreen.main.bounds.width/35) +// .padding(.bottom, UIScreen.main.bounds.height/30) +// } +// ) +// +// }.padding() +// .navigationBarHidden(true) +// } +//} +// +//struct CompleteCourseView_Previews: PreviewProvider { +// static var previews: some View { +// CompleteCourseView(settings: viewAssets, courseTitle: "Python Programming", completionRate: 4.5, numPoints: 32) +// } +//} +// +// +// +//struct StarsView: View { +// private static let MAXRATING: Float = 5 +// var color: Color +// var rating: Float +// +// private let fullCount: Int +// private let emptyCount: Int +// private let halfFullCount: Int +// +// init(color: Color, rating: Float) { +// self.color = color +// self.rating = rating +// fullCount = Int(rating) +// emptyCount = Int(StarsView.MAXRATING - rating) +// halfFullCount = (Float(fullCount + emptyCount) < StarsView.MAXRATING) ? 1 : 0 +// } +// +// var body: some View { +// HStack(spacing: 2) { +// ForEach(0.. UINavigationController? { - guard let viewController = viewController else { - return nil - } - - if let navigationController = viewController as? UINavigationController { - return navigationController - } - - for childViewController in viewController.children { - return findNavigationController(viewController: childViewController) - } - - return nil - } -} +//struct NavigationUtil { +// static func popToRootView() { +// findNavigationController(viewController: UIApplication.shared.windows.filter { $0.isKeyWindow }.first?.rootViewController)? +// .popToRootViewController(animated: true) +// } +// +// static func findNavigationController(viewController: UIViewController?) -> UINavigationController? { +// guard let viewController = viewController else { +// return nil +// } +// +// if let navigationController = viewController as? UINavigationController { +// return navigationController +// } +// +// for childViewController in viewController.children { +// return findNavigationController(viewController: childViewController) +// } +// +// return nil +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/CourseDetailSectionCellView.swift b/ReusEd/Views/Home/CourseContentViews/CourseDetailSectionCellView.swift index fb7479e..18ee143 100644 --- a/ReusEd/Views/Home/CourseContentViews/CourseDetailSectionCellView.swift +++ b/ReusEd/Views/Home/CourseContentViews/CourseDetailSectionCellView.swift @@ -6,6 +6,8 @@ // import SwiftUI +import LessonKit +import CourseCompletionKit struct CourseDetailSectionCellView: View { var settings: ViewAssets @@ -13,7 +15,9 @@ struct CourseDetailSectionCellView: View { @State var courseId: Int @Binding var showAlert: Bool @Binding var progress: Double + @StateObject var lessonViewModel: LessonViewModel = LessonViewModel() @ObservedObject var coursesViewModel: CoursesViewModel + @State var numPoints: Int = 0 var body: some View { HStack { @@ -28,18 +32,18 @@ struct CourseDetailSectionCellView: View { ) ) { lesson in if lesson.type == "text" { - NavigationLink(destination: TextImageLessonView(settings: settings, textLesson: lesson, coursesViewModel: coursesViewModel)) { + NavigationLink(destination: TextImageLessonView(settings: settings, jsonName: "lessons", lessonId: lesson.id, lessonViewModel: lessonViewModel)) { CourseDetailTopicCellView(lesson: lesson, settings: settings, coursesViewModel: coursesViewModel) .padding(.vertical, 10) } } else if lesson.type == "video"{ - NavigationLink(destination: VideoLessonView(settings: settings, videoLesson: lesson, coursesViewModel: coursesViewModel)) { + NavigationLink(destination: VideoLessonView(settings: settings, jsonName: "lessons", lessonId: lesson.id, lessonViewModel: lessonViewModel)) { CourseDetailTopicCellView(lesson: lesson, settings: settings, coursesViewModel: coursesViewModel) .padding(.vertical, 10) } } else if lesson.type == "finalQuiz"{ - NavigationLink(destination: QuizView(settings: settings, lesson: lesson, coursesViewModel: coursesViewModel, courseId: courseId)) { + NavigationLink(destination: QuizView(settings: settings, jsonName: "lessons", lessonId: lesson.id, lessonViewModel: lessonViewModel, nextView: CompleteCourseView(settings: settings, courseTitle: coursesViewModel.courses[courseId-1].title, completionRate: $progress, numPoints: $numPoints), numPoints: $numPoints)) { CourseDetailTopicCellView(lesson: lesson, settings: settings, coursesViewModel: coursesViewModel) .padding(.vertical, 10) @@ -50,7 +54,7 @@ struct CourseDetailSectionCellView: View { } } } else { - NavigationLink(destination: QuizView(settings: settings, lesson: lesson, coursesViewModel: coursesViewModel, courseId: courseId)) { + NavigationLink(destination: QuizView(settings: settings, jsonName: "lessons", lessonId: lesson.id, lessonViewModel: lessonViewModel, nextView: EmptyView(), numPoints: $numPoints)) { CourseDetailTopicCellView(lesson: lesson, settings: settings, coursesViewModel: coursesViewModel) .padding(.vertical, 10) @@ -62,6 +66,8 @@ struct CourseDetailSectionCellView: View { } Spacer() + }.onAppear { + self.numPoints = 0 } } } diff --git a/ReusEd/Views/Home/CourseContentViews/CourseDetailView.swift b/ReusEd/Views/Home/CourseContentViews/CourseDetailView.swift index 5e6634a..981944e 100644 --- a/ReusEd/Views/Home/CourseContentViews/CourseDetailView.swift +++ b/ReusEd/Views/Home/CourseContentViews/CourseDetailView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import LessonKit struct CourseDetailView: View { @State var course: Course @@ -124,22 +125,6 @@ struct CourseDetailMainView: View { progress: $progress, coursesViewModel: coursesViewModel) } - - self.progress > 0.9 ? - NavigationLink(destination: CompleteCourseView(settings: settings, courseTitle: course.title, completionRate: (self.progress * 500).rounded()/100, numPoints: 15), label: { - Text("Finish Course") - .font(Font.custom(settings.titleFont, size: 16)) - .frame(width: UIScreen.main.bounds.width - 60, height: 50, alignment: .center) - .background(Color(settings.primaryColor)) - .accentColor(Color(settings.buttonTextColor)) - .cornerRadius(UIScreen.main.bounds.width/35) - .padding(.leading, UIScreen.main.bounds.width/40) - - }) : nil - - - - } Spacer() } diff --git a/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizAlertView.swift b/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizAlertView.swift index bab2823..6b6a93a 100644 --- a/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizAlertView.swift +++ b/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizAlertView.swift @@ -1,54 +1,54 @@ +//// +//// QuizAlertView.swift +//// ReusEd +//// +//// Created by Anna Dluzhinskaya on 29.06.2022. +//// // -// QuizAlertView.swift -// ReusEd +//import SwiftUI // -// Created by Anna Dluzhinskaya on 29.06.2022. -// - -import SwiftUI - -struct QuizAlertView: View { - var settings: ViewAssets - @Binding var showAlert: Bool - var body: some View { - ZStack { - Image(settings.quizPopup) - .scaledToFit() - VStack(alignment: .center, spacing: 18) { - Image(settings.quizPopupImage) - Text("Opps, Wait a sec!") - .font(.custom(settings.titleFont, size: 16)) - .foregroundColor(Color(settings.mainTextColor)) - Group { - Text("You can not pass the quiz before you complete at least ") - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.descriptionTextColor)) - + - Text("80% of the course. ") - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.primaryColor)) - + - Text("Go back and learn a little more and come take quiz.") - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.descriptionTextColor)) - }.multilineTextAlignment(.center) - .fixedSize(horizontal: false, vertical: true) - - Button( - action: { - showAlert.toggle() - }, label: { - Text("Go Back to Course") - .font(Font.custom(settings.titleFont, size: 14)) - .frame(width: UIScreen.main.bounds.height/2.5 - 60, height: 45, alignment: .center) - .background(Color(settings.primaryColor)) - .accentColor(Color(settings.buttonTextColor)) - .cornerRadius(UIScreen.main.bounds.width/35) - .padding(.bottom, UIScreen.main.bounds.height/30) - } - ) - - }.padding(.horizontal, UIScreen.main.bounds.width/10) - }.frame(width: UIScreen.main.bounds.height/2.5, height: UIScreen.main.bounds.height/2.5, alignment: .center) - } -} +//struct QuizAlertView: View { +// var settings: ViewAssets +// @Binding var showAlert: Bool +// var body: some View { +// ZStack { +// Image(settings.quizPopup) +// .scaledToFit() +// VStack(alignment: .center, spacing: 18) { +// Image(settings.quizPopupImage) +// Text("Opps, Wait a sec!") +// .font(.custom(settings.titleFont, size: 16)) +// .foregroundColor(Color(settings.mainTextColor)) +// Group { +// Text("You can not pass the quiz before you complete at least ") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.descriptionTextColor)) +// + +// Text("80% of the course. ") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.primaryColor)) +// + +// Text("Go back and learn a little more and come take quiz.") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.descriptionTextColor)) +// }.multilineTextAlignment(.center) +// .fixedSize(horizontal: false, vertical: true) +// +// Button( +// action: { +// showAlert.toggle() +// }, label: { +// Text("Go Back to Course") +// .font(Font.custom(settings.titleFont, size: 14)) +// .frame(width: UIScreen.main.bounds.height/2.5 - 60, height: 45, alignment: .center) +// .background(Color(settings.primaryColor)) +// .accentColor(Color(settings.buttonTextColor)) +// .cornerRadius(UIScreen.main.bounds.width/35) +// .padding(.bottom, UIScreen.main.bounds.height/30) +// } +// ) +// +// }.padding(.horizontal, UIScreen.main.bounds.width/10) +// }.frame(width: UIScreen.main.bounds.height/2.5, height: UIScreen.main.bounds.height/2.5, alignment: .center) +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizQuestionView.swift b/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizQuestionView.swift index 529ff9e..c6dd85a 100644 --- a/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizQuestionView.swift +++ b/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizQuestionView.swift @@ -1,219 +1,219 @@ +//// +//// QuizQuestionView.swift +//// ReusEd +//// +//// Created by Ahror Jabborov on 6/28/22. +//// // -// QuizQuestionView.swift -// ReusEd +//import SwiftUI // -// Created by Ahror Jabborov on 6/28/22. +//struct QuizQuestionView: View { +// var settings: ViewAssets +// var quizQuestions: [QuizQuestion] +// @State var currentQuestion: QuizQuestion +// @State var questionCounter: Int = 0 +// @State var showResult: Bool = false +// @State var isFinished: Bool = false +// @State var hasSelectedAnswer: Bool = false +// @State var chosenAnswer: String = "" +// @State var score: Int = 0 +// @ObservedObject var coursesViewModel: CoursesViewModel +// var courseId: Int +// var lessonId: Int +// @Environment(\.presentationMode) var presentationMode +// var body: some View { +// VStack(alignment: .center) { +// HStack { +// Button { +// // save progress +// print("ON X \(Double(questionCounter) / Double(quizQuestions.count))") +// +// coursesViewModel.saveLessonProgress(userId: 1, lessonId: lessonId, progress: (Double(questionCounter) / Double(quizQuestions.count))) +// presentationMode.wrappedValue.dismiss() +// } label: { +// Image(viewAssets.cross) +// } // - -import SwiftUI - -struct QuizQuestionView: View { - var settings: ViewAssets - var quizQuestions: [QuizQuestion] - @State var currentQuestion: QuizQuestion - @State var questionCounter: Int = 0 - @State var showResult: Bool = false - @State var isFinished: Bool = false - @State var hasSelectedAnswer: Bool = false - @State var chosenAnswer: String = "" - @State var score: Int = 0 - @ObservedObject var coursesViewModel: CoursesViewModel - var courseId: Int - var lessonId: Int - @Environment(\.presentationMode) var presentationMode - var body: some View { - VStack(alignment: .center) { - HStack { - Button { - // save progress - print("ON X \(Double(questionCounter) / Double(quizQuestions.count))") - - coursesViewModel.saveLessonProgress(userId: 1, lessonId: lessonId, progress: (Double(questionCounter) / Double(quizQuestions.count))) - presentationMode.wrappedValue.dismiss() - } label: { - Image(viewAssets.cross) - } - - ProgressView(value: Double(self.questionCounter + 1), total: Double(quizQuestions.count)) - .accentColor( Color(settings.primaryColor)) - .padding(.horizontal, 20) - HStack { - Image(viewAssets.asteriks) - Text("\(currentQuestion.points)") - .font(.custom(settings.titleFont, size: 14)) - .foregroundColor(.white) - } - .padding(.vertical, 5) - .padding(.horizontal, 10) - .background(Color(settings.pinkAccentColor)) - .clipShape(Capsule()) - } - - HStack { - Text("Question \(currentQuestion.id + 1) of \(quizQuestions.count)") - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.detailsTextColor)) - .padding(.top, 10) - Spacer() - } - - Text(currentQuestion.questionContent.question) - .font(.custom(settings.titleFont, size: 16)) - .foregroundColor(Color(settings.mainTextColor)) - .padding(.top, 10) - .multilineTextAlignment(.leading) - - VStack { - SingleChoiceButtonList( - settings: settings, - answers: currentQuestion.questionContent.answers!, - correctAnswer: currentQuestion.questionContent.correctAnswer, chosenAnswer: $chosenAnswer, - showResult: showResult, - hasSelectedAnswer: $hasSelectedAnswer - ) - } - .disabled(showResult ? true : false) - - Spacer() - NavigationLink( - isActive: $isFinished, - destination: { - CompleteCourseView( - settings: settings, - courseTitle: coursesViewModel.getCourseNameFromId(courseId: courseId), - completionRate: ((coursesViewModel.saveCourseProgress(userId: 1, courseId: courseId) * 100).rounded() * 5) / 100, - numPoints: score - ) - }, - label: { - Button( - action: { - if hasSelectedAnswer { - if showResult { - if self.questionCounter == quizQuestions.count - 1 { - self.isFinished = true - coursesViewModel.saveLessonProgress(userId: 1, lessonId: lessonId, progress: 1.0) - // save progress - } else { - self.questionCounter += 1 - self.currentQuestion = quizQuestions[questionCounter] - self.showResult = false - self.hasSelectedAnswer = false - } - } else { - updateScore() - self.showResult = true - } - } - }, label: { - Text(showResult ? (questionCounter == quizQuestions.count - 1 ? "Finish Attempt" : "Next Question") : "Check Answer") - .font(Font.custom(viewAssets.titleFont, size: 16)) - .frame(width: UIScreen.main.bounds.width - 60, height: 50, alignment: .center) - .background(Color(viewAssets.primaryColor)) - .accentColor(Color(viewAssets.buttonTextColor)) - .cornerRadius(UIScreen.main.bounds.width/35) - .padding(.bottom, UIScreen.main.bounds.height/30) - } - ) - } - ) - } - .padding(.horizontal, 20) - .onAppear { - questionCounter = Int((coursesViewModel.getLessonProgress(userId: 1, lessonId: lessonId) * Double(quizQuestions.count)).rounded()) % quizQuestions.count - print(questionCounter) -// 0.0 -> 0 -// 0.33 -> 1 -// 0.66 -> 2 -// 1.0 -> 0 - - - currentQuestion = quizQuestions[questionCounter] - } - .navigationBarHidden(true) - } - - func updateScore() { - for answer in currentQuestion.questionContent.correctAnswer where chosenAnswer == answer { - self.score += currentQuestion.points - } - print(score) - } -} - - - -struct SingleChoiceButtonList: View { - var settings: ViewAssets - let answers: [String] - let correctAnswer: [String] - @Binding var chosenAnswer: String - var showResult: Bool - @Binding var hasSelectedAnswer: Bool - - var body: some View { - ScrollView { - ForEach(answers, id: \.self) { answer in - SingleChoiceButtonRow( - settings: settings, - answer: answer, - tapAction: { - hasSelectedAnswer = true - self.chosenAnswer = answer - }, - chosen: chosenAnswer == answer, - showResult: self.showResult, - isCorrect: self.isCorrect(answer: answer)) - - } - .padding(0) - } - .onAppear { - hasSelectedAnswer = false - } - } - - func isCorrect(answer: String) -> Bool { - for ans in self.correctAnswer where answer == ans { - return true - } - return false - } -} - -struct SingleChoiceButtonRow: View { - var settings: ViewAssets - let answer: String - let tapAction: () -> Void - let chosen: Bool - let showResult: Bool - let isCorrect: Bool - - var body: some View { - Button( - action: { - tapAction() - }, label: { - HStack { - Text(answer) - .font(.custom(settings.titleFont, size: 16)) - .foregroundColor(chosen ? Color(settings.primaryColor) : .black) - .padding(.leading, 20) - Spacer() - } - .frame(width: UIScreen.main.bounds.width - 60, height: 66, alignment: .leading) - - .overlay(RoundedRectangle(cornerRadius: 12) - .stroke( - showResult ? (isCorrect ? settings.successMain : (chosen ? settings.errorMain : Color(settings.borderColor))) : - (chosen ? Color(settings.primaryColor) : Color(settings.borderColor)), lineWidth: 2)) - - .background( - showResult ? (isCorrect ? settings.successLighter : (chosen ? settings.errorLighter : .white)) : (chosen ? Color(settings.primaryLighterColor) : .white)) - - } - ) - .cornerRadius(12) - .padding(.top, 10) - } -} +// ProgressView(value: Double(self.questionCounter + 1), total: Double(quizQuestions.count)) +// .accentColor( Color(settings.primaryColor)) +// .padding(.horizontal, 20) +// HStack { +// Image(viewAssets.asteriks) +// Text("\(currentQuestion.points)") +// .font(.custom(settings.titleFont, size: 14)) +// .foregroundColor(.white) +// } +// .padding(.vertical, 5) +// .padding(.horizontal, 10) +// .background(Color(settings.pinkAccentColor)) +// .clipShape(Capsule()) +// } +// +// HStack { +// Text("Question \(currentQuestion.id + 1) of \(quizQuestions.count)") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.detailsTextColor)) +// .padding(.top, 10) +// Spacer() +// } +// +// Text(currentQuestion.questionContent.question) +// .font(.custom(settings.titleFont, size: 16)) +// .foregroundColor(Color(settings.mainTextColor)) +// .padding(.top, 10) +// .multilineTextAlignment(.leading) +// +// VStack { +// SingleChoiceButtonList( +// settings: settings, +// answers: currentQuestion.questionContent.answers!, +// correctAnswer: currentQuestion.questionContent.correctAnswer, chosenAnswer: $chosenAnswer, +// showResult: showResult, +// hasSelectedAnswer: $hasSelectedAnswer +// ) +// } +// .disabled(showResult ? true : false) +// +// Spacer() +// NavigationLink( +// isActive: $isFinished, +// destination: { +// CompleteCourseView( +// settings: settings, +// courseTitle: coursesViewModel.getCourseNameFromId(courseId: courseId), +// completionRate: ((coursesViewModel.saveCourseProgress(userId: 1, courseId: courseId) * 100).rounded() * 5) / 100, +// numPoints: score +// ) +// }, +// label: { +// Button( +// action: { +// if hasSelectedAnswer { +// if showResult { +// if self.questionCounter == quizQuestions.count - 1 { +// self.isFinished = true +// coursesViewModel.saveLessonProgress(userId: 1, lessonId: lessonId, progress: 1.0) +// // save progress +// } else { +// self.questionCounter += 1 +// self.currentQuestion = quizQuestions[questionCounter] +// self.showResult = false +// self.hasSelectedAnswer = false +// } +// } else { +// updateScore() +// self.showResult = true +// } +// } +// }, label: { +// Text(showResult ? (questionCounter == quizQuestions.count - 1 ? "Finish Attempt" : "Next Question") : "Check Answer") +// .font(Font.custom(viewAssets.titleFont, size: 16)) +// .frame(width: UIScreen.main.bounds.width - 60, height: 50, alignment: .center) +// .background(Color(viewAssets.primaryColor)) +// .accentColor(Color(viewAssets.buttonTextColor)) +// .cornerRadius(UIScreen.main.bounds.width/35) +// .padding(.bottom, UIScreen.main.bounds.height/30) +// } +// ) +// } +// ) +// } +// .padding(.horizontal, 20) +// .onAppear { +// questionCounter = Int((coursesViewModel.getLessonProgress(userId: 1, lessonId: lessonId) * Double(quizQuestions.count)).rounded()) % quizQuestions.count +// print(questionCounter) +//// 0.0 -> 0 +//// 0.33 -> 1 +//// 0.66 -> 2 +//// 1.0 -> 0 +// +// +// currentQuestion = quizQuestions[questionCounter] +// } +// .navigationBarHidden(true) +// } +// +// func updateScore() { +// for answer in currentQuestion.questionContent.correctAnswer where chosenAnswer == answer { +// self.score += currentQuestion.points +// } +// print(score) +// } +//} +// +// +// +//struct SingleChoiceButtonList: View { +// var settings: ViewAssets +// let answers: [String] +// let correctAnswer: [String] +// @Binding var chosenAnswer: String +// var showResult: Bool +// @Binding var hasSelectedAnswer: Bool +// +// var body: some View { +// ScrollView { +// ForEach(answers, id: \.self) { answer in +// SingleChoiceButtonRow( +// settings: settings, +// answer: answer, +// tapAction: { +// hasSelectedAnswer = true +// self.chosenAnswer = answer +// }, +// chosen: chosenAnswer == answer, +// showResult: self.showResult, +// isCorrect: self.isCorrect(answer: answer)) +// +// } +// .padding(0) +// } +// .onAppear { +// hasSelectedAnswer = false +// } +// } +// +// func isCorrect(answer: String) -> Bool { +// for ans in self.correctAnswer where answer == ans { +// return true +// } +// return false +// } +//} +// +//struct SingleChoiceButtonRow: View { +// var settings: ViewAssets +// let answer: String +// let tapAction: () -> Void +// let chosen: Bool +// let showResult: Bool +// let isCorrect: Bool +// +// var body: some View { +// Button( +// action: { +// tapAction() +// }, label: { +// HStack { +// Text(answer) +// .font(.custom(settings.titleFont, size: 16)) +// .foregroundColor(chosen ? Color(settings.primaryColor) : .black) +// .padding(.leading, 20) +// Spacer() +// } +// .frame(width: UIScreen.main.bounds.width - 60, height: 66, alignment: .leading) +// +// .overlay(RoundedRectangle(cornerRadius: 12) +// .stroke( +// showResult ? (isCorrect ? Color(settings.successMain) : (chosen ? Color(settings.errorMain) : Color(settings.borderColor))) : +// (chosen ? Color(settings.primaryColor) : Color(settings.borderColor)), lineWidth: 2)) +// +// .background( +// showResult ? (isCorrect ? Color(settings.successLighter) : (chosen ? Color(settings.errorLighter) : .white)) : (chosen ? Color(settings.primaryLighterColor) : .white)) +// +// } +// ) +// .cornerRadius(12) +// .padding(.top, 10) +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizView.swift b/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizView.swift index f03323a..ad4e35a 100644 --- a/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizView.swift +++ b/ReusEd/Views/Home/CourseContentViews/QuizLessons/QuizView.swift @@ -1,119 +1,119 @@ +//// +//// QuizView.swift +//// ReusEd +//// +//// Created by Ahror Jabborov on 6/28/22. +//// // -// QuizView.swift -// ReusEd +//import SwiftUI // -// Created by Ahror Jabborov on 6/28/22. -// - -import SwiftUI - -struct QuizView: View { - - var settings: ViewAssets - var lesson: Lesson - @ObservedObject var coursesViewModel: CoursesViewModel - var courseId: Int - var courseProgress: Double = 0.0 - var body: some View { - VStack(alignment: .center, spacing: 30) { - ZStack(alignment: .center) { - Image(viewAssets.quizHeader) - .resizable() - .scaledToFit() - - Text(lesson.title) - .font(.custom(settings.titleFont, size: 18)) - .foregroundColor(Color(settings.buttonTextColor)) - .padding(.top) - } - - Text(lesson.quizData!.title) - .font(.custom(settings.titleFont, size: 20)) - .foregroundColor(Color(settings.primaryColor)) - - ZStack { - RoundedRectangle(cornerRadius: 15) - .foregroundColor(Color(settings.borderColor)) - HStack { - HStack { - Spacer() - - Image(viewAssets.questionMark) - Text(String(lesson.quizData!.quizQuestions.count)+" Questions") - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.mainTextColor)) - - Spacer() - } - - Divider() - .frame(height: UIScreen.main.bounds.height/15 - 15, alignment: .center) - - HStack { - Spacer() - - Image(viewAssets.asteriksCircle) - Text(String(coursesViewModel.getQuizPoints(lessonId: lesson.id))+" Points") - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.mainTextColor)) - - Spacer() - } - } - }.frame(width: UIScreen.main.bounds.width-40, height: UIScreen.main.bounds.height/15, alignment: .center) - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("DESCRIPTION") - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.descriptionTextColor)) - - Text(lesson.quizData!.description) - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.mainTextColor)) - - Text("QUESTIONS & TOPICS") - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.descriptionTextColor)) - - - VStack(alignment: .leading, spacing: 15) { - ForEach(lesson.quizData!.quizQuestions) { question in - HStack { - Text("\u{2022}") - .foregroundColor(Color(settings.mainTextColor)) - - Text(String(question.id + 1)) - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.primaryColor)) - - Text(": "+question.questionContent.topic) - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.mainTextColor)) - } - } - } - - }.padding(.horizontal) - } - - NavigationLink(destination: QuizQuestionView( - settings: settings, - quizQuestions: lesson.quizData!.quizQuestions, - currentQuestion: lesson.quizData!.quizQuestions[0], - coursesViewModel: coursesViewModel, - courseId: courseId, - lessonId: lesson.id - ), label: { - Text("Start Attempt") - .font(Font.custom(settings.titleFont, size: 16)) - .frame(width: UIScreen.main.bounds.width - 60, height: 50, alignment: .center) - .background(Color(settings.primaryColor)) - .foregroundColor(Color(settings.buttonTextColor)) - .cornerRadius(UIScreen.main.bounds.width/35) - .padding(.bottom, UIScreen.main.bounds.height/10) - }) - - - }.ignoresSafeArea() - } -} +//struct QuizView: View { +// +// var settings: ViewAssets +// var lesson: Lesson +// @ObservedObject var coursesViewModel: CoursesViewModel +// var courseId: Int +// var courseProgress: Double = 0.0 +// var body: some View { +// VStack(alignment: .center, spacing: 30) { +// ZStack(alignment: .center) { +// Image(viewAssets.quizHeader) +// .resizable() +// .scaledToFit() +// +// Text(lesson.title) +// .font(.custom(settings.titleFont, size: 18)) +// .foregroundColor(Color(settings.buttonTextColor)) +// .padding(.top) +// } +// +// Text(lesson.quizData!.title) +// .font(.custom(settings.titleFont, size: 20)) +// .foregroundColor(Color(settings.primaryColor)) +// +// ZStack { +// RoundedRectangle(cornerRadius: 15) +// .foregroundColor(Color(settings.borderColor)) +// HStack { +// HStack { +// Spacer() +// +// Image(viewAssets.questionMark) +// Text(String(lesson.quizData!.quizQuestions.count)+" Questions") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.mainTextColor)) +// +// Spacer() +// } +// +// Divider() +// .frame(height: UIScreen.main.bounds.height/15 - 15, alignment: .center) +// +// HStack { +// Spacer() +// +// Image(viewAssets.asteriksCircle) +// Text(String(coursesViewModel.getQuizPoints(lessonId: lesson.id))+" Points") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.mainTextColor)) +// +// Spacer() +// } +// } +// }.frame(width: UIScreen.main.bounds.width-40, height: UIScreen.main.bounds.height/15, alignment: .center) +// ScrollView { +// VStack(alignment: .leading, spacing: 20) { +// Text("DESCRIPTION") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.descriptionTextColor)) +// +// Text(lesson.quizData!.description) +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.mainTextColor)) +// +// Text("QUESTIONS & TOPICS") +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.descriptionTextColor)) +// +// +// VStack(alignment: .leading, spacing: 15) { +// ForEach(lesson.quizData!.quizQuestions) { question in +// HStack { +// Text("\u{2022}") +// .foregroundColor(Color(settings.mainTextColor)) +// +// Text(String(question.id + 1)) +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.primaryColor)) +// +// Text(": "+question.questionContent.topic) +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.mainTextColor)) +// } +// } +// } +// +// }.padding(.horizontal) +// } +// +// NavigationLink(destination: QuizQuestionView( +// settings: settings, +// quizQuestions: lesson.quizData!.quizQuestions, +// currentQuestion: lesson.quizData!.quizQuestions[0], +// coursesViewModel: coursesViewModel, +// courseId: courseId, +// lessonId: lesson.id +// ), label: { +// Text("Start Attempt") +// .font(Font.custom(settings.titleFont, size: 16)) +// .frame(width: UIScreen.main.bounds.width - 60, height: 50, alignment: .center) +// .background(Color(settings.primaryColor)) +// .foregroundColor(Color(settings.buttonTextColor)) +// .cornerRadius(UIScreen.main.bounds.width/35) +// .padding(.bottom, UIScreen.main.bounds.height/10) +// }) +// +// +// }.ignoresSafeArea() +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageLessonSectionView.swift b/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageLessonSectionView.swift index 054f887..a1e6b0f 100644 --- a/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageLessonSectionView.swift +++ b/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageLessonSectionView.swift @@ -1,25 +1,25 @@ +//// +//// TextImageLessonSection.swift +//// ReusEd +//// +//// Created by Ahror Jabborov on 6/16/22. +//// // -// TextImageLessonSection.swift -// ReusEd +//import SwiftUI // -// Created by Ahror Jabborov on 6/16/22. -// - -import SwiftUI - -struct TextImageLessonSectionView: View { - var settings: ViewAssets - @State var section: TextLessonSection - var body: some View { - VStack(alignment: .leading) { - Text(section.title) - .font(.custom(settings.titleFont, size: 16)) - .padding(.bottom, 1) - - ForEach(section.data) { data in - TextImageView(settings: settings, textImage: data) - } - } - .padding(.bottom, 30) - } -} +//struct TextImageLessonSectionView: View { +// var settings: ViewAssets +// @State var section: TextLessonSection +// var body: some View { +// VStack(alignment: .leading) { +// Text(section.title) +// .font(.custom(settings.titleFont, size: 16)) +// .padding(.bottom, 1) +// +// ForEach(section.data) { data in +// TextImageView(settings: settings, textImage: data) +// } +// } +// .padding(.bottom, 30) +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageLessonView.swift b/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageLessonView.swift index 0df924c..47e5a40 100644 --- a/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageLessonView.swift +++ b/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageLessonView.swift @@ -1,128 +1,128 @@ +//// +//// TextImageLessonView.swift +//// ReusEd +//// +//// Created by Ahror Jabborov on 6/16/22. +//// // -// TextImageLessonView.swift -// ReusEd +//import SwiftUI // -// Created by Ahror Jabborov on 6/16/22. +//struct TextImageLessonView: View { +// var settings: ViewAssets +// var textLesson: Lesson +// @ObservedObject var coursesViewModel: CoursesViewModel +// @State private var scrollViewHeight: CGFloat = 0 +// @State private var proportion: CGFloat = 0 +// var body: some View { +// ScrollView(.vertical, showsIndicators: false) { +// VStack { +// Text(textLesson.description!) +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.descriptionTextColor)) +// .multilineTextAlignment(.leading) +// HStack { +// Image(viewAssets.durationOffIcon) +// +// Text(textLesson.duration!) +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.detailsTextColor)) +// .padding(.leading, 10) +// Spacer() +// } +// .padding(.leading, 20) +// +// VStack { +// ForEach(textLesson.sections!) { section in +// TextImageLessonSectionView(settings: settings, section: section) +// } +// +// +// LessonFooterView(settings: settings) +// .padding(.leading, 8) +// }.navigationTitle(textLesson.title) +// .navigationBarTitleDisplayMode(.inline) +// .padding(.horizontal, 20) +// } +// .background( +// GeometryReader { geo in +// let scrollLength = geo.size.height - scrollViewHeight +// let rawProportion = -geo.frame(in: .named("scroll")).minY / scrollLength +// let proportion = min(max(rawProportion, 0), 1) +// +// Color.clear +// .preference( +// key: ScrollProportion.self, +// value: proportion +// ) +// .onPreferenceChange(ScrollProportion.self) { proportion in +// self.proportion = proportion +// +// } +// } +// ) +// +// } +// .onWillDisappear { +// coursesViewModel.saveLessonProgress(userId: 1, lessonId: self.textLesson.id, progress: self.proportion) +// } +// .background( +// GeometryReader { geo in +// Color.clear.onAppear { +// scrollViewHeight = geo.size.height +// } +// } +// ) +// .coordinateSpace(name: "scroll") +// } +//} // - -import SwiftUI - -struct TextImageLessonView: View { - var settings: ViewAssets - var textLesson: Lesson - @ObservedObject var coursesViewModel: CoursesViewModel - @State private var scrollViewHeight: CGFloat = 0 - @State private var proportion: CGFloat = 0 - var body: some View { - ScrollView(.vertical, showsIndicators: false) { - VStack { - Text(textLesson.description!) - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.descriptionTextColor)) - .multilineTextAlignment(.leading) - HStack { - Image(viewAssets.durationOffIcon) - - Text(textLesson.duration!) - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.detailsTextColor)) - .padding(.leading, 10) - Spacer() - } - .padding(.leading, 20) - - VStack { - ForEach(textLesson.sections!) { section in - TextImageLessonSectionView(settings: settings, section: section) - } - - - LessonFooterView(settings: settings) - .padding(.leading, 8) - }.navigationTitle(textLesson.title) - .navigationBarTitleDisplayMode(.inline) - .padding(.horizontal, 20) - } - .background( - GeometryReader { geo in - let scrollLength = geo.size.height - scrollViewHeight - let rawProportion = -geo.frame(in: .named("scroll")).minY / scrollLength - let proportion = min(max(rawProportion, 0), 1) - - Color.clear - .preference( - key: ScrollProportion.self, - value: proportion - ) - .onPreferenceChange(ScrollProportion.self) { proportion in - self.proportion = proportion - - } - } - ) - - } - .onWillDisappear { - coursesViewModel.saveLessonProgress(userId: 1, lessonId: self.textLesson.id, progress: self.proportion) - } - .background( - GeometryReader { geo in - Color.clear.onAppear { - scrollViewHeight = geo.size.height - } - } - ) - .coordinateSpace(name: "scroll") - } -} - - -struct WillDisappearHandler: UIViewControllerRepresentable { - func makeCoordinator() -> WillDisappearHandler.Coordinator { - Coordinator(onWillDisappear: onWillDisappear) - } - - let onWillDisappear: () -> Void - - func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIViewController { - context.coordinator - } - - func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext) { - } - - typealias UIViewControllerType = UIViewController - - class Coordinator: UIViewController { - let onWillDisappear: () -> Void - - init(onWillDisappear: @escaping () -> Void) { - self.onWillDisappear = onWillDisappear - super.init(nibName: nil, bundle: nil) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - onWillDisappear() - } - } -} - -struct WillDisappearModifier: ViewModifier { - let callback: () -> Void - - func body(content: Content) -> some View { - content - .background(WillDisappearHandler(onWillDisappear: callback)) - } -} - -extension View { - func onWillDisappear(_ perform: @escaping () -> Void) -> some View { - self.modifier(WillDisappearModifier(callback: perform)) - } -} +// +//struct WillDisappearHandler: UIViewControllerRepresentable { +// func makeCoordinator() -> WillDisappearHandler.Coordinator { +// Coordinator(onWillDisappear: onWillDisappear) +// } +// +// let onWillDisappear: () -> Void +// +// func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIViewController { +// context.coordinator +// } +// +// func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext) { +// } +// +// typealias UIViewControllerType = UIViewController +// +// class Coordinator: UIViewController { +// let onWillDisappear: () -> Void +// +// init(onWillDisappear: @escaping () -> Void) { +// self.onWillDisappear = onWillDisappear +// super.init(nibName: nil, bundle: nil) +// } +// +// required init?(coder: NSCoder) { +// fatalError("init(coder:) has not been implemented") +// } +// +// override func viewWillDisappear(_ animated: Bool) { +// super.viewWillDisappear(animated) +// onWillDisappear() +// } +// } +//} +// +//struct WillDisappearModifier: ViewModifier { +// let callback: () -> Void +// +// func body(content: Content) -> some View { +// content +// .background(WillDisappearHandler(onWillDisappear: callback)) +// } +//} +// +//extension View { +// func onWillDisappear(_ perform: @escaping () -> Void) -> some View { +// self.modifier(WillDisappearModifier(callback: perform)) +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageView.swift b/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageView.swift index b247e58..d9e9342 100644 --- a/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageView.swift +++ b/ReusEd/Views/Home/CourseContentViews/TextImageLessons/TextImageView.swift @@ -1,30 +1,30 @@ +//// +//// TextImage.swift +//// ReusEd +//// +//// Created by Ahror Jabborov on 6/16/22. +//// // -// TextImage.swift -// ReusEd +//import SwiftUI // -// Created by Ahror Jabborov on 6/16/22. -// - -import SwiftUI - -struct TextImageView: View { - var settings: ViewAssets - var textImage: TextLessonData - - var body: some View { - VStack(alignment: .leading) { - if let text = textImage.text { - Text(text) - .font(.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.mainTextColor)) - .padding(.horizontal, 0) - .multilineTextAlignment(.leading) - } - if let image = textImage.image { - UrlImageView(urlString: image) -// .resizable() - .aspectRatio(contentMode: .fit) - } - } - } -} +//struct TextImageView: View { +// var settings: ViewAssets +// var textImage: TextLessonData +// +// var body: some View { +// VStack(alignment: .leading) { +// if let text = textImage.text { +// Text(text) +// .font(.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.mainTextColor)) +// .padding(.horizontal, 0) +// .multilineTextAlignment(.leading) +// } +// if let image = textImage.image { +// UrlImageView(urlString: image) +//// .resizable() +// .aspectRatio(contentMode: .fit) +// } +// } +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/VideoLessons/AutoRotateVideoPlayerView.swift b/ReusEd/Views/Home/CourseContentViews/VideoLessons/AutoRotateVideoPlayerView.swift index 07e6930..e981f99 100644 --- a/ReusEd/Views/Home/CourseContentViews/VideoLessons/AutoRotateVideoPlayerView.swift +++ b/ReusEd/Views/Home/CourseContentViews/VideoLessons/AutoRotateVideoPlayerView.swift @@ -1,73 +1,73 @@ +//// +//// AutoRotateVideoPlayerView.swift +//// ReusEd +//// +//// Created by Anna Dluzhinskaya on 16.06.2022. +//// // -// AutoRotateVideoPlayerView.swift -// ReusEd +//import SwiftUI +//import AVKit // -// Created by Anna Dluzhinskaya on 16.06.2022. +//struct AutoRotateVideoPlayerView: View { +// @State private var showFullScreen = false +// @Binding var player: AVPlayer +// var body: some View { +// playerView +// .ignoresSafeArea() +// .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in +// DispatchQueue.main.async { +// if UIDevice.current.orientation.isLandscape { +// self.showFullScreen = true +// } else { +// self.showFullScreen = false +// } +// } +// } +// } +// +// private var playerView: some View { +// showFullScreen ? +// AVPlayerControllerRepresentable(showFullScreen: true, player: player) : +// AVPlayerControllerRepresentable(showFullScreen: false, player: player) +// } +//} // - -import SwiftUI -import AVKit - -struct AutoRotateVideoPlayerView: View { - @State private var showFullScreen = false - @Binding var player: AVPlayer - var body: some View { - playerView - .ignoresSafeArea() - .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in - DispatchQueue.main.async { - if UIDevice.current.orientation.isLandscape { - self.showFullScreen = true - } else { - self.showFullScreen = false - } - } - } - } - - private var playerView: some View { - showFullScreen ? - AVPlayerControllerRepresentable(showFullScreen: true, player: player) : - AVPlayerControllerRepresentable(showFullScreen: false, player: player) - } -} - -struct AVPlayerControllerRepresentable: UIViewControllerRepresentable { - let showFullScreen: Bool - let player: AVPlayer - - func makeUIViewController(context: Context) -> AVPlayerViewController { - let controller = AVPlayerViewControllerRotatable() - controller.player = player - chooseScreenType(controller) - return controller - } - - func updateUIViewController(_ controller: AVPlayerViewController, context content: Context) { - chooseScreenType(controller) - } - - private func chooseScreenType(_ controller: AVPlayerViewController) { - showFullScreen ? controller.enterFullScreen(animated: true) : controller.exitFullScreen(animated: true) - - } - -} - -class AVPlayerViewControllerRotatable: AVPlayerViewController { - - override var shouldAutorotate: Bool { - return true - } - -} - -extension AVPlayerViewController { - func enterFullScreen(animated: Bool) { - perform(NSSelectorFromString("enterFullScreenAnimated:completionHandler:"), with: animated, with: nil) - } - - func exitFullScreen(animated: Bool) { - perform(NSSelectorFromString("exitFullScreenAnimated:completionHandler:"), with: animated, with: nil) - } -} +//struct AVPlayerControllerRepresentable: UIViewControllerRepresentable { +// let showFullScreen: Bool +// let player: AVPlayer +// +// func makeUIViewController(context: Context) -> AVPlayerViewController { +// let controller = AVPlayerViewControllerRotatable() +// controller.player = player +// chooseScreenType(controller) +// return controller +// } +// +// func updateUIViewController(_ controller: AVPlayerViewController, context content: Context) { +// chooseScreenType(controller) +// } +// +// private func chooseScreenType(_ controller: AVPlayerViewController) { +// showFullScreen ? controller.enterFullScreen(animated: true) : controller.exitFullScreen(animated: true) +// +// } +// +//} +// +//class AVPlayerViewControllerRotatable: AVPlayerViewController { +// +// override var shouldAutorotate: Bool { +// return true +// } +// +//} +// +//extension AVPlayerViewController { +// func enterFullScreen(animated: Bool) { +// perform(NSSelectorFromString("enterFullScreenAnimated:completionHandler:"), with: animated, with: nil) +// } +// +// func exitFullScreen(animated: Bool) { +// perform(NSSelectorFromString("exitFullScreenAnimated:completionHandler:"), with: animated, with: nil) +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoDescriptionView.swift b/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoDescriptionView.swift index faf2eae..b9b0084 100644 --- a/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoDescriptionView.swift +++ b/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoDescriptionView.swift @@ -1,34 +1,34 @@ +//// +//// VideoDescriptionView.swift +//// ReusEd +//// +//// Created by Anna Dluzhinskaya on 16.06.2022. +//// // -// VideoDescriptionView.swift -// ReusEd +//import SwiftUI // -// Created by Anna Dluzhinskaya on 16.06.2022. -// - -import SwiftUI - -struct VideoDescriptionView: View { - var settings: ViewAssets - var title: String - var durationImage: String - var duration: String - var description: String - var body: some View { - VStack(alignment: .leading, spacing: 20) { - Text(title) - .font(Font.custom(settings.titleFont, size: 18)) - .foregroundColor(Color(settings.mainTextColor)) - - HStack { - Image(durationImage) - Text(duration) - .font(Font.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.detailsTextColor)) - } - - Text(description) - .font(Font.custom(settings.descriptionFont, size: 14)) - .foregroundColor(Color(settings.descriptionTextColor)) - } - } -} +//struct VideoDescriptionView: View { +// var settings: ViewAssets +// var title: String +// var durationImage: String +// var duration: String +// var description: String +// var body: some View { +// VStack(alignment: .leading, spacing: 20) { +// Text(title) +// .font(Font.custom(settings.titleFont, size: 18)) +// .foregroundColor(Color(settings.mainTextColor)) +// +// HStack { +// Image(durationImage) +// Text(duration) +// .font(Font.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.detailsTextColor)) +// } +// +// Text(description) +// .font(Font.custom(settings.descriptionFont, size: 14)) +// .foregroundColor(Color(settings.descriptionTextColor)) +// } +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoLessonView.swift b/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoLessonView.swift index dfc51cd..b5af517 100644 --- a/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoLessonView.swift +++ b/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoLessonView.swift @@ -1,67 +1,67 @@ +//// +//// VideoLessonView.swift +//// ReusEd +//// +//// Created by Anna Dluzhinskaya on 15.06.2022. +//// // -// VideoLessonView.swift -// ReusEd -// -// Created by Anna Dluzhinskaya on 15.06.2022. -// - -import SwiftUI -import AVKit - -struct VideoLessonView: View { - var settings: ViewAssets - var videoLesson: Lesson - @ObservedObject var coursesViewModel: CoursesViewModel - - @State var player: AVPlayer - - init( settings: ViewAssets, videoLesson: Lesson, coursesViewModel: CoursesViewModel) { - self.settings = settings - self.videoLesson = videoLesson - self.player = AVPlayer(url: URL(string: videoLesson.url!)!) - self.coursesViewModel = coursesViewModel - } - - var body: some View { - VStack { - - AutoRotateVideoPlayerView(player: $player) - .onAppear { - DispatchQueue.main.async { - - let progress = coursesViewModel.getLessonProgress(userId: 1, lessonId: self.videoLesson.id) - - player.seek(to: CMTime(seconds: progress * CMTimeGetSeconds(player.currentItem!.asset.duration), preferredTimescale: player.currentTime().timescale)) - } - } - .onWillDisappear { - DispatchQueue.main.async { - coursesViewModel.saveLessonProgress(userId: 1, lessonId: self.videoLesson.id, progress: CMTimeGetSeconds(player.currentTime())/CMTimeGetSeconds(player.currentItem!.asset.duration)) - - } - } - - - ScrollView(.vertical, showsIndicators: false) { - VStack(alignment: .leading, spacing: 20) { - - VideoDescriptionView(settings: settings, - title: videoLesson.title, - durationImage: viewAssets.timeImage, - duration: videoLesson.duration!, - description: videoLesson.description!) - - VideoStampsIView(settings: settings, - stamps: videoLesson.stamps!, - player: $player) - - LessonFooterView(settings: settings) - .padding(.leading, 8) - - - }.padding() - } - - } - } -} +//import SwiftUI +//import AVKit +// +//struct VideoLessonView: View { +// var settings: ViewAssets +// var videoLesson: Lesson +// @ObservedObject var coursesViewModel: CoursesViewModel +// +// @State var player: AVPlayer +// +// init( settings: ViewAssets, videoLesson: Lesson, coursesViewModel: CoursesViewModel) { +// self.settings = settings +// self.videoLesson = videoLesson +// self.player = AVPlayer(url: URL(string: videoLesson.url!)!) +// self.coursesViewModel = coursesViewModel +// } +// +// var body: some View { +// VStack { +// +// AutoRotateVideoPlayerView(player: $player) +// .onAppear { +// DispatchQueue.main.async { +// +// let progress = coursesViewModel.getLessonProgress(userId: 1, lessonId: self.videoLesson.id) +// +// player.seek(to: CMTime(seconds: progress * CMTimeGetSeconds(player.currentItem!.asset.duration), preferredTimescale: player.currentTime().timescale)) +// } +// } +// .onWillDisappear { +// DispatchQueue.main.async { +// coursesViewModel.saveLessonProgress(userId: 1, lessonId: self.videoLesson.id, progress: CMTimeGetSeconds(player.currentTime())/CMTimeGetSeconds(player.currentItem!.asset.duration)) +// +// } +// } +// +// +// ScrollView(.vertical, showsIndicators: false) { +// VStack(alignment: .leading, spacing: 20) { +// +// VideoDescriptionView(settings: settings, +// title: videoLesson.title, +// durationImage: viewAssets.timeImage, +// duration: videoLesson.duration!, +// description: videoLesson.description!) +// +// VideoStampsIView(settings: settings, +// stamps: videoLesson.stamps!, +// player: $player) +// +// LessonFooterView(settings: settings) +// .padding(.leading, 8) +// +// +// }.padding() +// } +// +// } +// } +//} diff --git a/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoStampsIView.swift b/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoStampsIView.swift index a46b841..567b656 100644 --- a/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoStampsIView.swift +++ b/ReusEd/Views/Home/CourseContentViews/VideoLessons/VideoStampsIView.swift @@ -1,48 +1,48 @@ +//// +//// VideoStampsIView.swift +//// ReusEd +//// +//// Created by Anna Dluzhinskaya on 16.06.2022. +//// // -// VideoStampsIView.swift -// ReusEd +//import SwiftUI +//import AVKit // -// Created by Anna Dluzhinskaya on 16.06.2022. +//struct VideoStampsIView: View { +// var settings: ViewAssets +// var stamps: [VideoLessonStamp] +// @Binding var player: AVPlayer +// var body: some View { +// VStack(alignment: .leading, spacing: 10) { +// HStack(alignment: .firstTextBaseline) { +// Text("Video Stamps") +// .font(Font.custom(settings.titleFont, size: 18)) +// .foregroundColor(Color(settings.mainTextColor)) +// Text("- Click to watch directly") +// .font(Font.custom(settings.descriptionFont, size: 12)) +// .foregroundColor(Color(settings.detailsTextColor)) +// } // - -import SwiftUI -import AVKit - -struct VideoStampsIView: View { - var settings: ViewAssets - var stamps: [VideoLessonStamp] - @Binding var player: AVPlayer - var body: some View { - VStack(alignment: .leading, spacing: 10) { - HStack(alignment: .firstTextBaseline) { - Text("Video Stamps") - .font(Font.custom(settings.titleFont, size: 18)) - .foregroundColor(Color(settings.mainTextColor)) - Text("- Click to watch directly") - .font(Font.custom(settings.descriptionFont, size: 12)) - .foregroundColor(Color(settings.detailsTextColor)) - } - - ForEach(0..