From 801a6899e7f1021481e603fecc323ebbb07f9f65 Mon Sep 17 00:00:00 2001 From: Syer10 Date: Mon, 31 Oct 2022 17:19:44 -0400 Subject: [PATCH] Cleanup uneeded StableHolder classes --- .../ui/base/chapter/ChapterDownloadButtons.kt | 8 +-- .../ui/downloads/DownloadsScreenViewModel.kt | 3 +- .../components/DownloadsScreenContent.kt | 8 +-- .../jui/ui/library/LibraryScreenViewModel.kt | 40 +++++++------- .../library/components/LibraryMangaBadges.kt | 4 +- .../ui/library/components/LibraryMangaList.kt | 16 +++--- .../jui/ui/library/components/LibraryPager.kt | 5 +- .../components/LibraryScreenContent.kt | 7 +-- .../jui/ui/library/components/LibraryTabs.kt | 5 +- .../components/MangaComfortableGrid.kt | 16 +++--- .../ui/library/components/MangaCompactGrid.kt | 16 +++--- .../library/components/MangaCoverOnlyGrid.kt | 16 +++--- .../gosyer/jui/ui/main/about/AboutScreen.kt | 2 +- .../jui/ui/main/about/AboutViewModel.kt | 7 +-- .../ui/main/about/components/AboutContent.kt | 8 +-- .../ca/gosyer/jui/ui/manga/MangaScreen.kt | 2 +- .../jui/ui/manga/MangaScreenViewModel.kt | 24 ++++---- .../jui/ui/manga/components/MangaMenu.kt | 27 ++++----- .../ui/manga/components/MangaScreenContent.kt | 15 +++-- .../jui/ui/sources/browse/SourceScreen.kt | 5 +- .../sources/browse/SourceScreenViewModel.kt | 7 +-- .../components/SourceMangaComfortableGrid.kt | 14 ++--- .../components/SourceMangaCompactGrid.kt | 14 ++--- .../browse/components/SourceMangaList.kt | 14 ++--- .../browse/components/SourceScreenContent.kt | 33 +++++------ .../browse/filter/SourceFiltersMenu.kt | 55 ++++++------------- .../browse/filter/SourceFiltersViewModel.kt | 7 +-- .../globalsearch/GlobalSearchViewModel.kt | 9 ++- .../GlobalSearchMangaComfortableGrid.kt | 4 +- .../GlobalSearchMangaCompactGrid.kt | 4 +- .../components/GlobalSearchScreenContent.kt | 32 +++++------ .../settings/SourceSettingsScreenViewModel.kt | 7 +-- .../components/SourceSettingsScreenContent.kt | 27 ++++----- 33 files changed, 192 insertions(+), 269 deletions(-) diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt index 2634499d..f6ac47c5 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/base/chapter/ChapterDownloadButtons.kt @@ -39,7 +39,6 @@ import ca.gosyer.jui.domain.download.model.DownloadChapter import ca.gosyer.jui.domain.download.model.DownloadState import ca.gosyer.jui.domain.manga.model.Manga import ca.gosyer.jui.i18n.MR -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.uicore.components.DropdownIconButton import ca.gosyer.jui.uicore.components.DropdownMenuItem import ca.gosyer.jui.uicore.resources.stringResource @@ -57,7 +56,7 @@ data class ChapterDownloadItem( ChapterDownloadState.NotDownloaded } ), - private val _downloadChapterFlow: MutableStateFlow> = MutableStateFlow(StableHolder(null)) + private val _downloadChapterFlow: MutableStateFlow = MutableStateFlow(null) ) { val downloadState = _downloadState.asStateFlow() val downloadChapterFlow = _downloadChapterFlow.asStateFlow() @@ -72,7 +71,7 @@ data class ChapterDownloadItem( if (downloadState.value == ChapterDownloadState.Downloading && downloadingChapter == null) { _downloadState.value = ChapterDownloadState.Downloaded } - _downloadChapterFlow.value = StableHolder(downloadingChapter) + _downloadChapterFlow.value = downloadingChapter } suspend fun deleteDownload(deleteChapterDownload: DeleteChapterDownload) { @@ -144,8 +143,7 @@ private fun DownloadIconButton(onClick: () -> Unit) { } @Composable -private fun DownloadingIconButton(downloadChapterHolder: StableHolder, onClick: () -> Unit) { - val downloadChapter = downloadChapterHolder.item +private fun DownloadingIconButton(downloadChapter: DownloadChapter?, onClick: () -> Unit) { DropdownIconButton( downloadChapter?.mangaId to downloadChapter?.chapterIndex, { diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/DownloadsScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/DownloadsScreenViewModel.kt index cd0fa97a..33cdc577 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/DownloadsScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/DownloadsScreenViewModel.kt @@ -14,7 +14,6 @@ import ca.gosyer.jui.domain.download.interactor.ClearDownloadQueue import ca.gosyer.jui.domain.download.interactor.StartDownloading import ca.gosyer.jui.domain.download.interactor.StopDownloading import ca.gosyer.jui.domain.download.service.DownloadService -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.uicore.vm.ContextWrapper import ca.gosyer.jui.uicore.vm.ViewModel import kotlinx.collections.immutable.persistentListOf @@ -51,7 +50,7 @@ class DownloadsScreenViewModel @Inject constructor( val serviceStatus get() = DownloadService.status.asStateFlow() val downloaderStatus get() = DownloadService.downloaderStatus.asStateFlow() - val downloadQueue get() = DownloadService.downloadQueue.map { it.map(::StableHolder).toImmutableList() } + val downloadQueue get() = DownloadService.downloadQueue.map { it.toImmutableList() } .stateIn(scope, SharingStarted.Eagerly, persistentListOf()) fun start() { diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/components/DownloadsScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/components/DownloadsScreenContent.kt index 7c7b67e3..4f659036 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/components/DownloadsScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/downloads/components/DownloadsScreenContent.kt @@ -49,7 +49,6 @@ import ca.gosyer.jui.domain.chapter.model.Chapter import ca.gosyer.jui.domain.download.model.DownloadChapter import ca.gosyer.jui.domain.download.model.DownloaderStatus import ca.gosyer.jui.i18n.MR -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.base.navigation.ActionItem import ca.gosyer.jui.ui.base.navigation.Toolbar import ca.gosyer.jui.ui.main.components.bottomNav @@ -72,7 +71,7 @@ import kotlinx.collections.immutable.toImmutableList @Composable fun DownloadsScreenContent( - downloadQueue: ImmutableList>, + downloadQueue: ImmutableList, downloadStatus: DownloaderStatus, startDownloading: () -> Unit, pauseDownloading: () -> Unit, @@ -115,7 +114,7 @@ fun DownloadsScreenContent( items(downloadQueue) { DownloadsItem( it, - { onMangaClick(it.item.mangaId) }, + { onMangaClick(it.mangaId) }, stopDownload, moveDownloadToBottom ) @@ -140,12 +139,11 @@ fun DownloadsScreenContent( @Composable fun DownloadsItem( - itemHolder: StableHolder, + item: DownloadChapter, onClickCover: () -> Unit, onClickCancel: (Chapter) -> Unit, onClickMoveToBottom: (Chapter) -> Unit ) { - val item = itemHolder.item MangaListItem( modifier = Modifier .height(96.dp) diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/LibraryScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/LibraryScreenViewModel.kt index c4194a19..4f82f526 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/LibraryScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/LibraryScreenViewModel.kt @@ -23,7 +23,6 @@ import ca.gosyer.jui.domain.manga.model.MangaStatus import ca.gosyer.jui.domain.updates.interactor.UpdateCategory import ca.gosyer.jui.domain.updates.interactor.UpdateLibrary import ca.gosyer.jui.i18n.MR -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.base.state.SavedStateHandle import ca.gosyer.jui.ui.base.state.getStateFlow import ca.gosyer.jui.ui.util.lang.Collator @@ -65,13 +64,13 @@ sealed class CategoryState { @Stable data class Loaded( - val items: StateFlow>>, - val unfilteredItems: MutableStateFlow>> + val items: StateFlow>, + val unfilteredItems: MutableStateFlow> ) : CategoryState() } private typealias LibraryMap = MutableMap> -private data class Library(val categories: MutableStateFlow>>, val mangaMap: LibraryMap) +private data class Library(val categories: MutableStateFlow>, val mangaMap: LibraryMap) private fun LibraryMap.getManga(id: Long) = getOrPut(id) { @@ -80,7 +79,7 @@ private fun LibraryMap.getManga(id: Long) = private fun LibraryMap.setError(id: Long, e: Throwable) { getManga(id).value = CategoryState.Failed(e) } -private fun LibraryMap.setManga(id: Long, manga: ImmutableList>, getItemsFlow: (StateFlow>>) -> StateFlow>>) { +private fun LibraryMap.setManga(id: Long, manga: ImmutableList, getItemsFlow: (StateFlow>) -> StateFlow>) { val flow = getManga(id) when (val state = flow.value) { is CategoryState.Loaded -> state.unfilteredItems.value = manga @@ -121,12 +120,12 @@ class LibraryScreenViewModel @Inject constructor( private val sortMode = libraryPreferences.sortMode().stateIn(scope) private val sortAscending = libraryPreferences.sortAscending().stateIn(scope) - private val filter: Flow<(StableHolder) -> Boolean> = combine( + private val filter: Flow<(Manga) -> Boolean> = combine( libraryPreferences.filterDownloaded().getAsFlow(), libraryPreferences.filterUnread().getAsFlow(), libraryPreferences.filterCompleted().getAsFlow() ) { downloaded, unread, completed -> - { (manga) -> + { manga -> when (downloaded) { FilterState.EXCLUDED -> manga.downloadCount == null || manga.downloadCount == 0 FilterState.INCLUDED -> manga.downloadCount != null && (manga.downloadCount ?: 0) > 0 @@ -154,7 +153,7 @@ class LibraryScreenViewModel @Inject constructor( private val comparator = combine(sortMode, sortAscending) { sortMode, sortAscending -> getComparator(sortMode, sortAscending) - }.stateIn(scope, SharingStarted.Eagerly, compareBy { it.item.title }) + }.stateIn(scope, SharingStarted.Eagerly, compareBy { it.title }) init { getLibrary() @@ -168,7 +167,6 @@ class LibraryScreenViewModel @Inject constructor( throw Exception(MR.strings.library_empty.toPlatformString()) } library.categories.value = categories.sortedBy { it.order } - .map(::StableHolder) .toImmutableList() updateCategories(categories) _isLoading.value = false @@ -189,18 +187,18 @@ class LibraryScreenViewModel @Inject constructor( _showingMenu.value = showingMenu } - private fun getComparator(sortMode: Sort, ascending: Boolean): Comparator> { - val sortFn: (StableHolder, StableHolder) -> Int = when (sortMode) { + private fun getComparator(sortMode: Sort, ascending: Boolean): Comparator { + val sortFn: (Manga, Manga) -> Int = when (sortMode) { Sort.ALPHABETICAL -> { val locale = Locale.current val collator = Collator(locale); - { (a), (b) -> + { a, b -> collator.compare(a.title.toLowerCase(locale), b.title.toLowerCase(locale)) } } Sort.UNREAD -> { - { (a), (b) -> + { a, b -> when { // Ensure unread content comes first (a.unreadCount ?: 0) == (b.unreadCount ?: 0) -> 0 @@ -211,7 +209,7 @@ class LibraryScreenViewModel @Inject constructor( } } Sort.DATE_ADDED -> { - { (a), (b) -> + { a, b -> a.inLibraryAt.compareTo(b.inLibraryAt) } } @@ -223,11 +221,11 @@ class LibraryScreenViewModel @Inject constructor( } } - private suspend fun filterManga(query: String, mangaList: List>): List> { + private suspend fun filterManga(query: String, mangaList: List): List { if (query.isBlank()) return mangaList val queries = query.split(" ") return mangaList.asFlow() - .filter { (manga) -> + .filter { manga -> queries.all { query -> manga.title.contains(query, true) || manga.author.orEmpty().contains(query, true) || @@ -242,7 +240,7 @@ class LibraryScreenViewModel @Inject constructor( .toList() } - private fun getMangaItemsFlow(unfilteredItemsFlow: StateFlow>>): StateFlow>> { + private fun getMangaItemsFlow(unfilteredItemsFlow: StateFlow>): StateFlow> { return combine(unfilteredItemsFlow, query) { unfilteredItems, query -> filterManga(query, unfilteredItems) }.combine(filter) { filteredManga, filterer -> @@ -266,7 +264,7 @@ class LibraryScreenViewModel @Inject constructor( .onEach { library.mangaMap.setManga( id = category.id, - manga = it.map(::StableHolder).toImmutableList(), + manga = it.toImmutableList(), getItemsFlow = ::getMangaItemsFlow ) } @@ -280,12 +278,12 @@ class LibraryScreenViewModel @Inject constructor( } } - private fun getCategoriesToUpdate(mangaId: Long): List> { + private fun getCategoriesToUpdate(mangaId: Long): List { return library.mangaMap .filter { mangaMapEntry -> - (mangaMapEntry.value.value as? CategoryState.Loaded)?.items?.value?.firstOrNull { it.item.id == mangaId } != null + (mangaMapEntry.value.value as? CategoryState.Loaded)?.items?.value?.firstOrNull { it.id == mangaId } != null } - .map { (id) -> library.categories.value.first { it.item.id == id } } + .map { (id) -> library.categories.value.first { it.id == id } } } fun removeManga(mangaId: Long) { diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryMangaBadges.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryMangaBadges.kt index 31c181ec..46de6724 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryMangaBadges.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryMangaBadges.kt @@ -23,19 +23,17 @@ import androidx.compose.ui.unit.dp import ca.gosyer.jui.domain.manga.model.Manga import ca.gosyer.jui.domain.source.model.Source import ca.gosyer.jui.i18n.MR -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.uicore.resources.stringResource @Composable fun LibraryMangaBadges( modifier: Modifier = Modifier, - mangaHolder: StableHolder, + manga: Manga, showUnread: Boolean, showDownloaded: Boolean, showLanguage: Boolean, showLocal: Boolean ) { - val manga = mangaHolder.item val unread = manga.unreadCount val downloaded = manga.downloadCount val isLocal = manga.sourceId == Source.LOCAL_SOURCE_ID diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryMangaList.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryMangaList.kt index 13d47bc9..1df0a8d9 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryMangaList.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryMangaList.kt @@ -30,7 +30,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import ca.gosyer.jui.domain.manga.model.Manga -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.main.components.bottomNav import ca.gosyer.jui.uicore.components.MangaListItem import ca.gosyer.jui.uicore.components.MangaListItemImage @@ -43,7 +42,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable fun LibraryMangaList( - library: ImmutableList>, + library: ImmutableList, onClickManga: (Long) -> Unit, onRemoveMangaClicked: (Long) -> Unit, showUnread: Boolean, @@ -62,13 +61,13 @@ fun LibraryMangaList( ) ).asPaddingValues() ) { - items(library) { mangaHolder -> + items(library) { manga -> LibraryMangaListItem( modifier = Modifier.libraryMangaModifier( - { onClickManga(mangaHolder.item.id) }, - { onRemoveMangaClicked(mangaHolder.item.id) } + { onClickManga(manga.id) }, + { onRemoveMangaClicked(manga.id) } ), - mangaHolder = mangaHolder, + manga = manga, showUnread = showUnread, showDownloaded = showDownloaded, showLanguage = showLanguage, @@ -95,13 +94,12 @@ fun LibraryMangaList( @Composable private fun LibraryMangaListItem( modifier: Modifier, - mangaHolder: StableHolder, + manga: Manga, showUnread: Boolean, showDownloaded: Boolean, showLanguage: Boolean, showLocal: Boolean ) { - val manga = mangaHolder.item MangaListItem( modifier = modifier then Modifier .requiredHeight(56.dp) @@ -122,7 +120,7 @@ private fun LibraryMangaListItem( ) Box(Modifier.width(IntrinsicSize.Min)) { LibraryMangaBadges( - mangaHolder = mangaHolder, + manga = manga, showUnread = showUnread, showDownloaded = showDownloaded, showLanguage = showLanguage, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryPager.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryPager.kt index b293f1cc..c4db4aa6 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryPager.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryPager.kt @@ -13,7 +13,6 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import ca.gosyer.jui.domain.category.model.Category import ca.gosyer.jui.domain.library.model.DisplayMode -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.library.CategoryState import ca.gosyer.jui.uicore.components.ErrorScreen import ca.gosyer.jui.uicore.components.LoadingScreen @@ -24,7 +23,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable fun LibraryPager( pagerState: PagerState, - categories: ImmutableList>, + categories: ImmutableList, displayMode: DisplayMode, gridColumns: Int, gridSize: Int, @@ -39,7 +38,7 @@ fun LibraryPager( if (categories.isEmpty()) return HorizontalPager(categories.size, state = pagerState) { - when (val library = getLibraryForPage(categories[it].item.id).value) { + when (val library = getLibraryForPage(categories[it].id).value) { CategoryState.Loading -> LoadingScreen() is CategoryState.Failed -> ErrorScreen(library.e.message) is CategoryState.Loaded -> LibraryLoadedPage( diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryScreenContent.kt index 0823f063..0c58a9e8 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryScreenContent.kt @@ -40,7 +40,6 @@ import androidx.compose.ui.unit.dp import ca.gosyer.jui.domain.category.model.Category import ca.gosyer.jui.domain.library.model.DisplayMode import ca.gosyer.jui.i18n.MR -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.base.navigation.ActionItem import ca.gosyer.jui.ui.base.navigation.BackHandler import ca.gosyer.jui.ui.base.navigation.Toolbar @@ -58,7 +57,7 @@ import kotlinx.collections.immutable.toImmutableList @Composable fun LibraryScreenContent( - categories: ImmutableList>, + categories: ImmutableList, selectedCategoryIndex: Int, displayMode: DisplayMode, gridColumns: Int, @@ -156,7 +155,7 @@ fun LibraryScreenContent( @Composable fun WideLibraryScreenContent( pagerState: PagerState, - categories: ImmutableList>, + categories: ImmutableList, selectedCategoryIndex: Int, displayMode: DisplayMode, gridColumns: Int, @@ -257,7 +256,7 @@ fun WideLibraryScreenContent( @Composable fun ThinLibraryScreenContent( pagerState: PagerState, - categories: ImmutableList>, + categories: ImmutableList, selectedCategoryIndex: Int, displayMode: DisplayMode, gridColumns: Int, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryTabs.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryTabs.kt index a59fcbb9..952f1e27 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryTabs.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/LibraryTabs.kt @@ -19,7 +19,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEachIndexed import ca.gosyer.jui.domain.category.model.Category -import ca.gosyer.jui.ui.base.model.StableHolder import com.google.accompanist.pager.PagerState import com.google.accompanist.pager.pagerTabIndicatorOffset import kotlinx.collections.immutable.ImmutableList @@ -28,7 +27,7 @@ import kotlinx.collections.immutable.ImmutableList fun LibraryTabs( visible: Boolean, pagerState: PagerState, - categories: ImmutableList>, + categories: ImmutableList, selectedPage: Int, onPageChanged: (Int) -> Unit ) { @@ -50,7 +49,7 @@ fun LibraryTabs( ) } ) { - categories.fastForEachIndexed { i, (category) -> + categories.fastForEachIndexed { i, category -> Tab( selected = selectedPage == i, onClick = { onPageChanged(i) }, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaComfortableGrid.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaComfortableGrid.kt index ccbc87e7..8634fe64 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaComfortableGrid.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaComfortableGrid.kt @@ -37,7 +37,6 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import ca.gosyer.jui.domain.manga.model.Manga -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.main.components.bottomNav import ca.gosyer.jui.uicore.components.VerticalScrollbar import ca.gosyer.jui.uicore.components.mangaAspectRatio @@ -49,7 +48,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable fun LibraryMangaComfortableGrid( - library: ImmutableList>, + library: ImmutableList, gridColumns: Int, gridSize: Int, onClickManga: (Long) -> Unit, @@ -76,13 +75,13 @@ fun LibraryMangaComfortableGrid( ) ).asPaddingValues() ) { - items(library) { mangaHolder -> + items(library) { manga -> LibraryMangaComfortableGridItem( modifier = Modifier.libraryMangaModifier( - { onClickManga(mangaHolder.item.id) }, - { onRemoveMangaClicked(mangaHolder.item.id) } + { onClickManga(manga.id) }, + { onRemoveMangaClicked(manga.id) } ), - mangaHolder = mangaHolder, + manga = manga, showUnread = showUnread, showDownloaded = showDownloaded, showLanguage = showLanguage, @@ -109,13 +108,12 @@ fun LibraryMangaComfortableGrid( @Composable private fun LibraryMangaComfortableGridItem( modifier: Modifier, - mangaHolder: StableHolder, + manga: Manga, showUnread: Boolean, showDownloaded: Boolean, showLanguage: Boolean, showLocal: Boolean ) { - val manga = mangaHolder.item val fontStyle = LocalTextStyle.current.merge( TextStyle(letterSpacing = 0.sp, fontFamily = FontFamily.SansSerif, fontSize = 14.sp) ) @@ -146,7 +144,7 @@ private fun LibraryMangaComfortableGridItem( } LibraryMangaBadges( modifier = Modifier.padding(4.dp), - mangaHolder = mangaHolder, + manga = manga, showUnread = showUnread, showDownloaded = showDownloaded, showLanguage = showLanguage, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaCompactGrid.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaCompactGrid.kt index 84ffa10f..af231f54 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaCompactGrid.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaCompactGrid.kt @@ -40,7 +40,6 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import ca.gosyer.jui.domain.manga.model.Manga -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.main.components.bottomNav import ca.gosyer.jui.uicore.components.VerticalScrollbar import ca.gosyer.jui.uicore.components.mangaAspectRatio @@ -57,7 +56,7 @@ expect fun Modifier.libraryMangaModifier( @Composable fun LibraryMangaCompactGrid( - library: ImmutableList>, + library: ImmutableList, gridColumns: Int, gridSize: Int, onClickManga: (Long) -> Unit, @@ -84,13 +83,13 @@ fun LibraryMangaCompactGrid( ) ).asPaddingValues() ) { - items(library) { mangaHolder -> + items(library) { manga -> LibraryMangaCompactGridItem( modifier = Modifier.libraryMangaModifier( - { onClickManga(mangaHolder.item.id) }, - { onRemoveMangaClicked(mangaHolder.item.id) } + { onClickManga(manga.id) }, + { onRemoveMangaClicked(manga.id) } ), - mangaHolder = mangaHolder, + manga = manga, showUnread = showUnread, showDownloaded = showDownloaded, showLanguage = showLanguage, @@ -117,13 +116,12 @@ fun LibraryMangaCompactGrid( @Composable private fun LibraryMangaCompactGridItem( modifier: Modifier, - mangaHolder: StableHolder, + manga: Manga, showUnread: Boolean, showDownloaded: Boolean, showLanguage: Boolean, showLocal: Boolean ) { - val manga = mangaHolder.item val fontStyle = LocalTextStyle.current.merge( TextStyle(letterSpacing = 0.sp, fontFamily = FontFamily.SansSerif, fontSize = 14.sp) ) @@ -151,7 +149,7 @@ private fun LibraryMangaCompactGridItem( ) LibraryMangaBadges( modifier = Modifier.padding(4.dp), - mangaHolder = mangaHolder, + manga = manga, showUnread = showUnread, showDownloaded = showDownloaded, showLanguage = showLanguage, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaCoverOnlyGrid.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaCoverOnlyGrid.kt index 79868bf0..099076ed 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaCoverOnlyGrid.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/library/components/MangaCoverOnlyGrid.kt @@ -31,7 +31,6 @@ import androidx.compose.ui.graphics.FilterQuality import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import ca.gosyer.jui.domain.manga.model.Manga -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.main.components.bottomNav import ca.gosyer.jui.uicore.components.VerticalScrollbar import ca.gosyer.jui.uicore.components.mangaAspectRatio @@ -43,7 +42,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable fun LibraryMangaCoverOnlyGrid( - library: ImmutableList>, + library: ImmutableList, gridColumns: Int, gridSize: Int, onClickManga: (Long) -> Unit, @@ -70,13 +69,13 @@ fun LibraryMangaCoverOnlyGrid( ) ).asPaddingValues() ) { - items(library) { mangaHolder -> + items(library) { manga -> LibraryMangaCoverOnlyGridItem( modifier = Modifier.libraryMangaModifier( - { onClickManga(mangaHolder.item.id) }, - { onRemoveMangaClicked(mangaHolder.item.id) } + { onClickManga(manga.id) }, + { onRemoveMangaClicked(manga.id) } ), - mangaHolder = mangaHolder, + manga = manga, showUnread = showUnread, showDownloaded = showDownloaded, showLanguage = showLanguage, @@ -103,13 +102,12 @@ fun LibraryMangaCoverOnlyGrid( @Composable private fun LibraryMangaCoverOnlyGridItem( modifier: Modifier, - mangaHolder: StableHolder, + manga: Manga, showUnread: Boolean, showDownloaded: Boolean, showLanguage: Boolean, showLocal: Boolean ) { - val manga = mangaHolder.item Box( modifier = Modifier.padding(4.dp) .fillMaxWidth() @@ -125,7 +123,7 @@ private fun LibraryMangaCoverOnlyGridItem( ) LibraryMangaBadges( modifier = Modifier.padding(4.dp), - mangaHolder = mangaHolder, + manga = manga, showUnread = showUnread, showDownloaded = showDownloaded, showLanguage = showLanguage, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/AboutScreen.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/AboutScreen.kt index 0d792ba5..09b51c65 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/AboutScreen.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/AboutScreen.kt @@ -37,7 +37,7 @@ class AboutScreen : Screen { } } AboutContent( - aboutHolder = vm.aboutHolder.collectAsState().value, + about = vm.aboutHolder.collectAsState().value, formattedBuildTime = vm.formattedBuildTime.collectAsState().value, checkForUpdates = vm::checkForUpdates, openSourceLicenses = { diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/AboutViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/AboutViewModel.kt index 0dbe34c8..6af1f311 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/AboutViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/AboutViewModel.kt @@ -11,7 +11,6 @@ import ca.gosyer.jui.domain.settings.interactor.AboutServer import ca.gosyer.jui.domain.settings.model.About import ca.gosyer.jui.domain.updates.interactor.UpdateChecker import ca.gosyer.jui.domain.updates.interactor.UpdateChecker.Update -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.uicore.vm.ContextWrapper import ca.gosyer.jui.uicore.vm.ViewModel import kotlinx.coroutines.flow.MutableSharedFlow @@ -33,10 +32,10 @@ class AboutViewModel @Inject constructor( contextWrapper: ContextWrapper ) : ViewModel(contextWrapper) { - private val _aboutHolder = MutableStateFlow>(StableHolder(null)) + private val _aboutHolder = MutableStateFlow(null) val aboutHolder = _aboutHolder.asStateFlow() - val formattedBuildTime = aboutHolder.map { (about) -> + val formattedBuildTime = aboutHolder.map { about -> about ?: return@map "" getFormattedDate(Instant.fromEpochSeconds(about.buildTime)) }.stateIn(scope, SharingStarted.Eagerly, "") @@ -50,7 +49,7 @@ class AboutViewModel @Inject constructor( private fun getAbout() { scope.launch { - _aboutHolder.value = StableHolder(aboutServer.await()) + _aboutHolder.value = aboutServer.await() } } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/components/AboutContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/components/AboutContent.kt index 902faeba..cc9658e7 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/components/AboutContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/main/about/components/AboutContent.kt @@ -43,7 +43,6 @@ import ca.gosyer.jui.domain.settings.model.About import ca.gosyer.jui.domain.updates.interactor.UpdateChecker import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.presentation.build.BuildKonfig -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.base.navigation.Toolbar import ca.gosyer.jui.ui.base.prefs.PreferenceRow import ca.gosyer.jui.ui.main.components.bottomNav @@ -61,7 +60,7 @@ import dev.icerock.moko.resources.StringResource @Composable fun AboutContent( - aboutHolder: StableHolder, + about: About?, formattedBuildTime: String, checkForUpdates: () -> Unit, openSourceLicenses: () -> Unit @@ -100,7 +99,7 @@ fun AboutContent( ClientVersionInfo() } item { - ServerVersionInfo(aboutHolder, formattedBuildTime) + ServerVersionInfo(about, formattedBuildTime) } item { WhatsNew() @@ -174,8 +173,7 @@ private fun ClientVersionInfo() { } @Composable -private fun ServerVersionInfo(aboutHolder: StableHolder, formattedBuildTime: String) { - val about = aboutHolder.item +private fun ServerVersionInfo(about: About?, formattedBuildTime: String) { if (about == null) { Box(Modifier.fillMaxWidth().height(48.dp), contentAlignment = Alignment.Center) { CircularProgressIndicator() diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreen.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreen.kt index 9671fab7..74081167 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreen.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreen.kt @@ -26,7 +26,7 @@ class MangaScreen(private val mangaId: Long) : Screen { MangaScreenContent( isLoading = vm.isLoading.collectAsState().value, - mangaHolder = vm.manga.collectAsState().value, + manga = vm.manga.collectAsState().value, chapters = vm.chapters.collectAsState().value, dateTimeFormatter = vm.dateTimeFormatter.collectAsState().value, categoriesExist = vm.categoriesExist.collectAsState().value, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreenViewModel.kt index 75db4d68..8216bd21 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/MangaScreenViewModel.kt @@ -73,7 +73,7 @@ class MangaScreenViewModel @Inject constructor( contextWrapper: ContextWrapper, private val params: Params ) : ViewModel(contextWrapper) { - private val _manga = MutableStateFlow>(StableHolder(null)) + private val _manga = MutableStateFlow(null) val manga = _manga.asStateFlow() private val _chapters = MutableStateFlow>(persistentListOf()) @@ -83,11 +83,11 @@ class MangaScreenViewModel @Inject constructor( val isLoading = _isLoading.asStateFlow() val categories = getCategories.asFlow(true) - .map { it.map(::StableHolder).toImmutableList() } + .map { it.toImmutableList() } .catch { log.warn(it) { "Failed to get categories" } } .stateIn(scope, SharingStarted.Eagerly, persistentListOf()) - private val _mangaCategories = MutableStateFlow>>(persistentListOf()) + private val _mangaCategories = MutableStateFlow>(persistentListOf()) val mangaCategories = _mangaCategories.asStateFlow() val categoriesExist = categories.map { it.isNotEmpty() } @@ -143,7 +143,7 @@ class MangaScreenViewModel @Inject constructor( fun setCategories() { scope.launch { - manga.value.item ?: return@launch + manga.value ?: return@launch chooseCategoriesFlow.emit(Unit) } } @@ -156,14 +156,14 @@ class MangaScreenViewModel @Inject constructor( getManga.await(mangaId) } if (manga != null) { - _manga.value = StableHolder(manga) + _manga.value = manga } else { // TODO: 2022-07-01 Error toast } val mangaCategories = getMangaCategories.await(mangaId) if (mangaCategories != null) { - _mangaCategories.value = mangaCategories.map(::StableHolder).toImmutableList() + _mangaCategories.value = mangaCategories.toImmutableList() } else { // TODO: 2022-07-01 Error toast } @@ -187,7 +187,7 @@ class MangaScreenViewModel @Inject constructor( fun toggleFavorite() { scope.launch { - manga.value.item?.let { manga -> + manga.value?.let { manga -> if (manga.inLibrary) { removeMangaFromLibrary.await(manga) refreshMangaAsync(manga.id).await() @@ -204,7 +204,7 @@ class MangaScreenViewModel @Inject constructor( fun addFavorite(categories: List, oldCategories: List) { scope.launch { - manga.value.item?.let { manga -> + manga.value?.let { manga -> if (manga.inLibrary) { oldCategories.filterNot { it in categories }.forEach { removeMangaFromCategory.await(manga, it) @@ -225,7 +225,7 @@ class MangaScreenViewModel @Inject constructor( fun toggleRead(index: Int) { val chapter = findChapter(index) ?: return scope.launch { - manga.value.item?.let { manga -> + manga.value?.let { manga -> updateChapterRead.await(manga, index, read = chapter.read.not()) refreshChaptersAsync(manga.id).await() } @@ -235,7 +235,7 @@ class MangaScreenViewModel @Inject constructor( fun toggleBookmarked(index: Int) { val chapter = findChapter(index) ?: return scope.launch { - manga.value.item?.let { manga -> + manga.value?.let { manga -> updateChapterBookmarked.await(manga, index, bookmarked = chapter.bookmarked.not()) refreshChaptersAsync(manga.id).await() } @@ -244,7 +244,7 @@ class MangaScreenViewModel @Inject constructor( fun markPreviousRead(index: Int) { scope.launch { - manga.value.item?.let { manga -> + manga.value?.let { manga -> updateChapterMarkPreviousRead.await(manga, index) refreshChaptersAsync(manga.id).await() } @@ -252,7 +252,7 @@ class MangaScreenViewModel @Inject constructor( } fun downloadChapter(index: Int) { - manga.value.item?.let { manga -> + manga.value?.let { manga -> scope.launch { queueChapterDownload.await(manga, index) } } } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/components/MangaMenu.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/components/MangaMenu.kt index 426c0adc..172d385a 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/components/MangaMenu.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/components/MangaMenu.kt @@ -37,7 +37,6 @@ import ca.gosyer.jui.domain.category.model.Category import ca.gosyer.jui.domain.manga.model.Manga import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.ui.base.dialog.getMaterialDialogProperties -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.uicore.components.VerticalScrollbar import ca.gosyer.jui.uicore.components.mangaAspectRatio import ca.gosyer.jui.uicore.components.rememberScrollbarAdapter @@ -52,30 +51,29 @@ import com.vanpra.composematerialdialogs.title import kotlinx.collections.immutable.ImmutableList @Composable -fun MangaItem(mangaHolder: StableHolder) { +fun MangaItem(manga: Manga) { BoxWithConstraints(Modifier.padding(8.dp)) { if (maxWidth > 720.dp) { Row { - Cover(mangaHolder, Modifier.width(300.dp)) + Cover(manga, Modifier.width(300.dp)) Spacer(Modifier.width(16.dp)) - MangaInfo(mangaHolder) + MangaInfo(manga) } } else { Column(horizontalAlignment = Alignment.CenterHorizontally) { Cover( - mangaHolder, + manga, Modifier.heightIn(120.dp, 300.dp) ) Spacer(Modifier.height(16.dp)) - MangaInfo(mangaHolder) + MangaInfo(manga) } } } } @Composable -private fun Cover(mangaHolder: StableHolder, modifier: Modifier = Modifier) { - val manga = mangaHolder.item +private fun Cover(manga: Manga, modifier: Modifier = Modifier) { ImageLoaderImage( data = manga, contentDescription = manga.title, @@ -90,8 +88,7 @@ private fun Cover(mangaHolder: StableHolder, modifier: Modifier = Modifie } @Composable -private fun MangaInfo(mangaHolder: StableHolder, modifier: Modifier = Modifier) { - val manga = mangaHolder.item +private fun MangaInfo(manga: Manga, modifier: Modifier = Modifier) { SelectionContainer { Column(modifier) { Text( @@ -165,8 +162,8 @@ private fun Chip(text: String) { @Composable fun CategorySelectDialog( state: MaterialDialogState, - categories: ImmutableList>, - oldCategories: ImmutableList>, + categories: ImmutableList, + oldCategories: ImmutableList, onPositiveClick: (List, List) -> Unit ) { MaterialDialog( @@ -182,13 +179,13 @@ fun CategorySelectDialog( Box { val listState = rememberLazyListState() listItemsMultiChoice( - list = categories.map { it.item.name }, + list = categories.map { it.name }, state = listState, initialSelection = oldCategories.mapNotNull { category -> - categories.indexOfFirst { it.item.id == category.item.id }.takeUnless { it == -1 } + categories.indexOfFirst { it.id == category.id }.takeUnless { it == -1 } }.toSet(), onCheckedChange = { indexes -> - onPositiveClick(indexes.map { categories[it].item }, oldCategories.map { it.item }) + onPositiveClick(indexes.map { categories[it] }, oldCategories) } ) VerticalScrollbar( diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/components/MangaScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/components/MangaScreenContent.kt index e77989b7..d3b59650 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/components/MangaScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/manga/components/MangaScreenContent.kt @@ -61,13 +61,13 @@ import kotlinx.datetime.Instant @Composable fun MangaScreenContent( isLoading: Boolean, - mangaHolder: StableHolder, + manga: Manga?, chapters: ImmutableList, dateTimeFormatter: (Instant) -> String, categoriesExist: Boolean, chooseCategoriesFlowHolder: StableHolder>, - availableCategories: ImmutableList>, - mangaCategories: ImmutableList>, + availableCategories: ImmutableList, + mangaCategories: ImmutableList, addFavorite: (List, List) -> Unit, setCategories: () -> Unit, toggleFavorite: () -> Unit, @@ -100,7 +100,6 @@ fun MangaScreenContent( Toolbar( stringResource(MR.strings.location_manga), actions = { - val manga = mangaHolder.item val uriHandler = LocalUriHandler.current getActionItems( refreshManga = refreshManga, @@ -120,8 +119,8 @@ fun MangaScreenContent( } ) { Box(Modifier.padding(it)) { - mangaHolder.let { mangaHolder -> - if (mangaHolder.item != null) { + manga.let { manga -> + if (manga != null) { Box { val state = rememberLazyListState() LazyColumn( @@ -135,14 +134,14 @@ fun MangaScreenContent( ) { item { @Suppress("UNCHECKED_CAST") - MangaItem(mangaHolder as StableHolder) + MangaItem(manga) } if (chapters.isNotEmpty()) { items(chapters) { chapter -> ChapterItem( chapter, dateTimeFormatter, - onClick = { readerLauncher.launch(it, mangaHolder.item.id) }, + onClick = { readerLauncher.launch(it, manga.id) }, toggleRead = toggleRead, toggleBookmarked = toggleBookmarked, markPreviousAsRead = markPreviousRead, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreen.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreen.kt index fa7bbcdd..d392d57d 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreen.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreen.kt @@ -8,9 +8,7 @@ package ca.gosyer.jui.ui.sources.browse import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.remember import ca.gosyer.jui.domain.source.model.Source -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.manga.MangaScreen import ca.gosyer.jui.ui.sources.browse.components.SourceScreenContent import ca.gosyer.jui.ui.sources.browse.filter.SourceFiltersViewModel @@ -28,7 +26,6 @@ class SourceScreen(val source: Source, private val initialQuery: String? = null) @Composable override fun Content() { - val sourceHolder = remember { StableHolder(source) } val sourceVM = viewModel { sourceViewModel(SourceScreenViewModel.Params(source, initialQuery)) } @@ -38,7 +35,7 @@ class SourceScreen(val source: Source, private val initialQuery: String? = null) val sourcesNavigator = LocalSourcesNavigator.current val navigator = LocalNavigator.currentOrThrow SourceScreenContent( - sourceHolder = sourceHolder, + source = source, onMangaClick = { navigator push MangaScreen(it) }, onCloseSourceTabClick = if (sourcesNavigator != null) { { sourcesNavigator.remove(it) } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreenViewModel.kt index 588295bd..ac3897ae 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/SourceScreenViewModel.kt @@ -13,7 +13,6 @@ import ca.gosyer.jui.domain.source.model.MangaPage import ca.gosyer.jui.domain.source.model.Source import ca.gosyer.jui.domain.source.service.CatalogPreferences import ca.gosyer.jui.domain.source.service.SourceRepository -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.uicore.vm.ContextWrapper import ca.gosyer.jui.uicore.vm.ViewModel import kotlinx.collections.immutable.ImmutableList @@ -58,7 +57,7 @@ class SourceScreenViewModel( val gridColumns = libraryPreferences.gridColumns().stateIn(scope) val gridSize = libraryPreferences.gridSize().stateIn(scope) - private val _mangas = MutableStateFlow>>(persistentListOf()) + private val _mangas = MutableStateFlow>(persistentListOf()) val mangas = _mangas.asStateFlow() private val _hasNextPage = MutableStateFlow(false) @@ -88,7 +87,7 @@ class SourceScreenViewModel( init { scope.launch { getPage()?.let { (mangas, hasNextPage) -> - _mangas.value = mangas.map(::StableHolder).toImmutableList() + _mangas.value = mangas.toImmutableList() _hasNextPage.value = hasNextPage } @@ -102,7 +101,7 @@ class SourceScreenViewModel( _pageNum.value++ val page = getPage() if (page != null) { - _mangas.value = _mangas.value.toPersistentList() + page.mangaList.map(::StableHolder) + _mangas.value = _mangas.value.toPersistentList() + page.mangaList _hasNextPage.value = page.hasNextPage } else { _pageNum.value-- diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaComfortableGrid.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaComfortableGrid.kt index f8af69de..bad2458a 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaComfortableGrid.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaComfortableGrid.kt @@ -39,7 +39,6 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import ca.gosyer.jui.domain.manga.model.Manga -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.main.components.bottomNav import ca.gosyer.jui.uicore.components.VerticalScrollbar import ca.gosyer.jui.uicore.components.mangaAspectRatio @@ -51,7 +50,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable fun SourceMangaComfortableGrid( - mangas: ImmutableList>, + mangas: ImmutableList, gridColumns: Int, gridSize: Int, onClickManga: (Long) -> Unit, @@ -75,16 +74,16 @@ fun SourceMangaComfortableGrid( ) ).asPaddingValues() ) { - itemsIndexed(mangas) { index, mangaHolder -> + itemsIndexed(mangas) { index, manga -> if (hasNextPage && index == mangas.lastIndex) { LaunchedEffect(Unit) { onLoadNextPage() } } SourceMangaComfortableGridItem( modifier = Modifier.clickable( - onClick = { onClickManga(mangaHolder.item.id) } + onClick = { onClickManga(manga.id) } ), - mangaHolder = mangaHolder, - inLibrary = mangaHolder.item.inLibrary + manga = manga, + inLibrary = manga.inLibrary ) } } @@ -107,10 +106,9 @@ fun SourceMangaComfortableGrid( @Composable private fun SourceMangaComfortableGridItem( modifier: Modifier, - mangaHolder: StableHolder, + manga: Manga, inLibrary: Boolean ) { - val manga = mangaHolder.item val fontStyle = LocalTextStyle.current.merge( TextStyle(letterSpacing = 0.sp, fontFamily = FontFamily.SansSerif, fontSize = 14.sp) ) diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaCompactGrid.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaCompactGrid.kt index 1183f0cc..af686c28 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaCompactGrid.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaCompactGrid.kt @@ -42,7 +42,6 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import ca.gosyer.jui.domain.manga.model.Manga -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.main.components.bottomNav import ca.gosyer.jui.uicore.components.VerticalScrollbar import ca.gosyer.jui.uicore.components.mangaAspectRatio @@ -54,7 +53,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable fun SourceMangaCompactGrid( - mangas: ImmutableList>, + mangas: ImmutableList, gridColumns: Int, gridSize: Int, onClickManga: (Long) -> Unit, @@ -78,16 +77,16 @@ fun SourceMangaCompactGrid( ) ).asPaddingValues() ) { - itemsIndexed(mangas) { index, mangaHolder -> + itemsIndexed(mangas) { index, manga -> if (hasNextPage && index == mangas.lastIndex) { LaunchedEffect(Unit) { onLoadNextPage() } } SourceMangaCompactGridItem( modifier = Modifier.clickable( - onClick = { onClickManga(mangaHolder.item.id) } + onClick = { onClickManga(manga.id) } ), - mangaHolder = mangaHolder, - inLibrary = mangaHolder.item.inLibrary + manga = manga, + inLibrary = manga.inLibrary ) } } @@ -110,10 +109,9 @@ fun SourceMangaCompactGrid( @Composable private fun SourceMangaCompactGridItem( modifier: Modifier, - mangaHolder: StableHolder, + manga: Manga, inLibrary: Boolean ) { - val manga = mangaHolder.item val fontStyle = LocalTextStyle.current.merge( TextStyle(letterSpacing = 0.sp, fontFamily = FontFamily.SansSerif, fontSize = 14.sp) ) diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaList.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaList.kt index e16bd91b..89a6807b 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaList.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceMangaList.kt @@ -30,7 +30,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import ca.gosyer.jui.domain.manga.model.Manga -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.main.components.bottomNav import ca.gosyer.jui.uicore.components.MangaListItem import ca.gosyer.jui.uicore.components.MangaListItemImage @@ -43,7 +42,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable fun SourceMangaList( - mangas: ImmutableList>, + mangas: ImmutableList, onClickManga: (Long) -> Unit, hasNextPage: Boolean = false, onLoadNextPage: () -> Unit @@ -59,16 +58,16 @@ fun SourceMangaList( ) ).asPaddingValues() ) { - itemsIndexed(mangas) { index, mangaHolder -> + itemsIndexed(mangas) { index, manga -> if (hasNextPage && index == mangas.lastIndex) { LaunchedEffect(Unit) { onLoadNextPage() } } MangaListItem( modifier = Modifier.clickable( - onClick = { onClickManga(mangaHolder.item.id) } + onClick = { onClickManga(manga.id) } ), - mangaHolder = mangaHolder, - inLibrary = mangaHolder.item.inLibrary + manga = manga, + inLibrary = manga.inLibrary ) } } @@ -91,10 +90,9 @@ fun SourceMangaList( @Composable private fun MangaListItem( modifier: Modifier, - mangaHolder: StableHolder, + manga: Manga, inLibrary: Boolean ) { - val manga = mangaHolder.item MangaListItem( modifier = modifier then Modifier .requiredHeight(56.dp) diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceScreenContent.kt index 7478d9fe..a889836c 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/components/SourceScreenContent.kt @@ -52,7 +52,6 @@ import ca.gosyer.jui.domain.library.model.DisplayMode import ca.gosyer.jui.domain.manga.model.Manga import ca.gosyer.jui.domain.source.model.Source import ca.gosyer.jui.i18n.MR -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.base.navigation.ActionItem import ca.gosyer.jui.ui.base.navigation.BackHandler import ca.gosyer.jui.ui.base.navigation.Toolbar @@ -70,14 +69,14 @@ import kotlinx.collections.immutable.toImmutableList @Composable fun SourceScreenContent( - sourceHolder: StableHolder, + source: Source, onMangaClick: (Long) -> Unit, onCloseSourceTabClick: (Source) -> Unit, onSourceSettingsClick: (Long) -> Unit, displayMode: DisplayMode, gridColumns: Int, gridSize: Int, - mangas: ImmutableList>, + mangas: ImmutableList, hasNextPage: Boolean, loading: Boolean, isLatest: Boolean, @@ -91,13 +90,12 @@ fun SourceScreenContent( setUsingFilters: (Boolean) -> Unit, onSelectDisplayMode: (DisplayMode) -> Unit, // filter - filters: ImmutableList>>, + filters: ImmutableList>, showingFilters: Boolean, showFilterButton: Boolean, setShowingFilters: (Boolean) -> Unit, resetFiltersClicked: () -> Unit ) { - val source = sourceHolder.item LaunchedEffect(source) { enableLatest(source.supportsLatest) } @@ -113,7 +111,7 @@ fun SourceScreenContent( BoxWithConstraints { if (maxWidth > 720.dp) { SourceWideScreenContent( - sourceHolder = sourceHolder, + source = source, onMangaClick = onMangaClick, onCloseSourceTabClick = onCloseSourceTabClick, onSourceSettingsClick = onSourceSettingsClick, @@ -140,7 +138,7 @@ fun SourceScreenContent( ) } else { SourceThinScreenContent( - sourceHolder = sourceHolder, + source = source, onMangaClick = onMangaClick, onCloseSourceTabClick = onCloseSourceTabClick, onSourceSettingsClick = onSourceSettingsClick, @@ -171,14 +169,14 @@ fun SourceScreenContent( @Composable private fun SourceWideScreenContent( - sourceHolder: StableHolder, + source: Source, onMangaClick: (Long) -> Unit, onCloseSourceTabClick: (Source) -> Unit, onSourceSettingsClick: (Long) -> Unit, displayMode: DisplayMode, gridColumns: Int, gridSize: Int, - mangas: ImmutableList>, + mangas: ImmutableList, hasNextPage: Boolean, loading: Boolean, isLatest: Boolean, @@ -190,7 +188,7 @@ private fun SourceWideScreenContent( loadNextPage: () -> Unit, setUsingFilters: (Boolean) -> Unit, // filter - filters: ImmutableList>>, + filters: ImmutableList>, showingFilters: Boolean, showFilterButton: Boolean, setShowingFilters: (Boolean) -> Unit, @@ -205,7 +203,7 @@ private fun SourceWideScreenContent( ), topBar = { SourceToolbar( - sourceHolder = sourceHolder, + source = source, onCloseSourceTabClick = onCloseSourceTabClick, sourceSearchQuery = sourceSearchQuery, onSearch = search, @@ -266,14 +264,14 @@ private fun SourceWideScreenContent( @Composable private fun SourceThinScreenContent( - sourceHolder: StableHolder, + source: Source, onMangaClick: (Long) -> Unit, onCloseSourceTabClick: (Source) -> Unit, onSourceSettingsClick: (Long) -> Unit, displayMode: DisplayMode, gridColumns: Int, gridSize: Int, - mangas: ImmutableList>, + mangas: ImmutableList, hasNextPage: Boolean, loading: Boolean, isLatest: Boolean, @@ -285,7 +283,7 @@ private fun SourceThinScreenContent( loadNextPage: () -> Unit, setUsingFilters: (Boolean) -> Unit, // filter - filters: ImmutableList>>, + filters: ImmutableList>, showingFilters: Boolean, showFilterButton: Boolean, setShowingFilters: (Boolean) -> Unit, @@ -318,7 +316,7 @@ private fun SourceThinScreenContent( ), topBar = { SourceToolbar( - sourceHolder = sourceHolder, + source = source, onCloseSourceTabClick = onCloseSourceTabClick, sourceSearchQuery = sourceSearchQuery, onSearch = search, @@ -410,7 +408,7 @@ private fun SourceThinScreenContent( @Composable fun SourceToolbar( - sourceHolder: StableHolder, + source: Source, onCloseSourceTabClick: (Source) -> Unit, sourceSearchQuery: String?, onSearch: (String) -> Unit, @@ -424,7 +422,6 @@ fun SourceToolbar( onToggleFiltersClick: (Boolean) -> Unit, onSelectDisplayMode: (DisplayMode) -> Unit ) { - val source = sourceHolder.item Toolbar( source.name, closable = true, @@ -490,7 +487,7 @@ private fun MangaTable( displayMode: DisplayMode, gridColumns: Int, gridSize: Int, - mangas: ImmutableList>, + mangas: ImmutableList, isLoading: Boolean = false, hasNextPage: Boolean = false, onLoadNextPage: () -> Unit, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/filter/SourceFiltersMenu.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/filter/SourceFiltersMenu.kt index ba32ab01..c1e5c84d 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/filter/SourceFiltersMenu.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/filter/SourceFiltersMenu.kt @@ -60,7 +60,6 @@ import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastForEachIndexed import ca.gosyer.jui.domain.source.model.sourcefilters.SortFilter import ca.gosyer.jui.i18n.MR -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.base.prefs.ExpandablePreference import ca.gosyer.jui.ui.sources.browse.filter.model.SourceFiltersView import ca.gosyer.jui.uicore.components.Spinner @@ -75,7 +74,7 @@ import kotlinx.coroutines.flow.filterIsInstance @Composable fun SourceFiltersMenu( modifier: Modifier, - filters: ImmutableList>>, + filters: ImmutableList>, onSearchClicked: () -> Unit, resetFiltersClicked: () -> Unit ) { @@ -100,7 +99,7 @@ fun SourceFiltersMenu( val scrollState = rememberScrollState() Column(Modifier.fillMaxSize().verticalScroll(scrollState)) { filters.fastForEach { item -> - item.toView(startExpanded = item.item.index in expandedGroups) { expanded, index -> + item.toView(startExpanded = item.index in expandedGroups) { expanded, index -> if (expanded) { expandedGroups += index } else { @@ -120,32 +119,17 @@ fun SourceFiltersMenu( } } -@Suppress("UNCHECKED_CAST") -@Composable -fun StableHolder>.toView(startExpanded: Boolean = false, onExpandChanged: ((Boolean, Int) -> Unit)? = null) { - when (this.item) { - is SourceFiltersView.CheckBox -> CheckboxView(this as StableHolder) - is SourceFiltersView.Group -> GroupView(this as StableHolder, startExpanded, onExpandChanged) - is SourceFiltersView.Header -> HeaderView(this as StableHolder) - is SourceFiltersView.Select -> SelectView(this as StableHolder) - is SourceFiltersView.Separator -> SeparatorView() - is SourceFiltersView.Sort -> SortView(this as StableHolder, startExpanded, onExpandChanged) - is SourceFiltersView.Text -> TextView(this as StableHolder) - is SourceFiltersView.TriState -> TriStateView(this as StableHolder) - } -} - @Composable fun SourceFiltersView<*, *>.toView(startExpanded: Boolean = false, onExpandChanged: ((Boolean, Int) -> Unit)? = null) { when (this) { - is SourceFiltersView.CheckBox -> CheckboxView(StableHolder(this)) - is SourceFiltersView.Group -> GroupView(StableHolder(this), startExpanded, onExpandChanged) - is SourceFiltersView.Header -> HeaderView(StableHolder(this)) - is SourceFiltersView.Select -> SelectView(StableHolder(this)) + is SourceFiltersView.CheckBox -> CheckboxView(this) + is SourceFiltersView.Group -> GroupView(this, startExpanded, onExpandChanged) + is SourceFiltersView.Header -> HeaderView(this) + is SourceFiltersView.Select -> SelectView(this) is SourceFiltersView.Separator -> SeparatorView() - is SourceFiltersView.Sort -> SortView(StableHolder(this), startExpanded, onExpandChanged) - is SourceFiltersView.Text -> TextView(StableHolder(this)) - is SourceFiltersView.TriState -> TriStateView(StableHolder(this)) + is SourceFiltersView.Sort -> SortView(this, startExpanded, onExpandChanged) + is SourceFiltersView.Text -> TextView(this) + is SourceFiltersView.TriState -> TriStateView(this) } } @@ -175,8 +159,7 @@ fun SourceFilterAction( } @Composable -fun GroupView(groupHolder: StableHolder, startExpanded: Boolean, onExpandChanged: ((Boolean, Int) -> Unit)? = null) { - val group = groupHolder.item +fun GroupView(group: SourceFiltersView.Group, startExpanded: Boolean, onExpandChanged: ((Boolean, Int) -> Unit)? = null) { val state by key(group.hashCode()) { group.state.collectAsState() } ExpandablePreference( title = group.name, @@ -192,8 +175,7 @@ fun GroupView(groupHolder: StableHolder, startExpanded: } @Composable -fun CheckboxView(checkBoxHolder: StableHolder) { - val checkBox = checkBoxHolder.item +fun CheckboxView(checkBox: SourceFiltersView.CheckBox) { val state by key(checkBox.hashCode()) { checkBox.state.collectAsState() } SourceFilterAction( name = checkBox.name, @@ -205,8 +187,7 @@ fun CheckboxView(checkBoxHolder: StableHolder) { } @Composable -fun HeaderView(headerHolder: StableHolder) { - val header = headerHolder.item +fun HeaderView(header: SourceFiltersView.Header) { Box(Modifier.padding(horizontal = 16.dp, vertical = 8.dp).fillMaxWidth()) { Text( text = header.name, @@ -219,8 +200,7 @@ fun HeaderView(headerHolder: StableHolder) { } @Composable -fun SelectView(selectHolder: StableHolder) { - val select = selectHolder.item +fun SelectView(select: SourceFiltersView.Select) { val state by key(select.hashCode()) { select.state.collectAsState() } Row( Modifier.fillMaxWidth().defaultMinSize(minHeight = 56.dp) @@ -279,8 +259,7 @@ fun SortRow(name: String, selected: Boolean, asc: Boolean, onClick: () -> Unit) } @Composable -fun SortView(sortHolder: StableHolder, startExpanded: Boolean, onExpandChanged: ((Boolean, Int) -> Unit)?) { - val sort = sortHolder.item +fun SortView(sort: SourceFiltersView.Sort, startExpanded: Boolean, onExpandChanged: ((Boolean, Int) -> Unit)?) { val state by key(sort.hashCode()) { sort.state.collectAsState() } ExpandablePreference( sort.name, @@ -313,8 +292,7 @@ fun SortView(sortHolder: StableHolder, startExpanded: Bo } @Composable -fun TextView(textHolder: StableHolder) { - val text = textHolder.item +fun TextView(text: SourceFiltersView.Text) { val placeholderText = remember(text) { text.filter.name } val state by key(text.hashCode()) { text.state.collectAsState() } var stateText by remember(text, state) { @@ -350,8 +328,7 @@ fun TextView(textHolder: StableHolder) { } @Composable -fun TriStateView(triStateHolder: StableHolder) { - val triState = triStateHolder.item +fun TriStateView(triState: SourceFiltersView.TriState) { val state by key(triState.hashCode()) { triState.state.collectAsState() } SourceFilterAction( name = triState.name, diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/filter/SourceFiltersViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/filter/SourceFiltersViewModel.kt index f8cb1c92..78c88f0b 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/filter/SourceFiltersViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/browse/filter/SourceFiltersViewModel.kt @@ -9,7 +9,6 @@ package ca.gosyer.jui.ui.sources.browse.filter import ca.gosyer.jui.domain.source.model.sourcefilters.SourceFilter import ca.gosyer.jui.domain.source.model.sourcefilters.SourceFilterChange import ca.gosyer.jui.domain.source.service.SourceRepository -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.sources.browse.filter.model.SourceFiltersView import ca.gosyer.jui.uicore.vm.ContextWrapper import ca.gosyer.jui.uicore.vm.ViewModel @@ -49,7 +48,7 @@ class SourceFiltersViewModel( private val _loading = MutableStateFlow(true) val loading = _loading.asStateFlow() - private val _filters = MutableStateFlow>>>(persistentListOf()) + private val _filters = MutableStateFlow>>(persistentListOf()) val filters = _filters.asStateFlow() private val _showingFilters = MutableStateFlow(false) @@ -64,7 +63,7 @@ class SourceFiltersViewModel( filters.mapLatest { settings -> _filterButtonEnabled.value = settings.isNotEmpty() supervisorScope { - settings.forEach { (filter) -> + settings.forEach { filter -> if (filter is SourceFiltersView.Group) { filter.state.value.forEach { childFilter -> childFilter.state.drop(1) @@ -124,7 +123,7 @@ class SourceFiltersViewModel( private fun List.toView() = mapIndexed { index, sourcePreference -> SourceFiltersView(index, sourcePreference) - }.map(::StableHolder).toImmutableList() + }.toImmutableList() private companion object { private val log = logging() diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/GlobalSearchViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/GlobalSearchViewModel.kt index 5776e18d..9f137495 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/GlobalSearchViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/GlobalSearchViewModel.kt @@ -12,7 +12,6 @@ import ca.gosyer.jui.domain.source.model.Source import ca.gosyer.jui.domain.source.service.CatalogPreferences import ca.gosyer.jui.domain.source.service.SourceRepository import ca.gosyer.jui.i18n.MR -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.uicore.vm.ContextWrapper import ca.gosyer.jui.uicore.vm.ViewModel import kotlinx.collections.immutable.ImmutableList @@ -59,7 +58,7 @@ class GlobalSearchViewModel @Inject constructor( val sources = combine(installedSources, languages) { installedSources, languages -> installedSources.filter { it.lang in languages || it.id == Source.LOCAL_SOURCE_ID - }.map(::StableHolder).toImmutableList() + }.toImmutableList() }.stateIn(scope, SharingStarted.Eagerly, persistentListOf()) private val search = MutableStateFlow(params.initialQuery) @@ -99,7 +98,7 @@ class GlobalSearchViewModel @Inject constructor( .mapLatest { (query, sources) -> results.clear() supervisorScope { - sources.map { (source) -> + sources.map { source -> async { semaphore.withPermit { sourceHandler @@ -108,7 +107,7 @@ class GlobalSearchViewModel @Inject constructor( if (it.mangaList.isEmpty()) { Search.Failure(MR.strings.no_results_found.toPlatformString()) } else { - Search.Success(it.mangaList.map(::StableHolder).toImmutableList()) + Search.Success(it.mangaList.toImmutableList()) } } .catch { @@ -143,7 +142,7 @@ class GlobalSearchViewModel @Inject constructor( sealed class Search { object Searching : Search() - data class Success(val mangaList: ImmutableList>) : Search() + data class Success(val mangaList: ImmutableList) : Search() data class Failure(val e: String?) : Search() { constructor(e: Throwable) : this(e.message) } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchMangaComfortableGrid.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchMangaComfortableGrid.kt index 23bf937a..981270e4 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchMangaComfortableGrid.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchMangaComfortableGrid.kt @@ -26,7 +26,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.times import ca.gosyer.jui.domain.manga.model.Manga -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.sources.browse.components.SourceMangaBadges import ca.gosyer.jui.uicore.components.mangaAspectRatio import ca.gosyer.jui.uicore.image.ImageLoaderImage @@ -34,10 +33,9 @@ import ca.gosyer.jui.uicore.image.ImageLoaderImage @Composable fun GlobalSearchMangaComfortableGridItem( modifier: Modifier, - mangaHolder: StableHolder, + manga: Manga, inLibrary: Boolean ) { - val manga = mangaHolder.item val fontStyle = LocalTextStyle.current.merge( TextStyle(letterSpacing = 0.sp, fontFamily = FontFamily.SansSerif, fontSize = 14.sp) ) diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchMangaCompactGrid.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchMangaCompactGrid.kt index 4430f73a..ef8adff1 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchMangaCompactGrid.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchMangaCompactGrid.kt @@ -29,7 +29,6 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import ca.gosyer.jui.domain.manga.model.Manga -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.sources.browse.components.SourceMangaBadges import ca.gosyer.jui.uicore.components.mangaAspectRatio import ca.gosyer.jui.uicore.image.ImageLoaderImage @@ -37,10 +36,9 @@ import ca.gosyer.jui.uicore.image.ImageLoaderImage @Composable fun GlobalSearchMangaCompactGridItem( modifier: Modifier, - mangaHolder: StableHolder, + manga: Manga, inLibrary: Boolean ) { - val manga = mangaHolder.item val fontStyle = LocalTextStyle.current.merge( TextStyle(letterSpacing = 0.sp, fontFamily = FontFamily.SansSerif, fontSize = 14.sp) ) diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchScreenContent.kt index de5bcf79..06453791 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/globalsearch/components/GlobalSearchScreenContent.kt @@ -47,7 +47,6 @@ import ca.gosyer.jui.domain.manga.model.Manga import ca.gosyer.jui.domain.source.model.Source import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.ui.base.components.localeToString -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.base.navigation.Toolbar import ca.gosyer.jui.ui.main.components.bottomNav import ca.gosyer.jui.ui.sources.globalsearch.GlobalSearchViewModel.Search @@ -63,7 +62,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable fun GlobalSearchScreenContent( - sources: ImmutableList>, + sources: ImmutableList, results: SnapshotStateMap, displayMode: DisplayMode, query: String, @@ -91,17 +90,17 @@ fun GlobalSearchScreenContent( val state = rememberLazyListState() val sourcesSuccess by remember(sources) { derivedStateOf { - sources.filter { results[it.item.id] is Search.Success } + sources.filter { results[it.id] is Search.Success } } } val loadingSources by remember(sources) { derivedStateOf { - sources.filter { results[it.item.id] == null } + sources.filter { results[it.id] == null } } } val failedSources by remember(sources) { derivedStateOf { - sources.filter { results[it.item.id] is Search.Failure } + sources.filter { results[it.id] is Search.Failure } } } LazyColumn( @@ -115,8 +114,8 @@ fun GlobalSearchScreenContent( ) { items(sourcesSuccess) { GlobalSearchItem( - sourceHolder = it, - search = results[it.item.id] ?: Search.Searching, + source = it, + search = results[it.id] ?: Search.Searching, displayMode = displayMode, onSourceClick = onSourceClick, onMangaClick = onMangaClick @@ -124,8 +123,8 @@ fun GlobalSearchScreenContent( } items(loadingSources) { GlobalSearchItem( - sourceHolder = it, - search = results[it.item.id] ?: Search.Searching, + source = it, + search = results[it.id] ?: Search.Searching, displayMode = displayMode, onSourceClick = onSourceClick, onMangaClick = onMangaClick @@ -133,8 +132,8 @@ fun GlobalSearchScreenContent( } items(failedSources) { GlobalSearchItem( - sourceHolder = it, - search = results[it.item.id] ?: Search.Searching, + source = it, + search = results[it.id] ?: Search.Searching, displayMode = displayMode, onSourceClick = onSourceClick, onMangaClick = onMangaClick @@ -160,13 +159,12 @@ fun GlobalSearchScreenContent( @Composable fun GlobalSearchItem( - sourceHolder: StableHolder, + source: Source, search: Search, displayMode: DisplayMode, onSourceClick: (Source) -> Unit, onMangaClick: (Manga) -> Unit ) { - val source = sourceHolder.item Column { Row( Modifier.fillMaxWidth() @@ -209,15 +207,15 @@ fun GlobalSearchItem( items(search.mangaList) { if (displayMode == DisplayMode.ComfortableGrid) { GlobalSearchMangaComfortableGridItem( - Modifier.clickable { onMangaClick(it.item) }, + Modifier.clickable { onMangaClick(it) }, it, - it.item.inLibrary + it.inLibrary ) } else { GlobalSearchMangaCompactGridItem( - Modifier.clickable { onMangaClick(it.item) }, + Modifier.clickable { onMangaClick(it) }, it, - it.item.inLibrary + it.inLibrary ) } } diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/SourceSettingsScreenViewModel.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/SourceSettingsScreenViewModel.kt index 67eae1e3..aa039fe2 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/SourceSettingsScreenViewModel.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/SourceSettingsScreenViewModel.kt @@ -9,7 +9,6 @@ package ca.gosyer.jui.ui.sources.settings import ca.gosyer.jui.domain.source.model.sourcepreference.SourcePreference import ca.gosyer.jui.domain.source.model.sourcepreference.SourcePreferenceChange import ca.gosyer.jui.domain.source.service.SourceRepository -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.sources.settings.model.SourceSettingsView import ca.gosyer.jui.uicore.vm.ContextWrapper import ca.gosyer.jui.uicore.vm.ViewModel @@ -37,14 +36,14 @@ class SourceSettingsScreenViewModel @Inject constructor( private val _loading = MutableStateFlow(true) val loading = _loading.asStateFlow() - private val _sourceSettings = MutableStateFlow>>>(persistentListOf()) + private val _sourceSettings = MutableStateFlow>>(persistentListOf()) val sourceSettings = _sourceSettings.asStateFlow() init { getSourceSettings() sourceSettings.mapLatest { settings -> supervisorScope { - settings.forEach { (setting) -> + settings.forEach { setting -> setting.state.drop(1) .filterNotNull() .onEach { @@ -78,7 +77,7 @@ class SourceSettingsScreenViewModel @Inject constructor( private fun List.toView() = mapIndexed { index, sourcePreference -> SourceSettingsView(index, sourcePreference) - }.map(::StableHolder).toImmutableList() + }.toImmutableList() private companion object { private val log = logging() diff --git a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/components/SourceSettingsScreenContent.kt b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/components/SourceSettingsScreenContent.kt index 687e14c7..ca73557e 100644 --- a/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/components/SourceSettingsScreenContent.kt +++ b/presentation/src/commonMain/kotlin/ca/gosyer/jui/ui/sources/settings/components/SourceSettingsScreenContent.kt @@ -31,7 +31,6 @@ import androidx.compose.ui.Modifier import ca.gosyer.jui.i18n.MR import ca.gosyer.jui.presentation.build.BuildKonfig import ca.gosyer.jui.ui.base.dialog.getMaterialDialogProperties -import ca.gosyer.jui.ui.base.model.StableHolder import ca.gosyer.jui.ui.base.navigation.Toolbar import ca.gosyer.jui.ui.base.prefs.ChoiceDialog import ca.gosyer.jui.ui.base.prefs.MultiSelectDialog @@ -61,7 +60,7 @@ import kotlinx.collections.immutable.ImmutableList @Composable fun SourceSettingsScreenContent( - settings: ImmutableList>> + settings: ImmutableList> ) { Scaffold( modifier = Modifier.windowInsetsPadding( @@ -84,20 +83,20 @@ fun SourceSettingsScreenContent( ) ).asPaddingValues() ) { - items(settings, { it.item.props.hashCode() }) { + items(settings, { it.props.hashCode() }) { @Suppress("UNCHECKED_CAST") - when (it.item) { + when (it) { is CheckBox, is Switch -> { - TwoStatePreference(it as StableHolder, it.item is CheckBox) + TwoStatePreference(it as TwoState, it is CheckBox) } is List -> { - ListPreference(it as StableHolder) + ListPreference(it) } is EditText -> { - EditTextPreference(it as StableHolder) + EditTextPreference(it) } is MultiSelect -> { - MultiSelectPreference(it as StableHolder) + MultiSelectPreference(it) } } } @@ -120,8 +119,7 @@ fun SourceSettingsScreenContent( } @Composable -private fun TwoStatePreference(twoStateHolder: StableHolder, checkbox: Boolean) { - val twoState = twoStateHolder.item +private fun TwoStatePreference(twoState: TwoState, checkbox: Boolean) { val state by twoState.state.collectAsState() val title = remember(state) { twoState.title ?: twoState.summary ?: "No title" } val subtitle = remember(state) { @@ -146,8 +144,7 @@ private fun TwoStatePreference(twoStateHolder: StableHolder, checkbox: } @Composable -private fun ListPreference(listHolder: StableHolder) { - val list = listHolder.item +private fun ListPreference(list: List) { val state by list.state.collectAsState() val title = remember(state) { list.title ?: list.summary ?: "No title" } val subtitle = remember(state) { @@ -175,8 +172,7 @@ private fun ListPreference(listHolder: StableHolder) { } @Composable -private fun MultiSelectPreference(multiSelectHolder: StableHolder) { - val multiSelect = multiSelectHolder.item +private fun MultiSelectPreference(multiSelect: MultiSelect) { val state by multiSelect.state.collectAsState() val title = remember(state) { multiSelect.title ?: multiSelect.summary ?: "No title" } val subtitle = remember(state) { @@ -205,8 +201,7 @@ private fun MultiSelectPreference(multiSelectHolder: StableHolder) } @Composable -private fun EditTextPreference(editTextHolder: StableHolder) { - val editText = editTextHolder.item +private fun EditTextPreference(editText: EditText) { val state by editText.state.collectAsState() val title = remember(state) { editText.title ?: editText.summary ?: "No title" } val subtitle = remember(state) {