diff --git a/Course/Course/Presentation/Unit/CourseNavigationView.swift b/Course/Course/Presentation/Unit/CourseNavigationView.swift index 5778f1fd0..a302323fd 100644 --- a/Course/Course/Presentation/Unit/CourseNavigationView.swift +++ b/Course/Course/Presentation/Unit/CourseNavigationView.swift @@ -43,12 +43,6 @@ struct CourseNavigationView: View { }) } UnitButtonView(type: .last, action: { - let sequentials = viewModel.chapters[viewModel.chapterIndex].childs - let verticals = viewModel - .chapters[viewModel.chapterIndex] - .childs[viewModel.sequentialIndex] - .childs - let chapters = viewModel.chapters let currentVertical = viewModel.verticals[viewModel.verticalIndex] viewModel.router.presentAlert( @@ -56,15 +50,11 @@ struct CourseNavigationView: View { alertMessage: (CourseLocalization.Courseware.section + currentVertical.displayName + CourseLocalization.Courseware.isFinished), nextSectionName: { - if viewModel.verticals.count > viewModel.verticalIndex + 1 { - return viewModel.verticals[viewModel.verticalIndex + 1].displayName - } else if sequentials.count > viewModel.sequentialIndex + 1 { - return sequentials[viewModel.sequentialIndex + 1].childs.first?.displayName ?? "" - } else if chapters.count > viewModel.chapterIndex + 1 { - return chapters[viewModel.chapterIndex + 1].childs.first?.childs.first?.displayName - } else { - return nil + if let data = viewModel.nextData, + let vertical = viewModel.vertical(for: data) { + return vertical.displayName } + return nil }(), action: CourseLocalization.Courseware.backToOutline, image: CoreAssets.goodWork.swiftUIImage, @@ -82,27 +72,6 @@ struct CourseNavigationView: View { playerStateSubject.send(VideoPlayerState.kill) viewModel.router.dismiss(animated: false) - let chapterIndex: Int - let sequentialIndex: Int - let verticalIndex: Int - - // Switch to the next Vertical - if verticals.count - 1 > viewModel.verticalIndex { - chapterIndex = viewModel.chapterIndex - sequentialIndex = viewModel.sequentialIndex - verticalIndex = viewModel.verticalIndex + 1 - // Switch to the next Sequential - } else if sequentials.count - 1 > viewModel.sequentialIndex { - chapterIndex = viewModel.chapterIndex - sequentialIndex = viewModel.sequentialIndex + 1 - verticalIndex = 0 - } else { - // Switch to the next Chapter - chapterIndex = viewModel.chapterIndex + 1 - sequentialIndex = 0 - verticalIndex = 0 - } - viewModel.analytics .finishVerticalNextSectionClicked( courseId: viewModel.courseID, @@ -110,16 +79,17 @@ struct CourseNavigationView: View { blockId: viewModel.selectedLesson().blockId, blockName: viewModel.selectedLesson().displayName ) - + + guard let data = viewModel.nextData else { return } viewModel.router.replaceCourseUnit( courseName: viewModel.courseName, blockId: viewModel.lessonID, courseID: viewModel.courseID, sectionName: viewModel.selectedLesson().displayName, - verticalIndex: verticalIndex, + verticalIndex: data.verticalIndex, chapters: viewModel.chapters, - chapterIndex: chapterIndex, - sequentialIndex: sequentialIndex, + chapterIndex: data.chapterIndex, + sequentialIndex: data.sequentialIndex, animated: true ) } diff --git a/Course/Course/Presentation/Unit/CourseUnitViewModel.swift b/Course/Course/Presentation/Unit/CourseUnitViewModel.swift index 6b2b10411..bf4f22807 100644 --- a/Course/Course/Presentation/Unit/CourseUnitViewModel.swift +++ b/Course/Course/Presentation/Unit/CourseUnitViewModel.swift @@ -180,7 +180,61 @@ public class CourseUnitViewModel: ObservableObject { func trackFinishVerticalBackToOutlineClicked() { analytics.finishVerticalBackToOutlineClicked(courseId: courseID, courseName: courseName) } + + //MARK: Navigation to next vertical + typealias VerticalData = (chapterIndex: Int, sequentialIndex: Int, verticalIndex: Int) + var nextData: VerticalData? { + nextData(from: (chapterIndex, sequentialIndex, verticalIndex)) + } + + private func chapter(for data: VerticalData) -> CourseChapter? { + guard data.chapterIndex >= 0 && data.chapterIndex < chapters.count else { return nil } + return chapters[data.chapterIndex] + } + + private func sequential(for data: VerticalData) -> CourseSequential? { + guard let chapter = chapter(for: data), + data.sequentialIndex >= 0 && data.sequentialIndex < chapter.childs.count + else { return nil } + return chapter.childs[data.sequentialIndex] + } + + func vertical(for data: VerticalData) -> CourseVertical? { + guard let sequential = sequential(for: data), + data.verticalIndex >= 0 && data.verticalIndex < sequential.childs.count + else { return nil } + return sequential.childs[data.verticalIndex] + } + + private func sequentials(for data: VerticalData) -> [CourseSequential]? { + guard let chapter = chapter(for: data) else { return nil } + return chapter.childs + } + private func verticals(for data: VerticalData) -> [CourseVertical]? { + guard let sequential = sequential(for: data) else { return nil } + return sequential.childs + } + + private func nextData(from data: VerticalData) -> VerticalData? { + var resultData: VerticalData = data + if let verticals = verticals(for: data), verticals.count > data.verticalIndex + 1 { + resultData = (data.chapterIndex, data.sequentialIndex, data.verticalIndex + 1) + } else if let sequentials = sequentials(for: data), sequentials.count > data.sequentialIndex + 1 { + resultData = (data.chapterIndex, data.sequentialIndex + 1, 0) + } else if chapters.count > data.chapterIndex + 1 { + resultData = (data.chapterIndex + 1, 0, 0) + } else { + return nil + } + + if let vertical = vertical(for: resultData), vertical.childs.count > 0 { + return resultData + } else { + return nextData(from: resultData) + } + } + func route(to vertical: CourseVertical) { if let index = verticals.firstIndex(where: { $0.id == vertical.id }), let block = vertical.childs.first {