[优化] 修复一些稳定性和界面问题,清明了孩子们这几天华南F3要干活忙忙忙没空修bug
This commit is contained in:
11 files changed
+159
-194
No files matched your search
@@ -46,9 +46,7 @@ import androidx.compose.material.icons.filled.Warning
|
|||||||
import androidx.compose.material.icons.outlined.FilterAlt
|
import androidx.compose.material.icons.outlined.FilterAlt
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
import androidx.compose.material3.FilterChip
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.OutlinedButton
|
import androidx.compose.material3.OutlinedButton
|
||||||
import androidx.compose.material3.Slider
|
import androidx.compose.material3.Slider
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
@@ -69,16 +67,15 @@ import androidx.compose.ui.draw.clip
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import dev.chrisbanes.haze.HazeState
|
import dev.chrisbanes.haze.HazeState
|
||||||
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
|
||||||
import io.legado.app.data.entities.SearchBook
|
import io.legado.app.data.entities.SearchBook
|
||||||
import io.legado.app.data.entities.rule.ExploreKind
|
|
||||||
import io.legado.app.model.BookShelfState
|
import io.legado.app.model.BookShelfState
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
|
import io.legado.app.ui.theme.ThemeResolver
|
||||||
import io.legado.app.ui.theme.responsiveHazeEffect
|
import io.legado.app.ui.theme.responsiveHazeEffect
|
||||||
import io.legado.app.ui.theme.responsiveHazeSource
|
import io.legado.app.ui.theme.responsiveHazeSource
|
||||||
import io.legado.app.ui.widget.components.AppScaffold
|
import io.legado.app.ui.widget.components.AppScaffold
|
||||||
@@ -88,6 +85,7 @@ import io.legado.app.ui.widget.components.button.TopBarActionButton
|
|||||||
import io.legado.app.ui.widget.components.button.TopbarNavigationButton
|
import io.legado.app.ui.widget.components.button.TopbarNavigationButton
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.cover.Cover
|
import io.legado.app.ui.widget.components.cover.Cover
|
||||||
|
import io.legado.app.ui.widget.components.explore.ExploreKindItem
|
||||||
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.components.modalBottomSheet.AppModalBottomSheet
|
import io.legado.app.ui.widget.components.modalBottomSheet.AppModalBottomSheet
|
||||||
@@ -132,6 +130,7 @@ fun ExploreShowScreen(
|
|||||||
val isGridMode = layoutState == 1
|
val isGridMode = layoutState == 1
|
||||||
var showGridCountSheet by remember { mutableStateOf(false) }
|
var showGridCountSheet by remember { mutableStateOf(false) }
|
||||||
val gridColumnCount by viewModel.gridCount.collectAsState()
|
val gridColumnCount by viewModel.gridCount.collectAsState()
|
||||||
|
val isMiuix = ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)
|
||||||
|
|
||||||
val isRefreshing by viewModel.isRefreshing.collectAsState()
|
val isRefreshing by viewModel.isRefreshing.collectAsState()
|
||||||
val pullToRefreshState = rememberPullToRefreshState()
|
val pullToRefreshState = rememberPullToRefreshState()
|
||||||
@@ -236,6 +235,7 @@ fun ExploreShowScreen(
|
|||||||
|
|
||||||
AppModalBottomSheet(
|
AppModalBottomSheet(
|
||||||
show = showKindSheet,
|
show = showKindSheet,
|
||||||
|
containerColor = LegadoTheme.colorScheme.surface,
|
||||||
onDismissRequest = { showKindSheet = false }
|
onDismissRequest = { showKindSheet = false }
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@ fun ExploreShowScreen(
|
|||||||
|
|
||||||
SearchBarSection(
|
SearchBarSection(
|
||||||
query = kindQuery,
|
query = kindQuery,
|
||||||
backgroundColor = MaterialTheme.colorScheme.surfaceContainerHigh,
|
backgroundColor = LegadoTheme.colorScheme.surfaceContainerHigh,
|
||||||
onQueryChange = { kindQuery = it },
|
onQueryChange = { kindQuery = it },
|
||||||
placeholder = "选择或搜索分类",
|
placeholder = "选择或搜索分类",
|
||||||
)
|
)
|
||||||
@@ -258,7 +258,7 @@ fun ExploreShowScreen(
|
|||||||
|
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Fixed(3),
|
columns = GridCells.Fixed(3),
|
||||||
contentPadding = PaddingValues(16.dp),
|
contentPadding = PaddingValues(vertical = 16.dp),
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
modifier = Modifier.weight(1f, fill = false)
|
modifier = Modifier.weight(1f, fill = false)
|
||||||
@@ -271,14 +271,15 @@ fun ExploreShowScreen(
|
|||||||
if (isClickable) GridItemSpan(1) else GridItemSpan(3)
|
if (isClickable) GridItemSpan(1) else GridItemSpan(3)
|
||||||
}
|
}
|
||||||
) { _, kind ->
|
) { _, kind ->
|
||||||
KindGridItem(
|
ExploreKindItem(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItem(),
|
||||||
kind = kind,
|
kind = kind,
|
||||||
currentTitle = selectedTitle ?: title,
|
isClickable = !kind.url.isNullOrBlank(),
|
||||||
onClick = {
|
onClick = {
|
||||||
showKindSheet = false
|
showKindSheet = false
|
||||||
viewModel.switchExploreUrl(kind)
|
viewModel.switchExploreUrl(kind)
|
||||||
}
|
},
|
||||||
|
isMiuix = isMiuix
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,34 +487,6 @@ fun ExploreShowScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun KindGridItem(
|
|
||||||
kind: ExploreKind,
|
|
||||||
currentTitle: String?,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier
|
|
||||||
) {
|
|
||||||
val isClickable = !kind.url.isNullOrBlank()
|
|
||||||
val isSelected = kind.title == currentTitle
|
|
||||||
|
|
||||||
FilterChip(
|
|
||||||
onClick = { if (isClickable) onClick() },
|
|
||||||
enabled = isClickable,
|
|
||||||
selected = isSelected,
|
|
||||||
label = {
|
|
||||||
AppText(
|
|
||||||
text = kind.title,
|
|
||||||
fontSize = 12.sp,
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis
|
|
||||||
)
|
|
||||||
},
|
|
||||||
modifier = modifier.fillMaxWidth()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ExploreBookItem(
|
fun ExploreBookItem(
|
||||||
book: SearchBook,
|
book: SearchBook,
|
||||||
|
|||||||
@@ -60,9 +60,8 @@ import androidx.compose.material3.FloatingActionButtonMenuItem
|
|||||||
import androidx.compose.material3.FloatingToolbarDefaults.ScreenOffset
|
import androidx.compose.material3.FloatingToolbarDefaults.ScreenOffset
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.PrimaryScrollableTabRow
|
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Tab
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.ToggleFloatingActionButton
|
import androidx.compose.material3.ToggleFloatingActionButton
|
||||||
import androidx.compose.material3.ToggleFloatingActionButtonDefaults.animateIcon
|
import androidx.compose.material3.ToggleFloatingActionButtonDefaults.animateIcon
|
||||||
import androidx.compose.material3.animateFloatingActionButton
|
import androidx.compose.material3.animateFloatingActionButton
|
||||||
@@ -95,6 +94,7 @@ import io.legado.app.help.book.isLocal
|
|||||||
import io.legado.app.ui.book.toc.rule.TxtTocRuleActivity
|
import io.legado.app.ui.book.toc.rule.TxtTocRuleActivity
|
||||||
import io.legado.app.ui.replace.ReplaceEditRoute
|
import io.legado.app.ui.replace.ReplaceEditRoute
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
|
import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
||||||
import io.legado.app.ui.widget.CollapsibleHeader
|
import io.legado.app.ui.widget.CollapsibleHeader
|
||||||
import io.legado.app.ui.widget.components.ActionItem
|
import io.legado.app.ui.widget.components.ActionItem
|
||||||
import io.legado.app.ui.widget.components.AppScaffold
|
import io.legado.app.ui.widget.components.AppScaffold
|
||||||
@@ -108,6 +108,7 @@ import io.legado.app.ui.widget.components.divider.PillHeaderDivider
|
|||||||
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
|
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
|
||||||
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.components.tabRow.AppTabRow
|
||||||
import io.legado.app.ui.widget.components.text.AppText
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
import io.legado.app.ui.widget.components.topbar.DynamicTopAppBar
|
import io.legado.app.ui.widget.components.topbar.DynamicTopAppBar
|
||||||
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults
|
import io.legado.app.ui.widget.components.topbar.GlassTopAppBarDefaults
|
||||||
@@ -415,39 +416,21 @@ fun TocScreen(
|
|||||||
},
|
},
|
||||||
bottomContent = {
|
bottomContent = {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.adaptiveHorizontalPadding(),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
PrimaryScrollableTabRow(
|
AppTabRow(
|
||||||
|
tabTitles = listOf("目录", "书签"),
|
||||||
selectedTabIndex = pagerState.currentPage,
|
selectedTabIndex = pagerState.currentPage,
|
||||||
edgePadding = 0.dp,
|
onTabSelected = { index ->
|
||||||
divider = {},
|
scope.launch {
|
||||||
modifier = Modifier.weight(1f),
|
pagerState.animateScrollToPage(index)
|
||||||
containerColor = Color.Transparent
|
|
||||||
) {
|
|
||||||
Tab(
|
|
||||||
selected = pagerState.currentPage == 0,
|
|
||||||
onClick = { scope.launch { pagerState.animateScrollToPage(0) } },
|
|
||||||
text = {
|
|
||||||
AppText(
|
|
||||||
text = "目录",
|
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
},
|
||||||
Tab(
|
modifier = Modifier.weight(1f)
|
||||||
selected = pagerState.currentPage == 1,
|
)
|
||||||
onClick = { scope.launch { pagerState.animateScrollToPage(1) } },
|
|
||||||
text = {
|
|
||||||
AppText(
|
|
||||||
text = "书签",
|
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pagerState.currentPage == 0 && hasVolumes) {
|
if (pagerState.currentPage == 0 && hasVolumes) {
|
||||||
Box(
|
Box(
|
||||||
@@ -542,7 +525,7 @@ fun TocScreen(
|
|||||||
fabMenuExpanded = false
|
fabMenuExpanded = false
|
||||||
},
|
},
|
||||||
icon = { Icon(icon, contentDescription = null) },
|
icon = { Icon(icon, contentDescription = null) },
|
||||||
text = { AppText(text = label) }
|
text = { Text(text = label) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -683,25 +666,25 @@ fun ChapterItem(
|
|||||||
) {
|
) {
|
||||||
val backgroundColor by animateColorAsState(
|
val backgroundColor by animateColorAsState(
|
||||||
targetValue = when {
|
targetValue = when {
|
||||||
item.isSelected -> MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.5f)
|
item.isSelected -> LegadoTheme.colorScheme.primaryContainer.copy(alpha = 0.5f)
|
||||||
item.isDur -> MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.3f)
|
item.isDur -> LegadoTheme.colorScheme.secondaryContainer.copy(alpha = 0.3f)
|
||||||
else -> Color.Transparent
|
else -> Color.Transparent
|
||||||
}, label = "BgColor"
|
}, label = "BgColor"
|
||||||
)
|
)
|
||||||
|
|
||||||
val textColor by animateColorAsState(
|
val textColor by animateColorAsState(
|
||||||
targetValue = when {
|
targetValue = when {
|
||||||
item.isSelected -> MaterialTheme.colorScheme.onSurface
|
item.isSelected -> LegadoTheme.colorScheme.onSurface
|
||||||
item.isDur -> MaterialTheme.colorScheme.primary
|
item.isDur -> LegadoTheme.colorScheme.primary
|
||||||
else -> MaterialTheme.colorScheme.onSurface
|
else -> LegadoTheme.colorScheme.onSurface
|
||||||
}, label = "BgColor"
|
}, label = "BgColor"
|
||||||
)
|
)
|
||||||
|
|
||||||
val detailColor by animateColorAsState(
|
val detailColor by animateColorAsState(
|
||||||
targetValue = when {
|
targetValue = when {
|
||||||
item.isSelected -> MaterialTheme.colorScheme.onSurfaceVariant
|
item.isSelected -> LegadoTheme.colorScheme.onSurfaceVariant
|
||||||
item.isDur -> MaterialTheme.colorScheme.primary
|
item.isDur -> LegadoTheme.colorScheme.primary
|
||||||
else -> MaterialTheme.colorScheme.onSurfaceVariant
|
else -> LegadoTheme.colorScheme.onSurfaceVariant
|
||||||
}, label = "BgColor"
|
}, label = "BgColor"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -725,7 +708,7 @@ fun ChapterItem(
|
|||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Lock,
|
imageVector = Icons.Default.Lock,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = MaterialTheme.colorScheme.error,
|
tint = LegadoTheme.colorScheme.error,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(14.dp)
|
.size(14.dp)
|
||||||
.padding(end = 4.dp)
|
.padding(end = 4.dp)
|
||||||
@@ -891,7 +874,7 @@ private fun StatusIcon(
|
|||||||
imageVector = Icons.Rounded.LocationOn,
|
imageVector = Icons.Rounded.LocationOn,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.size(24.dp),
|
modifier = Modifier.size(24.dp),
|
||||||
tint = MaterialTheme.colorScheme.secondary
|
tint = LegadoTheme.colorScheme.secondary
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -899,7 +882,7 @@ private fun StatusIcon(
|
|||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
modifier = Modifier.size(24.dp),
|
modifier = Modifier.size(24.dp),
|
||||||
strokeWidth = 2.dp,
|
strokeWidth = 2.dp,
|
||||||
color = MaterialTheme.colorScheme.secondary
|
color = LegadoTheme.colorScheme.secondary
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -908,7 +891,7 @@ private fun StatusIcon(
|
|||||||
shape = MaterialTheme.shapes.medium,
|
shape = MaterialTheme.shapes.medium,
|
||||||
border = BorderStroke(
|
border = BorderStroke(
|
||||||
1.dp,
|
1.dp,
|
||||||
MaterialTheme.colorScheme.outlineVariant
|
LegadoTheme.colorScheme.outlineVariant
|
||||||
),
|
),
|
||||||
color = Color.Transparent
|
color = Color.Transparent
|
||||||
) {
|
) {
|
||||||
@@ -918,7 +901,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 = MaterialTheme.colorScheme.onSurfaceVariant
|
color = LegadoTheme.colorScheme.onSurfaceVariant
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -929,7 +912,7 @@ private fun StatusIcon(
|
|||||||
imageVector = Icons.Default.CheckCircle,
|
imageVector = Icons.Default.CheckCircle,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.size(24.dp),
|
modifier = Modifier.size(24.dp),
|
||||||
tint = MaterialTheme.colorScheme.secondary
|
tint = LegadoTheme.colorScheme.secondary
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,7 +921,7 @@ private fun StatusIcon(
|
|||||||
imageVector = Icons.Default.Refresh,
|
imageVector = Icons.Default.Refresh,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.size(24.dp),
|
modifier = Modifier.size(24.dp),
|
||||||
tint = MaterialTheme.colorScheme.error
|
tint = LegadoTheme.colorScheme.error
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,7 +930,7 @@ private fun StatusIcon(
|
|||||||
imageVector = Icons.Outlined.DownloadForOffline,
|
imageVector = Icons.Outlined.DownloadForOffline,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.size(24.dp),
|
modifier = Modifier.size(24.dp),
|
||||||
tint = MaterialTheme.colorScheme.outline.copy(alpha = 0.5f)
|
tint = LegadoTheme.colorScheme.outline.copy(alpha = 0.5f)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,11 +188,12 @@ fun BookshelfItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (BookshelfConfig.bookshelfShowDivider) HorizontalDivider(
|
if (BookshelfConfig.bookshelfShowDivider)
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
HorizontalDivider(
|
||||||
thickness = 0.5.dp,
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.5f)
|
thickness = 0.5.dp,
|
||||||
)
|
color = LegadoTheme.colorScheme.outlineVariant.copy(alpha = 0.5f)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ import io.legado.app.ui.book.manage.BookshelfManageActivity
|
|||||||
import io.legado.app.ui.book.search.SearchActivity
|
import io.legado.app.ui.book.search.SearchActivity
|
||||||
import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
|
import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
|
||||||
import io.legado.app.ui.theme.LegadoTheme
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
|
import io.legado.app.ui.theme.adaptiveHorizontalPadding
|
||||||
import io.legado.app.ui.widget.components.button.SmallOutlinedIconToggleButton
|
import io.legado.app.ui.widget.components.button.SmallOutlinedIconToggleButton
|
||||||
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
|
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
|
||||||
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
|
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
|
||||||
@@ -317,7 +318,9 @@ fun BookshelfScreen(
|
|||||||
val selectedTabIndex =
|
val selectedTabIndex =
|
||||||
pagerState.currentPage.coerceIn(0, uiState.groups.size - 1)
|
pagerState.currentPage.coerceIn(0, uiState.groups.size - 1)
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.adaptiveHorizontalPadding(),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
val tabTitles = remember(uiState.groups) {
|
val tabTitles = remember(uiState.groups) {
|
||||||
@@ -334,7 +337,7 @@ fun BookshelfScreen(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (BookshelfConfig.shouldShowExpandButton) {
|
if (BookshelfConfig.shouldShowExpandButton) {
|
||||||
Box(modifier = Modifier.padding(end = 16.dp)) {
|
Box(modifier = Modifier) {
|
||||||
SmallOutlinedIconToggleButton(
|
SmallOutlinedIconToggleButton(
|
||||||
checked = showGroupMenu,
|
checked = showGroupMenu,
|
||||||
onCheckedChange = { showGroupMenu = it },
|
onCheckedChange = { showGroupMenu = it },
|
||||||
|
|||||||
@@ -33,18 +33,14 @@ import androidx.compose.material.icons.filled.Refresh
|
|||||||
import androidx.compose.material.icons.filled.Search
|
import androidx.compose.material.icons.filled.Search
|
||||||
import androidx.compose.material.icons.filled.VerticalAlignTop
|
import androidx.compose.material.icons.filled.VerticalAlignTop
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.CardDefaults
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.ListItemDefaults
|
import androidx.compose.material3.ListItemDefaults
|
||||||
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
@@ -59,9 +55,6 @@ import androidx.compose.ui.draw.rotate
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.unit.Dp
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.data.entities.BookSourcePart
|
import io.legado.app.data.entities.BookSourcePart
|
||||||
@@ -77,6 +70,7 @@ import io.legado.app.ui.theme.ThemeResolver
|
|||||||
import io.legado.app.ui.widget.components.card.GlassCard
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
import io.legado.app.ui.widget.components.card.TextCard
|
import io.legado.app.ui.widget.components.card.TextCard
|
||||||
import io.legado.app.ui.widget.components.divider.PillHeaderDivider
|
import io.legado.app.ui.widget.components.divider.PillHeaderDivider
|
||||||
|
import io.legado.app.ui.widget.components.explore.ExploreKindItem
|
||||||
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
|
import io.legado.app.ui.widget.components.lazylist.FastScrollLazyColumn
|
||||||
import io.legado.app.ui.widget.components.list.ListScaffold
|
import io.legado.app.ui.widget.components.list.ListScaffold
|
||||||
import io.legado.app.ui.widget.components.menuItem.MenuItemIcon
|
import io.legado.app.ui.widget.components.menuItem.MenuItemIcon
|
||||||
@@ -473,81 +467,3 @@ fun ExploreStickyCard(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ExploreKindItem(
|
|
||||||
kind: ExploreKind,
|
|
||||||
isClickable: Boolean,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
isMiuix: Boolean,
|
|
||||||
) {
|
|
||||||
val color = if (isMiuix)
|
|
||||||
MiuixTheme.colorScheme.surfaceContainer
|
|
||||||
else
|
|
||||||
MaterialTheme.colorScheme.secondaryContainer
|
|
||||||
|
|
||||||
val contentColor = if (isMiuix)
|
|
||||||
MiuixTheme.colorScheme.onSurface
|
|
||||||
else
|
|
||||||
MaterialTheme.colorScheme.secondary
|
|
||||||
|
|
||||||
val unClickBackColor = if (isMiuix)
|
|
||||||
MiuixTheme.colorScheme.surfaceContainer
|
|
||||||
else
|
|
||||||
MaterialTheme.colorScheme.surface
|
|
||||||
|
|
||||||
val unClickColor = if (isMiuix)
|
|
||||||
MiuixTheme.colorScheme.disabledOnSurface
|
|
||||||
else
|
|
||||||
MaterialTheme.colorScheme.primary
|
|
||||||
|
|
||||||
CompositionLocalProvider(
|
|
||||||
LocalMinimumInteractiveComponentSize provides Dp.Unspecified
|
|
||||||
) {
|
|
||||||
|
|
||||||
val shape = MaterialTheme.shapes.medium
|
|
||||||
|
|
||||||
if (isClickable) {
|
|
||||||
GlassCard(
|
|
||||||
onClick = onClick,
|
|
||||||
shape = shape,
|
|
||||||
containerColor = color.copy(alpha = 0.6f),
|
|
||||||
contentColor = contentColor,
|
|
||||||
modifier = modifier
|
|
||||||
) {
|
|
||||||
KindText(kind)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GlassCard(
|
|
||||||
shape = shape,
|
|
||||||
containerColor = unClickBackColor.copy(alpha = 0.6f),
|
|
||||||
contentColor = unClickColor,
|
|
||||||
modifier = modifier,
|
|
||||||
border = CardDefaults.outlinedCardBorder()
|
|
||||||
) {
|
|
||||||
KindText(kind)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
|
||||||
@Composable
|
|
||||||
private fun KindText(
|
|
||||||
kind: ExploreKind
|
|
||||||
) {
|
|
||||||
AppText(
|
|
||||||
text = kind.title,
|
|
||||||
color = if (kind.url.isNullOrBlank())
|
|
||||||
LegadoTheme.colorScheme.primary
|
|
||||||
else
|
|
||||||
LegadoTheme.colorScheme.onSurface,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(vertical = 8.dp),
|
|
||||||
style = LegadoTheme.typography.labelMediumEmphasized,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
maxLines = 1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ import io.legado.app.ui.theme.LegadoTheme.composeEngine
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Modifier.adaptiveHorizontalPadding(): Modifier {
|
fun Modifier.adaptiveHorizontalPadding(): Modifier {
|
||||||
val horizontal = if (ThemeResolver.isMiuixEngine(composeEngine)) 12.dp else 16.dp
|
val horizontal = if (ThemeResolver.isMiuixEngine(composeEngine)) 8.dp else 16.dp
|
||||||
return this.padding(horizontal = horizontal)
|
return this.padding(horizontal = horizontal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,12 +36,9 @@ fun AppTextField(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
enabled: Boolean = true,
|
enabled: Boolean = true,
|
||||||
readOnly: Boolean = false,
|
readOnly: Boolean = false,
|
||||||
// 1. 核心思想:保留 AppText 的统一样式与颜色降级参数
|
|
||||||
textStyle: TextStyle? = null,
|
textStyle: TextStyle? = null,
|
||||||
textColor: Color = Color.Unspecified,
|
textColor: Color = Color.Unspecified,
|
||||||
// 2. 将 Label 统一定义为 String 以兼容两套引擎
|
|
||||||
label: String? = null,
|
label: String? = null,
|
||||||
// 3. 保留 M3 TextField 的所有其他参数
|
|
||||||
labelPosition: TextFieldLabelPosition = TextFieldLabelPosition.Attached(),
|
labelPosition: TextFieldLabelPosition = TextFieldLabelPosition.Attached(),
|
||||||
placeholder: @Composable (() -> Unit)? = null,
|
placeholder: @Composable (() -> Unit)? = null,
|
||||||
leadingIcon: @Composable (() -> Unit)? = null,
|
leadingIcon: @Composable (() -> Unit)? = null,
|
||||||
@@ -77,6 +74,7 @@ fun AppTextField(
|
|||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
readOnly = readOnly,
|
readOnly = readOnly,
|
||||||
textStyle = MiuixTheme.textStyles.main,
|
textStyle = MiuixTheme.textStyles.main,
|
||||||
|
backgroundColor = MiuixTheme.colorScheme.surfaceContainerHigh,
|
||||||
label = label ?: "",
|
label = label ?: "",
|
||||||
leadingIcon = leadingIcon,
|
leadingIcon = leadingIcon,
|
||||||
trailingIcon = trailingIcon,
|
trailingIcon = trailingIcon,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import androidx.compose.material3.Surface
|
|||||||
import androidx.compose.material3.TextFieldDefaults
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
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.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -37,6 +36,7 @@ fun SearchBarSection(
|
|||||||
placeholder: String = "搜索...",
|
placeholder: String = "搜索...",
|
||||||
leadingIcon: @Composable (() -> Unit)? = {
|
leadingIcon: @Composable (() -> Unit)? = {
|
||||||
AppIcon(
|
AppIcon(
|
||||||
|
modifier = Modifier.padding(horizontal = 12.dp),
|
||||||
imageVector = AppIcons.Search,
|
imageVector = AppIcons.Search,
|
||||||
contentDescription = null
|
contentDescription = null
|
||||||
)
|
)
|
||||||
@@ -67,23 +67,13 @@ fun SearchBarSection(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val showScrollToTop by remember(scrollState) {
|
|
||||||
derivedStateOf {
|
|
||||||
(scrollState?.firstVisibleItemIndex ?: 0) > 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val isMiuix = ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)
|
val isMiuix = ThemeResolver.isMiuixEngine(LegadoTheme.composeEngine)
|
||||||
|
|
||||||
val searchTextField = @Composable {
|
val searchTextField = @Composable {
|
||||||
AppTextField(
|
AppTextField(
|
||||||
state = textFieldState,
|
state = textFieldState,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth(),
|
||||||
.then(
|
|
||||||
if (isMiuix) Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
||||||
else Modifier
|
|
||||||
),
|
|
||||||
placeholder = { AppText(placeholder) },
|
placeholder = { AppText(placeholder) },
|
||||||
leadingIcon = leadingIcon,
|
leadingIcon = leadingIcon,
|
||||||
lineLimits = TextFieldLineLimits.SingleLine,
|
lineLimits = TextFieldLineLimits.SingleLine,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ fun TextCard(
|
|||||||
NormalCard(
|
NormalCard(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
shape = RoundedCornerShape(cornerRadius),
|
shape = RoundedCornerShape(cornerRadius),
|
||||||
|
cornerRadius = 4.dp,
|
||||||
containerColor = finalBackgroundColor,
|
containerColor = finalBackgroundColor,
|
||||||
contentColor = finalContentColor,
|
contentColor = finalContentColor,
|
||||||
onClick = onClick
|
onClick = onClick
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package io.legado.app.ui.widget.components.explore
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.CardDefaults
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
|
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import io.legado.app.data.entities.rule.ExploreKind
|
||||||
|
import io.legado.app.ui.theme.LegadoTheme
|
||||||
|
import io.legado.app.ui.widget.components.card.GlassCard
|
||||||
|
import io.legado.app.ui.widget.components.text.AppText
|
||||||
|
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ExploreKindItem(
|
||||||
|
kind: ExploreKind,
|
||||||
|
isClickable: Boolean,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
isMiuix: Boolean
|
||||||
|
) {
|
||||||
|
val color = if (isMiuix)
|
||||||
|
MiuixTheme.colorScheme.surfaceContainer
|
||||||
|
else
|
||||||
|
MaterialTheme.colorScheme.secondaryContainer
|
||||||
|
|
||||||
|
val contentColor = if (isMiuix)
|
||||||
|
MiuixTheme.colorScheme.onSurface
|
||||||
|
else
|
||||||
|
MaterialTheme.colorScheme.secondary
|
||||||
|
|
||||||
|
val unClickBackColor = if (isMiuix)
|
||||||
|
MiuixTheme.colorScheme.surfaceContainer
|
||||||
|
else
|
||||||
|
MaterialTheme.colorScheme.surface
|
||||||
|
|
||||||
|
val unClickColor = if (isMiuix)
|
||||||
|
MiuixTheme.colorScheme.disabledOnSurface
|
||||||
|
else
|
||||||
|
MaterialTheme.colorScheme.primary
|
||||||
|
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalMinimumInteractiveComponentSize provides Dp.Unspecified
|
||||||
|
) {
|
||||||
|
|
||||||
|
val shape = MaterialTheme.shapes.medium
|
||||||
|
|
||||||
|
if (isClickable) {
|
||||||
|
GlassCard(
|
||||||
|
onClick = onClick,
|
||||||
|
shape = shape,
|
||||||
|
containerColor = LegadoTheme.colorScheme.surfaceContainer.copy(alpha = 0.6f),
|
||||||
|
contentColor = LegadoTheme.colorScheme.onSurface,
|
||||||
|
modifier = modifier
|
||||||
|
) {
|
||||||
|
KindText(kind)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GlassCard(
|
||||||
|
shape = shape,
|
||||||
|
containerColor = LegadoTheme.colorScheme.surfaceContainer.copy(alpha = 0.6f),
|
||||||
|
contentColor = LegadoTheme.colorScheme.primary,
|
||||||
|
modifier = modifier,
|
||||||
|
border = CardDefaults.outlinedCardBorder()
|
||||||
|
) {
|
||||||
|
KindText(kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
|
@Composable
|
||||||
|
private fun KindText(
|
||||||
|
kind: ExploreKind
|
||||||
|
) {
|
||||||
|
AppText(
|
||||||
|
text = kind.title,
|
||||||
|
color = if (kind.url.isNullOrBlank())
|
||||||
|
LegadoTheme.colorScheme.primary
|
||||||
|
else
|
||||||
|
LegadoTheme.colorScheme.onSurface,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 8.dp),
|
||||||
|
style = LegadoTheme.typography.labelMediumEmphasized,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines = 1
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -29,7 +29,8 @@ fun AppTabRow(
|
|||||||
tabs = tabTitles,
|
tabs = tabTitles,
|
||||||
selectedTabIndex = selectedTabIndex,
|
selectedTabIndex = selectedTabIndex,
|
||||||
onTabSelected = onTabSelected,
|
onTabSelected = onTabSelected,
|
||||||
modifier = modifier.padding(start = 12.dp),
|
modifier = modifier
|
||||||
|
.padding(vertical = 4.dp),
|
||||||
colors = TabRowDefaults.tabRowColors(
|
colors = TabRowDefaults.tabRowColors(
|
||||||
backgroundColor = Color.Transparent
|
backgroundColor = Color.Transparent
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in new issue
Block a user