|
@@ -42,17 +42,13 @@ import androidx.compose.material.icons.Icons
|
|
|
import androidx.compose.material.icons.automirrored.outlined.FormatListBulleted
|
|
import androidx.compose.material.icons.automirrored.outlined.FormatListBulleted
|
|
|
import androidx.compose.material.icons.filled.Check
|
|
import androidx.compose.material.icons.filled.Check
|
|
|
import androidx.compose.material.icons.filled.FilterList
|
|
import androidx.compose.material.icons.filled.FilterList
|
|
|
-import androidx.compose.material.icons.filled.Grid4x4
|
|
|
|
|
import androidx.compose.material.icons.filled.GridView
|
|
import androidx.compose.material.icons.filled.GridView
|
|
|
import androidx.compose.material.icons.filled.Warning
|
|
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.DropdownMenu
|
|
|
|
|
-import androidx.compose.material3.DropdownMenuItem
|
|
|
|
|
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.FilterChip
|
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.Icon
|
|
|
-import androidx.compose.material3.IconButton
|
|
|
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.MaterialTheme
|
|
|
import androidx.compose.material3.OutlinedButton
|
|
import androidx.compose.material3.OutlinedButton
|
|
|
import androidx.compose.material3.Scaffold
|
|
import androidx.compose.material3.Scaffold
|
|
@@ -61,7 +57,9 @@ import androidx.compose.material3.Slider
|
|
|
import androidx.compose.material3.Surface
|
|
import androidx.compose.material3.Surface
|
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.material3.Text
|
|
|
import androidx.compose.material3.TopAppBarDefaults
|
|
import androidx.compose.material3.TopAppBarDefaults
|
|
|
-import androidx.compose.material3.TopAppBarScrollBehavior
|
|
|
|
|
|
|
+import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
|
|
|
|
+import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults
|
|
|
|
|
+import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
|
|
|
import androidx.compose.material3.rememberModalBottomSheetState
|
|
import androidx.compose.material3.rememberModalBottomSheetState
|
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.Composable
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
@@ -82,28 +80,34 @@ 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.HazeProgressive
|
|
|
|
|
import dev.chrisbanes.haze.HazeState
|
|
import dev.chrisbanes.haze.HazeState
|
|
|
-import dev.chrisbanes.haze.hazeEffect
|
|
|
|
|
-import dev.chrisbanes.haze.hazeSource
|
|
|
|
|
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.data.entities.rule.ExploreKind
|
|
|
import io.legado.app.model.BookShelfState
|
|
import io.legado.app.model.BookShelfState
|
|
|
|
|
+import io.legado.app.ui.theme.responsiveHazeEffect
|
|
|
|
|
+import io.legado.app.ui.theme.responsiveHazeSource
|
|
|
import io.legado.app.ui.widget.components.AnimatedTextLine
|
|
import io.legado.app.ui.widget.components.AnimatedTextLine
|
|
|
import io.legado.app.ui.widget.components.Cover
|
|
import io.legado.app.ui.widget.components.Cover
|
|
|
import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar
|
|
import io.legado.app.ui.widget.components.GlassMediumFlexibleTopAppBar
|
|
|
|
|
+import io.legado.app.ui.widget.components.GlassTopAppBarDefaults
|
|
|
import io.legado.app.ui.widget.components.SearchBarSection
|
|
import io.legado.app.ui.widget.components.SearchBarSection
|
|
|
import io.legado.app.ui.widget.components.button.AnimatedTextButton
|
|
import io.legado.app.ui.widget.components.button.AnimatedTextButton
|
|
|
-import io.legado.app.ui.widget.components.button.SmallTopBarButton
|
|
|
|
|
|
|
+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.card.TextCard
|
|
import io.legado.app.ui.widget.components.card.TextCard
|
|
|
|
|
+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.modalBottomSheet.GlassModalBottomSheet
|
|
import io.legado.app.ui.widget.components.modalBottomSheet.GlassModalBottomSheet
|
|
|
import kotlinx.coroutines.delay
|
|
import kotlinx.coroutines.delay
|
|
|
import kotlinx.coroutines.flow.Flow
|
|
import kotlinx.coroutines.flow.Flow
|
|
|
import org.koin.androidx.compose.koinViewModel
|
|
import org.koin.androidx.compose.koinViewModel
|
|
|
|
|
|
|
|
@SuppressLint("LocalContextConfigurationRead", "ConfigurationScreenWidthHeight")
|
|
@SuppressLint("LocalContextConfigurationRead", "ConfigurationScreenWidthHeight")
|
|
|
-@OptIn(ExperimentalMaterial3Api::class, ExperimentalHazeMaterialsApi::class)
|
|
|
|
|
|
|
+@OptIn(
|
|
|
|
|
+ ExperimentalMaterial3Api::class, ExperimentalHazeMaterialsApi::class,
|
|
|
|
|
+ ExperimentalMaterial3ExpressiveApi::class
|
|
|
|
|
+)
|
|
|
@Composable
|
|
@Composable
|
|
|
fun ExploreShowScreen(
|
|
fun ExploreShowScreen(
|
|
|
title: String,
|
|
title: String,
|
|
@@ -133,6 +137,10 @@ 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 isRefreshing by viewModel.isRefreshing.collectAsState()
|
|
|
|
|
+ val pullToRefreshState = rememberPullToRefreshState()
|
|
|
|
|
+
|
|
|
val hazeState = remember { HazeState() }
|
|
val hazeState = remember { HazeState() }
|
|
|
val shouldLoadMoreList = remember {
|
|
val shouldLoadMoreList = remember {
|
|
|
derivedStateOf {
|
|
derivedStateOf {
|
|
@@ -149,6 +157,7 @@ fun ExploreShowScreen(
|
|
|
total > 0 && last >= total - 1
|
|
total > 0 && last >= total - 1
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ var showMenu by remember { mutableStateOf(false) }
|
|
|
|
|
|
|
|
LaunchedEffect(shouldLoadMoreList.value, isGridMode) {
|
|
LaunchedEffect(shouldLoadMoreList.value, isGridMode) {
|
|
|
if (!isGridMode && shouldLoadMoreList.value) viewModel.loadMore()
|
|
if (!isGridMode && shouldLoadMoreList.value) viewModel.loadMore()
|
|
@@ -298,30 +307,130 @@ fun ExploreShowScreen(
|
|
|
|
|
|
|
|
Scaffold(
|
|
Scaffold(
|
|
|
modifier = Modifier
|
|
modifier = Modifier
|
|
|
- .nestedScroll(scrollBehavior.nestedScrollConnection)
|
|
|
|
|
- .hazeSource(hazeState),
|
|
|
|
|
|
|
+ .nestedScroll(scrollBehavior.nestedScrollConnection),
|
|
|
topBar = {
|
|
topBar = {
|
|
|
- ExploreTopBar(
|
|
|
|
|
- modifier = Modifier.hazeEffect(hazeState) {
|
|
|
|
|
- progressive =
|
|
|
|
|
- HazeProgressive.verticalGradient(startIntensity = 1f, endIntensity = 0f)
|
|
|
|
|
|
|
+ GlassMediumFlexibleTopAppBar(
|
|
|
|
|
+ modifier = Modifier.responsiveHazeEffect(
|
|
|
|
|
+ state = hazeState
|
|
|
|
|
+ ),
|
|
|
|
|
+ title = {
|
|
|
|
|
+ AnimatedTextLine(
|
|
|
|
|
+ selectedTitle ?: title,
|
|
|
|
|
+ maxLines = 1,
|
|
|
|
|
+ overflow = TextOverflow.Ellipsis
|
|
|
|
|
+ )
|
|
|
|
|
+ },
|
|
|
|
|
+ colors = GlassTopAppBarDefaults.glassColors(),
|
|
|
|
|
+ navigationIcon = {
|
|
|
|
|
+ TopbarNavigationButton(onClick = onBack)
|
|
|
|
|
+ },
|
|
|
|
|
+ actions = {
|
|
|
|
|
+ Row(
|
|
|
|
|
+ horizontalArrangement = Arrangement.End,
|
|
|
|
|
+ modifier = Modifier.animateContentSize(tween(300))
|
|
|
|
|
+ ) {
|
|
|
|
|
+ TopBarActionButton(
|
|
|
|
|
+ onClick = { showMenu = true },
|
|
|
|
|
+ imageVector = Icons.Default.FilterList,
|
|
|
|
|
+ contentDescription = "Filter"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ TopBarActionButton(
|
|
|
|
|
+ onClick = { showKindSheet = true },
|
|
|
|
|
+ imageVector = Icons.Outlined.FilterAlt,
|
|
|
|
|
+ contentDescription = "分类"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ AnimatedVisibility(
|
|
|
|
|
+ visible = isGridMode,
|
|
|
|
|
+ enter = fadeIn(tween(300)),
|
|
|
|
|
+ exit = fadeOut(tween(300))
|
|
|
|
|
+ ) {
|
|
|
|
|
+ TopBarActionButton(
|
|
|
|
|
+ onClick = { showGridCountSheet = true },
|
|
|
|
|
+ imageVector = Icons.AutoMirrored.Outlined.FormatListBulleted,
|
|
|
|
|
+ contentDescription = "列数设置"
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ TopBarActionButton(
|
|
|
|
|
+ onClick = { viewModel.setLayout() },
|
|
|
|
|
+ imageVector = if (!isGridMode) Icons.AutoMirrored.Outlined.FormatListBulleted else Icons.Default.GridView,
|
|
|
|
|
+ contentDescription = "切换布局"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ RoundDropdownMenu(
|
|
|
|
|
+ expanded = showMenu,
|
|
|
|
|
+ onDismissRequest = { showMenu = false }
|
|
|
|
|
+ ) {
|
|
|
|
|
+ RoundDropdownMenuItem(
|
|
|
|
|
+ text = { Text("全部显示") },
|
|
|
|
|
+ onClick = {
|
|
|
|
|
+ viewModel.setFilterState(BookFilterState.SHOW_ALL)
|
|
|
|
|
+ showMenu = false
|
|
|
|
|
+ },
|
|
|
|
|
+ trailingIcon = {
|
|
|
|
|
+ if (filterState == BookFilterState.SHOW_ALL)
|
|
|
|
|
+ Icon(Icons.Default.Check, null)
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ RoundDropdownMenuItem(
|
|
|
|
|
+ text = { Text("隐藏已在书架的同源书籍") },
|
|
|
|
|
+ onClick = {
|
|
|
|
|
+ viewModel.setFilterState(BookFilterState.HIDE_IN_SHELF)
|
|
|
|
|
+ showMenu = false
|
|
|
|
|
+ },
|
|
|
|
|
+ trailingIcon = {
|
|
|
|
|
+ if (filterState == BookFilterState.HIDE_IN_SHELF)
|
|
|
|
|
+ Icon(Icons.Default.Check, null)
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ RoundDropdownMenuItem(
|
|
|
|
|
+ text = { Text("隐藏已在书架的非同源书籍") },
|
|
|
|
|
+ onClick = {
|
|
|
|
|
+ viewModel.setFilterState(BookFilterState.HIDE_SAME_NAME_AUTHOR)
|
|
|
|
|
+ showMenu = false
|
|
|
|
|
+ },
|
|
|
|
|
+ trailingIcon = {
|
|
|
|
|
+ if (filterState == BookFilterState.HIDE_SAME_NAME_AUTHOR)
|
|
|
|
|
+ Icon(Icons.Default.Check, null)
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ RoundDropdownMenuItem(
|
|
|
|
|
+ text = { Text("只显示不在书架的书籍") },
|
|
|
|
|
+ onClick = {
|
|
|
|
|
+ viewModel.setFilterState(BookFilterState.SHOW_NOT_IN_SHELF_ONLY)
|
|
|
|
|
+ showMenu = false
|
|
|
|
|
+ },
|
|
|
|
|
+ trailingIcon = {
|
|
|
|
|
+ if (filterState == BookFilterState.SHOW_NOT_IN_SHELF_ONLY)
|
|
|
|
|
+ Icon(Icons.Default.Check, null)
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
},
|
|
},
|
|
|
- title = selectedTitle ?: title,
|
|
|
|
|
- filterState = filterState,
|
|
|
|
|
- onBack = onBack,
|
|
|
|
|
- onFilterSelect = viewModel::setFilterState,
|
|
|
|
|
- onSelectKindClick = { showKindSheet = true },
|
|
|
|
|
- onToggleGridMode = { viewModel.setLayout() },
|
|
|
|
|
- isGridMode = isGridMode,
|
|
|
|
|
- onGridCountClick = { showGridCountSheet = true },
|
|
|
|
|
scrollBehavior = scrollBehavior
|
|
scrollBehavior = scrollBehavior
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
) { paddingValues ->
|
|
) { paddingValues ->
|
|
|
- Box(
|
|
|
|
|
- modifier = Modifier
|
|
|
|
|
- .fillMaxSize()
|
|
|
|
|
- .padding(paddingValues)
|
|
|
|
|
|
|
+ PullToRefreshBox(
|
|
|
|
|
+ modifier = Modifier.fillMaxSize(),
|
|
|
|
|
+ isRefreshing = isRefreshing,
|
|
|
|
|
+ state = pullToRefreshState,
|
|
|
|
|
+ onRefresh = { viewModel.loadMore(isRefresh = true) },
|
|
|
|
|
+ indicator = {
|
|
|
|
|
+ PullToRefreshDefaults.LoadingIndicator(
|
|
|
|
|
+ state = pullToRefreshState,
|
|
|
|
|
+ isRefreshing = isRefreshing,
|
|
|
|
|
+ modifier = Modifier
|
|
|
|
|
+ .align(Alignment.TopCenter)
|
|
|
|
|
+ .padding(top = paddingValues.calculateTopPadding())
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
) {
|
|
) {
|
|
|
Crossfade(
|
|
Crossfade(
|
|
|
targetState = isGridMode,
|
|
targetState = isGridMode,
|
|
@@ -331,9 +440,16 @@ fun ExploreShowScreen(
|
|
|
if (isGrid) {
|
|
if (isGrid) {
|
|
|
LazyVerticalGrid(
|
|
LazyVerticalGrid(
|
|
|
state = gridState,
|
|
state = gridState,
|
|
|
- modifier = Modifier.fillMaxSize(),
|
|
|
|
|
|
|
+ modifier = Modifier
|
|
|
|
|
+ .fillMaxSize()
|
|
|
|
|
+ .responsiveHazeSource(hazeState),
|
|
|
columns = GridCells.Fixed(gridColumnCount),
|
|
columns = GridCells.Fixed(gridColumnCount),
|
|
|
- contentPadding = PaddingValues(12.dp),
|
|
|
|
|
|
|
+ contentPadding = PaddingValues(
|
|
|
|
|
+ top = paddingValues.calculateTopPadding() + 12.dp,
|
|
|
|
|
+ bottom = paddingValues.calculateBottomPadding() + 12.dp,
|
|
|
|
|
+ start = 12.dp,
|
|
|
|
|
+ end = 12.dp
|
|
|
|
|
+ ),
|
|
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
|
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
|
) {
|
|
) {
|
|
@@ -360,8 +476,14 @@ fun ExploreShowScreen(
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
LazyColumn(
|
|
LazyColumn(
|
|
|
|
|
+ modifier = Modifier
|
|
|
|
|
+ .fillMaxSize()
|
|
|
|
|
+ .responsiveHazeSource(hazeState),
|
|
|
state = listState,
|
|
state = listState,
|
|
|
- contentPadding = PaddingValues(bottom = 16.dp)
|
|
|
|
|
|
|
+ contentPadding = PaddingValues(
|
|
|
|
|
+ top = paddingValues.calculateTopPadding(),
|
|
|
|
|
+ bottom = paddingValues.calculateBottomPadding() + 16.dp
|
|
|
|
|
+ )
|
|
|
) {
|
|
) {
|
|
|
items(
|
|
items(
|
|
|
items = books,
|
|
items = books,
|
|
@@ -419,97 +541,6 @@ fun KindGridItem(
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
|
|
|
|
-@Composable
|
|
|
|
|
-fun ExploreTopBar(
|
|
|
|
|
- modifier: Modifier = Modifier,
|
|
|
|
|
- title: String,
|
|
|
|
|
- filterState: BookFilterState,
|
|
|
|
|
- onBack: () -> Unit,
|
|
|
|
|
- onFilterSelect: (BookFilterState) -> Unit,
|
|
|
|
|
- onSelectKindClick: () -> Unit,
|
|
|
|
|
- onToggleGridMode: () -> Unit,
|
|
|
|
|
- isGridMode: Boolean,
|
|
|
|
|
- onGridCountClick: () -> Unit,
|
|
|
|
|
- scrollBehavior: TopAppBarScrollBehavior? = null
|
|
|
|
|
-) {
|
|
|
|
|
- var showMenu by remember { mutableStateOf(false) }
|
|
|
|
|
-
|
|
|
|
|
- GlassMediumFlexibleTopAppBar(
|
|
|
|
|
- modifier = modifier,
|
|
|
|
|
- title = { AnimatedTextLine(title, maxLines = 1, overflow = TextOverflow.Ellipsis) },
|
|
|
|
|
- navigationIcon = {
|
|
|
|
|
- SmallTopBarButton(onClick = onBack)
|
|
|
|
|
- },
|
|
|
|
|
- actions = {
|
|
|
|
|
- Row(
|
|
|
|
|
- horizontalArrangement = Arrangement.End,
|
|
|
|
|
- modifier = Modifier.animateContentSize(tween(300))
|
|
|
|
|
- ) {
|
|
|
|
|
- IconButton(onClick = { showMenu = true }) {
|
|
|
|
|
- Icon(Icons.Default.FilterList, contentDescription = "Filter")
|
|
|
|
|
- }
|
|
|
|
|
- IconButton(onClick = { onSelectKindClick() }) {
|
|
|
|
|
- Icon(Icons.Outlined.FilterAlt, contentDescription = "分类")
|
|
|
|
|
- }
|
|
|
|
|
- AnimatedVisibility(
|
|
|
|
|
- visible = isGridMode,
|
|
|
|
|
- enter = fadeIn(tween(300)),
|
|
|
|
|
- exit = fadeOut(tween(300))
|
|
|
|
|
- ) {
|
|
|
|
|
- IconButton(onClick = onGridCountClick) {
|
|
|
|
|
- Icon(Icons.Default.Grid4x4, contentDescription = "列数设置")
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- IconButton(onClick = { onToggleGridMode() }) {
|
|
|
|
|
- Icon(
|
|
|
|
|
- imageVector = if (!isGridMode) Icons.AutoMirrored.Outlined.FormatListBulleted else Icons.Default.GridView,
|
|
|
|
|
- contentDescription = "切换布局"
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- DropdownMenu(
|
|
|
|
|
- expanded = showMenu,
|
|
|
|
|
- onDismissRequest = { showMenu = false }
|
|
|
|
|
- ) {
|
|
|
|
|
- DropdownMenuItem(
|
|
|
|
|
- text = { Text("全部显示") },
|
|
|
|
|
- onClick = {
|
|
|
|
|
- onFilterSelect(BookFilterState.SHOW_ALL)
|
|
|
|
|
- showMenu = false
|
|
|
|
|
- },
|
|
|
|
|
- trailingIcon = { if(filterState == BookFilterState.SHOW_ALL) Icon(Icons.Default.Check, null) }
|
|
|
|
|
- )
|
|
|
|
|
- DropdownMenuItem(
|
|
|
|
|
- text = { Text("隐藏已在书架的同源书籍") },
|
|
|
|
|
- onClick = {
|
|
|
|
|
- onFilterSelect(BookFilterState.HIDE_IN_SHELF)
|
|
|
|
|
- showMenu = false
|
|
|
|
|
- },
|
|
|
|
|
- trailingIcon = { if(filterState == BookFilterState.HIDE_IN_SHELF) Icon(Icons.Default.Check, null) }
|
|
|
|
|
- )
|
|
|
|
|
- DropdownMenuItem(
|
|
|
|
|
- text = { Text("隐藏已在书架的非同源书籍") },
|
|
|
|
|
- onClick = {
|
|
|
|
|
- onFilterSelect(BookFilterState.HIDE_SAME_NAME_AUTHOR)
|
|
|
|
|
- showMenu = false
|
|
|
|
|
- },
|
|
|
|
|
- trailingIcon = { if(filterState == BookFilterState.HIDE_SAME_NAME_AUTHOR) Icon(Icons.Default.Check, null) }
|
|
|
|
|
- )
|
|
|
|
|
- DropdownMenuItem(
|
|
|
|
|
- text = { Text("只显示不在书架的书籍") },
|
|
|
|
|
- onClick = {
|
|
|
|
|
- onFilterSelect(BookFilterState.SHOW_NOT_IN_SHELF_ONLY)
|
|
|
|
|
- showMenu = false
|
|
|
|
|
- },
|
|
|
|
|
- trailingIcon = { if(filterState == BookFilterState.SHOW_NOT_IN_SHELF_ONLY) Icon(Icons.Default.Check, null) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- scrollBehavior = scrollBehavior
|
|
|
|
|
- )
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
@Composable
|
|
@Composable
|
|
|
fun ExploreBookItem(
|
|
fun ExploreBookItem(
|
|
|
book: SearchBook,
|
|
book: SearchBook,
|