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

PLAYNEXT-1192 - Improve satellite radios discoverability #523

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import UIKit
@objc class RadioChannelsViewController: PageContainerViewController {
private var radioChannelName: String?

@objc init(radioChannels: [RadioChannel]) {
@objc init(radioChannels: [RadioChannel], satelliteRadioChannels: [RadioChannel]) {
assert(!radioChannels.isEmpty, "At least 1 radio channel expected")

var viewControllers = [UIViewController]()
Expand All @@ -19,14 +19,21 @@ import UIKit
viewControllers.append(pageViewController)
}

var satelliteViewControllers = [UIViewController]()
for (index, satelliteRadioChannel) in satelliteRadioChannels.enumerated() {
let placeholderVC = UIViewController()
placeholderVC.tabBarItem = UITabBarItem(title: satelliteRadioChannel.name, image: RadioChannelLogoImage(satelliteRadioChannel), tag: index + radioChannels.count)
satelliteViewControllers.append(placeholderVC)
}

let lastOpenedRadioChannel = ApplicationSettingLastOpenedRadioChannel()
let initialPage: Int = if let lastOpenedRadioChannel {
radioChannels.firstIndex(of: lastOpenedRadioChannel) ?? NSNotFound
} else {
NSNotFound
}

super.init(viewControllers: viewControllers, initialPage: initialPage)
super.init(viewControllers: viewControllers, placeholderViewControllers: satelliteViewControllers, satelliteRadioChannels: satelliteRadioChannels, initialPage: initialPage)
updateTitle()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,27 @@ class PageContainerViewController: UIViewController {
private var tabContainerViewController: TabContainerViewController
private(set) var initialPage: Int
private let tabBarItems: [TMBarItem]
private let regularRadioChannelsMaxIndex: Int
private weak var tabBarTopConstraint: NSLayoutConstraint?
private weak var blurView: UIVisualEffectView?
private var cancellables: Set<AnyCancellable> = []
private var satelliteRadioChannels: [RadioChannel] = []
private var cancellable: AnyCancellable?

init(viewControllers: [UIViewController], initialPage: Int) {
init(viewControllers: [UIViewController], placeholderViewControllers: [UIViewController], satelliteRadioChannels: [RadioChannel], initialPage: Int) {
assert(!viewControllers.isEmpty, "At least one view controller is required")

self.viewControllers = viewControllers
self.viewControllers = viewControllers + placeholderViewControllers
self.satelliteRadioChannels = satelliteRadioChannels

if initialPage >= 0, initialPage < viewControllers.count {
self.initialPage = initialPage
} else {
PlayLogWarning(category: "pageViewController", message: "Invalid page. Fixed to 0")
self.initialPage = 0
}

tabBarItems = viewControllers.map {
tabBarItems = viewControllers.appending(contentsOf: placeholderViewControllers).map {
if let tabBarItem = $0.tabBarItem, let image = tabBarItem.image {
let item = TMBarItem(image: image)
item.accessibilityLabel = tabBarItem.title ?? $0.title
Expand All @@ -43,15 +48,17 @@ class PageContainerViewController: UIViewController {
}
}

regularRadioChannelsMaxIndex = viewControllers.count - 1

tabContainerViewController = TabContainerViewController()

super.init(nibName: nil, bundle: nil)

addChild(tabContainerViewController)
}

convenience init(viewControllers: [UIViewController]) {
self.init(viewControllers: viewControllers, initialPage: 0)
convenience init(viewControllers: [UIViewController], placeholderViewControllers: [UIViewController], satelliteRadioChannels: [RadioChannel]) {
self.init(viewControllers: viewControllers, placeholderViewControllers: placeholderViewControllers, satelliteRadioChannels: satelliteRadioChannels, initialPage: 0)
}

@available(*, unavailable)
Expand All @@ -67,8 +74,14 @@ class PageContainerViewController: UIViewController {
barView.backgroundView.style = .custom(view: blurView)
barView.layout.alignment = .centerDistributed
barView.indicator.tintColor = .white
barView.buttons.customize { button in

var buttonIndex = 0
barView.buttons.customize { [weak self] button in
guard let self else { return }
button.tag = buttonIndex
button.imageContentMode = .center
button.addTarget(self, action: #selector(tabDidChange(_:)), for: .touchUpInside)
buttonIndex += 1
}
tabContainerViewController.addBar(barView, dataSource: self, at: .top)
}
Expand Down Expand Up @@ -208,7 +221,11 @@ extension PageContainerViewController: PageboyViewControllerDataSource, TMBarDat
}

func viewController(for _: Pageboy.PageboyViewController, at index: Pageboy.PageboyViewController.PageIndex) -> UIViewController? {
viewControllers[index]
if index <= regularRadioChannelsMaxIndex {
viewControllers[index]
} else {
nil
}
}

func defaultPage(for _: Pageboy.PageboyViewController) -> Pageboy.PageboyViewController.Page? {
Expand All @@ -219,3 +236,26 @@ extension PageContainerViewController: PageboyViewControllerDataSource, TMBarDat
tabBarItems[index]
}
}

// MARK: Swiss Satellite Radio

extension PageContainerViewController {
func srgMedia(for radioChannel: RadioChannel) -> AnyPublisher<SRGMedia, Error> {
SRGDataProvider.current!.regionalizedRadioLivestreams(for: ApplicationConfiguration.shared.vendor, contentProviders: .swissSatelliteRadio)
.compactMap { $0.first { $0.uid == radioChannel.uid } }
.eraseToAnyPublisher()
}

@objc private func tabDidChange(_ sender: TMTabItemBarButton) {
if sender.tag > regularRadioChannelsMaxIndex {
cancellable = srgMedia(for: satelliteRadioChannels[sender.tag - regularRadioChannelsMaxIndex - 1])
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { _ in },
receiveValue: { [weak self] srgMedia in
self?.play_presentMediaPlayer(with: srgMedia, position: nil, airPlaySuggestions: true, fromPushNotification: false, animated: true, completion: nil)
}
)
}
}
}
3 changes: 2 additions & 1 deletion Application/Sources/UI/Controllers/TabBarController.m
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ - (UIViewController *)audiosTabViewController
else {
NSArray<RadioChannel *> *radioChannels = applicationConfiguration.radioHomepageChannels;
if (radioChannels.count > 1) {
UIViewController *radioChannelsViewController = [[RadioChannelsViewController alloc] initWithRadioChannels:radioChannels];
NSArray<RadioChannel *> *satelliteRadioChannels = applicationConfiguration.satelliteRadioChannels;
UIViewController *radioChannelsViewController = [[RadioChannelsViewController alloc] initWithRadioChannels:radioChannels satelliteRadioChannels:satelliteRadioChannels];
NavigationController *audiosNavigationController = [[NavigationController alloc] initWithRootViewController:radioChannelsViewController];
audiosNavigationController.tabBarItem = [self audiosTabBarItem];
return audiosNavigationController;
Expand Down