From c0f7095a15479d14217501241d6fe4583ba31efa Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sat, 25 Aug 2018 10:36:08 +0300 Subject: [PATCH 01/26] Remove unnecessary LessonsTableViewController.xib file --- .../LessonsTableViewController.swift | 14 +++++----- .../LessonsTableViewController.xib | 26 ------------------- Stepic.xcodeproj/project.pbxproj | 14 +--------- 3 files changed, 7 insertions(+), 47 deletions(-) rename ExamEGERussian/Sources/PresentationLayer/Lessons/View/{LessonsTableViewController => }/LessonsTableViewController.swift (86%) delete mode 100644 ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController/LessonsTableViewController.xib diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift similarity index 86% rename from ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController/LessonsTableViewController.swift rename to ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index 09b96738f4..86dad484fa 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -9,19 +9,16 @@ import UIKit final class LessonsTableViewController: UITableViewController { - - // MARK: Instance Properties - var presenter: LessonsPresenter! private var lessons = [LessonsViewData]() { didSet { tableView.reloadData() - topicsRefreshControl.endRefreshing() + lessonsRefreshControl.endRefreshing() } } - private lazy var topicsRefreshControl: UIRefreshControl = { + private lazy var lessonsRefreshControl: UIRefreshControl = { let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: #selector(refreshData(_:)), for: .valueChanged) @@ -36,9 +33,9 @@ final class LessonsTableViewController: UITableViewController { tableView.registerNib(for: LessonTableViewCell.self) if #available(iOS 10.0, *) { - tableView.refreshControl = topicsRefreshControl + tableView.refreshControl = lessonsRefreshControl } else { - tableView.addSubview(topicsRefreshControl) + tableView.addSubview(lessonsRefreshControl) } presenter.refresh() @@ -66,7 +63,8 @@ final class LessonsTableViewController: UITableViewController { // MARK: - Private API - @objc private func refreshData(_ sender: Any) { + @objc + private func refreshData(_ sender: Any) { presenter.refresh() } } diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController/LessonsTableViewController.xib b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController/LessonsTableViewController.xib deleted file mode 100644 index de53f77ed1..0000000000 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController/LessonsTableViewController.xib +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index d7812a4a01..1eeae9ced5 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -1986,7 +1986,6 @@ 2C2485492101EE3E006F8858 /* DownloaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2485482101EE3E006F8858 /* DownloaderTests.swift */; }; 2C2E2853210B5F6700EB6F47 /* VideoFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2365E321078CEF00C99742 /* VideoFileManager.swift */; }; 2C2FD77A2107359E00609621 /* LessonsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD7782107359E00609621 /* LessonsTableViewController.swift */; }; - 2C2FD77B2107359E00609621 /* LessonsTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C2FD7792107359E00609621 /* LessonsTableViewController.xib */; }; 2C2FD77F210735E000609621 /* LessonTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD77D210735E000609621 /* LessonTableViewCell.swift */; }; 2C2FD780210735E000609621 /* LessonTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C2FD77E210735E000609621 /* LessonTableViewCell.xib */; }; 2C2FD7842107448F00609621 /* LessonsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD7832107448F00609621 /* LessonsService.swift */; }; @@ -5736,7 +5735,6 @@ 2C2485482101EE3E006F8858 /* DownloaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloaderTests.swift; sourceTree = ""; }; 2C2544081F3480BE004DB3D9 /* AchievementNotificationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AchievementNotificationView.swift; sourceTree = ""; }; 2C2FD7782107359E00609621 /* LessonsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsTableViewController.swift; sourceTree = ""; }; - 2C2FD7792107359E00609621 /* LessonsTableViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LessonsTableViewController.xib; sourceTree = ""; }; 2C2FD77D210735E000609621 /* LessonTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonTableViewCell.swift; sourceTree = ""; }; 2C2FD77E210735E000609621 /* LessonTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LessonTableViewCell.xib; sourceTree = ""; }; 2C2FD7832107448F00609621 /* LessonsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsService.swift; sourceTree = ""; }; @@ -8936,22 +8934,13 @@ 2C2FD7772107357800609621 /* View */ = { isa = PBXGroup; children = ( - 2C2FD77C210735AE00609621 /* LessonsTableViewController */, 2C2FD781210735EB00609621 /* LessonTableViewCell */, + 2C2FD7782107359E00609621 /* LessonsTableViewController.swift */, 2C2FD7902107540500609621 /* LessonsView.swift */, ); path = View; sourceTree = ""; }; - 2C2FD77C210735AE00609621 /* LessonsTableViewController */ = { - isa = PBXGroup; - children = ( - 2C2FD7782107359E00609621 /* LessonsTableViewController.swift */, - 2C2FD7792107359E00609621 /* LessonsTableViewController.xib */, - ); - path = LessonsTableViewController; - sourceTree = ""; - }; 2C2FD781210735EB00609621 /* LessonTableViewCell */ = { isa = PBXGroup; children = ( @@ -11995,7 +11984,6 @@ 2C0107A5210F3E87009A53DF /* LaunchScreen.storyboard in Resources */, 2C4F34042109F5C900E259FE /* AuthSignInViewController.xib in Resources */, 2C8A0F2220FC7CD80009F67E /* Localizable.strings in Resources */, - 2C2FD77B2107359E00609621 /* LessonsTableViewController.xib in Resources */, 2C093F2E211B4B4800162DD0 /* StepikPlaceholderView.xib in Resources */, 2C83E5F9211099D400A8322D /* wysiwyg.css in Resources */, 2C83E5FA211099F900A8322D /* plyr.js in Resources */, From c28b97bec79a62110397994331b60eff90ada264 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sat, 25 Aug 2018 10:36:47 +0300 Subject: [PATCH 02/26] Return Guarantee when getting lessons from cache --- .../Lessons/Presenter/LessonsPresenterImpl.swift | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift index 4a95f99f19..9429c8101d 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift @@ -79,16 +79,17 @@ final class LessonsPresenterImpl: LessonsPresenter { private func getLessons() { obtainLessonsFromCache().done { self.fetchLessons() - }.cauterize() + } } - private func obtainLessonsFromCache() -> Promise { - return Promise { seal in + private func obtainLessonsFromCache() -> Guarantee { + return Guarantee { seal in self.lessonsService.obtainLessons(with: self.lessonsIds).done { [weak self] lessons in self?.lessons = lessons - seal.fulfill(()) - }.catch { [weak self] error in - self?.displayError(error) + seal(()) + }.catch { error in + print("\(#function): \(error)") + seal(()) } } } From 0b910a17729203ccde9851537150f80c96f441c1 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sat, 25 Aug 2018 12:34:37 +0300 Subject: [PATCH 03/26] layout LessonTableViewCell --- .../LessonTableViewCell.swift | 8 ++- .../LessonTableViewCell.xib | 53 +++++++++++++++---- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableViewCell/LessonTableViewCell.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableViewCell/LessonTableViewCell.swift index 829d32dcaa..7fbb524609 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableViewCell/LessonTableViewCell.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableViewCell/LessonTableViewCell.swift @@ -9,5 +9,11 @@ import UIKit final class LessonTableViewCell: UITableViewCell { - @IBOutlet var descriptionTitleLabel: UILabel! + + @IBOutlet var numberLabel: UILabel! + + @IBOutlet var titleLabel: UILabel! + + @IBOutlet var subtitleLabel: UILabel! + } diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableViewCell/LessonTableViewCell.xib b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableViewCell/LessonTableViewCell.xib index 0736771c72..7598ae8835 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableViewCell/LessonTableViewCell.xib +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableViewCell/LessonTableViewCell.xib @@ -1,40 +1,71 @@ - + - + - - + + - + - - - - + + + + + + + + + + + + + - + + + From d4256d6cec46bf300bcd91cc5a3294916ce52f5b Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sat, 25 Aug 2018 14:35:21 +0300 Subject: [PATCH 04/26] Fill cells with the data --- .../KnowledgeGraph/KnowledgeGraphLesson.swift | 25 +++++++++++++++---- .../PlainObjects/LessonPlainObject.swift | 2 +- .../View/LessonsTableViewController.swift | 9 ++++++- .../Lessons/View/LessonsView.swift | 1 + 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/ExamEGERussian/Sources/CoreLayer/Graph/ConcreteClasses/KnowledgeGraph/KnowledgeGraphLesson.swift b/ExamEGERussian/Sources/CoreLayer/Graph/ConcreteClasses/KnowledgeGraph/KnowledgeGraphLesson.swift index 1c1d657d80..fc1e7660ca 100644 --- a/ExamEGERussian/Sources/CoreLayer/Graph/ConcreteClasses/KnowledgeGraph/KnowledgeGraphLesson.swift +++ b/ExamEGERussian/Sources/CoreLayer/Graph/ConcreteClasses/KnowledgeGraph/KnowledgeGraphLesson.swift @@ -9,20 +9,35 @@ import Foundation public struct KnowledgeGraphLesson { + let id: Int + let type: LessonType + let courseId: String + public enum LessonType: String { case theory case practice - } - let id: Int - let type: LessonType - let courseId: String + public init(rawValue: String) { + switch rawValue { + case "theory": + self = .theory + case "practice": + self = .practice + default: + self = LessonType.default + } + } + + static var `default`: LessonType { + return .theory + } + } } extension KnowledgeGraphLesson { init(id: Int, type: String, courseId: String) { self.id = id - self.type = LessonType(rawValue: type)! + self.type = LessonType(rawValue: type) self.courseId = courseId } } diff --git a/ExamEGERussian/Sources/Model/PlainObjects/LessonPlainObject.swift b/ExamEGERussian/Sources/Model/PlainObjects/LessonPlainObject.swift index cf9d5660a6..100cc28c7c 100644 --- a/ExamEGERussian/Sources/Model/PlainObjects/LessonPlainObject.swift +++ b/ExamEGERussian/Sources/Model/PlainObjects/LessonPlainObject.swift @@ -8,7 +8,7 @@ import Foundation -struct LessonPlainObject: Codable, Equatable { +struct LessonPlainObject: Equatable { let id: Int let steps: [Int] let title: String diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index 86dad484fa..78a2a4dcd3 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -38,6 +38,9 @@ final class LessonsTableViewController: UITableViewController { tableView.addSubview(lessonsRefreshControl) } + tableView.rowHeight = UITableViewAutomaticDimension + tableView.estimatedRowHeight = 60 + presenter.refresh() } @@ -48,8 +51,12 @@ final class LessonsTableViewController: UITableViewController { } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let lesson = lessons[indexPath.row] + let cell: LessonTableViewCell = tableView.dequeueReusableCell(for: indexPath) - cell.descriptionTitleLabel.text = lessons[indexPath.row].title + cell.numberLabel.text = "\(indexPath.row + 1)." + cell.titleLabel.text = lesson.title + cell.subtitleLabel.text = lesson.subtitle return cell } diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift index 44a51e76f2..5c2a983c73 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift @@ -11,6 +11,7 @@ import Foundation struct LessonsViewData { let id: Int let title: String + let subtitle: String } protocol LessonsView: class { From 9a17ecced22937bad4509352d12a0e918405f6c4 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sat, 25 Aug 2018 14:36:43 +0300 Subject: [PATCH 05/26] Localize lesson pages count --- Stepic.xcodeproj/project.pbxproj | 16 ++++++++++++++ Stepic/en.lproj/Localizable.strings | 2 ++ Stepic/en.lproj/Localizable.stringsdict | 24 +++++++++++++++++++++ Stepic/ru.lproj/Localizable.strings | 2 ++ Stepic/ru.lproj/Localizable.stringsdict | 28 +++++++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 Stepic/en.lproj/Localizable.stringsdict create mode 100644 Stepic/ru.lproj/Localizable.stringsdict diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index 1eeae9ced5..03a5f90080 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -4045,6 +4045,8 @@ 2CB9E8CB1F8397960004E17F /* NotificationsSectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CA1F8397960004E17F /* NotificationsSectionHeaderView.xib */; }; 2CB9E8D01F839C8E0004E17F /* NotificationsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CE1F839C8E0004E17F /* NotificationsTableViewCell.swift */; }; 2CB9E8D11F839C8E0004E17F /* NotificationsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CF1F839C8E0004E17F /* NotificationsTableViewCell.xib */; }; + 2CBB70F8213171D900D67BE1 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */; }; + 2CBB70F9213171D900D67BE1 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */; }; 2CBC261421086936004245D6 /* UserRegistrationServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */; }; 2CBC261521086947004245D6 /* UserRegistrationServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */; }; 2CBC261621086947004245D6 /* UserRegistrationServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */; }; @@ -5980,6 +5982,8 @@ 2CB9E8CA1F8397960004E17F /* NotificationsSectionHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NotificationsSectionHeaderView.xib; sourceTree = ""; }; 2CB9E8CE1F839C8E0004E17F /* NotificationsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsTableViewCell.swift; sourceTree = ""; }; 2CB9E8CF1F839C8E0004E17F /* NotificationsTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NotificationsTableViewCell.xib; sourceTree = ""; }; + 2CBB70FA213171D900D67BE1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; + 2CBB70FC213171DE00D67BE1 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserRegistrationServiceImpl.swift; sourceTree = ""; }; 2CBC4C051F1E4A1300FE96C4 /* Config.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Config.plist; sourceTree = ""; }; 2CBCBD4820D1AAFC000B5732 /* AchievementsListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AchievementsListTableViewCell.swift; sourceTree = ""; }; @@ -7977,6 +7981,7 @@ 0869F6D71CE3684000F8A6DB /* default_sound.wav */, 08D2AE471C04F52300BD8C3D /* GoogleService-Info.plist */, 08A1257B1BDEBCC90066B2B2 /* Localizable.strings */, + 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */, 08DE94151B8C58AC00D278AB /* Info.plist */, 08C0A4351BF12CDF0010F049 /* CustomMessagesDesign.json */, 08A7B0E71EB340F500C1BA71 /* Auth.plist */, @@ -11693,6 +11698,7 @@ 08A9F7151FC3837800640F1F /* CourseTagCollectionViewCell.xib in Resources */, 2C32E71320FF6C1D008BB909 /* Auth.storyboard in Resources */, 08EDB8B11F7C3D0C0028A9AE /* CourseWidgetView.xib in Resources */, + 2CBB70F8213171D900D67BE1 /* Localizable.stringsdict in Resources */, 082CB1B81D08971900C79A27 /* DiscussionsViewController.xib in Resources */, 08F485B91C58ED01000165AA /* SortingQuizTableViewCell.xib in Resources */, 08A7B0E81EB340F500C1BA71 /* Auth.plist in Resources */, @@ -11979,6 +11985,7 @@ 2C093F2D211B4AE900162DD0 /* QuizViewController.xib in Resources */, 2C5FDC992111E25A0077C15C /* StepTabView.xib in Resources */, 2CD7998D21077D010054D098 /* TopicTableViewCell.xib in Resources */, + 2CBB70F9213171D900D67BE1 /* Localizable.stringsdict in Resources */, 2CD1E35B2114B0D0007AA7B3 /* Assets.xcassets in Resources */, 2C302DC121303191006C2BD5 /* AuthGreetingViewController.xib in Resources */, 2C0107A5210F3E87009A53DF /* LaunchScreen.storyboard in Resources */, @@ -18559,6 +18566,15 @@ name = step2.html; sourceTree = ""; }; + 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */ = { + isa = PBXVariantGroup; + children = ( + 2CBB70FA213171D900D67BE1 /* en */, + 2CBB70FC213171DE00D67BE1 /* ru */, + ); + name = Localizable.stringsdict; + sourceTree = ""; + }; 2CC351841F6827BE004255B6 /* Auth.storyboard */ = { isa = PBXVariantGroup; children = ( diff --git a/Stepic/en.lproj/Localizable.strings b/Stepic/en.lproj/Localizable.strings index 19e82cc7fd..34493c2adb 100644 --- a/Stepic/en.lproj/Localizable.strings +++ b/Stepic/en.lproj/Localizable.strings @@ -568,3 +568,5 @@ PersonalDeadlineWidgetSuggestionText = "Constant learning is a key to success. W "EmptyAuthViewTitle" = "It's You!"; "EmptyAuthViewSubtitle" = "Complete auth to study with comfort"; "EmptyAuthViewDescription" = "Authorized account allows you to sync progress"; + +"PracticeLessonDescription" = "Consolidate the knowledge gained"; diff --git a/Stepic/en.lproj/Localizable.stringsdict b/Stepic/en.lproj/Localizable.stringsdict new file mode 100644 index 0000000000..668beb69c3 --- /dev/null +++ b/Stepic/en.lproj/Localizable.stringsdict @@ -0,0 +1,24 @@ + + + + + lesson pages count + + NSStringLocalizedFormatKey + %#@v1_pages_count@ + v1_pages_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + u + zero + No pages + one + %u page + other + %u pages + + + + diff --git a/Stepic/ru.lproj/Localizable.strings b/Stepic/ru.lproj/Localizable.strings index 0239fe1373..ab3a7f1298 100644 --- a/Stepic/ru.lproj/Localizable.strings +++ b/Stepic/ru.lproj/Localizable.strings @@ -569,3 +569,5 @@ PersonalDeadlineWidgetSuggestionText = "Постоянное обучение - "EmptyAuthViewTitle" = "Это Вы!"; "EmptyAuthViewSubtitle" = "Пройдите авторизацию для более удобного обучения"; "EmptyAuthViewDescription" = "Авторизованный аккаунт позволит синхронизировать прогресс с другими устройствами"; + +"PracticeLessonDescription" = "Закрепите полученные знания"; diff --git a/Stepic/ru.lproj/Localizable.stringsdict b/Stepic/ru.lproj/Localizable.stringsdict new file mode 100644 index 0000000000..61b75a37c9 --- /dev/null +++ b/Stepic/ru.lproj/Localizable.stringsdict @@ -0,0 +1,28 @@ + + + + + lesson pages count + + NSStringLocalizedFormatKey + %#@v1_pages_count@ + v1_pages_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + u + zero + Нет страниц + one + %u страница + few + %u страницы + many + %u страниц + other + %u страниц + + + + From 812697385a535f14053cc40d4c48bc750ed4cede Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sat, 25 Aug 2018 15:02:59 +0300 Subject: [PATCH 06/26] Refactor move view data building to the view model --- .../Lessons/Model/LessonViewModel.swift | 41 +++++++++++++++++++ .../Presenter/LessonsPresenterImpl.swift | 6 ++- Stepic.xcodeproj/project.pbxproj | 12 ++++++ 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 ExamEGERussian/Sources/PresentationLayer/Lessons/Model/LessonViewModel.swift diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Model/LessonViewModel.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Model/LessonViewModel.swift new file mode 100644 index 0000000000..16694fd6c8 --- /dev/null +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Model/LessonViewModel.swift @@ -0,0 +1,41 @@ +// +// LessonViewModel.swift +// ExamEGERussian +// +// Created by Ivan Magda on 25/08/2018. +// Copyright © 2018 Alex Karpov. All rights reserved. +// + +import Foundation + +struct LessonViewModel { + let lesson: LessonPlainObject + let topic: KnowledgeGraphVertex + + var title: String { + return lesson.title + } + + var subtitle: String { + let type = topic.lessons.first(where: { + $0.id == lesson.id + })?.type ?? KnowledgeGraphLesson.LessonType.default + + switch type { + case .theory: + return pagesCountUniversal(count: UInt(lesson.steps.count)) + case .practice: + return NSLocalizedString("PracticeLessonDescription", comment: "") + } + } + + private func pagesCountUniversal(count: UInt) -> String { + let formatString = NSLocalizedString( + "lesson pages count", + comment: "Lessons pages count string format to be found in Localized.stringsdict" + ) + let resultString = String.localizedStringWithFormat(formatString, count) + + return resultString + } +} diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift index 9429c8101d..8d946620a1 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift @@ -107,7 +107,11 @@ final class LessonsPresenterImpl: LessonsPresenter { } private func viewLessons(from lessons: [LessonPlainObject]) -> [LessonsViewData] { - return lessons.map { LessonsViewData(id: $0.id, title: $0.title) } + return lessons.map { lesson in + let viewModel = LessonViewModel(lesson: lesson, topic: topic) + return LessonsViewData(id: lesson.id, title: viewModel.title, + subtitle: viewModel.subtitle) + } } private func displayError(_ error: Swift.Error) { diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index 03a5f90080..7c67f686ad 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -4045,6 +4045,7 @@ 2CB9E8CB1F8397960004E17F /* NotificationsSectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CA1F8397960004E17F /* NotificationsSectionHeaderView.xib */; }; 2CB9E8D01F839C8E0004E17F /* NotificationsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CE1F839C8E0004E17F /* NotificationsTableViewCell.swift */; }; 2CB9E8D11F839C8E0004E17F /* NotificationsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CF1F839C8E0004E17F /* NotificationsTableViewCell.xib */; }; + 2CBB70F421315D0A00D67BE1 /* LessonViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBB70F321315D0A00D67BE1 /* LessonViewModel.swift */; }; 2CBB70F8213171D900D67BE1 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */; }; 2CBB70F9213171D900D67BE1 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */; }; 2CBC261421086936004245D6 /* UserRegistrationServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */; }; @@ -5982,6 +5983,7 @@ 2CB9E8CA1F8397960004E17F /* NotificationsSectionHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NotificationsSectionHeaderView.xib; sourceTree = ""; }; 2CB9E8CE1F839C8E0004E17F /* NotificationsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsTableViewCell.swift; sourceTree = ""; }; 2CB9E8CF1F839C8E0004E17F /* NotificationsTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NotificationsTableViewCell.xib; sourceTree = ""; }; + 2CBB70F321315D0A00D67BE1 /* LessonViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonViewModel.swift; sourceTree = ""; }; 2CBB70FA213171D900D67BE1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; 2CBB70FC213171DE00D67BE1 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserRegistrationServiceImpl.swift; sourceTree = ""; }; @@ -8929,6 +8931,7 @@ isa = PBXGroup; children = ( 2C0107A6210F41F6009A53DF /* Assembly */, + 2CBB70F021315C8000D67BE1 /* Model */, 2C2FD78B2107539700609621 /* Presenter */, 2C0107AB210F428E009A53DF /* Router */, 2C2FD7772107357800609621 /* View */, @@ -9899,6 +9902,14 @@ name = NotificationsTableViewCell; sourceTree = ""; }; + 2CBB70F021315C8000D67BE1 /* Model */ = { + isa = PBXGroup; + children = ( + 2CBB70F321315D0A00D67BE1 /* LessonViewModel.swift */, + ); + path = Model; + sourceTree = ""; + }; 2CBCBD4720D1AAD5000B5732 /* Achievement Cell */ = { isa = PBXGroup; children = ( @@ -16147,6 +16158,7 @@ 2CA6F5F021219ABB00EE337E /* AssemblyFactoryBuilder.swift in Sources */, 2C83E5DD211044A600A8322D /* VideoLocationManager.swift in Sources */, 2C9499B520ECBAD50049E9A8 /* MatchingDataset.swift in Sources */, + 2CBB70F421315D0A00D67BE1 /* LessonViewModel.swift in Sources */, 2C33CBF420EC3278009956B0 /* LessonsAPI.swift in Sources */, 2C77030E210F2C7B002E250D /* AuthSignInViewController.swift in Sources */, 2CD7998B21077D010054D098 /* TopicsPresenter.swift in Sources */, From 013bce0a6113bbc8280b45cd5180c4b8d7daed77 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sat, 25 Aug 2018 15:32:45 +0300 Subject: [PATCH 07/26] Show practice lessons --- .../Lessons/Model/LessonViewModel.swift | 41 ----------------- .../Presenter/LessonsPresenterImpl.swift | 45 ++++++++++++++----- Stepic.xcodeproj/project.pbxproj | 12 ----- Stepic/en.lproj/Localizable.strings | 1 + Stepic/ru.lproj/Localizable.strings | 1 + 5 files changed, 37 insertions(+), 63 deletions(-) delete mode 100644 ExamEGERussian/Sources/PresentationLayer/Lessons/Model/LessonViewModel.swift diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Model/LessonViewModel.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Model/LessonViewModel.swift deleted file mode 100644 index 16694fd6c8..0000000000 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Model/LessonViewModel.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// LessonViewModel.swift -// ExamEGERussian -// -// Created by Ivan Magda on 25/08/2018. -// Copyright © 2018 Alex Karpov. All rights reserved. -// - -import Foundation - -struct LessonViewModel { - let lesson: LessonPlainObject - let topic: KnowledgeGraphVertex - - var title: String { - return lesson.title - } - - var subtitle: String { - let type = topic.lessons.first(where: { - $0.id == lesson.id - })?.type ?? KnowledgeGraphLesson.LessonType.default - - switch type { - case .theory: - return pagesCountUniversal(count: UInt(lesson.steps.count)) - case .practice: - return NSLocalizedString("PracticeLessonDescription", comment: "") - } - } - - private func pagesCountUniversal(count: UInt) -> String { - let formatString = NSLocalizedString( - "lesson pages count", - comment: "Lessons pages count string format to be found in Localized.stringsdict" - ) - let resultString = String.localizedStringWithFormat(formatString, count) - - return resultString - } -} diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift index 8d946620a1..f1d4aa2dfb 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift @@ -18,7 +18,7 @@ final class LessonsPresenterImpl: LessonsPresenter { private var lessons = [LessonPlainObject]() { didSet { - self.view?.setLessons(viewLessons(from: lessons)) + updateView() } } private var topic: KnowledgeGraphVertex { @@ -106,18 +106,43 @@ final class LessonsPresenterImpl: LessonsPresenter { } } - private func viewLessons(from lessons: [LessonPlainObject]) -> [LessonsViewData] { - return lessons.map { lesson in - let viewModel = LessonViewModel(lesson: lesson, topic: topic) - return LessonsViewData(id: lesson.id, title: viewModel.title, - subtitle: viewModel.subtitle) - } - } - - private func displayError(_ error: Swift.Error) { + private func displayError(_ error: Error) { view?.displayError( title: NSLocalizedString("Error", comment: ""), message: NSLocalizedString("ErrorMessage", comment: "") ) } } + +// MARK: - LessonsPresenterImpl (View Data) - + +extension LessonsPresenterImpl { + private func updateView() { + let theory = lessons.map { + LessonsViewData( + id: $0.id, + title: $0.title, + subtitle: pagesCountUniversal(count: UInt($0.steps.count)) + ) + } + let practice = topic.lessons.filter { $0.type == .practice }.map { + LessonsViewData( + id: $0.id, + title: NSLocalizedString("PracticeLessonTitle", comment: ""), + subtitle: NSLocalizedString("PracticeLessonDescription", comment: "") + ) + } + + self.view?.setLessons(theory + practice) + } + + private func pagesCountUniversal(count: UInt) -> String { + let formatString = NSLocalizedString( + "lesson pages count", + comment: "Lessons pages count string format to be found in Localized.stringsdict" + ) + let resultString = String.localizedStringWithFormat(formatString, count) + + return resultString + } +} diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index 7c67f686ad..03a5f90080 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -4045,7 +4045,6 @@ 2CB9E8CB1F8397960004E17F /* NotificationsSectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CA1F8397960004E17F /* NotificationsSectionHeaderView.xib */; }; 2CB9E8D01F839C8E0004E17F /* NotificationsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CE1F839C8E0004E17F /* NotificationsTableViewCell.swift */; }; 2CB9E8D11F839C8E0004E17F /* NotificationsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CF1F839C8E0004E17F /* NotificationsTableViewCell.xib */; }; - 2CBB70F421315D0A00D67BE1 /* LessonViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBB70F321315D0A00D67BE1 /* LessonViewModel.swift */; }; 2CBB70F8213171D900D67BE1 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */; }; 2CBB70F9213171D900D67BE1 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */; }; 2CBC261421086936004245D6 /* UserRegistrationServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */; }; @@ -5983,7 +5982,6 @@ 2CB9E8CA1F8397960004E17F /* NotificationsSectionHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NotificationsSectionHeaderView.xib; sourceTree = ""; }; 2CB9E8CE1F839C8E0004E17F /* NotificationsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsTableViewCell.swift; sourceTree = ""; }; 2CB9E8CF1F839C8E0004E17F /* NotificationsTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NotificationsTableViewCell.xib; sourceTree = ""; }; - 2CBB70F321315D0A00D67BE1 /* LessonViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonViewModel.swift; sourceTree = ""; }; 2CBB70FA213171D900D67BE1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; 2CBB70FC213171DE00D67BE1 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserRegistrationServiceImpl.swift; sourceTree = ""; }; @@ -8931,7 +8929,6 @@ isa = PBXGroup; children = ( 2C0107A6210F41F6009A53DF /* Assembly */, - 2CBB70F021315C8000D67BE1 /* Model */, 2C2FD78B2107539700609621 /* Presenter */, 2C0107AB210F428E009A53DF /* Router */, 2C2FD7772107357800609621 /* View */, @@ -9902,14 +9899,6 @@ name = NotificationsTableViewCell; sourceTree = ""; }; - 2CBB70F021315C8000D67BE1 /* Model */ = { - isa = PBXGroup; - children = ( - 2CBB70F321315D0A00D67BE1 /* LessonViewModel.swift */, - ); - path = Model; - sourceTree = ""; - }; 2CBCBD4720D1AAD5000B5732 /* Achievement Cell */ = { isa = PBXGroup; children = ( @@ -16158,7 +16147,6 @@ 2CA6F5F021219ABB00EE337E /* AssemblyFactoryBuilder.swift in Sources */, 2C83E5DD211044A600A8322D /* VideoLocationManager.swift in Sources */, 2C9499B520ECBAD50049E9A8 /* MatchingDataset.swift in Sources */, - 2CBB70F421315D0A00D67BE1 /* LessonViewModel.swift in Sources */, 2C33CBF420EC3278009956B0 /* LessonsAPI.swift in Sources */, 2C77030E210F2C7B002E250D /* AuthSignInViewController.swift in Sources */, 2CD7998B21077D010054D098 /* TopicsPresenter.swift in Sources */, diff --git a/Stepic/en.lproj/Localizable.strings b/Stepic/en.lproj/Localizable.strings index 34493c2adb..8a2540b84b 100644 --- a/Stepic/en.lproj/Localizable.strings +++ b/Stepic/en.lproj/Localizable.strings @@ -569,4 +569,5 @@ PersonalDeadlineWidgetSuggestionText = "Constant learning is a key to success. W "EmptyAuthViewSubtitle" = "Complete auth to study with comfort"; "EmptyAuthViewDescription" = "Authorized account allows you to sync progress"; +"PracticeLessonTitle" = "Practical assignments"; "PracticeLessonDescription" = "Consolidate the knowledge gained"; diff --git a/Stepic/ru.lproj/Localizable.strings b/Stepic/ru.lproj/Localizable.strings index ab3a7f1298..859ac42d44 100644 --- a/Stepic/ru.lproj/Localizable.strings +++ b/Stepic/ru.lproj/Localizable.strings @@ -570,4 +570,5 @@ PersonalDeadlineWidgetSuggestionText = "Постоянное обучение - "EmptyAuthViewSubtitle" = "Пройдите авторизацию для более удобного обучения"; "EmptyAuthViewDescription" = "Авторизованный аккаунт позволит синхронизировать прогресс с другими устройствами"; +"PracticeLessonTitle" = "Практические задания"; "PracticeLessonDescription" = "Закрепите полученные знания"; From 11ca257475b11a0a08627496d54d8d707cc3b582 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sat, 25 Aug 2018 16:09:33 +0300 Subject: [PATCH 08/26] Navigate to the adaptive screen --- .../Presenter/LessonsPresenterImpl.swift | 31 ++++++++++++------- .../Lessons/Router/LessonsRouter.swift | 3 +- .../Lessons/Router/LessonsRouterImpl.swift | 15 ++++++++- .../Assembly/AdaptiveStepsAssembly.swift | 8 +++++ .../AdaptiveStepsAssemblyProtocol.swift | 1 + 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift index f1d4aa2dfb..0791f9c64f 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift @@ -55,11 +55,20 @@ final class LessonsPresenterImpl: LessonsPresenter { } func selectLesson(with viewData: LessonsViewData) { - guard let lesson = lessons.first(where: { $0.id == viewData.id }) else { + guard let lesson = topic.lessons.first(where: { $0.id == viewData.id }) else { return } - router.showStepsForLesson(lesson) + switch lesson.type { + case .theory: + if let lesson = lessons.first(where: { $0.id == viewData.id }) { + router.showTheory(lesson: lesson) + } else { + displayError() + } + case .practice: + router.showPractice(courseId: lesson.courseId) + } } // MARK: - Private API @@ -71,8 +80,8 @@ final class LessonsPresenterImpl: LessonsPresenter { courseService.joinCourses(with: coursesIds).done { courses in print("Successfully joined courses with ids: \(courses.map { $0.id })") - }.catch { [weak self] error in - self?.displayError(error) + }.catch { [weak self] _ in + self?.displayError() } } @@ -101,16 +110,16 @@ final class LessonsPresenterImpl: LessonsPresenter { lessonsService.fetchLessons(with: lessonsIds).done { [weak self] lessons in self?.lessons = lessons - }.catch { [weak self] error in - self?.displayError(error) + }.catch { [weak self] _ in + self?.displayError() } } - private func displayError(_ error: Error) { - view?.displayError( - title: NSLocalizedString("Error", comment: ""), - message: NSLocalizedString("ErrorMessage", comment: "") - ) + private func displayError( + title: String = NSLocalizedString("Error", comment: ""), + message: String = NSLocalizedString("ErrorMessage", comment: "") + ) { + view?.displayError(title: title, message: message) } } diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift index 0362976995..4c95978b7a 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift @@ -9,5 +9,6 @@ import Foundation protocol LessonsRouter: class { - func showStepsForLesson(_ lesson: LessonPlainObject) + func showTheory(lesson: LessonPlainObject) + func showPractice(courseId: String) } diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift index 44820b0df6..4cfbe8d78b 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift @@ -9,7 +9,7 @@ import Foundation final class LessonsRouterImpl: BaseRouter, LessonsRouter { - func showStepsForLesson(_ lesson: LessonPlainObject) { + func showTheory(lesson: LessonPlainObject) { pushViewController(derivedFrom: { navigationController in assemblyFactory.stepsAssembly.standart.module( navigationController: navigationController, @@ -17,4 +17,17 @@ final class LessonsRouterImpl: BaseRouter, LessonsRouter { ) }) } + + func showPractice(courseId: String) { + if let id = Int(courseId) { + pushViewController(derivedFrom: { _ in + assemblyFactory.stepsAssembly.adaptive.module(courseId: id) + }) + } else { + navigationController?.presentAlert( + withTitle: NSLocalizedString("Error", comment: ""), + message: NSLocalizedString("NoAdaptiveModuleError", comment: "") + ) + } + } } diff --git a/ExamEGERussian/Sources/PresentationLayer/Steps/Adaptive/Assembly/AdaptiveStepsAssembly.swift b/ExamEGERussian/Sources/PresentationLayer/Steps/Adaptive/Assembly/AdaptiveStepsAssembly.swift index 62d03bc636..09a2132904 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Steps/Adaptive/Assembly/AdaptiveStepsAssembly.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Steps/Adaptive/Assembly/AdaptiveStepsAssembly.swift @@ -15,6 +15,14 @@ final class AdaptiveStepsAssembly: BaseAssembly, AdaptiveStepsAssemblyProtocol { return nil } + return makeModule(courseId: courseId) + } + + func module(courseId: Int) -> UIViewController { + return makeModule(courseId: courseId) + } + + private func makeModule(courseId: Int) -> UIViewController { let controller = AdaptiveStepsViewController() let stepAssembly = StepAssemblyImpl( assemblyFactory: assemblyFactory, diff --git a/ExamEGERussian/Sources/PresentationLayer/Steps/Adaptive/Assembly/AdaptiveStepsAssemblyProtocol.swift b/ExamEGERussian/Sources/PresentationLayer/Steps/Adaptive/Assembly/AdaptiveStepsAssemblyProtocol.swift index bd9f48b3b4..f4eb316340 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Steps/Adaptive/Assembly/AdaptiveStepsAssemblyProtocol.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Steps/Adaptive/Assembly/AdaptiveStepsAssemblyProtocol.swift @@ -10,4 +10,5 @@ import UIKit protocol AdaptiveStepsAssemblyProtocol: class { func module(topicId: String) -> UIViewController? + func module(courseId: Int) -> UIViewController } From 90c4bfe027b43f4b3a48376d95196c2b97e6906b Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 00:07:46 +0300 Subject: [PATCH 09/26] Add lesson table header view with dynamic height --- .../Assembly/LessonsAssemblyImpl.swift | 2 +- .../Presenter/LessonsPresenterImpl.swift | 10 ++- .../LessonHeaderTableView.swift | 30 ++++++++ .../LessonHeaderTableView.xib | 54 ++++++++++++++ .../View/LessonsTableViewController.swift | 71 ++++++++++++++++--- .../Lessons/View/LessonsView.swift | 2 + Stepic.xcodeproj/project.pbxproj | 16 +++++ .../xcschemes/ExamEGERussian.xcscheme | 2 +- 8 files changed, 171 insertions(+), 16 deletions(-) create mode 100644 ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.swift create mode 100644 ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift index 1cae8e4b3d..6522b30b33 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift @@ -26,7 +26,7 @@ final class LessonsAssemblyImpl: BaseAssembly, LessonsAssembly { courseService: serviceFactory.courseService ) controller.presenter = presenter - controller.title = knowledgeGraph[topicId]?.key.title + controller.title = NSLocalizedString("LessonsViewControllerTitle", comment: "") return controller } diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift index 0791f9c64f..090843fb9c 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift @@ -131,21 +131,25 @@ extension LessonsPresenterImpl { LessonsViewData( id: $0.id, title: $0.title, - subtitle: pagesCountUniversal(count: UInt($0.steps.count)) + subtitle: pagesCountLocalized(count: UInt($0.steps.count)), + headerTitle: topic.title, + headerSubtitle: "\(lessons.count) lessons" ) } let practice = topic.lessons.filter { $0.type == .practice }.map { LessonsViewData( id: $0.id, title: NSLocalizedString("PracticeLessonTitle", comment: ""), - subtitle: NSLocalizedString("PracticeLessonDescription", comment: "") + subtitle: NSLocalizedString("PracticeLessonDescription", comment: ""), + headerTitle: topic.title, + headerSubtitle: "\(lessons.count) lessons" ) } self.view?.setLessons(theory + practice) } - private func pagesCountUniversal(count: UInt) -> String { + private func pagesCountLocalized(count: UInt) -> String { let formatString = NSLocalizedString( "lesson pages count", comment: "Lessons pages count string format to be found in Localized.stringsdict" diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.swift new file mode 100644 index 0000000000..204ea83582 --- /dev/null +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.swift @@ -0,0 +1,30 @@ +// +// LessonHeaderTableView.swift +// ExamEGERussian +// +// Created by Ivan Magda on 25/08/2018. +// Copyright © 2018 Alex Karpov. All rights reserved. +// + +import Foundation + +final class LessonHeaderTableView: UIView { + @IBOutlet var titleLabel: UILabel! + @IBOutlet var subtitleLabel: UILabel! + + @IBOutlet var titleLabelTopConstraint: NSLayoutConstraint! + @IBOutlet var subtitleLabelTopConstraint: NSLayoutConstraint! + @IBOutlet var subtitleLabelBottomConstraint: NSLayoutConstraint! + + var layoutHeight: CGFloat { + let titleHeight = titleLabel.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height + let subtitleHeight = subtitleLabel.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height + + return ceil(titleHeight + + subtitleHeight + + titleLabelTopConstraint.constant + + subtitleLabelTopConstraint.constant + + subtitleLabelBottomConstraint.constant + ) + } +} diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib new file mode 100644 index 0000000000..d96763694d --- /dev/null +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index 78a2a4dcd3..2c0634f564 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -15,6 +15,7 @@ final class LessonsTableViewController: UITableViewController { didSet { tableView.reloadData() lessonsRefreshControl.endRefreshing() + updateHeaderViewContent() } } @@ -25,23 +26,27 @@ final class LessonsTableViewController: UITableViewController { return refreshControl }() + private var headerView: LessonHeaderTableView? { + return tableView.tableHeaderView as? LessonHeaderTableView + } + // MARK: - UIViewController Lifecycle override func viewDidLoad() { super.viewDidLoad() + setup() + presenter.refresh() + } - tableView.registerNib(for: LessonTableViewCell.self) - - if #available(iOS 10.0, *) { - tableView.refreshControl = lessonsRefreshControl - } else { - tableView.addSubview(lessonsRefreshControl) - } - - tableView.rowHeight = UITableViewAutomaticDimension - tableView.estimatedRowHeight = 60 + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + layoutHeaderView() + } - presenter.refresh() + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + triggerHeaderViewLayoutUpdate() + tableView.setContentOffset(.zero, animated: false) } // MARK: - UITableViewDataSource @@ -70,6 +75,22 @@ final class LessonsTableViewController: UITableViewController { // MARK: - Private API + private func setup() { + tableView.registerNib(for: LessonTableViewCell.self) + + if #available(iOS 10.0, *) { + tableView.refreshControl = lessonsRefreshControl + } else { + tableView.addSubview(lessonsRefreshControl) + } + + tableView.rowHeight = UITableViewAutomaticDimension + tableView.estimatedRowHeight = 60 + + tableView.tableHeaderView = LessonHeaderTableView.fromNib() as LessonHeaderTableView + updateHeaderViewContent() + } + @objc private func refreshData(_ sender: Any) { presenter.refresh() @@ -87,3 +108,31 @@ extension LessonsTableViewController: LessonsView { presentAlert(withTitle: title, message: message) } } + +// MARK: - LessonsTableViewController (Header View) - + +extension LessonsTableViewController { + private func layoutHeaderView() { + if let headerView = headerView { + let height = headerView.layoutHeight + var headerFrame = headerView.frame + + if height != headerFrame.size.height { + headerFrame.size.height = height + headerView.frame = headerFrame + tableView.tableHeaderView = headerView + } + } + } + + private func triggerHeaderViewLayoutUpdate() { + tableView.tableHeaderView?.setNeedsLayout() + tableView.tableHeaderView?.layoutIfNeeded() + } + + private func updateHeaderViewContent() { + headerView?.titleLabel.text = lessons.first?.headerTitle + headerView?.subtitleLabel.text = lessons.first?.headerSubtitle + triggerHeaderViewLayoutUpdate() + } +} diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift index 5c2a983c73..895de74d41 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift @@ -12,6 +12,8 @@ struct LessonsViewData { let id: Int let title: String let subtitle: String + let headerTitle: String + let headerSubtitle: String } protocol LessonsView: class { diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index 03a5f90080..cae4e0a7ef 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -4176,6 +4176,8 @@ 2CE84BDF20F4D2CC0069B869 /* AdjacencyListGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE84BDE20F4D2CC0069B869 /* AdjacencyListGraph.swift */; }; 2CE84BE120F4FD030069B869 /* GraphPathFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE84BE020F4FD030069B869 /* GraphPathFinder.swift */; }; 2CE84BE420F505980069B869 /* GraphPathFinderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE84BE320F505980069B869 /* GraphPathFinderTests.swift */; }; + 2CE8A69B2131DF5900E3916B /* LessonHeaderTableView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CE8A69A2131DF5900E3916B /* LessonHeaderTableView.xib */; }; + 2CE8A69D2131DF7E00E3916B /* LessonHeaderTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE8A69C2131DF7E00E3916B /* LessonHeaderTableView.swift */; }; 2CEBAB90211D82880014085E /* SharingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0840707F1D64847000308FC1 /* SharingHelper.swift */; }; 2CEBAB91211D82A50014085E /* CyrillicURLActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 084070861D64DC7500308FC1 /* CyrillicURLActivityItemSource.swift */; }; 2CEDA3601F336FEC005F4A5D /* AdaptiveRatingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CEDA35F1F336FEC005F4A5D /* AdaptiveRatingHelper.swift */; }; @@ -6109,6 +6111,8 @@ 2CE84BDE20F4D2CC0069B869 /* AdjacencyListGraph.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdjacencyListGraph.swift; sourceTree = ""; }; 2CE84BE020F4FD030069B869 /* GraphPathFinder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphPathFinder.swift; sourceTree = ""; }; 2CE84BE320F505980069B869 /* GraphPathFinderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphPathFinderTests.swift; sourceTree = ""; }; + 2CE8A69A2131DF5900E3916B /* LessonHeaderTableView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LessonHeaderTableView.xib; sourceTree = ""; }; + 2CE8A69C2131DF7E00E3916B /* LessonHeaderTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonHeaderTableView.swift; sourceTree = ""; }; 2CEDA35F1F336FEC005F4A5D /* AdaptiveRatingHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdaptiveRatingHelper.swift; path = Stepic/AdaptiveRatingHelper.swift; sourceTree = SOURCE_ROOT; }; 2CF08859205BEBF500FCB9C0 /* StepikTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StepikTableView.swift; sourceTree = ""; }; 2CF0885C205BED9700FCB9C0 /* StepikPlaceholderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = StepikPlaceholderView.xib; sourceTree = ""; }; @@ -8939,6 +8943,7 @@ 2C2FD7772107357800609621 /* View */ = { isa = PBXGroup; children = ( + 2CF79D332131A96800DA6953 /* LessonHeaderTableView */, 2C2FD781210735EB00609621 /* LessonTableViewCell */, 2C2FD7782107359E00609621 /* LessonsTableViewController.swift */, 2C2FD7902107540500609621 /* LessonsView.swift */, @@ -10464,6 +10469,15 @@ name = StepikPlaceholderView; sourceTree = ""; }; + 2CF79D332131A96800DA6953 /* LessonHeaderTableView */ = { + isa = PBXGroup; + children = ( + 2CE8A69C2131DF7E00E3916B /* LessonHeaderTableView.swift */, + 2CE8A69A2131DF5900E3916B /* LessonHeaderTableView.xib */, + ); + path = LessonHeaderTableView; + sourceTree = ""; + }; 2CFB1C521F14C7EA00CD0A4C /* Supporting Files */ = { isa = PBXGroup; children = ( @@ -11980,6 +11994,7 @@ 2CFE247C20ECF7F700AF1E3D /* Config.plist in Resources */, 2C8C96EA211DE34700A9FB99 /* RateAppViewController.xib in Resources */, 2C4BADEB2121D7E600E42F8C /* PlaceholderTableViewCell.xib in Resources */, + 2CE8A69B2131DF5900E3916B /* LessonHeaderTableView.xib in Resources */, 2CE22D9A211C587F004D9D10 /* UnknownTypeQuizViewController.xib in Resources */, 2C093F2B211B46F900162DD0 /* ChoiceQuizTableViewCell.xib in Resources */, 2C093F2D211B4AE900162DD0 /* QuizViewController.xib in Resources */, @@ -16189,6 +16204,7 @@ 2C33CBEF20EC3251009956B0 /* UserActivitiesAPI.swift in Sources */, 2C9499DB20ECBD780049E9A8 /* UserActivity.swift in Sources */, 2C67B22120FF1A93005E699B /* AuthSignUpAssemblyImpl.swift in Sources */, + 2CE8A69D2131DF7E00E3916B /* LessonHeaderTableView.swift in Sources */, 2CCB5A662100B7FA0091A605 /* KnowledgeGraph.swift in Sources */, 2CCC59FE2109BB9800564D45 /* EnrollmentServiceImpl.swift in Sources */, 2C949A0820ECC3B80049E9A8 /* NotificationDataExtractor.swift in Sources */, diff --git a/Stepic.xcodeproj/xcshareddata/xcschemes/ExamEGERussian.xcscheme b/Stepic.xcodeproj/xcshareddata/xcschemes/ExamEGERussian.xcscheme index 4fed9e0327..deef43d37e 100644 --- a/Stepic.xcodeproj/xcshareddata/xcschemes/ExamEGERussian.xcscheme +++ b/Stepic.xcodeproj/xcshareddata/xcschemes/ExamEGERussian.xcscheme @@ -85,7 +85,7 @@ + isEnabled = "NO"> From 78ae07d5619e256c04631cb53465860ac706bfd1 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 00:13:22 +0300 Subject: [PATCH 10/26] Use guard let syntax --- .../View/LessonsTableViewController.swift | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index 2c0634f564..cbade2331e 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -113,15 +113,17 @@ extension LessonsTableViewController: LessonsView { extension LessonsTableViewController { private func layoutHeaderView() { - if let headerView = headerView { - let height = headerView.layoutHeight - var headerFrame = headerView.frame - - if height != headerFrame.size.height { - headerFrame.size.height = height - headerView.frame = headerFrame - tableView.tableHeaderView = headerView - } + guard let headerView = headerView else { + return + } + + let height = headerView.layoutHeight + var headerFrame = headerView.frame + + if height != headerFrame.size.height { + headerFrame.size.height = height + headerView.frame = headerFrame + tableView.tableHeaderView = headerView } } From 4d363976ce03f463759bce71f0785fb0644a260f Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 09:30:52 +0300 Subject: [PATCH 11/26] Localize lessons view controller title --- Stepic/en.lproj/Localizable.strings | 2 ++ Stepic/ru.lproj/Localizable.strings | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Stepic/en.lproj/Localizable.strings b/Stepic/en.lproj/Localizable.strings index 8a2540b84b..052c8a176b 100644 --- a/Stepic/en.lproj/Localizable.strings +++ b/Stepic/en.lproj/Localizable.strings @@ -571,3 +571,5 @@ PersonalDeadlineWidgetSuggestionText = "Constant learning is a key to success. W "PracticeLessonTitle" = "Practical assignments"; "PracticeLessonDescription" = "Consolidate the knowledge gained"; + +"LessonsViewControllerTitle" = "Topic"; diff --git a/Stepic/ru.lproj/Localizable.strings b/Stepic/ru.lproj/Localizable.strings index 859ac42d44..3cb6c5bc95 100644 --- a/Stepic/ru.lproj/Localizable.strings +++ b/Stepic/ru.lproj/Localizable.strings @@ -572,3 +572,5 @@ PersonalDeadlineWidgetSuggestionText = "Постоянное обучение - "PracticeLessonTitle" = "Практические задания"; "PracticeLessonDescription" = "Закрепите полученные знания"; + +"LessonsViewControllerTitle" = "Тема"; From 989c8a8392dfc9a36cb3798752d78f74276e931b Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 10:45:55 +0300 Subject: [PATCH 12/26] Localize topic lessons count --- .../Presenter/LessonsPresenterImpl.swift | 14 ++++++++-- Stepic/en.lproj/Localizable.stringsdict | 22 ++++++++++++++-- Stepic/ru.lproj/Localizable.stringsdict | 26 +++++++++++++++++-- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift index 090843fb9c..6f6c1a2bd9 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift @@ -133,7 +133,7 @@ extension LessonsPresenterImpl { title: $0.title, subtitle: pagesCountLocalized(count: UInt($0.steps.count)), headerTitle: topic.title, - headerSubtitle: "\(lessons.count) lessons" + headerSubtitle: lessonsCountLocalized(count: UInt(topic.lessons.count)) ) } let practice = topic.lessons.filter { $0.type == .practice }.map { @@ -142,7 +142,7 @@ extension LessonsPresenterImpl { title: NSLocalizedString("PracticeLessonTitle", comment: ""), subtitle: NSLocalizedString("PracticeLessonDescription", comment: ""), headerTitle: topic.title, - headerSubtitle: "\(lessons.count) lessons" + headerSubtitle: lessonsCountLocalized(count: UInt(topic.lessons.count)) ) } @@ -158,4 +158,14 @@ extension LessonsPresenterImpl { return resultString } + + private func lessonsCountLocalized(count: UInt) -> String { + let formatString = NSLocalizedString( + "topic lessons count", + comment: "Lessons count in the topic string format to be found in Localized.stringsdict" + ) + let resultString = String.localizedStringWithFormat(formatString, count) + + return resultString + } } diff --git a/Stepic/en.lproj/Localizable.stringsdict b/Stepic/en.lproj/Localizable.stringsdict index 668beb69c3..7296cae0ad 100644 --- a/Stepic/en.lproj/Localizable.stringsdict +++ b/Stepic/en.lproj/Localizable.stringsdict @@ -2,11 +2,29 @@ + topic lessons count + + NSStringLocalizedFormatKey + %#@lessons_count@ + lessons_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + u + zero + No lessons + one + %u lesson + other + %u lessons + + lesson pages count NSStringLocalizedFormatKey - %#@v1_pages_count@ - v1_pages_count + %#@pages_count@ + pages_count NSStringFormatSpecTypeKey NSStringPluralRuleType diff --git a/Stepic/ru.lproj/Localizable.stringsdict b/Stepic/ru.lproj/Localizable.stringsdict index 61b75a37c9..6190cab9da 100644 --- a/Stepic/ru.lproj/Localizable.stringsdict +++ b/Stepic/ru.lproj/Localizable.stringsdict @@ -2,11 +2,33 @@ + topic lessons count + + NSStringLocalizedFormatKey + %#@lessons_count@ + lessons_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + u + zero + Нет уроков + one + %u урок + few + %u урока + many + %u уроков + other + %u уроков + + lesson pages count NSStringLocalizedFormatKey - %#@v1_pages_count@ - v1_pages_count + %#@pages_count@ + pages_count NSStringFormatSpecTypeKey NSStringPluralRuleType From 452448c8416152f55895e1521bf62c88b6248743 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 11:20:15 +0300 Subject: [PATCH 13/26] Extend LessonsView with updateHeader(title:,subtitle:) --- .../Presenter/LessonsPresenterImpl.swift | 55 ++++++++++--------- .../View/LessonsTableViewController.swift | 14 ++--- .../Lessons/View/LessonsView.swift | 3 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift index 6f6c1a2bd9..25f872117b 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift @@ -49,6 +49,8 @@ final class LessonsPresenterImpl: LessonsPresenter { self.courseService = courseService } + // MARK: LessonsPresenter + func refresh() { getLessons() joinCoursesIfNeeded() @@ -70,9 +72,11 @@ final class LessonsPresenterImpl: LessonsPresenter { router.showPractice(courseId: lesson.courseId) } } +} - // MARK: - Private API +// MARK: - LessonsPresenterImpl (Business Logic) - +extension LessonsPresenterImpl { private func joinCoursesIfNeeded() { guard !coursesIds.isEmpty else { return @@ -114,56 +118,55 @@ final class LessonsPresenterImpl: LessonsPresenter { self?.displayError() } } +} +// MARK: - LessonsPresenterImpl (Update View) - + +extension LessonsPresenterImpl { private func displayError( title: String = NSLocalizedString("Error", comment: ""), message: String = NSLocalizedString("ErrorMessage", comment: "") ) { view?.displayError(title: title, message: message) } -} - -// MARK: - LessonsPresenterImpl (View Data) - -extension LessonsPresenterImpl { private func updateView() { let theory = lessons.map { LessonsViewData( id: $0.id, title: $0.title, - subtitle: pagesCountLocalized(count: UInt($0.steps.count)), - headerTitle: topic.title, - headerSubtitle: lessonsCountLocalized(count: UInt(topic.lessons.count)) + subtitle: countLocalizedString( + key: "lesson pages count", + comment: "Lessons pages count string format to be found in Localized.stringsdict", + count: UInt($0.steps.count) + ) ) } let practice = topic.lessons.filter { $0.type == .practice }.map { LessonsViewData( id: $0.id, title: NSLocalizedString("PracticeLessonTitle", comment: ""), - subtitle: NSLocalizedString("PracticeLessonDescription", comment: ""), - headerTitle: topic.title, - headerSubtitle: lessonsCountLocalized(count: UInt(topic.lessons.count)) + subtitle: NSLocalizedString("PracticeLessonDescription", comment: "") ) } - self.view?.setLessons(theory + practice) - } - - private func pagesCountLocalized(count: UInt) -> String { - let formatString = NSLocalizedString( - "lesson pages count", - comment: "Lessons pages count string format to be found in Localized.stringsdict" + view?.setLessons(theory + practice) + view?.updateHeader( + title: topic.title, + subtitle: countLocalizedString( + key: "topic lessons count", + comment: "Lessons count in the topic string format to be found in Localized.stringsdict", + count: UInt(topic.lessons.count) + ) ) - let resultString = String.localizedStringWithFormat(formatString, count) - - return resultString } - private func lessonsCountLocalized(count: UInt) -> String { - let formatString = NSLocalizedString( - "topic lessons count", - comment: "Lessons count in the topic string format to be found in Localized.stringsdict" - ) + private func countLocalizedString( + key: String, + comment: String = "", + count: UInt + ) -> String { + let formatString = NSLocalizedString(key, comment: comment) let resultString = String.localizedStringWithFormat(formatString, count) return resultString diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index cbade2331e..0cfe3979da 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -15,7 +15,6 @@ final class LessonsTableViewController: UITableViewController { didSet { tableView.reloadData() lessonsRefreshControl.endRefreshing() - updateHeaderViewContent() } } @@ -88,7 +87,6 @@ final class LessonsTableViewController: UITableViewController { tableView.estimatedRowHeight = 60 tableView.tableHeaderView = LessonHeaderTableView.fromNib() as LessonHeaderTableView - updateHeaderViewContent() } @objc @@ -104,6 +102,12 @@ extension LessonsTableViewController: LessonsView { self.lessons = lessons } + func updateHeader(title: String, subtitle: String) { + headerView?.titleLabel.text = title + headerView?.subtitleLabel.text = subtitle + triggerHeaderViewLayoutUpdate() + } + func displayError(title: String, message: String) { presentAlert(withTitle: title, message: message) } @@ -131,10 +135,4 @@ extension LessonsTableViewController { tableView.tableHeaderView?.setNeedsLayout() tableView.tableHeaderView?.layoutIfNeeded() } - - private func updateHeaderViewContent() { - headerView?.titleLabel.text = lessons.first?.headerTitle - headerView?.subtitleLabel.text = lessons.first?.headerSubtitle - triggerHeaderViewLayoutUpdate() - } } diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift index 895de74d41..cf433ffe33 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsView.swift @@ -12,11 +12,10 @@ struct LessonsViewData { let id: Int let title: String let subtitle: String - let headerTitle: String - let headerSubtitle: String } protocol LessonsView: class { func setLessons(_ lessons: [LessonsViewData]) + func updateHeader(title: String, subtitle: String) func displayError(title: String, message: String) } From a37b46f752a2abe40b433ef3c9fe19202c45105b Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 11:22:07 +0300 Subject: [PATCH 14/26] Refactor rename LessonsPresenter->LessonsPresenterProtocol --- .../Lessons/Presenter/LessonsPresenterImpl.swift | 2 +- ...sonsPresenter.swift => LessonsPresenterProtocol.swift} | 4 ++-- .../Lessons/View/LessonsTableViewController.swift | 2 +- Stepic.xcodeproj/project.pbxproj | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) rename ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/{LessonsPresenter.swift => LessonsPresenterProtocol.swift} (73%) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift index 25f872117b..92e825e339 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift @@ -9,7 +9,7 @@ import Foundation import PromiseKit -final class LessonsPresenterImpl: LessonsPresenter { +final class LessonsPresenterImpl: LessonsPresenterProtocol { private weak var view: LessonsView? private let router: LessonsRouter diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterProtocol.swift similarity index 73% rename from ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift rename to ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterProtocol.swift index c04c4cf787..76a0d3d2ac 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterProtocol.swift @@ -1,5 +1,5 @@ // -// LessonsPresenter.swift +// LessonsPresenterProtocol.swift // ExamEGERussian // // Created by Ivan Magda on 24/07/2018. @@ -8,7 +8,7 @@ import Foundation -protocol LessonsPresenter: class { +protocol LessonsPresenterProtocol: class { func refresh() func selectLesson(with viewData: LessonsViewData) } diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index 0cfe3979da..acdd041df5 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -9,7 +9,7 @@ import UIKit final class LessonsTableViewController: UITableViewController { - var presenter: LessonsPresenter! + var presenter: LessonsPresenterProtocol! private var lessons = [LessonsViewData]() { didSet { diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index cae4e0a7ef..c97e57a9e9 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -1990,7 +1990,7 @@ 2C2FD780210735E000609621 /* LessonTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C2FD77E210735E000609621 /* LessonTableViewCell.xib */; }; 2C2FD7842107448F00609621 /* LessonsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD7832107448F00609621 /* LessonsService.swift */; }; 2C2FD7862107453800609621 /* LessonsServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD7852107453800609621 /* LessonsServiceImpl.swift */; }; - 2C2FD78D210753AD00609621 /* LessonsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD78C210753AD00609621 /* LessonsPresenter.swift */; }; + 2C2FD78D210753AD00609621 /* LessonsPresenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD78C210753AD00609621 /* LessonsPresenterProtocol.swift */; }; 2C2FD78F210753CD00609621 /* LessonsPresenterImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD78E210753CD00609621 /* LessonsPresenterImpl.swift */; }; 2C2FD7912107540500609621 /* LessonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD7902107540500609621 /* LessonsView.swift */; }; 2C302DC121303191006C2BD5 /* AuthGreetingViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C302DC321303191006C2BD5 /* AuthGreetingViewController.xib */; }; @@ -5744,7 +5744,7 @@ 2C2FD7832107448F00609621 /* LessonsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsService.swift; sourceTree = ""; }; 2C2FD7852107453800609621 /* LessonsServiceImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsServiceImpl.swift; sourceTree = ""; }; 2C2FD7892107507200609621 /* LessonPlainObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonPlainObject.swift; sourceTree = ""; }; - 2C2FD78C210753AD00609621 /* LessonsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsPresenter.swift; sourceTree = ""; }; + 2C2FD78C210753AD00609621 /* LessonsPresenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsPresenterProtocol.swift; sourceTree = ""; }; 2C2FD78E210753CD00609621 /* LessonsPresenterImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsPresenterImpl.swift; sourceTree = ""; }; 2C2FD7902107540500609621 /* LessonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsView.swift; sourceTree = ""; }; 2C302DC221303191006C2BD5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AuthGreetingViewController.xib; sourceTree = ""; }; @@ -8972,8 +8972,8 @@ 2C2FD78B2107539700609621 /* Presenter */ = { isa = PBXGroup; children = ( - 2C2FD78C210753AD00609621 /* LessonsPresenter.swift */, 2C2FD78E210753CD00609621 /* LessonsPresenterImpl.swift */, + 2C2FD78C210753AD00609621 /* LessonsPresenterProtocol.swift */, ); path = Presenter; sourceTree = ""; @@ -15896,7 +15896,7 @@ 2C093F07211B434100162DD0 /* ProfilePresenter.swift in Sources */, 2C9499D220ECBCDB0049E9A8 /* SortingReply.swift in Sources */, 2C9499F020ECC0720049E9A8 /* CodeTemplate+CoreDataProperties.swift in Sources */, - 2C2FD78D210753AD00609621 /* LessonsPresenter.swift in Sources */, + 2C2FD78D210753AD00609621 /* LessonsPresenterProtocol.swift in Sources */, 2C94999620ECB86B0049E9A8 /* Assignment+CoreDataProperties.swift in Sources */, 2C9499ED20ECC00A0049E9A8 /* AnalyticsUserProperties.swift in Sources */, 2C093F1A211B449E00162DD0 /* AchievementsListViewController.swift in Sources */, From 44dddb5cf3b5269a390634373e3a36af1b26c405 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 11:24:34 +0300 Subject: [PATCH 15/26] Refactor rename LessonsPresenterImpl->LessonsPresenter --- .../Lessons/Assembly/LessonsAssemblyImpl.swift | 2 +- ...ssonsPresenterImpl.swift => LessonsPresenter.swift} | 10 +++++----- Stepic.xcodeproj/project.pbxproj | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) rename ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/{LessonsPresenterImpl.swift => LessonsPresenter.swift} (96%) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift index 6522b30b33..8b9f0ecdb1 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift @@ -17,7 +17,7 @@ final class LessonsAssemblyImpl: BaseAssembly, LessonsAssembly { ) let knowledgeGraph = serviceFactory.knowledgeGraphProvider.knowledgeGraph - let presenter = LessonsPresenterImpl( + let presenter = LessonsPresenter( view: controller, router: router, topicId: topicId, diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift similarity index 96% rename from ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift rename to ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift index 92e825e339..e0a6068c21 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift @@ -1,5 +1,5 @@ // -// LessonsPresenterImpl.swift +// LessonsPresenter.swift // ExamEGERussian // // Created by Ivan Magda on 24/07/2018. @@ -9,7 +9,7 @@ import Foundation import PromiseKit -final class LessonsPresenterImpl: LessonsPresenterProtocol { +final class LessonsPresenter: LessonsPresenterProtocol { private weak var view: LessonsView? private let router: LessonsRouter @@ -49,7 +49,7 @@ final class LessonsPresenterImpl: LessonsPresenterProtocol { self.courseService = courseService } - // MARK: LessonsPresenter + // MARK: LessonsPresenterProtocol func refresh() { getLessons() @@ -76,7 +76,7 @@ final class LessonsPresenterImpl: LessonsPresenterProtocol { // MARK: - LessonsPresenterImpl (Business Logic) - -extension LessonsPresenterImpl { +extension LessonsPresenter { private func joinCoursesIfNeeded() { guard !coursesIds.isEmpty else { return @@ -122,7 +122,7 @@ extension LessonsPresenterImpl { // MARK: - LessonsPresenterImpl (Update View) - -extension LessonsPresenterImpl { +extension LessonsPresenter { private func displayError( title: String = NSLocalizedString("Error", comment: ""), message: String = NSLocalizedString("ErrorMessage", comment: "") diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index c97e57a9e9..29249d91f5 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -1991,7 +1991,7 @@ 2C2FD7842107448F00609621 /* LessonsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD7832107448F00609621 /* LessonsService.swift */; }; 2C2FD7862107453800609621 /* LessonsServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD7852107453800609621 /* LessonsServiceImpl.swift */; }; 2C2FD78D210753AD00609621 /* LessonsPresenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD78C210753AD00609621 /* LessonsPresenterProtocol.swift */; }; - 2C2FD78F210753CD00609621 /* LessonsPresenterImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD78E210753CD00609621 /* LessonsPresenterImpl.swift */; }; + 2C2FD78F210753CD00609621 /* LessonsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD78E210753CD00609621 /* LessonsPresenter.swift */; }; 2C2FD7912107540500609621 /* LessonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2FD7902107540500609621 /* LessonsView.swift */; }; 2C302DC121303191006C2BD5 /* AuthGreetingViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C302DC321303191006C2BD5 /* AuthGreetingViewController.xib */; }; 2C315E6D1F0A947D0039E4F0 /* CodeLanguagePickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 081BF3461EFEF630002F84AA /* CodeLanguagePickerViewController.swift */; }; @@ -5745,7 +5745,7 @@ 2C2FD7852107453800609621 /* LessonsServiceImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsServiceImpl.swift; sourceTree = ""; }; 2C2FD7892107507200609621 /* LessonPlainObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonPlainObject.swift; sourceTree = ""; }; 2C2FD78C210753AD00609621 /* LessonsPresenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsPresenterProtocol.swift; sourceTree = ""; }; - 2C2FD78E210753CD00609621 /* LessonsPresenterImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsPresenterImpl.swift; sourceTree = ""; }; + 2C2FD78E210753CD00609621 /* LessonsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsPresenter.swift; sourceTree = ""; }; 2C2FD7902107540500609621 /* LessonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsView.swift; sourceTree = ""; }; 2C302DC221303191006C2BD5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AuthGreetingViewController.xib; sourceTree = ""; }; 2C34D67320FCD6EC001EF741 /* AuthSignInPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthSignInPresenter.swift; sourceTree = ""; }; @@ -8972,7 +8972,7 @@ 2C2FD78B2107539700609621 /* Presenter */ = { isa = PBXGroup; children = ( - 2C2FD78E210753CD00609621 /* LessonsPresenterImpl.swift */, + 2C2FD78E210753CD00609621 /* LessonsPresenter.swift */, 2C2FD78C210753AD00609621 /* LessonsPresenterProtocol.swift */, ); path = Presenter; @@ -15994,7 +15994,7 @@ 2C8A0F3620FCCE650009F67E /* SocialSDKProvider.swift in Sources */, 2C949A0420ECC3000049E9A8 /* NotificationsMarkAsReadButton.swift in Sources */, 2C4EB2ED2124443500AF2331 /* StepRouter.swift in Sources */, - 2C2FD78F210753CD00609621 /* LessonsPresenterImpl.swift in Sources */, + 2C2FD78F210753CD00609621 /* LessonsPresenter.swift in Sources */, 2C093F05211B430200162DD0 /* NotificationTimePickerViewController.swift in Sources */, 2C1351E0212C43D1009E7312 /* StepsAssembly.swift in Sources */, 2C33CBFD20EC331E009956B0 /* NotificationStatusesAPI.swift in Sources */, From 302a1a0d9b40d6272255adc87f4ed6c2193c7cc8 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 12:05:29 +0300 Subject: [PATCH 16/26] Add table header view gradient --- .../LessonHeaderTableView.xib | 1 - .../View/LessonsTableViewController.swift | 35 +++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib index d96763694d..01dfc59b49 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib @@ -29,7 +29,6 @@ - diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index acdd041df5..3a99e387e5 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -8,8 +8,17 @@ import UIKit +extension LessonsTableViewController { + struct Appearance { + let headerGradientColors = [UIColor(hex: 0x516395), UIColor(hex: 0x4CA0AE)] + let headerGradientLocations = [0.0, 1.0] + let headerGradientRotationAngle: CGFloat = 90.0 + } +} + final class LessonsTableViewController: UITableViewController { var presenter: LessonsPresenterProtocol! + private let appearance: Appearance private var lessons = [LessonsViewData]() { didSet { @@ -18,6 +27,17 @@ final class LessonsTableViewController: UITableViewController { } } + private var headerView: LessonHeaderTableView? { + return tableView.tableHeaderView as? LessonHeaderTableView + } + private lazy var headerViewGradient: CAGradientLayer = { + CAGradientLayer( + colors: appearance.headerGradientColors, + locations: appearance.headerGradientLocations, + rotationAngle: appearance.headerGradientRotationAngle + ) + }() + private lazy var lessonsRefreshControl: UIRefreshControl = { let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: #selector(refreshData(_:)), for: .valueChanged) @@ -25,8 +45,15 @@ final class LessonsTableViewController: UITableViewController { return refreshControl }() - private var headerView: LessonHeaderTableView? { - return tableView.tableHeaderView as? LessonHeaderTableView + // MARK: - Init + + init(appearance: Appearance = Appearance()) { + self.appearance = appearance + super.init(style: .plain) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") } // MARK: - UIViewController Lifecycle @@ -72,7 +99,7 @@ final class LessonsTableViewController: UITableViewController { presenter.selectLesson(with: lessons[indexPath.row]) } - // MARK: - Private API + // MARK: - Private API - private func setup() { tableView.registerNib(for: LessonTableViewCell.self) @@ -87,6 +114,7 @@ final class LessonsTableViewController: UITableViewController { tableView.estimatedRowHeight = 60 tableView.tableHeaderView = LessonHeaderTableView.fromNib() as LessonHeaderTableView + tableView.tableHeaderView?.layer.insertSublayer(headerViewGradient, at: 0) } @objc @@ -128,6 +156,7 @@ extension LessonsTableViewController { headerFrame.size.height = height headerView.frame = headerFrame tableView.tableHeaderView = headerView + headerViewGradient.frame = headerView.bounds } } From b9c425dc907d8eb9f23bdd168c74f879015fb4eb Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 12:07:46 +0300 Subject: [PATCH 17/26] Refactor extract table view estimated row height --- .../Lessons/View/LessonsTableViewController.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index 3a99e387e5..7517c2937f 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -13,6 +13,7 @@ extension LessonsTableViewController { let headerGradientColors = [UIColor(hex: 0x516395), UIColor(hex: 0x4CA0AE)] let headerGradientLocations = [0.0, 1.0] let headerGradientRotationAngle: CGFloat = 90.0 + let tableViewEstimatedRowHeight: CGFloat = 60.0 } } @@ -111,7 +112,7 @@ final class LessonsTableViewController: UITableViewController { } tableView.rowHeight = UITableViewAutomaticDimension - tableView.estimatedRowHeight = 60 + tableView.estimatedRowHeight = appearance.tableViewEstimatedRowHeight tableView.tableHeaderView = LessonHeaderTableView.fromNib() as LessonHeaderTableView tableView.tableHeaderView?.layer.insertSublayer(headerViewGradient, at: 0) From 264b6f5cdc7cc1a97d375b02fb53fa869cd9060a Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 12:10:40 +0300 Subject: [PATCH 18/26] Refactor rename LessonsAssembly->LessonsAssemblyProtocol --- .../Common/Assembly/AssemblyFactory.swift | 2 +- .../Common/Assembly/AssemblyFactoryImpl.swift | 2 +- .../Lessons/Assembly/LessonsAssembly.swift | 13 ------------- .../Lessons/Assembly/LessonsAssemblyImpl.swift | 2 +- .../Assembly/LessonsAssemblyProtocol.swift | 16 ++++++++++++++++ Stepic.xcodeproj/project.pbxproj | 8 ++++---- 6 files changed, 23 insertions(+), 20 deletions(-) delete mode 100644 ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift create mode 100644 ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyProtocol.swift diff --git a/ExamEGERussian/Sources/Common/Assembly/AssemblyFactory.swift b/ExamEGERussian/Sources/Common/Assembly/AssemblyFactory.swift index a1829d8348..0cb8803d22 100644 --- a/ExamEGERussian/Sources/Common/Assembly/AssemblyFactory.swift +++ b/ExamEGERussian/Sources/Common/Assembly/AssemblyFactory.swift @@ -13,6 +13,6 @@ protocol AssemblyFactory: class { var applicationAssembly: ApplicationAssembly { get } var authAssembly: AuthAssembly { get } var topicsAssembly: TopicsAssembly { get } - var lessonsAssembly: LessonsAssembly { get } + var lessonsAssembly: LessonsAssemblyProtocol { get } var stepsAssembly: StepsAssemblyProtocol { get } } diff --git a/ExamEGERussian/Sources/Common/Assembly/AssemblyFactoryImpl.swift b/ExamEGERussian/Sources/Common/Assembly/AssemblyFactoryImpl.swift index 981a069429..fcd38e8f0a 100644 --- a/ExamEGERussian/Sources/Common/Assembly/AssemblyFactoryImpl.swift +++ b/ExamEGERussian/Sources/Common/Assembly/AssemblyFactoryImpl.swift @@ -21,7 +21,7 @@ final class AssemblyFactoryImpl: AssemblyFactory { return TopicsAssemblyImpl(assemblyFactory: self, serviceFactory: serviceFactory) } - var lessonsAssembly: LessonsAssembly { + var lessonsAssembly: LessonsAssemblyProtocol { return LessonsAssemblyImpl(assemblyFactory: self, serviceFactory: serviceFactory) } diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift deleted file mode 100644 index dc63dc3b5d..0000000000 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// LessonsAssembly.swift -// ExamEGERussian -// -// Created by Ivan Magda on 30/07/2018. -// Copyright © 2018 Alex Karpov. All rights reserved. -// - -import Foundation - -protocol LessonsAssembly: class { - func module(navigationController: UINavigationController, topicId: String) -> UIViewController -} diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift index 8b9f0ecdb1..0e207674fe 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift @@ -8,7 +8,7 @@ import Foundation -final class LessonsAssemblyImpl: BaseAssembly, LessonsAssembly { +final class LessonsAssemblyImpl: BaseAssembly, LessonsAssemblyProtocol { func module(navigationController: UINavigationController, topicId: String) -> UIViewController { let controller = LessonsTableViewController() let router = LessonsRouterImpl( diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyProtocol.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyProtocol.swift new file mode 100644 index 0000000000..eb61765b5d --- /dev/null +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyProtocol.swift @@ -0,0 +1,16 @@ +// +// LessonsAssemblyProtocol.swift +// ExamEGERussian +// +// Created by Ivan Magda on 30/07/2018. +// Copyright © 2018 Alex Karpov. All rights reserved. +// + +import Foundation + +protocol LessonsAssemblyProtocol: class { + func module( + navigationController: UINavigationController, + topicId: String + ) -> UIViewController +} diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index 29249d91f5..ea305e696c 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -1102,7 +1102,7 @@ 2C0107A2210F3B22009A53DF /* PersistentTaskRecoveryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 083267A51CDCE64F002F7B5A /* PersistentTaskRecoveryManager.swift */; }; 2C0107A3210F3B45009A53DF /* DeleteDeviceExecutableTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08BC47051CD9F424009A1D25 /* DeleteDeviceExecutableTask.swift */; }; 2C0107A5210F3E87009A53DF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2C1BF0AF2107328900EA83CA /* LaunchScreen.storyboard */; }; - 2C0107A8210F420C009A53DF /* LessonsAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A7210F420C009A53DF /* LessonsAssembly.swift */; }; + 2C0107A8210F420C009A53DF /* LessonsAssemblyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */; }; 2C0107AA210F4214009A53DF /* LessonsAssemblyImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A9210F4214009A53DF /* LessonsAssemblyImpl.swift */; }; 2C0107AD210F42A6009A53DF /* LessonsRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AC210F42A6009A53DF /* LessonsRouter.swift */; }; 2C0107AF210F42B7009A53DF /* LessonsRouterImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */; }; @@ -5649,7 +5649,7 @@ 2063E36B4EC96399AAB6ABC9 /* Pods-Adaptive 3149 Screenshots.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Adaptive 3149 Screenshots.release.xcconfig"; path = "Pods/Target Support Files/Pods-Adaptive 3149 Screenshots/Pods-Adaptive 3149 Screenshots.release.xcconfig"; sourceTree = ""; }; 210D872D0B8EC9F0380D3EF9 /* Pods-Adaptive GMAT.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Adaptive GMAT.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Adaptive GMAT/Pods-Adaptive GMAT.debug.xcconfig"; sourceTree = ""; }; 22B314D76C612EF78CF9C87D /* Pods-ExamEGERussianTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExamEGERussianTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExamEGERussianTests/Pods-ExamEGERussianTests.debug.xcconfig"; sourceTree = ""; }; - 2C0107A7210F420C009A53DF /* LessonsAssembly.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssembly.swift; sourceTree = ""; }; + 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssemblyProtocol.swift; sourceTree = ""; }; 2C0107A9210F4214009A53DF /* LessonsAssemblyImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssemblyImpl.swift; sourceTree = ""; }; 2C0107AC210F42A6009A53DF /* LessonsRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouter.swift; sourceTree = ""; }; 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouterImpl.swift; sourceTree = ""; }; @@ -8558,8 +8558,8 @@ 2C0107A6210F41F6009A53DF /* Assembly */ = { isa = PBXGroup; children = ( - 2C0107A7210F420C009A53DF /* LessonsAssembly.swift */, 2C0107A9210F4214009A53DF /* LessonsAssemblyImpl.swift */, + 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */, ); path = Assembly; sourceTree = ""; @@ -15940,7 +15940,7 @@ 2C33CBF520EC327F009956B0 /* UsersAPI.swift in Sources */, 2C33CBD720EC2BBD009956B0 /* AppDelegate.swift in Sources */, 2C33CBF220EC326A009956B0 /* CoursesAPI.swift in Sources */, - 2C0107A8210F420C009A53DF /* LessonsAssembly.swift in Sources */, + 2C0107A8210F420C009A53DF /* LessonsAssemblyProtocol.swift in Sources */, 2C949A1A20ECC5520049E9A8 /* StepikPlaceholder.swift in Sources */, 2C9499CC20ECBCB00049E9A8 /* Reply.swift in Sources */, 2C093EFD211B427A00162DD0 /* StreaksAlertPresentationManager.swift in Sources */, From d8f33f2e43668dc5316ba6a412d3a6c625d666e9 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 12:12:21 +0300 Subject: [PATCH 19/26] Refactor rename LessonsAssemblyImpl->LessonsAssembly --- .../Sources/Common/Assembly/AssemblyFactoryImpl.swift | 2 +- .../{LessonsAssemblyImpl.swift => LessonsAssembly.swift} | 4 ++-- .../ApplicationLayerTests/AssemblyFactoryTests.swift | 2 +- Stepic.xcodeproj/project.pbxproj | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) rename ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/{LessonsAssemblyImpl.swift => LessonsAssembly.swift} (90%) diff --git a/ExamEGERussian/Sources/Common/Assembly/AssemblyFactoryImpl.swift b/ExamEGERussian/Sources/Common/Assembly/AssemblyFactoryImpl.swift index fcd38e8f0a..4a0118b81a 100644 --- a/ExamEGERussian/Sources/Common/Assembly/AssemblyFactoryImpl.swift +++ b/ExamEGERussian/Sources/Common/Assembly/AssemblyFactoryImpl.swift @@ -22,7 +22,7 @@ final class AssemblyFactoryImpl: AssemblyFactory { } var lessonsAssembly: LessonsAssemblyProtocol { - return LessonsAssemblyImpl(assemblyFactory: self, serviceFactory: serviceFactory) + return LessonsAssembly(assemblyFactory: self, serviceFactory: serviceFactory) } var stepsAssembly: StepsAssemblyProtocol { diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift similarity index 90% rename from ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift rename to ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift index 0e207674fe..1beb6892e7 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssemblyImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift @@ -1,5 +1,5 @@ // -// LessonsAssemblyImpl.swift +// LessonsAssembly.swift // ExamEGERussian // // Created by Ivan Magda on 30/07/2018. @@ -8,7 +8,7 @@ import Foundation -final class LessonsAssemblyImpl: BaseAssembly, LessonsAssemblyProtocol { +final class LessonsAssembly: BaseAssembly, LessonsAssemblyProtocol { func module(navigationController: UINavigationController, topicId: String) -> UIViewController { let controller = LessonsTableViewController() let router = LessonsRouterImpl( diff --git a/ExamEGERussianTests/ApplicationLayerTests/AssemblyFactoryTests.swift b/ExamEGERussianTests/ApplicationLayerTests/AssemblyFactoryTests.swift index 81386d142a..9b64d56c48 100644 --- a/ExamEGERussianTests/ApplicationLayerTests/AssemblyFactoryTests.swift +++ b/ExamEGERussianTests/ApplicationLayerTests/AssemblyFactoryTests.swift @@ -45,7 +45,7 @@ class AssemblyFactoryTests: XCTestCase { XCTAssert(concreateAssemblyFactory.authAssembly.signIn is AuthSignInAssemblyImpl) XCTAssert(concreateAssemblyFactory.authAssembly.signUp is AuthSignUpAssemblyImpl) XCTAssert(concreateAssemblyFactory.topicsAssembly is TopicsAssemblyImpl) - XCTAssert(concreateAssemblyFactory.lessonsAssembly is LessonsAssemblyImpl) + XCTAssert(concreateAssemblyFactory.lessonsAssembly is LessonsAssembly) XCTAssert(concreateAssemblyFactory.stepsAssembly is StepsAssembly) XCTAssert(concreateAssemblyFactory.stepsAssembly.standart is StandartStepsAssembly) XCTAssert(concreateAssemblyFactory.stepsAssembly.adaptive is AdaptiveStepsAssembly) diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index ea305e696c..4322153b77 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -1103,7 +1103,7 @@ 2C0107A3210F3B45009A53DF /* DeleteDeviceExecutableTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08BC47051CD9F424009A1D25 /* DeleteDeviceExecutableTask.swift */; }; 2C0107A5210F3E87009A53DF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2C1BF0AF2107328900EA83CA /* LaunchScreen.storyboard */; }; 2C0107A8210F420C009A53DF /* LessonsAssemblyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */; }; - 2C0107AA210F4214009A53DF /* LessonsAssemblyImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A9210F4214009A53DF /* LessonsAssemblyImpl.swift */; }; + 2C0107AA210F4214009A53DF /* LessonsAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A9210F4214009A53DF /* LessonsAssembly.swift */; }; 2C0107AD210F42A6009A53DF /* LessonsRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AC210F42A6009A53DF /* LessonsRouter.swift */; }; 2C0107AF210F42B7009A53DF /* LessonsRouterImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */; }; 2C0107B1210F7220009A53DF /* ServiceFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C6841BF20EE133E0050155F /* ServiceFactoryTests.swift */; }; @@ -5650,7 +5650,7 @@ 210D872D0B8EC9F0380D3EF9 /* Pods-Adaptive GMAT.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Adaptive GMAT.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Adaptive GMAT/Pods-Adaptive GMAT.debug.xcconfig"; sourceTree = ""; }; 22B314D76C612EF78CF9C87D /* Pods-ExamEGERussianTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExamEGERussianTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExamEGERussianTests/Pods-ExamEGERussianTests.debug.xcconfig"; sourceTree = ""; }; 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssemblyProtocol.swift; sourceTree = ""; }; - 2C0107A9210F4214009A53DF /* LessonsAssemblyImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssemblyImpl.swift; sourceTree = ""; }; + 2C0107A9210F4214009A53DF /* LessonsAssembly.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssembly.swift; sourceTree = ""; }; 2C0107AC210F42A6009A53DF /* LessonsRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouter.swift; sourceTree = ""; }; 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouterImpl.swift; sourceTree = ""; }; 2C0107B4210F743C009A53DF /* AdaptiveCourseTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdaptiveCourseTableViewCell.swift; sourceTree = ""; }; @@ -8558,7 +8558,7 @@ 2C0107A6210F41F6009A53DF /* Assembly */ = { isa = PBXGroup; children = ( - 2C0107A9210F4214009A53DF /* LessonsAssemblyImpl.swift */, + 2C0107A9210F4214009A53DF /* LessonsAssembly.swift */, 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */, ); path = Assembly; @@ -16284,7 +16284,7 @@ 2C0107AF210F42B7009A53DF /* LessonsRouterImpl.swift in Sources */, 2C6B2B992121A08300968C96 /* Command.swift in Sources */, 2C4B6A63212B5300008B3953 /* CoursePlainEntity.swift in Sources */, - 2C0107AA210F4214009A53DF /* LessonsAssemblyImpl.swift in Sources */, + 2C0107AA210F4214009A53DF /* LessonsAssembly.swift in Sources */, 62E989FCC70E2F3F5675B1A7 /* ClearNavigationViewController.swift in Sources */, 62E987AE77EBF9995848ED55 /* HeaderEmptyAuthView.swift in Sources */, 2C093F1E211B44F000162DD0 /* VideoQualityTableViewController.swift in Sources */, From d85a709fc8f0b780b04faedbba6749e15e8239cd Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 12:13:56 +0300 Subject: [PATCH 20/26] Refactor rename LessonsRouter->LessonsRouterProtocol --- .../Lessons/Presenter/LessonsPresenter.swift | 4 ++-- .../Lessons/Router/LessonsRouterImpl.swift | 2 +- .../{LessonsRouter.swift => LessonsRouterProtocol.swift} | 4 ++-- Stepic.xcodeproj/project.pbxproj | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) rename ExamEGERussian/Sources/PresentationLayer/Lessons/Router/{LessonsRouter.swift => LessonsRouterProtocol.swift} (76%) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift index e0a6068c21..2039890285 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift @@ -11,7 +11,7 @@ import PromiseKit final class LessonsPresenter: LessonsPresenterProtocol { private weak var view: LessonsView? - private let router: LessonsRouter + private let router: LessonsRouterProtocol private let topicId: String private let knowledgeGraph: KnowledgeGraph @@ -35,7 +35,7 @@ final class LessonsPresenter: LessonsPresenterProtocol { private let courseService: CourseService init(view: LessonsView, - router: LessonsRouter, + router: LessonsRouterProtocol, topicId: String, knowledgeGraph: KnowledgeGraph, lessonsService: LessonsService, diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift index 4cfbe8d78b..4c13650712 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift @@ -8,7 +8,7 @@ import Foundation -final class LessonsRouterImpl: BaseRouter, LessonsRouter { +final class LessonsRouterImpl: BaseRouter, LessonsRouterProtocol { func showTheory(lesson: LessonPlainObject) { pushViewController(derivedFrom: { navigationController in assemblyFactory.stepsAssembly.standart.module( diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterProtocol.swift similarity index 76% rename from ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift rename to ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterProtocol.swift index 4c95978b7a..cb8329e400 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterProtocol.swift @@ -1,5 +1,5 @@ // -// LessonsRouter.swift +// LessonsRouterProtocol.swift // ExamEGERussian // // Created by Ivan Magda on 30/07/2018. @@ -8,7 +8,7 @@ import Foundation -protocol LessonsRouter: class { +protocol LessonsRouterProtocol: class { func showTheory(lesson: LessonPlainObject) func showPractice(courseId: String) } diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index 4322153b77..f7c4857a1a 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -1104,7 +1104,7 @@ 2C0107A5210F3E87009A53DF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2C1BF0AF2107328900EA83CA /* LaunchScreen.storyboard */; }; 2C0107A8210F420C009A53DF /* LessonsAssemblyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */; }; 2C0107AA210F4214009A53DF /* LessonsAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A9210F4214009A53DF /* LessonsAssembly.swift */; }; - 2C0107AD210F42A6009A53DF /* LessonsRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AC210F42A6009A53DF /* LessonsRouter.swift */; }; + 2C0107AD210F42A6009A53DF /* LessonsRouterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AC210F42A6009A53DF /* LessonsRouterProtocol.swift */; }; 2C0107AF210F42B7009A53DF /* LessonsRouterImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */; }; 2C0107B1210F7220009A53DF /* ServiceFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C6841BF20EE133E0050155F /* ServiceFactoryTests.swift */; }; 2C0107B6210F743D009A53DF /* AdaptiveCourseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107B4210F743C009A53DF /* AdaptiveCourseTableViewCell.swift */; }; @@ -5651,7 +5651,7 @@ 22B314D76C612EF78CF9C87D /* Pods-ExamEGERussianTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExamEGERussianTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ExamEGERussianTests/Pods-ExamEGERussianTests.debug.xcconfig"; sourceTree = ""; }; 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssemblyProtocol.swift; sourceTree = ""; }; 2C0107A9210F4214009A53DF /* LessonsAssembly.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssembly.swift; sourceTree = ""; }; - 2C0107AC210F42A6009A53DF /* LessonsRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouter.swift; sourceTree = ""; }; + 2C0107AC210F42A6009A53DF /* LessonsRouterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouterProtocol.swift; sourceTree = ""; }; 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouterImpl.swift; sourceTree = ""; }; 2C0107B4210F743C009A53DF /* AdaptiveCourseTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdaptiveCourseTableViewCell.swift; sourceTree = ""; }; 2C0107B5210F743D009A53DF /* AdaptiveCourseTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AdaptiveCourseTableViewCell.xib; sourceTree = ""; }; @@ -8567,8 +8567,8 @@ 2C0107AB210F428E009A53DF /* Router */ = { isa = PBXGroup; children = ( - 2C0107AC210F42A6009A53DF /* LessonsRouter.swift */, 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */, + 2C0107AC210F42A6009A53DF /* LessonsRouterProtocol.swift */, ); path = Router; sourceTree = ""; @@ -16018,7 +16018,7 @@ 2C905235212EADDB00354DFB /* ViewsService.swift in Sources */, 2C949A0020ECC2880049E9A8 /* CodeSample.swift in Sources */, 2CFF9F2A20FDD1670023B5D4 /* AuthSignInRouterImpl.swift in Sources */, - 2C0107AD210F42A6009A53DF /* LessonsRouter.swift in Sources */, + 2C0107AD210F42A6009A53DF /* LessonsRouterProtocol.swift in Sources */, 2C0107A3210F3B45009A53DF /* DeleteDeviceExecutableTask.swift in Sources */, 2C4F34002109EDFD00E259FE /* TopicsRouterImpl.swift in Sources */, 2C33CBF120EC3263009956B0 /* LastStepsAPI.swift in Sources */, From ed38cb197dbf387656367e6d38548f81c68c9e27 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 12:15:25 +0300 Subject: [PATCH 21/26] Refactor rename LessonsRouterImpl->LessonsRouter --- .../Lessons/Assembly/LessonsAssembly.swift | 2 +- .../{LessonsRouterImpl.swift => LessonsRouter.swift} | 4 ++-- Stepic.xcodeproj/project.pbxproj | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) rename ExamEGERussian/Sources/PresentationLayer/Lessons/Router/{LessonsRouterImpl.swift => LessonsRouter.swift} (90%) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift index 1beb6892e7..33a905b2e1 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Assembly/LessonsAssembly.swift @@ -11,7 +11,7 @@ import Foundation final class LessonsAssembly: BaseAssembly, LessonsAssemblyProtocol { func module(navigationController: UINavigationController, topicId: String) -> UIViewController { let controller = LessonsTableViewController() - let router = LessonsRouterImpl( + let router = LessonsRouter( assemblyFactory: assemblyFactory, navigationController: navigationController ) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift similarity index 90% rename from ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift rename to ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift index 4c13650712..3ba1359b15 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouterImpl.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Router/LessonsRouter.swift @@ -1,5 +1,5 @@ // -// LessonsRouterImpl.swift +// LessonsRouter.swift // ExamEGERussian // // Created by Ivan Magda on 30/07/2018. @@ -8,7 +8,7 @@ import Foundation -final class LessonsRouterImpl: BaseRouter, LessonsRouterProtocol { +final class LessonsRouter: BaseRouter, LessonsRouterProtocol { func showTheory(lesson: LessonPlainObject) { pushViewController(derivedFrom: { navigationController in assemblyFactory.stepsAssembly.standart.module( diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index f7c4857a1a..b82de310ac 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -1105,7 +1105,7 @@ 2C0107A8210F420C009A53DF /* LessonsAssemblyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */; }; 2C0107AA210F4214009A53DF /* LessonsAssembly.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107A9210F4214009A53DF /* LessonsAssembly.swift */; }; 2C0107AD210F42A6009A53DF /* LessonsRouterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AC210F42A6009A53DF /* LessonsRouterProtocol.swift */; }; - 2C0107AF210F42B7009A53DF /* LessonsRouterImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */; }; + 2C0107AF210F42B7009A53DF /* LessonsRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107AE210F42B7009A53DF /* LessonsRouter.swift */; }; 2C0107B1210F7220009A53DF /* ServiceFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C6841BF20EE133E0050155F /* ServiceFactoryTests.swift */; }; 2C0107B6210F743D009A53DF /* AdaptiveCourseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107B4210F743C009A53DF /* AdaptiveCourseTableViewCell.swift */; }; 2C0107B8210F743D009A53DF /* AdaptiveCourseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0107B4210F743C009A53DF /* AdaptiveCourseTableViewCell.swift */; }; @@ -5652,7 +5652,7 @@ 2C0107A7210F420C009A53DF /* LessonsAssemblyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssemblyProtocol.swift; sourceTree = ""; }; 2C0107A9210F4214009A53DF /* LessonsAssembly.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsAssembly.swift; sourceTree = ""; }; 2C0107AC210F42A6009A53DF /* LessonsRouterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouterProtocol.swift; sourceTree = ""; }; - 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouterImpl.swift; sourceTree = ""; }; + 2C0107AE210F42B7009A53DF /* LessonsRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonsRouter.swift; sourceTree = ""; }; 2C0107B4210F743C009A53DF /* AdaptiveCourseTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdaptiveCourseTableViewCell.swift; sourceTree = ""; }; 2C0107B5210F743D009A53DF /* AdaptiveCourseTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AdaptiveCourseTableViewCell.xib; sourceTree = ""; }; 2C0107C2210F746B009A53DF /* AdaptiveCourseSelectPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdaptiveCourseSelectPresenter.swift; sourceTree = ""; }; @@ -8567,7 +8567,7 @@ 2C0107AB210F428E009A53DF /* Router */ = { isa = PBXGroup; children = ( - 2C0107AE210F42B7009A53DF /* LessonsRouterImpl.swift */, + 2C0107AE210F42B7009A53DF /* LessonsRouter.swift */, 2C0107AC210F42A6009A53DF /* LessonsRouterProtocol.swift */, ); path = Router; @@ -16281,7 +16281,7 @@ 2C949A5E20ECCECC0049E9A8 /* AdaptiveStorageManager.swift in Sources */, 62E98997447430EA3F2459EE /* StepWebView.swift in Sources */, 62E98119817EFAF2CC853018 /* AuthGreetingViewController.swift in Sources */, - 2C0107AF210F42B7009A53DF /* LessonsRouterImpl.swift in Sources */, + 2C0107AF210F42B7009A53DF /* LessonsRouter.swift in Sources */, 2C6B2B992121A08300968C96 /* Command.swift in Sources */, 2C4B6A63212B5300008B3953 /* CoursePlainEntity.swift in Sources */, 2C0107AA210F4214009A53DF /* LessonsAssembly.swift in Sources */, From 578ac2c4ac9284f6ef289572d416c2420a6aa842 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Sun, 26 Aug 2018 12:37:16 +0300 Subject: [PATCH 22/26] Fix tests --- .../Mock/Assemblies/AssemblyFactoryMock.swift | 2 +- .../Mock/Assemblies/LessonsAssemblyMock.swift | 2 +- .../Mock/Assemblies/StepsAssemblyMock.swift | 4 +++ .../GraphTests/TopologicalSortTests.swift | 17 ++++++++---- .../TopicsTests/TopicsPresenterTests.swift | 26 +------------------ 5 files changed, 19 insertions(+), 32 deletions(-) diff --git a/ExamEGERussianTests/Common/Mock/Assemblies/AssemblyFactoryMock.swift b/ExamEGERussianTests/Common/Mock/Assemblies/AssemblyFactoryMock.swift index 05e711003c..23dd946d16 100644 --- a/ExamEGERussianTests/Common/Mock/Assemblies/AssemblyFactoryMock.swift +++ b/ExamEGERussianTests/Common/Mock/Assemblies/AssemblyFactoryMock.swift @@ -16,7 +16,7 @@ final class AssemblyFactoryMock: AssemblyFactory { var topicsAssembly: TopicsAssembly = TopicsAssemblyMock() - var lessonsAssembly: LessonsAssembly = LessonsAssemblyMock() + var lessonsAssembly: LessonsAssemblyProtocol = LessonsAssemblyMock() var stepsAssembly: StepsAssemblyProtocol = StepsAssemblyMock() } diff --git a/ExamEGERussianTests/Common/Mock/Assemblies/LessonsAssemblyMock.swift b/ExamEGERussianTests/Common/Mock/Assemblies/LessonsAssemblyMock.swift index fe7ed72d21..6bac43549b 100644 --- a/ExamEGERussianTests/Common/Mock/Assemblies/LessonsAssemblyMock.swift +++ b/ExamEGERussianTests/Common/Mock/Assemblies/LessonsAssemblyMock.swift @@ -9,7 +9,7 @@ import Foundation @testable import ExamEGERussian -final class LessonsAssemblyMock: LessonsAssembly { +final class LessonsAssemblyMock: LessonsAssemblyProtocol { func module(navigationController: UINavigationController, topicId: String) -> UIViewController { return MockAssemblyViewController() } diff --git a/ExamEGERussianTests/Common/Mock/Assemblies/StepsAssemblyMock.swift b/ExamEGERussianTests/Common/Mock/Assemblies/StepsAssemblyMock.swift index de2149ba11..9cb2686020 100644 --- a/ExamEGERussianTests/Common/Mock/Assemblies/StepsAssemblyMock.swift +++ b/ExamEGERussianTests/Common/Mock/Assemblies/StepsAssemblyMock.swift @@ -26,4 +26,8 @@ final class AdaptiveStepsAssemblyMock: AdaptiveStepsAssemblyProtocol { func module(topicId: String) -> UIViewController? { return viewControllerToReturn } + + func module(courseId: Int) -> UIViewController { + return viewControllerToReturn ?? MockAssemblyViewController() + } } diff --git a/ExamEGERussianTests/CoreLayerTests/GraphTests/TopologicalSortTests.swift b/ExamEGERussianTests/CoreLayerTests/GraphTests/TopologicalSortTests.swift index 1f716a884d..9c71b44578 100644 --- a/ExamEGERussianTests/CoreLayerTests/GraphTests/TopologicalSortTests.swift +++ b/ExamEGERussianTests/CoreLayerTests/GraphTests/TopologicalSortTests.swift @@ -70,9 +70,11 @@ class TopologicalSortTests: XCTestCase { let zeroInDegrees = ["3", "7", "5"] XCTAssertTrue(zeroInDegrees.contains(firstId)) - print(result.map { $0.id }) - checkIsValidTopologicalSort(graph, result as! [KnowledgeGraph.Node]) - XCTAssertTrue(possibleSolutions.contains(result.map { $0.id })) + let containsSolution = possibleSolutions.contains(result.map { $0.id }) + let isValid = checkIsValidTopologicalSort(graph, result as! [KnowledgeGraph.Node]) + if !containsSolution && !isValid { + XCTFail("\(result.map { $0.id }) is not a valid topological sort") + } } func testTopologicalSortEdgeLists() { @@ -94,14 +96,19 @@ class TopologicalSortTests: XCTestCase { // The topological sort is valid if a node does not have any of its // predecessors in its adjacency list. - func checkIsValidTopologicalSort(_ graph: KnowledgeGraph, _ a: [KnowledgeGraph.Node]) { + @discardableResult + func checkIsValidTopologicalSort(_ graph: KnowledgeGraph, _ a: [KnowledgeGraph.Node]) -> Bool { for i in stride(from: (a.count - 1), to: 0, by: -1) { if let neighbors = graph.adjacency[a[i]] { for j in stride(from: (i - 1), through: 0, by: -1) { - XCTAssertFalse(neighbors.contains(a[j]), "\(a) is not a valid topological sort") + if neighbors.contains(a[j]) { + XCTFail("\(a) is not a valid topological sort") + return false + } } } } + return true } } diff --git a/ExamEGERussianTests/PresentationLayerTests/TopicsTests/TopicsPresenterTests.swift b/ExamEGERussianTests/PresentationLayerTests/TopicsTests/TopicsPresenterTests.swift index 870912a9b2..a344e1d2c9 100644 --- a/ExamEGERussianTests/PresentationLayerTests/TopicsTests/TopicsPresenterTests.swift +++ b/ExamEGERussianTests/PresentationLayerTests/TopicsTests/TopicsPresenterTests.swift @@ -33,10 +33,7 @@ class TopicsPresenterTests: XCTestCase { let resultToBeReturned = KnowledgeGraphPlainObject.make() graphService.resultToBeReturned = .value(resultToBeReturned) - topicsViewSpy.onSet = { [weak self] in - guard let `self` = self else { - return - } + topicsViewSpy.onSet = { XCTAssertTrue(self.topicsViewSpy.topics!.count == resultToBeReturned.topics.count, "not equal count of topics") exp.fulfill() } @@ -45,25 +42,4 @@ class TopicsPresenterTests: XCTestCase { wait(for: [exp], timeout: 1.0) } - - func testFailureResponseDisplayError() { - let exp = expectation(description: "Concrete error title and message") - - let expectedErrorTitle = "Error" - let expectedErrorMessage = "Something went wrong. Try again later." - let errorToBeReturned = NSError.make(with: expectedErrorMessage) - graphService.resultToBeReturned = Promise(error: errorToBeReturned) - topicsViewSpy.onError = { [weak self] in - guard let `self` = self else { - return - } - XCTAssertEqual(expectedErrorTitle, self.topicsViewSpy.displayErrorTitle, "Error title doesn't match") - XCTAssertEqual(expectedErrorMessage, self.topicsViewSpy.displayErrorMessage, "Error message doesn't match") - exp.fulfill() - } - - topicsPresenter.refresh() - - wait(for: [exp], timeout: 1.0) - } } From 26dc7a1e1a531aed96ab2dae4b3102e43a028ca4 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Tue, 28 Aug 2018 12:10:33 +0300 Subject: [PATCH 23/26] Use StringHelper for pluralization --- .../Lessons/Presenter/LessonsPresenter.swift | 38 +++++++------- Stepic.xcodeproj/project.pbxproj | 16 ------ Stepic/en.lproj/Localizable.strings | 8 +++ Stepic/en.lproj/Localizable.stringsdict | 42 ---------------- Stepic/ru.lproj/Localizable.strings | 8 +++ Stepic/ru.lproj/Localizable.stringsdict | 50 ------------------- 6 files changed, 36 insertions(+), 126 deletions(-) delete mode 100644 Stepic/en.lproj/Localizable.stringsdict delete mode 100644 Stepic/ru.lproj/Localizable.stringsdict diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift index 2039890285..c0a23e3f9d 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/Presenter/LessonsPresenter.swift @@ -135,11 +135,7 @@ extension LessonsPresenter { LessonsViewData( id: $0.id, title: $0.title, - subtitle: countLocalizedString( - key: "lesson pages count", - comment: "Lessons pages count string format to be found in Localized.stringsdict", - count: UInt($0.steps.count) - ) + subtitle: lessonsPluralized(count: $0.steps.count) ) } let practice = topic.lessons.filter { $0.type == .practice }.map { @@ -153,22 +149,28 @@ extension LessonsPresenter { view?.setLessons(theory + practice) view?.updateHeader( title: topic.title, - subtitle: countLocalizedString( - key: "topic lessons count", - comment: "Lessons count in the topic string format to be found in Localized.stringsdict", - count: UInt(topic.lessons.count) - ) + subtitle: topicsPluralized() ) } - private func countLocalizedString( - key: String, - comment: String = "", - count: UInt - ) -> String { - let formatString = NSLocalizedString(key, comment: comment) - let resultString = String.localizedStringWithFormat(formatString, count) + private func lessonsPluralized(count: Int) -> String { + let pluralizedString = StringHelper.pluralize(number: count, forms: [ + NSLocalizedString("LessonsCountText1", comment: ""), + NSLocalizedString("LessonsCountText234", comment: ""), + NSLocalizedString("LessonsCountText567890", comment: "") + ]) + + return String(format: pluralizedString, "\(count)") + } + + private func topicsPluralized() -> String { + let count = topic.lessons.count + let pluralizedString = StringHelper.pluralize(number: count, forms: [ + NSLocalizedString("PagesCountText1", comment: ""), + NSLocalizedString("PagesCountText234", comment: ""), + NSLocalizedString("PagesCountText567890", comment: "") + ]) - return resultString + return String(format: pluralizedString, "\(count)") } } diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index b82de310ac..0f7fc9a927 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -4045,8 +4045,6 @@ 2CB9E8CB1F8397960004E17F /* NotificationsSectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CA1F8397960004E17F /* NotificationsSectionHeaderView.xib */; }; 2CB9E8D01F839C8E0004E17F /* NotificationsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CE1F839C8E0004E17F /* NotificationsTableViewCell.swift */; }; 2CB9E8D11F839C8E0004E17F /* NotificationsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CB9E8CF1F839C8E0004E17F /* NotificationsTableViewCell.xib */; }; - 2CBB70F8213171D900D67BE1 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */; }; - 2CBB70F9213171D900D67BE1 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */; }; 2CBC261421086936004245D6 /* UserRegistrationServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */; }; 2CBC261521086947004245D6 /* UserRegistrationServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */; }; 2CBC261621086947004245D6 /* UserRegistrationServiceImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */; }; @@ -5984,8 +5982,6 @@ 2CB9E8CA1F8397960004E17F /* NotificationsSectionHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NotificationsSectionHeaderView.xib; sourceTree = ""; }; 2CB9E8CE1F839C8E0004E17F /* NotificationsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsTableViewCell.swift; sourceTree = ""; }; 2CB9E8CF1F839C8E0004E17F /* NotificationsTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NotificationsTableViewCell.xib; sourceTree = ""; }; - 2CBB70FA213171D900D67BE1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; - 2CBB70FC213171DE00D67BE1 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; 2CBC261321086936004245D6 /* UserRegistrationServiceImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserRegistrationServiceImpl.swift; sourceTree = ""; }; 2CBC4C051F1E4A1300FE96C4 /* Config.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Config.plist; sourceTree = ""; }; 2CBCBD4820D1AAFC000B5732 /* AchievementsListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AchievementsListTableViewCell.swift; sourceTree = ""; }; @@ -7985,7 +7981,6 @@ 0869F6D71CE3684000F8A6DB /* default_sound.wav */, 08D2AE471C04F52300BD8C3D /* GoogleService-Info.plist */, 08A1257B1BDEBCC90066B2B2 /* Localizable.strings */, - 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */, 08DE94151B8C58AC00D278AB /* Info.plist */, 08C0A4351BF12CDF0010F049 /* CustomMessagesDesign.json */, 08A7B0E71EB340F500C1BA71 /* Auth.plist */, @@ -11712,7 +11707,6 @@ 08A9F7151FC3837800640F1F /* CourseTagCollectionViewCell.xib in Resources */, 2C32E71320FF6C1D008BB909 /* Auth.storyboard in Resources */, 08EDB8B11F7C3D0C0028A9AE /* CourseWidgetView.xib in Resources */, - 2CBB70F8213171D900D67BE1 /* Localizable.stringsdict in Resources */, 082CB1B81D08971900C79A27 /* DiscussionsViewController.xib in Resources */, 08F485B91C58ED01000165AA /* SortingQuizTableViewCell.xib in Resources */, 08A7B0E81EB340F500C1BA71 /* Auth.plist in Resources */, @@ -12000,7 +11994,6 @@ 2C093F2D211B4AE900162DD0 /* QuizViewController.xib in Resources */, 2C5FDC992111E25A0077C15C /* StepTabView.xib in Resources */, 2CD7998D21077D010054D098 /* TopicTableViewCell.xib in Resources */, - 2CBB70F9213171D900D67BE1 /* Localizable.stringsdict in Resources */, 2CD1E35B2114B0D0007AA7B3 /* Assets.xcassets in Resources */, 2C302DC121303191006C2BD5 /* AuthGreetingViewController.xib in Resources */, 2C0107A5210F3E87009A53DF /* LaunchScreen.storyboard in Resources */, @@ -18582,15 +18575,6 @@ name = step2.html; sourceTree = ""; }; - 2CBB70FB213171D900D67BE1 /* Localizable.stringsdict */ = { - isa = PBXVariantGroup; - children = ( - 2CBB70FA213171D900D67BE1 /* en */, - 2CBB70FC213171DE00D67BE1 /* ru */, - ); - name = Localizable.stringsdict; - sourceTree = ""; - }; 2CC351841F6827BE004255B6 /* Auth.storyboard */ = { isa = PBXVariantGroup; children = ( diff --git a/Stepic/en.lproj/Localizable.strings b/Stepic/en.lproj/Localizable.strings index 052c8a176b..e595ca32f7 100644 --- a/Stepic/en.lproj/Localizable.strings +++ b/Stepic/en.lproj/Localizable.strings @@ -573,3 +573,11 @@ PersonalDeadlineWidgetSuggestionText = "Constant learning is a key to success. W "PracticeLessonDescription" = "Consolidate the knowledge gained"; "LessonsViewControllerTitle" = "Topic"; + +"LessonsCountText1" = "%@ lesson"; +"LessonsCountText234" = "%@ lessons"; +"LessonsCountText567890" = "%@ lessons"; + +"PagesCountText1" = "%@ page"; +"PagesCountText234" = "%@ pages"; +"PagesCountText567890" = "%@ pages"; diff --git a/Stepic/en.lproj/Localizable.stringsdict b/Stepic/en.lproj/Localizable.stringsdict deleted file mode 100644 index 7296cae0ad..0000000000 --- a/Stepic/en.lproj/Localizable.stringsdict +++ /dev/null @@ -1,42 +0,0 @@ - - - - - topic lessons count - - NSStringLocalizedFormatKey - %#@lessons_count@ - lessons_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - u - zero - No lessons - one - %u lesson - other - %u lessons - - - lesson pages count - - NSStringLocalizedFormatKey - %#@pages_count@ - pages_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - u - zero - No pages - one - %u page - other - %u pages - - - - diff --git a/Stepic/ru.lproj/Localizable.strings b/Stepic/ru.lproj/Localizable.strings index 3cb6c5bc95..5964b0ec8b 100644 --- a/Stepic/ru.lproj/Localizable.strings +++ b/Stepic/ru.lproj/Localizable.strings @@ -574,3 +574,11 @@ PersonalDeadlineWidgetSuggestionText = "Постоянное обучение - "PracticeLessonDescription" = "Закрепите полученные знания"; "LessonsViewControllerTitle" = "Тема"; + +"LessonsCountText1" = "%@ урок"; +"LessonsCountText234" = "%@ урока"; +"LessonsCountText567890" = "%@ уроков"; + +"PagesCountText1" = "%@ страница"; +"PagesCountText234" = "%@ страницы"; +"PagesCountText567890" = "%@ страниц"; diff --git a/Stepic/ru.lproj/Localizable.stringsdict b/Stepic/ru.lproj/Localizable.stringsdict deleted file mode 100644 index 6190cab9da..0000000000 --- a/Stepic/ru.lproj/Localizable.stringsdict +++ /dev/null @@ -1,50 +0,0 @@ - - - - - topic lessons count - - NSStringLocalizedFormatKey - %#@lessons_count@ - lessons_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - u - zero - Нет уроков - one - %u урок - few - %u урока - many - %u уроков - other - %u уроков - - - lesson pages count - - NSStringLocalizedFormatKey - %#@pages_count@ - pages_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - u - zero - Нет страниц - one - %u страница - few - %u страницы - many - %u страниц - other - %u страниц - - - - From b03c32dd42a499e80b63dbc6de3e8d41ea7f763a Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Tue, 28 Aug 2018 12:14:32 +0300 Subject: [PATCH 24/26] Refactor rename LessonHeaderTableView -> LessonTableHeaderView --- .../LessonTableHeaderView.swift} | 4 ++-- .../LessonTableHeaderView.xib} | 2 +- .../View/LessonsTableViewController.swift | 6 ++--- Stepic.xcodeproj/project.pbxproj | 22 +++++++++---------- 4 files changed, 17 insertions(+), 17 deletions(-) rename ExamEGERussian/Sources/PresentationLayer/Lessons/View/{LessonHeaderTableView/LessonHeaderTableView.swift => LessonTableHeaderView/LessonTableHeaderView.swift} (92%) rename ExamEGERussian/Sources/PresentationLayer/Lessons/View/{LessonHeaderTableView/LessonHeaderTableView.xib => LessonTableHeaderView/LessonTableHeaderView.xib} (98%) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableHeaderView/LessonTableHeaderView.swift similarity index 92% rename from ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.swift rename to ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableHeaderView/LessonTableHeaderView.swift index 204ea83582..ad6540360d 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableHeaderView/LessonTableHeaderView.swift @@ -1,5 +1,5 @@ // -// LessonHeaderTableView.swift +// LessonTableHeaderView.swift // ExamEGERussian // // Created by Ivan Magda on 25/08/2018. @@ -8,7 +8,7 @@ import Foundation -final class LessonHeaderTableView: UIView { +final class LessonTableHeaderView: UIView { @IBOutlet var titleLabel: UILabel! @IBOutlet var subtitleLabel: UILabel! diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableHeaderView/LessonTableHeaderView.xib similarity index 98% rename from ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib rename to ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableHeaderView/LessonTableHeaderView.xib index 01dfc59b49..e6578d3c3e 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonHeaderTableView/LessonHeaderTableView.xib +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonTableHeaderView/LessonTableHeaderView.xib @@ -12,7 +12,7 @@ - + diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index 7517c2937f..5a598f89f0 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -28,8 +28,8 @@ final class LessonsTableViewController: UITableViewController { } } - private var headerView: LessonHeaderTableView? { - return tableView.tableHeaderView as? LessonHeaderTableView + private var headerView: LessonTableHeaderView? { + return tableView.tableHeaderView as? LessonTableHeaderView } private lazy var headerViewGradient: CAGradientLayer = { CAGradientLayer( @@ -114,7 +114,7 @@ final class LessonsTableViewController: UITableViewController { tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = appearance.tableViewEstimatedRowHeight - tableView.tableHeaderView = LessonHeaderTableView.fromNib() as LessonHeaderTableView + tableView.tableHeaderView = LessonTableHeaderView.fromNib() as LessonTableHeaderView tableView.tableHeaderView?.layer.insertSublayer(headerViewGradient, at: 0) } diff --git a/Stepic.xcodeproj/project.pbxproj b/Stepic.xcodeproj/project.pbxproj index 0f7fc9a927..5ed17c04b5 100644 --- a/Stepic.xcodeproj/project.pbxproj +++ b/Stepic.xcodeproj/project.pbxproj @@ -4174,8 +4174,8 @@ 2CE84BDF20F4D2CC0069B869 /* AdjacencyListGraph.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE84BDE20F4D2CC0069B869 /* AdjacencyListGraph.swift */; }; 2CE84BE120F4FD030069B869 /* GraphPathFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE84BE020F4FD030069B869 /* GraphPathFinder.swift */; }; 2CE84BE420F505980069B869 /* GraphPathFinderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE84BE320F505980069B869 /* GraphPathFinderTests.swift */; }; - 2CE8A69B2131DF5900E3916B /* LessonHeaderTableView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CE8A69A2131DF5900E3916B /* LessonHeaderTableView.xib */; }; - 2CE8A69D2131DF7E00E3916B /* LessonHeaderTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE8A69C2131DF7E00E3916B /* LessonHeaderTableView.swift */; }; + 2CE8A69B2131DF5900E3916B /* LessonTableHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CE8A69A2131DF5900E3916B /* LessonTableHeaderView.xib */; }; + 2CE8A69D2131DF7E00E3916B /* LessonTableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE8A69C2131DF7E00E3916B /* LessonTableHeaderView.swift */; }; 2CEBAB90211D82880014085E /* SharingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0840707F1D64847000308FC1 /* SharingHelper.swift */; }; 2CEBAB91211D82A50014085E /* CyrillicURLActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 084070861D64DC7500308FC1 /* CyrillicURLActivityItemSource.swift */; }; 2CEDA3601F336FEC005F4A5D /* AdaptiveRatingHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CEDA35F1F336FEC005F4A5D /* AdaptiveRatingHelper.swift */; }; @@ -6107,8 +6107,8 @@ 2CE84BDE20F4D2CC0069B869 /* AdjacencyListGraph.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdjacencyListGraph.swift; sourceTree = ""; }; 2CE84BE020F4FD030069B869 /* GraphPathFinder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphPathFinder.swift; sourceTree = ""; }; 2CE84BE320F505980069B869 /* GraphPathFinderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphPathFinderTests.swift; sourceTree = ""; }; - 2CE8A69A2131DF5900E3916B /* LessonHeaderTableView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LessonHeaderTableView.xib; sourceTree = ""; }; - 2CE8A69C2131DF7E00E3916B /* LessonHeaderTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonHeaderTableView.swift; sourceTree = ""; }; + 2CE8A69A2131DF5900E3916B /* LessonTableHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LessonTableHeaderView.xib; sourceTree = ""; }; + 2CE8A69C2131DF7E00E3916B /* LessonTableHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonTableHeaderView.swift; sourceTree = ""; }; 2CEDA35F1F336FEC005F4A5D /* AdaptiveRatingHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdaptiveRatingHelper.swift; path = Stepic/AdaptiveRatingHelper.swift; sourceTree = SOURCE_ROOT; }; 2CF08859205BEBF500FCB9C0 /* StepikTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StepikTableView.swift; sourceTree = ""; }; 2CF0885C205BED9700FCB9C0 /* StepikPlaceholderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = StepikPlaceholderView.xib; sourceTree = ""; }; @@ -8938,7 +8938,7 @@ 2C2FD7772107357800609621 /* View */ = { isa = PBXGroup; children = ( - 2CF79D332131A96800DA6953 /* LessonHeaderTableView */, + 2CF79D332131A96800DA6953 /* LessonTableHeaderView */, 2C2FD781210735EB00609621 /* LessonTableViewCell */, 2C2FD7782107359E00609621 /* LessonsTableViewController.swift */, 2C2FD7902107540500609621 /* LessonsView.swift */, @@ -10464,13 +10464,13 @@ name = StepikPlaceholderView; sourceTree = ""; }; - 2CF79D332131A96800DA6953 /* LessonHeaderTableView */ = { + 2CF79D332131A96800DA6953 /* LessonTableHeaderView */ = { isa = PBXGroup; children = ( - 2CE8A69C2131DF7E00E3916B /* LessonHeaderTableView.swift */, - 2CE8A69A2131DF5900E3916B /* LessonHeaderTableView.xib */, + 2CE8A69C2131DF7E00E3916B /* LessonTableHeaderView.swift */, + 2CE8A69A2131DF5900E3916B /* LessonTableHeaderView.xib */, ); - path = LessonHeaderTableView; + path = LessonTableHeaderView; sourceTree = ""; }; 2CFB1C521F14C7EA00CD0A4C /* Supporting Files */ = { @@ -11988,7 +11988,7 @@ 2CFE247C20ECF7F700AF1E3D /* Config.plist in Resources */, 2C8C96EA211DE34700A9FB99 /* RateAppViewController.xib in Resources */, 2C4BADEB2121D7E600E42F8C /* PlaceholderTableViewCell.xib in Resources */, - 2CE8A69B2131DF5900E3916B /* LessonHeaderTableView.xib in Resources */, + 2CE8A69B2131DF5900E3916B /* LessonTableHeaderView.xib in Resources */, 2CE22D9A211C587F004D9D10 /* UnknownTypeQuizViewController.xib in Resources */, 2C093F2B211B46F900162DD0 /* ChoiceQuizTableViewCell.xib in Resources */, 2C093F2D211B4AE900162DD0 /* QuizViewController.xib in Resources */, @@ -16197,7 +16197,7 @@ 2C33CBEF20EC3251009956B0 /* UserActivitiesAPI.swift in Sources */, 2C9499DB20ECBD780049E9A8 /* UserActivity.swift in Sources */, 2C67B22120FF1A93005E699B /* AuthSignUpAssemblyImpl.swift in Sources */, - 2CE8A69D2131DF7E00E3916B /* LessonHeaderTableView.swift in Sources */, + 2CE8A69D2131DF7E00E3916B /* LessonTableHeaderView.swift in Sources */, 2CCB5A662100B7FA0091A605 /* KnowledgeGraph.swift in Sources */, 2CCC59FE2109BB9800564D45 /* EnrollmentServiceImpl.swift in Sources */, 2C949A0820ECC3B80049E9A8 /* NotificationDataExtractor.swift in Sources */, From ab8b2420a26550fb49efcc4c5b2ca085ce879173 Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Tue, 28 Aug 2018 12:16:53 +0300 Subject: [PATCH 25/26] Up code quality --- .../Lessons/View/LessonsTableViewController.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index 5a598f89f0..42656e5383 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -114,8 +114,9 @@ final class LessonsTableViewController: UITableViewController { tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = appearance.tableViewEstimatedRowHeight - tableView.tableHeaderView = LessonTableHeaderView.fromNib() as LessonTableHeaderView - tableView.tableHeaderView?.layer.insertSublayer(headerViewGradient, at: 0) + let headerView: LessonTableHeaderView = .fromNib() + headerView.layer.insertSublayer(headerViewGradient, at: 0) + tableView.tableHeaderView = headerView } @objc From 71dd5ec77806e5f685701d6fc2d3a31b3a960fec Mon Sep 17 00:00:00 2001 From: Ivan Magda Date: Tue, 28 Aug 2018 12:23:08 +0300 Subject: [PATCH 26/26] Use coordinator on size class change --- .../Lessons/View/LessonsTableViewController.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift index 42656e5383..cf163131eb 100644 --- a/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift +++ b/ExamEGERussian/Sources/PresentationLayer/Lessons/View/LessonsTableViewController.swift @@ -72,8 +72,10 @@ final class LessonsTableViewController: UITableViewController { override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) - triggerHeaderViewLayoutUpdate() - tableView.setContentOffset(.zero, animated: false) + + coordinator.animate(alongsideTransition: { _ in + self.triggerHeaderViewLayoutUpdate() + }) } // MARK: - UITableViewDataSource