mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-12 12:08:56 +01:00
Use immutable collections in more places
This commit is contained in:
@@ -6,6 +6,11 @@ import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.domain.extension.interactor.GetExtensionLanguages
|
||||
import eu.kanade.domain.source.interactor.ToggleLanguage
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
import kotlinx.collections.immutable.persistentSetOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -41,8 +46,8 @@ class ExtensionFilterScreenModel(
|
||||
.collectLatest { (extensionLanguages, enabledLanguages) ->
|
||||
mutableState.update {
|
||||
ExtensionFilterState.Success(
|
||||
languages = extensionLanguages,
|
||||
enabledLanguages = enabledLanguages,
|
||||
languages = extensionLanguages.toImmutableList(),
|
||||
enabledLanguages = enabledLanguages.toImmutableSet(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -65,8 +70,8 @@ sealed interface ExtensionFilterState {
|
||||
|
||||
@Immutable
|
||||
data class Success(
|
||||
val languages: List<String>,
|
||||
val enabledLanguages: Set<String> = emptySet(),
|
||||
val languages: ImmutableList<String>,
|
||||
val enabledLanguages: ImmutableSet<String> = persistentSetOf(),
|
||||
) : ExtensionFilterState {
|
||||
|
||||
val isEmpty: Boolean
|
||||
|
||||
@@ -12,6 +12,9 @@ import eu.kanade.tachiyomi.extension.model.Extension
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -75,10 +78,10 @@ class ExtensionDetailsScreenModel(
|
||||
}
|
||||
.catch { throwable ->
|
||||
logcat(LogPriority.ERROR, throwable)
|
||||
mutableState.update { it.copy(_sources = emptyList()) }
|
||||
mutableState.update { it.copy(_sources = persistentListOf()) }
|
||||
}
|
||||
.collectLatest { sources ->
|
||||
mutableState.update { it.copy(_sources = sources) }
|
||||
mutableState.update { it.copy(_sources = sources.toImmutableList()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,11 +167,11 @@ class ExtensionDetailsScreenModel(
|
||||
@Immutable
|
||||
data class State(
|
||||
val extension: Extension.Installed? = null,
|
||||
private val _sources: List<ExtensionSourceItem>? = null,
|
||||
private val _sources: ImmutableList<ExtensionSourceItem>? = null,
|
||||
) {
|
||||
|
||||
val sources: List<ExtensionSourceItem>
|
||||
get() = _sources.orEmpty()
|
||||
val sources: ImmutableList<ExtensionSourceItem>
|
||||
get() = _sources ?: persistentListOf()
|
||||
|
||||
val isLoading: Boolean
|
||||
get() = extension == null || _sources == null
|
||||
|
||||
@@ -4,6 +4,9 @@ import androidx.compose.runtime.Immutable
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -40,11 +43,13 @@ class MigrateMangaScreenModel(
|
||||
logcat(LogPriority.ERROR, it)
|
||||
_events.send(MigrationMangaEvent.FailedFetchingFavorites)
|
||||
mutableState.update { state ->
|
||||
state.copy(titleList = emptyList())
|
||||
state.copy(titleList = persistentListOf())
|
||||
}
|
||||
}
|
||||
.map { manga ->
|
||||
manga.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.title })
|
||||
manga
|
||||
.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.title })
|
||||
.toImmutableList()
|
||||
}
|
||||
.collectLatest { list ->
|
||||
mutableState.update { it.copy(titleList = list) }
|
||||
@@ -55,11 +60,11 @@ class MigrateMangaScreenModel(
|
||||
@Immutable
|
||||
data class State(
|
||||
val source: Source? = null,
|
||||
private val titleList: List<Manga>? = null,
|
||||
private val titleList: ImmutableList<Manga>? = null,
|
||||
) {
|
||||
|
||||
val titles: List<Manga>
|
||||
get() = titleList.orEmpty()
|
||||
val titles: ImmutableList<Manga>
|
||||
get() = titleList ?: persistentListOf()
|
||||
|
||||
val isLoading: Boolean
|
||||
get() = source == null || titleList == null
|
||||
|
||||
@@ -6,6 +6,9 @@ import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.domain.source.interactor.GetSourcesWithFavoriteCount
|
||||
import eu.kanade.domain.source.interactor.SetMigrateSorting
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
@@ -40,7 +43,7 @@ class MigrateSourceScreenModel(
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
isLoading = false,
|
||||
items = sources,
|
||||
items = sources.toImmutableList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -80,7 +83,7 @@ class MigrateSourceScreenModel(
|
||||
@Immutable
|
||||
data class State(
|
||||
val isLoading: Boolean = true,
|
||||
val items: List<Pair<Source, Long>> = emptyList(),
|
||||
val items: ImmutableList<Pair<Source, Long>> = persistentListOf(),
|
||||
val sortingMode: SetMigrateSorting.Mode = SetMigrateSorting.Mode.ALPHABETICAL,
|
||||
val sortingDirection: SetMigrateSorting.Direction = SetMigrateSorting.Direction.ASCENDING,
|
||||
) {
|
||||
|
||||
@@ -7,6 +7,9 @@ import eu.kanade.domain.source.interactor.GetEnabledSources
|
||||
import eu.kanade.domain.source.interactor.ToggleSource
|
||||
import eu.kanade.domain.source.interactor.ToggleSourcePin
|
||||
import eu.kanade.presentation.browse.SourceUiModel
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
@@ -65,14 +68,16 @@ class SourcesScreenModel(
|
||||
|
||||
state.copy(
|
||||
isLoading = false,
|
||||
items = byLang.flatMap {
|
||||
listOf(
|
||||
SourceUiModel.Header(it.key),
|
||||
*it.value.map { source ->
|
||||
SourceUiModel.Item(source)
|
||||
}.toTypedArray(),
|
||||
)
|
||||
},
|
||||
items = byLang
|
||||
.flatMap {
|
||||
listOf(
|
||||
SourceUiModel.Header(it.key),
|
||||
*it.value.map { source ->
|
||||
SourceUiModel.Item(source)
|
||||
}.toTypedArray(),
|
||||
)
|
||||
}
|
||||
.toImmutableList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -103,7 +108,7 @@ class SourcesScreenModel(
|
||||
data class State(
|
||||
val dialog: Dialog? = null,
|
||||
val isLoading: Boolean = true,
|
||||
val items: List<SourceUiModel> = emptyList(),
|
||||
val items: ImmutableList<SourceUiModel> = persistentListOf(),
|
||||
) {
|
||||
val isEmpty = items.isEmpty()
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@ import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.presentation.util.ioCoroutineScope
|
||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||
import eu.kanade.tachiyomi.source.CatalogueSource
|
||||
import kotlinx.collections.immutable.PersistentMap
|
||||
import kotlinx.collections.immutable.mutate
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import kotlinx.collections.immutable.toPersistentMap
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.async
|
||||
@@ -125,9 +129,17 @@ abstract class SearchScreenModel(
|
||||
// Reuse previous results if possible
|
||||
if (sameQuery) {
|
||||
val existingResults = state.value.items
|
||||
updateItems(sources.associateWith { existingResults[it] ?: SearchItemResult.Loading })
|
||||
updateItems(
|
||||
sources
|
||||
.associateWith { existingResults[it] ?: SearchItemResult.Loading }
|
||||
.toPersistentMap(),
|
||||
)
|
||||
} else {
|
||||
updateItems(sources.associateWith { SearchItemResult.Loading })
|
||||
updateItems(
|
||||
sources
|
||||
.associateWith { SearchItemResult.Loading }
|
||||
.toPersistentMap(),
|
||||
)
|
||||
}
|
||||
|
||||
searchJob = ioCoroutineScope.launch {
|
||||
@@ -160,14 +172,21 @@ abstract class SearchScreenModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateItems(items: Map<CatalogueSource, SearchItemResult>) {
|
||||
mutableState.update { it.copy(items = items.toSortedMap(sortComparator(items))) }
|
||||
private fun updateItems(items: PersistentMap<CatalogueSource, SearchItemResult>) {
|
||||
mutableState.update {
|
||||
it.copy(
|
||||
items = items
|
||||
.toSortedMap(sortComparator(items))
|
||||
.toPersistentMap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateItem(source: CatalogueSource, result: SearchItemResult) {
|
||||
val mutableItems = state.value.items.toMutableMap()
|
||||
mutableItems[source] = result
|
||||
updateItems(mutableItems)
|
||||
val newItems = state.value.items.mutate {
|
||||
it[source] = result
|
||||
}
|
||||
updateItems(newItems)
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@@ -176,7 +195,7 @@ abstract class SearchScreenModel(
|
||||
val searchQuery: String? = null,
|
||||
val sourceFilter: SourceFilter = SourceFilter.PinnedOnly,
|
||||
val onlyShowHasResults: Boolean = false,
|
||||
val items: Map<CatalogueSource, SearchItemResult> = emptyMap(),
|
||||
val items: PersistentMap<CatalogueSource, SearchItemResult> = persistentMapOf(),
|
||||
) {
|
||||
val progress: Int = items.count { it.value !is SearchItemResult.Loading }
|
||||
val total: Int = items.size
|
||||
|
||||
@@ -5,6 +5,8 @@ import androidx.compose.runtime.Immutable
|
||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||
import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import eu.kanade.tachiyomi.R
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
@@ -36,7 +38,9 @@ class CategoryScreenModel(
|
||||
.collectLatest { categories ->
|
||||
mutableState.update {
|
||||
CategoryScreenState.Success(
|
||||
categories = categories.filterNot(Category::isSystemCategory),
|
||||
categories = categories
|
||||
.filterNot(Category::isSystemCategory)
|
||||
.toImmutableList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -135,7 +139,7 @@ sealed interface CategoryScreenState {
|
||||
|
||||
@Immutable
|
||||
data class Success(
|
||||
val categories: List<Category>,
|
||||
val categories: ImmutableList<Category>,
|
||||
val dialog: CategoryDialog? = null,
|
||||
) : CategoryScreenState {
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@ import eu.kanade.tachiyomi.source.model.SManga
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import eu.kanade.tachiyomi.util.chapter.getNextUnread
|
||||
import eu.kanade.tachiyomi.util.removeCovers
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.mutate
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -562,16 +565,16 @@ class LibraryScreenModel(
|
||||
}
|
||||
|
||||
fun clearSelection() {
|
||||
mutableState.update { it.copy(selection = emptyList()) }
|
||||
mutableState.update { it.copy(selection = persistentListOf()) }
|
||||
}
|
||||
|
||||
fun toggleSelection(manga: LibraryManga) {
|
||||
mutableState.update { state ->
|
||||
val newSelection = state.selection.toMutableList().apply {
|
||||
if (fastAny { it.id == manga.id }) {
|
||||
removeAll { it.id == manga.id }
|
||||
val newSelection = state.selection.mutate { list ->
|
||||
if (list.fastAny { it.id == manga.id }) {
|
||||
list.removeAll { it.id == manga.id }
|
||||
} else {
|
||||
add(manga)
|
||||
list.add(manga)
|
||||
}
|
||||
}
|
||||
state.copy(selection = newSelection)
|
||||
@@ -584,11 +587,11 @@ class LibraryScreenModel(
|
||||
*/
|
||||
fun toggleRangeSelection(manga: LibraryManga) {
|
||||
mutableState.update { state ->
|
||||
val newSelection = state.selection.toMutableList().apply {
|
||||
val lastSelected = lastOrNull()
|
||||
val newSelection = state.selection.mutate { list ->
|
||||
val lastSelected = list.lastOrNull()
|
||||
if (lastSelected?.category != manga.category) {
|
||||
add(manga)
|
||||
return@apply
|
||||
list.add(manga)
|
||||
return@mutate
|
||||
}
|
||||
|
||||
val items = state.getLibraryItemsByCategoryId(manga.category)
|
||||
@@ -596,17 +599,17 @@ class LibraryScreenModel(
|
||||
val lastMangaIndex = items.indexOf(lastSelected)
|
||||
val curMangaIndex = items.indexOf(manga)
|
||||
|
||||
val selectedIds = fastMap { it.id }
|
||||
val selectedIds = list.fastMap { it.id }
|
||||
val selectionRange = when {
|
||||
lastMangaIndex < curMangaIndex -> IntRange(lastMangaIndex, curMangaIndex)
|
||||
curMangaIndex < lastMangaIndex -> IntRange(curMangaIndex, lastMangaIndex)
|
||||
// We shouldn't reach this point
|
||||
else -> return@apply
|
||||
else -> return@mutate
|
||||
}
|
||||
val newSelections = selectionRange.mapNotNull { index ->
|
||||
items[index].takeUnless { it.id in selectedIds }
|
||||
}
|
||||
addAll(newSelections)
|
||||
list.addAll(newSelections)
|
||||
}
|
||||
state.copy(selection = newSelection)
|
||||
}
|
||||
@@ -614,14 +617,14 @@ class LibraryScreenModel(
|
||||
|
||||
fun selectAll(index: Int) {
|
||||
mutableState.update { state ->
|
||||
val newSelection = state.selection.toMutableList().apply {
|
||||
val newSelection = state.selection.mutate { list ->
|
||||
val categoryId = state.categories.getOrNull(index)?.id ?: -1
|
||||
val selectedIds = fastMap { it.id }
|
||||
val selectedIds = list.fastMap { it.id }
|
||||
state.getLibraryItemsByCategoryId(categoryId)
|
||||
?.fastMapNotNull { item ->
|
||||
item.libraryManga.takeUnless { it.id in selectedIds }
|
||||
}
|
||||
?.let { addAll(it) }
|
||||
?.let { list.addAll(it) }
|
||||
}
|
||||
state.copy(selection = newSelection)
|
||||
}
|
||||
@@ -629,14 +632,14 @@ class LibraryScreenModel(
|
||||
|
||||
fun invertSelection(index: Int) {
|
||||
mutableState.update { state ->
|
||||
val newSelection = state.selection.toMutableList().apply {
|
||||
val newSelection = state.selection.mutate { list ->
|
||||
val categoryId = state.categories[index].id
|
||||
val items = state.getLibraryItemsByCategoryId(categoryId)?.fastMap { it.libraryManga }.orEmpty()
|
||||
val selectedIds = fastMap { it.id }
|
||||
val selectedIds = list.fastMap { it.id }
|
||||
val (toRemove, toAdd) = items.fastPartition { it.id in selectedIds }
|
||||
val toRemoveIds = toRemove.fastMap { it.id }
|
||||
removeAll { it.id in toRemoveIds }
|
||||
addAll(toAdd)
|
||||
list.removeAll { it.id in toRemoveIds }
|
||||
list.addAll(toAdd)
|
||||
}
|
||||
state.copy(selection = newSelection)
|
||||
}
|
||||
@@ -703,7 +706,7 @@ class LibraryScreenModel(
|
||||
val isLoading: Boolean = true,
|
||||
val library: LibraryMap = emptyMap(),
|
||||
val searchQuery: String? = null,
|
||||
val selection: List<LibraryManga> = emptyList(),
|
||||
val selection: PersistentList<LibraryManga> = persistentListOf(),
|
||||
val hasActiveFilters: Boolean = false,
|
||||
val showCategoryTabs: Boolean = false,
|
||||
val showMangaCount: Boolean = false,
|
||||
|
||||
@@ -43,6 +43,7 @@ import eu.kanade.tachiyomi.ui.home.HomeScreen
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
@@ -154,7 +155,7 @@ object LibraryTab : Tab {
|
||||
EmptyScreen(
|
||||
textResource = R.string.information_empty_library,
|
||||
modifier = Modifier.padding(contentPadding),
|
||||
actions = listOf(
|
||||
actions = persistentListOf(
|
||||
EmptyScreenAction(
|
||||
stringResId = R.string.getting_started_guide,
|
||||
icon = Icons.Outlined.HelpOutline,
|
||||
|
||||
@@ -58,6 +58,7 @@ import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.util.lang.convertEpochMillisZone
|
||||
import eu.kanade.tachiyomi.util.system.openInBrowser
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
@@ -398,7 +399,7 @@ private data class TrackScoreSelectorScreen(
|
||||
private val tracker: Tracker,
|
||||
) : StateScreenModel<Model.State>(State(tracker.displayScore(track.toDbTrack()))) {
|
||||
|
||||
fun getSelections(): List<String> {
|
||||
fun getSelections(): ImmutableList<String> {
|
||||
return tracker.getScoreList()
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||
import eu.kanade.tachiyomi.util.lang.toDateKey
|
||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.mutate
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -106,27 +110,29 @@ class UpdatesScreenModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<UpdatesWithRelations>.toUpdateItems(): List<UpdatesItem> {
|
||||
return this.map { update ->
|
||||
val activeDownload = downloadManager.getQueuedDownloadOrNull(update.chapterId)
|
||||
val downloaded = downloadManager.isChapterDownloaded(
|
||||
update.chapterName,
|
||||
update.scanlator,
|
||||
update.mangaTitle,
|
||||
update.sourceId,
|
||||
)
|
||||
val downloadState = when {
|
||||
activeDownload != null -> activeDownload.status
|
||||
downloaded -> Download.State.DOWNLOADED
|
||||
else -> Download.State.NOT_DOWNLOADED
|
||||
private fun List<UpdatesWithRelations>.toUpdateItems(): PersistentList<UpdatesItem> {
|
||||
return this
|
||||
.map { update ->
|
||||
val activeDownload = downloadManager.getQueuedDownloadOrNull(update.chapterId)
|
||||
val downloaded = downloadManager.isChapterDownloaded(
|
||||
update.chapterName,
|
||||
update.scanlator,
|
||||
update.mangaTitle,
|
||||
update.sourceId,
|
||||
)
|
||||
val downloadState = when {
|
||||
activeDownload != null -> activeDownload.status
|
||||
downloaded -> Download.State.DOWNLOADED
|
||||
else -> Download.State.NOT_DOWNLOADED
|
||||
}
|
||||
UpdatesItem(
|
||||
update = update,
|
||||
downloadStateProvider = { downloadState },
|
||||
downloadProgressProvider = { activeDownload?.progress ?: 0 },
|
||||
selected = update.chapterId in selectedChapterIds,
|
||||
)
|
||||
}
|
||||
UpdatesItem(
|
||||
update = update,
|
||||
downloadStateProvider = { downloadState },
|
||||
downloadProgressProvider = { activeDownload?.progress ?: 0 },
|
||||
selected = update.chapterId in selectedChapterIds,
|
||||
)
|
||||
}
|
||||
.toPersistentList()
|
||||
}
|
||||
|
||||
fun updateLibrary(): Boolean {
|
||||
@@ -144,17 +150,14 @@ class UpdatesScreenModel(
|
||||
*/
|
||||
private fun updateDownloadState(download: Download) {
|
||||
mutableState.update { state ->
|
||||
val newItems = state.items.toMutableList().apply {
|
||||
val modifiedIndex = indexOfFirst { it.update.chapterId == download.chapter.id }
|
||||
if (modifiedIndex < 0) return@apply
|
||||
val newItems = state.items.mutate { list ->
|
||||
val modifiedIndex = list.indexOfFirst { it.update.chapterId == download.chapter.id }
|
||||
if (modifiedIndex < 0) return@mutate
|
||||
|
||||
val item = get(modifiedIndex)
|
||||
set(
|
||||
modifiedIndex,
|
||||
item.copy(
|
||||
downloadStateProvider = { download.status },
|
||||
downloadProgressProvider = { download.progress },
|
||||
),
|
||||
val item = list[modifiedIndex]
|
||||
list[modifiedIndex] = item.copy(
|
||||
downloadStateProvider = { download.status },
|
||||
downloadProgressProvider = { download.progress },
|
||||
)
|
||||
}
|
||||
state.copy(items = newItems)
|
||||
@@ -330,7 +333,7 @@ class UpdatesScreenModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
state.copy(items = newItems)
|
||||
state.copy(items = newItems.toPersistentList())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +343,7 @@ class UpdatesScreenModel(
|
||||
selectedChapterIds.addOrRemove(it.update.chapterId, selected)
|
||||
it.copy(selected = selected)
|
||||
}
|
||||
state.copy(items = newItems)
|
||||
state.copy(items = newItems.toPersistentList())
|
||||
}
|
||||
|
||||
selectedPositions[0] = -1
|
||||
@@ -353,7 +356,7 @@ class UpdatesScreenModel(
|
||||
selectedChapterIds.addOrRemove(it.update.chapterId, !it.selected)
|
||||
it.copy(selected = !it.selected)
|
||||
}
|
||||
state.copy(items = newItems)
|
||||
state.copy(items = newItems.toPersistentList())
|
||||
}
|
||||
selectedPositions[0] = -1
|
||||
selectedPositions[1] = -1
|
||||
@@ -370,7 +373,7 @@ class UpdatesScreenModel(
|
||||
@Immutable
|
||||
data class State(
|
||||
val isLoading: Boolean = true,
|
||||
val items: List<UpdatesItem> = emptyList(),
|
||||
val items: PersistentList<UpdatesItem> = persistentListOf(),
|
||||
val dialog: Dialog? = null,
|
||||
) {
|
||||
val selected = items.filter { it.selected }
|
||||
|
||||
Reference in New Issue
Block a user