Skip to content

Commit

Permalink
Merge pull request #8 from touchapp/feat/unit-animation
Browse files Browse the repository at this point in the history
Feat/unit animation
  • Loading branch information
rnr authored Jan 23, 2024
2 parents 96e5d72 + bfd5507 commit 9079d30
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 122 deletions.
23 changes: 19 additions & 4 deletions Core/Core/View/Base/UnitButtonView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,26 @@ public struct UnitButtonView: View {
private let action: () -> Void
private let type: UnitButtonType
private let bgColor: Color?
private let isVerticalNavigation: Bool

public init(type: UnitButtonType, bgColor: Color? = nil, action: @escaping () -> Void) {
private var nextButtonDegrees: Double {
isVerticalNavigation ? -90 : 180
}

private var prevButtonDegrees: Double {
isVerticalNavigation ? 90 : 0
}

public init(
type: UnitButtonType,
isVerticalNavigation: Bool = true,
bgColor: Color? = nil,
action: @escaping () -> Void
) {
self.type = type
self.bgColor = bgColor
self.action = action
self.isVerticalNavigation = isVerticalNavigation
}

public var body: some View {
Expand All @@ -68,7 +83,7 @@ public struct UnitButtonView: View {
.font(Theme.Fonts.labelLarge)
CoreAssets.arrowLeft.swiftUIImage.renderingMode(.template)
.foregroundColor(Theme.Colors.styledButtonText)
.rotationEffect(Angle.degrees(-90))
.rotationEffect(Angle.degrees(nextButtonDegrees))
}.padding(.horizontal, 16)
case .next, .nextBig:
HStack {
Expand All @@ -81,7 +96,7 @@ public struct UnitButtonView: View {
}
CoreAssets.arrowLeft.swiftUIImage.renderingMode(.template)
.foregroundColor(Theme.Colors.styledButtonText)
.rotationEffect(Angle.degrees(-90))
.rotationEffect(Angle.degrees(nextButtonDegrees))
.padding(.trailing, 20)
}
case .previous:
Expand All @@ -91,7 +106,7 @@ public struct UnitButtonView: View {
.font(Theme.Fonts.labelLarge)
.padding(.leading, 20)
CoreAssets.arrowLeft.swiftUIImage.renderingMode(.template)
.rotationEffect(Angle.degrees(90))
.rotationEffect(Angle.degrees(prevButtonDegrees))
.padding(.trailing, 20)
.foregroundColor(Theme.Colors.accentColor)

Expand Down
8 changes: 6 additions & 2 deletions Course/Course.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
02F78AEB29E6BCA20038DE30 /* VideoPlayerViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02F78AEA29E6BCA20038DE30 /* VideoPlayerViewModelTests.swift */; };
02F98A8128F8224200DE94C0 /* Discussion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02F98A8028F8224200DE94C0 /* Discussion.framework */; };
02FFAD0D29E4347300140E46 /* VideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02FFAD0C29E4347300140E46 /* VideoPlayerViewModel.swift */; };
060E8BCA2B5FD68C0080C952 /* UnitStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 060E8BC92B5FD68C0080C952 /* UnitStack.swift */; };
068DDA5F2B1E198700FF8CCB /* CourseUnitDropDownList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068DDA5B2B1E198700FF8CCB /* CourseUnitDropDownList.swift */; };
068DDA602B1E198700FF8CCB /* CourseUnitVerticalsDropdownView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068DDA5C2B1E198700FF8CCB /* CourseUnitVerticalsDropdownView.swift */; };
068DDA612B1E198700FF8CCB /* CourseUnitDropDownCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068DDA5D2B1E198700FF8CCB /* CourseUnitDropDownCell.swift */; };
Expand All @@ -70,8 +71,8 @@
0766DFD0299AB29000EBEF6A /* PlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0766DFCF299AB29000EBEF6A /* PlayerViewController.swift */; };
197FB8EA8F92F00A8F383D82 /* Pods_App_Course.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E795BD160CDA7D9C120DE6 /* Pods_App_Course.framework */; };
B8F50317B6B830A0E520C954 /* Pods_App_Course_CourseTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50E59D2B81E12610964282C5 /* Pods_App_Course_CourseTests.framework */; };
BAD9CA2D2B2736BB00DE790A /* LessonLineProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAD9CA2C2B2736BB00DE790A /* LessonLineProgressView.swift */; };
BAAD62C82AFD00EE000E6103 /* CourseExpandableContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAAD62C72AFD00EE000E6103 /* CourseExpandableContentView.swift */; };
BAD9CA2D2B2736BB00DE790A /* LessonLineProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAD9CA2C2B2736BB00DE790A /* LessonLineProgressView.swift */; };
DB205BFB2AE81B1200136EC2 /* CourseDateViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB205BFA2AE81B1200136EC2 /* CourseDateViewModelTests.swift */; };
DB7D6EAC2ADFCAC50036BB13 /* CourseDatesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7D6EAB2ADFCAC40036BB13 /* CourseDatesView.swift */; };
DB7D6EAE2ADFCB4A0036BB13 /* CourseDatesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7D6EAD2ADFCB4A0036BB13 /* CourseDatesViewModel.swift */; };
Expand Down Expand Up @@ -143,6 +144,7 @@
02F78AEA29E6BCA20038DE30 /* VideoPlayerViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = VideoPlayerViewModelTests.swift; path = CourseTests/Presentation/Unit/VideoPlayerViewModelTests.swift; sourceTree = SOURCE_ROOT; };
02F98A8028F8224200DE94C0 /* Discussion.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Discussion.framework; sourceTree = BUILT_PRODUCTS_DIR; };
02FFAD0C29E4347300140E46 /* VideoPlayerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerViewModel.swift; sourceTree = "<group>"; };
060E8BC92B5FD68C0080C952 /* UnitStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitStack.swift; sourceTree = "<group>"; };
068DDA5B2B1E198700FF8CCB /* CourseUnitDropDownList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CourseUnitDropDownList.swift; sourceTree = "<group>"; };
068DDA5C2B1E198700FF8CCB /* CourseUnitVerticalsDropdownView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CourseUnitVerticalsDropdownView.swift; sourceTree = "<group>"; };
068DDA5D2B1E198700FF8CCB /* CourseUnitDropDownCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CourseUnitDropDownCell.swift; sourceTree = "<group>"; };
Expand All @@ -169,8 +171,8 @@
A47C63D9EB0D866F303D4588 /* Pods-App-Course.releasestage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Course.releasestage.xcconfig"; path = "Target Support Files/Pods-App-Course/Pods-App-Course.releasestage.xcconfig"; sourceTree = "<group>"; };
ADC2A1B8183A674705F5F7E2 /* Pods-App-Course.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Course.debug.xcconfig"; path = "Target Support Files/Pods-App-Course/Pods-App-Course.debug.xcconfig"; sourceTree = "<group>"; };
B196A14555D0E006995A5683 /* Pods-App-CourseDetails.releaseprod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-CourseDetails.releaseprod.xcconfig"; path = "Target Support Files/Pods-App-CourseDetails/Pods-App-CourseDetails.releaseprod.xcconfig"; sourceTree = "<group>"; };
BAD9CA2C2B2736BB00DE790A /* LessonLineProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonLineProgressView.swift; sourceTree = "<group>"; };
BAAD62C72AFD00EE000E6103 /* CourseExpandableContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseExpandableContentView.swift; sourceTree = "<group>"; };
BAD9CA2C2B2736BB00DE790A /* LessonLineProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LessonLineProgressView.swift; sourceTree = "<group>"; };
DB205BFA2AE81B1200136EC2 /* CourseDateViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDateViewModelTests.swift; sourceTree = "<group>"; };
DB7D6EAB2ADFCAC40036BB13 /* CourseDatesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CourseDatesView.swift; sourceTree = "<group>"; };
DB7D6EAD2ADFCB4A0036BB13 /* CourseDatesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDatesViewModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -238,6 +240,7 @@
02454CA72A2619890043052A /* DiscussionView.swift */,
02454CA92A2619B40043052A /* LessonProgressView.swift */,
BAD9CA2C2B2736BB00DE790A /* LessonLineProgressView.swift */,
060E8BC92B5FD68C0080C952 /* UnitStack.swift */,
);
path = Subviews;
sourceTree = "<group>";
Expand Down Expand Up @@ -766,6 +769,7 @@
DB7D6EB02ADFDA0E0036BB13 /* CourseDates.swift in Sources */,
BAD9CA2D2B2736BB00DE790A /* LessonLineProgressView.swift in Sources */,
02E685C028E4B629000AE015 /* CourseDetailsViewModel.swift in Sources */,
060E8BCA2B5FD68C0080C952 /* UnitStack.swift in Sources */,
0295C889299BBE8200ABE571 /* CourseNavigationView.swift in Sources */,
06FD7EDF2B1F29F3008D632B /* CourseVerticalImageView.swift in Sources */,
DB7D6EAE2ADFCB4A0036BB13 /* CourseDatesViewModel.swift in Sources */,
Expand Down
182 changes: 106 additions & 76 deletions Course/Course/Presentation/Unit/CourseNavigationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,94 +30,124 @@ struct CourseNavigationView: View {
HStack(alignment: .top, spacing: 7) {
if viewModel.selectedLesson() == viewModel.verticals[viewModel.verticalIndex].childs.first
&& viewModel.verticals[viewModel.verticalIndex].childs.count != 1 {
UnitButtonView(type: .nextBig, action: {
playerStateSubject.send(VideoPlayerState.pause)
viewModel.select(move: .next)
}).frame(width: 215)
nextBigButton
.frame(width: 215)
} else {
if viewModel.selectedLesson() == viewModel.verticals[viewModel.verticalIndex].childs.last {
if viewModel.selectedLesson() != viewModel.verticals[viewModel.verticalIndex].childs.first {
UnitButtonView(type: .previous, action: {
playerStateSubject.send(VideoPlayerState.pause)
viewModel.select(move: .previous)
})
prevButton
}
UnitButtonView(type: .last, action: {
let currentVertical = viewModel.verticals[viewModel.verticalIndex]

viewModel.router.presentAlert(
alertTitle: CourseLocalization.Courseware.goodWork,
alertMessage: (CourseLocalization.Courseware.section
+ currentVertical.displayName + CourseLocalization.Courseware.isFinished),
nextSectionName: {
if let data = viewModel.nextData,
let vertical = viewModel.vertical(for: data) {
return vertical.displayName
}
return nil
}(),
action: CourseLocalization.Courseware.backToOutline,
image: CoreAssets.goodWork.swiftUIImage,
onCloseTapped: { viewModel.router.dismiss(animated: false) },
okTapped: {
playerStateSubject.send(VideoPlayerState.pause)
playerStateSubject.send(VideoPlayerState.kill)

viewModel.trackFinishVerticalBackToOutlineClicked()
viewModel.router.dismiss(animated: false)
viewModel.router.back(animated: true)
},
nextSectionTapped: {
playerStateSubject.send(VideoPlayerState.pause)
playerStateSubject.send(VideoPlayerState.kill)
viewModel.router.dismiss(animated: false)

viewModel.analytics
.finishVerticalNextSectionClicked(
courseId: viewModel.courseID,
courseName: viewModel.courseName,
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: data.verticalIndex,
chapters: viewModel.chapters,
chapterIndex: data.chapterIndex,
sequentialIndex: data.sequentialIndex,
animated: true
)
}
)
playerStateSubject.send(VideoPlayerState.pause)
viewModel.analytics.finishVerticalClicked(
courseId: viewModel.courseID,
courseName: viewModel.courseName,
blockId: viewModel.selectedLesson().blockId,
blockName: viewModel.selectedLesson().displayName
)
})
lastButton
} else {
if viewModel.selectedLesson() != viewModel.verticals[viewModel.verticalIndex].childs.first {
UnitButtonView(type: .previous, action: {
playerStateSubject.send(VideoPlayerState.pause)
viewModel.select(move: .previous)
})
prevButton
}

UnitButtonView(type: .next, action: {
playerStateSubject.send(VideoPlayerState.pause)
viewModel.select(move: .next)
})
nextButton
}
}
}.padding(.horizontal, 24)
}

