mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Play item directly when clicking play button on remote (#424)
On the home page or any grid, if focused on a "playable" item (movie, episode, etc), pressing the Play or Play-Pause button on the remote will immediately start playback. Dev note: Also guards against an edge case where an item passed into playback doesn't have media sources due to more limited item fields in the query.
This commit is contained in:
parent
c97553f82a
commit
319b46983f
7 changed files with 49 additions and 8 deletions
|
|
@ -579,7 +579,10 @@ fun CollectionFolderGrid(
|
||||||
defaultViewOptions = defaultViewOptions,
|
defaultViewOptions = defaultViewOptions,
|
||||||
onSaveViewOptions = { viewModel.saveViewOptions(it) },
|
onSaveViewOptions = { viewModel.saveViewOptions(it) },
|
||||||
playEnabled = playEnabled,
|
playEnabled = playEnabled,
|
||||||
onClickPlay = { shuffle ->
|
onClickPlay = { _, item ->
|
||||||
|
viewModel.navigationManager.navigateTo(Destination.Playback(item))
|
||||||
|
},
|
||||||
|
onClickPlayAll = { shuffle ->
|
||||||
itemId.toUUIDOrNull()?.let {
|
itemId.toUUIDOrNull()?.let {
|
||||||
viewModel.navigationManager.navigateTo(
|
viewModel.navigationManager.navigateTo(
|
||||||
Destination.PlaybackList(
|
Destination.PlaybackList(
|
||||||
|
|
@ -678,7 +681,8 @@ fun CollectionFolderGridContent(
|
||||||
letterPosition: suspend (Char) -> Int,
|
letterPosition: suspend (Char) -> Int,
|
||||||
sortOptions: List<ItemSortBy>,
|
sortOptions: List<ItemSortBy>,
|
||||||
playEnabled: Boolean,
|
playEnabled: Boolean,
|
||||||
onClickPlay: (shuffle: Boolean) -> Unit,
|
onClickPlayAll: (shuffle: Boolean) -> Unit,
|
||||||
|
onClickPlay: (Int, BaseItem) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
showTitle: Boolean = true,
|
showTitle: Boolean = true,
|
||||||
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
|
||||||
|
|
@ -786,12 +790,12 @@ fun CollectionFolderGridContent(
|
||||||
title = R.string.play,
|
title = R.string.play,
|
||||||
resume = Duration.ZERO,
|
resume = Duration.ZERO,
|
||||||
icon = Icons.Default.PlayArrow,
|
icon = Icons.Default.PlayArrow,
|
||||||
onClick = { onClickPlay.invoke(false) },
|
onClick = { onClickPlayAll.invoke(false) },
|
||||||
)
|
)
|
||||||
ExpandableFaButton(
|
ExpandableFaButton(
|
||||||
title = R.string.shuffle,
|
title = R.string.shuffle,
|
||||||
iconStringRes = R.string.fa_shuffle,
|
iconStringRes = R.string.fa_shuffle,
|
||||||
onClick = { onClickPlay.invoke(true) },
|
onClick = { onClickPlayAll.invoke(true) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -813,6 +817,7 @@ fun CollectionFolderGridContent(
|
||||||
pager = pager,
|
pager = pager,
|
||||||
onClickItem = onClickItem,
|
onClickItem = onClickItem,
|
||||||
onLongClickItem = onLongClickItem,
|
onLongClickItem = onLongClickItem,
|
||||||
|
onClickPlay = onClickPlay,
|
||||||
letterPosition = letterPosition,
|
letterPosition = letterPosition,
|
||||||
gridFocusRequester = gridFocusRequester,
|
gridFocusRequester = gridFocusRequester,
|
||||||
showJumpButtons = false, // TODO add preference
|
showJumpButtons = false, // TODO add preference
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ fun GenreCardGrid(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onLongClickItem = { _, _ -> },
|
onLongClickItem = { _, _ -> },
|
||||||
|
onClickPlay = { _, _ -> },
|
||||||
letterPosition = { viewModel.positionOfLetter(it) },
|
letterPosition = { viewModel.positionOfLetter(it) },
|
||||||
gridFocusRequester = gridFocusRequester,
|
gridFocusRequester = gridFocusRequester,
|
||||||
showJumpButtons = false,
|
showJumpButtons = false,
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,7 @@ fun ItemGrid(
|
||||||
viewModel.navigateTo(Destination.Playback(item.id, 0))
|
viewModel.navigateTo(Destination.Playback(item.id, 0))
|
||||||
},
|
},
|
||||||
onLongClickItem = { index: Int, item: BaseItem -> },
|
onLongClickItem = { index: Int, item: BaseItem -> },
|
||||||
|
onClickPlay = { _, item -> viewModel.navigateTo(Destination.Playback(item)) },
|
||||||
letterPosition = { c: Char -> 0 },
|
letterPosition = { c: Char -> 0 },
|
||||||
gridFocusRequester = focusRequester,
|
gridFocusRequester = focusRequester,
|
||||||
showJumpButtons = false,
|
showJumpButtons = false,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import com.github.damontecres.wholphin.ui.detail.PlaylistLoadingState
|
||||||
import com.github.damontecres.wholphin.ui.detail.buildMoreDialogItemsForHome
|
import com.github.damontecres.wholphin.ui.detail.buildMoreDialogItemsForHome
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.main.HomePageContent
|
import com.github.damontecres.wholphin.ui.main.HomePageContent
|
||||||
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
import com.github.damontecres.wholphin.util.ApiRequestPager
|
import com.github.damontecres.wholphin.util.ApiRequestPager
|
||||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
|
|
@ -146,6 +147,9 @@ fun RecommendedContent(
|
||||||
onLongClickItem = { position, item ->
|
onLongClickItem = { position, item ->
|
||||||
moreDialog.makePresent(RowColumnItem(position, item))
|
moreDialog.makePresent(RowColumnItem(position, item))
|
||||||
},
|
},
|
||||||
|
onClickPlay = { _, item ->
|
||||||
|
viewModel.navigationManager.navigateTo(Destination.Playback(item))
|
||||||
|
},
|
||||||
onFocusPosition = onFocusPosition,
|
onFocusPosition = onFocusPosition,
|
||||||
showClock = preferences.appPreferences.interfacePreferences.showClock,
|
showClock = preferences.appPreferences.interfacePreferences.showClock,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ import com.github.damontecres.wholphin.ui.ifElse
|
||||||
import com.github.damontecres.wholphin.ui.playback.isBackwardButton
|
import com.github.damontecres.wholphin.ui.playback.isBackwardButton
|
||||||
import com.github.damontecres.wholphin.ui.playback.isForwardButton
|
import com.github.damontecres.wholphin.ui.playback.isForwardButton
|
||||||
import com.github.damontecres.wholphin.ui.playback.isPlayKeyUp
|
import com.github.damontecres.wholphin.ui.playback.isPlayKeyUp
|
||||||
|
import com.github.damontecres.wholphin.ui.playback.playable
|
||||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|
@ -78,6 +79,7 @@ fun CardGrid(
|
||||||
pager: List<BaseItem?>,
|
pager: List<BaseItem?>,
|
||||||
onClickItem: (Int, BaseItem) -> Unit,
|
onClickItem: (Int, BaseItem) -> Unit,
|
||||||
onLongClickItem: (Int, BaseItem) -> Unit,
|
onLongClickItem: (Int, BaseItem) -> Unit,
|
||||||
|
onClickPlay: (Int, BaseItem) -> Unit,
|
||||||
letterPosition: suspend (Char) -> Int,
|
letterPosition: suspend (Char) -> Int,
|
||||||
gridFocusRequester: FocusRequester,
|
gridFocusRequester: FocusRequester,
|
||||||
showJumpButtons: Boolean,
|
showJumpButtons: Boolean,
|
||||||
|
|
@ -213,7 +215,11 @@ fun CardGrid(
|
||||||
jumpToTop()
|
jumpToTop()
|
||||||
return@onKeyEvent true
|
return@onKeyEvent true
|
||||||
} else if (isPlayKeyUp(it)) {
|
} else if (isPlayKeyUp(it)) {
|
||||||
// TODO play the focused item
|
val item = pager.getOrNull(focusedIndex)
|
||||||
|
if (item?.type?.playable == true) {
|
||||||
|
Timber.v("Clicked play on ${item.id}")
|
||||||
|
onClickPlay.invoke(focusedIndex, item)
|
||||||
|
}
|
||||||
return@onKeyEvent true
|
return@onKeyEvent true
|
||||||
} else if (useJumpRemoteButtons && isForwardButton(it)) {
|
} else if (useJumpRemoteButtons && isForwardButton(it)) {
|
||||||
jump(jump1)
|
jump(jump1)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.focus.focusRestorer
|
import androidx.compose.ui.focus.focusRestorer
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.input.key.onKeyEvent
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
|
@ -67,12 +68,16 @@ import com.github.damontecres.wholphin.ui.detail.PlaylistLoadingState
|
||||||
import com.github.damontecres.wholphin.ui.detail.buildMoreDialogItemsForHome
|
import com.github.damontecres.wholphin.ui.detail.buildMoreDialogItemsForHome
|
||||||
import com.github.damontecres.wholphin.ui.ifElse
|
import com.github.damontecres.wholphin.ui.ifElse
|
||||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||||
|
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||||
|
import com.github.damontecres.wholphin.ui.playback.isPlayKeyUp
|
||||||
|
import com.github.damontecres.wholphin.ui.playback.playable
|
||||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
import org.jellyfin.sdk.model.api.MediaType
|
import org.jellyfin.sdk.model.api.MediaType
|
||||||
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -157,6 +162,9 @@ fun HomePage(
|
||||||
items = dialogItems,
|
items = dialogItems,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
onClickPlay = { _, item ->
|
||||||
|
viewModel.navigationManager.navigateTo(Destination.Playback(item))
|
||||||
|
},
|
||||||
loadingState = refreshing,
|
loadingState = refreshing,
|
||||||
showClock = preferences.appPreferences.interfacePreferences.showClock,
|
showClock = preferences.appPreferences.interfacePreferences.showClock,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
@ -193,6 +201,7 @@ fun HomePageContent(
|
||||||
homeRows: List<HomeRowLoadingState>,
|
homeRows: List<HomeRowLoadingState>,
|
||||||
onClickItem: (RowColumn, BaseItem) -> Unit,
|
onClickItem: (RowColumn, BaseItem) -> Unit,
|
||||||
onLongClickItem: (RowColumn, BaseItem) -> Unit,
|
onLongClickItem: (RowColumn, BaseItem) -> Unit,
|
||||||
|
onClickPlay: (RowColumn, BaseItem) -> Unit,
|
||||||
showClock: Boolean,
|
showClock: Boolean,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onFocusPosition: ((RowColumn) -> Unit)? = null,
|
onFocusPosition: ((RowColumn) -> Unit)? = null,
|
||||||
|
|
@ -264,7 +273,18 @@ fun HomePageContent(
|
||||||
top = 0.dp,
|
top = 0.dp,
|
||||||
bottom = Cards.height2x3,
|
bottom = Cards.height2x3,
|
||||||
),
|
),
|
||||||
modifier = Modifier.focusRestorer(),
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.focusRestorer()
|
||||||
|
.onKeyEvent {
|
||||||
|
val item = focusedItem
|
||||||
|
if (isPlayKeyUp(it) && item?.type?.playable == true) {
|
||||||
|
Timber.v("Clicked play on ${item.id}")
|
||||||
|
onClickPlay.invoke(position, item)
|
||||||
|
return@onKeyEvent true
|
||||||
|
}
|
||||||
|
return@onKeyEvent false
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
itemsIndexed(homeRows) { rowIndex, row ->
|
itemsIndexed(homeRows) { rowIndex, row ->
|
||||||
when (val r = row) {
|
when (val r = row) {
|
||||||
|
|
|
||||||
|
|
@ -225,9 +225,13 @@ class PlaybackViewModel
|
||||||
"Error preparing for playback for $itemId",
|
"Error preparing for playback for $itemId",
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
|
val destItem = (destination as? Destination.Playback)?.item?.data
|
||||||
val queriedItem =
|
val queriedItem =
|
||||||
(destination as? Destination.Playback)?.item?.data
|
if (destItem?.mediaSources != null) {
|
||||||
?: api.userLibraryApi.getItem(itemId).content
|
destItem
|
||||||
|
} else {
|
||||||
|
api.userLibraryApi.getItem(itemId).content
|
||||||
|
}
|
||||||
val base =
|
val base =
|
||||||
if (queriedItem.type.playable) {
|
if (queriedItem.type.playable) {
|
||||||
queriedItem
|
queriedItem
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue