1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-01-08 00:10:32 +00:00

PlayerUIList: rename get to getOpt and make get nullable

In Kotlin, dealing with nulls works better so we don’t need optional.
This commit is contained in:
Profpatsch 2024-12-26 12:05:10 +01:00
parent 6830890f98
commit 5b92de4f76
6 changed files with 40 additions and 28 deletions

View File

@ -243,7 +243,7 @@ public final class VideoDetailFragment
// It will do nothing if the player is not in fullscreen mode // It will do nothing if the player is not in fullscreen mode
hideSystemUiIfNeeded(); hideSystemUiIfNeeded();
final Optional<MainPlayerUi> playerUi = player.UIs().get(MainPlayerUi.class); final Optional<MainPlayerUi> playerUi = player.UIs().getOpt(MainPlayerUi.class);
if (!player.videoPlayerSelected() && !playAfterConnect) { if (!player.videoPlayerSelected() && !playAfterConnect) {
return; return;
} }
@ -519,7 +519,7 @@ public final class VideoDetailFragment
binding.overlayPlayPauseButton.setOnClickListener(v -> { binding.overlayPlayPauseButton.setOnClickListener(v -> {
if (playerIsNotStopped()) { if (playerIsNotStopped()) {
player.playPause(); player.playPause();
player.UIs().get(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0)); player.UIs().getOpt(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0));
showSystemUi(); showSystemUi();
} else { } else {
autoPlayEnabled = true; // forcefully start playing autoPlayEnabled = true; // forcefully start playing
@ -678,7 +678,7 @@ public final class VideoDetailFragment
@Override @Override
public boolean onKeyDown(final int keyCode) { public boolean onKeyDown(final int keyCode) {
return isPlayerAvailable() return isPlayerAvailable()
&& player.UIs().get(VideoPlayerUi.class) && player.UIs().getOpt(VideoPlayerUi.class)
.map(playerUi -> playerUi.onKeyDown(keyCode)).orElse(false); .map(playerUi -> playerUi.onKeyDown(keyCode)).orElse(false);
} }
@ -1018,7 +1018,7 @@ public final class VideoDetailFragment
// If a user watched video inside fullscreen mode and than chose another player // If a user watched video inside fullscreen mode and than chose another player
// return to non-fullscreen mode // return to non-fullscreen mode
if (isPlayerAvailable()) { if (isPlayerAvailable()) {
player.UIs().get(MainPlayerUi.class).ifPresent(playerUi -> { player.UIs().getOpt(MainPlayerUi.class).ifPresent(playerUi -> {
if (playerUi.isFullscreen()) { if (playerUi.isFullscreen()) {
playerUi.toggleFullscreen(); playerUi.toggleFullscreen();
} }
@ -1234,7 +1234,7 @@ public final class VideoDetailFragment
// setup the surface view height, so that it fits the video correctly // setup the surface view height, so that it fits the video correctly
setHeightThumbnail(); setHeightThumbnail();
player.UIs().get(MainPlayerUi.class).ifPresent(playerUi -> { player.UIs().getOpt(MainPlayerUi.class).ifPresent(playerUi -> {
// sometimes binding would be null here, even though getView() != null above u.u // sometimes binding would be null here, even though getView() != null above u.u
if (binding != null) { if (binding != null) {
// prevent from re-adding a view multiple times // prevent from re-adding a view multiple times
@ -1250,7 +1250,7 @@ public final class VideoDetailFragment
makeDefaultHeightForVideoPlaceholder(); makeDefaultHeightForVideoPlaceholder();
if (player != null) { if (player != null) {
player.UIs().get(VideoPlayerUi.class).ifPresent(VideoPlayerUi::removeViewFromParent); player.UIs().getOpt(VideoPlayerUi.class).ifPresent(VideoPlayerUi::removeViewFromParent);
} }
} }
@ -1317,7 +1317,7 @@ public final class VideoDetailFragment
binding.detailThumbnailImageView.setMinimumHeight(newHeight); binding.detailThumbnailImageView.setMinimumHeight(newHeight);
if (isPlayerAvailable()) { if (isPlayerAvailable()) {
final int maxHeight = (int) (metrics.heightPixels * MAX_PLAYER_HEIGHT); final int maxHeight = (int) (metrics.heightPixels * MAX_PLAYER_HEIGHT);
player.UIs().get(VideoPlayerUi.class).ifPresent(ui -> player.UIs().getOpt(VideoPlayerUi.class).ifPresent(ui ->
ui.getBinding().surfaceView.setHeights(newHeight, ui.getBinding().surfaceView.setHeights(newHeight,
ui.isFullscreen() ? newHeight : maxHeight)); ui.isFullscreen() ? newHeight : maxHeight));
} }
@ -1848,7 +1848,7 @@ public final class VideoDetailFragment
public void onFullscreenStateChanged(final boolean fullscreen) { public void onFullscreenStateChanged(final boolean fullscreen) {
setupBrightness(); setupBrightness();
if (!isPlayerAndPlayerServiceAvailable() if (!isPlayerAndPlayerServiceAvailable()
|| player.UIs().get(MainPlayerUi.class).isEmpty() || player.UIs().getOpt(MainPlayerUi.class).isEmpty()
|| getRoot().map(View::getParent).isEmpty()) { || getRoot().map(View::getParent).isEmpty()) {
return; return;
} }
@ -1877,7 +1877,7 @@ public final class VideoDetailFragment
final boolean isLandscape = DeviceUtils.isLandscape(requireContext()); final boolean isLandscape = DeviceUtils.isLandscape(requireContext());
if (DeviceUtils.isTablet(activity) if (DeviceUtils.isTablet(activity)
&& (!globalScreenOrientationLocked(activity) || isLandscape)) { && (!globalScreenOrientationLocked(activity) || isLandscape)) {
player.UIs().get(MainPlayerUi.class).ifPresent(MainPlayerUi::toggleFullscreen); player.UIs().getOpt(MainPlayerUi.class).ifPresent(MainPlayerUi::toggleFullscreen);
return; return;
} }
@ -1977,7 +1977,7 @@ public final class VideoDetailFragment
} }
private boolean isFullscreen() { private boolean isFullscreen() {
return isPlayerAvailable() && player.UIs().get(VideoPlayerUi.class) return isPlayerAvailable() && player.UIs().getOpt(VideoPlayerUi.class)
.map(VideoPlayerUi::isFullscreen).orElse(false); .map(VideoPlayerUi::isFullscreen).orElse(false);
} }
@ -2054,7 +2054,7 @@ public final class VideoDetailFragment
setAutoPlay(true); setAutoPlay(true);
} }
player.UIs().get(MainPlayerUi.class).ifPresent(MainPlayerUi::checkLandscape); player.UIs().getOpt(MainPlayerUi.class).ifPresent(MainPlayerUi::checkLandscape);
// Let's give a user time to look at video information page if video is not playing // Let's give a user time to look at video information page if video is not playing
if (globalScreenOrientationLocked(activity) && !player.isPlaying()) { if (globalScreenOrientationLocked(activity) && !player.isPlaying()) {
player.play(); player.play();
@ -2319,7 +2319,7 @@ public final class VideoDetailFragment
&& player.isPlaying() && player.isPlaying()
&& !isFullscreen() && !isFullscreen()
&& !DeviceUtils.isTablet(activity)) { && !DeviceUtils.isTablet(activity)) {
player.UIs().get(MainPlayerUi.class) player.UIs().getOpt(MainPlayerUi.class)
.ifPresent(MainPlayerUi::toggleFullscreen); .ifPresent(MainPlayerUi::toggleFullscreen);
} }
setOverlayLook(binding.appBarLayout, behavior, 1); setOverlayLook(binding.appBarLayout, behavior, 1);
@ -2333,7 +2333,7 @@ public final class VideoDetailFragment
// Re-enable clicks // Re-enable clicks
setOverlayElementsClickable(true); setOverlayElementsClickable(true);
if (isPlayerAvailable()) { if (isPlayerAvailable()) {
player.UIs().get(MainPlayerUi.class) player.UIs().getOpt(MainPlayerUi.class)
.ifPresent(MainPlayerUi::closeItemsList); .ifPresent(MainPlayerUi::closeItemsList);
} }
setOverlayLook(binding.appBarLayout, behavior, 0); setOverlayLook(binding.appBarLayout, behavior, 0);
@ -2344,7 +2344,7 @@ public final class VideoDetailFragment
showSystemUi(); showSystemUi();
} }
if (isPlayerAvailable()) { if (isPlayerAvailable()) {
player.UIs().get(MainPlayerUi.class).ifPresent(ui -> { player.UIs().getOpt(MainPlayerUi.class).ifPresent(ui -> {
if (ui.isControlsVisible()) { if (ui.isControlsVisible()) {
ui.hideControls(0, 0); ui.hideControls(0, 0);
} }
@ -2441,7 +2441,7 @@ public final class VideoDetailFragment
public Optional<View> getRoot() { public Optional<View> getRoot() {
return Optional.ofNullable(player) return Optional.ofNullable(player)
.flatMap(player1 -> player1.UIs().get(VideoPlayerUi.class)) .flatMap(player1 -> player1.UIs().getOpt(VideoPlayerUi.class))
.map(playerUi -> playerUi.getBinding().getRoot()); .map(playerUi -> playerUi.getBinding().getRoot());
} }

View File

@ -463,14 +463,15 @@ public final class Player implements PlaybackListener, Listener {
} }
private void initUIsForCurrentPlayerType() { private void initUIsForCurrentPlayerType() {
if ((UIs.get(MainPlayerUi.class).isPresent() && playerType == PlayerType.MAIN) if ((UIs.getOpt(MainPlayerUi.class).isPresent() && playerType == PlayerType.MAIN)
|| (UIs.get(PopupPlayerUi.class).isPresent() && playerType == PlayerType.POPUP)) { || (UIs.getOpt(PopupPlayerUi.class).isPresent()
&& playerType == PlayerType.POPUP)) {
// correct UI already in place // correct UI already in place
return; return;
} }
// try to reuse binding if possible // try to reuse binding if possible
final PlayerBinding binding = UIs.get(VideoPlayerUi.class).map(VideoPlayerUi::getBinding) final PlayerBinding binding = UIs.getOpt(VideoPlayerUi.class).map(VideoPlayerUi::getBinding)
.orElseGet(() -> { .orElseGet(() -> {
if (playerType == PlayerType.AUDIO) { if (playerType == PlayerType.AUDIO) {
return null; return null;

View File

@ -66,7 +66,7 @@ public final class PlayerService extends Service {
loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the
service would never be put in the foreground while we said to the system we would do so service would never be put in the foreground while we said to the system we would do so
*/ */
player.UIs().get(NotificationPlayerUi.class) player.UIs().getOpt(NotificationPlayerUi.class)
.ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground);
} }
@ -88,7 +88,7 @@ public final class PlayerService extends Service {
do anything do anything
*/ */
if (player != null) { if (player != null) {
player.UIs().get(NotificationPlayerUi.class) player.UIs().getOpt(NotificationPlayerUi.class)
.ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground);
} }
@ -106,7 +106,7 @@ public final class PlayerService extends Service {
if (player != null) { if (player != null) {
player.handleIntent(intent); player.handleIntent(intent);
player.UIs().get(MediaSessionPlayerUi.class) player.UIs().getOpt(MediaSessionPlayerUi.class)
.ifPresent(ui -> ui.handleMediaButtonIntent(intent)); .ifPresent(ui -> ui.handleMediaButtonIntent(intent));
} }

View File

@ -145,7 +145,7 @@ public class MediaSessionPlayerUi extends PlayerUi
public void play() { public void play() {
player.play(); player.play();
// hide the player controls even if the play command came from the media session // hide the player controls even if the play command came from the media session
player.UIs().get(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0)); player.UIs().getOpt(VideoPlayerUi.class).ifPresent(ui -> ui.hideControls(0, 0));
} }
@Override @Override

View File

@ -102,7 +102,7 @@ public final class NotificationUtil {
mediaStyle.setShowActionsInCompactView(compactSlots); mediaStyle.setShowActionsInCompactView(compactSlots);
} }
player.UIs() player.UIs()
.get(MediaSessionPlayerUi.class) .getOpt(MediaSessionPlayerUi.class)
.flatMap(MediaSessionPlayerUi::getSessionToken) .flatMap(MediaSessionPlayerUi::getSessionToken)
.ifPresent(mediaStyle::setMediaSession); .ifPresent(mediaStyle::setMediaSession);

View File

@ -65,21 +65,32 @@ class PlayerUiList(vararg initialPlayerUis: PlayerUi) {
* @param playerUiType the class of the player UI to return; * @param playerUiType the class of the player UI to return;
* the [Class.isInstance] method will be used, so even subclasses could be returned * the [Class.isInstance] method will be used, so even subclasses could be returned
* @param T the class type parameter * @param T the class type parameter
* @return the first player UI of the required type found in the list, or an empty * @return the first player UI of the required type found in the list, or null
* [ ] otherwise
</T> */ </T> */
fun <T> get(playerUiType: Class<T>): Optional<T & Any> { fun <T> get(playerUiType: Class<T>): T? {
for (ui in playerUis) { for (ui in playerUis) {
if (playerUiType.isInstance(ui)) { if (playerUiType.isInstance(ui)) {
when (val r = playerUiType.cast(ui)) { when (val r = playerUiType.cast(ui)) {
// try all UIs before returning null
null -> continue null -> continue
else -> return Optional.of(r) else -> return r
} }
} }
} }
return Optional.empty() return null
} }
/**
* @param playerUiType the class of the player UI to return;
* the [Class.isInstance] method will be used, so even subclasses could be returned
* @param T the class type parameter
* @return the first player UI of the required type found in the list, or an empty
* [ ] otherwise
</T> */
@Deprecated("use get", ReplaceWith("get(playerUiType)"))
fun <T> getOpt(playerUiType: Class<T>): Optional<T & Any> =
Optional.ofNullable(get(playerUiType))
/** /**
* Calls the provided consumer on all player UIs in the list, in order of addition. * Calls the provided consumer on all player UIs in the list, in order of addition.
* @param consumer the consumer to call with player UIs * @param consumer the consumer to call with player UIs