mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 16:11:20 +02:00
Optimize quick details UI (#674)
## Description This PR optimizes the rendering of "quick details" in headers. That's the dot separated row of Season/Episode/Date/Runtime, etc The UI is slightly different because I moved the "Ends at" part to the end of the row. The dots & spacing is also slightly different. In testing this on my CCwGTV HD, a pretty low powered device, the PR improved the time to render by over 3x (59.42ms->17.72ms). Note: these times are during profiling and are not real world performance, but the relative change should be applicable in the real world. ### Dev details - Changes the dot separated row of multiple Text & Box composables into a row of two Texts - The text is an `AnnotatedString` which is created on the IO thread when `BaseItem` is created - A separate composable creates the "Ends at" to prevent recompositions of the other strings
This commit is contained in:
parent
3215326515
commit
c9d1244057
18 changed files with 339 additions and 386 deletions
|
|
@ -1,20 +1,29 @@
|
|||
package com.github.damontecres.wholphin.data.model
|
||||
|
||||
import androidx.compose.foundation.text.appendInlineContent
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import com.github.damontecres.wholphin.ui.DateFormatter
|
||||
import com.github.damontecres.wholphin.ui.detail.CardGridItem
|
||||
import com.github.damontecres.wholphin.ui.detail.series.SeasonEpisodeIds
|
||||
import com.github.damontecres.wholphin.ui.dot
|
||||
import com.github.damontecres.wholphin.ui.formatDateTime
|
||||
import com.github.damontecres.wholphin.ui.nav.Destination
|
||||
import com.github.damontecres.wholphin.ui.playback.playable
|
||||
import com.github.damontecres.wholphin.ui.roundMinutes
|
||||
import com.github.damontecres.wholphin.ui.seasonEpisode
|
||||
import com.github.damontecres.wholphin.ui.seasonEpisodePadded
|
||||
import com.github.damontecres.wholphin.ui.seriesProductionYears
|
||||
import com.github.damontecres.wholphin.ui.timeRemaining
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||
import org.jellyfin.sdk.model.extensions.ticks
|
||||
import java.util.Locale
|
||||
import kotlin.time.Duration
|
||||
|
||||
@Serializable
|
||||
|
|
@ -73,6 +82,61 @@ data class BaseItem(
|
|||
|
||||
val favorite get() = data.userData?.isFavorite ?: false
|
||||
|
||||
@Transient
|
||||
val timeRemainingOrRuntime: Duration? = data.timeRemaining ?: data.runTimeTicks?.ticks
|
||||
|
||||
@Transient
|
||||
val ui =
|
||||
BaseItemUi(
|
||||
quickDetails =
|
||||
buildAnnotatedString {
|
||||
val details =
|
||||
buildList {
|
||||
if (type == BaseItemKind.EPISODE) {
|
||||
data.seasonEpisode?.let(::add)
|
||||
data.premiereDate?.let { add(DateFormatter.format(it)) }
|
||||
} else if (type == BaseItemKind.SERIES) {
|
||||
data.seriesProductionYears?.let(::add)
|
||||
} else {
|
||||
data.productionYear?.let { add(it.toString()) }
|
||||
}
|
||||
data.runTimeTicks
|
||||
?.ticks
|
||||
?.roundMinutes
|
||||
?.let { add(it.toString()) }
|
||||
data.timeRemaining
|
||||
?.roundMinutes
|
||||
?.let { add("$it left") }
|
||||
}
|
||||
details.forEachIndexed { index, string ->
|
||||
append(string)
|
||||
if (index != details.lastIndex) {
|
||||
dot()
|
||||
}
|
||||
}
|
||||
// TODO time remaining
|
||||
|
||||
data.officialRating?.let {
|
||||
dot()
|
||||
append(it)
|
||||
}
|
||||
data.communityRating?.let {
|
||||
dot()
|
||||
append(String.format(Locale.getDefault(), "%.1f", it))
|
||||
appendInlineContent(id = "star")
|
||||
}
|
||||
data.criticRating?.let {
|
||||
dot()
|
||||
append("${it.toInt()}%")
|
||||
if (it >= 60f) {
|
||||
appendInlineContent(id = "fresh")
|
||||
} else {
|
||||
appendInlineContent(id = "rotten")
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
private fun dateAsIndex(): Int? =
|
||||
data.premiereDate
|
||||
?.let {
|
||||
|
|
@ -124,3 +188,8 @@ data class BaseItem(
|
|||
}
|
||||
|
||||
val BaseItemDto.aspectRatioFloat: Float? get() = width?.let { w -> height?.let { h -> w.toFloat() / h.toFloat() } }
|
||||
|
||||
@Immutable
|
||||
data class BaseItemUi(
|
||||
val quickDetails: AnnotatedString,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue