diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt index f58cd2df..e0bbc593 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt @@ -46,6 +46,8 @@ import com.nuvio.app.core.network.NetworkStatusRepository import com.nuvio.app.core.ui.NuvioNetworkOfflineCard import coil3.compose.AsyncImage import com.nuvio.app.core.format.formatReleaseDateForDisplay +import com.nuvio.app.core.ui.NuvioAnimatedBookmarkedBadge +import com.nuvio.app.core.ui.NuvioAnimatedWatchedBadge import com.nuvio.app.core.ui.NuvioBackButton import com.nuvio.app.core.ui.rememberPosterCardStyleUiState import com.nuvio.app.core.ui.posterCardClickable @@ -55,6 +57,7 @@ import com.nuvio.app.features.home.MetaPreview import com.nuvio.app.features.home.HomeCatalogSettingsRepository import com.nuvio.app.features.home.PosterShape import com.nuvio.app.features.home.stableKey +import com.nuvio.app.features.library.LibraryRepository import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map @@ -81,6 +84,10 @@ fun CatalogScreen( val gridState = rememberLazyGridState() var headerHeightPx by remember { mutableIntStateOf(0) } var observedOfflineState by remember { mutableStateOf(false) } + val libraryUiState by remember { + LibraryRepository.ensureLoaded() + LibraryRepository.uiState + }.collectAsStateWithLifecycle() LaunchedEffect(manifestUrl, type, catalogId, genre, supportsPagination, homeCatalogSettingsUiState.hideUnreleasedContent) { CatalogRepository.load( @@ -182,10 +189,20 @@ fun CatalogScreen( key = { item -> item.lazyKey }, ) { keyedItem -> val item = keyedItem.value + val isSaved = remember( + libraryUiState.items, + libraryUiState.sections, + libraryUiState.sourceMode, + item.id, + item.type, + ) { + LibraryRepository.isSaved(item.id, item.type) + } CatalogPosterTile( item = item, cornerRadiusDp = posterCardStyle.cornerRadiusDp, hideLabels = posterCardStyle.hideLabelsEnabled, + isSaved = isSaved, onClick = onPosterClick?.let { { it(item) } }, ) } @@ -256,6 +273,7 @@ private fun CatalogPosterTile( item: MetaPreview, cornerRadiusDp: Int, hideLabels: Boolean, + isSaved: Boolean = false, onClick: (() -> Unit)? = null, ) { Column( @@ -277,6 +295,13 @@ private fun CatalogPosterTile( contentScale = ContentScale.Crop, ) } + + NuvioAnimatedBookmarkedBadge( + isVisible = isSaved, + modifier = Modifier + .align(Alignment.TopStart) + .padding(6.dp), + ) } if (!hideLabels) { Text( diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/collection/FolderDetailScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/collection/FolderDetailScreen.kt index 6101d18a..e98bd314 100644 --- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/collection/FolderDetailScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/collection/FolderDetailScreen.kt @@ -49,6 +49,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import coil3.compose.AsyncImage import com.nuvio.app.core.ui.NuvioPosterCard import com.nuvio.app.core.ui.NuvioPosterShape @@ -61,6 +62,7 @@ import com.nuvio.app.features.home.PosterShape import com.nuvio.app.features.home.canOpenCatalog import com.nuvio.app.features.home.stableKey import com.nuvio.app.features.home.components.HomeCatalogRowSection +import com.nuvio.app.features.library.LibraryRepository import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map @@ -204,6 +206,10 @@ private fun TabbedGridContent( onPosterClick: (MetaPreview) -> Unit, ) { val gridState = rememberLazyGridState() + val libraryUiState by remember { + LibraryRepository.ensureLoaded() + LibraryRepository.uiState + }.collectAsStateWithLifecycle() LaunchedEffect(gridState, uiState.selectedTabIndex, uiState.selectedTabCanLoadMore, uiState.selectedTabIsLoadingMore) { snapshotFlow { gridState.layoutInfo } @@ -280,11 +286,21 @@ private fun TabbedGridContent( key = { item -> item.lazyKey }, ) { keyedItem -> val item = keyedItem.value + val isSaved = remember( + libraryUiState.items, + libraryUiState.sections, + libraryUiState.sourceMode, + item.id, + item.type, + ) { + LibraryRepository.isSaved(item.id, item.type) + } NuvioPosterCard( title = item.name, imageUrl = item.poster, shape = NuvioPosterShape.Poster, detailLine = item.releaseInfo, + isSaved = isSaved, onClick = { onPosterClick(item) }, ) }