private var nextBigButton: some View {
UnitButtonView(
type: .nextBig,
isVerticalNavigation: !viewModel.courseUnitProgressEnabled,
action: {
playerStateSubject.send(VideoPlayerState.pause)
viewModel.select(move: .next)
}
)
}

private var nextButton: some View {
UnitButtonView(
type: .next,
isVerticalNavigation: !viewModel.courseUnitProgressEnabled,
action: {
playerStateSubject.send(VideoPlayerState.pause)
viewModel.select(move: .next)
}
)
}

private var prevButton: some View {
UnitButtonView(
type: .previous,
isVerticalNavigation: !viewModel.courseUnitProgressEnabled,
action: {
playerStateSubject.send(VideoPlayerState.pause)
viewModel.select(move: .previous)
}
)
}

private var lastButton: some View {
UnitButtonView(
type: .last,
isVerticalNavigation: !viewModel.courseUnitProgressEnabled,
action: {
let currentVertical = viewModel.verticals[viewModel.verticalIndex]

viewModel.router.presentAlert(
alertTitle: CourseLocalization.Courseware.goodWork,
alertMessage: (CourseLocalization.Courseware.section
+ currentVertical.displayName + CourseLocalization.Courseware.isFinished),
nextSectionName: {
if let data = viewModel.nextData,
let vertical = viewModel.vertical(for: data) {
return vertical.displayName
}
return nil
}(),
action: CourseLocalization.Courseware.backToOutline,
image: CoreAssets.goodWork.swiftUIImage,
onCloseTapped: { viewModel.router.dismiss(animated: false) },
okTapped: {
playerStateSubject.send(VideoPlayerState.pause)
playerStateSubject.send(VideoPlayerState.kill)

viewModel.trackFinishVerticalBackToOutlineClicked()
viewModel.router.dismiss(animated: false)
viewModel.router.back(animated: true)
},
nextSectionTapped: {
playerStateSubject.send(VideoPlayerState.pause)
playerStateSubject.send(VideoPlayerState.kill)
viewModel.router.dismiss(animated: false)

viewModel.analytics
.finishVerticalNextSectionClicked(
courseId: viewModel.courseID,
courseName: viewModel.courseName,
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: data.verticalIndex,
chapters: viewModel.chapters,
chapterIndex: data.chapterIndex,
sequentialIndex: data.sequentialIndex,
animated: true
)
}
)
playerStateSubject.send(VideoPlayerState.pause)
viewModel.analytics.finishVerticalClicked(
courseId: viewModel.courseID,
courseName: viewModel.courseName,
blockId: viewModel.selectedLesson().blockId,
blockName: viewModel.selectedLesson().displayName
)
}
)
}
}

#if DEBUG
Expand Down
Loading

0 comments on commit 9079d30

Please sign in to comment.