Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/pip mode #384

Merged
merged 21 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Course/Course.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
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 */; };
065275352BB1B39C0093BCCA /* PlayerViewControllerHolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 065275342BB1B39C0093BCCA /* PlayerViewControllerHolder.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 Down Expand Up @@ -150,6 +151,7 @@
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>"; };
065275342BB1B39C0093BCCA /* PlayerViewControllerHolder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerViewControllerHolder.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 Down Expand Up @@ -445,6 +447,7 @@
070019AA28F6F79E00D5FC78 /* Video */ = {
isa = PBXGroup;
children = (
065275342BB1B39C0093BCCA /* PlayerViewControllerHolder.swift */,
02F066E729DC71750073E13B /* SubtittlesView.swift */,
0766DFCB299AA7A600EBEF6A /* YouTubeVideoPlayer.swift */,
022F8E152A1DFBC6008EFAB9 /* YouTubeVideoPlayerViewModel.swift */,
Expand Down Expand Up @@ -830,6 +833,7 @@
022C64E029ADEA9B000F532B /* Data_UpdatesResponse.swift in Sources */,
02454CA02A2618E70043052A /* YouTubeView.swift in Sources */,
02454CA22A26190A0043052A /* EncodedVideoView.swift in Sources */,
065275352BB1B39C0093BCCA /* PlayerViewControllerHolder.swift in Sources */,
068DDA612B1E198700FF8CCB /* CourseUnitDropDownCell.swift in Sources */,
BAC0E0DE2B32F0F3006B68A9 /* DownloadsViewModel.swift in Sources */,
02B6B3BC28E1D14F00232911 /* CourseRepository.swift in Sources */,
Expand Down
4 changes: 0 additions & 4 deletions Course/Course/Presentation/CourseRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public protocol CourseRouter: BaseRouter {
courseName: String,
blockId: String,
courseID: String,
sectionName: String,
verticalIndex: Int,
chapters: [CourseChapter],
chapterIndex: Int,
Expand All @@ -27,7 +26,6 @@ public protocol CourseRouter: BaseRouter {
courseName: String,
blockId: String,
courseID: String,
sectionName: String,
verticalIndex: Int,
chapters: [CourseChapter],
chapterIndex: Int,
Expand Down Expand Up @@ -75,7 +73,6 @@ public class CourseRouterMock: BaseRouterMock, CourseRouter {
courseName: String,
blockId: String,
courseID: String,
sectionName: String,
verticalIndex: Int,
chapters: [CourseChapter],
chapterIndex: Int,
Expand All @@ -86,7 +83,6 @@ public class CourseRouterMock: BaseRouterMock, CourseRouter {
courseName: String,
blockId: String,
courseID: String,
sectionName: String,
verticalIndex: Int,
chapters: [CourseChapter],
chapterIndex: Int,
Expand Down
1 change: 0 additions & 1 deletion Course/Course/Presentation/Outline/CourseOutlineView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ public struct CourseOutlineView: View {
courseName: course.displayName,
blockId: continueBlock?.id ?? "",
courseID: course.id,
sectionName: continueUnit.displayName,
verticalIndex: continueWith.verticalIndex,
chapters: course.childs,
chapterIndex: continueWith.chapterIndex,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ struct CourseStructureNestedListView: View {
courseName: viewModel.courseStructure?.displayName ?? "",
blockId: block.id,
courseID: viewModel.courseStructure?.id ?? "",
sectionName: block.displayName,
verticalIndex: 0,
chapters: course.childs,
chapterIndex: chapterIndex,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public struct CourseVerticalView: View {
courseName: courseName,
blockId: block.id,
courseID: courseID,
sectionName: block.displayName,
verticalIndex: index,
chapters: viewModel.chapters,
chapterIndex: viewModel.chapterIndex,
Expand Down
5 changes: 0 additions & 5 deletions Course/Course/Presentation/Unit/CourseNavigationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@ struct CourseNavigationView: View {

@ObservedObject
private var viewModel: CourseUnitViewModel
private let sectionName: String
private let playerStateSubject: CurrentValueSubject<VideoPlayerState?, Never>

init(
sectionName: String,
viewModel: CourseUnitViewModel,
playerStateSubject: CurrentValueSubject<VideoPlayerState?, Never>
) {
self.viewModel = viewModel
self.sectionName = sectionName
self.playerStateSubject = playerStateSubject
}

Expand Down Expand Up @@ -128,7 +125,6 @@ struct CourseNavigationView: View {
courseName: viewModel.courseName,
blockId: viewModel.lessonID,
courseID: viewModel.courseID,
sectionName: viewModel.selectedLesson().displayName,
verticalIndex: data.verticalIndex,
chapters: viewModel.chapters,
chapterIndex: data.chapterIndex,
Expand Down Expand Up @@ -170,7 +166,6 @@ struct CourseNavigationView_Previews: PreviewProvider {
)

CourseNavigationView(
sectionName: "Name",
viewModel: viewModel,
playerStateSubject: CurrentValueSubject<VideoPlayerState?, Never>(nil)
)
Expand Down
14 changes: 6 additions & 8 deletions Course/Course/Presentation/Unit/CourseUnitView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Theme

public struct CourseUnitView: View {

@ObservedObject private var viewModel: CourseUnitViewModel
@ObservedObject public var viewModel: CourseUnitViewModel
@State private var showAlert: Bool = false
@State var alertMessage: String? {
didSet {
Expand All @@ -27,7 +27,6 @@ public struct CourseUnitView: View {
@State var showDiscussion: Bool = false
@Environment(\.isPresented) private var isPresented
@Environment(\.isHorizontal) private var isHorizontal
private let sectionName: String
public let playerStateSubject = CurrentValueSubject<VideoPlayerState?, Never>(nil)

//Dropdown parameters
Expand Down Expand Up @@ -60,11 +59,9 @@ public struct CourseUnitView: View {

public init(
viewModel: CourseUnitViewModel,
sectionName: String,
isDropdownActive: Bool = false
) {
self.viewModel = viewModel
self.sectionName = sectionName
self.isDropdownActive = isDropdownActive
viewModel.loadIndex()
viewModel.nextTitles()
Expand Down Expand Up @@ -122,7 +119,9 @@ public struct CourseUnitView: View {
offsetY: isHorizontal ? landscapeTopSpacing : portraitTopSpacing,
showDropdown: $showDropdown
) { [weak viewModel] vertical in
viewModel?.route(to: vertical)
let data = VerticalData.dataFor(blockId: vertical.childs.first?.id, in: viewModel?.chapters ?? [])
viewModel?.route(to: data)
playerStateSubject.send(VideoPlayerState.kill)
}
}
}
Expand Down Expand Up @@ -173,7 +172,7 @@ public struct CourseUnitView: View {
switch LessonType.from(block, streamingQuality: viewModel.streamingQuality) {
// MARK: YouTube
case let .youtube(url, blockID):
if index >= viewModel.index - 1 && index <= viewModel.index + 1 {
if index == viewModel.index {
if viewModel.connectivity.isInternetAvaliable {
YouTubeView(
name: block.displayName,
Expand Down Expand Up @@ -418,7 +417,6 @@ public struct CourseUnitView: View {
Spacer()
}
CourseNavigationView(
sectionName: sectionName,
viewModel: viewModel,
playerStateSubject: playerStateSubject
)
Expand Down Expand Up @@ -566,7 +564,7 @@ struct CourseUnitView_Previews: PreviewProvider {
connectivity: Connectivity(),
storage: CourseStorageMock(),
manager: DownloadManagerMock()
), sectionName: "")
))
}
}
//swiftlint:enable all
Expand Down
94 changes: 71 additions & 23 deletions Course/Course/Presentation/Unit/CourseUnitViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public enum LessonType: Equatable {
case .discussion:
return .discussion(block.topicId ?? "", block.id, block.displayName)
case .video:
if block.encodedVideo?.youtubeVideoUrl != nil, let encodedVideo = block.encodedVideo?.video(streamingQuality: streamingQuality)?.url {
if block.encodedVideo?.youtubeVideoUrl != nil,
let encodedVideo = block.encodedVideo?.video(streamingQuality: streamingQuality)?.url {
return .video(videoUrl: encodedVideo, blockID: block.id)
} else if let youtubeVideoUrl = block.encodedVideo?.youtubeVideoUrl {
return .youtube(youtubeVideoUrl: youtubeVideoUrl, blockID: block.id)
Expand All @@ -53,19 +54,46 @@ public enum LessonType: Equatable {
}
}

public struct VerticalData: Equatable {
public var chapterIndex: Int
public var sequentialIndex: Int
public var verticalIndex: Int
public var blockIndex: Int

public init(chapterIndex: Int, sequentialIndex: Int, verticalIndex: Int, blockIndex: Int) {
self.chapterIndex = chapterIndex
self.sequentialIndex = sequentialIndex
self.verticalIndex = verticalIndex
self.blockIndex = blockIndex
}

public static func dataFor(blockId: String?, in chapters: [CourseChapter]) -> VerticalData? {
guard let blockId = blockId else { return nil }
for (chapterIndex, chapter) in chapters.enumerated() {
for (sequentialIndex, sequential) in chapter.childs.enumerated() {
for (verticalIndex, vertical) in sequential.childs.enumerated() {
for (blockIndex, block) in vertical.childs.enumerated() where block.id.contains(blockId) {
return VerticalData(
chapterIndex: chapterIndex,
sequentialIndex: sequentialIndex,
verticalIndex: verticalIndex,
blockIndex: blockIndex
)
}
}
}
}
return nil
}
}

public class CourseUnitViewModel: ObservableObject {

enum LessonAction {
case next
case previous
}

struct VerticalData {
var chapterIndex: Int
var sequentialIndex: Int
var verticalIndex: Int
}

var verticals: [CourseVertical]
var verticalIndex: Int
var courseName: String
Expand Down Expand Up @@ -95,7 +123,7 @@ public class CourseUnitViewModel: ObservableObject {
let chapterIndex: Int
let sequentialIndex: Int

var streamingQuality: StreamingQuality {
var streamingQuality: StreamingQuality {
storage.userSettings?.streamingQuality ?? .auto
}

Expand Down Expand Up @@ -142,7 +170,7 @@ public class CourseUnitViewModel: ObservableObject {

private func selectLesson() -> Int {
guard verticals[verticalIndex].childs.count > 0 else { return 0 }
let index = verticals[verticalIndex].childs.firstIndex(where: { $0.id == lessonID }) ?? 0
let index = verticals[verticalIndex].childs.firstIndex(where: { $0.id.contains(lessonID) }) ?? 0
nextTitles()
return index
}
Expand Down Expand Up @@ -218,11 +246,16 @@ public class CourseUnitViewModel: ObservableObject {
// MARK: Navigation to next vertical
var nextData: VerticalData? {
nextData(
from: VerticalData(
chapterIndex: chapterIndex,
sequentialIndex: sequentialIndex,
verticalIndex: verticalIndex
)
from: currentData
)
}

var currentData: VerticalData {
VerticalData(
chapterIndex: chapterIndex,
sequentialIndex: sequentialIndex,
verticalIndex: verticalIndex,
blockIndex: index
)
}

Expand Down Expand Up @@ -271,6 +304,7 @@ public class CourseUnitViewModel: ObservableObject {
}

if let vertical = vertical(for: resultData), vertical.childs.count > 0 {
resultData.blockIndex = 0
return resultData
} else {
return nextData(from: resultData)
Expand All @@ -291,20 +325,34 @@ public class CourseUnitViewModel: ObservableObject {
)
}

func route(to vertical: CourseVertical) {
if let index = verticals.firstIndex(where: { $0.id == vertical.id }),
let block = vertical.childs.first {
func blockFor(index: Int, in vertical: CourseVertical) -> CourseBlock? {
guard index >= 0 && index < vertical.childs.count else { return nil }
return vertical.childs[index]
}

func route(to data: VerticalData?, animated: Bool = false) {
guard let data = data, data != currentData else { return }
if let vertical = vertical(for: data),
let block = blockFor(index: data.blockIndex, in: vertical) {
router.replaceCourseUnit(
courseName: courseName,
blockId: block.id,
blockId: block.blockId,
courseID: courseID,
sectionName: block.displayName,
verticalIndex: index,
verticalIndex: data.verticalIndex,
chapters: chapters,
chapterIndex: chapterIndex,
sequentialIndex: sequentialIndex,
animated: false
chapterIndex: data.chapterIndex,
sequentialIndex: data.sequentialIndex,
animated: animated
)
}
}

public func route(to blockId: String?) {
guard let data = VerticalData.dataFor(blockId: blockId, in: chapters) else { return }
route(to: data, animated: true)
}

public var currentCourseId: String {
courseID
}
}
11 changes: 8 additions & 3 deletions Course/Course/Presentation/Video/EncodedVideoPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public struct EncodedVideoPlayer: View {
VStack {
PlayerViewController(
videoURL: viewModel.url,
controller: viewModel.controller,
playerHolder: viewModel.controllerHolder,
bitrate: viewModel.getVideoResolution(),
progress: { progress in
if progress >= 0.8 {
Expand All @@ -81,7 +81,10 @@ public struct EncodedVideoPlayer: View {
.frame(minWidth: playerWidth(for: reader.size))
.cornerRadius(12)
.onAppear {
viewModel.controller.player?.play()
if !viewModel.controllerHolder.isPlayingInPip,
!viewModel.controllerHolder.isOtherPlayerInPip {
viewModel.controller.player?.play()
}
}
if isHorizontal {
Spacer()
Expand Down Expand Up @@ -168,7 +171,9 @@ struct EncodedVideoPlayer_Previews: PreviewProvider {
interactor: CourseInteractor(repository: CourseRepositoryMock()),
router: CourseRouterMock(),
appStorage: CoreStorageMock(),
connectivity: Connectivity()
connectivity: Connectivity(),
pipManager: PipManagerProtocolMock(),
selectedCourseTab: 0
),
isOnScreen: true
)
Expand Down
Loading
Loading