mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-16 23:12:12 +00:00
fix: patch remaining areas generating duplicate keys
This commit is contained in:
parent
0a663560d8
commit
8a58fabfdd
11 changed files with 66 additions and 26 deletions
|
|
@ -0,0 +1,23 @@
|
|||
package com.nuvio.app.core.ui
|
||||
|
||||
internal data class DuplicateSafeLazyEntry<T>(
|
||||
val value: T,
|
||||
val lazyKey: Any,
|
||||
)
|
||||
|
||||
internal fun <T> List<T>.withDuplicateSafeLazyKeys(key: (T) -> Any): List<DuplicateSafeLazyEntry<T>> {
|
||||
val keyCounts = groupingBy(key).eachCount()
|
||||
val occurrences = mutableMapOf<Any, Int>()
|
||||
|
||||
return map { entry ->
|
||||
val baseKey = key(entry)
|
||||
val lazyKey = if (keyCounts[baseKey] == 1) {
|
||||
baseKey
|
||||
} else {
|
||||
val occurrence = occurrences.getOrElse(baseKey) { 0 }
|
||||
occurrences[baseKey] = occurrence + 1
|
||||
"$baseKey#$occurrence"
|
||||
}
|
||||
DuplicateSafeLazyEntry(value = entry, lazyKey = lazyKey)
|
||||
}
|
||||
}
|
||||
|
|
@ -82,10 +82,10 @@ fun <T> NuvioShelfSection(
|
|||
) {
|
||||
if (key != null) {
|
||||
items(
|
||||
items = entries,
|
||||
key = key,
|
||||
) { entry ->
|
||||
itemContent(entry)
|
||||
items = entries.withDuplicateSafeLazyKeys(key),
|
||||
key = { entry -> entry.lazyKey },
|
||||
) { keyedEntry ->
|
||||
itemContent(keyedEntry.value)
|
||||
}
|
||||
} else {
|
||||
items(entries) { entry ->
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import com.nuvio.app.core.ui.NuvioBackButton
|
|||
import com.nuvio.app.core.ui.rememberPosterCardStyleUiState
|
||||
import com.nuvio.app.core.ui.posterCardClickable
|
||||
import com.nuvio.app.core.ui.nuvioSafeBottomPadding
|
||||
import com.nuvio.app.core.ui.withDuplicateSafeLazyKeys
|
||||
import com.nuvio.app.features.home.MetaPreview
|
||||
import com.nuvio.app.features.home.PosterShape
|
||||
import com.nuvio.app.features.home.stableKey
|
||||
|
|
@ -175,9 +176,10 @@ fun CatalogScreen(
|
|||
}
|
||||
} else {
|
||||
items(
|
||||
items = uiState.items,
|
||||
key = { item -> item.stableKey() },
|
||||
) { item ->
|
||||
items = uiState.items.withDuplicateSafeLazyKeys { item -> item.stableKey() },
|
||||
key = { item -> item.lazyKey },
|
||||
) { keyedItem ->
|
||||
val item = keyedItem.value
|
||||
CatalogPosterTile(
|
||||
item = item,
|
||||
cornerRadiusDp = posterCardStyle.cornerRadiusDp,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import com.nuvio.app.core.ui.NuvioPosterCard
|
|||
import com.nuvio.app.core.ui.NuvioPosterShape
|
||||
import com.nuvio.app.core.ui.NuvioScreenHeader
|
||||
import com.nuvio.app.core.ui.nuvioSafeBottomPadding
|
||||
import com.nuvio.app.core.ui.withDuplicateSafeLazyKeys
|
||||
import com.nuvio.app.features.home.HomeCatalogSection
|
||||
import com.nuvio.app.features.home.MetaPreview
|
||||
import com.nuvio.app.features.home.PosterShape
|
||||
|
|
@ -275,9 +276,10 @@ private fun TabbedGridContent(
|
|||
verticalArrangement = Arrangement.spacedBy(14.dp),
|
||||
) {
|
||||
items(
|
||||
items = selectedTab.items,
|
||||
key = { item -> item.stableKey() },
|
||||
) { item ->
|
||||
items = selectedTab.items.withDuplicateSafeLazyKeys { item -> item.stableKey() },
|
||||
key = { item -> item.lazyKey },
|
||||
) { keyedItem ->
|
||||
val item = keyedItem.value
|
||||
NuvioPosterCard(
|
||||
title = item.name,
|
||||
imageUrl = item.poster,
|
||||
|
|
@ -326,9 +328,10 @@ private fun RowsContent(
|
|||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
items(
|
||||
items = sections,
|
||||
key = { it.key },
|
||||
) { section ->
|
||||
items = sections.withDuplicateSafeLazyKeys { it.key },
|
||||
key = { it.lazyKey },
|
||||
) { keyedSection ->
|
||||
val section = keyedSection.value
|
||||
HomeCatalogRowSection(
|
||||
section = section,
|
||||
entries = section.items.take(18),
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.nuvio.app.core.ui.withDuplicateSafeLazyKeys
|
||||
import com.nuvio.app.features.trakt.TraktCommentReview
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import nuvio.composeapp.generated.resources.*
|
||||
|
|
@ -122,7 +123,11 @@ fun DetailCommentsSection(
|
|||
state = listState,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
items(comments, key = { it.id }) { review ->
|
||||
items(
|
||||
items = comments.withDuplicateSafeLazyKeys { it.id },
|
||||
key = { it.lazyKey },
|
||||
) { keyedReview ->
|
||||
val review = keyedReview.value
|
||||
CommentCard(
|
||||
review = review,
|
||||
onClick = { onCommentClick(review) },
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import androidx.compose.foundation.layout.size
|
|||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
|
|
@ -582,7 +583,10 @@ private fun EpisodeHorizontalRow(
|
|||
contentPadding = PaddingValues(horizontal = rowMetrics.rowHorizontalPadding, vertical = rowMetrics.rowVerticalPadding),
|
||||
horizontalArrangement = Arrangement.spacedBy(rowMetrics.itemSpacing),
|
||||
) {
|
||||
items(episodes, key = { it.id }) { episode ->
|
||||
itemsIndexed(
|
||||
items = episodes,
|
||||
key = { index, episode -> "${episode.season}:${episode.episode}:${episode.id}#$index" },
|
||||
) { _, episode ->
|
||||
val episodeVideoId = buildPlaybackVideoId(
|
||||
parentMetaId = parentMetaId,
|
||||
seasonNumber = episode.season,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ExpandMore
|
||||
|
|
@ -158,10 +158,10 @@ fun DetailTrailersSection(
|
|||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(sizing.cardSpacing),
|
||||
) {
|
||||
items(
|
||||
itemsIndexed(
|
||||
items = selectedTrailers,
|
||||
key = { trailer -> "${trailer.type}-${trailer.id}-${trailer.seasonNumber ?: 0}" },
|
||||
) { trailer ->
|
||||
key = { index, trailer -> "${trailer.type}-${trailer.id}-${trailer.seasonNumber ?: 0}#$index" },
|
||||
) { _, trailer ->
|
||||
TrailerCard(
|
||||
trailer = trailer,
|
||||
cardWidth = sizing.cardWidth,
|
||||
|
|
|
|||
|
|
@ -291,7 +291,10 @@ private fun EpisodesListSubView(
|
|||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
contentPadding = androidx.compose.foundation.layout.PaddingValues(bottom = 16.dp),
|
||||
) {
|
||||
items(seasonEpisodes, key = { "${it.season}:${it.episode}:${it.id}" }) { episode ->
|
||||
itemsIndexed(
|
||||
items = seasonEpisodes,
|
||||
key = { index, episode -> "${episode.season}:${episode.episode}:${episode.id}#$index" },
|
||||
) { _, episode ->
|
||||
val isCurrent = episode.season == currentSeason && episode.episode == currentEpisode
|
||||
EpisodeRow(
|
||||
episode = episode,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import com.nuvio.app.core.ui.NuvioInputField
|
|||
import com.nuvio.app.core.ui.NuvioScreen
|
||||
import com.nuvio.app.core.ui.NuvioNetworkOfflineCard
|
||||
import com.nuvio.app.core.ui.NuvioScreenHeader
|
||||
import com.nuvio.app.core.ui.withDuplicateSafeLazyKeys
|
||||
import com.nuvio.app.features.addons.AddonRepository
|
||||
import com.nuvio.app.features.home.MetaPreview
|
||||
import com.nuvio.app.features.home.components.HomeCatalogRowSection
|
||||
|
|
@ -303,9 +304,10 @@ fun SearchScreen(
|
|||
|
||||
else -> {
|
||||
items(
|
||||
items = uiState.sections,
|
||||
key = { section -> section.key },
|
||||
) { section ->
|
||||
items = uiState.sections.withDuplicateSafeLazyKeys { section -> section.key },
|
||||
key = { section -> section.lazyKey },
|
||||
) { keyedSection ->
|
||||
val section = keyedSection.value
|
||||
HomeCatalogRowSection(
|
||||
section = section,
|
||||
modifier = Modifier.padding(bottom = 12.dp),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
CURRENT_PROJECT_VERSION=48
|
||||
MARKETING_VERSION=0.1.12
|
||||
MARKETING_VERSION=0.1.0
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@
|
|||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
|
|
|
|||
Loading…
Reference in a new issue