diff --git a/.swiftlint.yml b/.swiftlint.yml index 757d8cacb6..78e7e0cbb6 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -342,7 +342,7 @@ legacy_nsgeometry_functions: line_length: warning: 120 - error: 120 + error: 200 ignores_urls: true ignores_comments: true ignores_interpolated_strings: true diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index 31e4b09ad3..ffabb5a10a 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -511,6 +511,8 @@ 2C8F3AE323CCBEAB004D113A /* StreamVideoQuality.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8F3AE223CCBEAB004D113A /* StreamVideoQuality.swift */; }; 2C92669720B5C7CF00525AFC /* PlaceholderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C92669520B5C7CF00525AFC /* PlaceholderTableViewCell.swift */; }; 2C92669820B5C7CF00525AFC /* PlaceholderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C92669620B5C7CF00525AFC /* PlaceholderTableViewCell.xib */; }; + 2C936D45243D3ADB00A4A4A9 /* ApplicationThemeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C936D44243D3ADB00A4A4A9 /* ApplicationThemeService.swift */; }; + 2C936D47243D3FCE00A4A4A9 /* ApplicationTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C936D46243D3FCE00A4A4A9 /* ApplicationTheme.swift */; }; 2C96E11624192ACB005EDE2B /* UIColor+DynamicColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C96E11524192ACB005EDE2B /* UIColor+DynamicColor.swift */; }; 2C9776EA24222AED0097AEFC /* UIView+TraitCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C9776E924222AED0097AEFC /* UIView+TraitCollection.swift */; }; 2C97E008215E47D8005684A1 /* SearchResultsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08C1BF271FB9ED01008F342F /* SearchResultsPresenter.swift */; }; @@ -584,7 +586,7 @@ 2CBD855C201799B700E14F83 /* AdaptiveRatingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBD855B201799B700E14F83 /* AdaptiveRatingsViewController.swift */; }; 2CC0754720177A2E004A6005 /* AdaptiveStatsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC0754620177A2E004A6005 /* AdaptiveStatsViewController.swift */; }; 2CC16BA923875DE30000EF36 /* DiscussionsSkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC16BA823875DE30000EF36 /* DiscussionsSkeletonView.swift */; }; - 2CC276FE23EB98CE00E88D6E /* UIBarButtonItem+CloseBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC276FD23EB98CE00E88D6E /* UIBarButtonItem+CloseBarButtonItem.swift */; }; + 2CC276FE23EB98CE00E88D6E /* UIBarButtonItem+StepikBarButtonItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC276FD23EB98CE00E88D6E /* UIBarButtonItem+StepikBarButtonItems.swift */; }; 2CC2770023EB9E2200E88D6E /* SubmissionsSkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC276FF23EB9E2200E88D6E /* SubmissionsSkeletonView.swift */; }; 2CC3518A1F682A02004255B6 /* SocialAuthCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC351881F682A02004255B6 /* SocialAuthCollectionViewCell.swift */; }; 2CC3518B1F682A02004255B6 /* SocialAuthCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CC351891F682A02004255B6 /* SocialAuthCollectionViewCell.xib */; }; @@ -621,7 +623,6 @@ 2CDBCCCF23EB777E005D2370 /* SubmissionURLProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CDBCCCE23EB777E005D2370 /* SubmissionURLProvider.swift */; }; 2CDE82E2221D5CCB00C41887 /* highlight.js in Resources */ = {isa = PBXBuildFile; fileRef = 2CDE82E1221D5CCB00C41887 /* highlight.js */; }; 2CE02A772176649F009C633C /* UserNotificationsCenterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE02A762176649F009C633C /* UserNotificationsCenterDelegate.swift */; }; - 2CE2425623F9FAF9004972A2 /* CourseListSeeAllTextSplitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE2425523F9FAF9004972A2 /* CourseListSeeAllTextSplitTest.swift */; }; 2CE3BCA71FBF13CE000AD405 /* SQLReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE3BCA61FBF13CE000AD405 /* SQLReply.swift */; }; 2CE42D4423CCC4530073F774 /* StreamVideoQualityStorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE42D4323CCC4530073F774 /* StreamVideoQualityStorageManager.swift */; }; 2CE42D4623CCC6500073F774 /* VideoRateStorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE42D4523CCC6500073F774 /* VideoRateStorageManager.swift */; }; @@ -1740,6 +1741,8 @@ 2C8F3AE223CCBEAB004D113A /* StreamVideoQuality.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamVideoQuality.swift; sourceTree = ""; }; 2C92669520B5C7CF00525AFC /* PlaceholderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderTableViewCell.swift; sourceTree = ""; }; 2C92669620B5C7CF00525AFC /* PlaceholderTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PlaceholderTableViewCell.xib; sourceTree = ""; }; + 2C936D44243D3ADB00A4A4A9 /* ApplicationThemeService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationThemeService.swift; sourceTree = ""; }; + 2C936D46243D3FCE00A4A4A9 /* ApplicationTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationTheme.swift; sourceTree = ""; }; 2C96E11524192ACB005EDE2B /* UIColor+DynamicColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+DynamicColor.swift"; sourceTree = ""; }; 2C9776E924222AED0097AEFC /* UIView+TraitCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+TraitCollection.swift"; sourceTree = ""; }; 2C98B6B51FDFD74C005AB72C /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = ""; }; @@ -1810,7 +1813,7 @@ 2CBF593423C8A61D00C366A1 /* Model_is_certificate_issued.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model_is_certificate_issued.xcdatamodel; sourceTree = ""; }; 2CC0754620177A2E004A6005 /* AdaptiveStatsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdaptiveStatsViewController.swift; sourceTree = ""; }; 2CC16BA823875DE30000EF36 /* DiscussionsSkeletonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscussionsSkeletonView.swift; sourceTree = ""; }; - 2CC276FD23EB98CE00E88D6E /* UIBarButtonItem+CloseBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBarButtonItem+CloseBarButtonItem.swift"; sourceTree = ""; }; + 2CC276FD23EB98CE00E88D6E /* UIBarButtonItem+StepikBarButtonItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBarButtonItem+StepikBarButtonItems.swift"; sourceTree = ""; }; 2CC276FF23EB9E2200E88D6E /* SubmissionsSkeletonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubmissionsSkeletonView.swift; sourceTree = ""; }; 2CC351851F6827BE004255B6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Auth.storyboard; sourceTree = ""; }; 2CC351881F682A02004255B6 /* SocialAuthCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocialAuthCollectionViewCell.swift; sourceTree = ""; }; @@ -1846,7 +1849,6 @@ 2CDBCCCE23EB777E005D2370 /* SubmissionURLProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubmissionURLProvider.swift; sourceTree = ""; }; 2CDE82E1221D5CCB00C41887 /* highlight.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = highlight.js; sourceTree = ""; }; 2CE02A762176649F009C633C /* UserNotificationsCenterDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationsCenterDelegate.swift; sourceTree = ""; }; - 2CE2425523F9FAF9004972A2 /* CourseListSeeAllTextSplitTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseListSeeAllTextSplitTest.swift; sourceTree = ""; }; 2CE3BCA61FBF13CE000AD405 /* SQLReply.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SQLReply.swift; sourceTree = ""; }; 2CE42D4323CCC4530073F774 /* StreamVideoQualityStorageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamVideoQualityStorageManager.swift; sourceTree = ""; }; 2CE42D4523CCC6500073F774 /* VideoRateStorageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRateStorageManager.swift; sourceTree = ""; }; @@ -2537,7 +2539,7 @@ isa = PBXGroup; children = ( 2CD063E5242A8D950052134F /* UIActivityIndicatorViewStyle+Fallback.swift */, - 2CC276FD23EB98CE00E88D6E /* UIBarButtonItem+CloseBarButtonItem.swift */, + 2CC276FD23EB98CE00E88D6E /* UIBarButtonItem+StepikBarButtonItems.swift */, 62E9866C8BA98FF768F487E2 /* UICollectionViewExtensions.swift */, 2C96E11524192ACB005EDE2B /* UIColor+DynamicColor.swift */, 08DE94381B8E3FCE00D278AB /* UIColor+Hex.swift */, @@ -2617,7 +2619,6 @@ isa = PBXGroup; children = ( 08421BCA21764FC400E8A81B /* ActiveSplitTestsContainer.swift */, - 2CE2425523F9FAF9004972A2 /* CourseListSeeAllTextSplitTest.swift */, ); path = ActiveTests; sourceTree = ""; @@ -2755,6 +2756,7 @@ 2C8F3ADF23CCBD16004D113A /* Model */ = { isa = PBXGroup; children = ( + 2C936D46243D3FCE00A4A4A9 /* ApplicationTheme.swift */, 2C20C86522F8E4BF0052E9BF /* CodeDetails.swift */, 2C20C86B22F988030052E9BF /* CodeEditorTheme.swift */, 087585BF1FB524C20047A269 /* ContentLanguage.swift */, @@ -4915,6 +4917,7 @@ children = ( 2CB9529D22A0351F00A6117A /* AssignmentsPersistenceService.swift */, 2C04BA532407C3BF00D74D4B /* AttemptsPersistenceService.swift */, + 62E98C9F5E7C0823E94A4527 /* CourseListsCollectionPersistenceService.swift */, 62E98B4C083CFD4E93597D32 /* CourseReviewsPersistenceService.swift */, 62E985BDDC6349F80D395284 /* CourseReviewSummariesPersistenceService.swift */, 62E98B706335B4BAC35D3C6D /* CoursesPersistenceService.swift */, @@ -5128,16 +5131,6 @@ path = Protocols; sourceTree = ""; }; - 62E982D07183954F2EA8A7AB /* Provider */ = { - isa = PBXGroup; - children = ( - 62E98AC3108C157422114826 /* CourseListsCollectionNetworkService.swift */, - 62E98C9F5E7C0823E94A4527 /* CourseListsCollectionPersistenceService.swift */, - 62E9817A86F42E256CC300A1 /* CourseListsCollectionProvider.swift */, - ); - path = Provider; - sourceTree = ""; - }; 62E983089C0B8189533489F8 /* InputOutput */ = { isa = PBXGroup; children = ( @@ -5224,6 +5217,7 @@ 2CDAD307229EB3F600AA9EF5 /* AssignmentsNetworkService.swift */, 2C6BBBBC22B265B300889A45 /* AttemptsNetworkService.swift */, 2C1B75B622CE1E4400262707 /* CommentsNetworkService.swift */, + 62E98AC3108C157422114826 /* CourseListsCollectionNetworkService.swift */, 62E98C33B3BE2FC29E5D3654 /* CourseReviewsNetworkService.swift */, 62E9860B3CAE0438AD4A29E7 /* CourseReviewSummariesNetworkService.swift */, 62E98F431EF3B10C63AE0575 /* CoursesNetworkService.swift */, @@ -5712,9 +5706,9 @@ 62E98C1BE7FF1711B73DBA1F /* CourseListsCollectionDataFlow.swift */, 62E9822ADB6CACBE201078D2 /* CourseListsCollectionInteractor.swift */, 62E98E8E99F0D3C5FB973A43 /* CourseListsCollectionPresenter.swift */, + 62E9817A86F42E256CC300A1 /* CourseListsCollectionProvider.swift */, 62E985F26BBBFDD8722C6B5D /* CourseListsCollectionViewController.swift */, 62E98C4A1776CAB4D0D2E381 /* CourseListsCollectionViewModel.swift */, - 62E982D07183954F2EA8A7AB /* Provider */, 62E9836D8ACC618042C17B48 /* Views */, ); path = CourseListsCollection; @@ -5968,9 +5962,11 @@ 62E98E0FB32DB9DAC0362672 /* Services */ = { isa = PBXGroup; children = ( + 2C936D44243D3ADB00A4A4A9 /* ApplicationThemeService.swift */, 2C20C86722F903D10052E9BF /* CodeEditorThemeService.swift */, 2C5E90832333DF2100288BE3 /* CodeLanguageSuggestionsService.swift */, 62E98256FF0135D7A7B59A54 /* ContentLanguageService.swift */, + 62E9847B46C78DACD9B3EE72 /* ContentLanguageSwitchAvailabilityService.swift */, 62E98EFD0E3B6DA84FCE723B /* DataBackUpdateService.swift */, 62E98E01F05F1205F284595F /* NetworkReachabilityService.swift */, 2CDAD309229EC81A00AA9EF5 /* PersistenceQueuesService.swift */, @@ -6071,7 +6067,6 @@ 62E98F31487ED7D2B320B2AA /* Explore */ = { isa = PBXGroup; children = ( - 62E9847B46C78DACD9B3EE72 /* ContentLanguageSwitchAvailabilityService.swift */, 62E98BE257BD24B6E46FD69D /* ExploreAssembly.swift */, 62E981F56E0A7BC3E740D805 /* ExploreDataFlow.swift */, 62E98CCF23A51B326FAFA51D /* ExploreInteractor.swift */, @@ -7364,13 +7359,14 @@ 62E98382AC35194D9C0CE966 /* UITableViewExtensions.swift in Sources */, 62E98C3B15ABFA56C29FEC3B /* UICollectionViewExtensions.swift in Sources */, 62E98116576B12451E5418F4 /* CourseCoverImageView.swift in Sources */, + 2C936D45243D3ADB00A4A4A9 /* ApplicationThemeService.swift in Sources */, 2C7F641C23B0F5B7006C7648 /* PlayNextCircleControlView.swift in Sources */, 62E98C3824298B04928351E5 /* FormatterHelper.swift in Sources */, 2CF10C8B238426B300F8CC95 /* StepSourcesNetworkService.swift in Sources */, 2C04BA47240726BA00D74D4B /* SubmissionEntity+CoreDataProperties.swift in Sources */, 2CD6E25F234E392900F49303 /* EmailAddressesNetworkService.swift in Sources */, 62E9862FEEA0320F590E1C3D /* UniqueIdentifiable.swift in Sources */, - 2CC276FE23EB98CE00E88D6E /* UIBarButtonItem+CloseBarButtonItem.swift in Sources */, + 2CC276FE23EB98CE00E88D6E /* UIBarButtonItem+StepikBarButtonItems.swift in Sources */, 62E98D1BBD212BF163DCAF48 /* SectionsPersistenceService.swift in Sources */, 62E98490B6A6BF294A86E6E6 /* UnitsPersistenceService.swift in Sources */, 62E98D1D1B374D09B4E6EAA5 /* LessonsPersistenceService.swift in Sources */, @@ -7387,7 +7383,6 @@ 2C20778422BBA54800D44DC0 /* QuizStatus.swift in Sources */, 62E980F97C42FABD40DC27D6 /* TooltipStorageManager.swift in Sources */, 2CBBCB9A23980ED6006D6C15 /* WeakBox.swift in Sources */, - 2CE2425623F9FAF9004972A2 /* CourseListSeeAllTextSplitTest.swift in Sources */, 2C3ABA8D23D1FE1D00E90439 /* StepikSocialNetwork.swift in Sources */, 2C20778022BB897200D44DC0 /* DispatchQueue+Promise.swift in Sources */, 62E982132F6F132B7B228D1D /* UserAccountService.swift in Sources */, @@ -7804,6 +7799,7 @@ 62E980B8758DEF7D06A56FB5 /* WriteCommentSolutionControl.swift in Sources */, 62E980D610A476A99FF7CAF4 /* WriteCourseReviewAssembly.swift in Sources */, 62E9852E9E2178B0917B73F6 /* WriteCourseReviewDataFlow.swift in Sources */, + 2C936D47243D3FCE00A4A4A9 /* ApplicationTheme.swift in Sources */, 62E98D63AAEB2656634F9AF9 /* WriteCourseReviewInteractor.swift in Sources */, 62E98EC31C92264863CBA7AC /* WriteCourseReviewPresenter.swift in Sources */, 62E98E1B5B67C786076FD6E8 /* WriteCourseReviewProvider.swift in Sources */, @@ -8163,7 +8159,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 194; + CURRENT_PROJECT_VERSION = 196; DEVELOPMENT_TEAM = UJ4KC2QN7B; ENABLE_BITCODE = YES; INFOPLIST_FILE = Stepic/Info.plist; @@ -8193,7 +8189,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 194; + CURRENT_PROJECT_VERSION = 196; DEVELOPMENT_TEAM = UJ4KC2QN7B; ENABLE_BITCODE = YES; INFOPLIST_FILE = Stepic/Info.plist; diff --git a/Stepic/Images.xcassets/lesson_cover_50.imageset/Contents.json b/Stepic/Images.xcassets/lesson_cover_50.imageset/Contents.json index 0d6b3a2bfc..67727c7350 100644 --- a/Stepic/Images.xcassets/lesson_cover_50.imageset/Contents.json +++ b/Stepic/Images.xcassets/lesson_cover_50.imageset/Contents.json @@ -1,23 +1,56 @@ { "images" : [ { - "idiom" : "universal", "filename" : "lesson_cover_50.png", + "idiom" : "universal", "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "general_placeholder.png", "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "lesson_cover_50@2x.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "general_placeholder@2x.png", "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "lesson_cover_50@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "general_placeholder@3x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/Stepic/Images.xcassets/lesson_cover_50.imageset/general_placeholder.png b/Stepic/Images.xcassets/lesson_cover_50.imageset/general_placeholder.png new file mode 100644 index 0000000000..31286bedcd Binary files /dev/null and b/Stepic/Images.xcassets/lesson_cover_50.imageset/general_placeholder.png differ diff --git a/Stepic/Images.xcassets/lesson_cover_50.imageset/general_placeholder@2x.png b/Stepic/Images.xcassets/lesson_cover_50.imageset/general_placeholder@2x.png new file mode 100644 index 0000000000..37d161938b Binary files /dev/null and b/Stepic/Images.xcassets/lesson_cover_50.imageset/general_placeholder@2x.png differ diff --git a/Stepic/Images.xcassets/lesson_cover_50.imageset/general_placeholder@3x.png b/Stepic/Images.xcassets/lesson_cover_50.imageset/general_placeholder@3x.png new file mode 100644 index 0000000000..021f869c91 Binary files /dev/null and b/Stepic/Images.xcassets/lesson_cover_50.imageset/general_placeholder@3x.png differ diff --git a/Stepic/Info.plist b/Stepic/Info.plist index 2ccb743274..424a46a4c3 100644 --- a/Stepic/Info.plist +++ b/Stepic/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.118 + 1.119 CFBundleSignature ???? CFBundleURLTypes @@ -54,7 +54,7 @@ CFBundleVersion - 194 + 196 Fabric APIKey diff --git a/Stepic/Legacy/Analytics/AnalyticsReporter.swift b/Stepic/Legacy/Analytics/AnalyticsReporter.swift index 46e22bcd27..22795dba6a 100644 --- a/Stepic/Legacy/Analytics/AnalyticsReporter.swift +++ b/Stepic/Legacy/Analytics/AnalyticsReporter.swift @@ -4,7 +4,7 @@ import Foundation import YandexMobileMetrica final class AnalyticsReporter { - private init() { } + private init() {} static func reportEvent(_ event: String, parameters: [String: Any]? = nil) { let params = parameters as? [String: NSObject] diff --git a/Stepic/Legacy/Analytics/SplitTests/ActiveTests/ActiveSplitTestsContainer.swift b/Stepic/Legacy/Analytics/SplitTests/ActiveTests/ActiveSplitTestsContainer.swift index 327a7925be..51e54c3fa8 100644 --- a/Stepic/Legacy/Analytics/SplitTests/ActiveTests/ActiveSplitTestsContainer.swift +++ b/Stepic/Legacy/Analytics/SplitTests/ActiveTests/ActiveSplitTestsContainer.swift @@ -15,6 +15,6 @@ final class ActiveSplitTestsContainer { ) static func setActiveTestsGroups() { - self.splitTestingService.fetchSplitTest(CourseListSeeAllTextSplitTest.self).setSplitTestGroup() + // There are no A/B tests now } } diff --git a/Stepic/Legacy/Analytics/SplitTests/ActiveTests/CourseListSeeAllTextSplitTest.swift b/Stepic/Legacy/Analytics/SplitTests/ActiveTests/CourseListSeeAllTextSplitTest.swift deleted file mode 100644 index 0879ece334..0000000000 --- a/Stepic/Legacy/Analytics/SplitTests/ActiveTests/CourseListSeeAllTextSplitTest.swift +++ /dev/null @@ -1,38 +0,0 @@ -import Foundation - -final class CourseListSeeAllTextSplitTest: SplitTestProtocol { - typealias GroupType = Group - - static let identifier = "course_list_see_all_text" - static let minParticipatingStartVersion = "1.113" - - var currentGroup: Group - var analytics: ABAnalyticsServiceProtocol - - init(currentGroup: Group, analytics: ABAnalyticsServiceProtocol) { - self.currentGroup = currentGroup - self.analytics = analytics - } - - enum Group: String, SplitTestGroupProtocol, CaseIterable { - case control = "control" - case testDetailIndicator = "test_detail_indicator" - case testText = "test_text" - case testTextDetailIndicator = "test_text_detail_indicator" - - static var groups: [Group] = Self.allCases - - var seeAllTitle: String { - switch self { - case .control: - return NSLocalizedString("ShowAll", comment: "") - case .testDetailIndicator: - return NSLocalizedString("ShowAllTestDetailIndicator", comment: "") - case .testText: - return NSLocalizedString("ShowAllTestText", comment: "") - case .testTextDetailIndicator: - return NSLocalizedString("ShowAllTestTextDetailIndicator", comment: "") - } - } - } -} diff --git a/Stepic/Legacy/AppDelegate.swift b/Stepic/Legacy/AppDelegate.swift index bb39c817bc..1bd30ac354 100644 --- a/Stepic/Legacy/AppDelegate.swift +++ b/Stepic/Legacy/AppDelegate.swift @@ -48,9 +48,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate { NotificationsBadgesManager.shared.setup() RemoteConfig.shared.setup() + RemoteConfig.shared.loadingDoneCallback = { + ApplicationThemeService().registerDefaultTheme() + } SVProgressHUD.setMinimumDismissTimeInterval(0.5) SVProgressHUD.setDefaultMaskType(SVProgressHUDMaskType.clear) + SVProgressHUD.setDefaultStyle(SVProgressHUDStyle.light) SVProgressHUD.setHapticsEnabled(true) ConnectionHelper.shared.instantiate() @@ -116,9 +120,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { self.branchService.setup(launchOptions: launchOptions) - if #available(iOS 13.0, *) { - self.window?.overrideUserInterfaceStyle = .light - } + ApplicationThemeService().registerDefaultTheme() return true } diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/CardStep/CardStepDelegate.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/CardStep/CardStepDelegate.swift index 89032a060d..a84d72ca07 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/CardStep/CardStepDelegate.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/CardStep/CardStepDelegate.swift @@ -17,9 +17,9 @@ protocol CardStepDelegate: AnyObject { } extension CardStepDelegate { - func stepSubmissionDidCorrect() { } - func stepSubmissionDidWrong() { } - func stepSubmissionDidRetry() { } - func contentLoadingDidFail() { } - func contentLoadingDidComplete() { } + func stepSubmissionDidCorrect() {} + func stepSubmissionDidWrong() {} + func stepSubmissionDidRetry() {} + func contentLoadingDidFail() {} + func contentLoadingDidComplete() {} } diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/CardStep/OnboardingCardStepViewController.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/CardStep/OnboardingCardStepViewController.swift index 3785498b26..6e1ea70a8d 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/CardStep/OnboardingCardStepViewController.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/CardStep/OnboardingCardStepViewController.swift @@ -20,11 +20,27 @@ final class OnboardingCardStepViewController: CardStepViewController { let step = self.loadOnboardingStep(from: "step\(self.stepIndex!)") + let styles = """ + +""" // Add small top padding let processor = HTMLProcessor(html: step.text ?? "") let html = processor .injectDefault() - .inject(script: .customHead(head: "")) + .inject(script: .customHead(head: styles)) .html self.stepWebView.loadHTMLString(html, baseURL: step.baseURL) diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/CardsSteps/BaseCardsStepsViewController.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/CardsSteps/BaseCardsStepsViewController.swift index a1b72d98d9..fb1cfbdfa2 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/CardsSteps/BaseCardsStepsViewController.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/CardsSteps/BaseCardsStepsViewController.swift @@ -101,7 +101,7 @@ final class BaseCardsStepsViewController: CardsStepsViewController { self.shadowViewHeight.constant = 0.5 self.statusBarPad = UIView() - self.statusBarPad?.backgroundColor = .stepikBackground + self.statusBarPad?.backgroundColor = .stepikNavigationBarBackground if let padView = self.statusBarPad { self.view.insertSubview(padView, at: 0) } @@ -138,14 +138,14 @@ final class BaseCardsStepsViewController: CardsStepsViewController { } private func updateAppearance() { - self.view.backgroundColor = .stepikBackground + self.view.backgroundColor = .dynamic(light: .stepikLightSecondaryBackground, dark: .stepikBackground) self.kolodaView.backgroundColor = .clear self.progressBar.progressTintColor = .stepikGreen - self.shadowView.backgroundColor = .stepikOpaqueSeparator - self.trophyButton.tintColor = .stepikAccent - self.backButton.tintColor = .stepikAccent - self.expLabel.textColor = .stepikAccent - self.levelLabel.textColor = .stepikAccent + self.shadowView.backgroundColor = .dynamic(light: .stepikOpaqueSeparator, dark: .clear) + self.trophyButton.tintColor = .stepikPrimaryText + self.backButton.tintColor = .stepikPrimaryText + self.expLabel.textColor = .stepikPrimaryText + self.levelLabel.textColor = .stepikPrimaryText } @IBAction diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveRatings/AdaptiveRatingsViewController.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveRatings/AdaptiveRatingsViewController.swift index 6ab4f58852..8b703e4f1e 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveRatings/AdaptiveRatingsViewController.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveRatings/AdaptiveRatingsViewController.swift @@ -106,7 +106,7 @@ final class AdaptiveRatingsViewController: UIViewController { self.view.backgroundColor = .stepikBackground self.loadingIndicator.color = .stepikLoadingIndicator self.ratingSegmentedControl.tintColor = .stepikAccent - self.allCountLabel.textColor = .stepikGray2 + self.allCountLabel.textColor = .stepikSystemGray2 } private func localize() { diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveStats/AdaptiveStatsViewController.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveStats/AdaptiveStatsViewController.swift index a1b2913389..a383ce6051 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveStats/AdaptiveStatsViewController.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveStats/AdaptiveStatsViewController.swift @@ -120,13 +120,13 @@ final class AdaptiveStatsViewController: UIViewController { self.levelTitleLabel, self.streakTitleLabel, self.xpPer7DaysTitleLabel - ].forEach { $0?.textColor = .stepikGray } + ].forEach { $0?.textColor = .stepikSystemGray } [ self.last7DaysTitleLabel, self.progressByWeeksTitleLabel, self.allCountLabel - ].forEach { $0?.textColor = .stepikGray2 } + ].forEach { $0?.textColor = .stepikSystemGray2 } [ self.mainStatHorizontalSeparator, diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveStatsPagerViewController.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveStatsPagerViewController.swift index 80b957485c..87af050be2 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveStatsPagerViewController.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/AdaptiveStatsPagerViewController.swift @@ -30,10 +30,11 @@ final class AdaptiveStatsPagerViewController: PagerController { self.indicatorHeight = 1.5 self.centerCurrentTab = true self.indicatorColor = .stepikAccent - self.selectedTabTextColor = .stepikAccent - self.tabsTextColor = .stepikAccent - self.tabsTextFont = UIFont.systemFont(ofSize: 16.0, weight: UIFont.Weight.light) - self.tabsViewBackgroundColor = .stepikBackground + self.selectedTabTextColor = .stepikPrimaryText + self.tabsTextColor = .stepikPrimaryText + self.tabsTextFont = UIFont.systemFont(ofSize: 16.0, weight: .light) + self.tabsViewBackgroundColor = .stepikNavigationBarBackground + self.contentViewBackgroundColor = .stepikBackground } internal func controllerForSection(_ section: AdaptiveStatsSection) -> UIViewController { diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/Views/LeaderboardTableViewCell/LeaderboardTableViewCell.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/Views/LeaderboardTableViewCell/LeaderboardTableViewCell.swift index 28b4507138..4d21ed4265 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/Views/LeaderboardTableViewCell/LeaderboardTableViewCell.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/Views/LeaderboardTableViewCell/LeaderboardTableViewCell.swift @@ -18,6 +18,12 @@ final class LeaderboardTableViewCell: UITableViewCell { @IBOutlet weak var separatorImageView: UIImageView! private var isMe: Bool = false + private var isMeBackgroundColor: UIColor { + .dynamic( + light: UIColor.stepikYellow.withAlphaComponent(0.4), + dark: UIColor.stepikYellow.withAlphaComponent(0.1) + ) + } var isSeparator: Bool = false { didSet { @@ -59,7 +65,7 @@ final class LeaderboardTableViewCell: UITableViewCell { self.isMe = isMe if isMe { - self.backgroundColor = .stepikYellow + self.backgroundColor = self.isMeBackgroundColor self.userLabel.text = NSLocalizedString("AdaptiveRatingYou", comment: "") } } @@ -83,10 +89,10 @@ final class LeaderboardTableViewCell: UITableViewCell { } private func colorize() { - self.backgroundColor = self.isMe ? .stepikYellow : .clear - self.separatorImageView.tintColor = .stepikOpaqueSeparator - self.userLabel.textColor = .stepikGray - self.positionLabel.textColor = .stepikGray - self.expLabel.textColor = .stepikGray2 + self.backgroundColor = self.isMe ? self.isMeBackgroundColor : .clear + self.separatorImageView.tintColor = .stepikSeparator + self.userLabel.textColor = .stepikSystemGray + self.positionLabel.textColor = .stepikSystemGray + self.expLabel.textColor = .stepikSystemGray2 } } diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/Views/ProgressTableViewCell/ProgressTableViewCell.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/Views/ProgressTableViewCell/ProgressTableViewCell.swift index 5aa75e892f..2b0d29b1e1 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/Views/ProgressTableViewCell/ProgressTableViewCell.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/Stats/Views/ProgressTableViewCell/ProgressTableViewCell.swift @@ -53,7 +53,7 @@ final class ProgressTableViewCell: UITableViewCell { self.xpPerWeekTitleLabel, self.firstDateLabel, self.secondDateLabel - ].forEach { $0.textColor = .stepikGray } + ].forEach { $0.textColor = .stepikSystemGray } self.bracketLabel.textColor = .stepikAccent } diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/Views/StepCardView/StepCardView.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/Views/StepCardView/StepCardView.swift index beaf32cb5e..71bcc69493 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/Views/StepCardView/StepCardView.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/Views/StepCardView/StepCardView.swift @@ -15,8 +15,8 @@ protocol StepCardViewDelegate: AnyObject { } extension StepCardViewDelegate { - func onControlButtonClick() { } - func onTitleButtonClick() { } + func onControlButtonClick() {} + func onTitleButtonClick() {} } final class StepCardView: NibInitializableView { @@ -167,7 +167,7 @@ final class StepCardView: NibInitializableView { } self.titlePadView.backgroundColor = .clear - self.titleLabel.textColor = .stepikSystemLabel + self.titleLabel.textColor = .stepikSystemPrimaryText self.titleButton.superview?.tintColor = .stepikAccent self.titleSeparatorView.backgroundColor = .stepikSeparator diff --git a/Stepic/Legacy/Controllers/AdaptiveSteps/Views/StepReversedCardView.swift b/Stepic/Legacy/Controllers/AdaptiveSteps/Views/StepReversedCardView.swift index c35da691a6..f29f8fd361 100644 --- a/Stepic/Legacy/Controllers/AdaptiveSteps/Views/StepReversedCardView.swift +++ b/Stepic/Legacy/Controllers/AdaptiveSteps/Views/StepReversedCardView.swift @@ -19,16 +19,8 @@ final class StepReversedCardView: UIView { override func layoutSubviews() { super.layoutSubviews() - if #available(iOS 13.0, *), self.traitCollection.userInterfaceStyle == .dark { - self.backgroundColor = .stepikSecondaryBackground - } else { - self.backgroundColor = .stepikBackground - } - + self.backgroundColor = .dynamic(light: .stepikBackground, dark: .stepikSecondaryBackground) self.layer.cornerRadius = 12 - self.layer.borderWidth = 0.5 - self.layer.borderColor = UIColor.stepikOpaqueSeparator.cgColor - self.whiteView.frame = self.bounds } } diff --git a/Stepic/Legacy/Controllers/Certificates/CertificatesViewController.swift b/Stepic/Legacy/Controllers/Certificates/CertificatesViewController.swift index 3969a43511..3e28bd7292 100644 --- a/Stepic/Legacy/Controllers/Certificates/CertificatesViewController.swift +++ b/Stepic/Legacy/Controllers/Certificates/CertificatesViewController.swift @@ -105,7 +105,7 @@ final class CertificatesViewController: UIViewController, ControllerWithStepikPl presenter?.getCachedCertificates() presenter?.refreshCertificates() - tableView.backgroundColor = .stepikGroupTableViewBackground + tableView.backgroundColor = .stepikGroupedBackground tableView.contentInsetAdjustmentBehavior = .never DispatchQueue.main.async { diff --git a/Stepic/Legacy/Controllers/Courses/SearchQueries/SearchQueriesView/SearchSuggestionTableViewCell.swift b/Stepic/Legacy/Controllers/Courses/SearchQueries/SearchQueriesView/SearchSuggestionTableViewCell.swift index 4cfcec576b..78f5b3bedb 100644 --- a/Stepic/Legacy/Controllers/Courses/SearchQueries/SearchQueriesView/SearchSuggestionTableViewCell.swift +++ b/Stepic/Legacy/Controllers/Courses/SearchQueries/SearchQueriesView/SearchSuggestionTableViewCell.swift @@ -23,7 +23,7 @@ final class SearchSuggestionTableViewCell: UITableViewCell { string: suggestion, attributes: [ NSAttributedString.Key.font: regularFont, - NSAttributedString.Key.foregroundColor: UIColor.stepikSystemSecondaryLabel + NSAttributedString.Key.foregroundColor: UIColor.stepikSystemSecondaryText ] ) diff --git a/Stepic/Legacy/Controllers/Notifications/Helpers/NotificationsBadgesManager.swift b/Stepic/Legacy/Controllers/Notifications/Helpers/NotificationsBadgesManager.swift index 3745ac5644..7ef963b64b 100644 --- a/Stepic/Legacy/Controllers/Notifications/Helpers/NotificationsBadgesManager.swift +++ b/Stepic/Legacy/Controllers/Notifications/Helpers/NotificationsBadgesManager.swift @@ -33,7 +33,7 @@ final class NotificationsBadgesManager { NotificationCenter.default.removeObserver(self) } - func setup() { } + func setup() {} @objc func didNotificationUpdate(systemNotification: Foundation.Notification) { guard let userInfo = systemNotification.userInfo, diff --git a/Stepic/Legacy/Controllers/Notifications/NotificationsPagerViewController.swift b/Stepic/Legacy/Controllers/Notifications/NotificationsPagerViewController.swift index 5109d7af37..079543620f 100644 --- a/Stepic/Legacy/Controllers/Notifications/NotificationsPagerViewController.swift +++ b/Stepic/Legacy/Controllers/Notifications/NotificationsPagerViewController.swift @@ -56,7 +56,7 @@ final class NotificationsPagerViewController: PagerController, ControllerWithSte self.selectedTabTextColor = .stepikAccent self.tabsTextColor = .stepikAccent self.tabsTextFont = .systemFont(ofSize: 16.0, weight: UIFont.Weight.light) - self.tabsViewBackgroundColor = .stepikBackground + self.tabsViewBackgroundColor = .stepikNavigationBarBackground self.contentViewBackgroundColor = .stepikBackground } diff --git a/Stepic/Legacy/Controllers/Notifications/NotificationsSectionHeaderView/NotificationsSectionHeaderView.swift b/Stepic/Legacy/Controllers/Notifications/NotificationsSectionHeaderView/NotificationsSectionHeaderView.swift index dc77c5f2d2..439d4eca68 100644 --- a/Stepic/Legacy/Controllers/Notifications/NotificationsSectionHeaderView/NotificationsSectionHeaderView.swift +++ b/Stepic/Legacy/Controllers/Notifications/NotificationsSectionHeaderView/NotificationsSectionHeaderView.swift @@ -28,9 +28,15 @@ final class NotificationsSectionHeaderView: UITableViewHeaderFooterView { @IBOutlet weak var rightLabel: UILabel! @IBOutlet var topSeparatorView: UIView! @IBOutlet var bottomSeparatorView: UIView! + @IBOutlet var topSeparatorHeightConstraint: NSLayoutConstraint! + @IBOutlet var bottomSeparatorHeightConstraint: NSLayoutConstraint! override func awakeFromNib() { super.awakeFromNib() + + self.topSeparatorHeightConstraint.constant = 0.5 + self.bottomSeparatorHeightConstraint.constant = 0.5 + self.colorize() } @@ -48,11 +54,9 @@ final class NotificationsSectionHeaderView: UITableViewHeaderFooterView { } private func colorize() { - if #available(iOS 13.0, *), self.traitCollection.userInterfaceStyle == .dark { - self.backgroundColorView.backgroundColor = .stepikSecondaryBackground - } else { - self.backgroundColorView.backgroundColor = .stepikBackground - } + self.backgroundColorView.backgroundColor = self.isDarkInterfaceStyle + ? .stepikSecondaryBackground + : .stepikBackground self.leftLabel.textColor = .stepikPrimaryText self.rightLabel.textColor = .stepikPrimaryText diff --git a/Stepic/Legacy/Controllers/Notifications/NotificationsSectionHeaderView/NotificationsSectionHeaderView.xib b/Stepic/Legacy/Controllers/Notifications/NotificationsSectionHeaderView/NotificationsSectionHeaderView.xib index b6965d762c..10cd9238ea 100644 --- a/Stepic/Legacy/Controllers/Notifications/NotificationsSectionHeaderView/NotificationsSectionHeaderView.xib +++ b/Stepic/Legacy/Controllers/Notifications/NotificationsSectionHeaderView/NotificationsSectionHeaderView.xib @@ -1,9 +1,9 @@ - + - + @@ -25,7 +25,6 @@ - @@ -38,14 +37,13 @@ - @@ -56,8 +54,8 @@ + - @@ -67,9 +65,11 @@ + + diff --git a/Stepic/Legacy/Controllers/Notifications/NotificationsTableViewCell/NotificationsTableViewCell.swift b/Stepic/Legacy/Controllers/Notifications/NotificationsTableViewCell/NotificationsTableViewCell.swift index f85d9d1e5a..cb6a185449 100644 --- a/Stepic/Legacy/Controllers/Notifications/NotificationsTableViewCell/NotificationsTableViewCell.swift +++ b/Stepic/Legacy/Controllers/Notifications/NotificationsTableViewCell/NotificationsTableViewCell.swift @@ -74,7 +74,7 @@ final class NotificationsTableViewCell: UITableViewCell { private func colorize() { self.timeLabel.textColor = .stepikPrimaryText self.sectionLabel.textColor = .stepikAccentFixed - self.sectionLabel.backgroundColor = .stepikSecondaryBackground + self.sectionLabel.backgroundColor = .stepikLightSecondaryBackground } func update(with notification: NotificationViewData) { diff --git a/Stepic/Legacy/Controllers/PersonalDeadlines/PersonalDeadlineModeCollectionViewCell/PersonalDeadlineModeCollectionViewCell.swift b/Stepic/Legacy/Controllers/PersonalDeadlines/PersonalDeadlineModeCollectionViewCell/PersonalDeadlineModeCollectionViewCell.swift index 1bc98e23bd..fd2c341d34 100644 --- a/Stepic/Legacy/Controllers/PersonalDeadlines/PersonalDeadlineModeCollectionViewCell/PersonalDeadlineModeCollectionViewCell.swift +++ b/Stepic/Legacy/Controllers/PersonalDeadlines/PersonalDeadlineModeCollectionViewCell/PersonalDeadlineModeCollectionViewCell.swift @@ -55,7 +55,7 @@ final class PersonalDeadlineModeCollectionViewCell: UICollectionViewCell { private func colorize() { self.contentView.layer.borderColor = UIColor.stepikSeparator.cgColor - self.titleLabel.textColor = .stepikSystemLabel - self.loadLabel.textColor = .stepikSystemSecondaryLabel + self.titleLabel.textColor = .stepikSystemPrimaryText + self.loadLabel.textColor = .stepikSystemSecondaryText } } diff --git a/Stepic/Legacy/Controllers/PersonalDeadlines/PersonalDeadlinesModeSelectionViewController.swift b/Stepic/Legacy/Controllers/PersonalDeadlines/PersonalDeadlinesModeSelectionViewController.swift index 2de1ae1350..7785713eab 100644 --- a/Stepic/Legacy/Controllers/PersonalDeadlines/PersonalDeadlinesModeSelectionViewController.swift +++ b/Stepic/Legacy/Controllers/PersonalDeadlines/PersonalDeadlinesModeSelectionViewController.swift @@ -139,7 +139,7 @@ final class PersonalDeadlinesModeSelectionViewController: UIViewController { private func colorize() { self.view.backgroundColor = .stepikAlertBackground - self.questionLabel.textColor = .stepikSystemLabel + self.questionLabel.textColor = .stepikSystemPrimaryText self.cancelButton.setTitleColor(.stepikPrimaryText, for: .normal) } diff --git a/Stepic/Legacy/Controllers/Placeholders/StepikPlaceholderView/StepikPlaceholderView.swift b/Stepic/Legacy/Controllers/Placeholders/StepikPlaceholderView/StepikPlaceholderView.swift index 7c3f934afa..f2ee2ca24c 100644 --- a/Stepic/Legacy/Controllers/Placeholders/StepikPlaceholderView/StepikPlaceholderView.swift +++ b/Stepic/Legacy/Controllers/Placeholders/StepikPlaceholderView/StepikPlaceholderView.swift @@ -76,7 +76,7 @@ final class StepikPlaceholderView: NibInitializableView { private func colorize() { self.view.backgroundColor = .stepikBackground - self.textLabel.textColor = .stepikSystemSecondaryLabel + self.textLabel.textColor = .stepikSystemSecondaryText self.actionButton.layer.borderColor = UIColor.stepikOpaqueSeparator.cgColor self.actionButton.setTitleColor(.stepikPrimaryText, for: .normal) } diff --git a/Stepic/Legacy/Controllers/Profile/Achievements/List/AchievementCell/AchievementsListTableViewCell.swift b/Stepic/Legacy/Controllers/Profile/Achievements/List/AchievementCell/AchievementsListTableViewCell.swift index 8a2784e0c9..cc46f02372 100644 --- a/Stepic/Legacy/Controllers/Profile/Achievements/List/AchievementCell/AchievementsListTableViewCell.swift +++ b/Stepic/Legacy/Controllers/Profile/Achievements/List/AchievementCell/AchievementsListTableViewCell.swift @@ -20,14 +20,12 @@ final class AchievementsListTableViewCell: UITableViewCell { override func layoutSubviews() { super.layoutSubviews() - if #available(iOS 13.0, *), self.traitCollection.userInterfaceStyle == .dark { - self.contentView.backgroundColor = .stepikSecondaryBackground - } else { - self.contentView.backgroundColor = .stepikBackground - } + self.contentView.backgroundColor = self.isDarkInterfaceStyle + ? .stepikSecondaryBackground + : .stepikBackground self.achievementName.textColor = .stepikPrimaryText - self.achievementDescription.textColor = .stepikSystemSecondaryLabel + self.achievementDescription.textColor = .stepikSystemSecondaryText } func update(with viewData: AchievementViewData) { diff --git a/Stepic/Legacy/Controllers/Profile/Achievements/List/AchievementsListViewController.swift b/Stepic/Legacy/Controllers/Profile/Achievements/List/AchievementsListViewController.swift index 09f0761986..aabdd4a2b8 100644 --- a/Stepic/Legacy/Controllers/Profile/Achievements/List/AchievementsListViewController.swift +++ b/Stepic/Legacy/Controllers/Profile/Achievements/List/AchievementsListViewController.swift @@ -31,7 +31,7 @@ final class AchievementsListViewController: UIViewController, AchievementsListVi for: .connectionError ) - self.tableView.backgroundColor = .stepikGroupTableViewBackground + self.tableView.backgroundColor = .stepikGroupedBackground self.tableView.skeleton.viewBuilder = { UIView.fromNib(named: "AchievementListSkeletonPlaceholderView") } self.tableView.register( diff --git a/Stepic/Legacy/Controllers/Profile/Menu/MenuBlockCells/ContentMenuBlockTableViewCell/ContentMenuBlockTableViewCell.swift b/Stepic/Legacy/Controllers/Profile/Menu/MenuBlockCells/ContentMenuBlockTableViewCell/ContentMenuBlockTableViewCell.swift index c3ceccf4c2..397ae50955 100644 --- a/Stepic/Legacy/Controllers/Profile/Menu/MenuBlockCells/ContentMenuBlockTableViewCell/ContentMenuBlockTableViewCell.swift +++ b/Stepic/Legacy/Controllers/Profile/Menu/MenuBlockCells/ContentMenuBlockTableViewCell/ContentMenuBlockTableViewCell.swift @@ -37,7 +37,7 @@ final class ContentMenuBlockTableViewCell: MenuBlockTableViewCell { super.colorize() self.titleLabel.textColor = .stepikPrimaryText - self.actionButton.setTitleColor(.stepikSystemSecondaryLabel, for: .normal) + self.actionButton.setTitleColor(.stepikSystemSecondaryText, for: .normal) } @IBAction diff --git a/Stepic/Legacy/Controllers/Quizzes/BaseQuiz/QuizControllerDelegate.swift b/Stepic/Legacy/Controllers/Quizzes/BaseQuiz/QuizControllerDelegate.swift index 3cc5d832bf..d20a8728d9 100644 --- a/Stepic/Legacy/Controllers/Quizzes/BaseQuiz/QuizControllerDelegate.swift +++ b/Stepic/Legacy/Controllers/Quizzes/BaseQuiz/QuizControllerDelegate.swift @@ -16,10 +16,10 @@ protocol QuizControllerDelegate: AnyObject { } extension QuizControllerDelegate { - func submissionDidCorrect() { } - func submissionDidWrong() { } - func submissionDidRetry() { } - func didWarningPlaceholderShow() { } + func submissionDidCorrect() {} + func submissionDidWrong() {} + func submissionDidRetry() {} + func didWarningPlaceholderShow() {} } protocol QuizControllerDataSource: AnyObject { diff --git a/Stepic/Legacy/Controllers/Quizzes/CodeQuiz/InputAccessory/Toolbar/CodeInputAccessoryCollectionViewCell/CodeInputAccessoryCollectionViewCell.swift b/Stepic/Legacy/Controllers/Quizzes/CodeQuiz/InputAccessory/Toolbar/CodeInputAccessoryCollectionViewCell/CodeInputAccessoryCollectionViewCell.swift index ace298b239..2abcf61311 100644 --- a/Stepic/Legacy/Controllers/Quizzes/CodeQuiz/InputAccessory/Toolbar/CodeInputAccessoryCollectionViewCell/CodeInputAccessoryCollectionViewCell.swift +++ b/Stepic/Legacy/Controllers/Quizzes/CodeQuiz/InputAccessory/Toolbar/CodeInputAccessoryCollectionViewCell/CodeInputAccessoryCollectionViewCell.swift @@ -29,7 +29,7 @@ final class CodeInputAccessoryCollectionViewCell: UICollectionViewCell { super.layoutSubviews() self.backgroundColor = .stepikTertiaryBackground - self.textLabel.textColor = .stepikSystemLabel + self.textLabel.textColor = .stepikSystemPrimaryText } func initialize(text: String, size: CodeInputAccessorySize) { diff --git a/Stepic/Legacy/Controllers/RegistrationSignIn/AuthEmail/EmailAuthViewController.swift b/Stepic/Legacy/Controllers/RegistrationSignIn/AuthEmail/EmailAuthViewController.swift index db419f28e9..ace148c1b4 100644 --- a/Stepic/Legacy/Controllers/RegistrationSignIn/AuthEmail/EmailAuthViewController.swift +++ b/Stepic/Legacy/Controllers/RegistrationSignIn/AuthEmail/EmailAuthViewController.swift @@ -55,7 +55,7 @@ final class EmailAuthViewController: UIViewController { @IBOutlet var inputSeparator: UIView! @IBOutlet weak var separatorHeight: NSLayoutConstraint! - private lazy var closeBarButtonItem = UIBarButtonItem.closeBarButtonItem( + private lazy var closeBarButtonItem = UIBarButtonItem.stepikCloseBarButtonItem( target: self, action: #selector(self.onCloseClick(_:)) ) diff --git a/Stepic/Legacy/Controllers/RegistrationSignIn/AuthSocial/SocialAuthCollectionViewCell/SocialAuthCollectionViewCell.swift b/Stepic/Legacy/Controllers/RegistrationSignIn/AuthSocial/SocialAuthCollectionViewCell/SocialAuthCollectionViewCell.swift index 7d0de8bb8f..c321990783 100644 --- a/Stepic/Legacy/Controllers/RegistrationSignIn/AuthSocial/SocialAuthCollectionViewCell/SocialAuthCollectionViewCell.swift +++ b/Stepic/Legacy/Controllers/RegistrationSignIn/AuthSocial/SocialAuthCollectionViewCell/SocialAuthCollectionViewCell.swift @@ -9,6 +9,14 @@ import UIKit final class SocialAuthCollectionViewCell: UICollectionViewCell { + enum Appearance { + static let shadowColor = UIColor.dynamic(light: UIColor(hex6: 0xBBBBBB), dark: .clear) + static let backgroundColor = UIColor.dynamic( + light: .stepikBackground, + dark: .stepikSecondaryBackground + ) + } + static let reuseId = "socialAuthCell" @IBOutlet weak var imageView: UIImageView! @@ -34,7 +42,6 @@ final class SocialAuthCollectionViewCell: UICollectionViewCell { self.contentView.layer.cornerRadius = layer.cornerRadius self.contentView.layer.masksToBounds = true - self.layer.shadowColor = UIColor(hex6: 0xBBBBBB).cgColor self.layer.shadowOffset = CGSize(width: 0, height: 1.5) self.layer.shadowRadius = 1.7 self.layer.shadowOpacity = 0.3 @@ -56,10 +63,7 @@ final class SocialAuthCollectionViewCell: UICollectionViewCell { } private func colorize() { - if #available(iOS 13.0, *), self.traitCollection.userInterfaceStyle == .dark { - self.contentView.backgroundColor = UIColor.stepikSecondaryBackground.withAlphaComponent(0.1) - } else { - self.contentView.backgroundColor = .stepikBackground - } + self.layer.shadowColor = Appearance.shadowColor.cgColor + self.contentView.backgroundColor = Appearance.backgroundColor } } diff --git a/Stepic/Legacy/Controllers/RegistrationSignIn/AuthSocial/SocialAuthViewController.swift b/Stepic/Legacy/Controllers/RegistrationSignIn/AuthSocial/SocialAuthViewController.swift index 359ce8107d..8b68b9202b 100644 --- a/Stepic/Legacy/Controllers/RegistrationSignIn/AuthSocial/SocialAuthViewController.swift +++ b/Stepic/Legacy/Controllers/RegistrationSignIn/AuthSocial/SocialAuthViewController.swift @@ -79,7 +79,7 @@ final class SocialAuthViewController: UIViewController { @IBOutlet weak var collectionView: UICollectionView! @IBOutlet weak var stepikLogoHeightConstraint: NSLayoutConstraint! - private lazy var closeBarButtonItem = UIBarButtonItem.closeBarButtonItem( + private lazy var closeBarButtonItem = UIBarButtonItem.stepikCloseBarButtonItem( target: self, action: #selector(self.onCloseClick(_:)) ) @@ -342,7 +342,7 @@ final class SocialCollectionViewFlowLayout: UICollectionViewFlowLayout { } override var itemSize: CGSize { - set { } + set {} get { CGSize(width: itemSizeHeight, height: itemSizeHeight) } diff --git a/Stepic/Legacy/Controllers/RegistrationSignIn/Registration/RegistrationViewController.swift b/Stepic/Legacy/Controllers/RegistrationSignIn/Registration/RegistrationViewController.swift index 6e152bd332..5514c1885c 100644 --- a/Stepic/Legacy/Controllers/RegistrationSignIn/Registration/RegistrationViewController.swift +++ b/Stepic/Legacy/Controllers/RegistrationSignIn/Registration/RegistrationViewController.swift @@ -56,7 +56,7 @@ final class RegistrationViewController: UIViewController { @IBOutlet var separatorFirst: UIView! @IBOutlet var separatorSecond: UIView! - private lazy var closeBarButtonItem = UIBarButtonItem.closeBarButtonItem( + private lazy var closeBarButtonItem = UIBarButtonItem.stepikCloseBarButtonItem( target: self, action: #selector(self.onCloseClick(_:)) ) diff --git a/Stepic/Legacy/Controllers/Stories/Stories/StoryCollectionViewCell/StoryCollectionViewCell.swift b/Stepic/Legacy/Controllers/Stories/Stories/StoryCollectionViewCell/StoryCollectionViewCell.swift index 3817e0ebd9..db11a1d9e8 100644 --- a/Stepic/Legacy/Controllers/Stories/Stories/StoryCollectionViewCell/StoryCollectionViewCell.swift +++ b/Stepic/Legacy/Controllers/Stories/Stories/StoryCollectionViewCell/StoryCollectionViewCell.swift @@ -38,7 +38,7 @@ final class StoryCollectionViewCell: UICollectionViewCell { } private func updateWatched() { - if #available(iOS 13.0, *), self.traitCollection.userInterfaceStyle == .dark { + if self.isDarkInterfaceStyle { self.layer.borderColor = self.isWatched ? UIColor.stepikSecondaryBackground.withAlphaComponent(0.5).cgColor : UIColor.stepikTertiaryBackground.cgColor diff --git a/Stepic/Legacy/Controllers/Stories/Story.swift b/Stepic/Legacy/Controllers/Stories/Story.swift index 443cd635b4..24491fe332 100644 --- a/Stepic/Legacy/Controllers/Stories/Story.swift +++ b/Stepic/Legacy/Controllers/Stories/Story.swift @@ -87,7 +87,7 @@ final class TextStoryPart: StoryPart { case .light: return UIColor.white.withAlphaComponent(0.7) case .dark: - return UIColor.stepikAccentAlpha70 + return UIColor.stepikAccentFixed.withAlphaComponent(0.7) default: return .clear } diff --git a/Stepic/Legacy/Controllers/VideoPlayer/StepikVideoPlayerViewController/StepikVideoPlayerViewController.swift b/Stepic/Legacy/Controllers/VideoPlayer/StepikVideoPlayerViewController/StepikVideoPlayerViewController.swift index 4a135d2250..17eac56159 100644 --- a/Stepic/Legacy/Controllers/VideoPlayer/StepikVideoPlayerViewController/StepikVideoPlayerViewController.swift +++ b/Stepic/Legacy/Controllers/VideoPlayer/StepikVideoPlayerViewController/StepikVideoPlayerViewController.swift @@ -48,7 +48,7 @@ extension StepikVideoPlayerViewController { static let topContainerViewCornerRadius: CGFloat = 8 static let bottomFullscreenControlsCornerRadius: CGFloat = 8 - static let autoplayOverlayColor = UIColor.stepikAccentAlpha50 + static let autoplayOverlayColor = UIColor.stepikOverlayBackground static let autoplayPlayNextCircleHeight: CGFloat = 72 static let autoplayCancelTitleColor = UIColor.white diff --git a/Stepic/Legacy/Helpers/Containers/Defaults/DefaultsContainer.swift b/Stepic/Legacy/Helpers/Containers/Defaults/DefaultsContainer.swift index 703ff011b3..f24d61ea99 100644 --- a/Stepic/Legacy/Helpers/Containers/Defaults/DefaultsContainer.swift +++ b/Stepic/Legacy/Helpers/Containers/Defaults/DefaultsContainer.swift @@ -15,5 +15,5 @@ final class DefaultsContainer { static let launch = LaunchDefaultsContainer() static let explore = ExploreDefaultsContainer() - private init() { } + private init() {} } diff --git a/Stepic/Legacy/Helpers/Containers/Preferences/PreferencesContainer.swift b/Stepic/Legacy/Helpers/Containers/Preferences/PreferencesContainer.swift index b9c5eb10ae..c87026230b 100644 --- a/Stepic/Legacy/Helpers/Containers/Preferences/PreferencesContainer.swift +++ b/Stepic/Legacy/Helpers/Containers/Preferences/PreferencesContainer.swift @@ -15,5 +15,5 @@ final class PreferencesContainer { static let notifications = NotificationPreferencesContainer() static let codeEditor = CodeEditorPreferencesContainer() - private init() { } + private init() {} } diff --git a/Stepic/Legacy/Helpers/Containers/Presentation/PresentationContainer.swift b/Stepic/Legacy/Helpers/Containers/Presentation/PresentationContainer.swift index 1c0499b4c6..c8d6516154 100644 --- a/Stepic/Legacy/Helpers/Containers/Presentation/PresentationContainer.swift +++ b/Stepic/Legacy/Helpers/Containers/Presentation/PresentationContainer.swift @@ -14,5 +14,5 @@ import Foundation final class PresentationContainer { static let certificates = CertificatesPresentationContainer() - private init() { } + private init() {} } diff --git a/Stepic/Legacy/Helpers/DeviceInfo.swift b/Stepic/Legacy/Helpers/DeviceInfo.swift index 092ccd2f0c..11069631a7 100644 --- a/Stepic/Legacy/Helpers/DeviceInfo.swift +++ b/Stepic/Legacy/Helpers/DeviceInfo.swift @@ -14,7 +14,7 @@ final class DeviceInfo { private var currentDevice: DeviceKit.Device = DeviceKit.Device.current - private init() { } + private init() {} var isPad: Bool { self.currentDevice.isPad } diff --git a/Stepic/Legacy/Model/Network/Endpoints/AdaptiveRatingsAPI.swift b/Stepic/Legacy/Model/Network/Endpoints/AdaptiveRatingsAPI.swift index e6ae964210..fa564d83f5 100644 --- a/Stepic/Legacy/Model/Network/Endpoints/AdaptiveRatingsAPI.swift +++ b/Stepic/Legacy/Model/Network/Endpoints/AdaptiveRatingsAPI.swift @@ -30,7 +30,13 @@ final class AdaptiveRatingsAPI: APIEndpoint { } return Promise { seal in - manager.request("\(RemoteConfig.shared.adaptiveBackendUrl)/\(name)", method: .put, parameters: params, encoding: JSONEncoding.default, headers: nil).responseSwiftyJSON { response in + self.manager.request( + "\(RemoteConfig.shared.adaptiveBackendURL)/\(name)", + method: .put, + parameters: params, + encoding: JSONEncoding.default, + headers: nil + ).responseSwiftyJSON { response in switch response.result { case .failure(let error): seal.reject(error) @@ -61,7 +67,7 @@ final class AdaptiveRatingsAPI: APIEndpoint { return Promise { seal in self.manager.request( - "\(RemoteConfig.shared.adaptiveBackendUrl)/\(self.name)", + "\(RemoteConfig.shared.adaptiveBackendURL)/\(self.name)", method: .get, parameters: params, encoding: URLEncoding.default, @@ -102,7 +108,7 @@ final class AdaptiveRatingsAPI: APIEndpoint { return Promise { seal in self.manager.request( - "\(RemoteConfig.shared.adaptiveBackendUrl)/\(self.restoreName)", + "\(RemoteConfig.shared.adaptiveBackendURL)/\(self.restoreName)", method: .get, parameters: params, encoding: URLEncoding.default, diff --git a/Stepic/Legacy/Model/RemoteConfig/RemoteConfig.swift b/Stepic/Legacy/Model/RemoteConfig/RemoteConfig.swift index 9b4bb490b6..a0be639b0b 100644 --- a/Stepic/Legacy/Model/RemoteConfig/RemoteConfig.swift +++ b/Stepic/Legacy/Model/RemoteConfig/RemoteConfig.swift @@ -11,13 +11,6 @@ import FirebaseInstanceID import FirebaseRemoteConfig import Foundation -enum RemoteConfigKeys: String { - case showStreaksNotificationTrigger = "show_streaks_notification_trigger" - case adaptiveBackendUrl = "adaptive_backend_url" - case supportedInAdaptiveModeCourses = "supported_adaptive_courses_ios" - case newLessonAvailable = "new_lesson_available_ios" -} - final class RemoteConfig { private let defaultShowStreaksNotificationTrigger = ShowStreaksNotificationTrigger.loginAndSubmission static let shared = RemoteConfig() @@ -28,30 +21,26 @@ final class RemoteConfig { var fetchDuration: TimeInterval = 43200 lazy var appDefaults: [String: NSObject] = [ - RemoteConfigKeys.showStreaksNotificationTrigger.rawValue: defaultShowStreaksNotificationTrigger.rawValue as NSObject, - RemoteConfigKeys.adaptiveBackendUrl.rawValue: StepikApplicationsInfo.adaptiveRatingURL as NSObject, - RemoteConfigKeys.supportedInAdaptiveModeCourses.rawValue: StepikApplicationsInfo.adaptiveSupportedCourses as NSObject, - RemoteConfigKeys.newLessonAvailable.rawValue: true as NSObject + Key.showStreaksNotificationTrigger.rawValue: defaultShowStreaksNotificationTrigger.rawValue as NSObject, + Key.adaptiveBackendUrl.rawValue: StepikApplicationsInfo.adaptiveRatingURL as NSObject, + Key.supportedInAdaptiveModeCourses.rawValue: StepikApplicationsInfo.adaptiveSupportedCourses as NSObject, + Key.newLessonAvailable.rawValue: true as NSObject, + Key.darkModeAvailable.rawValue: false as NSObject ] - enum ShowStreaksNotificationTrigger: String { - case loginAndSubmission = "login_and_submission" - case submission = "submission" - } - var showStreaksNotificationTrigger: ShowStreaksNotificationTrigger { guard let configValue = FirebaseRemoteConfig.RemoteConfig.remoteConfig().configValue( - forKey: RemoteConfigKeys.showStreaksNotificationTrigger.rawValue + forKey: Key.showStreaksNotificationTrigger.rawValue ).stringValue else { - return defaultShowStreaksNotificationTrigger + return self.defaultShowStreaksNotificationTrigger } - return ShowStreaksNotificationTrigger(rawValue: configValue) ?? defaultShowStreaksNotificationTrigger + return ShowStreaksNotificationTrigger(rawValue: configValue) ?? self.defaultShowStreaksNotificationTrigger } - var adaptiveBackendUrl: String { + var adaptiveBackendURL: String { guard let configValue = FirebaseRemoteConfig.RemoteConfig.remoteConfig().configValue( - forKey: RemoteConfigKeys.adaptiveBackendUrl.rawValue + forKey: Key.adaptiveBackendUrl.rawValue ).stringValue else { return StepikApplicationsInfo.adaptiveRatingURL } @@ -59,9 +48,9 @@ final class RemoteConfig { return configValue } - var supportedInAdaptiveModeCourses: [Int] { + var supportedInAdaptiveModeCourses: [Course.IdType] { guard let configValue = FirebaseRemoteConfig.RemoteConfig.remoteConfig().configValue( - forKey: RemoteConfigKeys.supportedInAdaptiveModeCourses.rawValue + forKey: Key.supportedInAdaptiveModeCourses.rawValue ).stringValue else { return StepikApplicationsInfo.adaptiveSupportedCourses } @@ -89,30 +78,44 @@ final class RemoteConfig { return supportedCourses.compactMap { Int($0) } } + var isDarkModeAvailable: Bool { + if DeviceInfo.current.OSVersion.major < 13 { + return false + } + + return FirebaseRemoteConfig.RemoteConfig + .remoteConfig() + .configValue(forKey: Key.darkModeAvailable.rawValue) + .boolValue + } + init() { - loadDefaultValues() - fetchCloudValues() + self.loadDefaultValues() + self.fetchCloudValues() } - func setup() { } + func setup() {} + + // MARK: Private API private func loadDefaultValues() { - FirebaseRemoteConfig.RemoteConfig.remoteConfig().setDefaults(appDefaults) + FirebaseRemoteConfig.RemoteConfig.remoteConfig().setDefaults(self.appDefaults) } private func fetchCloudValues() { #if DEBUG - activateDebugMode() + self.activateDebugMode() #endif - FirebaseRemoteConfig.RemoteConfig.remoteConfig().fetch(withExpirationDuration: fetchDuration) { - [weak self] _, error in + + FirebaseRemoteConfig.RemoteConfig.remoteConfig().fetch( + withExpirationDuration: self.fetchDuration + ) { [weak self] _, error in guard error == nil else { - print("Got an error fetching remote values \(String(describing: error))") - return + return print("RemoteConfig :: Got an error fetching remote values \(String(describing: error))") } FirebaseRemoteConfig.RemoteConfig.remoteConfig().activate(completionHandler: { error in - print("remote config failed activate firebase remote config with error: \(error ??? "nil")") + print("RemoteConfig :: failed activate firebase remote config with error: \(error ??? "nil")") }) self?.fetchComplete = true @@ -121,13 +124,23 @@ final class RemoteConfig { } private func activateDebugMode() { - fetchDuration = 0 - let debugSettings = RemoteConfigSettings() - debugSettings.minimumFetchInterval = 0 + self.fetchDuration = 0 + let debugSettings = RemoteConfigSettings(developerModeEnabled: true) FirebaseRemoteConfig.RemoteConfig.remoteConfig().configSettings = debugSettings } - func string(forKey key: String) -> String? { - FirebaseRemoteConfig.RemoteConfig.remoteConfig().configValue(forKey: key).stringValue + // MARK: Inner Types + + enum ShowStreaksNotificationTrigger: String { + case loginAndSubmission = "login_and_submission" + case submission = "submission" + } + + enum Key: String { + case showStreaksNotificationTrigger = "show_streaks_notification_trigger" + case adaptiveBackendUrl = "adaptive_backend_url" + case supportedInAdaptiveModeCourses = "supported_adaptive_courses_ios" + case newLessonAvailable = "new_lesson_available_ios" + case darkModeAvailable = "is_dark_mode_available_ios" } } diff --git a/Stepic/Legacy/Model/ReplyCache.swift b/Stepic/Legacy/Model/ReplyCache.swift index f1f9c8b4f6..c6ab8e089d 100644 --- a/Stepic/Legacy/Model/ReplyCache.swift +++ b/Stepic/Legacy/Model/ReplyCache.swift @@ -13,7 +13,7 @@ final class ReplyCache { static var shared = ReplyCache() - private init() { } + private init() {} private var replyByStepID: [Int: ReplyForAttempt] = [:] diff --git a/Stepic/Legacy/Services/NextLessonService.swift b/Stepic/Legacy/Services/NextLessonService.swift index 932ba84230..51bdb7c7cc 100644 --- a/Stepic/Legacy/Services/NextLessonService.swift +++ b/Stepic/Legacy/Services/NextLessonService.swift @@ -24,7 +24,7 @@ protocol NextLessonServiceSectionSourceProtocol: UniqueIdentifiable { } @available(*, deprecated, message: "Should use Unit model") -protocol NextLessonServiceUnitSourceProtocol: UniqueIdentifiable { } +protocol NextLessonServiceUnitSourceProtocol: UniqueIdentifiable {} final class NextLessonService: NextLessonServiceProtocol { private var sections: [NextLessonServiceSectionSourceProtocol] = [] diff --git a/Stepic/Legacy/Views/AvatarImageView.swift b/Stepic/Legacy/Views/AvatarImageView.swift index b52a15c1dc..e1fa4ce1d4 100644 --- a/Stepic/Legacy/Views/AvatarImageView.swift +++ b/Stepic/Legacy/Views/AvatarImageView.swift @@ -8,35 +8,35 @@ import Alamofire import SVGKit +import SnapKit import UIKit final class AvatarImageView: UIImageView { - enum Shape { - case rectangle(cornerRadius: CGFloat) - case circle - } - - private let colors: [Int] = [0x69A1E5, 0xFFD19F, 0xE8B9B9, 0x85C096, 0xE1B3EA, 0xABE5D8] + private static let colorsLight: [UInt32] = [0x69A1E5, 0xFFD19F, 0xE8B9B9, 0x85C096, 0xE1B3EA, 0xABE5D8] + private static let colorsDark: [UInt32] = [0x184D8E, 0xCF6B00, 0x9C3333, 0x376B46, 0x8E2CA1, 0x2F9881] var shape: Shape = .circle { didSet { - updateShape() + self.updateShape() } } + private var colors: [UInt32] { + self.isDarkInterfaceStyle ? Self.colorsDark : Self.colorsLight + } + override func layoutSubviews() { super.layoutSubviews() - updateShape() + self.updateShape() } override func awakeFromNib() { super.awakeFromNib() - - reset() + self.reset() } private func updateShape() { - switch shape { + switch self.shape { case .circle: self.setRoundedBounds(width: 0) case .rectangle(let radius): @@ -45,7 +45,7 @@ final class AvatarImageView: UIImageView { } func reset() { - image = Constants.placeholderImage + self.image = UIImage(named: "lesson_cover_50") } func set(with url: URL) { @@ -91,7 +91,7 @@ final class AvatarImageView: UIImageView { label.textColor = UIColor.white label.text = letters label.textAlignment = NSTextAlignment.center - label.backgroundColor = UIColor(hex6: UInt32(colors[letters.hash % colors.count])) + label.backgroundColor = UIColor(hex6: self.colors[letters.hash % self.colors.count]) let scale = UIScreen.main.scale UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, scale) @@ -112,4 +112,11 @@ final class AvatarImageView: UIImageView { } return nil } + + // MARK: Inner Types + + enum Shape { + case rectangle(cornerRadius: CGFloat) + case circle + } } diff --git a/Stepic/Legacy/Views/PinsMap/PinsMap.swift b/Stepic/Legacy/Views/PinsMap/PinsMap.swift index 46df53a67b..aa9323ec6f 100644 --- a/Stepic/Legacy/Views/PinsMap/PinsMap.swift +++ b/Stepic/Legacy/Views/PinsMap/PinsMap.swift @@ -26,7 +26,7 @@ final class PinsMap { var allowedPins: [Bool] = Array(repeating: false, count: 7) var pins: [Int] = Array(repeating: 0, count: 7) - init() { } + init() {} init(allowedPins: [Bool], pins: [Int]) { self.allowedPins = allowedPins diff --git a/Stepic/Legacy/Views/Skeleton/SkeletonView.swift b/Stepic/Legacy/Views/Skeleton/SkeletonView.swift index a79602081c..fa3b3c6c4e 100644 --- a/Stepic/Legacy/Views/Skeleton/SkeletonView.swift +++ b/Stepic/Legacy/Views/Skeleton/SkeletonView.swift @@ -67,15 +67,9 @@ class SkeletonView: UIView { private func addGradient() { let gradientLayer = CAGradientLayer() - // FIXME: extract colors - gradientLayer.colors = [ - UIColor(red: 0.965, green: 0.965, blue: 0.965, alpha: 1.0).cgColor, - UIColor(red: 0.907, green: 0.907, blue: 0.907, alpha: 1.0).cgColor, - UIColor(red: 0.965, green: 0.965, blue: 0.965, alpha: 1.0).cgColor - ] - self.layer.addSublayer(gradientLayer) self.gradientLayer = gradientLayer + self.updateGradientColors() } private func rebuild(cleanCache: Bool) { @@ -155,8 +149,24 @@ class SkeletonView: UIView { self.setNeedsLayout() - rebuild(cleanCache: false) - gradientLayer?.frame = self.bounds - animate() + self.rebuild(cleanCache: false) + self.gradientLayer?.frame = self.bounds + self.animate() + } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + self.performBlockIfAppearanceChanged(from: previousTraitCollection) { + self.updateGradientColors() + } + } + + private func updateGradientColors() { + self.gradientLayer?.colors = [ + UIColor.skeletonGradientFirst.cgColor, + UIColor.skeletonGradientSecond.cgColor, + UIColor.skeletonGradientThird.cgColor + ] } } diff --git a/Stepic/Legacy/Views/StepikButton.swift b/Stepic/Legacy/Views/StepikButton.swift index 86c4a32585..c84ca42c09 100644 --- a/Stepic/Legacy/Views/StepikButton.swift +++ b/Stepic/Legacy/Views/StepikButton.swift @@ -57,7 +57,7 @@ class StepikButton: UIButton { private func updateStyle() { if self.isGray { self.backgroundColor = self.isLightBackground - ? UIColor.stepikSecondaryBackground + ? UIColor.stepikLightSecondaryBackground : UIColor(hex6: 0x5d5d70, alpha: 1) self.setTitleColor(self.isLightBackground ? UIColor.stepikPrimaryText : UIColor.white, for: .normal) self.setRoundedCorners(cornerRadius: 8, borderWidth: 0) diff --git a/Stepic/Sources/Controllers/AboutAppViewController.swift b/Stepic/Sources/Controllers/AboutAppViewController.swift index 96fb42b357..168eee71b5 100644 --- a/Stepic/Sources/Controllers/AboutAppViewController.swift +++ b/Stepic/Sources/Controllers/AboutAppViewController.swift @@ -4,7 +4,7 @@ import UIKit final class AboutAppViewController: UIViewController { private lazy var tableView: UITableView = { - let tableView = UITableView(frame: .zero, style: .insetGroupedFallbackGrouped) + let tableView = UITableView(frame: .zero, style: .stepikInsetGrouped) tableView.sectionHeaderHeight = UITableView.automaticDimension tableView.estimatedSectionHeaderHeight = 200 tableView.sectionFooterHeight = UITableView.automaticDimension @@ -79,7 +79,7 @@ final class AboutAppViewController: UIViewController { // MARK: Inner Types private enum Appearance { - static var appVersionLabelTextColor = UIColor.stepikAccent + static var appVersionLabelTextColor = UIColor.stepikSystemSecondaryText static var appVersionLabelFont = UIFont.systemFont(ofSize: 14) static var appVersionLabelTextAlignment = NSTextAlignment.center static var appVersionLabelInsets = UIEdgeInsets(top: 24, left: 16, bottom: 0, right: 16) diff --git a/Stepic/Sources/Controllers/StyledNavigationController.swift b/Stepic/Sources/Controllers/StyledNavigationController.swift index f439b0cf1a..24b7a4d4e4 100644 --- a/Stepic/Sources/Controllers/StyledNavigationController.swift +++ b/Stepic/Sources/Controllers/StyledNavigationController.swift @@ -3,17 +3,17 @@ import UIKit class StyledNavigationController: UINavigationController { enum Appearance { - static let backgroundColor = UIColor.stepikBackground - static let statusBarColor = UIColor.stepikBackground + static let backgroundColor = UIColor.stepikNavigationBarBackground + static let statusBarColor = UIColor.stepikNavigationBarBackground static let tintColor = UIColor.stepikAccent static let textColor = UIColor.stepikAccent static let titleFont = UIFont.systemFont(ofSize: 17, weight: .regular) - static let shadowViewColor = UIColor.lightGray + static let shadowViewColor = UIColor.stepikOpaqueSeparator static let shadowViewHeight: CGFloat = 0.5 - static let statusBarStyle = UIStatusBarStyle.dark + static let statusBarStyle = UIStatusBarStyle.default } struct NavigationBarAppearanceState { diff --git a/Stepic/Sources/Controllers/StyledTabBarViewController.swift b/Stepic/Sources/Controllers/StyledTabBarViewController.swift index 04b8fa35b5..cd8b600639 100644 --- a/Stepic/Sources/Controllers/StyledTabBarViewController.swift +++ b/Stepic/Sources/Controllers/StyledTabBarViewController.swift @@ -1,6 +1,16 @@ +import SVProgressHUD import UIKit final class StyledTabBarViewController: UITabBarController { + enum Appearance { + static let barTintColor = UIColor.stepikTabBarBackground + static let tintColor = UIColor.stepikAccent + static let unselectedItemTintColor = UIColor.dynamic( + light: UIColor(hex6: 0xBABAC1), + dark: .stepikTertiaryText + ) + } + private let items = StepikApplicationsInfo.Modules.tabs?.compactMap { TabController(rawValue: $0)?.itemInfo } ?? [] private var notificationsBadgeNumber: Int { @@ -21,8 +31,9 @@ final class StyledTabBarViewController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() - self.tabBar.tintColor = UIColor.stepikAccent - self.tabBar.unselectedItemTintColor = UIColor(hex6: 0xbabac1) + self.tabBar.barTintColor = Appearance.barTintColor + self.tabBar.tintColor = Appearance.tintColor + self.tabBar.unselectedItemTintColor = Appearance.unselectedItemTintColor self.tabBar.isTranslucent = false let tabBarViewControllers = self.items.map { tabBarItem -> UIViewController in @@ -51,6 +62,8 @@ final class StyledTabBarViewController: UITabBarController { name: UIDevice.orientationDidChangeNotification, object: nil ) + + self.updateSVProgressHUDDefaultStyle() } override func viewDidAppear(_ animated: Bool) { @@ -69,12 +82,25 @@ final class StyledTabBarViewController: UITabBarController { } } + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + self.view.performBlockIfAppearanceChanged(from: previousTraitCollection) { + self.updateSVProgressHUDDefaultStyle() + } + } + deinit { NotificationCenter.default.removeObserver(self) } // MARK: Private API + // FIXME: Create SVProgressHUD configurator. + private func updateSVProgressHUDDefaultStyle() { + SVProgressHUD.setDefaultStyle(self.view.isDarkInterfaceStyle ? .dark : .light) + } + @objc private func didBadgeUpdate(systemNotification: Foundation.Notification) { guard let userInfo = systemNotification.userInfo, @@ -130,11 +156,14 @@ private struct TabBarItemInfo { var title: String var controller: UIViewController var clickEventName: String - var image: UIImage + var image: UIImage? + var selectedImage: UIImage? var tag: Int func makeTabBarItem() -> UITabBarItem { - UITabBarItem(title: self.title, image: self.image, tag: self.tag) + let item = UITabBarItem(title: self.title, image: self.image, selectedImage: self.selectedImage) + item.tag = self.tag + return item } } @@ -166,11 +195,29 @@ private enum TabController: String { identifier: "ProfileNavigation", storyboardName: "Main" ) + + let personImage: UIImage? = { + if #available(iOS 13.0, *) { + return UIImage(systemName: "person") + } else { + return UIImage(named: "tab-profile").require() + } + }() + + let personFillImage: UIImage? = { + if #available(iOS 13.0, *) { + return UIImage(systemName: "person.fill") + } else { + return personImage + } + }() + return TabBarItemInfo( title: NSLocalizedString("Profile", comment: ""), controller: viewController, clickEventName: AnalyticsEvents.Tabs.profileClicked, - image: UIImage(named: "tab-profile").require(), + image: personImage, + selectedImage: personFillImage, tag: self.tag ) case .home: @@ -178,11 +225,29 @@ private enum TabController: String { let navigationViewController = StyledNavigationController( rootViewController: viewController ) + + let homeImage: UIImage? = { + if #available(iOS 13.0, *) { + return UIImage(systemName: "house") + } else { + return UIImage(named: "tab-home").require() + } + }() + + let homeFillImage: UIImage? = { + if #available(iOS 13.0, *) { + return UIImage(systemName: "house.fill") + } else { + return homeImage + } + }() + return TabBarItemInfo( title: NSLocalizedString("Home", comment: ""), controller: navigationViewController, clickEventName: AnalyticsEvents.Tabs.myCoursesClicked, - image: UIImage(named: "tab-home").require(), + image: homeImage, + selectedImage: homeFillImage, tag: self.tag ) case .notifications: @@ -190,11 +255,29 @@ private enum TabController: String { identifier: "NotificationsNavigation", storyboardName: "Main" ) + + let notificationsImage: UIImage? = { + if #available(iOS 13.0, *) { + return UIImage(systemName: "bell") + } else { + return UIImage(named: "tab-notifications").require() + } + }() + + let notificationsFillImage: UIImage? = { + if #available(iOS 13.0, *) { + return UIImage(systemName: "bell.fill") + } else { + return notificationsImage + } + }() + return TabBarItemInfo( title: NSLocalizedString("Notifications", comment: ""), controller: viewController, clickEventName: AnalyticsEvents.Tabs.notificationsClicked, - image: UIImage(named: "tab-notifications").require(), + image: notificationsImage, + selectedImage: notificationsFillImage, tag: self.tag ) case .explore: @@ -202,11 +285,21 @@ private enum TabController: String { let navigationViewController = StyledNavigationController( rootViewController: viewController ) + + let exploreImage: UIImage? = { + if #available(iOS 13.0, *) { + return UIImage(systemName: "magnifyingglass") + } else { + return UIImage(named: "tab-explore").require() + } + }() + return TabBarItemInfo( title: NSLocalizedString("Catalog", comment: ""), controller: navigationViewController, clickEventName: AnalyticsEvents.Tabs.catalogClicked, - image: UIImage(named: "tab-explore").require(), + image: exploreImage, + selectedImage: exploreImage, tag: self.tag ) } diff --git a/Stepic/Sources/Extensions/UIKit/UIBarButtonItem+CloseBarButtonItem.swift b/Stepic/Sources/Extensions/UIKit/UIBarButtonItem+CloseBarButtonItem.swift deleted file mode 100644 index 53ccab02f4..0000000000 --- a/Stepic/Sources/Extensions/UIKit/UIBarButtonItem+CloseBarButtonItem.swift +++ /dev/null @@ -1,20 +0,0 @@ -import UIKit - -extension UIBarButtonItem { - static func closeBarButtonItem(target: Any?, action: Selector?) -> UIBarButtonItem { - if #available(iOS 13.0, *) { - return UIBarButtonItem( - barButtonSystemItem: .close, - target: target, - action: action - ) - } else { - return UIBarButtonItem( - image: UIImage(named: "navigation-item-button-close"), - style: .plain, - target: target, - action: action - ) - } - } -} diff --git a/Stepic/Sources/Extensions/UIKit/UIBarButtonItem+StepikBarButtonItems.swift b/Stepic/Sources/Extensions/UIKit/UIBarButtonItem+StepikBarButtonItems.swift new file mode 100644 index 0000000000..5cdac35042 --- /dev/null +++ b/Stepic/Sources/Extensions/UIKit/UIBarButtonItem+StepikBarButtonItems.swift @@ -0,0 +1,40 @@ +import UIKit + +extension UIBarButtonItem { + static func stepikCloseBarButtonItem(target: Any?, action: Selector?) -> UIBarButtonItem { + if #available(iOS 13.0, *) { + return UIBarButtonItem( + barButtonSystemItem: .close, + target: target, + action: action + ) + } else { + return UIBarButtonItem( + image: UIImage(named: "navigation-item-button-close"), + style: .plain, + target: target, + action: action + ) + } + } + + static func stepikInfoBarButtonItem(target: Any?, action: Selector?) -> UIBarButtonItem { + let image: UIImage? + if #available(iOS 13.0, *) { + image = UIImage(systemName: "info.circle") + } else { + image = UIImage(named: "info-system") + } + + return UIBarButtonItem(image: image, style: .plain, target: target, action: action) + } + + static func stepikMoreBarButtonItem(target: Any?, action: Selector?) -> UIBarButtonItem { + UIBarButtonItem( + image: UIImage(named: "horizontal-dots-icon")?.withRenderingMode(.alwaysTemplate), + style: .plain, + target: target, + action: action + ) + } +} diff --git a/Stepic/Sources/Extensions/UIKit/UIColor+DynamicColor.swift b/Stepic/Sources/Extensions/UIKit/UIColor+DynamicColor.swift index 4666cd1203..404e3a5fce 100644 --- a/Stepic/Sources/Extensions/UIKit/UIColor+DynamicColor.swift +++ b/Stepic/Sources/Extensions/UIKit/UIColor+DynamicColor.swift @@ -8,7 +8,7 @@ extension UIColor { /// - dark: Color to use in dark mode. /// - lightAccessibility: Color to use in light/unspecified mode and with a high contrast level. /// - darkAccessibility: Color to use in dark mode and with a high contrast level. - static func dynamicColor( + static func dynamic( light: UIColor, dark: UIColor, lightAccessibility: UIColor? = nil, diff --git a/Stepic/Sources/Extensions/UIKit/UITableViewExtensions.swift b/Stepic/Sources/Extensions/UIKit/UITableViewExtensions.swift index 9b08029474..10ca0b34b0 100644 --- a/Stepic/Sources/Extensions/UIKit/UITableViewExtensions.swift +++ b/Stepic/Sources/Extensions/UIKit/UITableViewExtensions.swift @@ -34,7 +34,7 @@ extension UITableView { } extension UITableView.Style { - static var insetGroupedFallbackGrouped: UITableView.Style { + static var stepikInsetGrouped: UITableView.Style { if #available(iOS 13.0, *) { return .insetGrouped } else { diff --git a/Stepic/Sources/Extensions/UIKit/UIView+TraitCollection.swift b/Stepic/Sources/Extensions/UIKit/UIView+TraitCollection.swift index f8a0a5b7e6..7df73e1bdb 100644 --- a/Stepic/Sources/Extensions/UIKit/UIView+TraitCollection.swift +++ b/Stepic/Sources/Extensions/UIKit/UIView+TraitCollection.swift @@ -1,6 +1,14 @@ import UIKit extension UIView { + var isDarkInterfaceStyle: Bool { + if #available(iOS 13.0, *) { + return self.traitCollection.userInterfaceStyle == .dark + } else { + return false + } + } + func performBlockIfAppearanceChanged(from previousTraits: UITraitCollection?, block: () -> Void) { if #available(iOS 13, *) { if self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraits) { diff --git a/Stepic/Sources/Frameworks/ContentProcessor/ProcessedContentTextView.swift b/Stepic/Sources/Frameworks/ContentProcessor/ProcessedContentTextView.swift index 51afb13fcb..b8f4501f44 100644 --- a/Stepic/Sources/Frameworks/ContentProcessor/ProcessedContentTextView.swift +++ b/Stepic/Sources/Frameworks/ContentProcessor/ProcessedContentTextView.swift @@ -22,7 +22,7 @@ extension ProcessedContentTextViewDelegate { extension ProcessedContentTextView { struct Appearance { var insets = LayoutInsets(top: 10, left: 16, bottom: 4, right: 16) - var backgroundColor = UIColor.white + var backgroundColor = UIColor.stepikBackground } } diff --git a/Stepic/Sources/Frameworks/SettingsTable/SettingsTableViewModel.swift b/Stepic/Sources/Frameworks/SettingsTable/SettingsTableViewModel.swift index 74d8db889e..e0ca33cbad 100644 --- a/Stepic/Sources/Frameworks/SettingsTable/SettingsTableViewModel.swift +++ b/Stepic/Sources/Frameworks/SettingsTable/SettingsTableViewModel.swift @@ -100,7 +100,7 @@ struct RightDetailCellOptions { init( text: String, - appearance: Appearance = .init(textColor: .black, textAlignment: .natural) + appearance: Appearance = .init(textColor: .stepikSystemPrimaryText, textAlignment: .natural) ) { self.text = text self.appearance = appearance diff --git a/Stepic/Sources/Frameworks/SettingsTable/Views/Cell/RightDetailCells/Label/SettingsRightDetailCellView.swift b/Stepic/Sources/Frameworks/SettingsTable/Views/Cell/RightDetailCells/Label/SettingsRightDetailCellView.swift index 08e05e9dd8..96190205f3 100644 --- a/Stepic/Sources/Frameworks/SettingsTable/Views/Cell/RightDetailCells/Label/SettingsRightDetailCellView.swift +++ b/Stepic/Sources/Frameworks/SettingsTable/Views/Cell/RightDetailCells/Label/SettingsRightDetailCellView.swift @@ -3,11 +3,11 @@ import UIKit extension SettingsRightDetailCellView { struct Appearance { - let titleTextColor = UIColor.stepikAccent + let titleTextColor = UIColor.stepikSystemPrimaryText let titleFont = UIFont.systemFont(ofSize: 17) let titleInsets = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 8) - let detailTextColor = UIColor(hex6: 0x8F8E94) + let detailTextColor = UIColor.stepikSystemSecondaryText let detailFont = UIFont.systemFont(ofSize: 17) let detailInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16) @@ -52,7 +52,7 @@ final class SettingsRightDetailCellView: UIView { } } - var titleTextColor: UIColor = .black { + var titleTextColor: UIColor = .stepikSystemPrimaryText { didSet { self.titleLabel.textColor = self.titleTextColor } diff --git a/Stepic/Sources/Frameworks/SettingsTable/Views/Cell/RightDetailCells/Switch/SettingsRightDetailSwitchCellView.swift b/Stepic/Sources/Frameworks/SettingsTable/Views/Cell/RightDetailCells/Switch/SettingsRightDetailSwitchCellView.swift index c249da8159..3dc80baa5e 100644 --- a/Stepic/Sources/Frameworks/SettingsTable/Views/Cell/RightDetailCells/Switch/SettingsRightDetailSwitchCellView.swift +++ b/Stepic/Sources/Frameworks/SettingsTable/Views/Cell/RightDetailCells/Switch/SettingsRightDetailSwitchCellView.swift @@ -3,11 +3,11 @@ import UIKit extension SettingsRightDetailSwitchCellView { struct Appearance { - let titleTextColor = UIColor.stepikAccent + let titleTextColor = UIColor.stepikSystemPrimaryText let titleFont = UIFont.systemFont(ofSize: 17) let titleInsets = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 8) - let switchOnTintColor = UIColor.stepikAccent + let switchOnTintColor = UIColor.stepikSwitchOnTint let switchWidth: CGFloat = 51 let trailingOffsetWithAccessoryItem: CGFloat = 8 @@ -47,7 +47,7 @@ final class SettingsRightDetailSwitchCellView: UIView { } } - var textColor: UIColor = .black { + var textColor: UIColor = .stepikSystemPrimaryText { didSet { self.titleLabel.textColor = self.textColor } diff --git a/Stepic/Sources/Frameworks/SettingsTable/Views/SettingsTableSectionFooterView.swift b/Stepic/Sources/Frameworks/SettingsTable/Views/SettingsTableSectionFooterView.swift index 020bc45699..23e0eaf040 100644 --- a/Stepic/Sources/Frameworks/SettingsTable/Views/SettingsTableSectionFooterView.swift +++ b/Stepic/Sources/Frameworks/SettingsTable/Views/SettingsTableSectionFooterView.swift @@ -4,7 +4,7 @@ import UIKit final class SettingsTableSectionFooterView: UITableViewHeaderFooterView, Reusable { enum Appearance { static let font = UIFont.systemFont(ofSize: 13) - static let labelColor = UIColor(hex6: 0x000000, alpha: 0.4) + static let labelColor = UIColor.stepikSystemSecondaryText static let labelInsets = UIEdgeInsets(top: 8, left: 16, bottom: 0, right: 16) } diff --git a/Stepic/Sources/Frameworks/SettingsTable/Views/SettingsTableSectionHeaderView.swift b/Stepic/Sources/Frameworks/SettingsTable/Views/SettingsTableSectionHeaderView.swift index b9629a33e2..8c5214e6a4 100644 --- a/Stepic/Sources/Frameworks/SettingsTable/Views/SettingsTableSectionHeaderView.swift +++ b/Stepic/Sources/Frameworks/SettingsTable/Views/SettingsTableSectionHeaderView.swift @@ -4,12 +4,14 @@ import UIKit final class SettingsTableSectionHeaderView: UITableViewHeaderFooterView, Reusable { enum Appearance { static let font = UIFont.systemFont(ofSize: 18, weight: .bold) + static let textColor = UIColor.stepikSystemPrimaryText static let labelInsets = UIEdgeInsets(top: 20, left: 16, bottom: 8, right: 16) } private lazy var titleLabel: UILabel = { let label = UILabel() label.font = Appearance.font + label.textColor = Appearance.textColor return label }() diff --git a/Stepic/Sources/Model/ApplicationTheme.swift b/Stepic/Sources/Model/ApplicationTheme.swift new file mode 100644 index 0000000000..b4d3ea77a8 --- /dev/null +++ b/Stepic/Sources/Model/ApplicationTheme.swift @@ -0,0 +1,30 @@ +import Foundation + +enum ApplicationTheme: String, CaseIterable, UniqueIdentifiable { + case system + case dark + case light + + static var `default`: ApplicationTheme { .system } + + var uniqueIdentifier: UniqueIdentifierType { self.rawValue } + + var title: String { + switch self { + case .system: + return NSLocalizedString("SettingsThemeItemSystem", comment: "") + case .dark: + return NSLocalizedString("SettingsThemeItemDark", comment: "") + case .light: + return NSLocalizedString("SettingsThemeItemLight", comment: "") + } + } + + init?(uniqueIdentifier: UniqueIdentifierType) { + if let applicationTheme = ApplicationTheme(rawValue: uniqueIdentifier) { + self = applicationTheme + } else { + return nil + } + } +} diff --git a/Stepic/Sources/Modules/BaseExplore/BaseExploreDataFlow.swift b/Stepic/Sources/Modules/BaseExplore/BaseExploreDataFlow.swift index c528531812..172cee9503 100644 --- a/Stepic/Sources/Modules/BaseExplore/BaseExploreDataFlow.swift +++ b/Stepic/Sources/Modules/BaseExplore/BaseExploreDataFlow.swift @@ -70,9 +70,9 @@ enum BaseExplore { } enum AuthorizationPresentation { - struct Response { } + struct Response {} - struct ViewModel { } + struct ViewModel {} } /// Try to set online status for submodules diff --git a/Stepic/Sources/Modules/BaseExplore/BaseExploreInteractor.swift b/Stepic/Sources/Modules/BaseExplore/BaseExploreInteractor.swift index 467aaa0dd8..d9d74c6c44 100644 --- a/Stepic/Sources/Modules/BaseExplore/BaseExploreInteractor.swift +++ b/Stepic/Sources/Modules/BaseExplore/BaseExploreInteractor.swift @@ -56,11 +56,11 @@ class BaseExploreInteractor: BaseExploreInteractorProtocol, CourseListOutputProt self.presenter.presentAuthorization(response: .init()) } - func presentError(sourceModule: CourseListInputProtocol) { } - - func presentEmptyState(sourceModule: CourseListInputProtocol) { } - func presentPaidCourseInfo(course: Course) { self.presenter.presentPaidCourseBuying(response: .init(course: course)) } + + func presentEmptyState(sourceModule: CourseListInputProtocol) {} + + func presentError(sourceModule: CourseListInputProtocol) {} } diff --git a/Stepic/Sources/Modules/BaseExplore/BaseExploreView.swift b/Stepic/Sources/Modules/BaseExplore/BaseExploreView.swift index 0936ab2743..77428c980c 100644 --- a/Stepic/Sources/Modules/BaseExplore/BaseExploreView.swift +++ b/Stepic/Sources/Modules/BaseExplore/BaseExploreView.swift @@ -37,8 +37,7 @@ final class BaseExploreView: UIView { } func insertBlockView(_ view: UIView, before previousView: UIView) { - for (index, subview) in self.scrollableStackView.arrangedSubviews.enumerated() - where subview === previousView { + for (index, subview) in self.scrollableStackView.arrangedSubviews.enumerated() where subview === previousView { self.scrollableStackView.insertArrangedView(view, at: index) return } diff --git a/Stepic/Sources/Modules/BaseExplore/BaseExploreViewController.swift b/Stepic/Sources/Modules/BaseExplore/BaseExploreViewController.swift index 7557baad12..5073c064c9 100644 --- a/Stepic/Sources/Modules/BaseExplore/BaseExploreViewController.swift +++ b/Stepic/Sources/Modules/BaseExplore/BaseExploreViewController.swift @@ -1,9 +1,7 @@ import UIKit protocol BaseExploreViewControllerProtocol: AnyObject { - func displayFullscreenCourseList( - viewModel: BaseExplore.FullscreenCourseListModulePresentation.ViewModel - ) + func displayFullscreenCourseList(viewModel: BaseExplore.FullscreenCourseListModulePresentation.ViewModel) func displayCourseInfo(viewModel: BaseExplore.CourseInfoPresentation.ViewModel) func displayCourseSyllabus(viewModel: BaseExplore.CourseSyllabusPresentation.ViewModel) func displayLastStep(viewModel: BaseExplore.LastStepPresentation.ViewModel) @@ -104,11 +102,9 @@ class BaseExploreViewController: UIViewController { ) } - func refreshContentAfterLanguageChange() { - } + func refreshContentAfterLanguageChange() {} - func refreshContentAfterLoginAndLogout() { - } + func refreshContentAfterLoginAndLogout() {} @objc private func handleRefreshContentAfterLoginAndLogout() { @@ -130,28 +126,25 @@ class BaseExploreViewController: UIViewController { } } +// MARK: - BaseExploreViewController: BaseExploreViewControllerProtocol - + extension BaseExploreViewController: BaseExploreViewControllerProtocol { - func displayFullscreenCourseList( - viewModel: BaseExplore.FullscreenCourseListModulePresentation.ViewModel - ) { + func displayFullscreenCourseList(viewModel: BaseExplore.FullscreenCourseListModulePresentation.ViewModel) { let assembly = FullscreenCourseListAssembly( presentationDescription: viewModel.presentationDescription, courseListType: viewModel.courseListType ) - let viewController = assembly.makeModule() - self.navigationController?.pushViewController(viewController, animated: true) + self.push(module: assembly.makeModule()) } func displayCourseInfo(viewModel: BaseExplore.CourseInfoPresentation.ViewModel) { let assembly = CourseInfoAssembly(courseID: viewModel.courseID, initialTab: .info) - let viewController = assembly.makeModule() - self.navigationController?.pushViewController(viewController, animated: true) + self.push(module: assembly.makeModule()) } func displayCourseSyllabus(viewModel: BaseExplore.CourseSyllabusPresentation.ViewModel) { let assembly = CourseInfoAssembly(courseID: viewModel.courseID, initialTab: .syllabus) - let viewController = assembly.makeModule() - self.navigationController?.pushViewController(viewController, animated: true) + self.push(module: assembly.makeModule()) } func displayLastStep(viewModel: BaseExplore.LastStepPresentation.ViewModel) { diff --git a/Stepic/Sources/Modules/CourseInfo/CourseInfoDataFlow.swift b/Stepic/Sources/Modules/CourseInfo/CourseInfoDataFlow.swift index 3639e13a61..244479fb6b 100644 --- a/Stepic/Sources/Modules/CourseInfo/CourseInfoDataFlow.swift +++ b/Stepic/Sources/Modules/CourseInfo/CourseInfoDataFlow.swift @@ -22,7 +22,7 @@ enum CourseInfo { /// Load & show info about course enum CourseLoad { - struct Request { } + struct Request {} struct Response { var result: StepikResult @@ -86,7 +86,7 @@ enum CourseInfo { /// Share course enum CourseShareAction { - struct Request { } + struct Request {} struct Response { let urlPath: String @@ -132,29 +132,29 @@ enum CourseInfo { /// Drop course enum CourseUnenrollmentAction { - struct Request { } + struct Request {} } /// Do main action (continue, enroll, etc) enum MainCourseAction { - struct Request { } + struct Request {} } /// Try to set online mode enum OnlineModeReset { - struct Request { } + struct Request {} } /// Register for remote notifications enum RemoteNotificationsRegistration { - struct Request { } + struct Request {} } /// Present authorization controller enum AuthorizationPresentation { - struct Response { } + struct Response {} - struct ViewModel { } + struct ViewModel {} } /// Present web view for paid course diff --git a/Stepic/Sources/Modules/CourseInfo/CourseInfoViewController.swift b/Stepic/Sources/Modules/CourseInfo/CourseInfoViewController.swift index cea1d0736d..378f428947 100644 --- a/Stepic/Sources/Modules/CourseInfo/CourseInfoViewController.swift +++ b/Stepic/Sources/Modules/CourseInfo/CourseInfoViewController.swift @@ -129,6 +129,15 @@ final class CourseInfoViewController: UIViewController { self.view = view } + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + self.view.performBlockIfAppearanceChanged(from: previousTraitCollection) { + // Update status bar style. + self.updateContentOffset(scrollOffset: self.lastKnownScrollOffset) + } + } + private func updateTopBar(alpha: CGFloat) { self.view.performBlockUsingViewTraitCollection { self.styledNavigationController?.changeBackgroundColor( @@ -147,9 +156,15 @@ final class CourseInfoViewController: UIViewController { sender: self ) - let statusBarStyle = alpha > CGFloat(CourseInfoViewController.topBarAlphaStatusBarThreshold) - ? UIStatusBarStyle.dark - : UIStatusBarStyle.lightContent + + let statusBarStyle: UIStatusBarStyle = { + if alpha > CGFloat(CourseInfoViewController.topBarAlphaStatusBarThreshold) { + return self.view.isDarkInterfaceStyle ? .lightContent : .dark + } else { + return .lightContent + } + }() + self.styledNavigationController?.changeStatusBarStyle(statusBarStyle, sender: self) } } @@ -341,20 +356,20 @@ extension CourseInfoViewController: PageboyViewControllerDataSource, PageboyView willScrollToPageAt index: PageboyViewController.PageIndex, direction: PageboyViewController.NavigationDirection, animated: Bool - ) { } + ) {} func pageboyViewController( _ pageboyViewController: PageboyViewController, didScrollTo position: CGPoint, direction: PageboyViewController.NavigationDirection, animated: Bool - ) { } + ) {} func pageboyViewController( _ pageboyViewController: PageboyViewController, didReloadWith currentViewController: UIViewController, currentPageIndex: PageboyViewController.PageIndex - ) { } + ) {} } extension CourseInfoViewController: CourseInfoViewControllerProtocol { diff --git a/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoBlurredBackgroundView.swift b/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoBlurredBackgroundView.swift index 32648fa7d4..adf3937b47 100644 --- a/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoBlurredBackgroundView.swift +++ b/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoBlurredBackgroundView.swift @@ -22,8 +22,7 @@ final class CourseInfoBlurredBackgroundView: UIView { }() private lazy var blurView: UIVisualEffectView = { - let blurEffect = UIBlurEffect(style: .dark) - let blurView = UIVisualEffectView(effect: blurEffect) + let blurView = UIVisualEffectView(effect: nil) return blurView }() @@ -41,6 +40,8 @@ final class CourseInfoBlurredBackgroundView: UIView { self.setupView() self.addSubviews() self.makeConstraints() + + self.updateBlurEffect() } @available(*, unavailable) @@ -48,6 +49,14 @@ final class CourseInfoBlurredBackgroundView: UIView { fatalError("init(coder:) has not been implemented") } + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + self.performBlockIfAppearanceChanged(from: previousTraitCollection) { + self.updateBlurEffect() + } + } + func loadImage(url: URL?) { if let url = url { Nuke.loadImage( @@ -63,6 +72,14 @@ final class CourseInfoBlurredBackgroundView: UIView { self.imageView.image = nil } } + + private func updateBlurEffect() { + if #available(iOS 13.0, *), self.isDarkInterfaceStyle { + self.blurView.effect = UIBlurEffect(style: .systemThickMaterialDark) + } else { + self.blurView.effect = UIBlurEffect(style: .dark) + } + } } extension CourseInfoBlurredBackgroundView: ProgrammaticallyInitializableViewProtocol { diff --git a/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoStatsView.swift b/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoStatsView.swift index af55e1e264..a62ab0ea68 100644 --- a/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoStatsView.swift +++ b/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoStatsView.swift @@ -18,7 +18,7 @@ extension CourseInfoStatsView { let imagesRenderingSize = CGSize(width: 30, height: 30) let imagesRenderingLineWidth: CGFloat = 6.0 var imagesRenderingBackgroundColor = UIColor.white - var imagesRenderingTintColor = UIColor(hex6: 0x89cc89) + var imagesRenderingTintColor = UIColor.stepikGreenFixed } } diff --git a/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoView.swift b/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoView.swift index 1c2e9b81fe..b36cdacfa7 100644 --- a/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoView.swift +++ b/Stepic/Sources/Modules/CourseInfo/Views/CourseInfoView.swift @@ -137,7 +137,7 @@ final class CourseInfoView: UIView { extension CourseInfoView: ProgrammaticallyInitializableViewProtocol { func setupView() { self.clipsToBounds = true - self.backgroundColor = .white + self.backgroundColor = .stepikBackground } func addSubviews() { diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/CourseInfoTabInfoDataFlow.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/CourseInfoTabInfoDataFlow.swift index 051ef54076..4a7b34c1d0 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/CourseInfoTabInfoDataFlow.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/CourseInfoTabInfoDataFlow.swift @@ -4,7 +4,7 @@ enum CourseInfoTabInfo { // MARK: Use cases enum InfoLoad { - struct Request { } + struct Request {} struct Response { let course: Course? diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/InputOutput/CourseInfoTabInfoInputProtocol.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/InputOutput/CourseInfoTabInfoInputProtocol.swift index 3548cdda9f..bd169aa6c1 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/InputOutput/CourseInfoTabInfoInputProtocol.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/InputOutput/CourseInfoTabInfoInputProtocol.swift @@ -1,3 +1,3 @@ import Foundation -protocol CourseInfoTabInfoInputProtocol: CourseInfoSubmoduleProtocol { } +protocol CourseInfoTabInfoInputProtocol: CourseInfoSubmoduleProtocol {} diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoHeaderBlockView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoHeaderBlockView.swift index fe638e1145..38fab86e82 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoHeaderBlockView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoHeaderBlockView.swift @@ -8,7 +8,7 @@ extension CourseInfoTabInfoHeaderBlockView { var imageViewLeadingSpace: CGFloat = 0 var titleLabelFont = UIFont.systemFont(ofSize: 14, weight: .medium) - let titleLabelTextColor = UIColor.stepikAccent + let titleLabelTextColor = UIColor.stepikPrimaryText var titleLabelInsets = UIEdgeInsets(top: 0, left: 27, bottom: 0, right: 0) var titleLabelNumberOfLines = 1 } @@ -67,7 +67,7 @@ final class CourseInfoTabInfoHeaderBlockView: UIView { extension CourseInfoTabInfoHeaderBlockView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .clear } func addSubviews() { diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoInstructorView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoInstructorView.swift index 597d364dbd..935d1e5745 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoInstructorView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoInstructorView.swift @@ -9,11 +9,11 @@ extension CourseInfoTabInfoInstructorView { let titleLabelInsets = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 0) let titleLabelFont = UIFont.systemFont(ofSize: 14, weight: .medium) - let titleLabelTextColor = UIColor.stepikAccent + let titleLabelTextColor = UIColor.stepikPrimaryText let descriptionLabelInsets = UIEdgeInsets(top: 12, left: 0, bottom: 0, right: 0) let descriptionLabelFont = UIFont.systemFont(ofSize: 12, weight: .light) - let descriptionLabelTextColor = UIColor.stepikAccent + let descriptionLabelTextColor = UIColor.stepikSecondaryText } } @@ -113,7 +113,7 @@ final class CourseInfoTabInfoInstructorView: UIView { extension CourseInfoTabInfoInstructorView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .clear } func addSubviews() { @@ -133,7 +133,7 @@ extension CourseInfoTabInfoInstructorView: ProgrammaticallyInitializableViewProt self.titleLabel.translatesAutoresizingMaskIntoConstraints = false self.titleLabel.snp.makeConstraints { make in make.trailing.equalToSuperview().priority(999) - make.centerY.equalTo(self.imageView.snp.centerY) + make.top.equalTo(self.imageView.snp.top) make.leading .equalTo(self.imageView.snp.trailing) .offset(self.appearance.titleLabelInsets.left) diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoInstructorsBlockView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoInstructorsBlockView.swift index 9f96f9342c..1820918346 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoInstructorsBlockView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoInstructorsBlockView.swift @@ -65,7 +65,7 @@ final class CourseInfoTabInfoInstructorsBlockView: UIView { extension CourseInfoTabInfoInstructorsBlockView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .clear } func addSubviews() { diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoIntroVideoBlockView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoIntroVideoBlockView.swift index 349018491a..eee443f8e2 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoIntroVideoBlockView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoIntroVideoBlockView.swift @@ -30,8 +30,7 @@ extension CourseInfoTabInfoIntroVideoBlockView { let playImageTintColor = UIColor.white let playImageViewSize = CGSize(width: 25, height: 31) - let overlayColor = UIColor.stepikAccent - let overlayOpacity: CGFloat = 0.4 + let overlayColor = UIColor.stepikOverlayBackground } } @@ -59,7 +58,6 @@ final class CourseInfoTabInfoIntroVideoBlockView: UIView { private lazy var overlayView: UIView = { let view = UIView() view.backgroundColor = self.appearance.overlayColor - view.alpha = self.appearance.overlayOpacity self.addPlayVideoGestureRecognizer(view: view) return view }() @@ -139,7 +137,7 @@ final class CourseInfoTabInfoIntroVideoBlockView: UIView { extension CourseInfoTabInfoIntroVideoBlockView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .clear } func addSubviews() { diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoTextBlockView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoTextBlockView.swift index b7bf00d2d6..e768ab5016 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoTextBlockView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/Blocks/CourseInfoTabInfoTextBlockView.swift @@ -7,7 +7,7 @@ extension CourseInfoTabInfoTextBlockView { let messageLabelInsets = UIEdgeInsets(top: 16, left: 47, bottom: 30, right: 47) let messageLabelFont = UIFont.systemFont(ofSize: 14, weight: .light) - let messageLabelTextColor = UIColor.stepikAccent + let messageLabelTextColor = UIColor.stepikSecondaryText let messageLabelLineSpacing: CGFloat = 2.6 } @@ -64,7 +64,7 @@ final class CourseInfoTabInfoTextBlockView: UIView { extension CourseInfoTabInfoTextBlockView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .clear } func addSubviews() { diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/CourseInfoTabInfoView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/CourseInfoTabInfoView.swift index 32749b02ad..092f2b3ee7 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/CourseInfoTabInfoView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabInfo/Views/CourseInfoTabInfoView.swift @@ -15,7 +15,7 @@ extension CourseInfoTabInfoView { let stackViewInsets = LayoutInsets(top: 20) let authorTitleLabelFont = UIFont.systemFont(ofSize: 14, weight: .light) - let authorTitleHighlightColor = UIColor(hex6: 0x0092E4) + let authorTitleHighlightColor = UIColor.stepikLightBlue let authorTitleLabelInsets = UIEdgeInsets(top: 0, left: 47, bottom: 20, right: 47) let authorTitleLabelNumberOfLines = 0 let authorIconLeadingSpace: CGFloat = 20 @@ -38,7 +38,7 @@ final class CourseInfoTabInfoView: UIView { }() private lazy var loadingIndicator: UIActivityIndicatorView = { - let view = UIActivityIndicatorView(style: .gray) + let view = UIActivityIndicatorView(style: .stepikGray) view.hidesWhenStopped = true return view }() @@ -52,6 +52,7 @@ final class CourseInfoTabInfoView: UIView { self.delegate = delegate super.init(frame: frame) + self.setupView() self.addSubviews() self.makeConstraints() } @@ -174,6 +175,10 @@ final class CourseInfoTabInfoView: UIView { // MARK: - CourseInfoTabInfoView: ProgrammaticallyInitializableViewProtocol - extension CourseInfoTabInfoView: ProgrammaticallyInitializableViewProtocol { + func setupView() { + self.backgroundColor = .clear + } + func addSubviews() { self.addSubview(self.scrollableStackView) self.addSubview(self.loadingIndicator) diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/CourseInfoTabReviewsDataFlow.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/CourseInfoTabReviewsDataFlow.swift index 4ad551a35a..9fd8ab4341 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/CourseInfoTabReviewsDataFlow.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/CourseInfoTabReviewsDataFlow.swift @@ -13,7 +13,7 @@ enum CourseInfoTabReviews { /// Show reviews enum ReviewsLoad { - struct Request { } + struct Request {} struct Response { let course: Course @@ -29,7 +29,7 @@ enum CourseInfoTabReviews { /// Load next part reviews enum NextReviewsLoad { - struct Request { } + struct Request {} struct Response { let course: Course @@ -69,7 +69,7 @@ enum CourseInfoTabReviews { /// Present write course review (after click) enum WriteCourseReviewPresentation { - struct Request { } + struct Request {} struct Response { let course: Course diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/InputOutput/CourseInfoTabReviewsInputProtocol.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/InputOutput/CourseInfoTabReviewsInputProtocol.swift index a82bbaaf8d..413f2eeaf1 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/InputOutput/CourseInfoTabReviewsInputProtocol.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/InputOutput/CourseInfoTabReviewsInputProtocol.swift @@ -1,3 +1,3 @@ import Foundation -protocol CourseInfoTabReviewsInputProtocol: CourseInfoSubmoduleProtocol { } +protocol CourseInfoTabReviewsInputProtocol: CourseInfoSubmoduleProtocol {} diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Cell/CourseInfoTabReviewsCellView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Cell/CourseInfoTabReviewsCellView.swift index bfb711f0ff..2bdf854f82 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Cell/CourseInfoTabReviewsCellView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Cell/CourseInfoTabReviewsCellView.swift @@ -11,13 +11,13 @@ extension CourseInfoTabReviewsCellView { let dateLabelInsets = UIEdgeInsets(top: 20, left: 16, bottom: 0, right: 16) let dateLabelFont = UIFont.systemFont(ofSize: 12, weight: .light) - let dateLabelTextColor = UIColor.stepikAccent + let dateLabelTextColor = UIColor.stepikPrimaryText - let nameLabelTextColor = UIColor.stepikAccent + let nameLabelTextColor = UIColor.stepikPrimaryText let nameLabelFont = UIFont.systemFont(ofSize: 14, weight: .medium) let nameLabelInsets = UIEdgeInsets(top: 8, left: 16, bottom: 0, right: 20) - let textLabelTextColor = UIColor.stepikAccent + let textLabelTextColor = UIColor.stepikPrimaryText let textLabelFont = UIFont.systemFont(ofSize: 14, weight: .light) let textLabelInsets = UIEdgeInsets(top: 8, left: 0, bottom: 20, right: 20) @@ -60,7 +60,7 @@ final class CourseInfoTabReviewsCellView: UIView { private lazy var starsRatingView: CourseRatingView = { var appearance = CourseRatingView.Appearance() - appearance.statClearColor = self.appearance.clearStarsColor + appearance.starClearColor = self.appearance.clearStarsColor let view = CourseRatingView(appearance: appearance) return view }() diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Cell/CourseInfoTabReviewsTableViewCell.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Cell/CourseInfoTabReviewsTableViewCell.swift index cfc0f63a0e..4a18e73682 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Cell/CourseInfoTabReviewsTableViewCell.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Cell/CourseInfoTabReviewsTableViewCell.swift @@ -3,7 +3,7 @@ import Foundation final class CourseInfoTabReviewsTableViewCell: UITableViewCell, Reusable { enum Appearance { static let separatorHeight: CGFloat = 0.5 - static let separatorColor = UIColor(hex6: 0xe7e7e7) + static let separatorColor = UIColor.stepikSeparator } private lazy var cellView = CourseInfoTabReviewsCellView() diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/CourseInfoTabReviewsView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/CourseInfoTabReviewsView.swift index b4ccfaf1b8..1843bb05ce 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/CourseInfoTabReviewsView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/CourseInfoTabReviewsView.swift @@ -22,7 +22,7 @@ extension CourseInfoTabReviewsView { let paginationViewHeight: CGFloat = 52 let emptyStateLabelFont = UIFont.systemFont(ofSize: 17, weight: .light) - let emptyStateLabelColor = UIColor.stepikAccentAlpha40 + let emptyStateLabelColor = UIColor.stepikPlaceholderText let emptyStateLabelInsets = UIEdgeInsets(top: 0, left: 35, bottom: 0, right: 35) } } diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Header/CourseInfoTabReviewsHeaderView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Header/CourseInfoTabReviewsHeaderView.swift index 89c49d6e4c..57e7a00f68 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Header/CourseInfoTabReviewsHeaderView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabReviews/Views/Header/CourseInfoTabReviewsHeaderView.swift @@ -5,16 +5,18 @@ extension CourseInfoTabReviewsHeaderView { struct Appearance { let buttonSpacing: CGFloat = 14.0 - let buttonTintColor = UIColor.stepikAccent + let buttonTintColor = UIColor.stepikPrimaryText let buttonFont = UIFont.systemFont(ofSize: 14, weight: .light) let buttonImageInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 4) let buttonTitleInsets = UIEdgeInsets(top: 8, left: 4, bottom: 8, right: 0) let buttonImageSize = CGSize(width: 15, height: 15) let labelFont = UIFont.systemFont(ofSize: 14, weight: .light) - let labelTextColor = UIColor.stepikAccent + let labelTextColor = UIColor.stepikPrimaryText let insets = UIEdgeInsets(top: 0, left: 18, bottom: 0, right: 18) + + let separatorHeight: CGFloat = 0.5 } } @@ -170,7 +172,7 @@ extension CourseInfoTabReviewsHeaderView: ProgrammaticallyInitializableViewProto .equalTo(self.stackView.snp.bottom) .offset(self.appearance.insets.bottom) make.leading.trailing.bottom.equalToSuperview() - make.height.equalTo(SeparatorView.Appearance().height) + make.height.equalTo(self.appearance.separatorHeight) } } } diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/CourseInfoTabSyllabusDataFlow.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/CourseInfoTabSyllabusDataFlow.swift index 8c0df5e9b4..78045d1ab7 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/CourseInfoTabSyllabusDataFlow.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/CourseInfoTabSyllabusDataFlow.swift @@ -28,7 +28,7 @@ enum CourseInfoTabSyllabus { /// Course syllabus enum SyllabusLoad { - struct Request { } + struct Request {} struct Response { var result: StepikResult @@ -147,7 +147,7 @@ enum CourseInfoTabSyllabus { /// Update syllabus header (deadlines, download all) enum SyllabusHeaderUpdate { - struct Request { } + struct Request {} struct Response { let isPersonalDeadlinesAvailable: Bool @@ -164,7 +164,7 @@ enum CourseInfoTabSyllabus { /// Click on personal deadlines button enum PersonalDeadlinesButtonAction { - struct Request { } + struct Request {} } /// Handle HUD diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/InputOutput/CourseInfoTabSyllabusInputProtocol.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/InputOutput/CourseInfoTabSyllabusInputProtocol.swift index 8fad6e3507..1e24d6650e 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/InputOutput/CourseInfoTabSyllabusInputProtocol.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/InputOutput/CourseInfoTabSyllabusInputProtocol.swift @@ -1,3 +1,3 @@ import Foundation -protocol CourseInfoTabSyllabusInputProtocol: CourseInfoSubmoduleProtocol { } +protocol CourseInfoTabSyllabusInputProtocol: CourseInfoSubmoduleProtocol {} diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusCellStatsView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusCellStatsView.swift index 74fa381990..eb384be1c4 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusCellStatsView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusCellStatsView.swift @@ -7,7 +7,7 @@ extension CourseInfoTabSyllabusCellStatsView { let itemsSpacing: CGFloat = 8.0 let itemTextFont = UIFont.systemFont(ofSize: 12, weight: .light) - let itemTextColor = UIColor.stepikAccent + let itemTextColor = UIColor.stepikPrimaryText let learnersImageColor = UIColor.stepikAccent let learnersImageSize = CGSize(width: 8.5, height: 11) diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusCellView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusCellView.swift index 92fec0bfc2..d13101b85b 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusCellView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusCellView.swift @@ -9,7 +9,7 @@ extension CourseInfoTabSyllabusCellView { let coverImageViewInsets = UIEdgeInsets(top: 20, left: 23, bottom: 20, right: 0) let coverImageViewSize = CGSize(width: 30, height: 30) - let titleTextColor = UIColor.stepikAccent + let titleTextColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 14) let titleLabelInsets = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 16) @@ -18,14 +18,14 @@ extension CourseInfoTabSyllabusCellView { let downloadButtonCenterYOffsetOnCachedState: CGFloat = 9 let downloadedSizeLabelFont = UIFont.systemFont(ofSize: 12, weight: .light) - let downloadedSizeLabelTextColor = UIColor.stepikAccent + let downloadedSizeLabelTextColor = UIColor.stepikPrimaryText let downloadedSizeLabelInsets = UIEdgeInsets(top: 2, left: 0, bottom: 0, right: 16) let statsInsets = UIEdgeInsets(top: 10, left: 0, bottom: 20, right: 16) let statsViewHeight: CGFloat = 17.0 let progressViewHeight: CGFloat = 3 - let progressViewMainColor = UIColor.stepikGreen + let progressViewMainColor = UIColor.stepikGreenFixed let progressViewSecondaryColor = UIColor.clear let tapProxyViewSize = CGSize(width: 60, height: 60) @@ -210,6 +210,10 @@ final class CourseInfoTabSyllabusCellView: UIView { // MARK: - CourseInfoTabSyllabusCellView: ProgrammaticallyInitializableViewProtocol - extension CourseInfoTabSyllabusCellView: ProgrammaticallyInitializableViewProtocol { + func setupView() { + self.backgroundColor = .stepikBackground + } + func addSubviews() { self.addSubview(self.downloadButton) self.addSubview(self.downloadedSizeLabel) diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusTableViewCell.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusTableViewCell.swift index 6181556a97..a91ba36492 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusTableViewCell.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Cell/CourseInfoTabSyllabusTableViewCell.swift @@ -4,7 +4,7 @@ import UIKit final class CourseInfoTabSyllabusTableViewCell: UITableViewCell, Reusable { enum Appearance { static let separatorHeight: CGFloat = 0.5 - static let separatorColor = UIColor(hex6: 0xe7e7e7) + static let separatorColor = UIColor.stepikSeparator } private lazy var cellView = CourseInfoTabSyllabusCellView() diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Header/CourseInfoTabSyllabusHeaderView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Header/CourseInfoTabSyllabusHeaderView.swift index a158977876..38348b8044 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Header/CourseInfoTabSyllabusHeaderView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Header/CourseInfoTabSyllabusHeaderView.swift @@ -5,7 +5,7 @@ extension CourseInfoTabSyllabusHeaderView { struct Appearance { let buttonSpacing: CGFloat = 14.0 - let buttonTintColor = UIColor.stepikAccent + let buttonTintColor = UIColor.stepikPrimaryText let buttonFont = UIFont.systemFont(ofSize: 14, weight: .light) let buttonImageInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 4) let buttonTitleInsets = UIEdgeInsets(top: 8, left: 4, bottom: 8, right: 0) @@ -13,8 +13,8 @@ extension CourseInfoTabSyllabusHeaderView { let insets = UIEdgeInsets(top: 0, left: 18, bottom: 0, right: 18) - let separatorColor = UIColor(hex6: 0xcccccc) - let separatorHeight: CGFloat = 1 + let separatorColor = UIColor.stepikSeparator + let separatorHeight: CGFloat = 0.5 } } diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Section/CourseInfoTabSyllabusSectionDeadlinesView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Section/CourseInfoTabSyllabusSectionDeadlinesView.swift index 4dd99e9027..b6298b7d35 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Section/CourseInfoTabSyllabusSectionDeadlinesView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Section/CourseInfoTabSyllabusSectionDeadlinesView.swift @@ -11,7 +11,7 @@ extension CourseInfoTabSyllabusSectionDeadlinesView { let mainProgressColor = UIColor.stepikAccent let progressIndicatorHeight: CGFloat = 1.5 - let labelTextColor = UIColor.stepikAccent + let labelTextColor = UIColor.stepikPrimaryText let labelFont = UIFont.systemFont(ofSize: 13, weight: .light) let circleIndicatorRadius: CGFloat = 6.5 diff --git a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Section/CourseInfoTabSyllabusSectionView.swift b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Section/CourseInfoTabSyllabusSectionView.swift index 17f785b598..f8827b4c90 100644 --- a/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Section/CourseInfoTabSyllabusSectionView.swift +++ b/Stepic/Sources/Modules/CourseInfoSubmodules/CourseInfoTabSyllabus/Views/Section/CourseInfoTabSyllabusSectionView.swift @@ -3,27 +3,27 @@ import UIKit extension CourseInfoTabSyllabusSectionView { struct Appearance { - let backgroundColor = UIColor(hex6: 0xf6f6f6) + let backgroundColor = UIColor.stepikLightSecondaryBackground - let indexTextColor = UIColor.stepikAccent + let indexTextColor = UIColor.stepikPrimaryText let indexFont = UIFont.systemFont(ofSize: 15) let indexLabelInsets = UIEdgeInsets(top: 0, left: 18, bottom: 0, right: 12) // Width for two-digit indexes let indexLabelWidth: CGFloat = 16 - let examTextColor = UIColor.stepikAccent + let examTextColor = UIColor.stepikPrimaryText let examFont = UIFont.systemFont(ofSize: 14, weight: .light) let textStackViewSpacing: CGFloat = 10 let textStackViewInsets = UIEdgeInsets(top: 19, left: 12, bottom: 0, right: 15) - let titleTextColor = UIColor.stepikAccent + let titleTextColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 14) - let progressTextColor = UIColor.stepikAccent + let progressTextColor = UIColor.stepikPrimaryText let progressTextFont = UIFont.systemFont(ofSize: 14, weight: .light) - let requirementsTextColor = UIColor.stepikAccent + let requirementsTextColor = UIColor.stepikPrimaryText let requirementsTextFont = UIFont.systemFont(ofSize: 12) let downloadButtonInsets = UIEdgeInsets(top: 18, left: 0, bottom: 0, right: 16) @@ -31,13 +31,13 @@ extension CourseInfoTabSyllabusSectionView { let downloadButtonCenterYOffsetOnCachedState: CGFloat = 9 let downloadedSizeLabelFont = UIFont.systemFont(ofSize: 12, weight: .light) - let downloadedSizeLabelTextColor = UIColor.stepikAccent + let downloadedSizeLabelTextColor = UIColor.stepikPrimaryText let downloadedSizeLabelInsets = UIEdgeInsets(top: 2, left: 0, bottom: 0, right: 16) let deadlinesInsets = UIEdgeInsets(top: 16, left: 0, bottom: 19, right: 0) let progressViewHeight: CGFloat = 3 - let progressViewMainColor = UIColor.stepikGreen + let progressViewMainColor = UIColor.stepikGreenFixed let progressViewSecondaryColor = UIColor.clear let tapProxyViewSize = CGSize(width: 60, height: 60) diff --git a/Stepic/Sources/Modules/CourseList/CourseListAssembly.swift b/Stepic/Sources/Modules/CourseList/CourseListAssembly.swift index 974f38288b..16f845218b 100644 --- a/Stepic/Sources/Modules/CourseList/CourseListAssembly.swift +++ b/Stepic/Sources/Modules/CourseList/CourseListAssembly.swift @@ -17,7 +17,11 @@ class CourseListAssembly: Assembly { fatalError("Property should be overridden in subclass") } - fileprivate init(type: CourseListType, colorMode: CourseListColorMode, output: CourseListOutputProtocol? = nil) { + fileprivate init( + type: CourseListType, + colorMode: CourseListColorMode, + output: CourseListOutputProtocol? = nil + ) { self.type = type self.colorMode = colorMode self.moduleOutput = output diff --git a/Stepic/Sources/Modules/CourseList/CourseListDataFlow.swift b/Stepic/Sources/Modules/CourseList/CourseListDataFlow.swift index 4926393251..8394579ae2 100644 --- a/Stepic/Sources/Modules/CourseList/CourseListDataFlow.swift +++ b/Stepic/Sources/Modules/CourseList/CourseListDataFlow.swift @@ -1,3 +1,5 @@ +import Foundation + enum CourseList { // MARK: Common structs @@ -24,7 +26,7 @@ enum CourseList { /// Load and show courses for given course list enum CoursesLoad { - struct Request { } + struct Request {} struct Response { let isAuthorized: Bool @@ -37,7 +39,7 @@ enum CourseList { } /// Load and show next course page for given course list enum NextCoursesLoad { - struct Request { } + struct Request {} struct Response { let isAuthorized: Bool diff --git a/Stepic/Sources/Modules/CourseList/Provider/CourseListNetworkService.swift b/Stepic/Sources/Modules/CourseList/Provider/CourseListNetworkService.swift index d803e056ef..ede4f6f0f0 100644 --- a/Stepic/Sources/Modules/CourseList/Provider/CourseListNetworkService.swift +++ b/Stepic/Sources/Modules/CourseList/Provider/CourseListNetworkService.swift @@ -40,9 +40,9 @@ final class EnrolledCourseListNetworkService: BaseCourseListNetworkService, Cour return Promise.value(([], [], Meta.oneAndOnlyPage)) } - return self.coursesAPI.retrieve( - ids: userCoursesInfo.0.map { $0.courseId } - ).map { ($0, userCoursesInfo.0, userCoursesInfo.1) } + return self.coursesAPI + .retrieve(ids: userCoursesInfo.0.map { $0.courseId }) + .map { ($0, userCoursesInfo.0, userCoursesInfo.1) } }.done { courses, info, meta in let orderedCourses = courses.reordered( order: info.map { $0.courseId }, @@ -106,8 +106,7 @@ final class TagCourseListNetworkService: BaseCourseListNetworkService, CourseLis } } -final class CollectionCourseListNetworkService: BaseCourseListNetworkService, - CourseListNetworkServiceProtocol { +final class CollectionCourseListNetworkService: BaseCourseListNetworkService, CourseListNetworkServiceProtocol { let type: CollectionCourseListType init(type: CollectionCourseListType, coursesAPI: CoursesAPI) { @@ -150,11 +149,11 @@ final class SearchResultCourseListNetworkService: BaseCourseListNetworkService, query: self.type.query, language: self.type.language, page: page - ).then { result, meta -> Promise<([Int], Meta, [Course])> in + ).then { result, meta -> Promise<([Course.IdType], Meta, [Course])> in let ids = result.compactMap { $0.courseId } - return self.coursesAPI.retrieve( - ids: ids - ).map { (ids, meta, $0) } + return self.coursesAPI + .retrieve(ids: ids) + .map { (ids, meta, $0) } }.done { ids, meta, courses in let resultCourses = courses.reordered(order: ids, transform: { $0.id }) seal.fulfill((resultCourses, meta)) diff --git a/Stepic/Sources/Modules/CourseList/Provider/CourseListPersistenceStorage.swift b/Stepic/Sources/Modules/CourseList/Provider/CourseListPersistenceStorage.swift index bbb5adf35e..d2785b3c1d 100644 --- a/Stepic/Sources/Modules/CourseList/Provider/CourseListPersistenceStorage.swift +++ b/Stepic/Sources/Modules/CourseList/Provider/CourseListPersistenceStorage.swift @@ -28,8 +28,7 @@ final class PassiveCourseListPersistenceStorage: CourseListPersistenceStorage { self.list = cachedList } - func update(newCachedList: [Course.IdType]) { - } + func update(newCachedList: [Course.IdType]) {} func getCoursesList() -> [Course.IdType] { self.list } } diff --git a/Stepic/Sources/Modules/CourseList/Provider/CourseListProvider.swift b/Stepic/Sources/Modules/CourseList/Provider/CourseListProvider.swift index f78272fbdf..4b947cc76c 100644 --- a/Stepic/Sources/Modules/CourseList/Provider/CourseListProvider.swift +++ b/Stepic/Sources/Modules/CourseList/Provider/CourseListProvider.swift @@ -50,11 +50,11 @@ final class CourseListProvider: CourseListProviderProtocol { Promise { seal in self.networkService.fetch(page: page).then { (courses, meta) -> Promise<([Course], Meta, [Progress], [CourseReviewSummary])> in - let progressIDs = courses.compactMap { $0.progressId } + let progressesIDs = courses.compactMap { $0.progressId } let summariesIDs = courses.compactMap { $0.reviewSummaryId } return when( - fulfilled: self.progressesNetworkService.fetch(ids: progressIDs, page: 1), + fulfilled: self.progressesNetworkService.fetch(ids: progressesIDs, page: 1), self.reviewSummariesNetworkService.fetch(ids: summariesIDs, page: 1) ).compactMap { (courses, meta, $0.0, $1.0) } }.then { (courses, meta, progresses, reviewSummaries) -> Guarantee<([Course], Meta)> in diff --git a/Stepic/Sources/Modules/CourseList/Provider/CourseListTypes.swift b/Stepic/Sources/Modules/CourseList/Provider/CourseListTypes.swift index 521c67d563..fb78571980 100644 --- a/Stepic/Sources/Modules/CourseList/Provider/CourseListTypes.swift +++ b/Stepic/Sources/Modules/CourseList/Provider/CourseListTypes.swift @@ -10,8 +10,7 @@ struct PopularCourseListType: CourseListType { let language: ContentLanguage } -struct EnrolledCourseListType: CourseListType { -} +struct EnrolledCourseListType: CourseListType {} struct TagCourseListType: CourseListType { let id: Int diff --git a/Stepic/Sources/Modules/CourseList/Views/CourseListColorMode.swift b/Stepic/Sources/Modules/CourseList/Views/CourseListColorMode.swift index fcf8ebad02..631cc62634 100644 --- a/Stepic/Sources/Modules/CourseList/Views/CourseListColorMode.swift +++ b/Stepic/Sources/Modules/CourseList/Views/CourseListColorMode.swift @@ -12,8 +12,8 @@ extension CourseListColorMode { switch self { case .light: return .init( - titleLabelColor: UIColor.stepikAccent, - showAllButtonColor: UIColor.stepikAccentAlpha30 + titleLabelColor: .stepikPrimaryText, + showAllButtonColor: .stepikTertiaryText ) case .dark: return .init( @@ -63,59 +63,36 @@ extension CourseListColorMode { switch self { case .light: return .init( - textColor: UIColor.stepikPrimaryText, - backgroundColor: self.courseWidgetButtonBackgroundColor, - callToActionTextColor: UIColor.stepikGreen, - callToActionBackgroundColor: UIColor.stepikGreen.withAlphaComponent(0.1) + textColor: .stepikPrimaryText, + backgroundColor: .stepikLightSecondaryBackground, + callToActionTextColor: .stepikCallToActionText, + callToActionBackgroundColor: .stepikCallToActionBackground ) case .dark: return .init( - textColor: UIColor.white, - backgroundColor: self.courseWidgetButtonBackgroundColor, - callToActionTextColor: UIColor.stepikGreen, - callToActionBackgroundColor: UIColor.stepikGreen.withAlphaComponent(0.1) + textColor: .white, + backgroundColor: UIColor.white.withAlphaComponent(0.1), + callToActionTextColor: .stepikCallToActionText, + callToActionBackgroundColor: .stepikCallToActionBackground ) } } - private var courseWidgetButtonBackgroundColor: UIColor { - if #available(iOS 13.0, *) { - return UIColor { (traitCollection: UITraitCollection) -> UIColor in - switch self { - case .light: - if traitCollection.userInterfaceStyle == .dark { - return .stepikSecondaryBackground - } - return .stepikAccentAlpha06 - case .dark: - return UIColor.white.withAlphaComponent(0.1) - } - } - } else { - switch self { - case .light: - return .stepikAccentAlpha06 - case .dark: - return UIColor.white.withAlphaComponent(0.1) - } - } - } - var courseWidgetStatsViewAppearance: CourseWidgetStatsView.Appearance { switch self { case .light: return .init( - imagesRenderingBackgroundColor: UIColor.stepikAccent, - imagesRenderingTintColor: UIColor.stepikGreen, - itemTextColor: UIColor.stepikAccent, - itemImageTintColor: UIColor.stepikAccent + imagesRenderingBackgroundColor: .stepikAccent, + imagesRenderingTintColor: .stepikGreenFixed, + itemTextColor: .stepikPrimaryText, + itemImageTintColor: .stepikAccent ) case .dark: return .init( - imagesRenderingBackgroundColor: UIColor.white, - imagesRenderingTintColor: UIColor.stepikGreen, - itemTextColor: UIColor.white, - itemImageTintColor: UIColor.white + imagesRenderingBackgroundColor: .white, + imagesRenderingTintColor: .stepikGreenFixed, + itemTextColor: .white, + itemImageTintColor: .white ) } } @@ -124,7 +101,7 @@ extension CourseListColorMode { switch self { case .light: var appearance = CourseWidgetLabel.Appearance() - appearance.textColor = .stepikAccent + appearance.textColor = .stepikPrimaryText return appearance case .dark: var appearance = CourseWidgetLabel.Appearance() diff --git a/Stepic/Sources/Modules/CourseList/Views/CourseListView.swift b/Stepic/Sources/Modules/CourseList/Views/CourseListView.swift index dca8ba5c64..185ae01478 100644 --- a/Stepic/Sources/Modules/CourseList/Views/CourseListView.swift +++ b/Stepic/Sources/Modules/CourseList/Views/CourseListView.swift @@ -9,7 +9,7 @@ extension CourseListView { let lightModeBackgroundColor = UIColor.stepikBackground let darkModeBackgroundColor = UIColor.stepikAccentFixed - let darkModeDarkInterfaceStyleBackgroundColor = UIColor.stepikSecondaryBackground + let darkModeDarkInterfaceBackgroundColor = UIColor.stepikSecondaryBackground let horizontalLayoutNextPageWidth: CGFloat = 12.0 } @@ -104,11 +104,9 @@ class CourseListView: UIView { case .light: return self.appearance.lightModeBackgroundColor case .dark: - if #available(iOS 13.0, *), self.traitCollection.userInterfaceStyle == .dark { - return self.appearance.darkModeDarkInterfaceStyleBackgroundColor - } else { - return self.appearance.darkModeBackgroundColor - } + return self.isDarkInterfaceStyle + ? self.appearance.darkModeDarkInterfaceBackgroundColor + : self.appearance.darkModeBackgroundColor } } diff --git a/Stepic/Sources/Modules/CourseList/Views/Layouts/BaseCourseListFlowLayout.swift b/Stepic/Sources/Modules/CourseList/Views/Layouts/BaseCourseListFlowLayout.swift index faf113b935..33fa27cd9b 100644 --- a/Stepic/Sources/Modules/CourseList/Views/Layouts/BaseCourseListFlowLayout.swift +++ b/Stepic/Sources/Modules/CourseList/Views/Layouts/BaseCourseListFlowLayout.swift @@ -12,7 +12,7 @@ class BaseListFlowLayout: UICollectionViewFlowLayout { var count = 0 for section in 0.. Void)? { get { self.cellView.onReplyClick @@ -134,6 +142,14 @@ final class DiscussionsTableViewCell: UITableViewCell, Reusable { self.resetViews() } + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + self.performBlockIfAppearanceChanged(from: previousTraitCollection) { + self.backgroundColor = self.getBackgroundColor() + } + } + // MARK: - Public API func configure(viewModel: ViewModel) { @@ -143,10 +159,8 @@ final class DiscussionsTableViewCell: UITableViewCell, Reusable { separatorFollowsDepth: viewModel.separatorFollowsDepth ) self.updateSeparator(newStyle: viewModel.separatorStyle) + self.shouldHighlightBackground = viewModel.isSelected self.cellView.configure(viewModel: viewModel.comment) - self.backgroundColor = viewModel.isSelected - ? Appearance.selectedBackgroundColor - : Appearance.defaultBackgroundColor } func calculateCellHeight(maxPreferredWidth: CGFloat) -> CGFloat { @@ -192,7 +206,7 @@ final class DiscussionsTableViewCell: UITableViewCell, Reusable { private func resetViews() { self.updateLeadingOffsets(commentType: .discussion, hasReplies: false, separatorFollowsDepth: false) self.updateSeparator(newStyle: .small) - self.backgroundColor = Appearance.defaultBackgroundColor + self.shouldHighlightBackground = false self.cellView.configure(viewModel: nil) } @@ -224,6 +238,16 @@ final class DiscussionsTableViewCell: UITableViewCell, Reusable { self.separatorView.isHidden = style == .none } + private func getBackgroundColor() -> UIColor { + if self.shouldHighlightBackground { + return self.isDarkInterfaceStyle + ? Appearance.selectedDarkBackgroundColor + : Appearance.selectedLightBackgroundColor + } else { + return Appearance.defaultBackgroundColor + } + } + // MARK: - Types struct ViewModel { @@ -248,7 +272,7 @@ final class DiscussionsTableViewCell: UITableViewCell, Reusable { case .small: return 1.0 / UIScreen.main.scale case .large: - return 8.0 / UIScreen.main.scale + return 6.0 / UIScreen.main.scale case .none: return 0.0 } diff --git a/Stepic/Sources/Modules/Discussions/Views/DiscussionsSolutionControl.swift b/Stepic/Sources/Modules/Discussions/Views/DiscussionsSolutionControl.swift index 3a0b3d308d..7942f4b0a0 100644 --- a/Stepic/Sources/Modules/Discussions/Views/DiscussionsSolutionControl.swift +++ b/Stepic/Sources/Modules/Discussions/Views/DiscussionsSolutionControl.swift @@ -7,12 +7,12 @@ extension DiscussionsSolutionControl { let cornerRadius: CGFloat = 6 let borderWidth: CGFloat = 1 - let borderColor = UIColor(hex6: 0xCCCCCC) + let borderColor = UIColor.stepikSeparator var isBorderEnabled = true let iconInsets = LayoutInsets(top: 8, left: 8, bottom: 8, right: 8) - let titleTextColor = UIColor.stepikAccent + let titleTextColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 14) let titleInsets = LayoutInsets(top: 8, left: 8, bottom: 8, right: 8) } @@ -108,9 +108,9 @@ final class DiscussionsSolutionControl: UIControl { var tintColor: UIColor { switch self { case .correct: - return UIColor(hex6: 0x66CC66) + return UIColor.stepikGreen case .wrong: - return UIColor(hex6: 0xFF7965) + return UIColor.stepikLightRed } } diff --git a/Stepic/Sources/Modules/Discussions/Views/DiscussionsView.swift b/Stepic/Sources/Modules/Discussions/Views/DiscussionsView.swift index f023df8383..1878a303a2 100644 --- a/Stepic/Sources/Modules/Discussions/Views/DiscussionsView.swift +++ b/Stepic/Sources/Modules/Discussions/Views/DiscussionsView.swift @@ -9,8 +9,6 @@ protocol DiscussionsViewDelegate: AnyObject { extension DiscussionsView { struct Appearance { - let backgroundColor: UIColor = .white - let paginationViewHeight: CGFloat = 52 let skeletonCellHeight: CGFloat = 130 } @@ -29,7 +27,6 @@ final class DiscussionsView: UIView { private lazy var tableView: UITableView = { let tableView = UITableView() - tableView.backgroundColor = .clear tableView.separatorStyle = .none tableView.refreshControl = self.refreshControl @@ -63,7 +60,6 @@ final class DiscussionsView: UIView { self.tableViewDelegate = tableViewDelegate super.init(frame: frame) - self.setupView() self.addSubviews() self.makeConstraints() } @@ -152,10 +148,6 @@ final class DiscussionsView: UIView { // MARK: - DiscussionsView: ProgrammaticallyInitializableViewProtocol - extension DiscussionsView: ProgrammaticallyInitializableViewProtocol { - func setupView() { - self.backgroundColor = self.appearance.backgroundColor - } - func addSubviews() { self.addSubview(self.tableView) } diff --git a/Stepic/Sources/Modules/Downloads/DownloadsDataFlow.swift b/Stepic/Sources/Modules/Downloads/DownloadsDataFlow.swift index 49bf7e05f3..7d182b9449 100644 --- a/Stepic/Sources/Modules/Downloads/DownloadsDataFlow.swift +++ b/Stepic/Sources/Modules/Downloads/DownloadsDataFlow.swift @@ -12,7 +12,7 @@ enum Downloads { /// Show downloads enum DownloadsLoad { - struct Request { } + struct Request {} struct Response { let data: DownloadsData diff --git a/Stepic/Sources/Modules/Downloads/Views/Cell/DownloadsCellView.swift b/Stepic/Sources/Modules/Downloads/Views/Cell/DownloadsCellView.swift index c36e04721e..bf9641c8a7 100644 --- a/Stepic/Sources/Modules/Downloads/Views/Cell/DownloadsCellView.swift +++ b/Stepic/Sources/Modules/Downloads/Views/Cell/DownloadsCellView.swift @@ -10,7 +10,7 @@ extension DownloadsCellView { let titleInsets = LayoutInsets(left: 8) let subtitleFont = UIFont.systemFont(ofSize: 14, weight: .regular) - let subtitleTextColor = UIColor(hex6: 0x8E8E93) + let subtitleTextColor = UIColor.stepikSecondaryText let subtitleMaxLinesCount = 1 } } diff --git a/Stepic/Sources/Modules/Downloads/Views/Cell/DownloadsTableViewCell.swift b/Stepic/Sources/Modules/Downloads/Views/Cell/DownloadsTableViewCell.swift index c5f34525f1..b7b61a140a 100644 --- a/Stepic/Sources/Modules/Downloads/Views/Cell/DownloadsTableViewCell.swift +++ b/Stepic/Sources/Modules/Downloads/Views/Cell/DownloadsTableViewCell.swift @@ -6,7 +6,7 @@ final class DownloadsTableViewCell: UITableViewCell, Reusable { static let cellViewInsets = LayoutInsets(top: 8, left: 16, bottom: 8, right: 16) static let separatorHeight: CGFloat = 0.5 - static let separatorColor = UIColor(hex6: 0xe7e7e7) + static let separatorColor = UIColor.stepikSeparator static let separatorInsets = LayoutInsets(left: 16) } diff --git a/Stepic/Sources/Modules/EditStep/EditStepDataFlow.swift b/Stepic/Sources/Modules/EditStep/EditStepDataFlow.swift index 3220848ad8..bbb4a5160f 100644 --- a/Stepic/Sources/Modules/EditStep/EditStepDataFlow.swift +++ b/Stepic/Sources/Modules/EditStep/EditStepDataFlow.swift @@ -12,7 +12,7 @@ enum EditStep { /// Load step source content enum LoadStepSource { - struct Request { } + struct Request {} struct Response { let data: StepikResult @@ -40,7 +40,7 @@ enum EditStep { /// Try to update remote step source via API enum RemoteStepSourceUpdate { - struct Request { } + struct Request {} struct Response { let isSuccessful: Bool diff --git a/Stepic/Sources/Modules/EditStep/EditStepView.swift b/Stepic/Sources/Modules/EditStep/EditStepView.swift index 953af0687d..7c6655b192 100644 --- a/Stepic/Sources/Modules/EditStep/EditStepView.swift +++ b/Stepic/Sources/Modules/EditStep/EditStepView.swift @@ -5,19 +5,19 @@ import UIKit extension EditStepView { struct Appearance { - let backgroundColor = UIColor.white + let backgroundColor = UIColor.stepikBackground let loadingIndicatorColor = UIColor.stepikLoadingIndicator let messageFont = UIFont.systemFont(ofSize: 12) - let messageTextColor = UIColor(hex6: 0x8E8E93) + let messageTextColor = UIColor.stepikSecondaryText let messageLabelInsets = LayoutInsets(top: 16, left: 16, right: 16) let separatorInsets = LayoutInsets(top: 8) let textViewTextInsets = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) let textViewFont = UIFont.systemFont(ofSize: 16) - let textViewTextColor = UIColor.stepikAccent + let textViewTextColor = UIColor.stepikPrimaryText let textViewPlaceholderColor = UIColor.stepikPlaceholderText } } @@ -68,7 +68,7 @@ final class EditStepView: UIView { }() private lazy var loadingIndicator: UIActivityIndicatorView = { - let loadingIndicatorView = UIActivityIndicatorView(style: .whiteLarge) + let loadingIndicatorView = UIActivityIndicatorView(style: .stepikWhiteLarge) loadingIndicatorView.color = self.appearance.loadingIndicatorColor loadingIndicatorView.hidesWhenStopped = true loadingIndicatorView.startAnimating() @@ -143,8 +143,12 @@ extension EditStepView: ProgrammaticallyInitializableViewProtocol { func makeConstraints() { self.messageLabel.translatesAutoresizingMaskIntoConstraints = false self.messageLabel.snp.makeConstraints { make in - make.leading.equalTo(self.safeAreaLayoutGuide.snp.leading).offset(self.appearance.messageLabelInsets.left) - make.top.equalToSuperview().offset(self.appearance.messageLabelInsets.top) + make.leading + .equalTo(self.safeAreaLayoutGuide.snp.leading) + .offset(self.appearance.messageLabelInsets.left) + make.top + .equalToSuperview() + .offset(self.appearance.messageLabelInsets.top) make.trailing .equalTo(self.safeAreaLayoutGuide.snp.trailing) .offset(-self.appearance.messageLabelInsets.right) @@ -153,7 +157,9 @@ extension EditStepView: ProgrammaticallyInitializableViewProtocol { self.separatorView.translatesAutoresizingMaskIntoConstraints = false self.separatorView.snp.makeConstraints { make in make.leading.trailing.equalToSuperview() - make.top.equalTo(self.messageLabel.snp.bottom).offset(self.appearance.separatorInsets.top) + make.top + .equalTo(self.messageLabel.snp.bottom) + .offset(self.appearance.separatorInsets.top) } self.textView.translatesAutoresizingMaskIntoConstraints = false diff --git a/Stepic/Sources/Modules/EditStep/EditStepViewController.swift b/Stepic/Sources/Modules/EditStep/EditStepViewController.swift index 789e6349b8..a3b437c838 100644 --- a/Stepic/Sources/Modules/EditStep/EditStepViewController.swift +++ b/Stepic/Sources/Modules/EditStep/EditStepViewController.swift @@ -42,7 +42,7 @@ final class EditStepViewController: UIViewController, ControllerWithStepikPlaceh ) private lazy var activityIndicatorBarButtonItem: UIBarButtonItem = { - let activityIndicator = UIActivityIndicatorView(style: .white) + let activityIndicator = UIActivityIndicatorView(style: .stepikWhite) activityIndicator.color = .stepikLoadingIndicator activityIndicator.startAnimating() return UIBarButtonItem(customView: activityIndicator) diff --git a/Stepic/Sources/Modules/Explore/ExploreDataFlow.swift b/Stepic/Sources/Modules/Explore/ExploreDataFlow.swift index 9b6db08760..4e85879534 100644 --- a/Stepic/Sources/Modules/Explore/ExploreDataFlow.swift +++ b/Stepic/Sources/Modules/Explore/ExploreDataFlow.swift @@ -1,4 +1,4 @@ -import Foundation +import UIKit enum Explore { // MARK: Submodules identifiers @@ -17,8 +17,7 @@ enum Explore { /// Content refresh enum ContentLoad { - struct Request { - } + struct Request {} struct Response { let contentLanguage: ContentLanguage @@ -31,7 +30,7 @@ enum Explore { /// Check for language switch visibility enum LanguageSwitchAvailabilityCheck { - struct Request { } + struct Request {} struct Response { let isHidden: Bool diff --git a/Stepic/Sources/Modules/Explore/ExploreViewController.swift b/Stepic/Sources/Modules/Explore/ExploreViewController.swift index 1a01bd1da3..b426059223 100644 --- a/Stepic/Sources/Modules/Explore/ExploreViewController.swift +++ b/Stepic/Sources/Modules/Explore/ExploreViewController.swift @@ -54,6 +54,7 @@ final class ExploreViewController: BaseExploreViewController { override func viewDidLoad() { super.viewDidLoad() + self.exploreView?.delegate = self self.navigationItem.titleView = self.searchBar self.exploreInteractor?.doLanguageSwitchBlockLoad(request: .init()) @@ -88,8 +89,12 @@ final class ExploreViewController: BaseExploreViewController { case .normal(let language): self.exploreView?.endRefreshing() DispatchQueue.main.asyncAfter(deadline: .now() + Animation.modulesRefreshDelay) { [weak self] in - self?.removeLanguageDependentSubmodules() - self?.initLanguageDependentSubmodules(contentLanguage: language) + guard let strongSelf = self else { + return + } + + strongSelf.removeLanguageDependentSubmodules() + strongSelf.initLanguageDependentSubmodules(contentLanguage: language) } case .loading: break @@ -105,7 +110,7 @@ final class ExploreViewController: BaseExploreViewController { self.exploreInteractor?.doContentLoad(request: .init()) } - func initLanguageDependentSubmodules(contentLanguage: ContentLanguage) { + private func initLanguageDependentSubmodules(contentLanguage: ContentLanguage) { // Stories if !self.isStoriesHidden { let storiesAssembly = StoriesAssembly( @@ -143,8 +148,7 @@ final class ExploreViewController: BaseExploreViewController { // Collection let collectionAssembly = CourseListsCollectionAssembly( contentLanguage: contentLanguage, - output: self.interactor - as? (CourseListCollectionOutputProtocol & CourseListOutputProtocol) + output: self.interactor as? (CourseListCollectionOutputProtocol & CourseListOutputProtocol) ) let collectionViewController = collectionAssembly.makeModule() self.registerSubmodule( @@ -204,7 +208,7 @@ final class ExploreViewController: BaseExploreViewController { let viewController = searchResultAssembly.makeModule() self.addChild(viewController) self.view.addSubview(viewController.view) - viewController.view.snp.makeConstraints { make -> Void in + viewController.view.snp.makeConstraints { make in make.edges.equalToSuperview() } self.searchResultsModuleInput = searchResultAssembly.moduleInput diff --git a/Stepic/Sources/Modules/Explore/View/ExploreBlockHeaderView.swift b/Stepic/Sources/Modules/Explore/View/ExploreBlockHeaderView.swift index 9d82c87d9c..ada4257930 100644 --- a/Stepic/Sources/Modules/Explore/View/ExploreBlockHeaderView.swift +++ b/Stepic/Sources/Modules/Explore/View/ExploreBlockHeaderView.swift @@ -9,14 +9,14 @@ protocol ExploreBlockHeaderViewProtocol: AnyObject { extension ExploreBlockHeaderView { struct Appearance { - var titleLabelColor = UIColor.stepikAccent + var titleLabelColor = UIColor.stepikPrimaryText let titleLabelFont = UIFont.systemFont(ofSize: 20) let titleLabelInsets = UIEdgeInsets(top: 0, left: 0, bottom: 8, right: 0) let descriptionLabelFont = UIFont.systemFont(ofSize: 16) - let descriptionLabelColor = UIColor.stepikAccentAlpha30 + let descriptionLabelColor = UIColor.stepikTertiaryText - var showAllButtonColor = UIColor.stepikAccentAlpha30 + var showAllButtonColor = UIColor.stepikTertiaryText let showAllButtonFont = UIFont.systemFont(ofSize: 20) let showAllButtonInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 0) } @@ -25,11 +25,6 @@ extension ExploreBlockHeaderView { final class ExploreBlockHeaderView: UIView, ExploreBlockHeaderViewProtocol { let appearance: Appearance - private let splitTestingService = SplitTestingService( - analyticsService: AnalyticsUserProperties(), - storage: UserDefaults.standard - ) - private lazy var titleLabel: UILabel = { let label = UILabel() label.font = self.appearance.titleLabelFont @@ -52,14 +47,7 @@ final class ExploreBlockHeaderView: UIView, ExploreBlockHeaderViewProtocol { button.titleLabel?.font = self.appearance.showAllButtonFont button.contentHorizontalAlignment = .right button.addTarget(self, action: #selector(self.showAllButtonClicked), for: .touchUpInside) - - var showAllTitle = NSLocalizedString("ShowAll", comment: "") - if CourseListSeeAllTextSplitTest.shouldParticipate { - let splitTest = self.splitTestingService.fetchSplitTest(CourseListSeeAllTextSplitTest.self) - showAllTitle = splitTest.currentGroup.seeAllTitle - } - button.setTitle(showAllTitle, for: .normal) - + button.setTitle(NSLocalizedString("ShowAll", comment: ""), for: .normal) return button }() diff --git a/Stepic/Sources/Modules/Explore/View/ExploreSearchBar.swift b/Stepic/Sources/Modules/Explore/View/ExploreSearchBar.swift index 4c992b991b..5ee96ca7fc 100644 --- a/Stepic/Sources/Modules/Explore/View/ExploreSearchBar.swift +++ b/Stepic/Sources/Modules/Explore/View/ExploreSearchBar.swift @@ -4,7 +4,7 @@ import UIKit final class ExploreSearchBar: UISearchBar { enum Appearance { static let searchFieldPositionAdjustment = UIOffset(horizontal: -6, vertical: 0) - static let textColor = UIColor.stepikAccent + static let textColor = UIColor.stepikPrimaryText // Height should be fixed and leq than 44pt (due to iOS 11+ strange nav bar) static let barHeight: CGFloat = 44.0 diff --git a/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/ContentLanguageSwitchDataFlow.swift b/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/ContentLanguageSwitchDataFlow.swift index fe5538d038..d825eaf183 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/ContentLanguageSwitchDataFlow.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/ContentLanguageSwitchDataFlow.swift @@ -12,7 +12,7 @@ enum ContentLanguageSwitch { /// Show languages enum LanguagesLoad { - struct Request { } + struct Request {} struct Response { let result: ContentLanguageInfo diff --git a/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/ContentLanguageSwitchInteractor.swift b/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/ContentLanguageSwitchInteractor.swift index 08f651e4a1..1146a35efa 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/ContentLanguageSwitchInteractor.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/ContentLanguageSwitchInteractor.swift @@ -21,12 +21,19 @@ final class ContentLanguageSwitchInteractor: ContentLanguageSwitchInteractorProt } func doLanguagesListPresentation(request: ContentLanguageSwitch.LanguagesLoad.Request) { + let availableContentLanguagesGuarantee = self.provider.fetchAvailableLanguages() + let currentContentLanguageGuarantee = self.provider.fetchCurrentLanguage() + when( - fulfilled: self.provider.fetchAvailableLanguages(), - self.provider.fetchCurrentLanguage() - ).done { (availableContentLanguages, currentContentLanguage) in - let languages = availableContentLanguages.map { - language -> (UniqueIdentifierType, ContentLanguage) in + availableContentLanguagesGuarantee.asVoid(), + currentContentLanguageGuarantee.asVoid() + ).done { + guard let availableContentLanguages = availableContentLanguagesGuarantee.value, + let currentContentLanguage = currentContentLanguageGuarantee.value else { + return + } + + let languages = availableContentLanguages.map { language -> (UniqueIdentifierType, ContentLanguage) in (language.languageString, language) } @@ -39,8 +46,6 @@ final class ContentLanguageSwitchInteractor: ContentLanguageSwitchInteractorProt ) ) ) - }.catch { _ in - fatalError("Unexpected error while extracting info about languages") } } diff --git a/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/Views/ContentLanguageSwitchButton.swift b/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/Views/ContentLanguageSwitchButton.swift index 662b9c3d9d..bd7abe36bc 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/Views/ContentLanguageSwitchButton.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/Views/ContentLanguageSwitchButton.swift @@ -2,27 +2,42 @@ import UIKit final class ContentLanguageSwitchButton: BounceButton { enum Appearance { - static let selectedBackgroundColor = UIColor.stepikAccent - static let unselectedBackgroundColor = UIColor.stepikAccentAlpha06 + static let lightModeSelectedBackgroundColor = UIColor.stepikAccentFixed + static let darkModeSelectedBackgroundColor = UIColor.stepikTertiaryBackground + static let unselectedBackgroundColor = UIColor.stepikLightSecondaryBackground static let selectedTextColor = UIColor.white - static let unselectedTextColor = UIColor.stepikPrimaryText + static let unselectedTextColor = UIColor.stepikSecondaryText static let font = UIFont.systemFont(ofSize: 16, weight: .light) } override var isSelected: Bool { didSet { - if self.isSelected { - self.setSelectedState() - } else { - self.setUnselectedState() - } + self.updateViewColor() + } + } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + self.performBlockIfAppearanceChanged(from: previousTraitCollection) { + self.updateViewColor() + } + } + + private func updateViewColor() { + if self.isSelected { + self.setSelectedState() + } else { + self.setUnselectedState() } } private func setSelectedState() { - self.backgroundColor = Appearance.selectedBackgroundColor + self.backgroundColor = self.isDarkInterfaceStyle + ? Appearance.darkModeSelectedBackgroundColor + : Appearance.lightModeSelectedBackgroundColor self.titleLabel?.font = Appearance.font self.setTitleColor(Appearance.selectedTextColor, for: .selected) } diff --git a/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/Views/ContentLanguageSwitchView.swift b/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/Views/ContentLanguageSwitchView.swift index 5f8553ca2e..bb7ee2f989 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/Views/ContentLanguageSwitchView.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/ContentLanguageSwitch/Views/ContentLanguageSwitchView.swift @@ -10,10 +10,10 @@ protocol ContentLanguageSwitchViewDelegate: AnyObject { extension ContentLanguageSwitchView { struct Appearance { - let headerTitleColor = UIColor.stepikAccentAlpha30 + let headerTitleColor = UIColor.stepikTertiaryText let descriptionFont = UIFont.systemFont(ofSize: 14) - let descriptionTextColor = UIColor.lightGray + let descriptionTextColor = UIColor.stepikTertiaryText let descriptionLabelInsets = UIEdgeInsets(top: 20, left: 20, bottom: 16, right: 20) let buttonsInsets = UIEdgeInsets(top: 20, left: 20, bottom: 0, right: 20) @@ -139,7 +139,7 @@ final class ContentLanguageSwitchView: UIView { extension ContentLanguageSwitchView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .stepikBackground } func addSubviews() { @@ -163,7 +163,9 @@ extension ContentLanguageSwitchView: ProgrammaticallyInitializableViewProtocol { self.descriptionLabel.translatesAutoresizingMaskIntoConstraints = false self.descriptionLabel.snp.makeConstraints { make in - make.bottom.equalToSuperview().offset(-self.appearance.descriptionLabelInsets.bottom) + make.bottom + .equalToSuperview() + .offset(-self.appearance.descriptionLabelInsets.bottom) make.top .equalTo(self.buttonsStackView.snp.bottom) .offset(self.appearance.descriptionLabelInsets.top) diff --git a/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseAssembly.swift b/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseAssembly.swift index cf18c923a4..22c770a50d 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseAssembly.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseAssembly.swift @@ -37,6 +37,7 @@ final class ContinueCourseAssembly: Assembly { presenter.viewController = viewController interactor.moduleOutput = self.moduleOutput + return viewController } } diff --git a/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseDataFlow.swift b/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseDataFlow.swift index 568da8cf2b..e854fe4132 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseDataFlow.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseDataFlow.swift @@ -5,7 +5,7 @@ enum ContinueCourse { /// Load last course enum LastCourseLoad { - struct Request { } + struct Request {} struct Response { let result: Course @@ -18,12 +18,12 @@ enum ContinueCourse { /// Go to last step enum ContinueCourseAction { - struct Request { } + struct Request {} } /// Check for tooltip enum TooltipAvailabilityCheck { - struct Request { } + struct Request {} struct Response { let shouldShowTooltip: Bool diff --git a/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCoursePresenter.swift b/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCoursePresenter.swift index 1cb9fa3636..9ad9a69a36 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCoursePresenter.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCoursePresenter.swift @@ -39,6 +39,7 @@ final class ContinueCoursePresenter: ContinueCoursePresenterProtocol { } return nil }() + return ContinueCourseViewModel( title: course.title, coverImageURL: URL(string: course.coverURLString), diff --git a/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseProvider.swift b/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseProvider.swift index 185da74fed..a2354f1dbb 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseProvider.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/ContinueCourse/ContinueCourseProvider.swift @@ -22,8 +22,7 @@ final class ContinueCourseProvider: ContinueCourseProviderProtocol { func fetchLastCourse() -> Promise { Promise { seal in - self.userCoursesAPI.retrieve(page: 1).then { - result -> Promise<[Course]> in + self.userCoursesAPI.retrieve(page: 1).then { result -> Promise<[Course]> in let lastCourse = result.0 .sorted(by: { $0.lastViewed > $1.lastViewed }) .prefix(1) @@ -32,9 +31,9 @@ final class ContinueCourseProvider: ContinueCourseProviderProtocol { return self.coursesAPI.retrieve(ids: coursesIDs) }.then { courses -> Promise<(Course?, Progress?)> in if let course = courses.first, - let progressId = course.progressId { + let progressID = course.progressId { return self.progressesNetworkService - .fetch(id: progressId) + .fetch(id: progressID) .map { (course, $0) } } else { return Promise.value((nil, nil)) diff --git a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionDataFlow.swift b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionDataFlow.swift index a232207688..7e4f4e2a8a 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionDataFlow.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionDataFlow.swift @@ -5,7 +5,7 @@ enum CourseListsCollection { /// Show course lists enum CourseListsLoad { - struct Request { } + struct Request {} struct Response { var result: StepikResult<[CourseListModel]> diff --git a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionInteractor.swift b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionInteractor.swift index 77946ed323..e74a7654ad 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionInteractor.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionInteractor.swift @@ -23,8 +23,7 @@ final class CourseListsCollectionInteractor: CourseListsCollectionInteractorProt } func doCourseListsFetch(request: CourseListsCollection.CourseListsLoad.Request) { - self.provider.fetchCachedCourseLists().then { - cachedCourseLists -> Promise<[CourseListModel]> in + self.provider.fetchCachedCourseLists().then { cachedCourseLists -> Promise<[CourseListModel]> in // Pass cached data to presenter and start fetching from remote let response = StepikResult<[CourseListModel]>.success(cachedCourseLists) self.presenter.presentCourses( @@ -48,8 +47,7 @@ final class CourseListsCollectionInteractor: CourseListsCollectionInteractorProt func doFullscreenCourseListPresentation( request: CourseListsCollection.FullscreenCourseListModulePresentation.Request ) { - guard let collectionCourseListType = request.courseListType - as? CollectionCourseListType else { + guard let collectionCourseListType = request.courseListType as? CollectionCourseListType else { return } @@ -81,13 +79,11 @@ extension CourseListsCollectionInteractor: CourseListOutputProtocol { self.moduleOutput?.presentAuthorization() } - func presentEmptyState(sourceModule: CourseListInputProtocol) { - } - - func presentError(sourceModule: CourseListInputProtocol) { - } - func presentPaidCourseInfo(course: Course) { self.moduleOutput?.presentPaidCourseInfo(course: course) } + + func presentEmptyState(sourceModule: CourseListInputProtocol) {} + + func presentError(sourceModule: CourseListInputProtocol) {} } diff --git a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Provider/CourseListsCollectionProvider.swift b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionProvider.swift similarity index 100% rename from Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Provider/CourseListsCollectionProvider.swift rename to Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionProvider.swift diff --git a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionViewController.swift b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionViewController.swift index 867030231e..7a3dae9e75 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionViewController.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/CourseListsCollectionViewController.swift @@ -28,6 +28,8 @@ final class CourseListsCollectionViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + self.view.backgroundColor = .stepikBackground + self.updateState(newState: self.state) self.interactor.doCourseListsFetch(request: CourseListsCollection.CourseListsLoad.Request()) } diff --git a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/CourseListsCollectionView.swift b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/CourseListsCollectionView.swift index 7bcbb1ab2f..95ce001a7a 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/CourseListsCollectionView.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/CourseListsCollectionView.swift @@ -11,7 +11,6 @@ final class CourseListsCollectionView: UIView { let view = ExploreBlockHeaderView( appearance: CourseListColorMode.light.exploreBlockHeaderViewAppearance ) - view.titleText = NSLocalizedString("RecommendationsExplore", comment: "") view.summaryText = NSLocalizedString("RecommendationsExploreDescription", comment: "") view.shouldShowAllButton = false @@ -85,7 +84,7 @@ final class CourseListsCollectionView: UIView { extension CourseListsCollectionView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .stepikBackground } func addSubviews() { diff --git a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/GradientCoursesPlaceholderView.swift b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/GradientCoursesPlaceholderView.swift index 6b13b19966..f098ae7a0c 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/GradientCoursesPlaceholderView.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/GradientCoursesPlaceholderView.swift @@ -13,7 +13,7 @@ extension GradientCoursesPlaceholderView { var labelsInsets = UIEdgeInsets(top: 20, left: 28, bottom: 20, right: 30) - init() { } + init() {} } } @@ -102,15 +102,15 @@ final class GradientCoursesPlaceholderView: UIView { var titleTextColor: UIColor { switch self { case .purple: - return UIColor.white + return .white case .blue: - return UIColor(hex6: 0x00484e) + return .stepikGradientCoursesBluePlaceholderText case .pink: - return UIColor(hex6: 0x18073d) + return .stepikGradientCoursesPinkPlaceholderText } } - var subtitleTextColor: UIColor { .stepikAccentAlpha30 } + var subtitleTextColor: UIColor { .stepikTertiaryText } } } diff --git a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/GradientCoursesPlaceholderViewFactory.swift b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/GradientCoursesPlaceholderViewFactory.swift index 464897824d..f4ea77a672 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/GradientCoursesPlaceholderViewFactory.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Views/GradientCoursesPlaceholderViewFactory.swift @@ -11,7 +11,7 @@ final class GradientCoursesPlaceholderViewFactory { static let defaultLabelsInsets = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) } - init() { } + init() {} func makeCourseCollectionView( title: String, diff --git a/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsDataFlow.swift b/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsDataFlow.swift index 3938fa2d80..37b873e1f8 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsDataFlow.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsDataFlow.swift @@ -14,7 +14,7 @@ enum Tags { /// Show tag list enum TagsLoad { - struct Request { } + struct Request {} struct Response { let result: StepikResult<[(UniqueIdentifierType, Tag)]> diff --git a/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsInteractor.swift b/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsInteractor.swift index 68307d3479..482ce79a60 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsInteractor.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsInteractor.swift @@ -45,8 +45,7 @@ final class TagsInteractor: TagsInteractorProtocol { } func doTagCollectionPresentation(request: Tags.TagCollectionPresentation.Request) { - guard let tag = self.currentTags - .first(where: { $0.0 == request.viewModelUniqueIdentifier })?.1 else { + guard let tag = self.currentTags.first(where: { $0.0 == request.viewModelUniqueIdentifier })?.1 else { return } diff --git a/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsView.swift b/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsView.swift index f27ec5d1ea..9818686013 100644 --- a/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsView.swift +++ b/Stepic/Sources/Modules/ExploreSubmodules/Tags/TagsView.swift @@ -7,13 +7,13 @@ protocol TagsViewDelegate: AnyObject { extension TagsView { struct Appearance { - let headerTitleColor = UIColor.stepikAccentAlpha30 + let headerTitleColor = UIColor.stepikTertiaryText let tagsHeight: CGFloat = 40 let tagsSpacing: CGFloat = 15 let tagsViewInsets = UIEdgeInsets(top: 20, left: 20, bottom: 27, right: 20) - let tagBackgroundColor = UIColor.stepikAccentAlpha06 + let tagBackgroundColor = UIColor.stepikLightSecondaryBackground let tagFont = UIFont.systemFont(ofSize: 16, weight: .light) let tagTextColor = UIColor.stepikPrimaryText let tagTitleInsets = UIEdgeInsets(top: 11, left: 20, bottom: 11, right: 20) @@ -109,7 +109,7 @@ final class TagsView: UIView { extension TagsView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .stepikBackground } func addSubviews() { diff --git a/Stepic/Sources/Modules/FullscreenCourseList/FullscreenCourseListDataFlow.swift b/Stepic/Sources/Modules/FullscreenCourseList/FullscreenCourseListDataFlow.swift index e9ddb17c6f..6295dbab36 100644 --- a/Stepic/Sources/Modules/FullscreenCourseList/FullscreenCourseListDataFlow.swift +++ b/Stepic/Sources/Modules/FullscreenCourseList/FullscreenCourseListDataFlow.swift @@ -59,9 +59,9 @@ enum FullscreenCourseList { } enum PresentAuthorization { - struct Response { } + struct Response {} - struct ViewModel { } + struct ViewModel {} } enum PresentPlaceholder { diff --git a/Stepic/Sources/Modules/FullscreenCourseList/FullscreenCourseListView.swift b/Stepic/Sources/Modules/FullscreenCourseList/FullscreenCourseListView.swift index bdc180e9bc..20bc52f1a5 100644 --- a/Stepic/Sources/Modules/FullscreenCourseList/FullscreenCourseListView.swift +++ b/Stepic/Sources/Modules/FullscreenCourseList/FullscreenCourseListView.swift @@ -6,7 +6,7 @@ final class FullscreenCourseListView: UIView { override init(frame: CGRect) { super.init(frame: frame) - self.backgroundColor = .white + self.backgroundColor = .stepikBackground } func attachContentView(_ view: UIView) { diff --git a/Stepic/Sources/Modules/Home/HomeDataFlow.swift b/Stepic/Sources/Modules/Home/HomeDataFlow.swift index 497606e7bd..885f6a0c54 100644 --- a/Stepic/Sources/Modules/Home/HomeDataFlow.swift +++ b/Stepic/Sources/Modules/Home/HomeDataFlow.swift @@ -16,7 +16,7 @@ enum Home { /// Content refresh (we should get language and authorization state) enum ContentLoad { - struct Request { } + struct Request {} struct Response { let isAuthorized: Bool @@ -31,7 +31,7 @@ enum Home { /// Show streak activity enum StreakLoad { - struct Request { } + struct Request {} struct Response { enum Result { @@ -59,7 +59,7 @@ enum Home { case error } - struct Request { } + struct Request {} struct Response { let module: Home.Submodule diff --git a/Stepic/Sources/Modules/Home/HomeViewController.swift b/Stepic/Sources/Modules/Home/HomeViewController.swift index f88d78a620..034a723b2f 100644 --- a/Stepic/Sources/Modules/Home/HomeViewController.swift +++ b/Stepic/Sources/Modules/Home/HomeViewController.swift @@ -330,6 +330,8 @@ final class HomeViewController: BaseExploreViewController { } } +// MARK: - HomeViewController: HomeViewControllerProtocol - + extension HomeViewController: HomeViewControllerProtocol { func displayModuleErrorState(viewModel: Home.CourseListStateUpdate.ViewModel) { switch viewModel.module { @@ -381,9 +383,7 @@ extension HomeViewController: HomeViewControllerProtocol { let shouldDisplayAnonymousPlaceholder = !viewModel.isAuthorized strongSelf.refreshContinueCourse(state: shouldDisplayContinueCourse ? .shown : .hidden) - strongSelf.refreshStateForEnrolledCourses( - state: shouldDisplayAnonymousPlaceholder ? .anonymous : .normal - ) + strongSelf.refreshStateForEnrolledCourses(state: shouldDisplayAnonymousPlaceholder ? .anonymous : .normal) strongSelf.refreshStateForPopularCourses(state: .normal) } } diff --git a/Stepic/Sources/Modules/Lesson/LessonViewController.swift b/Stepic/Sources/Modules/Lesson/LessonViewController.swift index 04431d94a2..60e249fe66 100644 --- a/Stepic/Sources/Modules/Lesson/LessonViewController.swift +++ b/Stepic/Sources/Modules/Lesson/LessonViewController.swift @@ -25,48 +25,28 @@ final class LessonViewController: TabmanViewController, ControllerWithStepikPlac enum Appearance { static let barTintColor = UIColor.stepikAccent + static let barBackgroundColor = UIColor.stepikNavigationBarBackground static let backgroundColor = UIColor.stepikBackground static let indicatorHeight: CGFloat = 2 - static let separatorColor = UIColor.gray + static let separatorColor = UIColor.stepikOpaqueSeparator static let loadingIndicatorColor = UIColor.stepikLoadingIndicator - static let tooltipBackgroundColor = UIColor.stepikAccent + static let tooltipBackgroundColor = UIColor.dynamic(light: .stepikAccent, dark: .stepikAlertBackground) static let tooltipHorizontalSpacing: CGFloat = 16 } private let interactor: LessonInteractorProtocol - private lazy var infoBarButtonItem: UIBarButtonItem = { - let image: UIImage? - if #available(iOS 13.0, *) { - image = UIImage(systemName: "info.circle") - } else { - image = UIImage(named: "info-system") - } - - let item = UIBarButtonItem( - image: image, - style: .plain, - target: self, - action: #selector(self.infoButtonClicked) - ) - item.isEnabled = false - - return item - }() - - private lazy var moreBarButtonItem: UIBarButtonItem = { - let item = UIBarButtonItem( - image: UIImage(named: "horizontal-dots-icon")?.withRenderingMode(.alwaysTemplate), - style: .plain, - target: self, - action: #selector(self.moreButtonClicked) - ) - item.isEnabled = false - return item - }() + private lazy var infoBarButtonItem = UIBarButtonItem.stepikInfoBarButtonItem( + target: self, + action: #selector(self.infoButtonClicked) + ) + private lazy var moreBarButtonItem = UIBarButtonItem.stepikMoreBarButtonItem( + target: self, + action: #selector(self.moreButtonClicked) + ) private lazy var loadingIndicator: UIActivityIndicatorView = { - let loadingIndicatorView = UIActivityIndicatorView(style: .whiteLarge) + let loadingIndicatorView = UIActivityIndicatorView(style: .stepikWhiteLarge) loadingIndicatorView.color = Appearance.loadingIndicatorColor loadingIndicatorView.hidesWhenStopped = true loadingIndicatorView.startAnimating() @@ -76,7 +56,7 @@ final class LessonViewController: TabmanViewController, ControllerWithStepikPlac // Cause Tabman doesn't support controllers removing private lazy var overlayView: UIView = { let view = UIView() - view.backgroundColor = .white + view.backgroundColor = Appearance.backgroundColor return view }() @@ -94,7 +74,7 @@ final class LessonViewController: TabmanViewController, ControllerWithStepikPlac let bar = TMBarView() bar.layout.transitionStyle = .snap bar.tintColor = Appearance.barTintColor - bar.backgroundView.style = .flat(color: Appearance.backgroundColor) + bar.backgroundView.style = .flat(color: Appearance.barBackgroundColor) bar.indicator.tintColor = Appearance.barTintColor bar.indicator.weight = .custom(value: 2) bar.layout.interButtonSpacing = 0 @@ -146,9 +126,10 @@ final class LessonViewController: TabmanViewController, ControllerWithStepikPlac for: .connectionError ) - self.view.backgroundColor = .white + self.view.backgroundColor = Appearance.backgroundColor self.navigationItem.rightBarButtonItems = [self.moreBarButtonItem, self.infoBarButtonItem] + self.navigationItem.rightBarButtonItems?.forEach { $0.isEnabled = false } if let styledNavigationController = self.navigationController as? StyledNavigationController { styledNavigationController.removeBackButtonTitleForTopController() diff --git a/Stepic/Sources/Modules/ProfileEdit/ProfileEditDataFlow.swift b/Stepic/Sources/Modules/ProfileEdit/ProfileEditDataFlow.swift index 1f2cb15bab..595ff95fef 100644 --- a/Stepic/Sources/Modules/ProfileEdit/ProfileEditDataFlow.swift +++ b/Stepic/Sources/Modules/ProfileEdit/ProfileEditDataFlow.swift @@ -3,7 +3,7 @@ import Foundation enum ProfileEdit { /// Present form for edit enum ProfileEditLoad { - struct Request { } + struct Request {} struct Response { let profile: Profile diff --git a/Stepic/Sources/Modules/ProfileEdit/ProfileEditView.swift b/Stepic/Sources/Modules/ProfileEdit/ProfileEditView.swift index 1611dced32..11f8408f6e 100644 --- a/Stepic/Sources/Modules/ProfileEdit/ProfileEditView.swift +++ b/Stepic/Sources/Modules/ProfileEdit/ProfileEditView.swift @@ -1,10 +1,10 @@ import SnapKit import UIKit -protocol ProfileEditViewDelegate: SettingsTableViewDelegate { } +protocol ProfileEditViewDelegate: SettingsTableViewDelegate {} extension ProfileEditView { - struct Appearance { } + struct Appearance {} } final class ProfileEditView: UIView { @@ -15,7 +15,7 @@ final class ProfileEditView: UIView { } } - private lazy var tableView = SettingsTableView(appearance: .init(style: .insetGroupedFallbackGrouped)) + private lazy var tableView = SettingsTableView(appearance: .init(style: .stepikInsetGrouped)) init( frame: CGRect = .zero, diff --git a/Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizDataFlow.swift b/Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizDataFlow.swift index 0eb581b21d..2d31bd36bb 100644 --- a/Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizDataFlow.swift +++ b/Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizDataFlow.swift @@ -40,9 +40,9 @@ enum BaseQuiz { /// Present rate app alert enum RateAppAlertPresentation { - struct Response { } + struct Response {} - struct ViewModel { } + struct ViewModel {} } /// Present streak alert @@ -58,7 +58,7 @@ enum BaseQuiz { /// Navigate to next step inside lesson enum NextStepNavigation { - struct Request { } + struct Request {} } enum ViewControllerState { diff --git a/Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizView.swift b/Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizView.swift index 79ad82b172..cbfc3afbb2 100644 --- a/Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizView.swift +++ b/Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizView.swift @@ -11,10 +11,12 @@ protocol BaseQuizViewDelegate: AnyObject { extension BaseQuizView { struct Appearance { - let submitButtonBackgroundColor = UIColor.stepikGreen + let submitButtonBackgroundColor = UIColor.dynamic(light: .stepikGreen, dark: .stepikBackground) let submitButtonHeight: CGFloat = 44 - let submitButtonTextColor = UIColor.white + let submitButtonTextColor = UIColor.dynamic(light: .white, dark: .stepikGreen) let submitButtonCornerRadius: CGFloat = 6 + let submitButtonBorderWidth: CGFloat = 1 + let submitButtonBorderColor = UIColor.dynamic(light: .clear, dark: .stepikGreen) let submitButtonFont = UIFont.systemFont(ofSize: 16) let retryButtonSize = CGSize(width: 44, height: 44) @@ -22,10 +24,10 @@ extension BaseQuizView { let retryButtonIconInsets = UIEdgeInsets(top: 0, left: 11, bottom: 0, right: 0) let retryButtonBorderWidth: CGFloat = 1 let retryButtonCornerRadius: CGFloat = 6 - let retryButtonBackgroundColor = UIColor.white - let retryButtonTintColor = UIColor(hex6: 0xC8C7CC) + let retryButtonBackgroundColor = UIColor.stepikBackground + let retryButtonTintColor = UIColor.dynamic(light: .stepikSeparator, dark: .stepikOpaqueSeparator) - let discountingPolicyTextColor = UIColor.stepikAccent + let discountingPolicyTextColor = UIColor.stepikPrimaryText let discountingPolicyFont = UIFont.systemFont(ofSize: 12, weight: .medium) let spacing: CGFloat = 16 @@ -33,8 +35,8 @@ extension BaseQuizView { let insets = LayoutInsets(left: 16, right: 16) let loadingIndicatorColor = UIColor.stepikLoadingIndicator - let separatorColor = UIColor(hex6: 0xEAECF0) - let separatorHeight: CGFloat = 1 + let separatorColor = UIColor.stepikSeparator + let separatorHeight: CGFloat = 0.5 } enum Animation { @@ -48,7 +50,7 @@ final class BaseQuizView: UIView { weak var delegate: BaseQuizViewDelegate? private lazy var loadingIndicatorView: UIActivityIndicatorView = { - let loadingIndicatorView = UIActivityIndicatorView(style: .white) + let loadingIndicatorView = UIActivityIndicatorView(style: .stepikWhite) loadingIndicatorView.color = self.appearance.loadingIndicatorColor loadingIndicatorView.hidesWhenStopped = true loadingIndicatorView.startAnimating() @@ -74,6 +76,7 @@ final class BaseQuizView: UIView { submitButton.setTitleColor(self.appearance.submitButtonTextColor, for: .normal) submitButton.titleLabel?.font = self.appearance.submitButtonFont submitButton.layer.cornerRadius = self.appearance.submitButtonCornerRadius + submitButton.layer.borderWidth = self.appearance.submitButtonBorderWidth submitButton.clipsToBounds = true submitButton.backgroundColor = self.appearance.submitButtonBackgroundColor submitButton.addTarget(self, action: #selector(self.submitClicked), for: .touchUpInside) @@ -195,6 +198,11 @@ final class BaseQuizView: UIView { fatalError("init(coder:) has not been implemented") } + override func layoutSubviews() { + super.layoutSubviews() + self.updateAppearance() + } + func addQuiz(view: UIView) { guard let discountingPolicyLabelIndex = self.stackView.arrangedSubviews.firstIndex( where: { $0 === self.discountingPolicyContainerView } @@ -235,6 +243,11 @@ final class BaseQuizView: UIView { // MARK: - Private API + private func updateAppearance() { + self.submitButton.layer.borderColor = self.appearance.submitButtonBorderColor.cgColor + self.retryButton.layer.borderColor = self.appearance.retryButtonTintColor.cgColor + } + private func updateRetryButton() { // Hide retry button for last step in lesson. if !self.isNextStepAvailable && self.isRetryAvailable { diff --git a/Stepic/Sources/Modules/Quizzes/BaseQuiz/ChildProtocols/QuizInputProtocol.swift b/Stepic/Sources/Modules/Quizzes/BaseQuiz/ChildProtocols/QuizInputProtocol.swift index 5d8a502de5..afca4cf164 100644 --- a/Stepic/Sources/Modules/Quizzes/BaseQuiz/ChildProtocols/QuizInputProtocol.swift +++ b/Stepic/Sources/Modules/Quizzes/BaseQuiz/ChildProtocols/QuizInputProtocol.swift @@ -10,10 +10,10 @@ protocol QuizInputProtocol: AnyObject { } extension QuizInputProtocol { - func update(reply: Reply?) { } - func update(status: QuizStatus?) { } - func update(dataset: Dataset?) { } - func update(feedback: SubmissionFeedback?) { } - func update(codeDetails: CodeDetails?) { } - func update(quizTitleVisibility isVisible: Bool) { } + func update(reply: Reply?) {} + func update(status: QuizStatus?) {} + func update(dataset: Dataset?) {} + func update(feedback: SubmissionFeedback?) {} + func update(codeDetails: CodeDetails?) {} + func update(quizTitleVisibility isVisible: Bool) {} } diff --git a/Stepic/Sources/Modules/Quizzes/BaseQuiz/Views/QuizFeedbackView.swift b/Stepic/Sources/Modules/Quizzes/BaseQuiz/Views/QuizFeedbackView.swift index a24194e1dc..3e704aedef 100644 --- a/Stepic/Sources/Modules/Quizzes/BaseQuiz/Views/QuizFeedbackView.swift +++ b/Stepic/Sources/Modules/Quizzes/BaseQuiz/Views/QuizFeedbackView.swift @@ -14,7 +14,7 @@ extension QuizFeedbackView { let titleInsets = LayoutInsets(top: 15, left: 56, bottom: 15, right: 16) let leftViewInsets = LayoutInsets(left: 16, right: 16) - let feedbackBackgroundColor = UIColor(hex6: 0xF6F6F6) + let feedbackBackgroundColor = UIColor.stepikLightSecondaryBackground let feedbackContentInsets = LayoutInsets(top: 16, left: 16, bottom: 16, right: 16) } } @@ -160,22 +160,22 @@ final class QuizFeedbackView: UIView { var mainColor: UIColor { switch self { case .correct: - return UIColor(hex6: 0xE9F9E9) + return .quizElementCorrectBackground case .wrong: - return UIColor(hex6: 0xFF7965).withAlphaComponent(0.15) + return .quizElementWrongBackground default: - return UIColor(hex6: 0xE9EBFA) + return .quizElementEvaluationBackground } } var titleColor: UIColor { switch self { case .correct: - return UIColor(hex6: 0x66CC66) + return .stepikCallToActionText case .wrong: - return UIColor(hex6: 0xFF7965) + return .stepikLightRedFixed default: - return UIColor(hex6: 0x6C7BDF) + return .dynamic(light: .stepikVioletFixed, dark: .stepikExtraLightVioletFixed) } } @@ -196,7 +196,7 @@ final class QuizFeedbackView: UIView { view.tintColor = self.titleColor return view case .evaluation: - let indicatorView = UIActivityIndicatorView(style: .white) + let indicatorView = UIActivityIndicatorView(style: .stepikWhite) indicatorView.startAnimating() indicatorView.color = self.titleColor return indicatorView diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/CodeQuizView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/CodeQuizView.swift index adcfa68038..f724cbdfec 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/CodeQuizView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/CodeQuizView.swift @@ -10,7 +10,7 @@ protocol CodeQuizViewDelegate: AnyObject { extension CodeQuizView { struct Appearance { - let titleColor = UIColor.stepikAccent + let titleColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 12, weight: .medium) let insets = LayoutInsets(top: 16, left: 16, bottom: 16, right: 16) diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsButton.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsButton.swift index 420b40aee0..98c2a01c10 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsButton.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsButton.swift @@ -8,9 +8,9 @@ extension CodeDetailsButton { let insets = LayoutInsets(left: 16, right: 16) let horizontalSpacing: CGFloat = 16 - let mainColor = UIColor.stepikAccent + let mainColor = UIColor.stepikPrimaryText let textFont = UIFont.systemFont(ofSize: 16) - let backgroundColor = UIColor(hex6: 0xF6F6F6) + let backgroundColor = UIColor.stepikLightSecondaryBackground } enum Animation { diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsLimitItemView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsLimitItemView.swift index 6bf1abdc8d..85e9a9a89c 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsLimitItemView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsLimitItemView.swift @@ -6,7 +6,7 @@ extension CodeDetailsLimitItemView { let insets = LayoutInsets(top: 16, left: 16, bottom: 16, right: 16) let verticalSpacing: CGFloat = 16 - let backgroundColor = UIColor(hex6: 0xF6F6F6) + let backgroundColor = UIColor.stepikLightSecondaryBackground let mainColor = UIColor.stepikAccent let titleFont = UIFont.systemFont(ofSize: 16) let detailFont = UIFont.systemFont(ofSize: 14, weight: .light) diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsSampleItemView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsSampleItemView.swift index 29a0bea1aa..e5e2541b9f 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsSampleItemView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsSampleItemView.swift @@ -8,7 +8,7 @@ extension CodeDetailsSampleItemView { let horizontalSpacing: CGFloat = 16 let iconSize = CGSize(width: 16, height: 16) - let backgroundColor = UIColor(hex6: 0xF6F6F6) + let backgroundColor = UIColor.stepikLightSecondaryBackground let mainColor = UIColor.stepikAccent let titleFont = UIFont.systemFont(ofSize: 16) diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsView.swift index 861d4b5be1..f1b902d427 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeDetails/CodeDetailsView.swift @@ -4,7 +4,7 @@ import UIKit extension CodeDetailsView { struct Appearance { let spacing: CGFloat = 1 - let backgroundColor = UIColor.white + let backgroundColor = UIColor.stepikBackground let detailsButtonHeight: CGFloat = 44 } diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeEditorView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeEditorView.swift index 1963220247..311b8628ab 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeEditorView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeEditorView.swift @@ -29,7 +29,7 @@ extension CodeEditorView { struct Appearance { var languageNameLabelLayoutInsets = LayoutInsets(top: 8, right: 16) let languageNameLabelTextColor = UIColor.stepikAccent - let languageNameLabelBackgroundColor = UIColor(hex6: 0xF6F6F6).withAlphaComponent(0.75) + let languageNameLabelBackgroundColor = UIColor.stepikLightSecondaryBackground.withAlphaComponent(0.75) let languageNameLabelFont = UIFont.systemFont(ofSize: 10) let languageNameLabelInsets = UIEdgeInsets(top: 4, left: 8, bottom: 4, right: 8) let languageNameLabelCornerRadius: CGFloat = 10 diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeTextView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeTextView.swift index 879e81cc76..302656d8fa 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeTextView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeTextView.swift @@ -4,12 +4,12 @@ import UIKit extension CodeTextView { struct Appearance { let gutterWidth: CGFloat = 24 - var gutterBackgroundColor = UIColor(hex6: 0xF6F6F6) - var gutterBorderColor = UIColor(hex6: 0xC8C7CC) + var gutterBackgroundColor = UIColor.stepikLightSecondaryBackground + var gutterBorderColor = UIColor.stepikOpaqueSeparator let gutterBorderWidth: CGFloat = 0.5 let lineNumberFont = UIFont.monospacedDigitSystemFont(ofSize: 10, weight: .regular) - let lineNumberTextColor = UIColor.stepikAccentAlpha50 + let lineNumberTextColor = UIColor.stepikSecondaryText let lineSpacing: CGFloat = 1.2 } } diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeTextViewLayoutManager.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeTextViewLayoutManager.swift index 813cdeff9b..d560bf645a 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeTextViewLayoutManager.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/CodeEditor/CodeTextViewLayoutManager.swift @@ -6,10 +6,10 @@ extension CodeTextViewLayoutManager { var gutterWidth: CGFloat = 24.0 var lineNumberFont = UIFont.monospacedDigitSystemFont(ofSize: 10, weight: .regular) - var lineNumberTextColor = UIColor.stepikAccentAlpha50 + var lineNumberTextColor = UIColor.stepikSecondaryText let lineNumberInsets = LayoutInsets(right: 4) - var currentLineNumberTextColor = UIColor.stepikAccent + var currentLineNumberTextColor = UIColor.stepikPrimaryText var currentLineColor = UIColor.stepikAccentAlpha25 var currentLineWidth: CGFloat = 24.0 } diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/LanguagePicker/CodeLanguagePickerView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/LanguagePicker/CodeLanguagePickerView.swift index 819a0765c7..8709b10eda 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/LanguagePicker/CodeLanguagePickerView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/LanguagePicker/CodeLanguagePickerView.swift @@ -19,7 +19,7 @@ extension CodeLanguagePickerView { let mainColor = UIColor.stepikAccent let titleTextFont = UIFont.systemFont(ofSize: 16) let emptyTextFont = UIFont.systemFont(ofSize: 16) - let emptyTextColor = UIColor.lightGray + let emptyTextColor = UIColor.stepikSecondaryText } } diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/UnsupportedCodeLanguageView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/UnsupportedCodeLanguageView.swift index 63aca5c458..deb2850b70 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/UnsupportedCodeLanguageView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuiz/Views/UnsupportedCodeLanguageView.swift @@ -5,7 +5,7 @@ extension UnsupportedCodeLanguageView { struct Appearance { let height: CGFloat = 236 let textFont = UIFont.systemFont(ofSize: 16) - let textColor = UIColor.lightGray + let textColor = UIColor.stepikSecondaryText } } diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/CodeQuizFullscreenViewController.swift b/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/CodeQuizFullscreenViewController.swift index b28034659c..c1dc279ee9 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/CodeQuizFullscreenViewController.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/CodeQuizFullscreenViewController.swift @@ -11,12 +11,14 @@ protocol CodeQuizFullscreenViewControllerProtocol: AnyObject { extension CodeQuizFullscreenViewController { enum Appearance { + static let backgroundColor = UIColor.stepikBackground + static let barTintColor = UIColor.stepikAccent - static let barBackgroundColor = UIColor.stepikBackground - static let barSeparatorColor = UIColor.gray + static let barBackgroundColor = UIColor.stepikNavigationBarBackground + static let barSeparatorColor = UIColor.stepikOpaqueSeparator static let barButtonTitleFontNormal = UIFont.systemFont(ofSize: 15, weight: .light) static let barButtonTitleFontSelected = UIFont.systemFont(ofSize: 15) - static let barButtonTitleColor = UIColor.stepikAccent + static let barButtonTitleColor = UIColor.stepikPrimaryText static let spacingBetweenPages: CGFloat = 16.0 @@ -70,9 +72,7 @@ final class CodeQuizFullscreenViewController: TabmanViewController { return bar }() - private lazy var moreBarButton = UIBarButtonItem( - image: UIImage(named: "horizontal-dots-icon")?.withRenderingMode(.alwaysTemplate), - style: .plain, + private lazy var moreBarButton = UIBarButtonItem.stepikMoreBarButtonItem( target: self, action: #selector(self.actionButtonClicked) ) @@ -121,6 +121,7 @@ final class CodeQuizFullscreenViewController: TabmanViewController { override func viewDidLoad() { super.viewDidLoad() + self.view.backgroundColor = Appearance.backgroundColor self.navigationItem.rightBarButtonItem = self.moreBarButton self.dataSource = self diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenCodeViewController.swift b/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenCodeViewController.swift index 30ea5e92c9..4074ba81fb 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenCodeViewController.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenCodeViewController.swift @@ -18,7 +18,7 @@ protocol CodeQuizFullscreenCodeViewControllerDelegate: AnyObject { extension CodeQuizFullscreenCodeViewController { enum Appearance { - static let submitButtonBackgroundColor = UIColor.stepikGreen + static let submitButtonBackgroundColor = UIColor.dynamic(light: .stepikGreen, dark: .stepikDarkGreenFixed) static let submitButtonHeight: CGFloat = 44 static let submitButtonTextColor = UIColor.white static let submitButtonCornerRadius: CGFloat = 6 diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenInstruction/CodeQuizFullscreenInstructionView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenInstruction/CodeQuizFullscreenInstructionView.swift index 8e45ae22ca..4be68bd22f 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenInstruction/CodeQuizFullscreenInstructionView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenInstruction/CodeQuizFullscreenInstructionView.swift @@ -27,7 +27,7 @@ final class CodeQuizFullscreenInstructionView: UIView { weak var delegate: CodeQuizFullscreenInstructionViewDelegate? private lazy var loadingIndicatorView: UIActivityIndicatorView = { - let loadingIndicatorView = UIActivityIndicatorView(style: .whiteLarge) + let loadingIndicatorView = UIActivityIndicatorView(style: .stepikWhiteLarge) loadingIndicatorView.color = self.appearance.loadingIndicatorColor loadingIndicatorView.hidesWhenStopped = true loadingIndicatorView.startAnimating() diff --git a/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenRunCode/CodeQuizFullscreenRunCodeView.swift b/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenRunCode/CodeQuizFullscreenRunCodeView.swift index f4670e3e4a..2743dd96c1 100644 --- a/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenRunCode/CodeQuizFullscreenRunCodeView.swift +++ b/Stepic/Sources/Modules/Quizzes/CodeQuizFullscreen/Tabs/CodeQuizFullscreenRunCode/CodeQuizFullscreenRunCodeView.swift @@ -10,12 +10,12 @@ protocol CodeQuizFullscreenRunCodeViewDelegate: AnyObject { extension CodeQuizFullscreenRunCodeView { struct Appearance { let samplesButtonFont = UIFont.preferredFont(forTextStyle: .subheadline) - let samplesButtonTintColor = UIColor.stepikAccent + let samplesButtonTintColor = UIColor.stepikPrimaryText let samplesButtonImageSize = CGSize(width: 15, height: 15) let samplesButtonImageInsets = UIEdgeInsets(top: 2, left: 4, bottom: 0, right: 0) let samplesButtonInsets = UIEdgeInsets(top: 16, left: 0, bottom: 0, right: 16) - let runCodeButtonBackgroundColor = UIColor(hex6: 0x6C7BDF) + let runCodeButtonBackgroundColor = UIColor.dynamic(light: .stepikVioletFixed, dark: .stepikDarkVioletFixed) let runCodeButtonHeight: CGFloat = 44 let runCodeButtonTextColor = UIColor.white let runCodeButtonCornerRadius: CGFloat = 6 @@ -24,7 +24,7 @@ extension CodeQuizFullscreenRunCodeView { let bottomControlsStackViewSpacing: CGFloat = 16 let bottomControlsStackViewInsets = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) - let testInputOutputPrimaryTextColor = UIColor.stepikAccent + let testInputOutputPrimaryTextColor = UIColor.stepikPrimaryText let testInputPlaceholderTextColor = UIColor.stepikPlaceholderText let testInputOutputTitleFont = UIFont.preferredFont(forTextStyle: .headline) @@ -40,9 +40,9 @@ extension CodeQuizFullscreenRunCodeView { let testInputOutputTitleImageSize = CGSize(width: 20, height: 20) let testInputOutputTitleImageInsets = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 0) - let cardBackgroundColor = UIColor(hex6: 0xF6F6F6) + let cardBackgroundColor = UIColor.stepikLightSecondaryBackground let cardCornerRadius: CGFloat = 6 - let backgroundColor = UIColor.white + let backgroundColor = UIColor.stepikBackground let testInputTitle = NSLocalizedString("CodeQuizFullscreenTabRunInputDataTitle", comment: "") let testOutputTitle = NSLocalizedString("CodeQuizFullscreenTabRunOutputDataTitle", comment: "") @@ -225,11 +225,15 @@ final class CodeQuizFullscreenRunCodeView: UIView { if userCodeRunStatus == .failure { return ( UIImage(named: "quiz-mark-wrong"), - UIColor(hex6: 0xFF7965), - UIColor(hex6: 0xFF7965).withAlphaComponent(0.15) + UIColor.stepikLightRedFixed, + UIColor.quizElementWrongBackground ) } else if userCodeRunStatus == .success && isTestOutputMatchesSampleOutput { - return (UIImage(named: "quiz-feedback-correct"), UIColor(hex6: 0x66CC66), UIColor(hex6: 0xE9F9E9)) + return ( + UIImage(named: "quiz-feedback-correct"), + UIColor.stepikCallToActionText, + UIColor.quizElementCorrectBackground + ) } else { return ( UIImage(named: "console"), diff --git a/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/NewChoiceQuizViewController.swift b/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/NewChoiceQuizViewController.swift index 3d0db480e5..324c1e0a79 100644 --- a/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/NewChoiceQuizViewController.swift +++ b/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/NewChoiceQuizViewController.swift @@ -36,7 +36,7 @@ final class NewChoiceQuizViewController: UIViewController { extension NewChoiceQuizViewController: NewChoiceQuizViewControllerProtocol { func displayReply(viewModel: NewChoiceQuiz.ReplyLoad.ViewModel) { - if self.lastChoiceDataset != viewModel.data.choices.map { $0.text } { + if self.lastChoiceDataset != viewModel.data.choices.map({ $0.text }) { self.lastChoiceDataset = viewModel.data.choices.map { $0.text } self.newChoiceQuizView?.set( choices: viewModel.data.choices.map { (text: $0.text, isSelected: $0.isSelected) } @@ -46,7 +46,7 @@ extension NewChoiceQuizViewController: NewChoiceQuizViewControllerProtocol { self.newChoiceQuizView?.title = viewModel.data.title self.newChoiceQuizView?.isSingleChoice = !viewModel.data.isMultipleChoice - if self.lastFeedback != viewModel.data.choices.map { $0.hint } { + if self.lastFeedback != viewModel.data.choices.map({ $0.hint }) { self.lastFeedback = viewModel.data.choices.map { $0.hint } self.newChoiceQuizView?.updateFeedback(text: viewModel.data.choices.map { $0.hint }) } diff --git a/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/Views/ChoiceElementView.swift b/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/Views/ChoiceElementView.swift index b9d1b4c06e..ad7ea324fe 100644 --- a/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/Views/ChoiceElementView.swift +++ b/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/Views/ChoiceElementView.swift @@ -5,11 +5,11 @@ extension ChoiceElementView { struct Appearance { let contentInsets = LayoutInsets(top: 12, left: 16, bottom: 12, right: 16) - let shadowColor = UIColor(hex6: 0xEAECF0) + let shadowColor = UIColor.stepikShadowFixed let shadowOffset = CGSize(width: 0, height: 1) let shadowRadius: CGFloat = 4 - let feedbackBackgroundColor = UIColor(hex6: 0xF6F6F6) + let feedbackBackgroundColor = UIColor.stepikLightSecondaryBackground let feedbackContentInsets = LayoutInsets(top: 16, left: 16, bottom: 16, right: 16) } } @@ -132,8 +132,24 @@ final class ChoiceElementView: UIView { } } + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + self.performBlockIfAppearanceChanged(from: previousTraitCollection) { + self.updateShadowVisibility() + } + } + // MARK: - Private API + private func updateShadowVisibility() { + if self.isDarkInterfaceStyle { + self.shadowView.isHidden = true + } else { + self.shadowView.isHidden = !self.isEnabled + } + } + private func updateCornersForFeedback() { let path = UIBezierPath( roundedRect: self.feedbackContainerView.bounds, @@ -160,7 +176,7 @@ final class ChoiceElementView: UIView { self.quizElementView.state = .selected } - self.shadowView.isHidden = !self.isEnabled + self.updateShadowVisibility() } // MARK: - Enums diff --git a/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/Views/NewChoiceQuizView.swift b/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/Views/NewChoiceQuizView.swift index 45d03edde4..1de28dd28d 100644 --- a/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/Views/NewChoiceQuizView.swift +++ b/Stepic/Sources/Modules/Quizzes/NewChoiceQuiz/Views/NewChoiceQuizView.swift @@ -10,7 +10,7 @@ extension NewChoiceQuizView { let spacing: CGFloat = 16 let insets = LayoutInsets(left: 16, right: 16) - let titleColor = UIColor.stepikAccent + let titleColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 12, weight: .medium) let loadingIndicatorColor = UIColor.stepikLoadingIndicator @@ -27,7 +27,7 @@ final class NewChoiceQuizView: UIView { weak var delegate: NewChoiceQuizViewDelegate? private lazy var loadingIndicatorView: UIActivityIndicatorView = { - let loadingIndicatorView = UIActivityIndicatorView(style: .white) + let loadingIndicatorView = UIActivityIndicatorView(style: .stepikWhite) loadingIndicatorView.color = self.appearance.loadingIndicatorColor loadingIndicatorView.hidesWhenStopped = true loadingIndicatorView.startAnimating() diff --git a/Stepic/Sources/Modules/Quizzes/NewFreeAnswerQuiz/NewFreeAnswerQuizView.swift b/Stepic/Sources/Modules/Quizzes/NewFreeAnswerQuiz/NewFreeAnswerQuizView.swift index 4f98de5f27..9eab940e70 100644 --- a/Stepic/Sources/Modules/Quizzes/NewFreeAnswerQuiz/NewFreeAnswerQuizView.swift +++ b/Stepic/Sources/Modules/Quizzes/NewFreeAnswerQuiz/NewFreeAnswerQuizView.swift @@ -10,16 +10,16 @@ extension NewFreeAnswerQuizView { let spacing: CGFloat = 16 let insets = LayoutInsets(left: 16, right: 16) - let titleColor = UIColor.stepikAccent + let titleColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 12, weight: .medium) let textFieldPlaceholderFont = UIFont.systemFont(ofSize: 16) let textFieldPlaceholderColor = UIColor.stepikPlaceholderText - let textFieldTextColor = UIColor.stepikAccent + let textFieldTextColor = UIColor.stepikPrimaryText let textFieldBorderCornerRadius: CGFloat = 6 let textFieldBorderWidth: CGFloat = 1 - let textFieldBorderColor = UIColor(hex6: 0xCCCCCC) + let textFieldBorderColor = UIColor.stepikSeparator let textFieldInsets = UIEdgeInsets(top: 12, left: 12, bottom: 36, right: 12) } diff --git a/Stepic/Sources/Modules/Quizzes/NewMatchingQuiz/Views/NewMatchingQuizTitleView.swift b/Stepic/Sources/Modules/Quizzes/NewMatchingQuiz/Views/NewMatchingQuizTitleView.swift index 75644930c0..bcef0e51fa 100644 --- a/Stepic/Sources/Modules/Quizzes/NewMatchingQuiz/Views/NewMatchingQuizTitleView.swift +++ b/Stepic/Sources/Modules/Quizzes/NewMatchingQuiz/Views/NewMatchingQuizTitleView.swift @@ -12,7 +12,7 @@ extension NewMatchingQuizTitleView { var containerInsets = LayoutInsets(top: 12, left: 16, bottom: 10, right: 64) let contentInsets = LayoutInsets(top: 12, left: 16, bottom: 12, right: 16) - let shadowColor = UIColor(hex6: 0xEAECF0) + let shadowColor = UIColor.stepikShadowFixed let shadowOffset = CGSize(width: 0, height: 1) let shadowRadius: CGFloat = 4 } @@ -55,7 +55,7 @@ final class NewMatchingQuizTitleView: UIView { var isShadowVisible: Bool = true { didSet { - self.shadowView.isHidden = !self.isShadowVisible + self.updateShadowVisibility() } } @@ -95,6 +95,22 @@ final class NewMatchingQuizTitleView: UIView { ).cgPath } } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + self.performBlockIfAppearanceChanged(from: previousTraitCollection) { + self.updateShadowVisibility() + } + } + + private func updateShadowVisibility() { + if self.isDarkInterfaceStyle { + self.shadowView.isHidden = true + } else { + self.shadowView.isHidden = !self.isShadowVisible + } + } } extension NewMatchingQuizTitleView: ProgrammaticallyInitializableViewProtocol { diff --git a/Stepic/Sources/Modules/Quizzes/NewMatchingQuiz/Views/NewMatchingQuizView.swift b/Stepic/Sources/Modules/Quizzes/NewMatchingQuiz/Views/NewMatchingQuizView.swift index 41e4379f24..f81eae8563 100644 --- a/Stepic/Sources/Modules/Quizzes/NewMatchingQuiz/Views/NewMatchingQuizView.swift +++ b/Stepic/Sources/Modules/Quizzes/NewMatchingQuiz/Views/NewMatchingQuizView.swift @@ -24,7 +24,7 @@ extension NewMatchingQuizView { let defaultSortingTitleInsets = LayoutInsets(top: 12, left: 16, bottom: 10, right: 64) let firstSortingTitleInsets = LayoutInsets(top: 0, left: 16, bottom: 10, right: 64) - let titleColor = UIColor.stepikAccent + let titleColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 12, weight: .medium) let loadingIndicatorColor = UIColor.stepikLoadingIndicator @@ -43,7 +43,7 @@ final class NewMatchingQuizView: UIView { weak var delegate: NewMatchingQuizViewDelegate? private lazy var loadingIndicatorView: UIActivityIndicatorView = { - let loadingIndicatorView = UIActivityIndicatorView(style: .white) + let loadingIndicatorView = UIActivityIndicatorView(style: .stepikWhite) loadingIndicatorView.color = self.appearance.loadingIndicatorColor loadingIndicatorView.hidesWhenStopped = true loadingIndicatorView.startAnimating() diff --git a/Stepic/Sources/Modules/Quizzes/NewSortingQuiz/Views/NewSortingQuizElementView.swift b/Stepic/Sources/Modules/Quizzes/NewSortingQuiz/Views/NewSortingQuizElementView.swift index a26494b2a4..91cf040fe5 100644 --- a/Stepic/Sources/Modules/Quizzes/NewSortingQuiz/Views/NewSortingQuizElementView.swift +++ b/Stepic/Sources/Modules/Quizzes/NewSortingQuiz/Views/NewSortingQuizElementView.swift @@ -17,14 +17,14 @@ extension NewSortingQuizElementView { var containerInsets = LayoutInsets(top: 12, left: 16, bottom: 12, right: 16) let contentInsets = LayoutInsets(top: 12, left: 16, bottom: 12, right: 16) - let shadowColor = UIColor(hex6: 0xEAECF0) + let shadowColor = UIColor.stepikShadowFixed let shadowOffset = CGSize(width: 0, height: 1) let shadowRadius: CGFloat = 4 let navigationButtonSize = CGSize(width: 24, height: 24) let navigationButtonImageSize = CGSize(width: 20, height: 20) - let navigationButtonTintColorActive = UIColor.stepikAccent - let navigationButtonTintColorInactive = UIColor(hex6: 0xCCCCCC) + let navigationButtonTintColorActive = UIColor.stepikPrimaryText + let navigationButtonTintColorInactive = UIColor.stepikSeparator let navigationButtonVerticalSpacing: CGFloat = 16 let navigationButtonHorizontalSpacing: CGFloat = 8 } @@ -121,7 +121,7 @@ final class NewSortingQuizElementView: UIView { var isShadowVisible: Bool = true { didSet { - self.shadowView.isHidden = !self.isShadowVisible + self.updateShadowVisibility() } } @@ -155,6 +155,14 @@ final class NewSortingQuizElementView: UIView { } } + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + self.performBlockIfAppearanceChanged(from: previousTraitCollection) { + self.updateShadowVisibility() + } + } + // MARK: - Public API func configure(viewModel: ViewModel) { @@ -180,6 +188,14 @@ final class NewSortingQuizElementView: UIView { // MARK: - Private API + private func updateShadowVisibility() { + if self.isDarkInterfaceStyle { + self.shadowView.isHidden = true + } else { + self.shadowView.isHidden = !self.isShadowVisible + } + } + @objc private func topNavigationButtonClicked() { self.delegate?.newSortingQuizElementViewDidRequestMoveTop(self) diff --git a/Stepic/Sources/Modules/Quizzes/NewSortingQuiz/Views/NewSortingQuizView.swift b/Stepic/Sources/Modules/Quizzes/NewSortingQuiz/Views/NewSortingQuizView.swift index aa56e18427..0c9b3546c8 100644 --- a/Stepic/Sources/Modules/Quizzes/NewSortingQuiz/Views/NewSortingQuizView.swift +++ b/Stepic/Sources/Modules/Quizzes/NewSortingQuiz/Views/NewSortingQuizView.swift @@ -18,7 +18,7 @@ extension NewSortingQuizView { let spacing: CGFloat = 16 let insets = LayoutInsets(left: 16, right: 16) - let titleColor = UIColor.stepikAccent + let titleColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 12, weight: .medium) let loadingIndicatorColor = UIColor.stepikLoadingIndicator @@ -37,7 +37,7 @@ final class NewSortingQuizView: UIView { weak var delegate: NewSortingQuizViewDelegate? private lazy var loadingIndicatorView: UIActivityIndicatorView = { - let loadingIndicatorView = UIActivityIndicatorView(style: .white) + let loadingIndicatorView = UIActivityIndicatorView(style: .stepikWhite) loadingIndicatorView.color = self.appearance.loadingIndicatorColor loadingIndicatorView.hidesWhenStopped = true loadingIndicatorView.startAnimating() diff --git a/Stepic/Sources/Modules/Quizzes/NewStringQuiz/NewStringQuizView.swift b/Stepic/Sources/Modules/Quizzes/NewStringQuiz/NewStringQuizView.swift index 8c965eae95..9e53478851 100644 --- a/Stepic/Sources/Modules/Quizzes/NewStringQuiz/NewStringQuizView.swift +++ b/Stepic/Sources/Modules/Quizzes/NewStringQuiz/NewStringQuizView.swift @@ -12,15 +12,15 @@ extension NewStringQuizView { let textFieldPlaceholderFont = UIFont.systemFont(ofSize: 16) let textFieldPlaceholderColor = UIColor.stepikPlaceholderText - let textFieldTextColor = UIColor.stepikAccent + let textFieldTextColor = UIColor.stepikPrimaryText let textFieldHeight: CGFloat = 48 - let titleColor = UIColor.stepikAccent + let titleColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 12, weight: .medium) let textFieldBorderCornerRadius: CGFloat = 6 let textFieldBorderWidth: CGFloat = 1 - let textFieldBorderColor = UIColor(hex6: 0xCCCCCC) + let textFieldBorderColor = UIColor.stepikSeparator let statusMarkInsets = LayoutInsets(right: 16) let statusMarkSize = CGSize(width: 20, height: 20) diff --git a/Stepic/Sources/Modules/Quizzes/UnsupportedQuiz/UnsupportedQuizDataFlow.swift b/Stepic/Sources/Modules/Quizzes/UnsupportedQuiz/UnsupportedQuizDataFlow.swift index c73cb25203..b6fff74879 100644 --- a/Stepic/Sources/Modules/Quizzes/UnsupportedQuiz/UnsupportedQuizDataFlow.swift +++ b/Stepic/Sources/Modules/Quizzes/UnsupportedQuiz/UnsupportedQuizDataFlow.swift @@ -3,7 +3,7 @@ import Foundation enum UnsupportedQuiz { // Show step web version enum UnsupportedQuizPresentation { - struct Request { } + struct Request {} struct Response { let stepURLPath: String diff --git a/Stepic/Sources/Modules/Quizzes/UnsupportedQuiz/UnsupportedQuizView.swift b/Stepic/Sources/Modules/Quizzes/UnsupportedQuiz/UnsupportedQuizView.swift index 49af182f05..3059d6c168 100644 --- a/Stepic/Sources/Modules/Quizzes/UnsupportedQuiz/UnsupportedQuizView.swift +++ b/Stepic/Sources/Modules/Quizzes/UnsupportedQuiz/UnsupportedQuizView.swift @@ -10,14 +10,12 @@ extension UnsupportedQuizView { let spacing: CGFloat = 16 let insets = LayoutInsets(left: 16, right: 16) - let titleColor = UIColor.stepikAccent + let titleColor = UIColor.stepikPrimaryText let titleFont = UIFont.systemFont(ofSize: 12, weight: .medium) let actionButtonCornerRadius: CGFloat = 8 - let actionButtonBorderWidth: CGFloat = 8 - let actionButtonBorderColor = UIColor.stepikAccent - let actionButtonBackgroundColor = UIColor.stepikAccent - let actionButtonTitleColor = UIColor.white + let actionButtonBackgroundColor = UIColor.dynamic(light: .stepikAccent, dark: .stepikSecondaryBackground) + let actionButtonTitleColor = UIColor.dynamic(light: .white, dark: .stepikPrimaryText) let actionButtonHeight: CGFloat = 44 } } @@ -41,8 +39,6 @@ final class UnsupportedQuizView: UIView { button.setTitleColor(self.appearance.actionButtonTitleColor, for: .normal) button.backgroundColor = self.appearance.actionButtonBackgroundColor button.layer.cornerRadius = self.appearance.actionButtonCornerRadius - button.layer.borderWidth = self.appearance.actionButtonBorderWidth - button.layer.borderColor = self.appearance.actionButtonBorderColor.cgColor button.clipsToBounds = true button.addTarget(self, action: #selector(self.actionButtonClicked), for: .touchUpInside) return button @@ -67,7 +63,6 @@ final class UnsupportedQuizView: UIView { self.appearance = appearance super.init(frame: frame) - self.setupView() self.addSubviews() self.makeConstraints() } diff --git a/Stepic/Sources/Modules/Settings/SettingsAssembly.swift b/Stepic/Sources/Modules/Settings/SettingsAssembly.swift index 6c4104d61c..01a0f2511c 100644 --- a/Stepic/Sources/Modules/Settings/SettingsAssembly.swift +++ b/Stepic/Sources/Modules/Settings/SettingsAssembly.swift @@ -22,6 +22,7 @@ final class SettingsAssembly: Assembly { stepFontSizeStorageManager: StepFontSizeStorageManager(), autoplayStorageManager: AutoplayStorageManager(), adaptiveStorageManager: AdaptiveStorageManager.shared, + applicationThemeService: ApplicationThemeService(), downloadsProvider: DownloadsProvider( coursesPersistenceService: CoursesPersistenceService(), adaptiveStorageManager: AdaptiveStorageManager.shared, @@ -37,7 +38,8 @@ final class SettingsAssembly: Assembly { let interactor = SettingsInteractor( presenter: presenter, provider: provider, - userAccountService: UserAccountService() + userAccountService: UserAccountService(), + remoteConfig: .shared ) let viewController = SettingsViewController( interactor: interactor, diff --git a/Stepic/Sources/Modules/Settings/SettingsDataFlow.swift b/Stepic/Sources/Modules/Settings/SettingsDataFlow.swift index 151cad5b95..a09d8358c5 100644 --- a/Stepic/Sources/Modules/Settings/SettingsDataFlow.swift +++ b/Stepic/Sources/Modules/Settings/SettingsDataFlow.swift @@ -56,6 +56,27 @@ enum Settings { } } + /// Presents application theme setting screen. + enum ApplicationThemeSettingPresentation { + struct Request {} + + struct Response { + let availableApplicationThemes: [ApplicationTheme] + let currentApplicationTheme: ApplicationTheme + } + + struct ViewModel { + let settingDescription: SettingDescription + } + } + + /// Updates application theme setting. + enum ApplicationThemeSettingUpdate { + struct Request { + let setting: SettingDescription.Setting + } + } + /// Presents content language setting screen. enum ContentLanguageSettingPresentation { struct Request {} @@ -153,11 +174,13 @@ enum Settings { struct SettingsData { let downloadVideoQuality: DownloadVideoQuality let streamVideoQuality: StreamVideoQuality + let applicationTheme: ApplicationTheme let contentLanguage: ContentLanguage let stepFontSize: StepFontSize let shouldUseCellularDataForDownloads: Bool let isAutoplayEnabled: Bool let isAdaptiveModeEnabled: Bool + let isDarkModeAvailable: Bool } struct SettingDescription { diff --git a/Stepic/Sources/Modules/Settings/SettingsInteractor.swift b/Stepic/Sources/Modules/Settings/SettingsInteractor.swift index 343f32aef3..86d6d142a8 100644 --- a/Stepic/Sources/Modules/Settings/SettingsInteractor.swift +++ b/Stepic/Sources/Modules/Settings/SettingsInteractor.swift @@ -15,6 +15,9 @@ protocol SettingsInteractorProtocol { // StepFontSize func doStepFontSizeSettingPresentation(request: Settings.StepFontSizeSettingPresentation.Request) func doStepFontSizeUpdate(request: Settings.StepFontSizeSettingUpdate.Request) + // ApplicationTheme + func doApplicationThemeSettingPresentation(request: Settings.ApplicationThemeSettingPresentation.Request) + func doApplicationThemeSettingUpdate(request: Settings.ApplicationThemeSettingUpdate.Request) func doUseCellularDataForDownloadsSettingUpdate(request: Settings.UseCellularDataForDownloadsSettingUpdate.Request) func doAutoplayNextVideoSettingUpdate(request: Settings.AutoplayNextVideoSettingUpdate.Request) @@ -30,27 +33,32 @@ final class SettingsInteractor: SettingsInteractorProtocol { private let provider: SettingsProviderProtocol private let userAccountService: UserAccountServiceProtocol + private let remoteConfig: RemoteConfig private var settingsData: Settings.SettingsData { .init( downloadVideoQuality: self.provider.globalDownloadVideoQuality, streamVideoQuality: self.provider.globalStreamVideoQuality, + applicationTheme: self.provider.globalApplicationTheme, contentLanguage: self.provider.globalContentLanguage, stepFontSize: self.provider.globalStepFontSize, shouldUseCellularDataForDownloads: self.provider.shouldUseCellularDataForDownloads, isAutoplayEnabled: self.provider.isAutoplayEnabled, - isAdaptiveModeEnabled: self.provider.isAdaptiveModeEnabled + isAdaptiveModeEnabled: self.provider.isAdaptiveModeEnabled, + isDarkModeAvailable: self.remoteConfig.isDarkModeAvailable ) } init( presenter: SettingsPresenterProtocol, provider: SettingsProviderProtocol, - userAccountService: UserAccountServiceProtocol + userAccountService: UserAccountServiceProtocol, + remoteConfig: RemoteConfig ) { self.presenter = presenter self.provider = provider self.userAccountService = userAccountService + self.remoteConfig = remoteConfig } func doSettingsLoad(request: Settings.SettingsLoad.Request) { @@ -116,6 +124,21 @@ final class SettingsInteractor: SettingsInteractorProtocol { } } + func doApplicationThemeSettingPresentation(request: Settings.ApplicationThemeSettingPresentation.Request) { + self.presenter.presentApplicationThemeSetting( + response: .init( + availableApplicationThemes: self.provider.availableApplicationThemes, + currentApplicationTheme: self.provider.globalApplicationTheme + ) + ) + } + + func doApplicationThemeSettingUpdate(request: Settings.ApplicationThemeSettingUpdate.Request) { + if let newApplicationTheme = ApplicationTheme(uniqueIdentifier: request.setting.uniqueIdentifier) { + self.provider.globalApplicationTheme = newApplicationTheme + } + } + func doUseCellularDataForDownloadsSettingUpdate( request: Settings.UseCellularDataForDownloadsSettingUpdate.Request ) { diff --git a/Stepic/Sources/Modules/Settings/SettingsPresenter.swift b/Stepic/Sources/Modules/Settings/SettingsPresenter.swift index 78a4c2a828..3085222f7d 100644 --- a/Stepic/Sources/Modules/Settings/SettingsPresenter.swift +++ b/Stepic/Sources/Modules/Settings/SettingsPresenter.swift @@ -4,6 +4,7 @@ protocol SettingsPresenterProtocol { func presentSettings(response: Settings.SettingsLoad.Response) func presentDownloadVideoQualitySetting(response: Settings.DownloadVideoQualitySettingPresentation.Response) func presentStreamVideoQualitySetting(response: Settings.StreamVideoQualitySettingPresentation.Response) + func presentApplicationThemeSetting(response: Settings.ApplicationThemeSettingPresentation.Response) func presentContentLanguageSetting(response: Settings.ContentLanguageSettingPresentation.Response) func presentStepFontSizeSetting(response: Settings.StepFontSizeSettingPresentation.Response) func presentDeleteAllContentResult(response: Settings.DeleteAllContent.Response) @@ -51,6 +52,20 @@ final class SettingsPresenter: SettingsPresenterProtocol { self.viewController?.displayStreamVideoQualitySetting(viewModel: .init(settingDescription: settingDescription)) } + func presentApplicationThemeSetting(response: Settings.ApplicationThemeSettingPresentation.Response) { + let settingDescription = Settings.SettingDescription( + settings: response.availableApplicationThemes.map { + .init(uniqueIdentifier: $0.uniqueIdentifier, title: $0.title) + }, + currentSetting: .init( + uniqueIdentifier: response.currentApplicationTheme.uniqueIdentifier, + title: response.currentApplicationTheme.title + ) + ) + + self.viewController?.displayApplicationThemeSetting(viewModel: .init(settingDescription: settingDescription)) + } + func presentContentLanguageSetting(response: Settings.ContentLanguageSettingPresentation.Response) { let settingDescription = Settings.SettingDescription( settings: response.availableContentLanguages.map { @@ -93,11 +108,13 @@ final class SettingsPresenter: SettingsPresenterProtocol { SettingsViewModel( downloadVideoQuality: FormatterHelper.downloadVideoQualityInProgressiveScan(data.downloadVideoQuality), streamVideoQuality: FormatterHelper.streamVideoQualityInProgressiveScan(data.streamVideoQuality), + applicationTheme: data.applicationTheme.title, contentLanguage: data.contentLanguage.fullString, stepFontSize: data.stepFontSize.title, shouldUseCellularDataForDownloads: data.shouldUseCellularDataForDownloads, isAutoplayEnabled: data.isAutoplayEnabled, - isAdaptiveModeEnabled: data.isAdaptiveModeEnabled + isAdaptiveModeEnabled: data.isAdaptiveModeEnabled, + isApplicationThemeSettingAvailable: data.isDarkModeAvailable ) } } diff --git a/Stepic/Sources/Modules/Settings/SettingsProvider.swift b/Stepic/Sources/Modules/Settings/SettingsProvider.swift index 11c2021cc6..0b14839bb5 100644 --- a/Stepic/Sources/Modules/Settings/SettingsProvider.swift +++ b/Stepic/Sources/Modules/Settings/SettingsProvider.swift @@ -14,6 +14,9 @@ protocol SettingsProviderProtocol: AnyObject { // StepFontSize var globalStepFontSize: StepFontSize { get set } var availableStepFontSizes: [StepFontSize] { get } + // ApplicationTheme + var globalApplicationTheme: ApplicationTheme { get set } + var availableApplicationThemes: [ApplicationTheme] { get } var shouldUseCellularDataForDownloads: Bool { get set } @@ -31,6 +34,7 @@ final class SettingsProvider: SettingsProviderProtocol { private let stepFontSizeStorageManager: StepFontSizeStorageManagerProtocol private let autoplayStorageManager: AutoplayStorageManagerProtocol private let adaptiveStorageManager: AdaptiveStorageManagerProtocol + private let applicationThemeService: ApplicationThemeServiceProtocol private var downloadsProvider: DownloadsProviderProtocol @@ -78,6 +82,17 @@ final class SettingsProvider: SettingsProviderProtocol { var availableStepFontSizes: [StepFontSize] { StepFontSize.allCases } + var globalApplicationTheme: ApplicationTheme { + get { + self.applicationThemeService.theme + } + set { + self.applicationThemeService.theme = newValue + } + } + + var availableApplicationThemes: [ApplicationTheme] { ApplicationTheme.allCases } + var shouldUseCellularDataForDownloads: Bool { get { self.useCellularDataForDownloadsStorageManager.shouldUseCellularDataForDownloads @@ -113,6 +128,7 @@ final class SettingsProvider: SettingsProviderProtocol { stepFontSizeStorageManager: StepFontSizeStorageManagerProtocol, autoplayStorageManager: AutoplayStorageManagerProtocol, adaptiveStorageManager: AdaptiveStorageManagerProtocol, + applicationThemeService: ApplicationThemeServiceProtocol, downloadsProvider: DownloadsProviderProtocol ) { self.downloadVideoQualityStorageManager = downloadVideoQualityStorageManager @@ -122,6 +138,7 @@ final class SettingsProvider: SettingsProviderProtocol { self.stepFontSizeStorageManager = stepFontSizeStorageManager self.autoplayStorageManager = autoplayStorageManager self.adaptiveStorageManager = adaptiveStorageManager + self.applicationThemeService = applicationThemeService self.downloadsProvider = downloadsProvider } diff --git a/Stepic/Sources/Modules/Settings/SettingsView.swift b/Stepic/Sources/Modules/Settings/SettingsView.swift index 2199f8b8fb..6065672a30 100644 --- a/Stepic/Sources/Modules/Settings/SettingsView.swift +++ b/Stepic/Sources/Modules/Settings/SettingsView.swift @@ -15,7 +15,7 @@ final class SettingsView: UIView { } } - private lazy var tableView = SettingsTableView(appearance: .init(style: .insetGroupedFallbackGrouped)) + private lazy var tableView = SettingsTableView(appearance: .init(style: .stepikInsetGrouped)) init( frame: CGRect = .zero, diff --git a/Stepic/Sources/Modules/Settings/SettingsViewController.swift b/Stepic/Sources/Modules/Settings/SettingsViewController.swift index 602f59ca42..fdf32d12a2 100644 --- a/Stepic/Sources/Modules/Settings/SettingsViewController.swift +++ b/Stepic/Sources/Modules/Settings/SettingsViewController.swift @@ -7,6 +7,7 @@ protocol SettingsViewControllerProtocol: AnyObject { func displaySettings(viewModel: Settings.SettingsLoad.ViewModel) func displayDownloadVideoQualitySetting(viewModel: Settings.DownloadVideoQualitySettingPresentation.ViewModel) func displayStreamVideoQualitySetting(viewModel: Settings.StreamVideoQualitySettingPresentation.ViewModel) + func displayApplicationThemeSetting(viewModel: Settings.ApplicationThemeSettingPresentation.ViewModel) func displayContentLanguageSetting(viewModel: Settings.ContentLanguageSettingPresentation.ViewModel) func displayStepFontSizeSetting(viewModel: Settings.StepFontSizeSettingPresentation.ViewModel) func displayDeleteAllContentResult(viewModel: Settings.DeleteAllContent.ViewModel) @@ -31,7 +32,7 @@ final class SettingsViewController: UIViewController { lazy var settingsView = self.view as? SettingsView lazy var styledNavigationController = self.navigationController as? StyledNavigationController - private lazy var closeBarButtonItem = UIBarButtonItem.closeBarButtonItem( + private lazy var closeBarButtonItem = UIBarButtonItem.stepikCloseBarButtonItem( target: self, action: #selector(self.closeButtonClicked) ) @@ -99,9 +100,10 @@ final class SettingsViewController: UIViewController { case downloadQuality case streamQuality case useCellularDataForDownloads - case contentLanguage + case theme case textSize case codeEditor + case contentLanguage case autoplayNextVideo case adaptiveMode case downloads @@ -115,6 +117,8 @@ final class SettingsViewController: UIViewController { return NSLocalizedString("SettingsCellTitleDownloadQuality", comment: "") case .streamQuality: return NSLocalizedString("SettingsCellTitleStreamQuality", comment: "") + case .theme: + return NSLocalizedString("SettingsCellTitleTheme", comment: "") case .useCellularDataForDownloads: return NSLocalizedString("SettingsCellTitleUseCellularDataForDownloads", comment: "") case .contentLanguage: @@ -177,6 +181,22 @@ extension SettingsViewController: SettingsViewControllerProtocol { ) } + func displayApplicationThemeSetting(viewModel: Settings.ApplicationThemeSettingPresentation.ViewModel) { + self.displaySelectionList( + settingDescription: viewModel.settingDescription, + title: NSLocalizedString("SettingsThemeTitle", comment: ""), + onSettingSelected: { [weak self] selectedSetting in + guard let strongSelf = self else { + return + } + + DispatchQueue.main.async { + strongSelf.interactor.doApplicationThemeSettingUpdate(request: .init(setting: selectedSetting)) + } + } + ) + } + func displayContentLanguageSetting(viewModel: Settings.ContentLanguageSettingPresentation.ViewModel) { self.displaySelectionList( settingDescription: viewModel.settingDescription, @@ -232,7 +252,7 @@ extension SettingsViewController: SettingsViewControllerProtocol { }() let viewController = SelectItemTableViewController( - style: .insetGroupedFallbackGrouped, + style: .stepikInsetGrouped, viewModel: .init( sections: [ .init( @@ -292,19 +312,17 @@ extension SettingsViewController: SettingsViewControllerProtocol { ) ) - // Language - let contentLanguageCellViewModel = SettingsTableSectionViewModel.Cell( - uniqueIdentifier: Setting.contentLanguage.rawValue, + // Appearance + let themeCellViewModel = SettingsTableSectionViewModel.Cell( + uniqueIdentifier: Setting.theme.rawValue, type: .rightDetail( options: .init( - title: .init(text: Setting.contentLanguage.cellTitle), - detailType: .label(text: settingsViewModel.contentLanguage), + title: .init(text: Setting.theme.cellTitle), + detailType: .label(text: settingsViewModel.applicationTheme), accessoryType: .disclosureIndicator ) ) ) - - // Learning let stepTextSizeCellViewModel = SettingsTableSectionViewModel.Cell( uniqueIdentifier: Setting.textSize.rawValue, type: .rightDetail( @@ -324,7 +342,21 @@ extension SettingsViewController: SettingsViewControllerProtocol { ) ) ) - let autoplayNextVideoCellViewModel = SettingsTableSectionViewModel.Cell( + + // Language + let contentLanguageCellViewModel = SettingsTableSectionViewModel.Cell( + uniqueIdentifier: Setting.contentLanguage.rawValue, + type: .rightDetail( + options: .init( + title: .init(text: Setting.contentLanguage.cellTitle), + detailType: .label(text: settingsViewModel.contentLanguage), + accessoryType: .disclosureIndicator + ) + ) + ) + + // Learning + let autoplayCellViewModel = SettingsTableSectionViewModel.Cell( uniqueIdentifier: Setting.autoplayNextVideo.rawValue, type: .rightDetail( options: .init( @@ -393,7 +425,11 @@ extension SettingsViewController: SettingsViewControllerProtocol { ) ) - let sectionsViewModels: [SettingsTableSectionViewModel] = [ + let learningSectionCellsViewModels = settingsViewModel.isApplicationThemeSettingAvailable + ? [autoplayCellViewModel, adaptiveModeCellViewModel] + : [stepTextSizeCellViewModel, codeEditorSettingsCellViewModel, autoplayCellViewModel, adaptiveModeCellViewModel] + + var sectionsViewModels: [SettingsTableSectionViewModel] = [ .init( header: .init(title: NSLocalizedString("SettingsHeaderTitleVideo", comment: "")), cells: [ @@ -410,12 +446,7 @@ extension SettingsViewController: SettingsViewControllerProtocol { ), .init( header: .init(title: NSLocalizedString("SettingsHeaderTitleLearning", comment: "")), - cells: [ - stepTextSizeCellViewModel, - codeEditorSettingsCellViewModel, - autoplayNextVideoCellViewModel, - adaptiveModeCellViewModel - ], + cells: learningSectionCellsViewModels, footer: nil ), .init( @@ -431,6 +462,16 @@ extension SettingsViewController: SettingsViewControllerProtocol { .init(header: nil, cells: [logOutCellViewModel], footer: nil) ] + if settingsViewModel.isApplicationThemeSettingAvailable { + let appearanceSectionViewModel = SettingsTableSectionViewModel( + header: .init(title: NSLocalizedString("SettingsHeaderTitleAppearance", comment: "")), + cells: [themeCellViewModel, stepTextSizeCellViewModel, codeEditorSettingsCellViewModel], + footer: nil + ) + + sectionsViewModels.insert(appearanceSectionViewModel, at: 1) + } + self.settingsView?.configure(viewModel: SettingsTableViewModel(sections: sectionsViewModels)) } } @@ -453,6 +494,8 @@ extension SettingsViewController: SettingsViewDelegate { self.interactor.doDownloadVideoQualitySettingPresentation(request: .init()) case .streamQuality: self.interactor.doStreamVideoQualitySettingPresentation(request: .init()) + case .theme: + self.interactor.doApplicationThemeSettingPresentation(request: .init()) case .contentLanguage: self.interactor.doContentLanguageSettingPresentation(request: .init()) case .textSize: diff --git a/Stepic/Sources/Modules/Settings/SettingsViewModel.swift b/Stepic/Sources/Modules/Settings/SettingsViewModel.swift index 56f88b1e77..b3ed029e26 100644 --- a/Stepic/Sources/Modules/Settings/SettingsViewModel.swift +++ b/Stepic/Sources/Modules/Settings/SettingsViewModel.swift @@ -3,9 +3,11 @@ import Foundation struct SettingsViewModel { let downloadVideoQuality: String let streamVideoQuality: String + let applicationTheme: String let contentLanguage: String let stepFontSize: String let shouldUseCellularDataForDownloads: Bool let isAutoplayEnabled: Bool let isAdaptiveModeEnabled: Bool + let isApplicationThemeSettingAvailable: Bool } diff --git a/Stepic/Sources/Modules/Solution/SolutionView.swift b/Stepic/Sources/Modules/Solution/SolutionView.swift index 77f7349f12..30663733f6 100644 --- a/Stepic/Sources/Modules/Solution/SolutionView.swift +++ b/Stepic/Sources/Modules/Solution/SolutionView.swift @@ -13,7 +13,7 @@ extension SolutionView { let loadingIndicatorColor = UIColor.stepikLoadingIndicator - let actionButtonBackgroundColor = UIColor.stepikGreen + let actionButtonBackgroundColor = UIColor.dynamic(light: .stepikGreen, dark: .stepikDarkGreenFixed) let actionButtonHeight: CGFloat = 44 let actionButtonTextColor = UIColor.white let actionButtonCornerRadius: CGFloat = 6 @@ -31,7 +31,7 @@ final class SolutionView: UIView { weak var delegate: SolutionViewDelegate? private lazy var loadingIndicatorView: UIActivityIndicatorView = { - let loadingIndicatorView = UIActivityIndicatorView(style: .white) + let loadingIndicatorView = UIActivityIndicatorView(style: .stepikWhite) loadingIndicatorView.color = self.appearance.loadingIndicatorColor loadingIndicatorView.hidesWhenStopped = true loadingIndicatorView.startAnimating() @@ -147,7 +147,7 @@ final class SolutionView: UIView { extension SolutionView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .stepikBackground } func addSubviews() { diff --git a/Stepic/Sources/Modules/Step/StepView.swift b/Stepic/Sources/Modules/Step/StepView.swift index 8cedfb687f..16449c7af5 100644 --- a/Stepic/Sources/Modules/Step/StepView.swift +++ b/Stepic/Sources/Modules/Step/StepView.swift @@ -30,7 +30,7 @@ final class StepView: UIView { weak var delegate: StepViewDelegate? private lazy var loadingIndicatorView: UIActivityIndicatorView = { - let loadingIndicatorView = UIActivityIndicatorView(style: .whiteLarge) + let loadingIndicatorView = UIActivityIndicatorView(style: .stepikWhiteLarge) loadingIndicatorView.color = self.appearance.loadingIndicatorColor loadingIndicatorView.hidesWhenStopped = true loadingIndicatorView.startAnimating() diff --git a/Stepic/Sources/Modules/Step/Views/StepControlsView.swift b/Stepic/Sources/Modules/Step/Views/StepControlsView.swift index 18ccce0aa2..b2439841e3 100644 --- a/Stepic/Sources/Modules/Step/Views/StepControlsView.swift +++ b/Stepic/Sources/Modules/Step/Views/StepControlsView.swift @@ -12,8 +12,8 @@ extension StepControlsView { let discussionThreadButtonHeight: CGFloat = 44 let statisticsViewHeight: CGFloat = 44 - let separatorColor = UIColor(hex6: 0xEAECF0) - let separatorHeight: CGFloat = 1 + let separatorColor = UIColor.dynamic(light: UIColor.stepikShadowFixed, dark: .stepikSeparator) + let separatorHeight: CGFloat = 1.0 } } diff --git a/Stepic/Sources/Modules/Step/Views/StepDiscussionThreadButton.swift b/Stepic/Sources/Modules/Step/Views/StepDiscussionThreadButton.swift index 5eca302efe..ee25c29e00 100644 --- a/Stepic/Sources/Modules/Step/Views/StepDiscussionThreadButton.swift +++ b/Stepic/Sources/Modules/Step/Views/StepDiscussionThreadButton.swift @@ -9,7 +9,7 @@ extension StepDiscussionThreadButton { let mainColor = UIColor.stepikAccent let textFont = UIFont.systemFont(ofSize: 16) - let backgroundColor = UIColor(hex6: 0xF6F6F6) + let backgroundColor = UIColor.stepikLightSecondaryBackground } } diff --git a/Stepic/Sources/Modules/Step/Views/StepNavigationButton.swift b/Stepic/Sources/Modules/Step/Views/StepNavigationButton.swift index f29e2de363..ca7dc257c8 100644 --- a/Stepic/Sources/Modules/Step/Views/StepNavigationButton.swift +++ b/Stepic/Sources/Modules/Step/Views/StepNavigationButton.swift @@ -9,7 +9,7 @@ extension StepNavigationButton { let borderWidth: CGFloat = 1 let cornerRadius: CGFloat = 6 - let backgroundColor = UIColor.white + let backgroundColor = UIColor.stepikBackground let mainColor = UIColor.stepikGreen let textColor = UIColor.stepikGreen diff --git a/Stepic/Sources/Modules/Step/Views/StepStatisticsView.swift b/Stepic/Sources/Modules/Step/Views/StepStatisticsView.swift index 055943a2bc..040f428cc7 100644 --- a/Stepic/Sources/Modules/Step/Views/StepStatisticsView.swift +++ b/Stepic/Sources/Modules/Step/Views/StepStatisticsView.swift @@ -6,10 +6,10 @@ extension StepStatisticsView { let insets = LayoutInsets(top: 8, left: 16, bottom: 8, right: 16) let labelsSpacing: CGFloat = 8 - let separatorColor = UIColor(hex6: 0xEAECF0) - let separatorHeight: CGFloat = 1 + let separatorColor = UIColor.stepikSeparator + let separatorHeight: CGFloat = 0.5 - let textColor = UIColor.stepikAccent + let textColor = UIColor.stepikPrimaryText let textFont = UIFont.systemFont(ofSize: 14) let textFontDetail = UIFont.systemFont(ofSize: 14, weight: .bold) } diff --git a/Stepic/Sources/Modules/Step/Views/StepVideoPreviewView.swift b/Stepic/Sources/Modules/Step/Views/StepVideoPreviewView.swift index 4dff03263c..0fd135d905 100644 --- a/Stepic/Sources/Modules/Step/Views/StepVideoPreviewView.swift +++ b/Stepic/Sources/Modules/Step/Views/StepVideoPreviewView.swift @@ -4,7 +4,7 @@ import UIKit extension StepVideoPreviewView { struct Appearance { - let overlayColor = UIColor.stepikAccentAlpha40 + let overlayColor = UIColor.stepikOverlayBackground let introVideoHeightRatio: CGFloat = 9 / 16 let thumbnailImageFadeInDuration: TimeInterval = 0.15 @@ -96,7 +96,7 @@ final class StepVideoPreviewView: UIControl { extension StepVideoPreviewView: ProgrammaticallyInitializableViewProtocol { func setupView() { - self.backgroundColor = .white + self.backgroundColor = .stepikBackground self.isUserInteractionEnabled = true self.addGestureRecognizer(self.gestureRecognizer) diff --git a/Stepic/Sources/Modules/Submissions/SubmissionsViewController.swift b/Stepic/Sources/Modules/Submissions/SubmissionsViewController.swift index ce8ab05aea..d481ffb43d 100644 --- a/Stepic/Sources/Modules/Submissions/SubmissionsViewController.swift +++ b/Stepic/Sources/Modules/Submissions/SubmissionsViewController.swift @@ -23,7 +23,7 @@ final class SubmissionsViewController: UIViewController, ControllerWithStepikPla private lazy var submissionsView = self.view as? SubmissionsView private lazy var paginationView = PaginationView() - private lazy var closeBarButtonItem = UIBarButtonItem.closeBarButtonItem( + private lazy var closeBarButtonItem = UIBarButtonItem.stepikCloseBarButtonItem( target: self, action: #selector(self.closeButtonClicked) ) diff --git a/Stepic/Sources/Modules/Submissions/Views/Cell/SubmissionsCellView.swift b/Stepic/Sources/Modules/Submissions/Views/Cell/SubmissionsCellView.swift index d4de49942e..9f56cb915d 100644 --- a/Stepic/Sources/Modules/Submissions/Views/Cell/SubmissionsCellView.swift +++ b/Stepic/Sources/Modules/Submissions/Views/Cell/SubmissionsCellView.swift @@ -7,7 +7,7 @@ extension SubmissionsCellView { let avatarImageViewSize = CGSize(width: 36, height: 36) let avatarImageViewCornerRadius: CGFloat = 4.0 - let nameLabelTextColor = UIColor.stepikAccent + let nameLabelTextColor = UIColor.stepikPrimaryText let nameLabelFont = UIFont.systemFont(ofSize: 14, weight: .bold) let nameLabelInsets = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16) @@ -16,7 +16,7 @@ extension SubmissionsCellView { let dateLabelInsets = UIEdgeInsets(top: 8, left: 0, bottom: 16, right: 0) let dateLabelFont = UIFont.systemFont(ofSize: 12, weight: .light) - let dateLabelTextColor = UIColor.stepikAccent + let dateLabelTextColor = UIColor.stepikSecondaryText } } @@ -31,7 +31,7 @@ final class SubmissionsCellView: UIView { private lazy var avatarOverlayButton: UIButton = { let button = HighlightFakeButton() - button.highlightedBackgroundColor = UIColor.white.withAlphaComponent(0.5) + button.highlightedBackgroundColor = UIColor.stepikTertiaryBackground.withAlphaComponent(0.5) button.addTarget(self, action: #selector(self.avatarButtonClicked), for: .touchUpInside) return button }() diff --git a/Stepic/Sources/Modules/Submissions/Views/Cell/SubmissionsTableViewCell.swift b/Stepic/Sources/Modules/Submissions/Views/Cell/SubmissionsTableViewCell.swift index 3fa6ec7356..350ecdcd90 100644 --- a/Stepic/Sources/Modules/Submissions/Views/Cell/SubmissionsTableViewCell.swift +++ b/Stepic/Sources/Modules/Submissions/Views/Cell/SubmissionsTableViewCell.swift @@ -6,7 +6,7 @@ final class SubmissionsTableViewCell: UITableViewCell, Reusable { static let separatorLeadingOffset: CGFloat = 16 } - enum SeparatorIndentationType { + enum SeparatorIndentationStyle { case indented case edgeToEdge @@ -25,9 +25,9 @@ final class SubmissionsTableViewCell: UITableViewCell, Reusable { private lazy var separatorView = SeparatorView() private var separatorLeadingConstraint: Constraint? - var separatorIndentation: SeparatorIndentationType = .indented { + var separatorIndentationStyle: SeparatorIndentationStyle = .indented { didSet { - self.separatorLeadingConstraint?.update(offset: self.separatorIndentation.offset) + self.separatorLeadingConstraint?.update(offset: self.separatorIndentationStyle.offset) } } @@ -83,7 +83,7 @@ final class SubmissionsTableViewCell: UITableViewCell, Reusable { make.top.equalTo(self.cellView.snp.bottom) self.separatorLeadingConstraint = make.leading .equalToSuperview() - .offset(self.separatorIndentation.offset) + .offset(self.separatorIndentationStyle.offset) .constraint make.bottom.equalToSuperview().priority(999) make.trailing.equalToSuperview() diff --git a/Stepic/Sources/Modules/Submissions/Views/SubmissionsTableViewDataSource.swift b/Stepic/Sources/Modules/Submissions/Views/SubmissionsTableViewDataSource.swift index 36fc4d3df0..304c2928f0 100644 --- a/Stepic/Sources/Modules/Submissions/Views/SubmissionsTableViewDataSource.swift +++ b/Stepic/Sources/Modules/Submissions/Views/SubmissionsTableViewDataSource.swift @@ -35,7 +35,7 @@ extension SubmissionsTableViewDataSource: UITableViewDataSource { cell.configure(viewModel: viewModel) let isLastCell = indexPath.row == self.viewModels.count - 1 - cell.separatorIndentation = isLastCell ? .edgeToEdge : .indented + cell.separatorIndentationStyle = isLastCell ? .edgeToEdge : .indented cell.onAvatarClick = { [weak self] in guard let strongSelf = self else { diff --git a/Stepic/Sources/Modules/WriteComment/Views/WriteCommentSolutionControl.swift b/Stepic/Sources/Modules/WriteComment/Views/WriteCommentSolutionControl.swift index 80cb13a9e3..57f2292378 100644 --- a/Stepic/Sources/Modules/WriteComment/Views/WriteCommentSolutionControl.swift +++ b/Stepic/Sources/Modules/WriteComment/Views/WriteCommentSolutionControl.swift @@ -3,11 +3,12 @@ import UIKit extension WriteCommentSolutionControl { struct Appearance { - let textColor = UIColor.stepikAccent + let textColor = UIColor.stepikPrimaryText let textFont = UIFont.systemFont(ofSize: 17) let rightArrowImageSize = CGSize(width: 15, height: 15) let rightArrowImageInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0) + let rightArrowImageColor = UIColor.stepikSeparator } } @@ -36,9 +37,11 @@ final class WriteCommentSolutionControl: UIControl { }() private lazy var rightArrowImageView: UIImageView = { - let imageView = UIImageView(image: UIImage(named: "menu_arrow_right")) + let image = UIImage(named: "menu_arrow_right") + let imageView = UIImageView(image: image?.withRenderingMode(.alwaysTemplate)) imageView.contentMode = .scaleAspectFit imageView.isUserInteractionEnabled = false + imageView.tintColor = self.appearance.rightArrowImageColor return imageView }() @@ -52,7 +55,6 @@ final class WriteCommentSolutionControl: UIControl { self.appearance = appearance super.init(frame: frame) - self.setupView() self.addSubviews() self.makeConstraints() } @@ -86,8 +88,6 @@ final class WriteCommentSolutionControl: UIControl { } extension WriteCommentSolutionControl: ProgrammaticallyInitializableViewProtocol { - func setupView() {} - func addSubviews() { self.addSubview(self.solutionStackView) self.addSubview(self.rightArrowImageView) @@ -101,7 +101,9 @@ extension WriteCommentSolutionControl: ProgrammaticallyInitializableViewProtocol self.rightArrowImageView.translatesAutoresizingMaskIntoConstraints = false self.rightArrowImageView.snp.makeConstraints { make in - make.leading.equalTo(self.solutionStackView.snp.trailing).offset(self.appearance.rightArrowImageInsets.left) + make.leading + .equalTo(self.solutionStackView.snp.trailing) + .offset(self.appearance.rightArrowImageInsets.left) make.trailing.equalToSuperview() make.size.equalTo(self.appearance.rightArrowImageSize) make.centerY.equalToSuperview() diff --git a/Stepic/Sources/Modules/WriteComment/WriteCommentView.swift b/Stepic/Sources/Modules/WriteComment/WriteCommentView.swift index 7f7a79ee71..720955805c 100644 --- a/Stepic/Sources/Modules/WriteComment/WriteCommentView.swift +++ b/Stepic/Sources/Modules/WriteComment/WriteCommentView.swift @@ -12,14 +12,14 @@ protocol WriteCommentViewDelegate: AnyObject { extension WriteCommentView { struct Appearance { - let backgroundColor = UIColor.white + let backgroundColor = UIColor.stepikBackground let solutionControlHeight: CGFloat = 44 let solutionControlInsets = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16) let textViewTextInsets = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) let textViewFont = UIFont.systemFont(ofSize: 16) - let textViewTextColor = UIColor.stepikAccent + let textViewTextColor = UIColor.stepikPrimaryText let textViewPlaceholderColor = UIColor.stepikPlaceholderText } } diff --git a/Stepic/Sources/Modules/WriteComment/WriteCommentViewController.swift b/Stepic/Sources/Modules/WriteComment/WriteCommentViewController.swift index ebffa6fb8b..41f42671ec 100644 --- a/Stepic/Sources/Modules/WriteComment/WriteCommentViewController.swift +++ b/Stepic/Sources/Modules/WriteComment/WriteCommentViewController.swift @@ -44,7 +44,7 @@ final class WriteCommentViewController: UIViewController { action: #selector(self.doneButtonDidClick(_:)) ) private lazy var activityBarButtonItem: UIBarButtonItem = { - let activityIndicatorView = UIActivityIndicatorView(style: .white) + let activityIndicatorView = UIActivityIndicatorView(style: .stepikWhite) activityIndicatorView.color = .stepikLoadingIndicator activityIndicatorView.startAnimating() return UIBarButtonItem(customView: activityIndicatorView) diff --git a/Stepic/Sources/Modules/WriteCourseReview/WriteCourseReviewDataFlow.swift b/Stepic/Sources/Modules/WriteCourseReview/WriteCourseReviewDataFlow.swift index c7f1ceb327..533c07d3d4 100644 --- a/Stepic/Sources/Modules/WriteCourseReview/WriteCourseReviewDataFlow.swift +++ b/Stepic/Sources/Modules/WriteCourseReview/WriteCourseReviewDataFlow.swift @@ -12,7 +12,7 @@ enum WriteCourseReview { /// Show course review enum CourseReviewLoad { - struct Request { } + struct Request {} struct Response { let result: CourseReviewInfo @@ -55,7 +55,7 @@ enum WriteCourseReview { /// Do review main action (screate or update) enum CourseReviewMainAction { - struct Request { } + struct Request {} struct Response { let isSuccessful: Bool diff --git a/Stepic/Sources/Modules/WriteCourseReview/WriteCourseReviewView.swift b/Stepic/Sources/Modules/WriteCourseReview/WriteCourseReviewView.swift index 5c4c7ad085..70c3274ebb 100644 --- a/Stepic/Sources/Modules/WriteCourseReview/WriteCourseReviewView.swift +++ b/Stepic/Sources/Modules/WriteCourseReview/WriteCourseReviewView.swift @@ -8,7 +8,7 @@ protocol WriteCourseReviewViewDelegate: AnyObject { extension WriteCourseReviewView { struct Appearance { - let backgroundColor = UIColor.white + let backgroundColor = UIColor.stepikBackground let starsViewInsets = LayoutInsets(top: 16, left: 16, right: 16) let starsClearColor = UIColor.stepikAccent @@ -17,13 +17,13 @@ extension WriteCourseReviewView { let starsHintLabelInsets = LayoutInsets(top: 8) let starsHintLabelFont = UIFont.systemFont(ofSize: 12) - let starsHintLabelTextColor = UIColor.stepikAccent + let starsHintLabelTextColor = UIColor.stepikPrimaryText let separatorViewInsets = LayoutInsets(top: 16, left: 16) let textViewInsets = LayoutInsets(top: 16, left: 16, bottom: 16, right: 16) let textViewFont = UIFont.systemFont(ofSize: 16) - let textViewTextColor = UIColor.stepikAccent + let textViewTextColor = UIColor.stepikPrimaryText let textViewPlaceholderColor = UIColor.stepikPlaceholderText } } @@ -35,7 +35,7 @@ final class WriteCourseReviewView: UIView { private lazy var starsView: CourseRatingView = { var appearance = CourseRatingView.Appearance() - appearance.statClearColor = self.appearance.starsClearColor + appearance.starClearColor = self.appearance.starsClearColor appearance.starsSpacing = self.appearance.starsSpacing appearance.starsSize = self.appearance.starsSize let view = CourseRatingView(appearance: appearance) diff --git a/Stepic/Sources/Services/ApplicationThemeService.swift b/Stepic/Sources/Services/ApplicationThemeService.swift new file mode 100644 index 0000000000..1cf596e335 --- /dev/null +++ b/Stepic/Sources/Services/ApplicationThemeService.swift @@ -0,0 +1,77 @@ +import UIKit + +protocol ApplicationThemeServiceProtocol: AnyObject { + var theme: ApplicationTheme { get set } + + func registerDefaultTheme() +} + +final class ApplicationThemeService: ApplicationThemeServiceProtocol { + private static let applicationThemeKey = "applicationTheme" + + private let remoteConfig: RemoteConfig + + var theme: ApplicationTheme { + get { + if let applicationTheme = self.getApplicationTheme() { + return applicationTheme + } else { + return .default + } + } + set { + if #available(iOS 13.0, *) { + self.applyTheme(newValue) + UserDefaults.standard.set(newValue.rawValue, forKey: Self.applicationThemeKey) + } + } + } + + init(remoteConfig: RemoteConfig = .shared) { + self.remoteConfig = remoteConfig + } + + func registerDefaultTheme() { + if #available(iOS 13.0, *) { + guard self.remoteConfig.isDarkModeAvailable else { + return self.applyTheme(.light) + } + + if let userSelectedApplicationTheme = self.getApplicationTheme() { + self.applyTheme(userSelectedApplicationTheme) + } else { + self.applyTheme(.default) + } + } + } + + private func getApplicationTheme() -> ApplicationTheme? { + if let stringValue = UserDefaults.standard.string(forKey: Self.applicationThemeKey) { + return ApplicationTheme(rawValue: stringValue) + } + return nil + } + + @available(iOS 13.0, *) + private func applyTheme(_ theme: ApplicationTheme) { + DispatchQueue.main.async { + if let keyWindow = UIApplication.shared.keyWindow { + keyWindow.overrideUserInterfaceStyle = theme.userInterfaceStyle + } + } + } +} + +@available(iOS 13.0, *) +private extension ApplicationTheme { + var userInterfaceStyle: UIUserInterfaceStyle { + switch self { + case .system: + return .unspecified + case .dark: + return .dark + case .light: + return .light + } + } +} diff --git a/Stepic/Sources/Modules/Explore/ContentLanguageSwitchAvailabilityService.swift b/Stepic/Sources/Services/ContentLanguageSwitchAvailabilityService.swift similarity index 100% rename from Stepic/Sources/Modules/Explore/ContentLanguageSwitchAvailabilityService.swift rename to Stepic/Sources/Services/ContentLanguageSwitchAvailabilityService.swift diff --git a/Stepic/Sources/Services/DataBackUpdateService.swift b/Stepic/Sources/Services/DataBackUpdateService.swift index 1c8fb9d022..227e205cb8 100644 --- a/Stepic/Sources/Services/DataBackUpdateService.swift +++ b/Stepic/Sources/Services/DataBackUpdateService.swift @@ -42,12 +42,12 @@ extension DataBackUpdateServiceDelegate { _ dataBackUpdateService: DataBackUpdateService, didReport update: DataBackUpdateDescription, for target: DataBackUpdateTarget - ) { } + ) {} func dataBackUpdateService( _ dataBackUpdateService: DataBackUpdateService, didReport refreshedTarget: DataBackUpdateTarget - ) { } + ) {} } protocol DataBackUpdateServiceProtocol: AnyObject { diff --git a/Stepic/Sources/Services/Managers/TooltipStorageManager.swift b/Stepic/Sources/Services/Managers/TooltipStorageManager.swift index d0480ee817..17ec8de46a 100644 --- a/Stepic/Sources/Services/Managers/TooltipStorageManager.swift +++ b/Stepic/Sources/Services/Managers/TooltipStorageManager.swift @@ -35,5 +35,5 @@ final class TooltipStorageManager: TooltipStorageManagerProtocol { } } - init() { } + init() {} } diff --git a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Provider/CourseListsCollectionNetworkService.swift b/Stepic/Sources/Services/Models/Network/CourseListsCollectionNetworkService.swift similarity index 100% rename from Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Provider/CourseListsCollectionNetworkService.swift rename to Stepic/Sources/Services/Models/Network/CourseListsCollectionNetworkService.swift diff --git a/Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Provider/CourseListsCollectionPersistenceService.swift b/Stepic/Sources/Services/Models/Persistence/CourseListsCollectionPersistenceService.swift similarity index 100% rename from Stepic/Sources/Modules/ExploreSubmodules/CourseListsCollection/Provider/CourseListsCollectionPersistenceService.swift rename to Stepic/Sources/Services/Models/Persistence/CourseListsCollectionPersistenceService.swift diff --git a/Stepic/Sources/Views/ContinueLastStepView/ContinueActionButton.swift b/Stepic/Sources/Views/ContinueLastStepView/ContinueActionButton.swift index 3888127d95..374d8f2856 100644 --- a/Stepic/Sources/Views/ContinueLastStepView/ContinueActionButton.swift +++ b/Stepic/Sources/Views/ContinueLastStepView/ContinueActionButton.swift @@ -8,7 +8,7 @@ extension ContinueActionButton { let defaultBackgroundColor = UIColor.white let defaultTitleColor = UIColor.stepikAccentFixed - let callToActionBackgroundColor = UIColor.stepikGreen + let callToActionBackgroundColor = UIColor.stepikGreenFixed let callToActionTitleColor = UIColor.white } } diff --git a/Stepic/Sources/Views/ContinueLastStepView/ContinueLastStepView.swift b/Stepic/Sources/Views/ContinueLastStepView/ContinueLastStepView.swift index ff1aa7214a..fb3c0e83a0 100644 --- a/Stepic/Sources/Views/ContinueLastStepView/ContinueLastStepView.swift +++ b/Stepic/Sources/Views/ContinueLastStepView/ContinueLastStepView.swift @@ -8,7 +8,7 @@ extension ContinueLastStepView { let cornerRadius: CGFloat = 8.0 let progressHeight: CGFloat = 3.0 - let progressFillColor = UIColor.stepikGreen + let progressFillColor = UIColor.stepikGreenFixed let progressBackgroundColor = UIColor.clear let lightModeBackgroundOverlayViewColor = UIColor.stepikAccentFixed.withAlphaComponent(0.85) @@ -165,12 +165,9 @@ final class ContinueLastStepView: UIView { private func updateViewColor() { self.progressView.progressTintColor = self.appearance.progressFillColor - - if #available(iOS 13.0, *), self.traitCollection.userInterfaceStyle == .dark { - self.overlayView.backgroundColor = self.appearance.darkModeBackgroundOverlayViewColor - } else { - self.overlayView.backgroundColor = self.appearance.lightModeBackgroundOverlayViewColor - } + self.overlayView.backgroundColor = self.isDarkInterfaceStyle + ? self.appearance.darkModeBackgroundOverlayViewColor + : self.appearance.lightModeBackgroundOverlayViewColor } @objc diff --git a/Stepic/Sources/Views/CourseRatingView.swift b/Stepic/Sources/Views/CourseRatingView.swift index f209e86c1d..0156767048 100644 --- a/Stepic/Sources/Views/CourseRatingView.swift +++ b/Stepic/Sources/Views/CourseRatingView.swift @@ -8,8 +8,8 @@ protocol CourseRatingViewDelegate: AnyObject { extension CourseRatingView { struct Appearance { - var starFilledColor = UIColor(hex6: 0x66cc66) - var statClearColor = UIColor.white + var starFilledColor = UIColor.stepikGreenFixed + var starClearColor = UIColor.white var starsSpacing: CGFloat = 5.0 var starsSize = CGSize(width: 10.5, height: 10.5) @@ -71,7 +71,7 @@ final class CourseRatingView: UIView { ? UIImage(named: "rating-star-filled") : UIImage(named: "rating-star-clear") let imageView = UIImageView(image: image?.withRenderingMode(.alwaysTemplate)) - imageView.tintColor = isFilled ? self.appearance.starFilledColor : self.appearance.statClearColor + imageView.tintColor = isFilled ? self.appearance.starFilledColor : self.appearance.starClearColor let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.starDidClick(_:))) imageView.isUserInteractionEnabled = true diff --git a/Stepic/Sources/Views/DownloadControlView.swift b/Stepic/Sources/Views/DownloadControlView.swift index 202661d55c..20f6615611 100644 --- a/Stepic/Sources/Views/DownloadControlView.swift +++ b/Stepic/Sources/Views/DownloadControlView.swift @@ -5,7 +5,7 @@ extension DownloadControlView { struct Appearance { let circleWidth: CGFloat = 2.8 - let downloadingCircleColor = UIColor.stepikGreen + let downloadingCircleColor = UIColor.stepikGreenFixed let downloadingBackgroundColor = UIColor.stepikAccentAlpha25 let pendingCircleColor = UIColor.stepikAccent diff --git a/Stepic/Sources/Views/ExploreBlockContainerView.swift b/Stepic/Sources/Views/ExploreBlockContainerView.swift index 5333e30aff..43c6a4955b 100644 --- a/Stepic/Sources/Views/ExploreBlockContainerView.swift +++ b/Stepic/Sources/Views/ExploreBlockContainerView.swift @@ -3,7 +3,7 @@ import UIKit extension ExploreBlockContainerView { struct Appearance { - let separatorColor = UIColor.stepikOpaqueSeparator + let separatorColor = UIColor.stepikSeparator var backgroundColor = UIColor.stepikBackground let headerViewInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20) diff --git a/Stepic/Sources/Views/HighlightFakeButton.swift b/Stepic/Sources/Views/HighlightFakeButton.swift index ef02e7cb02..4cb6cfaa65 100644 --- a/Stepic/Sources/Views/HighlightFakeButton.swift +++ b/Stepic/Sources/Views/HighlightFakeButton.swift @@ -3,7 +3,7 @@ import Foundation /// Class to implement highlight (button feedback) by color changing for any UIView /// Should be used instead of adding gesture recognizer for UIView instance final class HighlightFakeButton: UIButton { - var highlightedBackgroundColor = UIColor.white.withAlphaComponent(0.08) + var highlightedBackgroundColor = UIColor.stepikTertiaryBackground.withAlphaComponent(0.08) var defaultBackgroundColor = UIColor.clear override var isHighlighted: Bool { diff --git a/Stepic/Sources/Views/PlayNextCircleControlView.swift b/Stepic/Sources/Views/PlayNextCircleControlView.swift index 7abcf68133..4c030ff6fc 100644 --- a/Stepic/Sources/Views/PlayNextCircleControlView.swift +++ b/Stepic/Sources/Views/PlayNextCircleControlView.swift @@ -8,7 +8,7 @@ extension PlayNextCircleControlView { let iconImageTintColor = UIColor.white let circleWidth: CGFloat = 4 - let circleProgressColor = UIColor.stepikGreen + let circleProgressColor = UIColor.stepikGreenFixed let circleTrackColor = UIColor.white } } diff --git a/Stepic/Sources/Views/QuizElementView.swift b/Stepic/Sources/Views/QuizElementView.swift index 816b1cfd89..23c830e52d 100644 --- a/Stepic/Sources/Views/QuizElementView.swift +++ b/Stepic/Sources/Views/QuizElementView.swift @@ -87,26 +87,29 @@ final class QuizElementView: UIView { var borderColor: UIColor { switch self { case .default: - return UIColor(hex6: 0xCCCCCC) + return UIColor.stepikSeparator case .correct: - return UIColor(hex6: 0x66CC66).withAlphaComponent(0.5) + return UIColor.stepikGreen.withAlphaComponent(0.5) case .wrong: - return UIColor(hex6: 0xFF7965).withAlphaComponent(0.5) + return UIColor.stepikLightRed.withAlphaComponent(0.5) case .selected: - return UIColor(hex6: 0x6C7BDF).withAlphaComponent(0.5) + return UIColor.dynamic( + light: UIColor.stepikVioletFixed.withAlphaComponent(0.5), + dark: UIColor.stepikExtraLightVioletFixed.withAlphaComponent(0.5) + ) } } var backgroundColor: UIColor { switch self { case .default: - return UIColor.white + return .quizElementDefaultBackground case .correct: - return UIColor(hex6: 0xECF8EC) + return .quizElementCorrectBackground case .wrong: - return UIColor(hex6: 0xFFEFEC) + return .quizElementWrongBackground case .selected: - return UIColor(hex6: 0xEDEFFB) + return .dynamic(light: .stepikExtraLightVioletFixed, dark: .stepikTertiaryBackground) } } } diff --git a/Stepic/Sources/Views/SeparatorView.swift b/Stepic/Sources/Views/SeparatorView.swift index d749be8660..01a44ae2cb 100644 --- a/Stepic/Sources/Views/SeparatorView.swift +++ b/Stepic/Sources/Views/SeparatorView.swift @@ -6,7 +6,7 @@ extension SeparatorView { /// UITableView's default separator height. let height: CGFloat = 1.0 /// UITableView's default separator color. - let color = UIColor(hex6: 0xC8C7CC) + let color = UIColor.stepikSeparator } } diff --git a/Stepic/Sources/Views/StepikSocialNetworksView.swift b/Stepic/Sources/Views/StepikSocialNetworksView.swift index b6d428ee73..8e13adb7b4 100644 --- a/Stepic/Sources/Views/StepikSocialNetworksView.swift +++ b/Stepic/Sources/Views/StepikSocialNetworksView.swift @@ -5,7 +5,7 @@ extension StepikSocialNetworksView { struct Appearance { let backgroundColor = UIColor.clear - let titleTextColor = UIColor.stepikAccent + let titleTextColor = UIColor.stepikSystemPrimaryText let titleFont = UIFont.systemFont(ofSize: 14) let titleInsets = UIEdgeInsets(top: 24, left: 0, bottom: 0, right: 0) @@ -13,7 +13,7 @@ extension StepikSocialNetworksView { let stackViewInsets = UIEdgeInsets(top: 16, left: 16, bottom: 24, right: 16) let stackViewSpacing: CGFloat = 16 - let socialNetworkButtonBackgroundColor = UIColor.white + let socialNetworkButtonBackgroundColor = UIColor.stepikTertiaryBackground let socialNetworkButtonCornerRadius: CGFloat = 6 let socialNetworkButtonSize = CGSize(width: 44, height: 44) } diff --git a/Stepic/Sources/Views/StreakActivityView.swift b/Stepic/Sources/Views/StreakActivityView.swift index f00ccaee4b..3797031579 100644 --- a/Stepic/Sources/Views/StreakActivityView.swift +++ b/Stepic/Sources/Views/StreakActivityView.swift @@ -7,8 +7,10 @@ extension StreakActivityView { let iconInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 5) let descriptionInsets = UIEdgeInsets(top: 12, left: 22, bottom: 12, right: 10) - let lightModeBackgroundColor = UIColor.stepikLightBlue.withAlphaComponent(0.08) - let darkModeBackgroundColor = UIColor.stepikSecondaryBackground + let backgroundColor = UIColor.dynamic( + light: UIColor.stepikLightBlue.withAlphaComponent(0.08), + dark: .stepikSecondaryBackground + ) let cornerRadius: CGFloat = 8.0 let streakIconColor = UIColor.stepikAccent @@ -24,7 +26,7 @@ final class StreakActivityView: UIView { private lazy var backgroundView: UIView = { let view = UIView() - view.backgroundColor = self.appearance.lightModeBackgroundColor + view.backgroundColor = self.appearance.backgroundColor view.clipsToBounds = true view.layer.cornerRadius = self.appearance.cornerRadius return view @@ -87,7 +89,6 @@ final class StreakActivityView: UIView { self.appearance = appearance super.init(frame: frame) - self.setupView() self.addSubviews() self.makeConstraints() } @@ -101,29 +102,9 @@ final class StreakActivityView: UIView { super.layoutSubviews() self.invalidateIntrinsicContentSize() } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - super.traitCollectionDidChange(previousTraitCollection) - - self.performBlockIfAppearanceChanged(from: previousTraitCollection) { - self.updateViewColor() - } - } - - private func updateViewColor() { - if #available(iOS 13.0, *), self.traitCollection.userInterfaceStyle == .dark { - self.backgroundView.backgroundColor = self.appearance.darkModeBackgroundColor - } else { - self.backgroundView.backgroundColor = self.appearance.lightModeBackgroundColor - } - } } extension StreakActivityView: ProgrammaticallyInitializableViewProtocol { - func setupView() { - self.updateViewColor() - } - func addSubviews() { self.addSubview(self.backgroundView) self.backgroundView.addSubview(self.iconStackView) diff --git a/Stepic/Sources/Views/TabSegmentedControlView.swift b/Stepic/Sources/Views/TabSegmentedControlView.swift index be55fa1833..14eba2d09e 100644 --- a/Stepic/Sources/Views/TabSegmentedControlView.swift +++ b/Stepic/Sources/Views/TabSegmentedControlView.swift @@ -10,14 +10,14 @@ protocol TabSegmentedControlViewDelegate: AnyObject { extension TabSegmentedControlView { struct Appearance { - let backgroundColor = UIColor.stepikBackground + let backgroundColor = UIColor.stepikNavigationBarBackground let buttonInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20) let buttonTitleFontNormal = UIFont.systemFont(ofSize: 15, weight: .light) let buttonTitleFontSelected = UIFont.systemFont(ofSize: 15) - let buttonTitleColor = UIColor.stepikAccent + let buttonTitleColor = UIColor.stepikPrimaryText - let bottomBorderColor = UIColor(hex6: 0x9b9b9b) + let bottomBorderColor = UIColor.stepikSeparator let bottomBorderHeight: CGFloat = 0.5 let bottomSelectedMarkerColor = UIColor.stepikAccent diff --git a/Stepic/Sources/Views/TableInputTextField.swift b/Stepic/Sources/Views/TableInputTextField.swift index 469868b38b..8ae95be94f 100644 --- a/Stepic/Sources/Views/TableInputTextField.swift +++ b/Stepic/Sources/Views/TableInputTextField.swift @@ -20,7 +20,7 @@ class TableInputTextField: UITextField { return 0 } - var placeholderColor = UIColor.black.withAlphaComponent(0.4) + var placeholderColor = UIColor.stepikSystemPlaceholderText var textInsets = Appearance.textAreaInsets { didSet { diff --git a/Stepic/Sources/Views/TableInputTextView.swift b/Stepic/Sources/Views/TableInputTextView.swift index f1ea2f3269..651e04d927 100644 --- a/Stepic/Sources/Views/TableInputTextView.swift +++ b/Stepic/Sources/Views/TableInputTextView.swift @@ -40,7 +40,7 @@ final class TableInputTextView: UITextView { } } - var placeholderColor = UIColor.black.withAlphaComponent(0.4) { + var placeholderColor = UIColor.stepikSystemPlaceholderText { didSet { self.placeholderLabel.textColor = self.placeholderColor } @@ -95,6 +95,7 @@ final class TableInputTextView: UITextView { self.isScrollEnabled = false + self.backgroundColor = .clear self.font = Appearance.defaultFont if self.placeholderLabel.superview == nil { diff --git a/Stepic/Theme/ColorPalette.swift b/Stepic/Theme/ColorPalette.swift index a49cc34bd7..d770f11707 100644 --- a/Stepic/Theme/ColorPalette.swift +++ b/Stepic/Theme/ColorPalette.swift @@ -1,12 +1,15 @@ import UIKit extension UIColor { - // MARK: - Brand Colors - + // MARK: - Standard Colors - + // The standard color objects for specific shades, such as red, blue, green, black, white, and more. + // MARK: - Stepik Standard Colors // MARK: Green + /// Adaptable color with base hex value #66CC66 (green01). static var stepikGreen: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.green400, dark: ColorPalette.green300, lightAccessibility: ColorPalette.green500, @@ -14,8 +17,9 @@ extension UIColor { ) } + /// Adaptable color with base hex value #E9F9E9 (green06). static var stepikLightGreen: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.lightGreen50, dark: ColorPalette.lightGreen50, lightAccessibility: ColorPalette.lightGreen200, @@ -23,8 +27,9 @@ extension UIColor { ) } + /// Adaptable color with base hex value #54AD54 (green03). static var stepikDarkGreen: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.darkGreen500, dark: ColorPalette.darkGreen300, lightAccessibility: ColorPalette.darkGreen600, @@ -32,10 +37,18 @@ extension UIColor { ) } + /// A non adaptable color with hex value #66CC66. + static let stepikGreenFixed = ColorPalette.green400 + /// A non adaptable color with hex value #E9F9E9. + static let stepikLightGreenFixed = ColorPalette.lightGreen50 + /// A non adaptable color with hex value #54AD54. + static let stepikDarkGreenFixed = ColorPalette.darkGreen500 + // MARK: Red + /// Adaptable color with base hex value #D41F1F (red00). static var stepikRed: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.red700, dark: ColorPalette.red300, lightAccessibility: ColorPalette.red800, @@ -43,19 +56,38 @@ extension UIColor { ) } + /// Adaptable color with base hex value #FF7965 (red01). static var stepikLightRed: UIColor { - UIColor.dynamicColor( - light: ColorPalette.lightRed50, - dark: ColorPalette.lightRed50, - lightAccessibility: ColorPalette.lightRed200, - darkAccessibility: ColorPalette.lightRed200 + .dynamic( + light: ColorPalette.lightRed300, + dark: ColorPalette.lightRed200, + lightAccessibility: ColorPalette.lightRed400, + darkAccessibility: ColorPalette.lightRed100 ) } + /// Adaptable color with base hex value #FFEBE8 (red02). + static var stepikExtraLightRed: UIColor { + .dynamic( + light: ColorPalette.extraLightRed50, + dark: ColorPalette.extraLightRed50, + lightAccessibility: ColorPalette.extraLightRed200, + darkAccessibility: ColorPalette.extraLightRed200 + ) + } + + /// A non adaptable color with hex value #D41F1F (red00). + static let stepikRedFixed = ColorPalette.red700 + /// A non adaptable color with hex value #FF7965 (red01). + static let stepikLightRedFixed = ColorPalette.lightRed300 + /// A non adaptable color with hex value #FFEBE8 (red02). + static let stepikExtraLightRedFixed = ColorPalette.extraLightRed50 + // MARK: Blue + /// Adaptable color with base hex value #4485ED (blue05). static var stepikBlue: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.blue600, dark: ColorPalette.blue300, lightAccessibility: ColorPalette.blue700, @@ -63,8 +95,9 @@ extension UIColor { ) } + /// Adaptable color with base hex value #56A4FF (blue03). static var stepikLightBlue: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.lightBlue400, dark: ColorPalette.lightBlue300, lightAccessibility: ColorPalette.lightBlue500, @@ -72,10 +105,16 @@ extension UIColor { ) } + /// A non adaptable color with hex value #4485ED (blue05). + static let stepikBlueFixed = ColorPalette.blue600 + /// A non adaptable color with hex value #56A4FF (blue03). + static let stepikLightBlueFixed = ColorPalette.lightBlue400 + // MARK: Yellow + /// Adaptable color with base hex value #FEDB41 (yellow02). static var stepikYellow: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.yellow600, dark: ColorPalette.yellow300, lightAccessibility: ColorPalette.yellow700, @@ -83,23 +122,39 @@ extension UIColor { ) } + /// A non adaptable color with hex value #FEDB41 (yellow02). + static let stepikYellowFixed = ColorPalette.yellow600 + // MARK: Grey + /// Adaptable color with base hex value #F6F6F6 (grey07). static var stepikGrey: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.grey100, dark: ColorPalette.grey050, lightAccessibility: ColorPalette.grey200 ) } - // MARK: Accent + /// A non adaptable color with hex value #F6F6F6 (grey07). + static let stepikGreyFixed = ColorPalette.grey100 + + // MARK: Violet + + /// A non adaptable color with hex value #6C7BDF (violet01). + static let stepikVioletFixed = ColorPalette.violet01 + /// A non adaptable color with hex value #9CA6E6 (violet03). + static let stepikLightVioletFixed = ColorPalette.violet03 + /// A non adaptable color with hex value #E9EBFA (violet02). + static let stepikExtraLightVioletFixed = ColorPalette.violet02 + /// A non adaptable color with hex value #3E50CB (violet04). + static let stepikDarkVioletFixed = ColorPalette.violet04 - /// A non adaptable color with hex value #535366. - static var stepikAccentFixed: UIColor { ColorPalette.accent700 } + // MARK: Accent (grey06) + /// Adaptable color with base hex value #535366 (grey06). static var stepikAccent: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.accent700, dark: ColorPalette.accent300, lightAccessibility: ColorPalette.accent800, @@ -107,26 +162,19 @@ extension UIColor { ) } - static var stepikAccentAlpha85: UIColor { - UIColor.dynamicColor( - light: ColorPalette.accent700Alpha85, - dark: ColorPalette.accent300Alpha85, - lightAccessibility: ColorPalette.accent800Alpha85, - darkAccessibility: ColorPalette.accent200Alpha85 - ) - } - - static var stepikAccentAlpha70: UIColor { - UIColor.dynamicColor( - light: ColorPalette.accent700Alpha70, - dark: ColorPalette.accent300Alpha70, - lightAccessibility: ColorPalette.accent800Alpha70, - darkAccessibility: ColorPalette.accent200Alpha70 + /// Adaptable color with base hex value #535366 and the opacity value of the 0.60 (grey06). + static var stepikAccentAlpha60: UIColor { + .dynamic( + light: ColorPalette.accent700Alpha60, + dark: ColorPalette.accent300Alpha60, + lightAccessibility: ColorPalette.accent800Alpha60, + darkAccessibility: ColorPalette.accent200Alpha60 ) } + /// Adaptable color with base hex value #535366 and the opacity value of the 0.50 (grey06). static var stepikAccentAlpha50: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.accent700Alpha50, dark: ColorPalette.accent300Alpha50, lightAccessibility: ColorPalette.accent800Alpha50, @@ -134,8 +182,9 @@ extension UIColor { ) } + /// Adaptable color with base hex value #535366 and the opacity value of the 0.40 (grey06). static var stepikAccentAlpha40: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.accent700Alpha40, dark: ColorPalette.accent300Alpha40, lightAccessibility: ColorPalette.accent800Alpha40, @@ -143,8 +192,9 @@ extension UIColor { ) } + /// Adaptable color with base hex value #535366 and the opacity value of the 0.30 (grey06). static var stepikAccentAlpha30: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.accent700Alpha30, dark: ColorPalette.accent300Alpha30, lightAccessibility: ColorPalette.accent800Alpha30, @@ -152,8 +202,9 @@ extension UIColor { ) } + /// Adaptable color with base hex value #535366 and the opacity value of the 0.25 (grey06). static var stepikAccentAlpha25: UIColor { - UIColor.dynamicColor( + .dynamic( light: ColorPalette.accent700Alpha25, dark: ColorPalette.accent300Alpha25, lightAccessibility: ColorPalette.accent800Alpha25, @@ -161,21 +212,50 @@ extension UIColor { ) } - static var stepikAccentAlpha06: UIColor { - UIColor.dynamicColor( - light: ColorPalette.accent700Alpha06, - dark: ColorPalette.accent300Alpha06, - lightAccessibility: ColorPalette.accent800Alpha06, - darkAccessibility: ColorPalette.accent200Alpha06 + /// Adaptable color with base hex value #535366 and the opacity value of the 0.18 (grey06). + static var stepikAccentAlpha18: UIColor { + .dynamic( + light: ColorPalette.accent700Alpha18, + dark: ColorPalette.accent300Alpha18, + lightAccessibility: ColorPalette.accent800Alpha18, + darkAccessibility: ColorPalette.accent200Alpha18 ) } + /// A non adaptable color with hex value #535366 (grey06). + static let stepikAccentFixed = ColorPalette.accent700 + /// A non adaptable color with hex value #282B41 (darkblue01). + static let stepikDarkAccentFixed = ColorPalette.darkAccent900 + /// A non adaptable color with hex value #222437 (darkblue02). + static let stepikExtraDarkAccentFixed = ColorPalette.extraDarkAccent900 + + // MARK: - System Standard Colors + + /// The base gray color. + static var stepikSystemGray: UIColor { + if #available(iOS 13.0, *) { + return .systemGray + } else { + return UIColor(hex6: 0x8E8E93) + } + } + + /// A second-level shade of grey. + static var stepikSystemGray2: UIColor { + if #available(iOS 13.0, *) { + return .systemGray2 + } else { + return UIColor(hex6: 0xAEAEB2) + } + } + // MARK: - UI Element Colors - + // The standard color objects for labels, text, backgrounds, links, and more. /// The color for thin borders or divider lines that allows some underlying content to be visible. static var stepikSeparator: UIColor { if #available(iOS 13.0, *) { - return UIColor.separator + return .separator } else { return UIColor(hex8: 0x99545458) } @@ -184,15 +264,50 @@ extension UIColor { /// The color for borders or divider lines that hides any underlying content. static var stepikOpaqueSeparator: UIColor { if #available(iOS 13.0, *) { - return UIColor.opaqueSeparator + return .opaqueSeparator } else { return UIColor(hex6: 0xC8C7CC) } } - /// The color for text labels that contain primary content. - /// Black in light mode and white in dark mode. - static var stepikSystemLabel: UIColor { + /// A non adaptable color for shadow views with hex value #EAECF0 (grey04). + static let stepikShadowFixed = ColorPalette.grey04 + + /// The color for activity indicators. + static var stepikLoadingIndicator: UIColor { .stepikAccent } + + /// The color used to tint the appearance of the switch when it is turned on. + static var stepikSwitchOnTint: UIColor { + if #available(iOS 13.0, *) { + return UIColor { (traitCollection: UITraitCollection) -> UIColor in + traitCollection.userInterfaceStyle == .dark && traitCollection.userInterfaceLevel == .elevated + ? .stepikAccentFixed + : .stepikAccent + } + } else { + return .stepikAccentFixed + } + } + + // MARK: Text Colors + + /// The color for texts that contain primary content. + static var stepikPrimaryText: UIColor { .stepikAccent } + + /// The color for texts that contain secondary content. + static var stepikSecondaryText: UIColor { .stepikAccentAlpha60 } + + /// The color for texts that contain tertiary content. + static var stepikTertiaryText: UIColor { .stepikAccentAlpha30 } + + /// The color for texts that contain quaternary content. + static var stepikQuaternaryText: UIColor { .stepikAccentAlpha18 } + + /// The color for placeholder text in controls or text views. + static var stepikPlaceholderText: UIColor { .stepikAccentAlpha40 } + + /// The system color for text labels that contain primary content. + static var stepikSystemPrimaryText: UIColor { if #available(iOS 13.0, *) { return .label } else { @@ -200,8 +315,8 @@ extension UIColor { } } - /// The color for text labels that contain secondary content. - static var stepikSystemSecondaryLabel: UIColor { + /// The system color for text labels that contain secondary content. + static var stepikSystemSecondaryText: UIColor { if #available(iOS 13.0, *) { return .secondaryLabel } else { @@ -209,8 +324,8 @@ extension UIColor { } } - /// The color for text labels that contain tertiary content. - static var stepikSystemTertiaryLabel: UIColor { + /// The system color for text labels that contain tertiary content. + static var stepikSystemTertiaryText: UIColor { if #available(iOS 13.0, *) { return .tertiaryLabel } else { @@ -218,8 +333,8 @@ extension UIColor { } } - /// The color for text labels that contain quaternary content. - static var stepikSystemQuaternaryLabel: UIColor { + /// The system color for text labels that contain quaternary content. + static var stepikSystemQuaternaryText: UIColor { if #available(iOS 13.0, *) { return .quaternaryLabel } else { @@ -227,18 +342,40 @@ extension UIColor { } } - /// The color for activity indicators. - static var stepikLoadingIndicator: UIColor { .stepikAccent } + /// The system color for placeholder text in controls or text views. + static var stepikSystemPlaceholderText: UIColor { + if #available(iOS 13.0, *) { + return .placeholderText + } else { + return UIColor(hex8: 0x4C3C3C43) + } + } - // MARK: Text Colors + // MARK: Other Text Colors - /// The color for texts that contain primary content. - static var stepikPrimaryText: UIColor { .stepikAccent } + /// The color for texts that calls to action (join course, sign in...). + static var stepikCallToActionText: UIColor { .stepikGreen } - /// The color for placeholder text in controls or text views. - static var stepikPlaceholderText: UIColor { .stepikAccentAlpha40 } + static var stepikGradientCoursesBluePlaceholderText: UIColor { + .dynamic( + light: ColorPalette.gradientCoursesBlue900, + dark: ColorPalette.gradientCoursesBlue200, + lightAccessibility: ColorPalette.gradientCoursesBlue900, + darkAccessibility: ColorPalette.gradientCoursesBlue100 + ) + } + + static var stepikGradientCoursesPinkPlaceholderText: UIColor { + .dynamic( + light: ColorPalette.gradientCoursesPink900, + dark: ColorPalette.gradientCoursesPink200, + lightAccessibility: ColorPalette.gradientCoursesPink900, + darkAccessibility: ColorPalette.gradientCoursesPink100 + ) + } // MARK: Standard Content Background Colors + // Colors for standard table views and designs that have a white primary background in a light environment. /// The color for the main background of the interface. static var stepikBackground: UIColor { @@ -260,15 +397,7 @@ extension UIColor { /// The color for content layered on top of the main background. static var stepikLightSecondaryBackground: UIColor { - if #available(iOS 13.0, *) { - return UIColor { (traitCollection: UITraitCollection) -> UIColor in - return traitCollection.userInterfaceStyle == .dark - ? .stepikSecondaryBackground - : ColorPalette.grey100 - } - } else { - return ColorPalette.grey100 - } + .dynamic(light: ColorPalette.grey100, dark: .stepikSecondaryBackground) } /// The color for content layered on top of secondary backgrounds. @@ -280,8 +409,11 @@ extension UIColor { } } - /// The color to use for the background of a grouped table. - static var stepikGroupTableViewBackground: UIColor { + // MARK: Grouped Content Background Colors + // Colors for grouped content, including table views and platter-based designs. + + /// The color for the main background of grouped interface. + static var stepikGroupedBackground: UIColor { if #available(iOS 13.0, *) { return .systemGroupedBackground } else { @@ -289,34 +421,88 @@ extension UIColor { } } - /// The color to use for the background of a alert. - static var stepikAlertBackground: UIColor { + /// The color for content layered on top of the main background of grouped interface. + static var stepikSecondaryGroupedBackground: UIColor { if #available(iOS 13.0, *) { - return .secondarySystemBackground + return .secondarySystemGroupedBackground } else { return .white } } - // MARK: Standard Colors - - /// The base gray color. - static var stepikGray: UIColor { + /// The color for content layered on top of secondary backgrounds of grouped interface. + static var stepikTertiaryGroupedBackground: UIColor { if #available(iOS 13.0, *) { - return .systemGray + return .tertiarySystemGroupedBackground } else { - return UIColor(hex6: 0x8E8E93) + return UIColor(hex6: 0xF2F2F7) } } - /// A second-level shade of grey. - static var stepikGray2: UIColor { + // MARK: Other Content Background Colors + + /// The color to use for the background of a navigation bar. + static var stepikNavigationBarBackground: UIColor { + .dynamic(light: ColorPalette.grey100, dark: UIColor(hex6: 0x121212)) + } + + /// The color to use for the background of a tab bar. + static var stepikTabBarBackground: UIColor { .stepikNavigationBarBackground } + + /// The color to use for the background of a alert. + static var stepikAlertBackground: UIColor { if #available(iOS 13.0, *) { - return .systemGray2 + return .secondarySystemBackground } else { - return UIColor(hex6: 0xAEAEB2) + return .white } } + + /// The color to use for the call to action background (join course, sign in...). + static var stepikCallToActionBackground: UIColor { UIColor.stepikGreen.withAlphaComponent(0.1) } + + /// The color to use for the content overlay (intro video overlay). + static var stepikOverlayBackground: UIColor { + .dynamic(light: .stepikAccentAlpha40, dark: UIColor.stepikSecondaryBackground.withAlphaComponent(0.4)) + } + + // MARK: - Skeleton Gradient - + + static var skeletonGradientFirst: UIColor { + .dynamic(light: ColorPalette.grey100, dark: .stepikSecondaryBackground) + } + + static var skeletonGradientSecond: UIColor { + .dynamic(light: UIColor(hex6: 0xE7E7E7), dark: .stepikTertiaryBackground) + } + + static var skeletonGradientThird: UIColor { + .dynamic(light: ColorPalette.grey100, dark: .stepikSecondaryBackground) + } + + // MARK: - Quizzes - + + static var quizElementDefaultBackground: UIColor { + .dynamic(light: .stepikBackground, dark: .stepikSecondaryBackground) + } + + static var quizElementCorrectBackground: UIColor { + .dynamic(light: .stepikLightGreen, dark: .stepikCallToActionBackground) + } + + static var quizElementWrongBackground: UIColor { + .dynamic( + light: UIColor.stepikLightRed.withAlphaComponent(0.15), + dark: UIColor.stepikRed.withAlphaComponent(0.1) + ) + } + + static var quizElementEvaluationBackground: UIColor { + .dynamic( + light: .stepikExtraLightVioletFixed, + dark: UIColor.stepikExtraLightVioletFixed.withAlphaComponent(0.1) + ) + } } // MARK: - ColorPalette - @@ -324,6 +510,8 @@ extension UIColor { private enum ColorPalette { // MARK: - Accent Color - + // MARK: Normal (grey06 #535366) + /// Color to use in light/unspecified mode and with a high contrast level. static let accent800 = UIColor(hex6: 0x353547) /// Color to use in light/unspecified mode and with a normal/unspecified contrast level. @@ -333,27 +521,16 @@ private enum ColorPalette { /// Color to use in dark mode and with a high contrast level. static let accent200 = UIColor(hex6: 0xE4E4FA) - // MARK: Alpha 85 + // MARK: Alpha 60 - /// Color to use in light/unspecified mode and with a high contrast level, and with alpha component 85. - static let accent800Alpha85 = UIColor(hex8: 0xD9353547) - /// Color to use in light/unspecified mode and with a normal/unspecified contrast level, and with alpha component 85. - static let accent700Alpha85 = UIColor(hex8: 0xD9535366) - /// Color to use in dark mode and with a normal/unspecified contrast level, and with alpha component 85. - static let accent300Alpha85 = UIColor(hex8: 0xD9D3D2E9) - /// Color to use in dark mode and with a high contrast level, and with alpha component 85. - static let accent200Alpha85 = UIColor(hex8: 0xD9E4E4FA) - - // MARK: Alpha 70 - - /// Color to use in light/unspecified mode and with a high contrast level, and with alpha component 70. - static let accent800Alpha70 = UIColor(hex8: 0xB3353547) - /// Color to use in light/unspecified mode and with a normal/unspecified contrast level, and with alpha component 70. - static let accent700Alpha70 = UIColor(hex8: 0xB3535366) - /// Color to use in dark mode and with a normal/unspecified contrast level, and with alpha component 70. - static let accent300Alpha70 = UIColor(hex8: 0xB3D3D2E9) - /// Color to use in dark mode and with a high contrast level, and with alpha component 70. - static let accent200Alpha70 = UIColor(hex8: 0xB3E4E4FA) + /// Color to use in light/unspecified mode and with a high contrast level, and with alpha component 60. + static let accent800Alpha60 = UIColor(hex8: 0x99353547) + /// Color to use in light/unspecified mode and with a normal/unspecified contrast level, and with alpha component 60. + static let accent700Alpha60 = UIColor(hex8: 0x99535366) + /// Color to use in dark mode and with a normal/unspecified contrast level, and with alpha component 60. + static let accent300Alpha60 = UIColor(hex8: 0x99D3D2E9) + /// Color to use in dark mode and with a high contrast level, and with alpha component 60. + static let accent200Alpha60 = UIColor(hex8: 0x99E4E4FA) // MARK: Alpha 50 @@ -399,16 +576,24 @@ private enum ColorPalette { /// Color to use in dark mode and with a high contrast level, and with alpha component 25. static let accent200Alpha25 = UIColor(hex8: 0x40E4E4FA) - // MARK: Alpha 6 + // MARK: Alpha 18 + + /// Color to use in light/unspecified mode and with a high contrast level, and with alpha component 18. + static let accent800Alpha18 = UIColor(hex8: 0x2E353547) + /// Color to use in light/unspecified mode and with a normal/unspecified contrast level, and with alpha component 18. + static let accent700Alpha18 = UIColor(hex8: 0x2E535366) + /// Color to use in dark mode and with a normal/unspecified contrast level, and with alpha component 18. + static let accent300Alpha18 = UIColor(hex8: 0x2ED3D2E9) + /// Color to use in dark mode and with a high contrast level, and with alpha component 18. + static let accent200Alpha18 = UIColor(hex8: 0x2EE4E4FA) + + // MARK: Dark (darkblue01 #282B41) + + static let darkAccent900 = UIColor(hex6: 0x282B41) - /// Color to use in light/unspecified mode and with a high contrast level, and with alpha component 6. - static let accent800Alpha06 = UIColor(hex8: 0x0F353547) - /// Color to use in light/unspecified mode and with a normal/unspecified contrast level, and with alpha component 6. - static let accent700Alpha06 = UIColor(hex8: 0x0F535366) - /// Color to use in dark mode and with a normal/unspecified contrast level, and with alpha component 6. - static let accent300Alpha06 = UIColor(hex8: 0x0FD3D2E9) - /// Color to use in dark mode and with a high contrast level, and with alpha component 6. - static let accent200Alpha06 = UIColor(hex8: 0x0FE4E4FA) + // MARK: Extra Dark (darkblue02 #222437) + + static let extraDarkAccent900 = UIColor(hex6: 0x222437) // MARK: - Red - @@ -423,12 +608,23 @@ private enum ColorPalette { /// Color to use in dark mode and with a high contrast level. static let red200 = UIColor(hex6: 0xF19693) - // MARK: Light + // MARK: Light (red01) /// Color to use in light/unspecified mode and with a high contrast level. - static let lightRed200 = UIColor(hex6: 0xFFB596) - /// Color to use in light/unspecified mode and with a normal/unspecified contrast level. - static let lightRed50 = UIColor(hex6: 0xFFEBE8) + static let lightRed400 = UIColor(hex6: 0xFF5945) + /// Color to use in light/unspecified mode and with a normal/unspecified contrast level (red01). + static let lightRed300 = UIColor(hex6: 0xFF7965) + /// Color to use in dark mode and with a normal/unspecified contrast level. + static let lightRed200 = UIColor(hex6: 0xFFA190) + /// Color to use in dark mode and with a high contrast level. + static let lightRed100 = UIColor(hex6: 0xFFC6BB) + + // MARK: Extra Light (red02) + + /// Color to use in light/unspecified mode and with a high contrast level. + static let extraLightRed200 = UIColor(hex6: 0xFFB596) + /// Color to use in light/unspecified mode and with a normal/unspecified contrast level (red02). + static let extraLightRed50 = UIColor(hex6: 0xFFEBE8) // MARK: - Blue - @@ -500,8 +696,33 @@ private enum ColorPalette { /// Color to use in light/unspecified mode and with a high contrast level. static let grey200 = UIColor(hex6: 0xF0F0F0) - /// Color to use in light/unspecified mode and with a normal/unspecified contrast level. + /// Color to use in light/unspecified mode and with a normal/unspecified contrast level (grey07). static let grey100 = UIColor(hex6: 0xF6F6F6) /// Color to use in dark mode and with a normal/unspecified contrast level. static let grey050 = UIColor(hex6: 0xFAFAFA) + + static let grey04 = UIColor(hex6: 0xEAECF0) + + // MARK: - Violet - + + static let violet01 = UIColor(hex6: 0x6C7BDF) + static let violet02 = UIColor(hex6: 0xE9EBFA) + static let violet03 = UIColor(hex6: 0x9CA6E6) + static let violet04 = UIColor(hex6: 0x3E50CB) + + // MARK: - Gradient Courses - + + /// Color to use in light/unspecified mode and with a normal/unspecified contrast level. + static let gradientCoursesBlue900 = UIColor(hex6: 0x00484E) + /// Color to use in dark mode and with a normal/unspecified contrast level. + static let gradientCoursesBlue200 = UIColor(hex6: 0x77CDDE) + /// Color to use in dark mode and with a high contrast level. + static let gradientCoursesBlue100 = UIColor(hex6: 0xACE1EB) + + /// Color to use in light/unspecified mode and with a normal/unspecified contrast level. + static let gradientCoursesPink900 = UIColor(hex6: 0x18073D) + /// Color to use in dark mode and with a normal/unspecified contrast level. + static let gradientCoursesPink200 = UIColor(hex6: 0x9492B5) + /// Color to use in dark mode and with a high contrast level. + static let gradientCoursesPink100 = UIColor(hex6: 0xBEBDD3) } diff --git a/Stepic/en.lproj/Localizable.strings b/Stepic/en.lproj/Localizable.strings index 918ec36adb..196279fc25 100644 --- a/Stepic/en.lproj/Localizable.strings +++ b/Stepic/en.lproj/Localizable.strings @@ -546,6 +546,7 @@ LoadStories = "Load stories"; /* Settings */ SettingsTitle = "Settings"; SettingsHeaderTitleVideo = "Video"; +SettingsHeaderTitleAppearance = "Appearance"; SettingsHeaderTitleLanguage = "Language"; SettingsHeaderTitleLearning = "Learning"; SettingsHeaderTitleDownloadedContent = "Downloaded content"; @@ -554,6 +555,7 @@ SettingsHeaderTitleOther = "Other"; SettingsCellTitleDownloadQuality = "Download quality"; SettingsCellTitleStreamQuality = "Stream quality"; SettingsCellTitleUseCellularDataForDownloads = "Use cellular data for downloads"; +SettingsCellTitleTheme = "Theme"; SettingsCellTitleContentLanguage = "Content language"; SettingsCellTitleTextSizeInSteps = "Text size in steps"; SettingsCellTitleCodeEditor = "Code editor settings"; @@ -581,6 +583,11 @@ SettingStreamVideoQualityVeryHigh = "Very high"; SettingsContentLanguageTitle = "Content language"; SettingsContentLanguageFooterTitle = "The language of displayed courses."; +SettingsThemeTitle = "Theme"; +SettingsThemeItemSystem = "System"; +SettingsThemeItemDark = "Dark"; +SettingsThemeItemLight = "Light"; + SettingsStepFontSizeTitle = "Text size"; SettingsStepFontSizeFooterTitle = "Text size changes affect only step text"; SettingsStepFontSizeItemSmall = "Small"; @@ -721,7 +728,7 @@ ProfileEditLastNamePlaceholder = "Last name"; ProfileEditShortBioPlaceholder = "Short bio (255 chars max)"; ProfileEditDetailsPlaceholder = "About"; ProfileEditGeneralTitle = "General"; -ProfileEditGeneralDescription = "Your legal names, used for any certificates"; +ProfileEditGeneralDescription = "Your legal names, used for any certificates."; ProfileEditAboutMeTitle = "About me"; ProfileEditEmailTitle = "Email"; ProfileEditEmailPlaceholder = "Address"; diff --git a/Stepic/ru.lproj/Localizable.strings b/Stepic/ru.lproj/Localizable.strings index 3bb60ca6ba..4242866b1a 100644 --- a/Stepic/ru.lproj/Localizable.strings +++ b/Stepic/ru.lproj/Localizable.strings @@ -547,6 +547,7 @@ LoadStories = "Загрузить истории"; /* Settings */ SettingsTitle = "Настройки"; SettingsHeaderTitleVideo = "Видео"; +SettingsHeaderTitleAppearance = "Оформление"; SettingsHeaderTitleLanguage = "Язык"; SettingsHeaderTitleLearning = "Обучение"; SettingsHeaderTitleDownloadedContent = "Загруженный контент"; @@ -555,6 +556,7 @@ SettingsHeaderTitleOther = "Другое"; SettingsCellTitleDownloadQuality = "Качество загрузки"; SettingsCellTitleStreamQuality = "Качество воспроизведения"; SettingsCellTitleUseCellularDataForDownloads = "Использовать сотовые данные для загрузки"; +SettingsCellTitleTheme = "Тема"; SettingsCellTitleContentLanguage = "Язык контента"; SettingsCellTitleTextSizeInSteps = "Размер текста в шагах"; SettingsCellTitleCodeEditor = "Настройки редактора кода"; @@ -582,6 +584,11 @@ SettingStreamVideoQualityVeryHigh = "Максимальное"; SettingsContentLanguageTitle = "Язык контента"; SettingsContentLanguageFooterTitle = "Выберите язык на котором вы будете видеть в приложении курсы."; +SettingsThemeTitle = "Тема"; +SettingsThemeItemSystem = "Системная"; +SettingsThemeItemDark = "Тёмная"; +SettingsThemeItemLight = "Светлая"; + SettingsStepFontSizeTitle = "Размер текста"; SettingsStepFontSizeFooterTitle = "Изменения размера текста влияют только на текст шага."; SettingsStepFontSizeItemSmall = "Маленький"; @@ -722,7 +729,7 @@ ProfileEditLastNamePlaceholder = "Фамилия"; ProfileEditShortBioPlaceholder = "Краткая биография (до 255 символов)"; ProfileEditDetailsPlaceholder = "Обо мне"; ProfileEditGeneralTitle = "Общие данные"; -ProfileEditGeneralDescription = "Ваше официальное имя, используемое в сертификатах"; +ProfileEditGeneralDescription = "Ваше официальное имя, используемое в сертификатах."; ProfileEditAboutMeTitle = "О себе"; ProfileEditEmailTitle = "Email"; ProfileEditEmailPlaceholder = "Адрес"; @@ -903,7 +910,7 @@ DiscussionsAlertActionUnlikeTitle = "Больше не нравится"; DiscussionsAlertActionAbuseTitle = "Пожаловаться"; DiscussionsAlertActionUnabuseTitle = "Не жаловаться"; DiscussionsAlertActionShowSolutionTitle = "Показать решение"; -DiscussionsSortTypeAlertTitle = "Сортировать по"; +DiscussionsSortTypeAlertTitle = "Сортировка:"; DiscussionsSortTypeLastDiscussions = "Новые обсуждения"; DiscussionsSortTypeMostLikedDiscussions = "Самые популярные"; DiscussionsSortTypeMostActiveDiscussions = "Самые обсуждаемые"; diff --git a/Stepic/stepikcontent.css b/Stepic/stepikcontent.css index ff771fd31d..1be4117be6 100644 --- a/Stepic/stepikcontent.css +++ b/Stepic/stepikcontent.css @@ -1,4 +1,5 @@ :root { + color-scheme: light dark; --textColor: #535366; --body-font-size: 12pt; --h1-font-size: 20pt; @@ -7,6 +8,12 @@ --blockquote-font-size: 16px; } +@media screen and (prefers-color-scheme: dark) { + :root { + --textColor: #D3D2E9; + } +} + html { -webkit-text-size-adjust: 100%; } diff --git a/Stepic/wysiwyg.css b/Stepic/wysiwyg.css index b7641341f3..57bcb3da47 100644 --- a/Stepic/wysiwyg.css +++ b/Stepic/wysiwyg.css @@ -1,3 +1,13 @@ +:root { + color-scheme: light dark; + --hljs-background-color: #FDF6E3; +} + +@media screen and (prefers-color-scheme: dark) { + :root { + --hljs-background-color: #161613; + } +} .wysiwyg-color-red { color: #ff4363; @@ -93,7 +103,7 @@ display: block; overflow-x: auto; padding: .5em; - background: #FDF6E3; + background: var(--hljs-background-color); color: #657B83; -webkit-text-size-adjust: none; -webkit-font-smoothing: antialiased; diff --git a/StepicTests/DownloaderTests.swift b/StepicTests/DownloaderTests.swift index 14e6a02cb3..7a29ca9231 100644 --- a/StepicTests/DownloaderTests.swift +++ b/StepicTests/DownloaderTests.swift @@ -150,7 +150,7 @@ class DownloaderSpec: QuickSpec { waitUntil { done in task.failureReporter = { error in expect(task.state) == .stopped - if case DownloaderError.serverSide(_) = error { } else { + if case DownloaderError.serverSide(_) = error {} else { fail("after server side error reported wrong error") } diff --git a/StepicTests/Info.plist b/StepicTests/Info.plist index 4398a1c2d3..2e8382ab8c 100644 --- a/StepicTests/Info.plist +++ b/StepicTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.118 + 1.119 CFBundleSignature ???? CFBundleVersion - 194 + 196 diff --git a/StickerPackExtension/Info.plist b/StickerPackExtension/Info.plist index dd64c209ac..188aa2be66 100644 --- a/StickerPackExtension/Info.plist +++ b/StickerPackExtension/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 1.118 + 1.119 CFBundleVersion - 194 + 196 NSExtension NSExtensionPointIdentifier