From c98f63c5e41f63435b8bc80799d6c9b366967c7d Mon Sep 17 00:00:00 2001 From: jhays Date: Sat, 20 Nov 2021 14:57:20 -0600 Subject: [PATCH] support playback on programs view --- .../Views/LiveTVProgramsView.swift | 30 ++++++++-- .../LiveTVChannelsCoordinator.swift | 1 + .../LiveTVProgramsCoordinator.swift | 6 +- .../ViewModels/LiveTVChannelsViewModel.swift | 2 +- .../ViewModels/LiveTVProgramsViewModel.swift | 57 +++++++++++++++---- 5 files changed, 74 insertions(+), 22 deletions(-) diff --git a/JellyfinPlayer tvOS/Views/LiveTVProgramsView.swift b/JellyfinPlayer tvOS/Views/LiveTVProgramsView.swift index f979848b..acefbada 100644 --- a/JellyfinPlayer tvOS/Views/LiveTVProgramsView.swift +++ b/JellyfinPlayer tvOS/Views/LiveTVProgramsView.swift @@ -28,7 +28,10 @@ struct LiveTVProgramsView: View { Spacer().frame(width: 45) ForEach(items, id: \.id) { item in Button { - self.programsRouter.route(to: \.modalItem, item) + if let chanId = item.channelId, + let chan = viewModel.findChannel(id: chanId) { + self.programsRouter.route(to: \.videoPlayer, chan) + } } label: { LandscapeItemElement(item: item) } @@ -49,7 +52,10 @@ struct LiveTVProgramsView: View { Spacer().frame(width: 45) ForEach(items, id: \.id) { item in Button { - self.programsRouter.route(to: \.modalItem, item) + if let chanId = item.channelId, + let chan = viewModel.findChannel(id: chanId) { + self.programsRouter.route(to: \.videoPlayer, chan) + } } label: { LandscapeItemElement(item: item) } @@ -70,7 +76,10 @@ struct LiveTVProgramsView: View { Spacer().frame(width: 45) ForEach(items, id: \.id) { item in Button { - self.programsRouter.route(to: \.modalItem, item) + if let chanId = item.channelId, + let chan = viewModel.findChannel(id: chanId) { + self.programsRouter.route(to: \.videoPlayer, chan) + } } label: { LandscapeItemElement(item: item) } @@ -91,7 +100,10 @@ struct LiveTVProgramsView: View { Spacer().frame(width: 45) ForEach(items, id: \.id) { item in Button { - self.programsRouter.route(to: \.modalItem, item) + if let chanId = item.channelId, + let chan = viewModel.findChannel(id: chanId) { + self.programsRouter.route(to: \.videoPlayer, chan) + } } label: { LandscapeItemElement(item: item) } @@ -112,7 +124,10 @@ struct LiveTVProgramsView: View { Spacer().frame(width: 45) ForEach(items, id: \.id) { item in Button { - self.programsRouter.route(to: \.modalItem, item) + if let chanId = item.channelId, + let chan = viewModel.findChannel(id: chanId) { + self.programsRouter.route(to: \.videoPlayer, chan) + } } label: { LandscapeItemElement(item: item) } @@ -133,7 +148,10 @@ struct LiveTVProgramsView: View { Spacer().frame(width: 45) ForEach(items, id: \.id) { item in Button { - self.programsRouter.route(to: \.modalItem, item) + if let chanId = item.channelId, + let chan = viewModel.findChannel(id: chanId) { + self.programsRouter.route(to: \.videoPlayer, chan) + } } label: { LandscapeItemElement(item: item) } diff --git a/Shared/Coordinators/LiveTVChannelsCoordinator.swift b/Shared/Coordinators/LiveTVChannelsCoordinator.swift index d2915f92..f2a6e482 100644 --- a/Shared/Coordinators/LiveTVChannelsCoordinator.swift +++ b/Shared/Coordinators/LiveTVChannelsCoordinator.swift @@ -22,6 +22,7 @@ final class LiveTVChannelsCoordinator: NavigationCoordinatable { func makeModalItem(item: BaseItemDto) -> NavigationViewCoordinator { return NavigationViewCoordinator(ItemCoordinator(item: item)) } + func makeVideoPlayer(item: BaseItemDto) -> NavigationViewCoordinator { NavigationViewCoordinator(VideoPlayerCoordinator(item: item)) } diff --git a/Shared/Coordinators/LiveTVProgramsCoordinator.swift b/Shared/Coordinators/LiveTVProgramsCoordinator.swift index c500697e..1dd26daf 100644 --- a/Shared/Coordinators/LiveTVProgramsCoordinator.swift +++ b/Shared/Coordinators/LiveTVProgramsCoordinator.swift @@ -17,10 +17,10 @@ final class LiveTVProgramsCoordinator: NavigationCoordinatable { let stack = NavigationStack(initial: \LiveTVProgramsCoordinator.start) @Root var start = makeStart - @Route(.modal) var modalItem = makeModalItem + @Route(.fullScreen) var videoPlayer = makeVideoPlayer - func makeModalItem(item: BaseItemDto) -> NavigationViewCoordinator { - return NavigationViewCoordinator(ItemCoordinator(item: item)) + func makeVideoPlayer(item: BaseItemDto) -> NavigationViewCoordinator { + NavigationViewCoordinator(VideoPlayerCoordinator(item: item)) } @ViewBuilder diff --git a/Shared/ViewModels/LiveTVChannelsViewModel.swift b/Shared/ViewModels/LiveTVChannelsViewModel.swift index e20df2ee..f4899e8f 100644 --- a/Shared/ViewModels/LiveTVChannelsViewModel.swift +++ b/Shared/ViewModels/LiveTVChannelsViewModel.swift @@ -70,7 +70,7 @@ final class LiveTVChannelsViewModel: ViewModel { LiveTvAPI.getLiveTvChannels( userId: SessionManager.main.currentLogin.user.id, startIndex: 0, - limit: 500, + limit: 1000, enableImageTypes: [.primary], enableUserData: false, enableFavoriteSorting: true diff --git a/Shared/ViewModels/LiveTVProgramsViewModel.swift b/Shared/ViewModels/LiveTVProgramsViewModel.swift index 29023213..862e3534 100644 --- a/Shared/ViewModels/LiveTVProgramsViewModel.swift +++ b/Shared/ViewModels/LiveTVProgramsViewModel.swift @@ -19,18 +19,51 @@ final class LiveTVProgramsViewModel: ViewModel { @Published var kidsItems = [BaseItemDto]() @Published var newsItems = [BaseItemDto]() + private var channels = [String:BaseItemDto]() + override init() { super.init() - loadRecommendedPrograms() - loadSeries() - loadMovies() - loadSports() - loadKids() - loadNews() + getChannels() } - private func loadRecommendedPrograms() { + func findChannel(id: String) -> BaseItemDto? { + return channels[id] + } + + private func getChannels() { + LiveTvAPI.getLiveTvChannels( + userId: SessionManager.main.currentLogin.user.id, + startIndex: 0, + limit: 1000, + enableImageTypes: [.primary], + enableUserData: false, + enableFavoriteSorting: true + ) + .trackActivity(loading) + .sink(receiveCompletion: { [weak self] completion in + self?.handleAPIRequestError(completion: completion) + }, receiveValue: { [weak self] response in + LogManager.shared.log.debug("Received \(response.items?.count ?? 0) Channels") + guard let self = self else { return } + if let chans = response.items { + for chan in chans { + if let chanId = chan.id { + self.channels[chanId] = chan + } + } + self.getRecommendedPrograms() + self.getSeries() + self.getMovies() + self.getSports() + self.getKids() + self.getNews() + } + }) + .store(in: &cancellables) + } + + private func getRecommendedPrograms() { LiveTvAPI.getRecommendedPrograms( userId: SessionManager.main.currentLogin.user.id, limit: 9, @@ -51,7 +84,7 @@ final class LiveTVProgramsViewModel: ViewModel { .store(in: &cancellables) } - private func loadSeries() { + private func getSeries() { let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id, hasAired: false, isMovie: false, @@ -77,7 +110,7 @@ final class LiveTVProgramsViewModel: ViewModel { .store(in: &cancellables) } - private func loadMovies() { + private func getMovies() { let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id, hasAired: false, isMovie: true, @@ -103,7 +136,7 @@ final class LiveTVProgramsViewModel: ViewModel { .store(in: &cancellables) } - private func loadSports() { + private func getSports() { let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id, hasAired: false, isSports: true, @@ -125,7 +158,7 @@ final class LiveTVProgramsViewModel: ViewModel { .store(in: &cancellables) } - private func loadKids() { + private func getKids() { let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id, hasAired: false, isKids: true, @@ -147,7 +180,7 @@ final class LiveTVProgramsViewModel: ViewModel { .store(in: &cancellables) } - private func loadNews() { + private func getNews() { let getProgramsDto = GetProgramsDto(userId: SessionManager.main.currentLogin.user.id, hasAired: false, isNews: true,