Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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 @@ -1069,7 +1069,7 @@ class VideoDetailFragment :

val queue = setupPlayQueueForIntent(append)
if (append) {
NavigationHelper.enqueueOnPlayer(activity, queue, PlayerType.AUDIO)
NavigationHelper.enqueueOnPlayer(activity, queue, PlayerType.BACKGROUND)
} else {
replaceQueueIfUserConfirms {
NavigationHelper.playOnBackgroundPlayer(activity, queue, true)
Expand Down
15 changes: 9 additions & 6 deletions app/src/main/java/org/schabi/newpipe/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -566,9 +566,12 @@ private static PlayQueue getPlayQueueFromCache(@NonNull final Intent intent) {
}

private void initUIsForCurrentPlayerType() {
if ((UIs.get(MainPlayerUi.class) != null && playerType == PlayerType.MAIN)
|| (UIs.get(BackgroundPlayerUi.class) != null && playerType == PlayerType.AUDIO)
|| (UIs.get(PopupPlayerUi.class) != null && playerType == PlayerType.POPUP)) {
final var playerClass = switch (playerType) {
case MAIN -> MainPlayerUi.class;
case POPUP -> PopupPlayerUi.class;
case BACKGROUND -> BackgroundPlayerUi.class;
};
if (UIs.get(playerClass) != null) {
// correct UI already in place
return;
}
Expand All @@ -578,7 +581,7 @@ private void initUIsForCurrentPlayerType() {
final PlayerBinding binding;
if (ui != null) {
binding = ui.getBinding();
} else if (playerType == PlayerType.AUDIO) {
} else if (playerType == PlayerType.BACKGROUND) {
binding = null;
} else {
binding = PlayerBinding.inflate(LayoutInflater.from(context));
Expand All @@ -595,7 +598,7 @@ private void initUIsForCurrentPlayerType() {
UIs.destroyAllOfType(BackgroundPlayerUi.class);
UIs.addAndPrepare(new PopupPlayerUi(this, binding));
break;
case AUDIO:
case BACKGROUND:
// destroys both MainPlayerUi and PopupPlayerUi
UIs.destroyAllOfType(VideoPlayerUi.class);
UIs.addAndPrepare(new BackgroundPlayerUi(this));
Expand Down Expand Up @@ -2406,7 +2409,7 @@ public PlayerType getPlayerType() {
}

public boolean audioPlayerSelected() {
return playerType == PlayerType.AUDIO;
return playerType == PlayerType.BACKGROUND;
}

public boolean videoPlayerSelected() {
Expand Down
16 changes: 12 additions & 4 deletions app/src/main/java/org/schabi/newpipe/player/PlayerType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@

package org.schabi.newpipe.player

enum class PlayerType {
MAIN,
AUDIO,
POPUP
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.PlaylistPlay
import androidx.compose.material.icons.filled.Headphones
import androidx.compose.material.icons.filled.PictureInPicture
import androidx.compose.ui.graphics.vector.ImageVector

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion you shouldn't add Compose code in the non-UI player one. The player has already a lot of dependencies breaking separation concerns.

import org.schabi.newpipe.R

enum class PlayerType(@StringRes val title: Int, val icon: ImageVector) {
BACKGROUND(R.string.controls_background_title, Icons.Default.Headphones),
MAIN(R.string.controls_main_title, Icons.AutoMirrored.Filled.PlaylistPlay),
POPUP(R.string.controls_popup_title, Icons.Default.PictureInPicture)
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package org.schabi.newpipe.ui.components.common

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.RichTooltip
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SegmentedButtonDefaults
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipAnchorPosition
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults.rememberTooltipPositionProvider
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewWrapper
import androidx.compose.ui.unit.dp
import net.newpipe.app.preview.ThemePreviewProvider
import org.schabi.newpipe.R
import org.schabi.newpipe.ktx.findFragmentActivity
import org.schabi.newpipe.player.PlayerType
import org.schabi.newpipe.player.playqueue.PlayQueue
import org.schabi.newpipe.util.NavigationHelper.playOnBackgroundPlayer
import org.schabi.newpipe.util.NavigationHelper.playOnMainPlayer
import org.schabi.newpipe.util.NavigationHelper.playOnPopupPlayer
import org.schabi.newpipe.util.PermissionHelper

@Composable
fun PlayerOptions(queue: PlayQueue) {
val context = LocalContext.current
var selectedOption by rememberSaveable { mutableStateOf<PlayerType?>(null) }

LaunchedEffect(selectedOption) {
when (selectedOption) {
PlayerType.MAIN -> playOnMainPlayer(context.findFragmentActivity(), queue)
PlayerType.BACKGROUND -> playOnBackgroundPlayer(context, queue, true)
PlayerType.POPUP -> playOnPopupPlayer(context, queue, false)
else -> {}
}
}

PlayerOptions(
selectedOption = selectedOption,
onSelectOption = {
if (it != PlayerType.POPUP || PermissionHelper.checkSystemAlertWindowPermission(context)) {
selectedOption = it
}
}
)
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PlayerOptions(
selectedOption: PlayerType?,
onSelectOption: (PlayerType) -> Unit
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = stringResource(R.string.player_options_label))

SingleChoiceSegmentedButtonRow {
PlayerType.entries.forEachIndexed { index, key ->
val tooltipState = rememberTooltipState()

TooltipBox(
positionProvider = rememberTooltipPositionProvider(positioning = TooltipAnchorPosition.Above),
tooltip = {
RichTooltip {
Text(text = stringResource(key.title))
}
},
state = tooltipState
) {
SegmentedButton(
selected = key == selectedOption,
onClick = { onSelectOption(key) },
shape = SegmentedButtonDefaults
.itemShape(index = index, count = PlayerType.entries.size)
) {
Icon(
imageVector = key.icon,
contentDescription = stringResource(key.title)
)
}
}
}
}
}
}

@PreviewWrapper(ThemePreviewProvider::class)
@PreviewLightDark
@Composable
private fun PlayerOptionsPreview() {
PlayerOptions(
selectedOption = PlayerType.MAIN,
onSelectOption = {}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import org.schabi.newpipe.local.history.HistoryViewModel
import org.schabi.newpipe.local.history.SortKey
import org.schabi.newpipe.player.playqueue.PlayQueue
import org.schabi.newpipe.player.playqueue.SinglePlayQueue
import org.schabi.newpipe.ui.components.common.PlaybackControlButtons
import org.schabi.newpipe.ui.components.common.PlayerOptions
import org.schabi.newpipe.ui.components.items.ItemList
import org.schabi.newpipe.ui.theme.AppTheme

Expand Down Expand Up @@ -61,14 +61,14 @@ private fun HistoryHeader(
verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterVertically),
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally)
) {
HistorySortRow(sortKey, onSelectSortKey)
HistorySortOptions(sortKey, onSelectSortKey)

PlaybackControlButtons(queue)
PlayerOptions(queue)
}
}

@Composable
private fun HistorySortRow(
private fun HistorySortOptions(
sortKey: SortKey,
onSelectSortKey: (SortKey) -> Unit
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public static void playOnBackgroundPlayer(final Context context,

final Intent intent = getPlayerIntent(context, PlayerService.class, queue,
PlayerIntentType.AllOthers)
.putExtra(Player.PLAYER_TYPE, PlayerType.AUDIO)
.putExtra(Player.PLAYER_TYPE, PlayerType.BACKGROUND)
.putExtra(Player.RESUME_PLAYBACK, resumePlayback);
ContextCompat.startForegroundService(context, intent);
}
Expand Down Expand Up @@ -198,7 +198,7 @@ public static void enqueueOnPlayer(final Context context, final PlayQueue queue)
PlayerType playerType = PlayerHolder.INSTANCE.getType();
if (playerType == null) {
Log.e(TAG, "Enqueueing but no player is open; defaulting to background player");
playerType = PlayerType.AUDIO;
playerType = PlayerType.BACKGROUND;
}

enqueueOnPlayer(context, queue, playerType);
Expand All @@ -209,7 +209,7 @@ public static void enqueueNextOnPlayer(final Context context, final PlayQueue qu
PlayerType playerType = PlayerHolder.INSTANCE.getType();
if (playerType == null) {
Log.e(TAG, "Enqueueing next but no player is open; defaulting to background player");
playerType = PlayerType.AUDIO;
playerType = PlayerType.BACKGROUND;
}
Toast.makeText(context, R.string.enqueued_next, Toast.LENGTH_SHORT).show();
final Intent intent = getPlayerEnqueueNextIntent(context, PlayerService.class, queue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ object PlayButtonHelper {
true
}
playlistControlBinding.playlistCtrlPlayBgButton.setOnLongClickListener {
NavigationHelper.enqueueOnPlayer(activity, fragment.getPlayQueue(), PlayerType.AUDIO)
NavigationHelper.enqueueOnPlayer(activity, fragment.getPlayQueue(), PlayerType.BACKGROUND)
true
}
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
<string name="tab_bookmarks">Bookmarked Playlists</string>
<string name="tab_bookmarks_short">Playlists</string>
<string name="tab_choose">Choose Tab</string>
<string name="player_options_label">Player</string>
<string name="controls_main_title">Main</string>
Comment thread
TobiGr marked this conversation as resolved.
Outdated
<string name="controls_background_title">Background</string>
<string name="controls_popup_title">Popup</string>
<string name="controls_add_to_playlist_title">Add To</string>
Expand Down
Loading