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