Skip to content

Commit

Permalink
Search Channels and Programs (#1037)
Browse files Browse the repository at this point in the history
  • Loading branch information
LePips authored Apr 19, 2024
1 parent 58190d7 commit 2dace31
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ final class MainTabCoordinator: TabCoordinatable {
}
}

func makeSearch() -> NavigationViewCoordinator<SearchCoordinator> {
NavigationViewCoordinator(SearchCoordinator())
// TODO: does this cause issues?
func makeSearch() -> VideoPlayerWrapperCoordinator {
VideoPlayerWrapperCoordinator {
SearchCoordinator()
.view()
}
}

@ViewBuilder
Expand Down
36 changes: 36 additions & 0 deletions Shared/ViewModels/LiveVideoPlayerManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import Foundation
import JellyfinAPI

// TODO: the video player needs to be slightly refactored anyways, so I'm fine
// with the channel retrieving method below and is mainly just for reference
// for how I should probably handle getting the channels of programs elsewhere.

class LiveVideoPlayerManager: VideoPlayerManager {

@Published
Expand All @@ -26,4 +30,36 @@ class LiveVideoPlayerManager: VideoPlayerManager {
}
}
}

init(program: BaseItemDto) {
super.init()

Task {
guard let channel = try? await self.getChannel(for: program), let mediaSource = channel.mediaSources?.first else {
assertionFailure("No channel for program?")
return
}

let viewModel = try await program.liveVideoPlayerViewModel(with: mediaSource, logger: logger)

await MainActor.run {
self.currentViewModel = viewModel
}
}
}

