mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-11-06 18:54:49 +01:00
Fix some bugs on discover pages (#1832)
## Description Fix some bugs on discover pages: - UI fixes for available seasons - Fix toggle not updating when removing a season from a pending request - Don't request images if the path is null - Better error handling when fetching ratings ### Related issues Follow up to #1816 ### Testing Emulator ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
ba52915cf0
commit
2110d846c1
7 changed files with 112 additions and 49 deletions
|
|
@ -184,21 +184,23 @@ class SeerrService
|
|||
)
|
||||
}
|
||||
}
|
||||
val current = seerrServerRepository.current.firstOrNull() ?: return null
|
||||
val cacheImages = current.serverConfig.cacheImages == true
|
||||
val base =
|
||||
if (cacheImages) {
|
||||
current.server.url.removeSuffix("/") + "/imageproxy/tmdb"
|
||||
} else {
|
||||
"https://image.tmdb.org"
|
||||
}
|
||||
val prefix =
|
||||
when (imageType) {
|
||||
ImageType.PRIMARY -> "/t/p/w500"
|
||||
ImageType.BACKDROP -> "/t/p/w${backdropWidth}_and_h${backdropHeight}_multi_faces"
|
||||
else -> throw IllegalArgumentException("Image type not supported: $imageType")
|
||||
}
|
||||
return "${base}${prefix}$path"
|
||||
return path?.takeIf { it.isNotNullOrBlank() }?.let {
|
||||
val current = seerrServerRepository.current.firstOrNull() ?: return null
|
||||
val cacheImages = current.serverConfig.cacheImages == true
|
||||
val base =
|
||||
if (cacheImages) {
|
||||
current.server.url.removeSuffix("/") + "/imageproxy/tmdb"
|
||||
} else {
|
||||
"https://image.tmdb.org"
|
||||
}
|
||||
val prefix =
|
||||
when (imageType) {
|
||||
ImageType.PRIMARY -> "/t/p/w500"
|
||||
ImageType.BACKDROP -> "/t/p/w${backdropWidth}_and_h${backdropHeight}_multi_faces"
|
||||
else -> throw IllegalArgumentException("Image type not supported: $imageType")
|
||||
}
|
||||
return "${base}${prefix}$path"
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getProfilesAndFolders(type: SeerrItemType): SeerrRequestData {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ 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.RequestStatus
|
||||
import com.github.damontecres.wholphin.data.model.SeerrItemType
|
||||
import com.github.damontecres.wholphin.data.model.SeerrPermission
|
||||
import com.github.damontecres.wholphin.data.model.Trailer
|
||||
|
|
@ -20,6 +21,7 @@ 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.equalsNotNull
|
||||
import com.github.damontecres.wholphin.ui.isNotNullOrBlank
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
|
|
@ -100,9 +102,13 @@ class DiscoverMovieViewModel
|
|||
updateCanCancel()
|
||||
|
||||
viewModelScope.launchIO {
|
||||
val result =
|
||||
seerrService.api.moviesApi.movieMovieIdRatingsGet(movieId = item.id)
|
||||
_state.update { it.copy(rating = DiscoverRating(result)) }
|
||||
val rating =
|
||||
getDiscoverRating(item.id) {
|
||||
DiscoverRating(
|
||||
seerrService.api.moviesApi.movieMovieIdRatingsGet(movieId = item.id),
|
||||
)
|
||||
}
|
||||
_state.update { it.copy(rating = rating) }
|
||||
}
|
||||
if (state.value.similar.isEmpty()) {
|
||||
viewModelScope.launchIO {
|
||||
|
|
@ -248,7 +254,12 @@ fun canUserCancelRequest(
|
|||
(
|
||||
// User requested this
|
||||
user.hasPermission(SeerrPermission.REQUEST) &&
|
||||
requests?.any { it.requestedBy?.id == user?.id } == true
|
||||
requests
|
||||
.orEmpty()
|
||||
.any {
|
||||
equalsNotNull(it.requestedBy?.id, user?.id) &&
|
||||
RequestStatus.from(it.status) < RequestStatus.APPROVED
|
||||
}
|
||||
)
|
||||
|
||||
data class DiscoverMovieState(
|
||||
|
|
|
|||
|
|
@ -105,8 +105,11 @@ class DiscoverSeriesViewModel
|
|||
updateCanCancel()
|
||||
|
||||
viewModelScope.launchIO {
|
||||
val result = seerrService.api.tvApi.tvTvIdRatingsGet(tvId = item.id)
|
||||
_state.update { it.copy(rating = DiscoverRating(result)) }
|
||||
val rating =
|
||||
getDiscoverRating(item.id) {
|
||||
DiscoverRating(seerrService.api.tvApi.tvTvIdRatingsGet(tvId = item.id))
|
||||
}
|
||||
_state.update { it.copy(rating = rating) }
|
||||
}
|
||||
if (state.value.similar.isEmpty()) {
|
||||
viewModelScope.launchIO {
|
||||
|
|
@ -183,6 +186,18 @@ class DiscoverSeriesViewModel
|
|||
seasonAvailability[seasonNumber] = availability
|
||||
}
|
||||
}
|
||||
tv.mediaInfo?.seasons?.forEach {
|
||||
it.seasonNumber?.let { seasonNumber ->
|
||||
val status = if (is4k) it.status4k else it.status
|
||||
val availability =
|
||||
SeerrAvailability.from(status) ?: SeerrAvailability.UNKNOWN
|
||||
val current =
|
||||
seasonAvailability.getOrDefault(seasonNumber, SeerrAvailability.UNKNOWN)
|
||||
if (availability > current) {
|
||||
seasonAvailability[seasonNumber] = availability
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tv.mediaInfo
|
||||
?.requests
|
||||
|
|
@ -209,10 +224,6 @@ class DiscoverSeriesViewModel
|
|||
tv.seasons?.firstOrNull { it.seasonNumber == seasonNumber }?.let {
|
||||
val availability =
|
||||
when (status) {
|
||||
RequestStatus.UNKNOWN -> {
|
||||
SeerrAvailability.UNKNOWN
|
||||
}
|
||||
|
||||
RequestStatus.PENDING -> {
|
||||
SeerrAvailability.PENDING
|
||||
}
|
||||
|
|
@ -229,22 +240,39 @@ class DiscoverSeriesViewModel
|
|||
SeerrAvailability.UNKNOWN
|
||||
}
|
||||
|
||||
RequestStatus.COMPLETED -> {
|
||||
RequestStatus.UNKNOWN,
|
||||
RequestStatus.COMPLETED,
|
||||
-> {
|
||||
seasonAvailability.getOrDefault(
|
||||
seasonNumber,
|
||||
SeerrAvailability.UNKNOWN,
|
||||
)
|
||||
}
|
||||
}
|
||||
val defaultEditable =
|
||||
availability != SeerrAvailability.AVAILABLE &&
|
||||
availability != SeerrAvailability.PARTIALLY_AVAILABLE &&
|
||||
availability != SeerrAvailability.PROCESSING &&
|
||||
availability != SeerrAvailability.BLOCKLISTED
|
||||
RequestSeason(
|
||||
season = it,
|
||||
status = status,
|
||||
availability = availability,
|
||||
editable = editable.getOrDefault(seasonNumber, true),
|
||||
editable = editable.getOrDefault(seasonNumber, defaultEditable),
|
||||
)
|
||||
}
|
||||
}
|
||||
Timber.v("Got %s seasons, is4k=%s", requestSeasons.size, is4k)
|
||||
// requestSeasons.forEach {
|
||||
// Timber.v(
|
||||
// "is4k=%s, season %s: availability=%s, status=%s, editable=%s",
|
||||
// is4k,
|
||||
// it.season.seasonNumber,
|
||||
// it.availability,
|
||||
// it.status,
|
||||
// it.editable,
|
||||
// )
|
||||
// }
|
||||
_state.update {
|
||||
if (is4k) {
|
||||
it.copy(seasons4k = requestSeasons)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package com.github.damontecres.wholphin.ui.detail.discover
|
||||
|
||||
import com.github.damontecres.wholphin.api.seerr.infrastructure.ClientException
|
||||
import com.github.damontecres.wholphin.data.model.DiscoverRating
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import timber.log.Timber
|
||||
|
||||
suspend fun getDiscoverRating(
|
||||
id: Int,
|
||||
func: suspend () -> DiscoverRating,
|
||||
): DiscoverRating? =
|
||||
try {
|
||||
func.invoke()
|
||||
} catch (ex: CancellationException) {
|
||||
throw ex
|
||||
} catch (ex: ClientException) {
|
||||
if (ex.statusCode == 404) {
|
||||
Timber.w("No rating for %s", id)
|
||||
} else {
|
||||
Timber.e(ex, "Error fetching rating for %s", id)
|
||||
}
|
||||
null
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Error fetching rating for %s", id)
|
||||
null
|
||||
}
|
||||
|
|
@ -83,11 +83,13 @@ fun RequestSeasons(
|
|||
mutableStateSetOf(
|
||||
*seasons
|
||||
.filter { season ->
|
||||
season.status == RequestStatus.PENDING ||
|
||||
season.status == RequestStatus.APPROVED ||
|
||||
season.status == RequestStatus.COMPLETED ||
|
||||
season.availability == SeerrAvailability.PARTIALLY_AVAILABLE ||
|
||||
season.availability == SeerrAvailability.AVAILABLE
|
||||
!season.editable && (
|
||||
season.status == RequestStatus.PENDING ||
|
||||
season.status == RequestStatus.APPROVED ||
|
||||
season.status == RequestStatus.COMPLETED ||
|
||||
season.availability == SeerrAvailability.PARTIALLY_AVAILABLE ||
|
||||
season.availability == SeerrAvailability.AVAILABLE
|
||||
)
|
||||
}.mapNotNull { season -> season.season.seasonNumber }
|
||||
.toTypedArray(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.github.damontecres.wholphin.R
|
||||
import com.github.damontecres.wholphin.api.seerr.infrastructure.ClientException
|
||||
import com.github.damontecres.wholphin.data.filter.DiscoverFilter
|
||||
import com.github.damontecres.wholphin.data.model.DiscoverItem
|
||||
import com.github.damontecres.wholphin.data.model.DiscoverRating
|
||||
|
|
@ -42,6 +41,7 @@ import com.github.damontecres.wholphin.services.NavigationManager
|
|||
import com.github.damontecres.wholphin.services.SeerrService
|
||||
import com.github.damontecres.wholphin.ui.components.Genre
|
||||
import com.github.damontecres.wholphin.ui.data.RowColumn
|
||||
import com.github.damontecres.wholphin.ui.detail.discover.getDiscoverRating
|
||||
import com.github.damontecres.wholphin.ui.launchIO
|
||||
import com.github.damontecres.wholphin.ui.listToDotString
|
||||
import com.github.damontecres.wholphin.ui.main.HomePageHeader
|
||||
|
|
@ -262,13 +262,11 @@ class SeerrDiscoverViewModel
|
|||
return@launchIO
|
||||
}
|
||||
val result =
|
||||
try {
|
||||
getDiscoverRating(id) {
|
||||
when (type) {
|
||||
SeerrItemType.MOVIE -> {
|
||||
DiscoverRating(
|
||||
seerrService.api.moviesApi.movieMovieIdRatingsGet(
|
||||
movieId = id,
|
||||
),
|
||||
seerrService.api.moviesApi.movieMovieIdRatingsGet(movieId = id),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -284,18 +282,8 @@ class SeerrDiscoverViewModel
|
|||
DiscoverRating(null, null)
|
||||
}
|
||||
}
|
||||
} catch (ex: ClientException) {
|
||||
if (ex.statusCode == 404) {
|
||||
Timber.w("No rating found for %s", id)
|
||||
DiscoverRating(null, null)
|
||||
} else {
|
||||
Timber.e(ex, "Error getting rating for %s", id)
|
||||
return@launchIO
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Error getting rating for %s", id)
|
||||
return@launchIO
|
||||
}
|
||||
} ?: DiscoverRating(null, null)
|
||||
|
||||
ratingCache.put(id, result)
|
||||
rating.update {
|
||||
ratingCache.asMap().toMap()
|
||||
|
|
|
|||
|
|
@ -1304,6 +1304,12 @@ components:
|
|||
type: integer
|
||||
example: 0
|
||||
description: Availability of the media. 1 = `UNKNOWN`, 2 = `PENDING`, 3 = `PROCESSING`, 4 = `PARTIALLY_AVAILABLE`, 5 = `AVAILABLE`, 6 = `DELETED`
|
||||
seasons:
|
||||
type: array
|
||||
readOnly: true
|
||||
nullable: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Season'
|
||||
requests:
|
||||
type: array
|
||||
readOnly: true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue