1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-06-28 16:13:02 +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 eccedc0ab0
commit 3d069cdf5b
6 changed files with 39 additions and 27 deletions

View File

@ -246,7 +246,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;
} }
@ -529,7 +529,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
@ -688,7 +688,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);
} }
@ -1028,7 +1028,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();
} }
@ -1244,7 +1244,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
@ -1260,7 +1260,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);
} }
} }
@ -1327,7 +1327,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));
} }
@ -1861,7 +1861,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;
} }
@ -1890,7 +1890,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;
} }
@ -1990,7 +1990,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);
} }
@ -2067,7 +2067,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();
@ -2332,7 +2332,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);
@ -2346,7 +2346,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);
@ -2357,7 +2357,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);
} }
@ -2454,7 +2454,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

@ -473,14 +473,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

@ -148,7 +148,7 @@ public final class PlayerService extends MediaBrowserServiceCompat {
// no one already and starting the service in foreground should not create any issues. // no one already and starting the service in foreground should not create any issues.
// If the service is already started in foreground, requesting it to be started // If the service is already started in foreground, requesting it to be started
// shouldn't do anything. // shouldn't do anything.
player.UIs().get(NotificationPlayerUi.class) player.UIs().getOpt(NotificationPlayerUi.class)
.ifPresent(NotificationPlayerUi::createNotificationAndStartForeground); .ifPresent(NotificationPlayerUi::createNotificationAndStartForeground);
if (playerWasNull && onPlayerStartedOrStopped != null) { if (playerWasNull && onPlayerStartedOrStopped != null) {
@ -173,7 +173,7 @@ public final class PlayerService extends MediaBrowserServiceCompat {
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

@ -138,7 +138,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
* [Optional] 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