private func getChannel(for program: BaseItemDto) async throws -> BaseItemDto? {

var parameters = Paths.GetItemsByUserIDParameters()
parameters.fields = .MinimumFields
parameters.ids = [program.channelID ?? ""]

let request = Paths.getItemsByUserID(
userID: userSession.user.id,
parameters: parameters
)
let response = try await userSession.client.send(request)

return response.value.items?.first
}
}
1 change: 0 additions & 1 deletion Shared/ViewModels/ProgramsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ final class ProgramsViewModel: ViewModel, Stateful {
var parameters = Paths.GetLiveTvProgramsParameters()
parameters.fields = .MinimumFields
.appending(.channelInfo)
.appending(.mediaSources)
parameters.hasAired = false
parameters.limit = 10
parameters.userID = userSession.user.id
Expand Down
22 changes: 17 additions & 5 deletions Shared/ViewModels/SearchViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ final class SearchViewModel: ViewModel, Stateful {
case searching
}

@Published
private(set) var channels: [BaseItemDto] = []
@Published
private(set) var collections: [BaseItemDto] = []
@Published
Expand All @@ -40,6 +42,8 @@ final class SearchViewModel: ViewModel, Stateful {
@Published
private(set) var people: [BaseItemDto] = []
@Published
private(set) var programs: [BaseItemDto] = []
@Published
private(set) var series: [BaseItemDto] = []
@Published
private(set) var suggestions: [BaseItemDto] = []
Expand All @@ -55,11 +59,15 @@ final class SearchViewModel: ViewModel, Stateful {
let filterViewModel: FilterViewModel

var hasNoResults: Bool {
collections.isEmpty &&
episodes.isEmpty &&
movies.isEmpty &&
people.isEmpty &&
series.isEmpty
[
collections,
channels,
episodes,
movies,
people,
programs,
series,
].allSatisfy(\.isEmpty)
}

// MARK: init
Expand Down Expand Up @@ -144,7 +152,9 @@ final class SearchViewModel: ViewModel, Stateful {
.boxSet,
.episode,
.movie,
.liveTvProgram,
.series,
.tvChannel,
]

for type in retrievingItemTypes {
Expand Down Expand Up @@ -173,9 +183,11 @@ final class SearchViewModel: ViewModel, Stateful {

await MainActor.run {
self.collections = items[.boxSet] ?? []
self.channels = items[.tvChannel] ?? []
self.episodes = items[.episode] ?? []
self.movies = items[.movie] ?? []
self.people = items[.person] ?? []
self.programs = items[.liveTvProgram] ?? []
self.series = items[.series] ?? []

self.state = .content
Expand Down
26 changes: 24 additions & 2 deletions Swiftfin tvOS/Views/SearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ struct SearchView: View {
@Default(.Customization.searchPosterType)
private var searchPosterType

@EnvironmentObject
private var videoPlayerRouter: VideoPlayerWrapperCoordinator.Router
@EnvironmentObject
private var router: SearchCoordinator.Router

Expand Down Expand Up @@ -58,15 +60,35 @@ struct SearchView: View {
if viewModel.people.isNotEmpty {
itemsSection(title: L10n.people, keyPath: \.people, posterType: .portrait)
}

if viewModel.programs.isNotEmpty {
itemsSection(title: L10n.programs, keyPath: \.programs, posterType: .landscape)
}

if viewModel.channels.isNotEmpty {
itemsSection(title: L10n.channels, keyPath: \.channels, posterType: .portrait)
}
}
}
}

private func select(_ item: BaseItemDto) {
if item.type == .person {
switch item.type {
case .person:
let viewModel = ItemLibraryViewModel(parent: item)
router.route(to: \.library, viewModel)
} else {
case .program:
videoPlayerRouter.route(
to: \.liveVideoPlayer,
LiveVideoPlayerManager(program: item)
)
case .tvChannel:
guard let mediaSource = item.mediaSources?.first else { return }
videoPlayerRouter.route(
to: \.liveVideoPlayer,
LiveVideoPlayerManager(item: item, mediaSource: mediaSource)
)
default:
router.route(to: \.item, item)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import JellyfinAPI
import SwiftUI

// TODO: item-type dependent views may be more appropriate near/on
// the `PosterButton` object instead of on these larger views
extension ProgramsView {

struct ProgramProgressOverlay: View {
Expand Down
28 changes: 26 additions & 2 deletions Swiftfin/Views/SearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ import SwiftUI
// TODO: have a `SearchLibraryViewModel` that allows paging on searched items?
// TODO: implement search view result type between `PosterHStack`
// and `ListHStack` (3 row list columns)? (iOS only)
// TODO: have programs only pull recommended/current?
// - have progress overlay
struct SearchView: View {

@Default(.Customization.Search.enabledDrawerFilters)
private var enabledDrawerFilters
@Default(.Customization.searchPosterType)
private var searchPosterType

@EnvironmentObject
private var mainRouter: MainCoordinator.Router
@EnvironmentObject
private var router: SearchCoordinator.Router

Expand Down Expand Up @@ -68,16 +72,36 @@ struct SearchView: View {
if viewModel.people.isNotEmpty {
itemsSection(title: L10n.people, keyPath: \.people, posterType: .portrait)
}

if viewModel.programs.isNotEmpty {
itemsSection(title: L10n.programs, keyPath: \.programs, posterType: .landscape)
}

if viewModel.channels.isNotEmpty {
itemsSection(title: L10n.channels, keyPath: \.channels, posterType: .portrait)
}
}
.edgePadding(.vertical)
}
}

private func select(_ item: BaseItemDto) {
if item.type == .person {
switch item.type {
case .person:
let viewModel = ItemLibraryViewModel(parent: item)
router.route(to: \.library, viewModel)
} else {
case .program:
mainRouter.route(
to: \.liveVideoPlayer,
LiveVideoPlayerManager(program: item)
)
case .tvChannel:
guard let mediaSource = item.mediaSources?.first else { return }
mainRouter.route(
to: \.liveVideoPlayer,
LiveVideoPlayerManager(item: item, mediaSource: mediaSource)
)
default:
router.route(to: \.item, item)
}
}
Expand Down

0 comments on commit 2dace31

Please sign in to comment.