mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Additional rows for albums & artists
This commit is contained in:
parent
5a4528541a
commit
dfed290125
4 changed files with 230 additions and 15 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
package com.github.damontecres.wholphin.ui.detail.music
|
package com.github.damontecres.wholphin.ui.detail.music
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -10,12 +11,14 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
import androidx.compose.foundation.relocation.BringIntoViewRequester
|
||||||
import androidx.compose.foundation.relocation.bringIntoViewRequester
|
import androidx.compose.foundation.relocation.bringIntoViewRequester
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
|
@ -50,6 +53,11 @@ import com.github.damontecres.wholphin.services.MediaReportService
|
||||||
import com.github.damontecres.wholphin.services.MusicService
|
import com.github.damontecres.wholphin.services.MusicService
|
||||||
import com.github.damontecres.wholphin.services.NavigationManager
|
import com.github.damontecres.wholphin.services.NavigationManager
|
||||||
import com.github.damontecres.wholphin.services.UserPreferencesService
|
import com.github.damontecres.wholphin.services.UserPreferencesService
|
||||||
|
import com.github.damontecres.wholphin.ui.AspectRatios
|
||||||
|
import com.github.damontecres.wholphin.ui.DefaultItemFields
|
||||||
|
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||||
|
import com.github.damontecres.wholphin.ui.cards.BannerCardWithTitle
|
||||||
|
import com.github.damontecres.wholphin.ui.cards.ItemRow
|
||||||
import com.github.damontecres.wholphin.ui.components.DialogParams
|
import com.github.damontecres.wholphin.ui.components.DialogParams
|
||||||
import com.github.damontecres.wholphin.ui.components.DialogPopup
|
import com.github.damontecres.wholphin.ui.components.DialogPopup
|
||||||
import com.github.damontecres.wholphin.ui.components.ErrorMessage
|
import com.github.damontecres.wholphin.ui.components.ErrorMessage
|
||||||
|
|
@ -61,10 +69,14 @@ import com.github.damontecres.wholphin.ui.components.QuickDetails
|
||||||
import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel
|
import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel
|
||||||
import com.github.damontecres.wholphin.ui.detail.PlaylistDialog
|
import com.github.damontecres.wholphin.ui.detail.PlaylistDialog
|
||||||
import com.github.damontecres.wholphin.ui.detail.PlaylistLoadingState
|
import com.github.damontecres.wholphin.ui.detail.PlaylistLoadingState
|
||||||
|
import com.github.damontecres.wholphin.ui.ifElse
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.letNotEmpty
|
import com.github.damontecres.wholphin.ui.letNotEmpty
|
||||||
|
import com.github.damontecres.wholphin.ui.toBaseItems
|
||||||
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.util.ApiRequestPager
|
import com.github.damontecres.wholphin.util.ApiRequestPager
|
||||||
import com.github.damontecres.wholphin.util.ExceptionHandler
|
import com.github.damontecres.wholphin.util.ExceptionHandler
|
||||||
|
import com.github.damontecres.wholphin.util.GetItemsRequestHandler
|
||||||
import com.github.damontecres.wholphin.util.LoadingState
|
import com.github.damontecres.wholphin.util.LoadingState
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
|
|
@ -79,9 +91,13 @@ import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jellyfin.sdk.api.client.ApiClient
|
import org.jellyfin.sdk.api.client.ApiClient
|
||||||
import org.jellyfin.sdk.api.client.extensions.itemsApi
|
import org.jellyfin.sdk.api.client.extensions.itemsApi
|
||||||
|
import org.jellyfin.sdk.api.client.extensions.libraryApi
|
||||||
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
||||||
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
import org.jellyfin.sdk.model.api.ImageType
|
import org.jellyfin.sdk.model.api.ImageType
|
||||||
import org.jellyfin.sdk.model.api.MediaType
|
import org.jellyfin.sdk.model.api.MediaType
|
||||||
|
import org.jellyfin.sdk.model.api.request.GetItemsRequest
|
||||||
|
import org.jellyfin.sdk.model.api.request.GetSimilarItemsRequest
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@HiltViewModel(assistedFactory = AlbumViewModel.Factory::class)
|
@HiltViewModel(assistedFactory = AlbumViewModel.Factory::class)
|
||||||
|
|
@ -135,7 +151,7 @@ class AlbumViewModel
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
.size > 1
|
.size > 1
|
||||||
_state.update {
|
_state.update {
|
||||||
AlbumState(
|
it.copy(
|
||||||
album = album,
|
album = album,
|
||||||
isVariousArtists = isVariousArtists,
|
isVariousArtists = isVariousArtists,
|
||||||
imageUrl = imageUrl,
|
imageUrl = imageUrl,
|
||||||
|
|
@ -159,6 +175,41 @@ class AlbumViewModel
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
?.let { backdropService.submit(BaseItem(it, false)) }
|
?.let { backdropService.submit(BaseItem(it, false)) }
|
||||||
}
|
}
|
||||||
|
if (state.value.similar.isEmpty()) {
|
||||||
|
viewModelScope.launchIO {
|
||||||
|
val similar =
|
||||||
|
api.libraryApi
|
||||||
|
.getSimilarItems(
|
||||||
|
GetSimilarItemsRequest(
|
||||||
|
userId = serverRepository.currentUser.value?.id,
|
||||||
|
itemId = itemId,
|
||||||
|
excludeArtistIds = album.data.albumArtists?.map { it.id },
|
||||||
|
fields = SlimItemFields,
|
||||||
|
limit = 25,
|
||||||
|
),
|
||||||
|
).content.items
|
||||||
|
.map { BaseItem.from(it, api) }
|
||||||
|
_state.update { it.copy(similar = similar) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModelScope.launchIO {
|
||||||
|
val request =
|
||||||
|
GetItemsRequest(
|
||||||
|
userId = serverRepository.currentUser.value?.id,
|
||||||
|
albumIds = listOf(itemId),
|
||||||
|
parentId = null,
|
||||||
|
fields = DefaultItemFields,
|
||||||
|
recursive = true,
|
||||||
|
includeItemTypes = listOf(BaseItemKind.MUSIC_VIDEO),
|
||||||
|
)
|
||||||
|
val musicVideos =
|
||||||
|
GetItemsRequestHandler.execute(api, request).toBaseItems(api, false)
|
||||||
|
if (musicVideos.isNotEmpty()) {
|
||||||
|
_state.update {
|
||||||
|
it.copy(musicVideos = musicVideos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
_state.update { it.copy(loading = LoadingState.Error(ex)) }
|
_state.update { it.copy(loading = LoadingState.Error(ex)) }
|
||||||
}
|
}
|
||||||
|
|
@ -192,10 +243,12 @@ data class AlbumState(
|
||||||
val isVariousArtists: Boolean,
|
val isVariousArtists: Boolean,
|
||||||
val imageUrl: String?,
|
val imageUrl: String?,
|
||||||
val songs: List<BaseItem?>,
|
val songs: List<BaseItem?>,
|
||||||
|
val similar: List<BaseItem>,
|
||||||
val loading: LoadingState,
|
val loading: LoadingState,
|
||||||
|
val musicVideos: List<BaseItem?> = emptyList(),
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val EMPTY = AlbumState(null, false, null, emptyList(), LoadingState.Pending)
|
val EMPTY = AlbumState(null, false, null, emptyList(), emptyList(), LoadingState.Pending)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,10 +299,27 @@ fun AlbumDetailsPage(
|
||||||
LoadingState.Success -> {
|
LoadingState.Success -> {
|
||||||
val album = state.album!!
|
val album = state.album!!
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
val firstFocusRequester = remember { FocusRequester() }
|
||||||
|
val firstBringIntoViewRequester = remember { BringIntoViewRequester() }
|
||||||
LaunchedEffect(Unit) { focusRequester.requestFocus() }
|
LaunchedEffect(Unit) { focusRequester.requestFocus() }
|
||||||
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
val bringIntoViewRequester = remember { BringIntoViewRequester() }
|
||||||
|
val listState = rememberLazyListState()
|
||||||
|
val itemsBefore = 2
|
||||||
|
val backHandlerActive by remember {
|
||||||
|
derivedStateOf {
|
||||||
|
listState.firstVisibleItemIndex > itemsBefore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BackHandler(backHandlerActive) {
|
||||||
|
scope.launch {
|
||||||
|
listState.animateScrollToItem(itemsBefore)
|
||||||
|
firstBringIntoViewRequester.bringIntoView()
|
||||||
|
firstFocusRequester.tryRequestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
Box(modifier = modifier) {
|
Box(modifier = modifier) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
state = listState,
|
||||||
verticalArrangement = Arrangement.spacedBy(0.dp),
|
verticalArrangement = Arrangement.spacedBy(0.dp),
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
) {
|
) {
|
||||||
|
|
@ -344,7 +414,63 @@ fun AlbumDetailsPage(
|
||||||
Modifier
|
Modifier
|
||||||
// .padding(horizontal = 16.dp)
|
// .padding(horizontal = 16.dp)
|
||||||
.fillMaxWidth(.75f)
|
.fillMaxWidth(.75f)
|
||||||
.align(Alignment.Center),
|
.align(Alignment.Center)
|
||||||
|
.ifElse(
|
||||||
|
index == 0,
|
||||||
|
Modifier
|
||||||
|
.focusRequester(firstFocusRequester)
|
||||||
|
.bringIntoViewRequester(firstBringIntoViewRequester),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.musicVideos.isNotEmpty()) {
|
||||||
|
item {
|
||||||
|
ItemRow(
|
||||||
|
title = stringResource(R.string.music_videos),
|
||||||
|
items = state.musicVideos,
|
||||||
|
onClickItem = { index, item ->
|
||||||
|
viewModel.navigationManager.navigateTo(item.destination())
|
||||||
|
},
|
||||||
|
onLongClickItem = { index, item ->
|
||||||
|
// TODO
|
||||||
|
},
|
||||||
|
cardContent = { index: Int, item: BaseItem?, mod: Modifier, onClick: () -> Unit, onLongClick: () -> Unit ->
|
||||||
|
BannerCardWithTitle(
|
||||||
|
title = item?.name,
|
||||||
|
subtitle = item?.data?.productionYear?.toString(),
|
||||||
|
item = item,
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
aspectRatio = AspectRatios.WIDE,
|
||||||
|
modifier = mod,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.similar.isNotEmpty()) {
|
||||||
|
item {
|
||||||
|
ItemRow(
|
||||||
|
title = stringResource(R.string.more_like_this),
|
||||||
|
items = state.similar,
|
||||||
|
onClickItem = { index, item ->
|
||||||
|
viewModel.navigationManager.navigateTo(item.destination())
|
||||||
|
},
|
||||||
|
onLongClickItem = { index, item ->
|
||||||
|
// TODO
|
||||||
|
},
|
||||||
|
cardContent = { index: Int, item: BaseItem?, mod: Modifier, onClick: () -> Unit, onLongClick: () -> Unit ->
|
||||||
|
BannerCardWithTitle(
|
||||||
|
title = item?.name,
|
||||||
|
subtitle = item?.data?.productionYear?.toString(),
|
||||||
|
item = item,
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
aspectRatio = AspectRatios.SQUARE,
|
||||||
|
modifier = mod,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ import com.github.damontecres.wholphin.services.NavigationManager
|
||||||
import com.github.damontecres.wholphin.services.UserPreferencesService
|
import com.github.damontecres.wholphin.services.UserPreferencesService
|
||||||
import com.github.damontecres.wholphin.ui.AspectRatios
|
import com.github.damontecres.wholphin.ui.AspectRatios
|
||||||
import com.github.damontecres.wholphin.ui.DefaultItemFields
|
import com.github.damontecres.wholphin.ui.DefaultItemFields
|
||||||
|
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||||
import com.github.damontecres.wholphin.ui.cards.BannerCardWithTitle
|
import com.github.damontecres.wholphin.ui.cards.BannerCardWithTitle
|
||||||
import com.github.damontecres.wholphin.ui.cards.ItemRow
|
import com.github.damontecres.wholphin.ui.cards.ItemRow
|
||||||
import com.github.damontecres.wholphin.ui.components.DialogParams
|
import com.github.damontecres.wholphin.ui.components.DialogParams
|
||||||
|
|
@ -85,6 +86,7 @@ import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jellyfin.sdk.api.client.ApiClient
|
import org.jellyfin.sdk.api.client.ApiClient
|
||||||
|
import org.jellyfin.sdk.api.client.extensions.libraryApi
|
||||||
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
|
||||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
import org.jellyfin.sdk.model.api.ImageType
|
import org.jellyfin.sdk.model.api.ImageType
|
||||||
|
|
@ -92,6 +94,7 @@ import org.jellyfin.sdk.model.api.ItemSortBy
|
||||||
import org.jellyfin.sdk.model.api.MediaType
|
import org.jellyfin.sdk.model.api.MediaType
|
||||||
import org.jellyfin.sdk.model.api.SortOrder
|
import org.jellyfin.sdk.model.api.SortOrder
|
||||||
import org.jellyfin.sdk.model.api.request.GetItemsRequest
|
import org.jellyfin.sdk.model.api.request.GetItemsRequest
|
||||||
|
import org.jellyfin.sdk.model.api.request.GetSimilarItemsRequest
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@HiltViewModel(assistedFactory = ArtistViewModel.Factory::class)
|
@HiltViewModel(assistedFactory = ArtistViewModel.Factory::class)
|
||||||
|
|
@ -181,6 +184,41 @@ class ArtistViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (state.value.similar.isEmpty()) {
|
||||||
|
viewModelScope.launchIO {
|
||||||
|
val similar =
|
||||||
|
api.libraryApi
|
||||||
|
.getSimilarItems(
|
||||||
|
GetSimilarItemsRequest(
|
||||||
|
userId = serverRepository.currentUser.value?.id,
|
||||||
|
itemId = itemId,
|
||||||
|
excludeArtistIds = listOf(itemId),
|
||||||
|
fields = SlimItemFields,
|
||||||
|
limit = 25,
|
||||||
|
),
|
||||||
|
).content.items
|
||||||
|
.map { BaseItem.from(it, api) }
|
||||||
|
_state.update { it.copy(similar = similar) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModelScope.launchIO {
|
||||||
|
val request =
|
||||||
|
GetItemsRequest(
|
||||||
|
userId = serverRepository.currentUser.value?.id,
|
||||||
|
artistIds = listOf(itemId),
|
||||||
|
parentId = null,
|
||||||
|
fields = DefaultItemFields,
|
||||||
|
recursive = true,
|
||||||
|
includeItemTypes = listOf(BaseItemKind.MUSIC_VIDEO),
|
||||||
|
)
|
||||||
|
val musicVideos =
|
||||||
|
GetItemsRequestHandler.execute(api, request).toBaseItems(api, false)
|
||||||
|
if (musicVideos.isNotEmpty()) {
|
||||||
|
_state.update {
|
||||||
|
it.copy(musicVideos = musicVideos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
_state.update { it.copy(loading = LoadingState.Error(ex)) }
|
_state.update { it.copy(loading = LoadingState.Error(ex)) }
|
||||||
}
|
}
|
||||||
|
|
@ -214,11 +252,21 @@ data class ArtistState(
|
||||||
val imageUrl: String?,
|
val imageUrl: String?,
|
||||||
val topSongs: List<BaseItem?>,
|
val topSongs: List<BaseItem?>,
|
||||||
val albums: List<BaseItem?>,
|
val albums: List<BaseItem?>,
|
||||||
val similar: List<BaseItem?>,
|
val similar: List<BaseItem>,
|
||||||
val loading: LoadingState,
|
val loading: LoadingState,
|
||||||
|
val musicVideos: List<BaseItem?>,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val EMPTY = ArtistState(null, null, emptyList(), emptyList(), emptyList(), LoadingState.Pending)
|
val EMPTY =
|
||||||
|
ArtistState(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
emptyList(),
|
||||||
|
emptyList(),
|
||||||
|
emptyList(),
|
||||||
|
LoadingState.Pending,
|
||||||
|
emptyList(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -392,6 +440,56 @@ fun ArtistDetailsPage(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (state.musicVideos.isNotEmpty()) {
|
||||||
|
item {
|
||||||
|
ItemRow(
|
||||||
|
title = stringResource(R.string.music_videos),
|
||||||
|
items = state.musicVideos,
|
||||||
|
onClickItem = { index, item ->
|
||||||
|
viewModel.navigationManager.navigateTo(item.destination())
|
||||||
|
},
|
||||||
|
onLongClickItem = { index, item ->
|
||||||
|
// TODO
|
||||||
|
},
|
||||||
|
cardContent = { index: Int, item: BaseItem?, mod: Modifier, onClick: () -> Unit, onLongClick: () -> Unit ->
|
||||||
|
BannerCardWithTitle(
|
||||||
|
title = item?.name,
|
||||||
|
subtitle = item?.data?.productionYear?.toString(),
|
||||||
|
item = item,
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
aspectRatio = AspectRatios.WIDE,
|
||||||
|
modifier = mod,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.similar.isNotEmpty()) {
|
||||||
|
item {
|
||||||
|
ItemRow(
|
||||||
|
title = stringResource(R.string.more_like_this),
|
||||||
|
items = state.similar,
|
||||||
|
onClickItem = { index, item ->
|
||||||
|
viewModel.navigationManager.navigateTo(item.destination())
|
||||||
|
},
|
||||||
|
onLongClickItem = { index, item ->
|
||||||
|
// TODO
|
||||||
|
},
|
||||||
|
cardContent = { index: Int, item: BaseItem?, mod: Modifier, onClick: () -> Unit, onLongClick: () -> Unit ->
|
||||||
|
BannerCardWithTitle(
|
||||||
|
title = item?.name,
|
||||||
|
subtitle = item?.data?.productionYear?.toString(),
|
||||||
|
item = item,
|
||||||
|
onClick = onClick,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
aspectRatio = AspectRatios.SQUARE,
|
||||||
|
modifier = mod,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,6 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.media3.common.Player
|
import androidx.media3.common.Player
|
||||||
import androidx.media3.common.util.UnstableApi
|
import androidx.media3.common.util.UnstableApi
|
||||||
import androidx.media3.ui.compose.state.rememberNextButtonState
|
|
||||||
import androidx.media3.ui.compose.state.rememberPlayPauseButtonState
|
|
||||||
import androidx.media3.ui.compose.state.rememberPreviousButtonState
|
|
||||||
import androidx.media3.ui.compose.state.rememberRepeatButtonState
|
|
||||||
import androidx.media3.ui.compose.state.rememberShuffleButtonState
|
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
|
|
@ -70,11 +65,6 @@ fun NowPlayingOverlay(
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
LaunchedEffect(Unit) { focusRequester.tryRequestFocus() }
|
LaunchedEffect(Unit) { focusRequester.tryRequestFocus() }
|
||||||
val playPauseState = rememberPlayPauseButtonState(player)
|
|
||||||
val previousState = rememberPreviousButtonState(player)
|
|
||||||
val nextState = rememberNextButtonState(player)
|
|
||||||
val shuffleState = rememberShuffleButtonState(player)
|
|
||||||
val repeatState = rememberRepeatButtonState(player)
|
|
||||||
|
|
||||||
var queueHasFocus by remember { mutableStateOf(false) }
|
var queueHasFocus by remember { mutableStateOf(false) }
|
||||||
val height by animateFloatAsState(
|
val height by animateFloatAsState(
|
||||||
|
|
|
||||||
|
|
@ -728,5 +728,6 @@
|
||||||
<string name="album">Album</string>
|
<string name="album">Album</string>
|
||||||
<string name="popular_songs">Popular songs</string>
|
<string name="popular_songs">Popular songs</string>
|
||||||
<string name="play_next">Play next</string>
|
<string name="play_next">Play next</string>
|
||||||
|
<string name="music_videos">Music videos</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue