diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/CommonOperations.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/CommonOperations.kt index aa620e0ce..de3b9204f 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/CommonOperations.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/CommonOperations.kt @@ -155,12 +155,14 @@ suspend fun DialogState.startDownload( } else { // Let use chose label val list = DownloadManager.labelList - val items = arrayOf( - getString(R.string.default_download_label_name), - *list.map { it.label }.toTypedArray(), - ) + val items = buildList { + add(getString(R.string.default_download_label_name)) + list.forEach { + add(it.label) + } + } val (selected, checked) = showSelectItemWithCheckBox( - *items, + items, title = R.string.download, checkBoxText = R.string.remember_download_label, ) @@ -195,15 +197,17 @@ suspend fun DialogState.modifyFavorites(galleryInfo: BaseGalleryInfo): Boolean { val localFav = getFavoriteIcon(localFavorited) to appCtx.getString(R.string.local_favorites) val cloudFav = Settings.favCat.mapIndexed { index, name -> getFavoriteIcon(galleryInfo.favoriteSlot == index) to name - }.toTypedArray() - val items = if (isFavorited) { - val remove = Icons.Default.HeartBroken to appCtx.getString(R.string.remove_from_favourites) - arrayOf(remove, localFav, *cloudFav) - } else { - arrayOf(localFav, *cloudFav) + } + val items = buildList { + if (isFavorited) { + val remove = Icons.Default.HeartBroken to appCtx.getString(R.string.remove_from_favourites) + add(remove) + } + add(localFav) + addAll(cloudFav) } val (slot, note) = showSelectItemWithIconAndTextField( - *items, + items, title = R.string.add_favorites_dialog_title, hint = R.string.favorite_note, maxChar = MAX_FAVNOTE_CHAR, @@ -279,23 +283,26 @@ fun Context.navToReader(info: BaseGalleryInfo, page: Int = -1) { suspend fun DialogState.doGalleryInfoAction(info: BaseGalleryInfo, context: Context) { val downloaded = DownloadManager.getDownloadState(info.gid) != DownloadInfo.STATE_INVALID - val favourite = info.favoriteSlot != NOT_FAVORITED - val selected = if (!downloaded) { - showSelectItemWithIcon( - Icons.AutoMirrored.Default.MenuBook to R.string.read, - Icons.Default.Download to R.string.download, - if (!favourite) Icons.Default.Favorite to R.string.add_to_favourites else Icons.Default.HeartBroken to R.string.remove_from_favourites, - title = EhUtils.getSuitableTitle(info), - ) - } else { - showSelectItemWithIcon( - Icons.AutoMirrored.Default.MenuBook to R.string.read, - Icons.Default.Delete to R.string.delete_downloads, - if (!favourite) Icons.Default.Favorite to R.string.add_to_favourites else Icons.Default.HeartBroken to R.string.remove_from_favourites, - Icons.AutoMirrored.Default.DriveFileMove to R.string.download_move_dialog_title, - title = EhUtils.getSuitableTitle(info), - ) + val favorited = info.favoriteSlot != NOT_FAVORITED + val items = buildList { + add(Icons.AutoMirrored.Default.MenuBook to R.string.read) + val download = if (downloaded) { + Icons.Default.Delete to R.string.delete_downloads + } else { + Icons.Default.Download to R.string.download + } + add(download) + val favorite = if (favorited) { + Icons.Default.HeartBroken to R.string.remove_from_favourites + } else { + Icons.Default.Favorite to R.string.add_to_favourites + } + add(favorite) + if (downloaded) { + add(Icons.AutoMirrored.Default.DriveFileMove to R.string.download_move_dialog_title) + } } + val selected = showSelectItemWithIcon(items, EhUtils.getSuitableTitle(info)) with(context.findActivity()) { when (selected) { 0 -> navToReader(info) @@ -307,7 +314,7 @@ suspend fun DialogState.doGalleryInfoAction(info: BaseGalleryInfo, context: Cont } } - 2 -> if (favourite) { + 2 -> if (favorited) { runSuspendCatching { removeFromFavorites(info) showTip(R.string.remove_from_favorite_success) @@ -397,18 +404,28 @@ suspend fun DialogState.confirmRemoveDownloadRange(list: Collection): String? { val defaultLabel = appCtx.getString(R.string.default_download_label_name) - val labels = DownloadManager.labelList.map { it.label }.toTypedArray() - val selected = showSelectItem(defaultLabel, *labels, title = R.string.download_move_dialog_title) - val label = if (selected == 0) null else labels[selected - 1] + val labels = buildList { + add(defaultLabel) + DownloadManager.labelList.forEach { + add(it.label) + } + } + val selected = showSelectItem(labels, R.string.download_move_dialog_title) + val label = if (selected == 0) null else labels[selected] withUIContext { DownloadManager.changeLabel(list, label) } return label } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/SearchFilter.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/SearchFilter.kt index bf54916a2..7714c661b 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/main/SearchFilter.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/main/SearchFilter.kt @@ -88,7 +88,7 @@ fun SearchFilter( it } } - }.toTypedArray() + } } Row( modifier = Modifier.horizontalScroll(rememberScrollState()).padding(horizontal = 16.dp, vertical = 8.dp), @@ -100,7 +100,11 @@ fun SearchFilter( selected = languageFilter != -1, onClick = { scope.launch { - languageFilter = dialogState.showSingleChoice(any, *languages, selected = languageFilter + 1) - 1 + val items = buildList { + add(any) + addAll(languages) + } + languageFilter = dialogState.showSingleChoice(items, languageFilter + 1) - 1 } }, label = { @@ -201,7 +205,7 @@ fun SearchFilter( selected = advancedOption.minRating != 0, onClick = { scope.launch { - val selected = dialogState.showSingleChoice(*minRatingItems, selected = minRatingIndex) + val selected = dialogState.showSingleChoice(minRatingItems.toList(), minRatingIndex) onAdvancedOptionChanged(advancedOption.copy(minRating = if (selected == 0) 0 else selected + 1)) } }, diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsScreen.kt index 3d6298cfe..122715e74 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/DownloadsScreen.kt @@ -347,7 +347,7 @@ fun DownloadsScreen(navigator: DestinationsNavigator) { onClick = { expanded = false coroutineScope.launch { - filterType = dialogState.showSingleChoice(*states, selected = filterType + 1) - 1 + filterType = dialogState.showSingleChoice(states.toList(), filterType + 1) - 1 } }, ) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/FavoritesScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/FavoritesScreen.kt index b70077944..c1825cab6 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/FavoritesScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/FavoritesScreen.kt @@ -371,12 +371,13 @@ fun FavouritesScreen(navigator: DestinationsNavigator) { } onClick(Icons.AutoMirrored.Default.DriveFileMove) { // First is local favorite, the other 10 is cloud favorite - val array = if (EhCookieStore.hasSignedIn()) { - arrayOf(localFavName, *Settings.favCat) - } else { - arrayOf(localFavName) + val items = buildList { + add(localFavName) + if (EhCookieStore.hasSignedIn()) { + addAll(Settings.favCat) + } } - val index = dialogState.showSelectItem(*array, title = R.string.move_favorites_dialog_title) + val index = dialogState.showSelectItem(items, R.string.move_favorites_dialog_title) val srcCat = urlBuilder.favCat val dstCat = if (index == 0) FavListUrlBuilder.FAV_CAT_LOCAL else index - 1 val info = checkedInfoMap.run { toMap().values.also { clear() } } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailScreen.kt index f0be0f80f..885635a4b 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/screen/GalleryDetailScreen.kt @@ -536,16 +536,13 @@ fun GalleryDetailScreen(args: GalleryDetailScreenArgs, navigator: DestinationsNa } suspend fun showNewerVersionDialog() { val items = galleryDetail.newerVersions.map { - context.getString( - R.string.newer_version_title, - it.title, - it.posted, - ) to { - navigator.navigate(GalleryDetailScreenDestination(TokenArgs(it.gid, it.token!!))) - } - }.toTypedArray() - val navAction = dialogState.showSelectItem(*items) - withUIContext { navAction.invoke() } + context.getString(R.string.newer_version_title, it.title, it.posted) + } + val selected = dialogState.showSelectItem(items) + val info = galleryDetail.newerVersions[selected] + withUIContext { + navigator.navigate(GalleryDetailScreenDestination(GalleryInfoArgs(info))) + } } Spacer(modifier = Modifier.size(dimensionResource(id = R.dimen.keyline_margin))) if (galleryDetail.newerVersions.isNotEmpty()) { diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt index 29784dbb2..3e0938699 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/settings/EhScreen.kt @@ -233,12 +233,14 @@ fun EhScreen(navigator: DestinationsNavigator) { summary = summary, ) { coroutineScope.launch { - defaultFavSlot = dialogState.showSelectItem( - disabled, - localFav, - *Settings.favCat.takeIf { signin } ?: emptyArray(), - title = R.string.default_favorites_collection, - ) - 2 + val items = buildList { + add(disabled) + add(localFav) + if (signin) { + addAll(Settings.favCat) + } + } + defaultFavSlot = dialogState.showSelectItem(items, R.string.default_favorites_collection) - 2 } } SimpleMenuPreferenceInt( diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/Dialog.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/Dialog.kt index 1cd168fb9..1051005ef 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/Dialog.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/tools/Dialog.kt @@ -405,7 +405,7 @@ class DialogState { } suspend fun showSingleChoice( - vararg items: String, + items: List, selected: Int, ): Int = showNoButton { Column(modifier = Modifier.verticalScroll(rememberScrollState()).padding(vertical = 8.dp)) { @@ -423,17 +423,9 @@ class DialogState { } suspend fun showSelectItem( - vararg items: String?, - @StringRes title: Int, - ) = showSelectItem( - *items.filterNotNull().mapIndexed { a, b -> b to a }.toTypedArray(), - title = title, - ) - - suspend fun showSelectItem( - vararg items: Pair, + items: List, @StringRes title: Int? = null, - ): R = showNoButton { + ): Int = showNoButton { Column(modifier = Modifier.padding(vertical = 8.dp)) { if (title != null) { Text( @@ -443,11 +435,11 @@ class DialogState { ) } LazyColumn { - items(items) { (text, item) -> + itemsIndexed(items) { index, text -> CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.tertiary) { Text( text = text, - modifier = Modifier.clickable { dismissWith(item) }.fillMaxWidth() + modifier = Modifier.clickable { dismissWith(index) }.fillMaxWidth() .padding(horizontal = 24.dp, vertical = 16.dp), style = MaterialTheme.typography.titleMedium, ) @@ -460,26 +452,17 @@ class DialogState { suspend inline fun showSelectActions( @StringRes title: Int? = null, builder: ActionScope.() -> Unit, - ) = showSelectItem( - *buildList { builder(ActionScope { action, that -> add(action to that) }) }.toTypedArray(), - title = title, - ).invoke() + ) { + val (items, actions) = buildList { builder(ActionScope { action, that -> add(action to that) }) }.unzip() + val selected = showSelectItem(items, title) + actions[selected].invoke() + } suspend fun showSelectItemWithCheckBox( - vararg items: String?, + items: List, @StringRes title: Int, @StringRes checkBoxText: Int, - ) = showSelectItemWithCheckBox( - *items.filterNotNull().mapIndexed { a, b -> b to a }.toTypedArray(), - title = title, - checkBoxText = checkBoxText, - ) - - private suspend fun showSelectItemWithCheckBox( - vararg items: Pair, - @StringRes title: Int, - @StringRes checkBoxText: Int, - ): Pair = showNoButton { + ): Pair = showNoButton { var checked by remember { mutableStateOf(false) } Column(modifier = Modifier.padding(vertical = 8.dp)) { Text( @@ -488,11 +471,11 @@ class DialogState { style = MaterialTheme.typography.headlineSmall, ) LazyColumn { - items(items) { (text, item) -> + itemsIndexed(items) { index, text -> CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.tertiary) { Text( text = text, - modifier = Modifier.clickable { dismissWith(item to checked) }.fillMaxWidth() + modifier = Modifier.clickable { dismissWith(index to checked) }.fillMaxWidth() .padding(horizontal = 24.dp, vertical = 16.dp), style = MaterialTheme.typography.titleMedium, ) @@ -509,7 +492,7 @@ class DialogState { } suspend fun showSelectItemWithIcon( - vararg items: Pair, + items: List>, title: String, ): Int = showNoButton { LazyColumn { @@ -531,7 +514,7 @@ class DialogState { } suspend fun showSelectItemWithIconAndTextField( - vararg items: Pair, + items: List>, @StringRes title: Int, @StringRes hint: Int, maxChar: Int,