diff --git a/Core/Core/Assets.xcassets/CourseDates/Contents.json b/Core/Core/Assets.xcassets/CourseDates/Contents.json
new file mode 100644
index 000000000..73c00596a
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Core/Core/Assets.xcassets/CourseDates/assignment_icon.imageset/Contents.json b/Core/Core/Assets.xcassets/CourseDates/assignment_icon.imageset/Contents.json
new file mode 100644
index 000000000..40941b157
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/assignment_icon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "edit_square.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Core/Core/Assets.xcassets/CourseDates/assignment_icon.imageset/edit_square.svg b/Core/Core/Assets.xcassets/CourseDates/assignment_icon.imageset/edit_square.svg
new file mode 100644
index 000000000..0fd888059
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/assignment_icon.imageset/edit_square.svg
@@ -0,0 +1,3 @@
+
diff --git a/Core/Core/Assets.xcassets/CourseDates/calendar_icon.imageset/Contents.json b/Core/Core/Assets.xcassets/CourseDates/calendar_icon.imageset/Contents.json
new file mode 100644
index 000000000..2a14fd4fa
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/calendar_icon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "calender_icon.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Core/Core/Assets.xcassets/CourseDates/calendar_icon.imageset/calender_icon.svg b/Core/Core/Assets.xcassets/CourseDates/calendar_icon.imageset/calender_icon.svg
new file mode 100644
index 000000000..e0cdf5f31
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/calendar_icon.imageset/calender_icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/Core/Core/Assets.xcassets/CourseDates/certificate_icon.imageset/Contents.json b/Core/Core/Assets.xcassets/CourseDates/certificate_icon.imageset/Contents.json
new file mode 100644
index 000000000..47d94b155
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/certificate_icon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "certificate_icon.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Core/Core/Assets.xcassets/CourseDates/certificate_icon.imageset/certificate_icon.svg b/Core/Core/Assets.xcassets/CourseDates/certificate_icon.imageset/certificate_icon.svg
new file mode 100644
index 000000000..532dd1baf
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/certificate_icon.imageset/certificate_icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/Core/Core/Assets.xcassets/CourseDates/lock_icon.imageset/Contents.json b/Core/Core/Assets.xcassets/CourseDates/lock_icon.imageset/Contents.json
new file mode 100644
index 000000000..f94ec1e8c
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/lock_icon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "lock_icon.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Core/Core/Assets.xcassets/CourseDates/lock_icon.imageset/lock_icon.svg b/Core/Core/Assets.xcassets/CourseDates/lock_icon.imageset/lock_icon.svg
new file mode 100644
index 000000000..823dd2e69
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/lock_icon.imageset/lock_icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/Core/Core/Assets.xcassets/CourseDates/lock_with_watch_icon.imageset/Contents.json b/Core/Core/Assets.xcassets/CourseDates/lock_with_watch_icon.imageset/Contents.json
new file mode 100644
index 000000000..705033805
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/lock_with_watch_icon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "locked.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Core/Core/Assets.xcassets/CourseDates/lock_with_watch_icon.imageset/locked.svg b/Core/Core/Assets.xcassets/CourseDates/lock_with_watch_icon.imageset/locked.svg
new file mode 100644
index 000000000..bebb2111f
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/lock_with_watch_icon.imageset/locked.svg
@@ -0,0 +1,4 @@
+
diff --git a/Core/Core/Assets.xcassets/CourseDates/school_cap_icon.imageset/Contents.json b/Core/Core/Assets.xcassets/CourseDates/school_cap_icon.imageset/Contents.json
new file mode 100644
index 000000000..f31579037
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/school_cap_icon.imageset/Contents.json
@@ -0,0 +1,15 @@
+{
+ "images" : [
+ {
+ "filename" : "school_cap_icon.svg",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+}
diff --git a/Core/Core/Assets.xcassets/CourseDates/school_cap_icon.imageset/school_cap_icon.svg b/Core/Core/Assets.xcassets/CourseDates/school_cap_icon.imageset/school_cap_icon.svg
new file mode 100644
index 000000000..4636ce2fd
--- /dev/null
+++ b/Core/Core/Assets.xcassets/CourseDates/school_cap_icon.imageset/school_cap_icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/Core/Core/Extensions/DateExtension.swift b/Core/Core/Extensions/DateExtension.swift
index 362a3dc33..36f93d5ee 100644
--- a/Core/Core/Extensions/DateExtension.swift
+++ b/Core/Core/Extensions/DateExtension.swift
@@ -9,12 +9,18 @@ import Foundation
public extension Date {
init(iso8601: String) {
- let date: Date
+ let formats = ["yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ"]
+ var date: Date
var dateFormatter: DateFormatter?
dateFormatter = DateFormatter()
- dateFormatter?.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatter?.locale = Locale(identifier: "en_US_POSIX")
- date = dateFormatter?.date(from: iso8601) ?? Date()
+
+ date = formats.compactMap { format in
+ dateFormatter?.dateFormat = format
+ return dateFormatter?.date(from: iso8601)
+ }
+ .first ?? Date()
+
defer {
dateFormatter = nil
}
@@ -26,7 +32,7 @@ public extension Date {
formatter.locale = .current
formatter.unitsStyle = .full
formatter.locale = Locale(identifier: "en_US_POSIX")
- if self.description == Date().description {
+ if description == Date().description {
return CoreLocalization.Date.justNow
} else {
return formatter.localizedString(for: self, relativeTo: Date())
@@ -104,7 +110,7 @@ public extension Date {
case .iso8601:
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
case .shortWeekdayMonthDayYear:
- dateFormatter.dateFormat = "EEE, MMM d, yyyy"
+ applyShortWeekdayMonthDayYear(dateFormatter: dateFormatter)
}
let date = dateFormatter.string(from: self)
@@ -124,7 +130,7 @@ public extension Date {
let days = Calendar.current.dateComponents([.day], from: self, to: Date())
if let day = days.day {
if day < 2 {
- return self.timeAgoDisplay()
+ return timeAgoDisplay()
} else {
return date
}
@@ -134,7 +140,57 @@ public extension Date {
case .iso8601:
return date
case .shortWeekdayMonthDayYear:
- return date
+ return getShortWeekdayMonthDayYear(dateFormatterString: date)
+ }
+ }
+
+ private func applyShortWeekdayMonthDayYear(dateFormatter: DateFormatter) {
+ if isCurrentYear() {
+ let days = Calendar.current.dateComponents([.day], from: self, to: Date())
+ if let day = days.day, (-6 ... -2).contains(day) {
+ dateFormatter.dateFormat = "EEEE"
+ } else {
+ dateFormatter.dateFormat = "MMMM d"
+ }
+ } else {
+ dateFormatter.dateFormat = "MMMM d, yyyy"
}
}
+
+ private func getShortWeekdayMonthDayYear(dateFormatterString: String) -> String {
+ let days = Calendar.current.dateComponents([.day], from: self, to: Date())
+
+ if let day = days.day {
+ guard isCurrentYear() else {
+ // It's past year or future year
+ return dateFormatterString
+ }
+
+ switch day {
+ case -6...(-2):
+ return dateFormatterString
+ case 2...6:
+ return timeAgoDisplay()
+ case -1:
+ return CoreLocalization.CourseDates.tomorrow
+ case 1:
+ return CoreLocalization.CourseDates.yesterday
+ default:
+ if day > 6 || day < -6 {
+ return dateFormatterString
+ } else {
+ // It means, date is in hours past due or upcoming
+ return timeAgoDisplay()
+ }
+ }
+ } else {
+ return dateFormatterString
+ }
+ }
+
+ func isCurrentYear() -> Bool {
+ let selfYear = Calendar.current.component(.year, from: self)
+ let runningYear = Calendar.current.component(.year, from: Date())
+ return selfYear == runningYear
+ }
}
diff --git a/Core/Core/SwiftGen/Assets.swift b/Core/Core/SwiftGen/Assets.swift
index 202ab2639..1d1c84625 100644
--- a/Core/Core/SwiftGen/Assets.swift
+++ b/Core/Core/SwiftGen/Assets.swift
@@ -28,6 +28,12 @@ public enum CoreAssets {
public static let facebookButtonColor = ColorAsset(name: "FacebookButtonColor")
public static let googleButtonColor = ColorAsset(name: "GoogleButtonColor")
public static let microsoftButtonColor = ColorAsset(name: "MicrosoftButtonColor")
+ public static let assignmentIcon = ImageAsset(name: "assignment_icon")
+ public static let calendarIcon = ImageAsset(name: "calendar_icon")
+ public static let certificateIcon = ImageAsset(name: "certificate_icon")
+ public static let lockIcon = ImageAsset(name: "lock_icon")
+ public static let lockWithWatchIcon = ImageAsset(name: "lock_with_watch_icon")
+ public static let schoolCapIcon = ImageAsset(name: "school_cap_icon")
public static let bookCircle = ImageAsset(name: "book.circle")
public static let bubbleLeftCircle = ImageAsset(name: "bubble.left.circle")
public static let docCircle = ImageAsset(name: "doc.circle")
diff --git a/Core/Core/SwiftGen/Strings.swift b/Core/Core/SwiftGen/Strings.swift
index 71a71130f..dad529b53 100644
--- a/Core/Core/SwiftGen/Strings.swift
+++ b/Core/Core/SwiftGen/Strings.swift
@@ -63,14 +63,22 @@ public enum CoreLocalization {
public static let completed = CoreLocalization.tr("Localizable", "COURSE_DATES.COMPLETED", fallback: "Completed")
/// Due next
public static let dueNext = CoreLocalization.tr("Localizable", "COURSE_DATES.DUE_NEXT", fallback: "Due next")
+ /// Item Hidden
+ public static let itemHidden = CoreLocalization.tr("Localizable", "COURSE_DATES.ITEM_HIDDEN", fallback: "Item Hidden")
+ /// Items Hidden
+ public static let itemsHidden = CoreLocalization.tr("Localizable", "COURSE_DATES.ITEMS_HIDDEN", fallback: "Items Hidden")
/// Past due
public static let pastDue = CoreLocalization.tr("Localizable", "COURSE_DATES.PAST_DUE", fallback: "Past due")
/// Today
public static let today = CoreLocalization.tr("Localizable", "COURSE_DATES.TODAY", fallback: "Today")
+ /// Tomorrow
+ public static let tomorrow = CoreLocalization.tr("Localizable", "COURSE_DATES.TOMORROW", fallback: "Tomorrow")
/// Unreleased
public static let unreleased = CoreLocalization.tr("Localizable", "COURSE_DATES.UNRELEASED", fallback: "Unreleased")
/// Verified Only
public static let verifiedOnly = CoreLocalization.tr("Localizable", "COURSE_DATES.VERIFIED_ONLY", fallback: "Verified Only")
+ /// Yesterday
+ public static let yesterday = CoreLocalization.tr("Localizable", "COURSE_DATES.YESTERDAY", fallback: "Yesterday")
}
public enum Date {
/// Ended
diff --git a/Core/Core/en.lproj/Localizable.strings b/Core/Core/en.lproj/Localizable.strings
index 673144473..a132e9445 100644
--- a/Core/Core/en.lproj/Localizable.strings
+++ b/Core/Core/en.lproj/Localizable.strings
@@ -94,6 +94,10 @@
"COURSE_DATES.DUE_NEXT" = "Due next";
"COURSE_DATES.UNRELEASED" = "Unreleased";
"COURSE_DATES.VERIFIED_ONLY" = "Verified Only";
+"COURSE_DATES.TOMORROW" = "Tomorrow";
+"COURSE_DATES.YESTERDAY" = "Yesterday";
+"COURSE_DATES.ITEMS_HIDDEN" = "Items Hidden";
+"COURSE_DATES.ITEM_HIDDEN" = "Item Hidden";
"SOCIAL_SIGN_CANCELED" = "The user canceled the sign-in flow.";
diff --git a/Core/Core/uk.lproj/Localizable.strings b/Core/Core/uk.lproj/Localizable.strings
index ab592e519..f5763d308 100644
--- a/Core/Core/uk.lproj/Localizable.strings
+++ b/Core/Core/uk.lproj/Localizable.strings
@@ -94,6 +94,10 @@
"COURSE_DATES.DUE_NEXT" = "Due next";
"COURSE_DATES.UNRELEASED" = "Unreleased";
"COURSE_DATES.VERIFIED_ONLY" = "Verified Only";
+"COURSE_DATES.TOMORROW" = "Tomorrow";
+"COURSE_DATES.YESTERDAY" = "Yesterday";
+"COURSE_DATES.ITEMS_HIDDEN" = "Items Hidden";
+"COURSE_DATES.ITEM_HIDDEN" = "Item Hidden";
"SOCIAL_SIGN_CANCELED" = "The user canceled the sign-in flow.";
"AUTHORIZATION_FAILED" = "Authorization failed.";
diff --git a/Course/Course.xcodeproj/project.pbxproj b/Course/Course.xcodeproj/project.pbxproj
index d408ec8e0..38f92443f 100644
--- a/Course/Course.xcodeproj/project.pbxproj
+++ b/Course/Course.xcodeproj/project.pbxproj
@@ -64,6 +64,8 @@
0766DFCE299AB26D00EBEF6A /* EncodedVideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0766DFCD299AB26D00EBEF6A /* EncodedVideoPlayer.swift */; };
0766DFD0299AB29000EBEF6A /* PlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0766DFCF299AB29000EBEF6A /* PlayerViewController.swift */; };
197FB8EA8F92F00A8F383D82 /* Pods_App_Course.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E795BD160CDA7D9C120DE6 /* Pods_App_Course.framework */; };
+ 975F475E2B6151FD00E5B031 /* CourseDatesMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975F475D2B6151FD00E5B031 /* CourseDatesMock.swift */; };
+ 975F47602B615DA700E5B031 /* CourseStructureMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 975F475F2B615DA700E5B031 /* CourseStructureMock.swift */; };
B8F50317B6B830A0E520C954 /* Pods_App_Course_CourseTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50E59D2B81E12610964282C5 /* Pods_App_Course_CourseTests.framework */; };
BAAD62C82AFD00EE000E6103 /* CourseExpandableContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAAD62C72AFD00EE000E6103 /* CourseExpandableContentView.swift */; };
DB205BFB2AE81B1200136EC2 /* CourseDateViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB205BFA2AE81B1200136EC2 /* CourseDateViewModelTests.swift */; };
@@ -154,6 +156,8 @@
600A464AEDA7BEFEC1A7FE99 /* Pods-App-Course-CourseTests.debugdev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Course-CourseTests.debugdev.xcconfig"; path = "Target Support Files/Pods-App-Course-CourseTests/Pods-App-Course-CourseTests.debugdev.xcconfig"; sourceTree = ""; };
69A261790A0B4C724CCFA4F2 /* Pods-App-CourseDetails.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-CourseDetails.release.xcconfig"; path = "Target Support Files/Pods-App-CourseDetails/Pods-App-CourseDetails.release.xcconfig"; sourceTree = ""; };
831B08139890634968EDD44D /* Pods-App-Course-CourseTests.debugstage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Course-CourseTests.debugstage.xcconfig"; path = "Target Support Files/Pods-App-Course-CourseTests/Pods-App-Course-CourseTests.debugstage.xcconfig"; sourceTree = ""; };
+ 975F475D2B6151FD00E5B031 /* CourseDatesMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDatesMock.swift; sourceTree = ""; };
+ 975F475F2B615DA700E5B031 /* CourseStructureMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseStructureMock.swift; sourceTree = ""; };
99AEF08FD75F1509863D3302 /* Pods-App-CourseDetails.debugprod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-CourseDetails.debugprod.xcconfig"; path = "Target Support Files/Pods-App-CourseDetails/Pods-App-CourseDetails.debugprod.xcconfig"; sourceTree = ""; };
9B5D3D31A9CFA08B6C4347BD /* Pods-App-CourseDetails.releasedev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-CourseDetails.releasedev.xcconfig"; path = "Target Support Files/Pods-App-CourseDetails/Pods-App-CourseDetails.releasedev.xcconfig"; sourceTree = ""; };
A47C63D9EB0D866F303D4588 /* Pods-App-Course.releasestage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Course.releasestage.xcconfig"; path = "Target Support Files/Pods-App-Course/Pods-App-Course.releasestage.xcconfig"; sourceTree = ""; };
@@ -286,6 +290,7 @@
0208666A29CC6D8000BC05B2 /* Persistence */,
02B6B3BF28E1DB8800232911 /* Model */,
02B6B3B928E1D13500232911 /* Network */,
+ 975F475C2B61517A00E5B031 /* Mock */,
02B6B3BB28E1D14F00232911 /* CourseRepository.swift */,
);
path = Data;
@@ -446,6 +451,15 @@
path = Unit;
sourceTree = "";
};
+ 975F475C2B61517A00E5B031 /* Mock */ = {
+ isa = PBXGroup;
+ children = (
+ 975F475D2B6151FD00E5B031 /* CourseDatesMock.swift */,
+ 975F475F2B615DA700E5B031 /* CourseStructureMock.swift */,
+ );
+ path = Mock;
+ sourceTree = "";
+ };
D52670044E8768425E23C627 /* Pods */ = {
isa = PBXGroup;
children = (
@@ -712,7 +726,9 @@
02B6B3BC28E1D14F00232911 /* CourseRepository.swift in Sources */,
02280F60294B50030032823A /* CoursePersistenceProtocol.swift in Sources */,
02454CAA2A2619B40043052A /* LessonProgressView.swift in Sources */,
+ 975F475E2B6151FD00E5B031 /* CourseDatesMock.swift in Sources */,
DB7D6EB22ADFE9510036BB13 /* Data_CourseDates.swift in Sources */,
+ 975F47602B615DA700E5B031 /* CourseStructureMock.swift in Sources */,
02280F5E294B4FDA0032823A /* CourseCoreModel.xcdatamodeld in Sources */,
0766DFCE299AB26D00EBEF6A /* EncodedVideoPlayer.swift in Sources */,
0276D75B29DDA3890004CDF8 /* Data_ResumeBlock.swift in Sources */,
diff --git a/Course/Course/Data/CourseRepository.swift b/Course/Course/Data/CourseRepository.swift
index 7a154fa0e..df55aec12 100644
--- a/Course/Course/Data/CourseRepository.swift
+++ b/Course/Course/Data/CourseRepository.swift
@@ -209,7 +209,6 @@ public class CourseRepository: CourseRepositoryProtocol {
}
// Mark - For testing and SwiftUI preview
-// swiftlint:disable all
#if DEBUG
class CourseRepositoryMock: CourseRepositoryProtocol {
func getCourseDatesOffline(courseID: String) async throws -> CourseDates {
@@ -230,7 +229,8 @@ class CourseRepositoryMock: CourseRepositoryProtocol {
func getCourseDates(courseID: String) async throws -> CourseDates {
do {
- let courseDates = try courseDatesJSON.data(using: .utf8)!.mapResponse(DataLayer.CourseDates.self)
+ let courseDates = try
+ CourseRepository.courseDatesJSON.data(using: .utf8)!.mapResponse(DataLayer.CourseDates.self)
return courseDates.domain
} catch {
throw error
@@ -239,14 +239,15 @@ class CourseRepositoryMock: CourseRepositoryProtocol {
func getLoadedCourseBlocks(courseID: String) throws -> CourseStructure {
let decoder = JSONDecoder()
- let jsonData = Data(courseStructureJson.utf8)
+ let jsonData = Data(CourseRepository.courseStructureJson.utf8)
let courseBlocks = try decoder.decode(DataLayer.CourseStructure.self, from: jsonData)
return parseCourseStructure(course: courseBlocks)
}
public func getCourseBlocks(courseID: String) async throws -> CourseStructure {
do {
- let courseBlocks = try courseStructureJson.data(using: .utf8)!.mapResponse(DataLayer.CourseStructure.self)
+ let courseBlocks = try
+ CourseRepository.courseStructureJson.data(using: .utf8)!.mapResponse(DataLayer.CourseStructure.self)
return parseCourseStructure(course: courseBlocks)
} catch {
throw error
@@ -378,995 +379,5 @@ And there are various ways of describing it-- call it oral poetry or
videoUrl: block.userViewData?.encodedVideo?.fallback?.url,
youTubeUrl: block.userViewData?.encodedVideo?.youTube?.url)
}
-
- private let courseStructureJson: String = """
- {"root": "block-v1:QA+comparison+2022+type@course+block@course",
- "blocks": {
- "block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78": {
- "id": "block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78",
- "block_id": "be1704c576284ba39753c6f0ea4a4c78",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78",
- "type": "comparison",
- "display_name": "Comparison",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296": {
- "id": "block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296",
- "block_id": "93acc543871e4c73bc20a72a64e93296",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296",
- "type": "problem",
- "display_name": "Dropdown with Hints and Feedback",
- "graded": false,
- "student_view_multi_device": true,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b": {
- "id": "block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b",
- "block_id": "06c17035106e48328ebcd042babcf47b",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b",
- "type": "comparison",
- "display_name": "Comparison",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58": {
- "id": "block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58",
- "block_id": "c19e41b61db14efe9c45f1354332ae58",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58",
- "type": "problem",
- "display_name": "Text Input with Hints and Feedback",
- "graded": false,
- "student_view_multi_device": true,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb": {
- "id": "block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb",
- "block_id": "0d96732f577b4ff68799faf8235d1bfb",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb",
- "type": "problem",
- "display_name": "Numerical Input with Hints and Feedback",
- "graded": false,
- "student_view_multi_device": true,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96": {
- "id": "block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96",
- "block_id": "dd2e22fdf0724bd88c8b2e6b68dedd96",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96",
- "type": "problem",
- "display_name": "Blank Common Problem",
- "graded": false,
- "student_view_multi_device": true,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd": {
- "id": "block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd",
- "block_id": "d1e091aa305741c5bedfafed0d269efd",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd",
- "type": "problem",
- "display_name": "Blank Common Problem",
- "graded": false,
- "student_view_multi_device": true,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7": {
- "id": "block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7",
- "block_id": "23e10dea806345b19b77997b4fc0eea7",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7",
- "type": "comparison",
- "display_name": "Comparison",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904": {
- "id": "block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904",
- "block_id": "29e7eddbe8964770896e4036748c9904",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904",
- "type": "vertical",
- "display_name": "Unit",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78",
- "block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296",
- "block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b",
- "block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58",
- "block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb",
- "block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96",
- "block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd",
- "block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6": {
- "id": "block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6",
- "block_id": "f468bb5c6e8641179e523c7fcec4e6d6",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6",
- "type": "sequential",
- "display_name": "Subsection",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234": {
- "id": "block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234",
- "block_id": "eaf91d8fc70547339402043ba1a1c234",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234",
- "type": "problem",
- "display_name": "Dropdown with Hints and Feedback",
- "graded": false,
- "student_view_multi_device": true,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751": {
- "id": "block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751",
- "block_id": "fac531c3f1f3400cb8e3b97eb2c3d751",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751",
- "type": "comparison",
- "display_name": "Comparison",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de": {
- "id": "block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de",
- "block_id": "74a1074024fe401ea305534f2241e5de",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de",
- "type": "html",
- "display_name": "Raw HTML",
- "graded": false,
- "student_view_data": {
- "last_modified": "2023-05-04T19:08:07Z",
- "html_data": "https://s3.eu-central-1.amazonaws.com/vso-dev-edx-sorage/htmlxblock/QA/comparison/html/74a1074024fe401ea305534f2241e5de/content_html.zip",
- "size": 576,
- "index_page": "index.html",
- "icon_class": "other"
- },
- "student_view_multi_device": true,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca": {
- "id": "block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca",
- "block_id": "e5b2e105f4f947c5b76fb12c35da1eca",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca",
- "type": "vertical",
- "display_name": "Unit",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234",
- "block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751",
- "block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2": {
- "id": "block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2",
- "block_id": "d37cb0c5c2d24ddaacf3494760a055f2",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2",
- "type": "sequential",
- "display_name": "Another one subsection",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846": {
- "id": "block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846",
- "block_id": "abecaefe203c4c93b441d16cea3b7846",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846",
- "type": "chapter",
- "display_name": "Section",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6",
- "block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de": {
- "id": "block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de",
- "block_id": "a0c3ac29daab425f92a34b34eb2af9de",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de",
- "type": "pdf",
- "display_name": "PDF title",
- "graded": false,
- "student_view_data": {
- "last_modified": "2023-04-26T08:43:45Z",
- "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
- },
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9": {
- "id": "block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9",
- "block_id": "bcd1b0f3015b4d3696b12f65a5d682f9",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9",
- "type": "pdf",
- "display_name": "PDF",
- "graded": false,
- "student_view_data": {
- "last_modified": "2023-04-26T08:43:45Z",
- "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
- },
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59": {
- "id": "block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59",
- "block_id": "67d805daade34bd4b6ace607e6d48f59",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59",
- "type": "pdf",
- "display_name": "PDF",
- "graded": false,
- "student_view_data": {
- "last_modified": "2023-04-26T08:43:45Z",
- "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
- },
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974": {
- "id": "block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974",
- "block_id": "828606a51f4e44198e92f86a45be7974",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974",
- "type": "pdf",
- "display_name": "PDF",
- "graded": false,
- "student_view_data": {
- "last_modified": "2023-04-26T08:43:45Z",
- "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
- },
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee": {
- "id": "block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee",
- "block_id": "8646c3bc2184467b86e5ef01ecd452ee",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee",
- "type": "pdf",
- "display_name": "PDF",
- "graded": false,
- "student_view_data": {
- "last_modified": "2023-04-26T08:43:45Z",
- "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
- },
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1": {
- "id": "block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1",
- "block_id": "e2faa0e62223489e91a41700865c5fc1",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1",
- "type": "vertical",
- "display_name": "Unit",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de",
- "block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9",
- "block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59",
- "block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974",
- "block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52": {
- "id": "block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52",
- "block_id": "0c5e89fa6d7a4fac8f7b26f2ca0bbe52",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52",
- "type": "problem",
- "display_name": "Checkboxes with Hints and Feedback",
- "graded": false,
- "student_view_multi_device": true,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4": {
- "id": "block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4",
- "block_id": "8ba437d8b20d416d91a2d362b0c940a4",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4",
- "type": "vertical",
- "display_name": "Unit",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d": {
- "id": "block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d",
- "block_id": "021f70794f7349998e190b060260b70d",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d",
- "type": "pdf",
- "display_name": "PDF",
- "graded": false,
- "student_view_data": {
- "last_modified": "2023-04-26T08:43:45Z",
- "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
- },
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ],
- "completion": 0.0
- },
- "block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1": {
- "id": "block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1",
- "block_id": "2c344115d3554ac58c140ec86e591aa1",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1",
- "type": "vertical",
- "display_name": "Unit",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe": {
- "id": "block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe",
- "block_id": "6c9c6ba663b54c0eb9cbdcd0c6b4bebe",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe",
- "type": "sequential",
- "display_name": "Subsection",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1",
- "block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4",
- "block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7": {
- "id": "block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7",
- "block_id": "d5a4f1f2f5314288aae400c270fb03f7",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7",
- "type": "chapter",
- "display_name": "PDF",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe"
- ],
- "completion": 0
- },
- "block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf": {
- "id": "block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf",
- "block_id": "7ab45affb80f4846a60648ec6aff9fbf",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf",
- "type": "chapter",
- "display_name": "Section",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
-
- ]
- },
- "block-v1:QA+comparison+2022+type@course+block@course": {
- "id": "block-v1:QA+comparison+2022+type@course+block@course",
- "block_id": "course",
- "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@course+block@course",
- "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@course+block@course?experience=legacy",
- "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@course+block@course",
- "type": "course",
- "display_name": "Comparison xblock test coursre",
- "graded": false,
- "student_view_multi_device": false,
- "block_counts": {
- "video": 0
- },
- "descendants": [
- "block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846",
- "block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7",
- "block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf"
- ],
- "completion": 0
- }
- },
- "id": "course-v1:QA+comparison+2022",
- "name": "Comparison xblock test coursre",
- "number": "comparison",
- "org": "QA",
- "start": "2022-01-01T00:00:00Z",
- "start_display": "01 january 2022 р.",
- "start_type": "timestamp",
- "end": null,
- "courseware_access": {
- "has_access": true,
- "error_code": null,
- "developer_message": null,
- "user_message": null,
- "additional_context_user_message": null,
- "user_fragment": null
- },
- "media": {
- "image": {
- "raw": "/asset-v1:QA+comparison+2022+type@asset+block@images_course_image.jpg",
- "small": "/asset-v1:QA+comparison+2022+type@asset+block@images_course_image.jpg",
- "large": "/asset-v1:QA+comparison+2022+type@asset+block@images_course_image.jpg"
- }
- },
- "certificate": {
-
- },
- "is_self_paced": false
- }
- """
-
- private let courseDatesJSON: String = """
- {
- "dates_banner_info": {
- "missed_deadlines": false,
- "content_type_gating_enabled": true,
- "missed_gated_content": false,
- "verified_upgrade_link": null
- },
- "course_date_blocks": [
- {
- "assignment_type": null,
- "complete": null,
- "date": "2023-08-30T15:00:00Z",
- "date_type": "course-start-date",
- "description": "",
- "learner_has_access": true,
- "link": "",
- "link_text": "",
- "title": "Course starts",
- "extra_info": null,
- "first_component_block_id": ""
- },
- {
- "assignment_type": "Problem Set",
- "complete": true,
- "date": "2023-09-14T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@ca19e125470846f2a36ad1225410e39a",
- "link_text": "",
- "title": "Problem Set 1",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@problem+block@bd89c1dd129240f99bb8c5cbe3f56530"
- },
- {
- "assignment_type": "Problem Set",
- "complete": false,
- "date": "2023-09-14T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "",
- "link_text": "",
- "title": "Problem Set 1.1",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@problem+block@bd89c1dd129240f99bb8c5cbe3f56530a"
- },
- {
- "assignment_type": "Problem Set",
- "complete": false,
- "date": "2023-09-21T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@e137765987514da7851a59dedeb5ecec",
- "link_text": "",
- "title": "Problem Set 2",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@html+block@c99e81ffff4546e28fecab0a0c381abd"
- },
- {
- "assignment_type": "Problem Set",
- "complete": true,
- "date": "2023-09-21T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@e137765987514da7851a59dedeb5ececc",
- "link_text": "",
- "title": "Problem Set 2.1",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@html+block@c99e81ffff4546e28fecab0a0c381abdc"
- },
- {
- "assignment_type": "Problem Set",
- "complete": false,
- "date": "2023-09-21T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": false,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@e137765987514da7851a59dedeb5ececcc",
- "link_text": "",
- "title": "Problem Set 2.2",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@html+block@c99e81ffff4546e28fecab0a0c381abdcc"
- },
- {
- "assignment_type": "Problem Set",
- "complete": false,
- "date": "2023-09-28T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@bfe9eb02884a4812883ff9e543887968",
- "link_text": "",
- "title": "Problem Set 3",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@html+block@5e117d71433647eaa6de63434641c011"
- },
- {
- "assignment_type": "Midterm",
- "complete": false,
- "date": "2023-10-04T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": false,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@bb284b9c4ff04091951f77b50e3b72f4",
- "link_text": "",
- "title": "Midterm Exam (time limit removed due to grader issues)",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@vertical+block@ec1c5d83de6244d38b1f3ff4d32b6e17"
- },
- {
- "assignment_type": "Problem Set",
- "complete": false,
- "date": "2023-10-12T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@64f4d344ecdc48d2bef514882e6236ab",
- "link_text": "",
- "title": "Problem Set 4",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@html+block@eeb64a67e52e4f3e80656b9233204f25"
- },
- {
- "assignment_type": "Problem Set",
- "complete": false,
- "date": "2023-10-19T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@79d22d4ab4f740158930fca4e80d67db",
- "link_text": "",
- "title": "Problem Set 5",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@html+block@3dde572871fc4b6ebdb47722a184a514"
- },
- {
- "assignment_type": "Problem Set",
- "complete": false,
- "date": "2023-10-26T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@3d419098708e4bcd9209ffa31a4cb3dc",
- "link_text": "",
- "title": "Problem Set 6",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@problem+block@9b2a0176bf6a4c21ad4a63c2fce2d0cb"
- },
- {
- "assignment_type": "Final Exam",
- "complete": false,
- "date": "2023-10-31T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": false,
- "link": "",
- "link_text": "",
- "title": "Final Exam (time limit removed due to grader issues)",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@vertical+block@e7b4f091d7ad457097d0bbda9d9af267"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@221a4c17dba341d6a970a0d80343253c",
- "link_text": "",
- "title": "1. Introduction to Python (TIME: 1:03:12)",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@ad9387910b7e47069c452efebd7b36dd"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@35f82f6c3ecb4e9e913dc279a9b73a9f",
- "link_text": "",
- "title": "2. Core Elements of Programs (TIME: 54:14)",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@8fb4fa767a204d41a6366c2bc53bea22"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@62f08cc899344863a1ab678aee506dec",
- "link_text": "",
- "title": "3. Simple Algorithms (TIME: 41:06)",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@1f2b055948c9467492649b59e24e8fdc"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@38007cdb67c44b46b124cdbce33510b5",
- "link_text": "",
- "title": "4. Functions (TIME: 1:08:06)",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@9dc4c11c46274b87964c7534b449d50a"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@01df98c1e74a459b8fb20d2d785622cd",
- "link_text": "",
- "title": "5. Tuples and Lists",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@3464df78190b43948ba0507ef4287290"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@8a590293a22e46dd9760ec917d122ec1",
- "link_text": "",
- "title": "6. Dictionaries",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@d2abc5b3db0d43ba90c5d3a25e95e2d5"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@78648402e8bf4738ade97101cc1ba263",
- "link_text": "",
- "title": "7. Testing and Debugging",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@dd0621fbfe594e789b187a1e4f8406eb"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@c81c3de20ec54c37a04a8b3d1806e82c",
- "link_text": "",
- "title": "8. Exceptions and Assertions",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@6038a1b2f8a340eb8cdb41c021d62234"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@37cb9a5012e443bbaa776a80afd9c87a",
- "link_text": "",
- "title": "9. Classes and Inheritance",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@b87e596b827142f09e9664fac3ab0be0"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@54cd6b1bbbbe40f294ac0b5664c03f1e",
- "link_text": "",
- "title": "10. An Extended Example",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@6bc79b1a29ac46a7857caa53a8e203d0"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@1334ab336b1b4458b5c2972c50e903b2",
- "link_text": "",
- "title": "11. Computational Complexity",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@be73e5a3ee7847d98805a257189b9fad"
- },
- {
- "assignment_type": "Finger Exercises",
- "complete": false,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "assignment-due-date",
- "description": "",
- "learner_has_access": true,
- "link": "https://courses.edx.org/courses/course-v1:MITx+6.00.1x+2T2023a/jump_to/block-v1:MITx+6.00.1x+2T2023a+type@sequential+block@a7387dbd3728491c8f834e29a73e0cf4",
- "link_text": "",
- "title": "12. Searching and Sorting Algorithms",
- "extra_info": null,
- "first_component_block_id": "block-v1:MITx+6.00.1x+2T2023a+type@video+block@fa7e29b3b95b4a3b963d1c5dfdd4e8f8"
- },
- {
- "assignment_type": null,
- "complete": null,
- "date": "2023-11-01T23:30:00Z",
- "date_type": "course-end-date",
- "description": "After the course ends, the course content will be archived and no longer active.",
- "learner_has_access": true,
- "link": "",
- "link_text": "",
- "title": "Course ends",
- "extra_info": null,
- "first_component_block_id": ""
- },
- {
- "assignment_type": null,
- "complete": null,
- "date": "2023-11-03T00:00:00Z",
- "date_type": "certificate-available-date",
- "description": "Day certificates will become available for passing verified learners.",
- "learner_has_access": true,
- "link": "",
- "link_text": "",
- "title": "Certificate Available",
- "extra_info": null,
- "first_component_block_id": ""
- },
- {
- "assignment_type": null,
- "complete": null,
- "date": "2023-11-23T12:34:28Z",
- "date_type": "course-expired-date",
- "description": "You lose all access to this course, including your progress.",
- "learner_has_access": true,
- "link": "",
- "link_text": "",
- "title": "Audit Access Expires",
- "extra_info": null,
- "first_component_block_id": ""
- }
- ],
- "has_ended": false,
- "learner_is_full_access": false,
- "user_timezone": null
- }
- """
}
#endif
-// swiftlint:enable all
diff --git a/Course/Course/Data/Mock/CourseDatesMock.swift b/Course/Course/Data/Mock/CourseDatesMock.swift
new file mode 100644
index 000000000..66dcce53c
--- /dev/null
+++ b/Course/Course/Data/Mock/CourseDatesMock.swift
@@ -0,0 +1,616 @@
+//
+// CourseDatesMock.swift
+// Course
+//
+// Created by Shafqat Muneer on 1/24/24.
+//
+
+import Foundation
+
+// Mark - For testing and SwiftUI preview
+// swiftlint:disable all
+#if DEBUG
+extension CourseRepository {
+ static let courseDatesJSON: String = """
+ {
+ "dates_banner_info": {
+ "missed_deadlines": true,
+ "content_type_gating_enabled": false,
+ "missed_gated_content": false,
+ "verified_upgrade_link": "https://ecommerce.edx.org/basket/add/?sku=87701A8"
+ },
+ "course_date_blocks": [
+ {
+ "assignment_type": null,
+ "complete": null,
+ "date": "2023-09-26T04:41:52Z",
+ "date_type": "course-start-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "",
+ "link_text": "",
+ "title": "Course starts",
+ "extra_info": null,
+ "first_component_block_id": ""
+ },
+ {
+ "assignment_type": "Module 0",
+ "complete": true,
+ "date": "2024-01-11T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@fcc82b68eb944b83962be3fdaa004ac0",
+ "link_text": "",
+ "title": "Course Policies and Expectations",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@problem+block@c0e15c6127404c6d9f21b588342067ac"
+ },
+ {
+ "assignment_type": "Module 0",
+ "complete": false,
+ "date": "2024-01-11T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@2a3ed0b868cd429ebdfbd1fe416d9c5a",
+ "link_text": "",
+ "title": "Syllabus Quiz",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@987158ea28e24f13855ff6abfb3e63e2"
+ },
+ {
+ "assignment_type": "Module 1",
+ "complete": false,
+ "date": "2024-01-15T20:19:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@84141e77957c45cca6b5039da8ee679d",
+ "link_text": "",
+ "title": "1.2 Why Should we Invest in ECD Interventions?",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@bf278c64a4034e88a33e0904fe03e256"
+ },
+ {
+ "assignment_type": "Module 1",
+ "complete": false,
+ "date": "2024-01-16T09:19:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@e2d228da088648479e5fda7478c006b8",
+ "link_text": "",
+ "title": "1.6 Closing",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@c97497458d30419ea0d41f6b3688e584"
+ },
+ {
+ "assignment_type": "Module 2",
+ "complete": false,
+ "date": "2024-01-16T21:59:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@ade8a7cfbf724bf5b58902bd27b613b0",
+ "link_text": "",
+ "title": "2.2 What can we learn about active ingredients from case studies of ECD interventions around the world?",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@e14daeca668d4c77a6f918b41b486195"
+ },
+ {
+ "assignment_type": "Module 3",
+ "complete": false,
+ "date": "2024-01-17T17:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@57ee148192f046859d6c8a2c3531ab49",
+ "link_text": "",
+ "title": "3.1 Delivery and Dose",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@ded1a7f220cb403887d3f894d0171762"
+ },
+ {
+ "assignment_type": "Module 3",
+ "complete": false,
+ "date": "2024-01-22T06:59:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@5be015e209ee4a44b71a10682ddb3eee",
+ "link_text": "",
+ "title": "3.2 Demand",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@e4f7b5f3cf9c498cb9d41a665e420ac8"
+ },
+ {
+ "assignment_type": "Module 3",
+ "complete": false,
+ "date": "2024-01-18T17:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@1da589ea848740628d173cba2c6833c8",
+ "link_text": "",
+ "title": "3.4 Closure",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@problem+block@eae438670a9844818518d52fff4d8aa4"
+ },
+ {
+ "assignment_type": "Module 4",
+ "complete": false,
+ "date": "2024-01-19T04:19:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@47f62ec6b1744ba5a1350a9f69e28cdc",
+ "link_text": "",
+ "title": "4.5 Closure",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@aff4b3b4b4ad4301a6293be7f626287a"
+ },
+ {
+ "assignment_type": "Module 5",
+ "complete": false,
+ "date": "2024-01-27T04:19:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@d28b2ee7d1a4425b872d62bfaeb56128",
+ "link_text": "",
+ "title": "5.1 Measuring Progress in ECD Interventions",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@b2f2e069242945728fd7e7fbc401eed5"
+ },
+ {
+ "assignment_type": "Module 5",
+ "complete": false,
+ "date": "2024-01-28T14:59:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@e9875420bbb9405e95c18186718d7529",
+ "link_text": "",
+ "title": "5.2 Measuring Progress in ECD Policies",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@0d0111f05f974c1ebaf66e8262f39da4"
+ },
+ {
+ "assignment_type": "Module 5",
+ "complete": false,
+ "date": "2024-01-30T14:59:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@504b2e012ec143d2a45ca5a6d04f8b22",
+ "link_text": "",
+ "title": "5.3 Challenges and Data-Driven Solutions",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@2b94eda3fe694579b941a055f3fb963a"
+ },
+ {
+ "assignment_type": "Module 6",
+ "complete": false,
+ "date": "2024-01-31T01:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@3aed70e1f3354a4eb5d21d63ec44618c",
+ "link_text": "",
+ "title": "6.2 Examples of Innovations",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@c23ad5f08cd842b49d30a1c8b7ce176a"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2024-02-01T12:00:00Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@217e302038da4a638cc5c0eb8aa6a239",
+ "link_text": "",
+ "title": "Open Response Assessment (Self Assessment)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@217e302038da4a638cc5c0eb8aa6a239"
+ },
+ {
+ "assignment_type": "Module 0",
+ "complete": false,
+ "date": "2024-02-03T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@fcc82b68eb944b83962be3fdaa004ac0",
+ "link_text": "",
+ "title": "Course Policies and Expectations",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@problem+block@c0e15c6127404c6d9f21b588342067ac"
+ },
+ {
+ "assignment_type": "Module 0",
+ "complete": false,
+ "date": "2024-01-15T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@2a3ed0b868cd429ebdfbd1fe416d9c5a",
+ "link_text": "",
+ "title": "Syllabus Quiz",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@987158ea28e24f13855ff6abfb3e63e2"
+ },
+ {
+ "assignment_type": "Module 1",
+ "complete": true,
+ "date": "2024-01-14T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@84141e77957c45cca6b5039da8ee679d",
+ "link_text": "",
+ "title": "1.2 Why Should we Invest in ECD Interventions?",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@bf278c64a4034e88a33e0904fe03e256"
+ },
+ {
+ "assignment_type": "Module 1",
+ "complete": false,
+ "date": "2024-01-13T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@d11c050c03de4cb48b80faf011162195",
+ "link_text": "",
+ "title": "1.5: What Implementation Features Matter to Implement ECD Interventions?",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@1655c4b7d4934734b401e70babc14d28"
+ },
+ {
+ "assignment_type": "Module 1",
+ "complete": true,
+ "date": "2024-01-12T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@e2d228da088648479e5fda7478c006b8",
+ "link_text": "",
+ "title": "1.6 Closing",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@c97497458d30419ea0d41f6b3688e584"
+ },
+ {
+ "assignment_type": "Module 2",
+ "complete": true,
+ "date": "2024-01-11T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@ed3b874a340d4dfa9245a3d2deaee5da",
+ "link_text": "",
+ "title": "2.1 What are the active ingredients of effective ECD interventions?",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@286da9b199c24445b1685040ded994d1"
+ },
+ {
+ "assignment_type": "Module 2",
+ "complete": false,
+ "date": "2024-01-10T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@ade8a7cfbf724bf5b58902bd27b613b0",
+ "link_text": "",
+ "title": "2.2 What can we learn about active ingredients from case studies of ECD interventions around the world?",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@e14daeca668d4c77a6f918b41b486195"
+ },
+ {
+ "assignment_type": "Module 3",
+ "complete": false,
+ "date": "2024-01-09T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@57ee148192f046859d6c8a2c3531ab49",
+ "link_text": "",
+ "title": "3.1 Delivery and Dose",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@ded1a7f220cb403887d3f894d0171762"
+ },
+ {
+ "assignment_type": "Module 3",
+ "complete": false,
+ "date": "2024-01-08T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@5be015e209ee4a44b71a10682ddb3eee",
+ "link_text": "",
+ "title": "3.2 Demand",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@e4f7b5f3cf9c498cb9d41a665e420ac8"
+ },
+ {
+ "assignment_type": "Module 3",
+ "complete": false,
+ "date": "2020-01-07T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@1da589ea848740628d173cba2c6833c8",
+ "link_text": "",
+ "title": "3.4 Closure",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@problem+block@eae438670a9844818518d52fff4d8aa4"
+ },
+ {
+ "assignment_type": "Module 4",
+ "complete": false,
+ "date": "2024-01-16T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@47f62ec6b1744ba5a1350a9f69e28cdc",
+ "link_text": "",
+ "title": "4.5 Closure",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@aff4b3b4b4ad4301a6293be7f626287a"
+ },
+ {
+ "assignment_type": "Module 5",
+ "complete": false,
+ "date": "2024-01-17T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@d28b2ee7d1a4425b872d62bfaeb56128",
+ "link_text": "",
+ "title": "5.1 Measuring Progress in ECD Interventions",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@b2f2e069242945728fd7e7fbc401eed5"
+ },
+ {
+ "assignment_type": "Module 5",
+ "complete": false,
+ "date": "2024-01-18T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@e9875420bbb9405e95c18186718d7529",
+ "link_text": "",
+ "title": "5.2 Measuring Progress in ECD Policies",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@0d0111f05f974c1ebaf66e8262f39da4"
+ },
+ {
+ "assignment_type": "Module 5",
+ "complete": false,
+ "date": "2024-01-19T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@504b2e012ec143d2a45ca5a6d04f8b22",
+ "link_text": "",
+ "title": "5.3 Challenges and Data-Driven Solutions",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@2b94eda3fe694579b941a055f3fb963a"
+ },
+ {
+ "assignment_type": "Module 6",
+ "complete": false,
+ "date": "2024-01-20T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@3aed70e1f3354a4eb5d21d63ec44618c",
+ "link_text": "",
+ "title": "6.2 Examples of Innovations",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@c23ad5f08cd842b49d30a1c8b7ce176a"
+ },
+ {
+ "assignment_type": "Module 7",
+ "complete": false,
+ "date": "2024-01-23T15:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/course-v1:HarvardX+ECD01+1T2023/jump_to/block-v1:HarvardX+ECD01+1T2023+type@sequential+block@1aea57e69f2a40f8a25c8edd389e3608",
+ "link_text": "",
+ "title": "7.0 Course Summary",
+ "extra_info": null,
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@html+block@625c5399993344fdaa852a967be6f690"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2024-01-23T12:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@217e302038da4a638cc5c0eb8aa6a239",
+ "link_text": "",
+ "title": "Open Response Assessment (Submission)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@217e302038da4a638cc5c0eb8aa6a239"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2024-01-23T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103",
+ "link_text": "",
+ "title": "Practice Creating a Theory of Change (Submission)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2024-01-24T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9",
+ "link_text": "",
+ "title": "Activity 1: Logic Model (Submission)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2024-01-25T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@217e302038da4a638cc5c0eb8aa6a239",
+ "link_text": "",
+ "title": "Open Response Assessment (Peer Assessment)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@217e302038da4a638cc5c0eb8aa6a239"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2024-02-26T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@217e302038da4a638cc5c0eb8aa6a239",
+ "link_text": "",
+ "title": "Open Response Assessment (Self Assessment)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@217e302038da4a638cc5c0eb8aa6a239"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2024-03-27T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103",
+ "link_text": "",
+ "title": "Practice Creating a Theory of Change (Peer Assessment)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2024-04-28T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103",
+ "link_text": "",
+ "title": "Practice Creating a Theory of Change (Self Assessment)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2025-01-29T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": false,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9",
+ "link_text": "",
+ "title": "Activity 1: Logic Model (Peer Assessment)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2026-01-30T09:39:37.467099Z",
+ "date_type": "assignment-due-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9",
+ "link_text": "",
+ "title": "Activity 1: Logic Model (Self Assessment)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2027-02-21T12:00:00Z",
+ "date_type": "verified-upgrade-deadline",
+ "description": "You must successfully complete verification before this date to qualify for a Verified Certificate.",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103",
+ "link_text": "",
+ "title": "Practice Creating a Theory of Change (Peer Assessment)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2027-02-21T12:00:00Z",
+ "date_type": "verified-upgrade-deadline",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103",
+ "link_text": "",
+ "title": "Practice Creating a Theory of Change (Self Assessment)",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@c3880270b8c7471287dd72a4b4b7e103"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2027-02-21T12:00:00Z",
+ "date_type": "certificate-available-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9",
+ "link_text": "",
+ "title": "Certificate",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9"
+ },
+ {
+ "assignment_type": null,
+ "complete": false,
+ "date": "2027-02-21T12:00:00Z",
+ "date_type": "course-expired-date",
+ "description": "",
+ "learner_has_access": true,
+ "link": "https://courses.edx.org/courses/block-v1:HarvardX+ECD01+1T2023+type@course+block@course/jump_to/block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9",
+ "link_text": "",
+ "title": "Course Access Expires",
+ "extra_info": "This Open Response Assessment's due dates are set by your instructor and can't be shifted.",
+ "first_component_block_id": "block-v1:HarvardX+ECD01+1T2023+type@openassessment+block@7f7924ba31fe4dfba5aee3304fd56cc9"
+ },
+ {
+ "assignment_type": null,
+ "complete": null,
+ "date": "2027-02-22T12:00:00Z",
+ "date_type": "course-end-date",
+ "description": "After this date, the course will be archived, which means you can review the course content but can no longer participate in graded assignments or work towards earning a certificate.",
+ "learner_has_access": true,
+ "link": "",
+ "link_text": "",
+ "title": "Course ends",
+ "extra_info": null,
+ "first_component_block_id": ""
+ }
+ ],
+ "has_ended": false,
+ "learner_is_full_access": true,
+ "user_timezone": null
+ }
+ """
+}
+#endif
+// swiftlint:enable all
diff --git a/Course/Course/Data/Mock/CourseStructureMock.swift b/Course/Course/Data/Mock/CourseStructureMock.swift
new file mode 100644
index 000000000..fe2f39e37
--- /dev/null
+++ b/Course/Course/Data/Mock/CourseStructureMock.swift
@@ -0,0 +1,637 @@
+//
+// CourseStructureMock.swift
+// Course
+//
+// Created by Shafqat Muneer on 1/24/24.
+//
+
+import Foundation
+
+// Mark - For testing and SwiftUI preview
+// swiftlint:disable all
+#if DEBUG
+extension CourseRepository {
+ static let courseStructureJson: String = """
+ {"root": "block-v1:QA+comparison+2022+type@course+block@course",
+ "blocks": {
+ "block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78": {
+ "id": "block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78",
+ "block_id": "be1704c576284ba39753c6f0ea4a4c78",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78",
+ "type": "comparison",
+ "display_name": "Comparison",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296": {
+ "id": "block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296",
+ "block_id": "93acc543871e4c73bc20a72a64e93296",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296",
+ "type": "problem",
+ "display_name": "Dropdown with Hints and Feedback",
+ "graded": false,
+ "student_view_multi_device": true,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b": {
+ "id": "block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b",
+ "block_id": "06c17035106e48328ebcd042babcf47b",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b",
+ "type": "comparison",
+ "display_name": "Comparison",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58": {
+ "id": "block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58",
+ "block_id": "c19e41b61db14efe9c45f1354332ae58",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58",
+ "type": "problem",
+ "display_name": "Text Input with Hints and Feedback",
+ "graded": false,
+ "student_view_multi_device": true,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb": {
+ "id": "block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb",
+ "block_id": "0d96732f577b4ff68799faf8235d1bfb",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb",
+ "type": "problem",
+ "display_name": "Numerical Input with Hints and Feedback",
+ "graded": false,
+ "student_view_multi_device": true,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96": {
+ "id": "block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96",
+ "block_id": "dd2e22fdf0724bd88c8b2e6b68dedd96",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96",
+ "type": "problem",
+ "display_name": "Blank Common Problem",
+ "graded": false,
+ "student_view_multi_device": true,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd": {
+ "id": "block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd",
+ "block_id": "d1e091aa305741c5bedfafed0d269efd",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd",
+ "type": "problem",
+ "display_name": "Blank Common Problem",
+ "graded": false,
+ "student_view_multi_device": true,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7": {
+ "id": "block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7",
+ "block_id": "23e10dea806345b19b77997b4fc0eea7",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7",
+ "type": "comparison",
+ "display_name": "Comparison",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904": {
+ "id": "block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904",
+ "block_id": "29e7eddbe8964770896e4036748c9904",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904",
+ "type": "vertical",
+ "display_name": "Unit",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@comparison+block@be1704c576284ba39753c6f0ea4a4c78",
+ "block-v1:QA+comparison+2022+type@problem+block@93acc543871e4c73bc20a72a64e93296",
+ "block-v1:QA+comparison+2022+type@comparison+block@06c17035106e48328ebcd042babcf47b",
+ "block-v1:QA+comparison+2022+type@problem+block@c19e41b61db14efe9c45f1354332ae58",
+ "block-v1:QA+comparison+2022+type@problem+block@0d96732f577b4ff68799faf8235d1bfb",
+ "block-v1:QA+comparison+2022+type@problem+block@dd2e22fdf0724bd88c8b2e6b68dedd96",
+ "block-v1:QA+comparison+2022+type@problem+block@d1e091aa305741c5bedfafed0d269efd",
+ "block-v1:QA+comparison+2022+type@comparison+block@23e10dea806345b19b77997b4fc0eea7"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6": {
+ "id": "block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6",
+ "block_id": "f468bb5c6e8641179e523c7fcec4e6d6",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6",
+ "type": "sequential",
+ "display_name": "Subsection",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@vertical+block@29e7eddbe8964770896e4036748c9904"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234": {
+ "id": "block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234",
+ "block_id": "eaf91d8fc70547339402043ba1a1c234",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234",
+ "type": "problem",
+ "display_name": "Dropdown with Hints and Feedback",
+ "graded": false,
+ "student_view_multi_device": true,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751": {
+ "id": "block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751",
+ "block_id": "fac531c3f1f3400cb8e3b97eb2c3d751",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751",
+ "type": "comparison",
+ "display_name": "Comparison",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de": {
+ "id": "block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de",
+ "block_id": "74a1074024fe401ea305534f2241e5de",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de",
+ "type": "html",
+ "display_name": "Raw HTML",
+ "graded": false,
+ "student_view_data": {
+ "last_modified": "2023-05-04T19:08:07Z",
+ "html_data": "https://s3.eu-central-1.amazonaws.com/vso-dev-edx-sorage/htmlxblock/QA/comparison/html/74a1074024fe401ea305534f2241e5de/content_html.zip",
+ "size": 576,
+ "index_page": "index.html",
+ "icon_class": "other"
+ },
+ "student_view_multi_device": true,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca": {
+ "id": "block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca",
+ "block_id": "e5b2e105f4f947c5b76fb12c35da1eca",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca",
+ "type": "vertical",
+ "display_name": "Unit",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@problem+block@eaf91d8fc70547339402043ba1a1c234",
+ "block-v1:QA+comparison+2022+type@comparison+block@fac531c3f1f3400cb8e3b97eb2c3d751",
+ "block-v1:QA+comparison+2022+type@html+block@74a1074024fe401ea305534f2241e5de"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2": {
+ "id": "block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2",
+ "block_id": "d37cb0c5c2d24ddaacf3494760a055f2",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2",
+ "type": "sequential",
+ "display_name": "Another one subsection",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@vertical+block@e5b2e105f4f947c5b76fb12c35da1eca"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846": {
+ "id": "block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846",
+ "block_id": "abecaefe203c4c93b441d16cea3b7846",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846",
+ "type": "chapter",
+ "display_name": "Section",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@sequential+block@f468bb5c6e8641179e523c7fcec4e6d6",
+ "block-v1:QA+comparison+2022+type@sequential+block@d37cb0c5c2d24ddaacf3494760a055f2"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de": {
+ "id": "block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de",
+ "block_id": "a0c3ac29daab425f92a34b34eb2af9de",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de",
+ "type": "pdf",
+ "display_name": "PDF title",
+ "graded": false,
+ "student_view_data": {
+ "last_modified": "2023-04-26T08:43:45Z",
+ "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
+ },
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9": {
+ "id": "block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9",
+ "block_id": "bcd1b0f3015b4d3696b12f65a5d682f9",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9",
+ "type": "pdf",
+ "display_name": "PDF",
+ "graded": false,
+ "student_view_data": {
+ "last_modified": "2023-04-26T08:43:45Z",
+ "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
+ },
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59": {
+ "id": "block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59",
+ "block_id": "67d805daade34bd4b6ace607e6d48f59",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59",
+ "type": "pdf",
+ "display_name": "PDF",
+ "graded": false,
+ "student_view_data": {
+ "last_modified": "2023-04-26T08:43:45Z",
+ "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
+ },
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974": {
+ "id": "block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974",
+ "block_id": "828606a51f4e44198e92f86a45be7974",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974",
+ "type": "pdf",
+ "display_name": "PDF",
+ "graded": false,
+ "student_view_data": {
+ "last_modified": "2023-04-26T08:43:45Z",
+ "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
+ },
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee": {
+ "id": "block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee",
+ "block_id": "8646c3bc2184467b86e5ef01ecd452ee",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee",
+ "type": "pdf",
+ "display_name": "PDF",
+ "graded": false,
+ "student_view_data": {
+ "last_modified": "2023-04-26T08:43:45Z",
+ "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
+ },
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1": {
+ "id": "block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1",
+ "block_id": "e2faa0e62223489e91a41700865c5fc1",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1",
+ "type": "vertical",
+ "display_name": "Unit",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@pdf+block@a0c3ac29daab425f92a34b34eb2af9de",
+ "block-v1:QA+comparison+2022+type@pdf+block@bcd1b0f3015b4d3696b12f65a5d682f9",
+ "block-v1:QA+comparison+2022+type@pdf+block@67d805daade34bd4b6ace607e6d48f59",
+ "block-v1:QA+comparison+2022+type@pdf+block@828606a51f4e44198e92f86a45be7974",
+ "block-v1:QA+comparison+2022+type@pdf+block@8646c3bc2184467b86e5ef01ecd452ee"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52": {
+ "id": "block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52",
+ "block_id": "0c5e89fa6d7a4fac8f7b26f2ca0bbe52",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52",
+ "type": "problem",
+ "display_name": "Checkboxes with Hints and Feedback",
+ "graded": false,
+ "student_view_multi_device": true,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4": {
+ "id": "block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4",
+ "block_id": "8ba437d8b20d416d91a2d362b0c940a4",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4",
+ "type": "vertical",
+ "display_name": "Unit",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@problem+block@0c5e89fa6d7a4fac8f7b26f2ca0bbe52"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d": {
+ "id": "block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d",
+ "block_id": "021f70794f7349998e190b060260b70d",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d",
+ "type": "pdf",
+ "display_name": "PDF",
+ "graded": false,
+ "student_view_data": {
+ "last_modified": "2023-04-26T08:43:45Z",
+ "url": "https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf",
+ },
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ],
+ "completion": 0.0
+ },
+ "block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1": {
+ "id": "block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1",
+ "block_id": "2c344115d3554ac58c140ec86e591aa1",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1",
+ "type": "vertical",
+ "display_name": "Unit",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@pdf+block@021f70794f7349998e190b060260b70d"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe": {
+ "id": "block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe",
+ "block_id": "6c9c6ba663b54c0eb9cbdcd0c6b4bebe",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe",
+ "type": "sequential",
+ "display_name": "Subsection",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@vertical+block@e2faa0e62223489e91a41700865c5fc1",
+ "block-v1:QA+comparison+2022+type@vertical+block@8ba437d8b20d416d91a2d362b0c940a4",
+ "block-v1:QA+comparison+2022+type@vertical+block@2c344115d3554ac58c140ec86e591aa1"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7": {
+ "id": "block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7",
+ "block_id": "d5a4f1f2f5314288aae400c270fb03f7",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7",
+ "type": "chapter",
+ "display_name": "PDF",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@sequential+block@6c9c6ba663b54c0eb9cbdcd0c6b4bebe"
+ ],
+ "completion": 0
+ },
+ "block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf": {
+ "id": "block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf",
+ "block_id": "7ab45affb80f4846a60648ec6aff9fbf",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf",
+ "type": "chapter",
+ "display_name": "Section",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+
+ ]
+ },
+ "block-v1:QA+comparison+2022+type@course+block@course": {
+ "id": "block-v1:QA+comparison+2022+type@course+block@course",
+ "block_id": "course",
+ "lms_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@course+block@course",
+ "legacy_web_url": "https://lms.lilac-vso-dev.raccoongang.com/courses/course-v1:QA+comparison+2022/jump_to/block-v1:QA+comparison+2022+type@course+block@course?experience=legacy",
+ "student_view_url": "https://lms.lilac-vso-dev.raccoongang.com/xblock/block-v1:QA+comparison+2022+type@course+block@course",
+ "type": "course",
+ "display_name": "Comparison xblock test coursre",
+ "graded": false,
+ "student_view_multi_device": false,
+ "block_counts": {
+ "video": 0
+ },
+ "descendants": [
+ "block-v1:QA+comparison+2022+type@chapter+block@abecaefe203c4c93b441d16cea3b7846",
+ "block-v1:QA+comparison+2022+type@chapter+block@d5a4f1f2f5314288aae400c270fb03f7",
+ "block-v1:QA+comparison+2022+type@chapter+block@7ab45affb80f4846a60648ec6aff9fbf"
+ ],
+ "completion": 0
+ }
+ },
+ "id": "course-v1:QA+comparison+2022",
+ "name": "Comparison xblock test coursre",
+ "number": "comparison",
+ "org": "QA",
+ "start": "2022-01-01T00:00:00Z",
+ "start_display": "01 january 2022 р.",
+ "start_type": "timestamp",
+ "end": null,
+ "courseware_access": {
+ "has_access": true,
+ "error_code": null,
+ "developer_message": null,
+ "user_message": null,
+ "additional_context_user_message": null,
+ "user_fragment": null
+ },
+ "media": {
+ "image": {
+ "raw": "/asset-v1:QA+comparison+2022+type@asset+block@images_course_image.jpg",
+ "small": "/asset-v1:QA+comparison+2022+type@asset+block@images_course_image.jpg",
+ "large": "/asset-v1:QA+comparison+2022+type@asset+block@images_course_image.jpg"
+ }
+ },
+ "certificate": {
+
+ },
+ "is_self_paced": false
+ }
+ """
+}
+#endif
+// swiftlint:enable all
diff --git a/Course/Course/Domain/Model/CourseDates.swift b/Course/Course/Domain/Model/CourseDates.swift
index 0909610d4..a796a944b 100644
--- a/Course/Course/Domain/Model/CourseDates.swift
+++ b/Course/Course/Domain/Model/CourseDates.swift
@@ -14,41 +14,46 @@ public struct CourseDates {
let hasEnded, learnerIsFullAccess: Bool
let userTimezone: String?
- var sortedDateToCourseDateBlockDict: [Date: [CourseDateBlock]] {
- var dateToCourseDateBlockDict: [Date: [CourseDateBlock]] = [:]
- var hasToday = false
- let today = Date.today
-
- let calendar = Calendar.current
- let todayComponents = calendar.dateComponents([.year, .month, .day], from: .today)
+ var statusDatesBlocks: [CompletionStatus: [Date: [CourseDateBlock]]] {
+ var statusDatesBlocks: [CompletionStatus: [Date: [CourseDateBlock]]] = [:]
+ var statusBlocks: [CompletionStatus: [CourseDateBlock]] = [:]
for block in courseDateBlocks {
let date = block.date
- let dateComponents = calendar.dateComponents([.year, .month, .day], from: date)
-
- if dateComponents == todayComponents {
- hasToday = true
+ switch true {
+ case block.complete ?? false || block.blockStatus == .courseStartDate:
+ statusBlocks[.completed, default: []].append(block)
+ case date.isInPast:
+ statusBlocks[.pastDue, default: []].append(block)
+ case date.isToday:
+ if date < Date() {
+ statusBlocks[.pastDue, default: []].append(block)
+ } else {
+ statusBlocks[.today, default: []].append(block)
+ }
+ case date.isThisWeek:
+ statusBlocks[.thisWeek, default: []].append(block)
+ case date.isNextWeek:
+ statusBlocks[.nextWeek, default: []].append(block)
+ case date.isUpcoming:
+ statusBlocks[.upcoming, default: []].append(block)
+ default:
+ statusBlocks[.upcoming, default: []].append(block)
}
-
- dateToCourseDateBlockDict[date, default: []].append(block)
}
- if !hasToday {
- let todayBlock = CourseDateBlock(
- assignmentType: nil,
- complete: nil,
- date: today,
- dateType: "",
- description: "",
- learnerHasAccess: true,
- link: "", linkText: nil,
- title: CoreLocalization.CourseDates.today,
- extraInfo: nil,
- firstComponentBlockID: "uniqueIDForToday")
- dateToCourseDateBlockDict[today] = [todayBlock]
+ for status in statusBlocks.keys {
+ let courseDateBlocks = statusBlocks[status]
+ var dateToCourseDateBlockDict: [Date: [CourseDateBlock]] = [:]
+
+ for block in courseDateBlocks ?? [] {
+ let date = block.date
+ dateToCourseDateBlockDict[date, default: []].append(block)
+ }
+ statusDatesBlocks[status] = dateToCourseDateBlockDict
}
- return dateToCourseDateBlockDict
+ return statusDatesBlocks
}
}
@@ -80,6 +85,29 @@ extension Date {
var isInFuture: Bool {
return Date.compare(self, to: .today) == .orderedDescending
}
+
+ var isThisWeek: Bool {
+ // Items due within the next 7 days (7*24 hours from now)
+ let calendar = Calendar.current
+ let nextDay = calendar.date(byAdding: .day, value: 1, to: .today) ?? .distantPast
+ let nextSeventhDay = calendar.date(byAdding: .day, value: 8, to: .today) ?? .distantPast
+ return (nextDay...nextSeventhDay).contains(self)
+ }
+
+ var isNextWeek: Bool {
+ // Items due within the next 14 days (14*24 hours from now)
+ let calendar = Calendar.current
+ let nextEighthDay = calendar.date(byAdding: .day, value: 8, to: .today) ?? .distantPast
+ let nextFourteenthDay = calendar.date(byAdding: .day, value: 15, to: .today) ?? .distantPast
+ return (nextEighthDay...nextFourteenthDay).contains(self)
+ }
+
+ var isUpcoming: Bool {
+ // Items due after the next 14 days (14*24 hours from now)
+ let calendar = Calendar.current
+ let nextFourteenthDay = calendar.date(byAdding: .day, value: 14, to: .today) ?? .distantPast
+ return Date.compare(self, to: nextFourteenthDay) == .orderedDescending
+ }
}
public struct CourseDateBlock: Identifiable {
@@ -116,6 +144,18 @@ public struct CourseDateBlock: Identifiable {
return date.isInFuture
}
+ var isThisWeek: Bool {
+ return date.isThisWeek
+ }
+
+ var isNextWeek: Bool {
+ return date.isNextWeek
+ }
+
+ var isUpcoming: Bool {
+ return date.isUpcoming
+ }
+
var isAssignment: Bool {
return BlockStatus.status(of: dateType) == .assignment
}
@@ -167,6 +207,29 @@ public struct CourseDateBlock: Identifiable {
return BlockStatus.status(of: dateType)
}
+
+ var blockImage: ImageAsset? {
+ if !learnerHasAccess {
+ return CoreAssets.lockIcon
+ }
+
+ if isAssignment {
+ return CoreAssets.assignmentIcon
+ }
+
+ switch blockStatus {
+ case .courseStartDate, .courseEndDate:
+ return CoreAssets.schoolCapIcon
+ case .verifiedUpgradeDeadline, .verificationDeadlineDate:
+ return CoreAssets.calendarIcon
+ case .courseExpiredDate:
+ return CoreAssets.lockWithWatchIcon
+ case .certificateAvailbleDate:
+ return CoreAssets.certificateIcon
+ default:
+ return CoreAssets.calendarIcon
+ }
+ }
}
public struct DatesBannerInfo {
@@ -202,3 +265,12 @@ public enum BlockStatus {
}
}
}
+
+public enum CompletionStatus: String {
+ case completed = "Completed"
+ case pastDue = "Past Due"
+ case today = "Today"
+ case thisWeek = "This Week"
+ case nextWeek = "Next Week"
+ case upcoming = "Upcoming"
+}
diff --git a/Course/Course/Presentation/Dates/CourseDatesView.swift b/Course/Course/Presentation/Dates/CourseDatesView.swift
index 36bb79b9f..8110c350e 100644
--- a/Course/Course/Presentation/Dates/CourseDatesView.swift
+++ b/Course/Course/Presentation/Dates/CourseDatesView.swift
@@ -75,46 +75,17 @@ struct Line: Shape {
}
struct TimeLineView: View {
- let block: CourseDateBlock
- let date: Date
- let firstDate: Date?
- let lastDate: Date?
- let allHaveSameStatus: Bool
+ let status: CompletionStatus
var body: some View {
ZStack(alignment: .top) {
VStack {
Line()
- .stroke(style: StrokeStyle(lineWidth: 1))
- .frame(maxHeight: lastDate == date ? 10 : .infinity, alignment: .top)
- .padding(.top, firstDate == date && lastDate != date ? 10 : 0)
-
- if lastDate == date {
- Spacer()
- }
+ .stroke(style: StrokeStyle(lineWidth: 8, lineCap: .round, lineJoin: .round))
+ .frame(maxHeight: .infinity, alignment: .top)
+ .padding(.top, 0)
+ .foregroundColor(status.foregroundColor)
}
-
- Circle()
- .frame(width: date.isToday ? 12 : 8, height: date.isToday ? 12 : 8)
- .foregroundColor({
- if date.isToday {
- return Theme.Colors.warning
- } else if date.isInPast {
- switch block.blockStatus {
- case .completed: return allHaveSameStatus ? Color.white : Color.gray
- case .courseStartDate: return Color.white
- case .verifiedOnly: return Color.black
- case .pastDue: return Color.gray
- default: return Color.gray
- }
- } else if date.isInFuture {
- return Color.black
- } else {
- return Color.white
- }
- }())
- .overlay(Circle().stroke(Color.black, lineWidth: 1))
- .padding(.top, 5)
}
.frame(width: 16)
}
@@ -122,87 +93,197 @@ struct TimeLineView: View {
struct CourseDateListView: View {
@ObservedObject var viewModel: CourseDatesViewModel
+ @State private var isExpanded = false
var courseDates: CourseDates
var body: some View {
VStack {
ScrollView {
VStack(alignment: .leading, spacing: 0) {
- ForEach(viewModel.sortedDates, id: \.self) { date in
- let blocks = courseDates.sortedDateToCourseDateBlockDict[date]!
- let block = blocks[0]
-
- HStack(alignment: .center) {
- let ignoredStatuses: [BlockStatus] = [.courseStartDate, .courseEndDate]
- let allHaveSameStatus = blocks
- .filter { !ignoredStatuses.contains($0.blockStatus) }
- .allSatisfy { $0.blockStatus == block.blockStatus }
-
- TimeLineView(block: block, date: date,
- firstDate: viewModel.sortedDates.first,
- lastDate: viewModel.sortedDates.last,
- allHaveSameStatus: allHaveSameStatus)
-
- BlockStatusView(viewModel: viewModel,
+ ForEach(Array(viewModel.sortedStatuses), id: \.self) { status in
+ let courseDateBlockDict = courseDates.statusDatesBlocks[status]!
+ if status == .completed {
+ CompletedBlocks(
+ isExpanded: $isExpanded,
+ courseDateBlockDict: courseDateBlockDict,
+ viewModel: viewModel
+ )
+ } else {
+ Text(status.rawValue)
+ .font(Theme.Fonts.titleSmall)
+ .padding(.top, 10)
+ .padding(.bottom, 10)
+ HStack {
+ TimeLineView(status: status)
+ .padding(.bottom, 15)
+ VStack(alignment: .leading) {
+ ForEach(courseDateBlockDict.keys.sorted(), id: \.self) { date in
+ let blocks = courseDateBlockDict[date]!
+ let block = blocks[0]
+ Text(block.formattedDate)
+ .font(Theme.Fonts.labelMedium)
+ .foregroundStyle(Theme.Colors.textPrimary)
+ BlockStatusView(
+ viewModel: viewModel,
block: block,
- allHaveSameStatus: allHaveSameStatus,
- blocks: blocks)
-
- Spacer()
+ blocks: blocks
+ )
+ }
+ }
+ }
}
}
}
+ .frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 16)
+ .padding(.vertical, 5)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
+struct CompletedBlocks: View {
+ @Binding var isExpanded: Bool
+ let courseDateBlockDict: [Date: [CourseDateBlock]]
+ let viewModel: CourseDatesViewModel
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: 5) {
+ // Toggle button to expand/collapse the cell
+ Button(action: {
+ withAnimation {
+ isExpanded.toggle()
+ }
+ }) {
+ HStack {
+ VStack(alignment: .leading) {
+ Text(CompletionStatus.completed.rawValue)
+ .font(Theme.Fonts.titleSmall)
+ .foregroundColor(Theme.Colors.textPrimary)
+
+ if !isExpanded {
+ let totalCount = courseDateBlockDict.values.reduce(0) { $0 + $1.count }
+ let itemsHidden = totalCount == 1 ?
+ CoreLocalization.CourseDates.itemHidden :
+ CoreLocalization.CourseDates.itemsHidden
+ Text("\(totalCount) \(itemsHidden)")
+ .font(Theme.Fonts.labelMedium)
+ .foregroundColor(Theme.Colors.textPrimary)
+ }
+ }
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .padding(.leading, 16)
+ .padding(.vertical, 8)
+
+ Image(systemName: "chevron.right")
+ .labelStyle(.iconOnly)
+ .dropdownArrowRotationAnimation(value: isExpanded)
+ .foregroundColor(Theme.Colors.textPrimary)
+ .padding()
+ }
+ }
+
+ // Your expandable content goes here
+ if isExpanded {
+ VStack(alignment: .leading) {
+ ForEach(courseDateBlockDict.keys.sorted(), id: \.self) { date in
+ let blocks = courseDateBlockDict[date]!
+ let block = blocks[0]
+
+ Spacer()
+ Text(block.formattedDate)
+ .font(Theme.Fonts.labelMedium)
+ .foregroundStyle(Theme.Colors.textPrimary)
+
+ ForEach(blocks) { block in
+ HStack(alignment: .top) {
+ block.blockImage?.swiftUIImage
+ .foregroundColor(Theme.Colors.textPrimary)
+ StyleBlock(block: block, viewModel: viewModel)
+ .padding(.bottom, 15)
+ Spacer()
+ if block.canShowLink && !block.firstComponentBlockID.isEmpty {
+ Image(systemName: "chevron.right")
+ .resizable()
+ .scaledToFit()
+ .frame(width: 6.55, height: 11.15)
+ .labelStyle(.iconOnly)
+ .foregroundColor(Theme.Colors.textPrimary)
+ }
+ }
+ .padding(.trailing, 15)
+ }
+ }
+ }
+ .padding(.bottom, 15)
+ .padding(.leading, 16)
+ }
+
+ }
+ .overlay(
+ RoundedRectangle(cornerRadius: 8)
+ .stroke(Theme.Colors.datesSectionStroke, lineWidth: 2)
+ )
+ .background(Theme.Colors.datesSectionBackground)
+ }
+}
+
struct BlockStatusView: View {
let viewModel: CourseDatesViewModel
let block: CourseDateBlock
- let allHaveSameStatus: Bool
let blocks: [CourseDateBlock]
var body: some View {
VStack(alignment: .leading) {
- HStack {
- Text(block.formattedDate)
- .font(Theme.Fonts.bodyLarge)
- .bold()
-
- if block.isToday {
- Text(CoreLocalization.CourseDates.today)
- .font(Theme.Fonts.bodySmall)
- .foregroundColor(Color.black)
- .padding(EdgeInsets(top: 2, leading: 6, bottom: 2, trailing: 8))
- .background(Theme.Colors.warning)
- .cornerRadius(5)
- }
-
- if allHaveSameStatus {
- let lockImageText = block.isVerifiedOnly ? Text(Image(systemName: "lock.fill")) : Text("")
- Text("\(lockImageText) \(block.blockStatus.title)")
- .font(Theme.Fonts.bodySmall)
- .foregroundColor(block.blockStatus.foregroundColor)
- .padding(EdgeInsets(top: 2, leading: 6, bottom: 2, trailing: 8))
- .background(block.blockStatus.backgroundColor)
- .cornerRadius(5)
+ ForEach(blocks) { block in
+ HStack(alignment: .top) {
+ block.blockImage?.swiftUIImage
+ .foregroundColor(Theme.Colors.textPrimary)
+ StyleBlock(block: block, viewModel: viewModel)
+ .padding(.bottom, 15)
+ Spacer()
+ if block.canShowLink && !block.firstComponentBlockID.isEmpty {
+ Image(systemName: "chevron.right")
+ .resizable()
+ .scaledToFit()
+ .frame(width: 6.55, height: 11.15)
+ .labelStyle(.iconOnly)
+ .foregroundColor(Theme.Colors.textPrimary)
+ }
}
+ .padding(.trailing, 15)
}
+ .padding(.top, 0.2)
+ }
+ }
+
+ func applyStyle(string: String, forgroundColor: Color, backgroundColor: Color) -> AttributedString {
+ var attributedString = AttributedString(string)
+ attributedString.font = Theme.Fonts.bodySmall
+ attributedString.foregroundColor = forgroundColor
+ attributedString.backgroundColor = backgroundColor
+ return attributedString
+ }
+}
- ForEach(blocks) { block in
- styleBlock(block: block, allHaveSameStatus: allHaveSameStatus)
+struct StyleBlock: View {
+ let block: CourseDateBlock
+ let viewModel: CourseDatesViewModel
+
+ var body: some View {
+ VStack(alignment: .leading) {
+ styleBlock(block: block)
+ if !block.description.isEmpty {
+ Text(block.description)
+ .font(Theme.Fonts.labelMedium)
+ .foregroundStyle(Theme.Colors.thisWeekTimelineColor)
+ .fixedSize(horizontal: false, vertical: true)
}
- .padding(.top, 0.2)
}
- .padding(.vertical, 0)
- .padding(.leading, 5)
- .padding(.bottom, 10)
}
- func styleBlock(block: CourseDateBlock, allHaveSameStatus: Bool) -> some View {
+ func styleBlock(block: CourseDateBlock) -> some View {
var attributedString = AttributedString("")
if let prefix = block.assignmentType, !prefix.isEmpty {
@@ -211,44 +292,28 @@ struct BlockStatusView: View {
attributedString += styleTitle(block: block)
- if !allHaveSameStatus {
- attributedString.appendSpaces(2)
- attributedString += applyStyle(
- string: block.blockStatus.title,
- forgroundColor: block.blockStatus.foregroundColor,
- backgroundColor: block.blockStatus.backgroundColor)
- }
-
return Text(attributedString)
- .font(Theme.Fonts.bodyMedium)
- .foregroundColor({
+ .font(Theme.Fonts.titleSmall)
+ .lineLimit(1)
+ .foregroundStyle({
if block.isAssignment {
- return block.isAvailable ? Color.black : Color.gray.opacity(0.6)
+ return block.isAvailable ? Theme.Colors.textPrimary : Color.gray.opacity(0.6)
} else {
- return Color.black
+ return Theme.Colors.textPrimary
}
}())
.onTapGesture {
- Task {
- await viewModel.showCourseDetails(componentID: block.firstComponentBlockID)
+ if block.canShowLink && !block.firstComponentBlockID.isEmpty {
+ Task {
+ await viewModel.showCourseDetails(componentID: block.firstComponentBlockID)
+ }
}
}
}
func styleTitle(block: CourseDateBlock) -> AttributedString {
var attributedString = AttributedString(block.title)
- attributedString.font = Theme.Fonts.bodyMedium
- if block.canShowLink && !block.firstComponentBlockID.isEmpty {
- attributedString.underlineStyle = .single
- }
- return attributedString
- }
-
- func applyStyle(string: String, forgroundColor: Color, backgroundColor: Color) -> AttributedString {
- var attributedString = AttributedString(string)
- attributedString.font = Theme.Fonts.bodySmall
- attributedString.foregroundColor = forgroundColor
- attributedString.backgroundColor = backgroundColor
+ attributedString.font = Theme.Fonts.titleSmall
return attributedString
}
}
@@ -286,6 +351,19 @@ fileprivate extension BlockStatus {
}
}
+fileprivate extension CompletionStatus {
+ var foregroundColor: Color {
+ switch self {
+ case .pastDue: return Theme.Colors.pastDueTimelineColor
+ case .today: return Theme.Colors.todayTimelineColor
+ case .thisWeek: return Theme.Colors.thisWeekTimelineColor
+ case .nextWeek: return Theme.Colors.nextWeekTimelineColor
+ case .upcoming: return Theme.Colors.upcomingTimelineColor
+ default: return Color.white.opacity(0)
+ }
+ }
+}
+
fileprivate extension AttributedString {
mutating func appendSpaces(_ count: Int = 1) {
self += AttributedString(String(repeating: " ", count: count))
diff --git a/Course/Course/Presentation/Dates/CourseDatesViewModel.swift b/Course/Course/Presentation/Dates/CourseDatesViewModel.swift
index 75851d85e..3ee731bd0 100644
--- a/Course/Course/Presentation/Dates/CourseDatesViewModel.swift
+++ b/Course/Course/Presentation/Dates/CourseDatesViewModel.swift
@@ -43,12 +43,20 @@ public class CourseDatesViewModel: ObservableObject {
self.courseID = courseID
}
- var sortedDates: [Date] {
- courseDates?.sortedDateToCourseDateBlockDict.keys.sorted() ?? []
- }
-
- func blocks(for date: Date) -> [CourseDateBlock] {
- courseDates?.sortedDateToCourseDateBlockDict[date] ?? []
+ var sortedStatuses: [CompletionStatus] {
+ let desiredSequence = [
+ CompletionStatus.completed,
+ CompletionStatus.pastDue,
+ CompletionStatus.today,
+ CompletionStatus.thisWeek,
+ CompletionStatus.nextWeek,
+ CompletionStatus.upcoming
+ ]
+
+ // Filter out keys that don't exist in the dictionary
+ let filteredKeys = desiredSequence.filter {
+ courseDates?.statusDatesBlocks.keys.contains($0) ?? false }
+ return filteredKeys
}
@MainActor
diff --git a/Course/Course/Presentation/Outline/CourseOutlineView.swift b/Course/Course/Presentation/Outline/CourseOutlineView.swift
index 04ee19406..81d566c03 100644
--- a/Course/Course/Presentation/Outline/CourseOutlineView.swift
+++ b/Course/Course/Presentation/Outline/CourseOutlineView.swift
@@ -81,7 +81,6 @@ public struct CourseOutlineView: View {
sequentialIndex: continueWith.sequentialIndex
)
}
-//"Saeed"
}
}
diff --git a/Course/CourseTests/Presentation/Unit/CourseDateViewModelTests.swift b/Course/CourseTests/Presentation/Unit/CourseDateViewModelTests.swift
index 690b93325..797c27440 100644
--- a/Course/CourseTests/Presentation/Unit/CourseDateViewModelTests.swift
+++ b/Course/CourseTests/Presentation/Unit/CourseDateViewModelTests.swift
@@ -114,7 +114,7 @@ final class CourseDateViewModelTests: XCTestCase {
let block2 = CourseDateBlock(
assignmentType: nil,
- complete: nil,
+ complete: true,
date: Date.today,
dateType: "event",
description: "",
@@ -139,15 +139,15 @@ final class CourseDateViewModelTests: XCTestCase {
userTimezone: nil
)
- let sortedDict = courseDates.sortedDateToCourseDateBlockDict
+ let sortedDict = courseDates.statusDatesBlocks[.completed]
- XCTAssertEqual(sortedDict.keys.sorted().first, Date.today)
+ XCTAssertEqual(sortedDict?.keys.sorted().first, Date.today)
}
func testMultipleBlocksForSameDate() {
let block1 = CourseDateBlock(
assignmentType: nil,
- complete: nil,
+ complete: true,
date: Date.today,
dateType: "event",
description: "",
@@ -161,7 +161,7 @@ final class CourseDateViewModelTests: XCTestCase {
let block2 = CourseDateBlock(
assignmentType: nil,
- complete: nil,
+ complete: true,
date: Date.today,
dateType: "event",
description: "",
@@ -186,8 +186,8 @@ final class CourseDateViewModelTests: XCTestCase {
userTimezone: nil
)
- let sortedDict = courseDates.sortedDateToCourseDateBlockDict
- XCTAssertEqual(sortedDict[block1.date]?.count, 2, "There should be two blocks for the given date.")
+ let sortedDict = courseDates.statusDatesBlocks[.completed]
+ XCTAssertEqual(sortedDict?[block1.date]?.count, 2, "There should be two blocks for the given date.")
}
func testBlockStatusForAssignmentType() {
diff --git a/Podfile.lock b/Podfile.lock
index d9169ef4b..79fbd8c97 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -182,4 +182,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 544edab2f9ecc4ac18973fb8865f1d0613ec8a28
-COCOAPODS: 1.13.0
+COCOAPODS: 1.14.3
diff --git a/Theme/Theme/Assets.xcassets/CourseDates/Contents.json b/Theme/Theme/Assets.xcassets/CourseDates/Contents.json
new file mode 100644
index 000000000..73c00596a
--- /dev/null
+++ b/Theme/Theme/Assets.xcassets/CourseDates/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Theme/Theme/Assets.xcassets/CourseDates/DatesSectionBackground.colorset/Contents.json b/Theme/Theme/Assets.xcassets/CourseDates/DatesSectionBackground.colorset/Contents.json
new file mode 100644
index 000000000..b73d804ea
--- /dev/null
+++ b/Theme/Theme/Assets.xcassets/CourseDates/DatesSectionBackground.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.984",
+ "green" : "0.980",
+ "red" : "0.976"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.275",
+ "green" : "0.200",
+ "red" : "0.153"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Theme/Theme/Assets.xcassets/CourseDates/DatesSectionStroke.colorset/Contents.json b/Theme/Theme/Assets.xcassets/CourseDates/DatesSectionStroke.colorset/Contents.json
new file mode 100644
index 000000000..432fab345
--- /dev/null
+++ b/Theme/Theme/Assets.xcassets/CourseDates/DatesSectionStroke.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.878",
+ "green" : "0.831",
+ "red" : "0.800"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.439",
+ "green" : "0.353",
+ "red" : "0.306"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Theme/Theme/Assets.xcassets/CourseDates/NextWeekTimelineColor.colorset/Contents.json b/Theme/Theme/Assets.xcassets/CourseDates/NextWeekTimelineColor.colorset/Contents.json
new file mode 100644
index 000000000..5cd29db93
--- /dev/null
+++ b/Theme/Theme/Assets.xcassets/CourseDates/NextWeekTimelineColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.733",
+ "green" : "0.647",
+ "red" : "0.592"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.439",
+ "green" : "0.353",
+ "red" : "0.306"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Theme/Theme/Assets.xcassets/CourseDates/ThisWeekTimelineColor.colorset/Contents.json b/Theme/Theme/Assets.xcassets/CourseDates/ThisWeekTimelineColor.colorset/Contents.json
new file mode 100644
index 000000000..abd91436e
--- /dev/null
+++ b/Theme/Theme/Assets.xcassets/CourseDates/ThisWeekTimelineColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.392",
+ "green" : "0.286",
+ "red" : "0.239"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.624",
+ "green" : "0.533",
+ "red" : "0.475"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Theme/Theme/Assets.xcassets/CourseDates/TodayTimelineColor.colorset/Contents.json b/Theme/Theme/Assets.xcassets/CourseDates/TodayTimelineColor.colorset/Contents.json
new file mode 100644
index 000000000..3e35599d4
--- /dev/null
+++ b/Theme/Theme/Assets.xcassets/CourseDates/TodayTimelineColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "1.000",
+ "green" : "0.667",
+ "red" : "0.259"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "1.000",
+ "green" : "0.584",
+ "red" : "0.000"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Theme/Theme/Assets.xcassets/CourseDates/UpcomingTimelineColor.colorset/Contents.json b/Theme/Theme/Assets.xcassets/CourseDates/UpcomingTimelineColor.colorset/Contents.json
new file mode 100644
index 000000000..2af3cc3c3
--- /dev/null
+++ b/Theme/Theme/Assets.xcassets/CourseDates/UpcomingTimelineColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.878",
+ "green" : "0.831",
+ "red" : "0.800"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.275",
+ "green" : "0.200",
+ "red" : "0.153"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Theme/Theme/Assets.xcassets/CourseDates/pastDueTimelineColor.colorset/Contents.json b/Theme/Theme/Assets.xcassets/CourseDates/pastDueTimelineColor.colorset/Contents.json
new file mode 100644
index 000000000..a72efa461
--- /dev/null
+++ b/Theme/Theme/Assets.xcassets/CourseDates/pastDueTimelineColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.302",
+ "green" : "0.788",
+ "red" : "1.000"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.282",
+ "green" : "0.761",
+ "red" : "1.000"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Theme/Theme/SwiftGen/ThemeAssets.swift b/Theme/Theme/SwiftGen/ThemeAssets.swift
index b50937911..6796840e6 100644
--- a/Theme/Theme/SwiftGen/ThemeAssets.swift
+++ b/Theme/Theme/SwiftGen/ThemeAssets.swift
@@ -52,6 +52,13 @@ public enum ThemeAssets {
public static let textInputUnfocusedStroke = ColorAsset(name: "TextInputUnfocusedStroke")
public static let warning = ColorAsset(name: "warning")
public static let white = ColorAsset(name: "white")
+ public static let datesSectionBackground = ColorAsset(name: "DatesSectionBackground")
+ public static let datesSectionStroke = ColorAsset(name: "DatesSectionStroke")
+ public static let nextWeekTimelineColor = ColorAsset(name: "NextWeekTimelineColor")
+ public static let thisWeekTimelineColor = ColorAsset(name: "ThisWeekTimelineColor")
+ public static let todayTimelineColor = ColorAsset(name: "TodayTimelineColor")
+ public static let upcomingTimelineColor = ColorAsset(name: "UpcomingTimelineColor")
+ public static let pastDueTimelineColor = ColorAsset(name: "pastDueTimelineColor")
public static let appLogo = ImageAsset(name: "appLogo")
}
// swiftlint:enable identifier_name line_length nesting type_body_length type_name
diff --git a/Theme/Theme/Theme.swift b/Theme/Theme/Theme.swift
index fb75972e0..afc1cd7ff 100644
--- a/Theme/Theme/Theme.swift
+++ b/Theme/Theme/Theme.swift
@@ -24,6 +24,11 @@ public struct Theme {
public private(set) static var cardViewStroke = ThemeAssets.cardViewStroke.swiftUIColor
public private(set) static var certificateForeground = ThemeAssets.certificateForeground.swiftUIColor
public private(set) static var commentCellBackground = ThemeAssets.commentCellBackground.swiftUIColor
+ public private(set) static var nextWeekTimelineColor = ThemeAssets.nextWeekTimelineColor.swiftUIColor
+ public private(set) static var pastDueTimelineColor = ThemeAssets.pastDueTimelineColor.swiftUIColor
+ public private(set) static var thisWeekTimelineColor = ThemeAssets.thisWeekTimelineColor.swiftUIColor
+ public private(set) static var todayTimelineColor = ThemeAssets.todayTimelineColor.swiftUIColor
+ public private(set) static var upcomingTimelineColor = ThemeAssets.upcomingTimelineColor.swiftUIColor
public private(set) static var shadowColor = ThemeAssets.shadowColor.swiftUIColor
public private(set) static var snackbarErrorColor = ThemeAssets.snackbarErrorColor.swiftUIColor
public private(set) static var snackbarErrorTextColor = ThemeAssets.snackbarErrorTextColor.swiftUIColor
@@ -39,6 +44,8 @@ public struct Theme {
public private(set) static var warning = ThemeAssets.warning.swiftUIColor
public private(set) static var white = ThemeAssets.white.swiftUIColor
public private(set) static var loginNavigationText = ThemeAssets.loginNavigationText.swiftUIColor
+ public private(set) static var datesSectionBackground = ThemeAssets.datesSectionBackground.swiftUIColor
+ public private(set) static var datesSectionStroke = ThemeAssets.datesSectionStroke.swiftUIColor
public static func update(
accentColor: Color = ThemeAssets.accentColor.swiftUIColor,
@@ -50,6 +57,11 @@ public struct Theme {
cardViewStroke: Color = ThemeAssets.cardViewStroke.swiftUIColor,
certificateForeground: Color = ThemeAssets.certificateForeground.swiftUIColor,
commentCellBackground: Color = ThemeAssets.commentCellBackground.swiftUIColor,
+ nextWeekTimelineColor: Color = ThemeAssets.nextWeekTimelineColor.swiftUIColor,
+ pastDueTimelineColor: Color = ThemeAssets.pastDueTimelineColor.swiftUIColor,
+ thisWeekTimelineColor: Color = ThemeAssets.thisWeekTimelineColor.swiftUIColor,
+ todayTimelineColor: Color = ThemeAssets.todayTimelineColor.swiftUIColor,
+ upcomingTimelineColor: Color = ThemeAssets.upcomingTimelineColor.swiftUIColor,
shadowColor: Color = ThemeAssets.shadowColor.swiftUIColor,
snackbarErrorColor: Color = ThemeAssets.snackbarErrorColor.swiftUIColor,
snackbarErrorTextColor: Color = ThemeAssets.snackbarErrorTextColor.swiftUIColor,
@@ -63,7 +75,9 @@ public struct Theme {
textInputUnfocusedBackground: Color = ThemeAssets.textInputUnfocusedBackground.swiftUIColor,
textInputUnfocusedStroke: Color = ThemeAssets.textInputUnfocusedStroke.swiftUIColor,
warning: Color = ThemeAssets.warning.swiftUIColor,
- white: Color = ThemeAssets.white.swiftUIColor
+ white: Color = ThemeAssets.white.swiftUIColor,
+ datesSectionBackground: Color = ThemeAssets.datesSectionBackground.swiftUIColor,
+ datesSectionStroke: Color = ThemeAssets.datesSectionStroke.swiftUIColor
) {
self.accentColor = accentColor
self.alert = alert
@@ -74,6 +88,11 @@ public struct Theme {
self.cardViewStroke = cardViewStroke
self.certificateForeground = certificateForeground
self.commentCellBackground = commentCellBackground
+ self.nextWeekTimelineColor = nextWeekTimelineColor
+ self.pastDueTimelineColor = pastDueTimelineColor
+ self.thisWeekTimelineColor = thisWeekTimelineColor
+ self.todayTimelineColor = todayTimelineColor
+ self.upcomingTimelineColor = upcomingTimelineColor
self.shadowColor = shadowColor
self.snackbarErrorColor = snackbarErrorColor
self.snackbarErrorTextColor = snackbarErrorTextColor
@@ -88,6 +107,8 @@ public struct Theme {
self.textInputUnfocusedStroke = textInputUnfocusedStroke
self.warning = warning
self.white = white
+ self.datesSectionBackground = datesSectionBackground
+ self.datesSectionStroke = datesSectionStroke
}
}