修复一些问题

This commit is contained in:
HapeLee
2026-05-24 02:39:59 +08:00
parent 5b59b5a743
commit 7b32cb732f
13 changed files with 194 additions and 206 deletions
@@ -274,6 +274,7 @@ object PreferKey {
const val bookshelfGroupListStyle = "bookshelfGroupListStyle"
const val bookshelfGroupCoverCount = "bookshelfGroupCoverCount"
const val bookshelfListCoverWidth = "bookshelfListCoverWidth"
const val bookshelfGridCoverWidth = "bookshelfGridCoverWidth"
const val exploreLayoutGridLandscape = "exploreLayoutGridLandscape"
@@ -13,7 +13,6 @@ import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar
import androidx.core.os.bundleOf
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle.State.STARTED
import androidx.lifecycle.lifecycleScope
@@ -34,6 +33,7 @@ import io.legado.app.help.config.AppConfig
import io.legado.app.lib.dialogs.alert
import io.legado.app.model.ReadBook
import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.book.search.SearchScope
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.ui.book.source.manage.BookSourceActivity
import io.legado.app.ui.widget.dialog.WaitDialog
@@ -83,14 +83,15 @@ class ChangeBookSourceDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_b
private var currentSelectedSearchBook: SearchBook? = null
private val searchFinishCallback: (isEmpty: Boolean) -> Unit = {
if (it) {
val searchGroup = AppConfig.searchGroup
if (searchGroup.isNotEmpty()) {
val searchScope = SearchScope(ChangeSourceConfig.searchScope)
val group = searchScope.display
if (!searchScope.isAll()) {
lifecycleScope.launch {
context?.alert("搜索结果为空") {
setMessage("${searchGroup}分组搜索结果为空,是否切换到全部分组")
setMessage("${group}分组搜索结果为空,是否切换到全部分组")
cancelButton()
okButton {
AppConfig.searchGroup = ""
ChangeSourceConfig.searchScope = ""
upGroupMenuName()
viewModel.startSearch()
}
@@ -343,9 +344,9 @@ class ChangeBookSourceDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_b
else -> if (item?.groupId == R.id.source_group && !item.isChecked) {
item.isChecked = true
if (item.title.toString() == getString(R.string.all_source)) {
AppConfig.searchGroup = ""
ChangeSourceConfig.searchScope = ""
} else {
AppConfig.searchGroup = item.title.toString()
ChangeSourceConfig.searchScope = item.title.toString()
}
upGroupMenuName()
lifecycleScope.launch(IO) {
@@ -493,7 +494,8 @@ class ChangeBookSourceDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_b
private fun upGroupMenu() {
binding.toolBar.menu.findItem(R.id.menu_group)?.run {
subMenu?.transaction { menu ->
val selectedGroup = AppConfig.searchGroup
val searchScope = SearchScope(ChangeSourceConfig.searchScope)
val selectedGroup = searchScope.displayNames.firstOrNull() ?: ""
menu.removeGroup(R.id.source_group)
val allItem = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, R.string.all_source)
var hasSelectedGroup = false
@@ -507,7 +509,7 @@ class ChangeBookSourceDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_b
}
menu.setGroupCheckable(R.id.source_group, true, true)
if (hasSelectedGroup) {
title = getString(R.string.group) + "(" + AppConfig.searchGroup + ")"
title = getString(R.string.group) + "(" + selectedGroup + ")"
} else {
allItem.isChecked = true
title = getString(R.string.group)
@@ -521,11 +523,11 @@ class ChangeBookSourceDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_b
*/
private fun upGroupMenuName() {
val menuGroup = binding.toolBar.menu.findItem(R.id.menu_group)
val searchGroup = AppConfig.searchGroup
if (searchGroup.isEmpty()) {
val searchScope = SearchScope(ChangeSourceConfig.searchScope)
if (searchScope.isAll()) {
menuGroup?.title = getString(R.string.group)
} else {
menuGroup?.title = getString(R.string.group) + "($searchGroup)"
menuGroup?.title = getString(R.string.group) + "(${searchScope.display})"
}
}
@@ -38,7 +38,6 @@ import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.delay
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -411,25 +410,24 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
}
private fun getDbSearchBooks(): List<SearchBook> {
val searchScope = io.legado.app.ui.book.search.SearchScope(
ChangeSourceConfig.searchScope
)
val group = when {
searchScope.isAll() || searchScope.isSource() -> ""
else -> searchScope.displayNames.firstOrNull() ?: ""
}
return if (screenKey.isEmpty()) {
if (AppConfig.changeSourceCheckAuthor) {
appDb.searchBookDao.changeSourceByGroup(
name, author, AppConfig.searchGroup
)
appDb.searchBookDao.changeSourceByGroup(name, author, group)
} else {
appDb.searchBookDao.changeSourceByGroup(
name, "", AppConfig.searchGroup
)
appDb.searchBookDao.changeSourceByGroup(name, "", group)
}
} else {
if (AppConfig.changeSourceCheckAuthor) {
appDb.searchBookDao.changeSourceSearch(
name, author, screenKey, AppConfig.searchGroup
)
appDb.searchBookDao.changeSourceSearch(name, author, screenKey, group)
} else {
appDb.searchBookDao.changeSourceSearch(
name, "", screenKey, AppConfig.searchGroup
)
appDb.searchBookDao.changeSourceSearch(name, "", screenKey, group)
}
}
}
@@ -1,5 +1,6 @@
package io.legado.app.ui.book.changesource
//import io.legado.app.lib.theme.primaryColor
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
@@ -13,7 +14,6 @@ import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle.State.STARTED
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
@@ -29,8 +29,8 @@ import io.legado.app.databinding.DialogChapterChangeSourceBinding
import io.legado.app.help.book.BookHelp
import io.legado.app.help.config.AppConfig
import io.legado.app.lib.dialogs.alert
//import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.book.search.SearchScope
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.ui.book.source.manage.BookSourceActivity
import io.legado.app.ui.widget.recycler.VerticalDivider
@@ -88,14 +88,15 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
private var searchBook: SearchBook? = null
private val searchFinishCallback: (isEmpty: Boolean) -> Unit = {
if (it) {
val searchGroup = AppConfig.searchGroup
if (searchGroup.isNotEmpty()) {
val searchScope = SearchScope(ChangeSourceConfig.searchScope)
val group = searchScope.display
if (!searchScope.isAll()) {
lifecycleScope.launch {
context?.alert("搜索结果为空") {
setMessage("${searchGroup}分组搜索结果为空,是否切换到全部分组")
setMessage("${group}分组搜索结果为空,是否切换到全部分组")
noButton()
yesButton {
AppConfig.searchGroup = ""
ChangeSourceConfig.searchScope = ""
upGroupMenu()
viewModel.startSearch()
}
@@ -282,9 +283,9 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
else -> if (item?.groupId == R.id.source_group && !item.isChecked) {
item.isChecked = true
if (item.title.toString() == getString(R.string.all_source)) {
AppConfig.searchGroup = ""
ChangeSourceConfig.searchScope = ""
} else {
AppConfig.searchGroup = item.title.toString()
ChangeSourceConfig.searchScope = item.title.toString()
}
lifecycleScope.launch(IO) {
viewModel.stopSearch()
@@ -380,7 +381,8 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
*/
private fun upGroupMenu() {
binding.toolBar.menu.findItem(R.id.menu_group)?.subMenu?.transaction { menu ->
val selectedGroup = AppConfig.searchGroup
val searchScope = SearchScope(ChangeSourceConfig.searchScope)
val selectedGroup = searchScope.displayNames.firstOrNull() ?: ""
menu.removeGroup(R.id.source_group)
val allItem = menu.add(R.id.source_group, Menu.NONE, Menu.NONE, R.string.all_source)
var hasSelectedGroup = false
@@ -6,11 +6,6 @@ import io.legado.app.ui.config.prefDelegate
object ChangeSourceConfig {
var searchGroup by prefDelegate(
key = "searchGroup",
defaultValue = ""
)
var searchScope by prefDelegate(
key = "changeSourceSearchScope",
defaultValue = ""
@@ -35,8 +35,6 @@ import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Share
import androidx.compose.material.icons.filled.Timeline
import androidx.compose.material.icons.outlined.Book
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.ExtendedFloatingActionButton
@@ -938,16 +936,12 @@ private fun BookInfoSummary(
}
Spacer(modifier = Modifier.height(4.dp))
book.remark?.takeIf { it.isNotBlank() }?.let { remark ->
ElevatedCard(
GlassCard(
modifier = Modifier.fillMaxWidth(),
onClick = onRemarkClick,
colors = CardDefaults.elevatedCardColors(
containerColor = LegadoTheme.colorScheme.surfaceContainerHigh,
contentColor = LegadoTheme.colorScheme.onSurface,
)
containerColor = LegadoTheme.colorScheme.surfaceContainerLow,
) {
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(4.dp)) {
AppText(text = stringResource(R.string.book_remark), style = LegadoTheme.typography.titleSmall)
AppText(text = remark, style = LegadoTheme.typography.labelMediumEmphasized)
}
}
@@ -760,7 +760,7 @@ fun ChapterItem(
text = item.title,
style = LegadoTheme.typography.bodyMediumEmphasized.copy(fontWeight = FontWeight.Medium),
color = textColor,
maxLines = 1,
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
}
@@ -779,7 +779,7 @@ fun ChapterItem(
val showStatusIcon =
remember(item.isDur, item.downloadState, item.wordCount, showWordCount) {
if (item.downloadState == DownloadState.LOCAL) {
showWordCount && !item.wordCount.isNullOrEmpty()
item.isDur || (showWordCount && !item.wordCount.isNullOrEmpty())
} else {
true
}
@@ -888,15 +888,12 @@ private fun StatusIcon(
) {
val targetState = when {
downloadState == DownloadState.LOCAL -> {
if (showWordCount && !wordCount.isNullOrEmpty()) "SUCCESS_WORD_COUNT" else "EMPTY"
}
showWordCount && !wordCount.isNullOrEmpty() && (downloadState == DownloadState.LOCAL || downloadState == DownloadState.SUCCESS) -> "SUCCESS_WORD_COUNT"
isDur -> "DUR"
downloadState == DownloadState.DOWNLOADING -> "LOADING"
downloadState == DownloadState.SUCCESS && showWordCount && !wordCount.isNullOrEmpty() -> "SUCCESS_WORD_COUNT"
downloadState == DownloadState.SUCCESS -> "SUCCESS_ICON"
downloadState == DownloadState.ERROR -> "ERROR"
downloadState == DownloadState.LOCAL -> "EMPTY"
else -> "NONE"
}
@@ -933,7 +930,7 @@ private fun StatusIcon(
"SUCCESS_WORD_COUNT" -> {
NormalCard(
cornerRadius = 12.dp,
containerColor = LegadoTheme.colorScheme.surfaceContainer
containerColor = if (isDur) LegadoTheme.colorScheme.primaryContainer else LegadoTheme.colorScheme.surfaceContainer
) {
if (wordCount != null) {
AppText(
@@ -941,7 +938,7 @@ private fun StatusIcon(
.padding(horizontal = 8.dp, vertical = 4.dp),
text = wordCount,
style = LegadoTheme.typography.labelSmall.copy(fontSize = 9.sp),
color = LegadoTheme.colorScheme.onSurfaceVariant
color = if (isDur) LegadoTheme.colorScheme.onPrimaryContainer else LegadoTheme.colorScheme.onSurfaceVariant
)
}
}
@@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
@@ -23,6 +24,9 @@ import androidx.compose.foundation.lazy.staggeredgrid.itemsIndexed
import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowForward
import androidx.compose.material.icons.filled.GridView
@@ -33,6 +37,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
@@ -227,14 +232,24 @@ fun HomepageScreen(
data = errorMsg,
onDismissRequest = { errorMsg = null },
title = stringResource(R.string.homepage_module_error),
text = errorMsg,
confirmText = stringResource(R.string.copy_text),
onConfirm = {
context.sendToClip(it)
errorMsg = null
},
dismissText = stringResource(R.string.close),
onDismiss = { errorMsg = null }
onDismiss = { errorMsg = null },
content = { msg ->
SelectionContainer {
Text(
text = msg,
style = LegadoTheme.typography.bodyMedium,
modifier = Modifier
.heightIn(max = 400.dp)
.verticalScroll(rememberScrollState())
)
}
}
)
HomepageModuleManageSheet(
@@ -7,11 +7,16 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -52,14 +57,24 @@ fun LoadMoreFooter(
data = showFullError,
onDismissRequest = { showFullError = null },
title = "错误详情",
textProvider = { this },
confirmText = "复制",
onConfirm = { error ->
context.sendToClip(error)
showFullError = null
},
dismissText = "关闭",
onDismiss = { showFullError = null }
onDismiss = { showFullError = null },
content = { error ->
SelectionContainer {
Text(
text = error,
style = LegadoTheme.typography.bodyMedium,
modifier = Modifier
.heightIn(max = 400.dp)
.verticalScroll(rememberScrollState())
)
}
}
)
Box(
@@ -12,8 +12,12 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
@@ -55,12 +59,14 @@ fun SearchBar(
val textFieldState = rememberTextFieldState(initialText = query)
val focusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current
var hasFocused by rememberSaveable { mutableStateOf(false) }
LaunchedEffect(autoFocus) {
if (autoFocus) {
if (autoFocus && !hasFocused) {
focusRequester.requestFocus()
// 某些情况下需要手动调用 show() 确保键盘弹出
keyboardController?.show()
hasFocused = true
}
}
@@ -54,6 +54,7 @@ fun AppAlertDialog(
modifier = Modifier
.fillMaxWidth()
.padding(top = 12.dp)
.verticalScroll(rememberScrollState())
) {
content()
}
@@ -13,6 +13,7 @@ import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.domain.usecase.ExploreKindUiUseCase
import io.legado.app.help.source.getExploreInfoMap
import io.legado.app.utils.InfoMap
import io.legado.app.utils.showDialogFragment
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
@@ -68,6 +69,10 @@ class ExploreKindItemState(
?: kind.title
}
}
fun showError(error: String) {
activity?.showDialogFragment(io.legado.app.ui.widget.dialog.TextDialog("ERROR", error))
}
}
@Composable
@@ -1,9 +1,14 @@
package io.legado.app.ui.widget.components.explore
import android.content.Context
import android.content.ContextWrapper
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.Refresh
@@ -18,17 +23,19 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.domain.usecase.ExploreKindUiUseCase
import io.legado.app.ui.theme.LegadoTheme
import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.icon.AppIcon
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.showDialogFragment
import io.legado.app.ui.widget.components.text.AppText
import io.legado.app.utils.sendToClip
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -52,84 +59,55 @@ fun ExploreKindMultiTypeItem(
onClick: (() -> Unit)? = null,
content: (@Composable (displayName: String, isSelected: Boolean, onClick: () -> Unit, trailingIcon: @Composable (() -> Unit)?) -> Unit)? = null
) {
val state = rememberExploreKindItemState(kind, sourceUrl, useCase, activity, onRefreshKinds)
val context = LocalContext.current
val currentActivity = remember(context, activity) { activity ?: context.findActivity() }
val state =
rememberExploreKindItemState(kind, sourceUrl, useCase, currentActivity, onRefreshKinds)
state.ResolveDisplayName(displayNameOverride)
var showFullError by remember { mutableStateOf<String?>(null) }
val errorMsg = remember(kind) { kind.errorMsg }
val trailingIcon = rememberTrailingIcon(kind.type, isSelected)
if (onClick != null) {
val BaseItem = @Composable { text: String, click: () -> Unit ->
if (content != null) {
content(state.displayName, isSelected, onClick, trailingIcon)
content(text, isSelected, click, trailingIcon)
} else {
ExploreKindItem(
kind = kind,
isClickable = true,
onClick = onClick,
onClick = click,
modifier = modifier,
backgroundColor = backgroundColor,
isMiuix = isMiuix,
displayText = state.displayName,
displayText = text,
isSelected = isSelected,
trailingIcon = trailingIcon
)
}
return
}
when (kind.type) {
ExploreKind.Type.url -> {
val url = kind.url?.takeIf { it.isNotBlank() }
val internalOnClick = {
if (!url.isNullOrBlank()) {
if (kind.title.startsWith("ERROR:")) {
activity?.showDialogFragment(TextDialog("ERROR", url))
} else {
onOpenUrl(url)
}
when {
errorMsg != null -> BaseItem(state.displayName) { showFullError = errorMsg }
onClick != null -> BaseItem(state.displayName, onClick)
else -> when (kind.type) {
ExploreKind.Type.url -> {
val url = kind.url?.takeIf { it.isNotBlank() }
BaseItem(state.displayName) {
if (!url.isNullOrBlank()) onOpenUrl(url)
}
}
if (content != null) {
content(state.displayName, isSelected, internalOnClick, trailingIcon)
} else {
ExploreKindItem(
kind = kind,
isClickable = !url.isNullOrBlank(),
onClick = internalOnClick,
modifier = modifier,
backgroundColor = backgroundColor,
isMiuix = isMiuix,
displayText = state.displayName,
isSelected = isSelected
)
}
}
ExploreKind.Type.button -> {
val internalOnClick = {
if (onRunAction != null) onRunAction()
else state.executeAction(kind.action)
ExploreKind.Type.button -> {
BaseItem(state.displayName) {
if (onRunAction != null) onRunAction()
else state.executeAction(kind.action)
}
}
if (content != null) {
content(state.displayName, isSelected, internalOnClick, trailingIcon)
} else {
ExploreKindItem(
kind = kind,
isClickable = !kind.action.isNullOrBlank(),
onClick = internalOnClick,
modifier = modifier,
backgroundColor = backgroundColor,
isMiuix = isMiuix,
displayText = state.displayName,
isSelected = isSelected,
trailingIcon = trailingIcon
)
}
}
ExploreKind.Type.text -> {
if (content != null) {
content(state.displayName, isSelected, {}, null)
} else {
ExploreKind.Type.text -> {
TextTypeItem(
kind,
sourceUrl,
@@ -140,56 +118,73 @@ fun ExploreKindMultiTypeItem(
backgroundColor
)
}
}
ExploreKind.Type.toggle -> {
ToggleTypeItem(
kind,
sourceUrl,
state,
valueOverride,
onValueChange,
isSelected,
modifier,
backgroundColor,
isMiuix,
trailingIcon,
content
)
}
ExploreKind.Type.toggle -> {
ToggleTypeItem(kind, sourceUrl, state, valueOverride, onValueChange, BaseItem)
}
ExploreKind.Type.select -> {
SelectTypeItem(
kind,
sourceUrl,
state,
valueOverride,
onValueChange,
isSelected,
modifier,
backgroundColor,
isMiuix,
trailingIcon,
content
)
}
ExploreKind.Type.select -> {
SelectTypeItem(kind, sourceUrl, state, valueOverride, onValueChange, BaseItem)
}
else -> {
if (content != null) {
content(state.displayName, isSelected, {}, null)
} else {
ExploreKindItem(
kind = kind,
isClickable = false,
onClick = {},
modifier = modifier,
backgroundColor = backgroundColor,
isMiuix = isMiuix,
displayText = state.displayName
)
else -> {
if (content != null) {
content(state.displayName, isSelected, {}, null)
} else {
ExploreKindItem(
kind = kind,
isClickable = false,
onClick = {},
modifier = modifier,
backgroundColor = backgroundColor,
isMiuix = isMiuix,
displayText = state.displayName
)
}
}
}
}
AppAlertDialog(
data = showFullError,
onDismissRequest = { showFullError = null },
title = "错误详情",
confirmText = "复制",
onConfirm = { error ->
context.sendToClip(error)
showFullError = null
},
dismissText = "关闭",
onDismiss = { showFullError = null },
content = { error ->
SelectionContainer {
AppText(
text = error,
style = LegadoTheme.typography.bodyMedium,
modifier = Modifier
.heightIn(max = 400.dp)
.verticalScroll(rememberScrollState())
)
}
}
)
}
private val ExploreKind.errorMsg: String?
get() = when {
title.startsWith("ERROR:", ignoreCase = true) -> url ?: title
url?.contains("Exception") == true -> url
title.contains("Exception") -> title
else -> null
}
private fun Context.findActivity(): AppCompatActivity? {
var context = this
while (context is ContextWrapper) {
if (context is AppCompatActivity) return context
context = context.baseContext
}
return null
}
@Composable
@@ -236,12 +231,7 @@ private fun ToggleTypeItem(
state: ExploreKindItemState,
valueOverride: String?,
onValueChange: ((String) -> Unit)?,
isSelected: Boolean,
modifier: Modifier,
backgroundColor: Color,
isMiuix: Boolean,
trailingIcon: @Composable (() -> Unit)?,
content: (@Composable (displayName: String, isSelected: Boolean, onClick: () -> Unit, trailingIcon: @Composable (() -> Unit)?) -> Unit)?
BaseItem: @Composable (String, () -> Unit) -> Unit
) {
val chars = remember(kind.chars) {
kind.chars?.filterNotNull().takeUnless { it.isNullOrEmpty() } ?: listOf("chars", "is null")
@@ -269,21 +259,7 @@ private fun ToggleTypeItem(
state.executeAction(kind.action)
}
if (content != null) {
content(text, isSelected, internalOnClick, trailingIcon)
} else {
ExploreKindItem(
kind = kind,
isClickable = true,
onClick = internalOnClick,
modifier = modifier,
backgroundColor = backgroundColor,
isMiuix = isMiuix,
displayText = text,
isSelected = isSelected,
trailingIcon = trailingIcon
)
}
BaseItem(text, internalOnClick)
}
@Composable
@@ -293,12 +269,7 @@ private fun SelectTypeItem(
state: ExploreKindItemState,
valueOverride: String?,
onValueChange: ((String) -> Unit)?,
isSelected: Boolean,
modifier: Modifier,
backgroundColor: Color,
isMiuix: Boolean,
trailingIcon: @Composable (() -> Unit)?,
content: (@Composable (displayName: String, isSelected: Boolean, onClick: () -> Unit, trailingIcon: @Composable (() -> Unit)?) -> Unit)?
BaseItem: @Composable (String, () -> Unit) -> Unit
) {
val chars = remember(kind.chars) {
kind.chars?.filterNotNull().takeUnless { it.isNullOrEmpty() } ?: listOf("chars", "is null")
@@ -318,25 +289,11 @@ private fun SelectTypeItem(
}
var showSelector by remember(sourceUrl, kind.title) { mutableStateOf(false) }
Box(modifier = modifier) {
Box {
val internalOnClick = { showSelector = true }
val displayText = "${state.displayName} $selected"
if (content != null) {
content(displayText, isSelected, internalOnClick, trailingIcon)
} else {
ExploreKindItem(
kind = kind,
isClickable = chars.isNotEmpty(),
onClick = internalOnClick,
modifier = Modifier.fillMaxWidth(),
backgroundColor = backgroundColor,
isMiuix = isMiuix,
displayText = displayText,
isSelected = isSelected,
trailingIcon = trailingIcon
)
}
BaseItem(displayText, internalOnClick)
RoundDropdownMenu(
expanded = showSelector,