mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Fixes a few discover page UI bugs (#710)
## Description - Fixes when to show/hide Request & Cancel buttons - Removes the More button - Uses a larger 16x9 backdrop so that the fade is better - Fix reloading the backdrop on series pages ### Related issues Fixes #706
This commit is contained in:
parent
ccd8c80d5e
commit
03b332e4c4
9 changed files with 73 additions and 47 deletions
|
|
@ -91,7 +91,7 @@ data class DiscoverItem(
|
|||
override val playable: Boolean = false
|
||||
override val sortName: String get() = title ?: ""
|
||||
|
||||
val backDropUrl: String? get() = backdropPath?.let { "https://image.tmdb.org/t/p/w1920_and_h800_multi_faces$it" }
|
||||
val backDropUrl: String? get() = backdropPath?.let { "https://image.tmdb.org/t/p/w1920_and_h1080_multi_faces$it" }
|
||||
val posterUrl: String? get() = posterPath?.let { "https://image.tmdb.org/t/p/w500$it" }
|
||||
|
||||
val destination: Destination
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ fun DiscoverMovieDetails(
|
|||
val loading by viewModel.loading.observeAsState(LoadingState.Loading)
|
||||
val userConfig by viewModel.userConfig.collectAsState(null)
|
||||
val request4kEnabled by viewModel.request4kEnabled.collectAsState(false)
|
||||
val canCancel by viewModel.canCancelRequest.collectAsState()
|
||||
|
||||
var overviewDialog by remember { mutableStateOf<ItemDetailsDialogInfo?>(null) }
|
||||
var moreDialog by remember { mutableStateOf<DialogParams?>(null) }
|
||||
|
|
@ -127,6 +128,7 @@ fun DiscoverMovieDetails(
|
|||
movie = movie,
|
||||
userConfig = userConfig,
|
||||
rating = rating,
|
||||
canCancel = canCancel,
|
||||
people = people,
|
||||
trailers = trailers,
|
||||
similar = similar,
|
||||
|
|
@ -234,6 +236,7 @@ fun DiscoverMovieDetailsContent(
|
|||
userConfig: SeerrUserConfig?,
|
||||
movie: MovieDetails,
|
||||
rating: DiscoverRating?,
|
||||
canCancel: Boolean,
|
||||
people: List<DiscoverItem>,
|
||||
trailers: List<Trailer>,
|
||||
similar: List<DiscoverItem>,
|
||||
|
|
@ -284,15 +287,6 @@ fun DiscoverMovieDetailsContent(
|
|||
.fillMaxWidth()
|
||||
.padding(top = 32.dp, bottom = 16.dp),
|
||||
)
|
||||
val canCancel =
|
||||
remember(movie, userConfig) {
|
||||
(
|
||||
// User requested this
|
||||
userConfig.hasPermission(SeerrPermission.REQUEST) &&
|
||||
movie.mediaInfo?.requests?.any { it.requestedBy?.id == userConfig?.id } == true
|
||||
) ||
|
||||
userConfig.hasPermission(SeerrPermission.MANAGE_REQUESTS)
|
||||
}
|
||||
ExpandableDiscoverButtons(
|
||||
availability =
|
||||
SeerrAvailability.from(movie.mediaInfo?.status)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.github.damontecres.wholphin.api.seerr.model.MediaRequest
|
||||
import com.github.damontecres.wholphin.api.seerr.model.MovieDetails
|
||||
import com.github.damontecres.wholphin.api.seerr.model.RelatedVideo
|
||||
import com.github.damontecres.wholphin.api.seerr.model.RequestPostRequest
|
||||
|
|
@ -11,11 +12,14 @@ import com.github.damontecres.wholphin.data.ServerRepository
|
|||
import com.github.damontecres.wholphin.data.model.DiscoverItem
|
||||
import com.github.damontecres.wholphin.data.model.DiscoverRating
|
||||
import com.github.damontecres.wholphin.data.model.RemoteTrailer
|
||||
import com.github.damontecres.wholphin.data.model.SeerrPermission
|
||||
import com.github.damontecres.wholphin.data.model.Trailer
|
||||
import com.github.damontecres.wholphin.data.model.hasPermission
|
||||
import com.github.damontecres.wholphin.services.BackdropService
|
||||
import com.github.damontecres.wholphin.services.NavigationManager
|
||||
import com.github.damontecres.wholphin.services.SeerrServerRepository
|
||||
import com.github.damontecres.wholphin.services.SeerrService
|
||||
import com.github.damontecres.wholphin.services.SeerrUserConfig
|
||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
|
|
@ -31,7 +35,10 @@ import kotlinx.coroutines.Deferred
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
|
|
@ -62,6 +69,7 @@ class DiscoverMovieViewModel
|
|||
val people = MutableLiveData<List<DiscoverItem>>(listOf())
|
||||
val similar = MutableLiveData<List<DiscoverItem>>(listOf())
|
||||
val recommended = MutableLiveData<List<DiscoverItem>>(listOf())
|
||||
val canCancelRequest = MutableStateFlow(false)
|
||||
|
||||
val userConfig = seerrServerRepository.current.map { it?.config }
|
||||
val request4kEnabled = seerrServerRepository.current.map { it?.request4kMovieEnabled ?: false }
|
||||
|
|
@ -95,6 +103,8 @@ class DiscoverMovieViewModel
|
|||
val discoveredItem = DiscoverItem(movie)
|
||||
backdropService.submit(discoveredItem)
|
||||
|
||||
updateCanCancel()
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
loading.value = LoadingState.Success
|
||||
}
|
||||
|
|
@ -142,6 +152,12 @@ class DiscoverMovieViewModel
|
|||
this@DiscoverMovieViewModel.trailers.setValueOnMain(trailers)
|
||||
}
|
||||
|
||||
private suspend fun updateCanCancel() {
|
||||
val user = userConfig.firstOrNull()
|
||||
val canCancel = canUserCancelRequest(user, movie.value?.mediaInfo?.requests)
|
||||
canCancelRequest.update { canCancel }
|
||||
}
|
||||
|
||||
fun navigateTo(destination: Destination) {
|
||||
navigationManager.navigateTo(destination)
|
||||
}
|
||||
|
|
@ -160,6 +176,7 @@ class DiscoverMovieViewModel
|
|||
),
|
||||
)
|
||||
fetchAndSetItem().await()
|
||||
updateCanCancel()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +186,18 @@ class DiscoverMovieViewModel
|
|||
// TODO handle multiple requests? Or just delete self's request?
|
||||
seerrService.api.requestApi.requestRequestIdDelete(it.id.toString())
|
||||
fetchAndSetItem().await()
|
||||
updateCanCancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun canUserCancelRequest(
|
||||
user: SeerrUserConfig?,
|
||||
requests: List<MediaRequest>?,
|
||||
) = user.hasPermission(SeerrPermission.MANAGE_REQUESTS) ||
|
||||
(
|
||||
// User requested this
|
||||
user.hasPermission(SeerrPermission.REQUEST) &&
|
||||
requests?.any { it.requestedBy?.id == user?.id } == true
|
||||
)
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ fun DiscoverSeriesDetails(
|
|||
val recommended by viewModel.recommended.observeAsState(listOf())
|
||||
val userConfig by viewModel.userConfig.collectAsState(null)
|
||||
val request4kEnabled by viewModel.request4kEnabled.collectAsState(false)
|
||||
val canCancel by viewModel.canCancelRequest.collectAsState()
|
||||
|
||||
var overviewDialog by remember { mutableStateOf<ItemDetailsDialogInfo?>(null) }
|
||||
var seasonDialog by remember { mutableStateOf<DialogParams?>(null) }
|
||||
|
|
@ -120,6 +121,7 @@ fun DiscoverSeriesDetails(
|
|||
series = item,
|
||||
userConfig = userConfig,
|
||||
rating = rating,
|
||||
canCancel = canCancel,
|
||||
seasons = seasons,
|
||||
people = people,
|
||||
similar = similar,
|
||||
|
|
@ -230,6 +232,7 @@ fun DiscoverSeriesDetailsContent(
|
|||
userConfig: SeerrUserConfig?,
|
||||
series: TvDetails,
|
||||
rating: DiscoverRating?,
|
||||
canCancel: Boolean,
|
||||
seasons: List<Season>,
|
||||
similar: List<DiscoverItem>,
|
||||
recommended: List<DiscoverItem>,
|
||||
|
|
@ -290,15 +293,6 @@ fun DiscoverSeriesDetailsContent(
|
|||
.fillMaxWidth()
|
||||
.padding(top = 32.dp, bottom = 16.dp),
|
||||
)
|
||||
val canCancel =
|
||||
remember(series, userConfig) {
|
||||
(
|
||||
// User requested this
|
||||
userConfig.hasPermission(SeerrPermission.REQUEST) &&
|
||||
series.mediaInfo?.requests?.any { it.requestedBy?.id == userConfig?.id } == true
|
||||
) ||
|
||||
userConfig.hasPermission(SeerrPermission.MANAGE_REQUESTS)
|
||||
}
|
||||
ExpandableDiscoverButtons(
|
||||
availability =
|
||||
SeerrAvailability.from(series.mediaInfo?.status)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,10 @@ import kotlinx.coroutines.Deferred
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
|
|
@ -61,6 +64,7 @@ class DiscoverSeriesViewModel
|
|||
val people = MutableLiveData<List<DiscoverItem>>(listOf())
|
||||
val similar = MutableLiveData<List<DiscoverItem>>(listOf())
|
||||
val recommended = MutableLiveData<List<DiscoverItem>>(listOf())
|
||||
val canCancelRequest = MutableStateFlow(false)
|
||||
|
||||
val userConfig = seerrServerRepository.current.map { it?.config }
|
||||
val request4kEnabled = seerrServerRepository.current.map { it?.request4kMovieEnabled ?: false }
|
||||
|
|
@ -94,6 +98,8 @@ class DiscoverSeriesViewModel
|
|||
val discoveredItem = DiscoverItem(tv)
|
||||
backdropService.submit(discoveredItem)
|
||||
|
||||
updateCanCancel()
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
loading.value = LoadingState.Success
|
||||
}
|
||||
|
|
@ -137,6 +143,12 @@ class DiscoverSeriesViewModel
|
|||
navigationManager.navigateTo(destination)
|
||||
}
|
||||
|
||||
private suspend fun updateCanCancel() {
|
||||
val user = userConfig.firstOrNull()
|
||||
val canCancel = canUserCancelRequest(user, tvSeries.value?.mediaInfo?.requests)
|
||||
canCancelRequest.update { canCancel }
|
||||
}
|
||||
|
||||
fun request(
|
||||
id: Int,
|
||||
is4k: Boolean,
|
||||
|
|
@ -152,6 +164,7 @@ class DiscoverSeriesViewModel
|
|||
),
|
||||
)
|
||||
fetchAndSetItem().await()
|
||||
updateCanCancel()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -161,6 +174,7 @@ class DiscoverSeriesViewModel
|
|||
// TODO handle multiple requests? Or just delete self's request?
|
||||
seerrService.api.requestApi.requestRequestIdDelete(it.id.toString())
|
||||
fetchAndSetItem().await()
|
||||
updateCanCancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.PaddingValues
|
|||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -140,15 +139,16 @@ fun ExpandableDiscoverButtons(
|
|||
}
|
||||
|
||||
// More button
|
||||
item("more") {
|
||||
ExpandablePlayButton(
|
||||
R.string.more,
|
||||
Duration.ZERO,
|
||||
Icons.Default.MoreVert,
|
||||
{ moreOnClick.invoke() },
|
||||
Modifier
|
||||
.onFocusChanged(buttonOnFocusChanged),
|
||||
)
|
||||
}
|
||||
// No functionality yet
|
||||
// item("more") {
|
||||
// ExpandablePlayButton(
|
||||
// R.string.more,
|
||||
// Duration.ZERO,
|
||||
// Icons.Default.MoreVert,
|
||||
// { moreOnClick.invoke() },
|
||||
// Modifier
|
||||
// .onFocusChanged(buttonOnFocusChanged),
|
||||
// )
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,10 +131,8 @@ fun SeriesDetails(
|
|||
LoadingState.Success -> {
|
||||
item?.let { item ->
|
||||
LifecycleResumeEffect(destination.itemId) {
|
||||
viewModel.maybePlayThemeSong(
|
||||
destination.itemId,
|
||||
preferences.appPreferences.interfacePreferences.playThemeSongs,
|
||||
)
|
||||
viewModel.onResumePage()
|
||||
|
||||
onPauseOrDispose {
|
||||
viewModel.release()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,10 +170,8 @@ fun SeriesOverview(
|
|||
"series_overview",
|
||||
)
|
||||
LifecycleResumeEffect(destination.itemId) {
|
||||
viewModel.maybePlayThemeSong(
|
||||
destination.itemId,
|
||||
preferences.appPreferences.interfacePreferences.playThemeSongs,
|
||||
)
|
||||
viewModel.onResumePage()
|
||||
|
||||
onPauseOrDispose {
|
||||
viewModel.release()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import com.github.damontecres.wholphin.data.model.DiscoverItem
|
|||
import com.github.damontecres.wholphin.data.model.ItemPlayback
|
||||
import com.github.damontecres.wholphin.data.model.Person
|
||||
import com.github.damontecres.wholphin.data.model.Trailer
|
||||
import com.github.damontecres.wholphin.preferences.ThemeSongVolume
|
||||
import com.github.damontecres.wholphin.services.BackdropService
|
||||
import com.github.damontecres.wholphin.services.ExtrasService
|
||||
import com.github.damontecres.wholphin.services.FavoriteWatchManager
|
||||
|
|
@ -222,15 +221,16 @@ class SeriesViewModel
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the series has a theme song & app settings allow, play it
|
||||
*/
|
||||
fun maybePlayThemeSong(
|
||||
seriesId: UUID,
|
||||
playThemeSongs: ThemeSongVolume,
|
||||
) {
|
||||
fun onResumePage() {
|
||||
viewModelScope.launchIO {
|
||||
themeSongPlayer.playThemeFor(seriesId, playThemeSongs)
|
||||
item.value?.let {
|
||||
backdropService.submit(it)
|
||||
val playThemeSongs =
|
||||
userPreferencesService
|
||||
.getCurrent()
|
||||
.appPreferences.interfacePreferences.playThemeSongs
|
||||
themeSongPlayer.playThemeFor(seriesId, playThemeSongs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue