From a7cbd5bcf9003965403e2d3b17c57f4b39bc6e38 Mon Sep 17 00:00:00 2001 From: jacobrein Date: Thu, 12 Sep 2024 07:32:03 -0600 Subject: [PATCH] - Fix duplicate items in recent list Ensure only distinct items are displayed in the recent list by filtering the source list based on URL. Move network observation to the ViewModel and trigger a reset if the source list is empty, a source is selected, the device is online, and the count is not 1. --- .../uiviews/recent/RecentFragment.kt | 10 +++------- .../uiviews/recent/RecentViewModel.kt | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/UIViews/src/main/java/com/programmersbox/uiviews/recent/RecentFragment.kt b/UIViews/src/main/java/com/programmersbox/uiviews/recent/RecentFragment.kt index dbd4da324..becab0d9c 100644 --- a/UIViews/src/main/java/com/programmersbox/uiviews/recent/RecentFragment.kt +++ b/UIViews/src/main/java/com/programmersbox/uiviews/recent/RecentFragment.kt @@ -104,10 +104,6 @@ fun RecentView( val isConnected by recentVm.observeNetwork.collectAsState(initial = true) - LaunchedEffect(isConnected) { - if (recentVm.sourceList.isEmpty() && source != null && isConnected && recentVm.count != 1) recentVm.reset() - } - val showButton by remember { derivedStateOf { state.firstVisibleItemIndex > 0 } } val sourceList = recentVm.sources @@ -221,11 +217,11 @@ fun RecentView( when { sourceList.isEmpty() -> NoSourcesInstalled(Modifier.fillMaxSize()) - recentVm.sourceList.isEmpty() -> Box(Modifier.fillMaxSize()) { info.ComposeShimmerItem() } + recentVm.filteredSourceList.isEmpty() -> Box(Modifier.fillMaxSize()) { info.ComposeShimmerItem() } else -> { info.ItemListView( - list = recentVm.sourceList, + list = recentVm.filteredSourceList, listState = state, favorites = recentVm.favoriteList, paddingValues = p, @@ -239,7 +235,7 @@ fun RecentView( } } - if (source?.canScroll == true && recentVm.sourceList.isNotEmpty()) { + if (source?.canScroll == true && recentVm.filteredSourceList.isNotEmpty()) { InfiniteListHandler(listState = state, buffer = info.scrollBuffer) { recentVm.loadMore() } diff --git a/UIViews/src/main/java/com/programmersbox/uiviews/recent/RecentViewModel.kt b/UIViews/src/main/java/com/programmersbox/uiviews/recent/RecentViewModel.kt index 55c0d6d47..23aa2cdae 100644 --- a/UIViews/src/main/java/com/programmersbox/uiviews/recent/RecentViewModel.kt +++ b/UIViews/src/main/java/com/programmersbox/uiviews/recent/RecentViewModel.kt @@ -1,12 +1,12 @@ package com.programmersbox.uiviews.recent import androidx.compose.foundation.lazy.grid.LazyGridState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow -import androidx.compose.runtime.toMutableStateList import androidx.compose.ui.util.fastMaxBy import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -41,8 +41,10 @@ class RecentViewModel( ) : ViewModel(), ToastItems by DefaultToastItems() { var isRefreshing by mutableStateOf(false) - val sourceList = mutableStateListOf() - var favoriteList = mutableStateListOf() + private val sourceList = mutableStateListOf() + val favoriteList = mutableStateListOf() + + val filteredSourceList by derivedStateOf { sourceList.distinctBy { it.url } } val observeNetwork = ReactiveNetwork() .observeInternetConnectivity() @@ -70,7 +72,10 @@ class RecentViewModel( itemListener.getAllShowsFlow(), dao.getAllFavorites() ) { f, d -> (f + d).groupBy(DbModel::url).map { it.value.fastMaxBy(DbModel::numChapters)!! } } - .onEach { favoriteList = it.toMutableStateList() } + .onEach { + favoriteList.clear() + favoriteList.addAll(it) + } .launchIn(viewModelScope) currentSourceRepository.asFlow() @@ -88,6 +93,10 @@ class RecentViewModel( .distinctUntilChanged() .onEach { gridState.scrollToItem(0) } .launchIn(viewModelScope) + + observeNetwork + .onEach { if (sourceList.isEmpty() && currentSource != null && it && count != 1) reset() } + .launchIn(viewModelScope) } fun reset() {