diff --git a/app/build.gradle b/app/build.gradle index 710c85c..f8e1b83 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -50,6 +50,7 @@ android { } dependencies { + implementation("androidx.compose.animation:animation-graphics:$compose_version") implementation("com.google.accompanist:accompanist-flowlayout:0.24.3-alpha") implementation("com.google.accompanist:accompanist-navigation-animation:0.24.3-alpha") implementation "androidx.datastore:datastore-preferences:1.0.0" @@ -83,7 +84,7 @@ dependencies { implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.0-alpha01" implementation "androidx.compose.material:material:1.2.0-alpha04" - implementation "androidx.compose.material3:material3:1.0.0-alpha06" + implementation "androidx.compose.material3:material3:1.0.0-alpha07" implementation "androidx.compose.material:material-icons-extended:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' diff --git a/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt b/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt index 696620d..bfc4847 100644 --- a/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt +++ b/app/src/main/java/me/ash/reader/ui/page/common/HomeEntry.kt @@ -6,13 +6,17 @@ import androidx.compose.animation.core.spring import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.* +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.rememberModalBottomSheetState import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import com.google.accompanist.insets.ProvideWindowInsets import com.google.accompanist.insets.navigationBarsHeight import com.google.accompanist.insets.statusBarsPadding @@ -20,11 +24,17 @@ import com.google.accompanist.navigation.animation.AnimatedNavHost import com.google.accompanist.navigation.animation.composable import com.google.accompanist.navigation.animation.rememberAnimatedNavController import com.google.accompanist.systemuicontroller.rememberSystemUiController +import me.ash.reader.ui.page.home.FeedOptionDrawer import me.ash.reader.ui.page.home.HomePage import me.ash.reader.ui.page.settings.SettingsPage import me.ash.reader.ui.theme.AppTheme -@OptIn(ExperimentalAnimationApi::class) +@OptIn(ExperimentalMaterialApi::class) +val LocalDrawerState = staticCompositionLocalOf { + error("CompositionLocal LocalDrawerState not present") +} + +@OptIn(ExperimentalAnimationApi::class, androidx.compose.material.ExperimentalMaterialApi::class) @Composable fun HomeEntry() { val navController = rememberAnimatedNavController() @@ -32,110 +42,117 @@ fun HomeEntry() { AppTheme { ProvideWindowInsets { rememberSystemUiController().run { - setStatusBarColor(MaterialTheme.colorScheme.surface, !isSystemInDarkTheme()) - setSystemBarsColor(MaterialTheme.colorScheme.surface, !isSystemInDarkTheme()) + setStatusBarColor(Color.Transparent, !isSystemInDarkTheme()) + setSystemBarsColor(Color.Transparent, !isSystemInDarkTheme()) setNavigationBarColor(MaterialTheme.colorScheme.surface, !isSystemInDarkTheme()) } - Column(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) { - Row( - modifier = Modifier - .weight(1f) - .statusBarsPadding() + Box { + CompositionLocalProvider( + LocalDrawerState provides rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) ) { - AnimatedNavHost( - modifier = Modifier.background(MaterialTheme.colorScheme.surface), - navController = navController, - startDestination = RouteName.HOME, - ) { - composable( - route = RouteName.HOME, - enterTransition = { - slideInHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - initialOffsetX = { -it } - ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) - }, - exitTransition = { - slideOutHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - targetOffsetX = { it } - ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) - }, - popEnterTransition = { - slideInHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - initialOffsetX = { -it } - ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) - }, - popExitTransition = { - slideOutHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - targetOffsetX = { it } - ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) - }, + Column(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) { + Row( + modifier = Modifier + .weight(1f) + .statusBarsPadding() ) { - HomePage(navController) - } - composable( - route = RouteName.SETTINGS, - enterTransition = { - slideInHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - initialOffsetX = { -it } - ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) - }, - exitTransition = { - slideOutHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - targetOffsetX = { -it } - ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) - }, - popEnterTransition = { - slideInHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - initialOffsetX = { -it } - ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) - }, - popExitTransition = { - slideOutHorizontally( - animationSpec = spring( - stiffness = Spring.StiffnessLow, - dampingRatio = Spring.DampingRatioNoBouncy - ), - targetOffsetX = { -it } - ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) - }, - ) { - SettingsPage(navController) + AnimatedNavHost( + modifier = Modifier.background(MaterialTheme.colorScheme.surface), + navController = navController, + startDestination = RouteName.HOME, + ) { + composable( + route = RouteName.HOME, + enterTransition = { + slideInHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + initialOffsetX = { -it } + ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) + }, + exitTransition = { + slideOutHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + targetOffsetX = { it } + ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) + }, + popEnterTransition = { + slideInHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + initialOffsetX = { -it } + ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) + }, + popExitTransition = { + slideOutHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + targetOffsetX = { it } + ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) + }, + ) { + HomePage(navController) + } + composable( + route = RouteName.SETTINGS, + enterTransition = { + slideInHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + initialOffsetX = { -it } + ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) + }, + exitTransition = { + slideOutHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + targetOffsetX = { -it } + ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) + }, + popEnterTransition = { + slideInHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + initialOffsetX = { -it } + ) + fadeIn(animationSpec = tween(220, delayMillis = 90)) + }, + popExitTransition = { + slideOutHorizontally( + animationSpec = spring( + stiffness = Spring.StiffnessLow, + dampingRatio = Spring.DampingRatioNoBouncy + ), + targetOffsetX = { -it } + ) + fadeOut(animationSpec = tween(220, delayMillis = 90)) + }, + ) { + SettingsPage(navController) + } + } } + Spacer( + modifier = Modifier + .navigationBarsHeight() + .fillMaxWidth() + ) } + FeedOptionDrawer(drawerState = LocalDrawerState.current) } - Spacer( - modifier = Modifier - .navigationBarsHeight() - .fillMaxWidth() - ) } } } diff --git a/app/src/main/java/me/ash/reader/ui/page/home/FeedOptionDrawer.kt b/app/src/main/java/me/ash/reader/ui/page/home/FeedOptionDrawer.kt new file mode 100644 index 0000000..f99e30a --- /dev/null +++ b/app/src/main/java/me/ash/reader/ui/page/home/FeedOptionDrawer.kt @@ -0,0 +1,116 @@ +package me.ash.reader.ui.page.home + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.ChipDefaults +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.RssFeed +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import me.ash.reader.R +import me.ash.reader.ui.page.home.feeds.subscribe.ResultViewPage +import me.ash.reader.ui.widget.BottomDrawer +import me.ash.reader.ui.widget.Subtitle + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun FeedOptionDrawer( + modifier: Modifier = Modifier, + drawerState: ModalBottomSheetState = androidx.compose.material.rememberModalBottomSheetState( + ModalBottomSheetValue.Hidden + ), +) { + BottomDrawer( + drawerState = drawerState, + ) { + Column { + Icon( + modifier = modifier + .fillMaxWidth() + .align(Alignment.CenterHorizontally), + imageVector = Icons.Rounded.RssFeed, + contentDescription = stringResource(R.string.subscribe), + ) + Spacer(modifier = modifier.height(16.dp)) + Text( + modifier = Modifier.fillMaxWidth(), + text = "Feed", + style = MaterialTheme.typography.headlineSmall, + textAlign = TextAlign.Center, + ) + Spacer(modifier = modifier.height(16.dp)) + ResultViewPage( + link = "https://joeycz.github.io/weekly/rss.xml", + groups = emptyList(), + selectedAllowNotificationPreset = true, + selectedParseFullContentPreset = true, + selectedGroupId = "selectedGroupId", + newGroupContent = "", + onNewGroupValueChange = { }, + newGroupSelected = false, + changeNewGroupSelected = { }, + allowNotificationPresetOnClick = { }, + parseFullContentPresetOnClick = { }, + groupOnClick = { }, + onKeyboardAction = { }, + ) + Spacer(modifier = Modifier.height(20.dp)) + Subtitle(text = "More") + Spacer(modifier = Modifier.height(10.dp)) + androidx.compose.material.FilterChip( + modifier = modifier, + colors = ChipDefaults.filterChipColors( + backgroundColor = Color.Transparent, + contentColor = MaterialTheme.colorScheme.error, + leadingIconColor = MaterialTheme.colorScheme.error, + disabledBackgroundColor = MaterialTheme.colorScheme.outline.copy( + alpha = 0.7f + ), + disabledContentColor = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f), + disabledLeadingIconColor = MaterialTheme.colorScheme.outline.copy( + alpha = 0.7f + ), + selectedBackgroundColor = Color.Transparent, + selectedContentColor = MaterialTheme.colorScheme.error, + selectedLeadingIconColor = MaterialTheme.colorScheme.error + ), + border = BorderStroke(1.dp, MaterialTheme.colorScheme.error), + selected = false, + shape = CircleShape, + onClick = { +// focusManager.clearFocus() +// onClick() + }, + content = { + Text( + modifier = modifier.padding( + start = if (false) 0.dp else 8.dp, + top = 8.dp, + end = 8.dp, + bottom = 8.dp + ), + text = "Delete", + style = MaterialTheme.typography.titleSmall, + color = if (true) { + MaterialTheme.colorScheme.error + } else { + MaterialTheme.colorScheme.error + }, + ) + }, + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/page/home/HomeBottomNavBar.kt b/app/src/main/java/me/ash/reader/ui/page/home/HomeBottomNavBar.kt index ef71d12..e890885 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/HomeBottomNavBar.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/HomeBottomNavBar.kt @@ -42,6 +42,7 @@ import com.google.accompanist.pager.PagerState import me.ash.reader.R import me.ash.reader.data.constant.Filter import me.ash.reader.ui.extension.getName +import me.ash.reader.ui.theme.LocalLightThemeColors import me.ash.reader.ui.widget.CanBeDisabledIconButton import kotlin.math.absoluteValue @@ -192,6 +193,9 @@ fun Item( onClick: () -> Unit = {}, ) { val view = LocalView.current + val lightThemeColors = LocalLightThemeColors.current + val lightPrimaryContainer = lightThemeColors.primaryContainer + val lightOnSurface = lightThemeColors.onSurface FilterChip( modifier = Modifier @@ -204,9 +208,9 @@ fun Item( disabledBackgroundColor = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f), disabledContentColor = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f), disabledLeadingIconColor = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f), - selectedBackgroundColor = MaterialTheme.colorScheme.primaryContainer, - selectedContentColor = MaterialTheme.colorScheme.onSurface, - selectedLeadingIconColor = MaterialTheme.colorScheme.onSurface + selectedBackgroundColor = lightPrimaryContainer, + selectedContentColor = lightOnSurface, + selectedLeadingIconColor = lightOnSurface ), selected = selected, selectedIcon = { @@ -216,7 +220,7 @@ fun Item( modifier = Modifier .padding(start = 8.dp) .size(20.dp), - tint = MaterialTheme.colorScheme.onSurface, + tint = lightOnSurface, ) }, onClick = { @@ -235,7 +239,7 @@ fun Item( text = if (selected) name.uppercase() else "", style = MaterialTheme.typography.titleSmall, color = if (selected) { - MaterialTheme.colorScheme.onSurface + lightOnSurface } else { MaterialTheme.colorScheme.outline }, diff --git a/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt b/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt index d13d624..c40f4a3 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/HomePage.kt @@ -2,9 +2,12 @@ package me.ash.reader.ui.page.home import android.util.Log import androidx.activity.compose.BackHandler +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope @@ -26,7 +29,7 @@ import me.ash.reader.ui.page.home.read.ReadViewAction import me.ash.reader.ui.page.home.read.ReadViewModel import me.ash.reader.ui.widget.ViewPager -@OptIn(ExperimentalPagerApi::class) +@OptIn(ExperimentalPagerApi::class, androidx.compose.material.ExperimentalMaterialApi::class) @Composable fun HomePage( navController: NavHostController, @@ -38,6 +41,7 @@ fun HomePage( val filterState = viewModel.filterState.collectAsStateValue() val readState = readViewModel.viewState.collectAsStateValue() val scope = rememberCoroutineScope() + val drawerState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) LaunchedEffect(Unit) { context.findActivity()?.let { activity -> @@ -92,66 +96,69 @@ fun HomePage( } } - Column { - ViewPager( - modifier = Modifier.weight(1f), - state = viewState.pagerState, - composableList = listOf( - { - FeedsPage(navController = navController) - }, - { - FlowPage(navController = navController) - }, - { - ReadPage( - navController = navController, - btnBackOnClickListener = { - viewModel.dispatch( - HomeViewAction.ScrollToPage( - scope = scope, - targetPage = 1, - callback = { - readViewModel.dispatch(ReadViewAction.ClearArticle) - } + Box { + Column { + ViewPager( + modifier = Modifier.weight(1f), + state = viewState.pagerState, + composableList = listOf( + { + FeedsPage(navController = navController) + }, + { + FlowPage(navController = navController) + }, + { + ReadPage( + navController = navController, + btnBackOnClickListener = { + viewModel.dispatch( + HomeViewAction.ScrollToPage( + scope = scope, + targetPage = 1, + callback = { + readViewModel.dispatch(ReadViewAction.ClearArticle) + } + ) ) - ) - }, - ) + }, + ) + }, + ), + ) + HomeBottomNavBar( + modifier = Modifier + .height(60.dp) + .fillMaxWidth(), + pagerState = viewState.pagerState, + disabled = readState.articleWithFeed == null, + isUnread = readState.articleWithFeed?.article?.isUnread ?: false, + isStarred = readState.articleWithFeed?.article?.isStarred ?: false, + isFullContent = readState.articleWithFeed?.feed?.isFullContent ?: false, + unreadOnClick = { + readViewModel.dispatch(ReadViewAction.MarkUnread(it)) }, - ), - ) - HomeBottomNavBar( - modifier = Modifier - .height(60.dp) - .fillMaxWidth(), - pagerState = viewState.pagerState, - disabled = readState.articleWithFeed == null, - isUnread = readState.articleWithFeed?.article?.isUnread ?: false, - isStarred = readState.articleWithFeed?.article?.isStarred ?: false, - isFullContent = readState.articleWithFeed?.feed?.isFullContent ?: false, - unreadOnClick = { - readViewModel.dispatch(ReadViewAction.MarkUnread(it)) - }, - starredOnClick = { - readViewModel.dispatch(ReadViewAction.MarkStarred(it)) - }, - fullContentOnClick = { afterIsFullContent -> - readState.articleWithFeed?.let { - if (afterIsFullContent) readViewModel.dispatch(ReadViewAction.RenderFullContent) - else readViewModel.dispatch(ReadViewAction.RenderDescriptionContent) - } - }, - filter = filterState.filter, - filterOnClick = { - viewModel.dispatch( - HomeViewAction.ChangeFilter( - filterState.copy( - filter = it + starredOnClick = { + readViewModel.dispatch(ReadViewAction.MarkStarred(it)) + }, + fullContentOnClick = { afterIsFullContent -> + readState.articleWithFeed?.let { + if (afterIsFullContent) readViewModel.dispatch(ReadViewAction.RenderFullContent) + else readViewModel.dispatch(ReadViewAction.RenderDescriptionContent) + } + }, + filter = filterState.filter, + filterOnClick = { + viewModel.dispatch( + HomeViewAction.ChangeFilter( + filterState.copy( + filter = it + ) ) ) - ) - }, - ) + }, + ) + } + FeedOptionDrawer(drawerState = drawerState) } } \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/GroupItem.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/GroupItem.kt index 0f7fc1f..66a1bad 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/GroupItem.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/GroupItem.kt @@ -3,9 +3,11 @@ package me.ash.reader.ui.page.home.feeds import androidx.compose.animation.* import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.ExpandLess import androidx.compose.material.icons.rounded.ExpandMore @@ -18,9 +20,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import kotlinx.coroutines.launch import me.ash.reader.R import me.ash.reader.data.feed.Feed +import me.ash.reader.ui.page.common.LocalDrawerState +@OptIn(ExperimentalMaterialApi::class, androidx.compose.foundation.ExperimentalFoundationApi::class) @Composable fun GroupItem( modifier: Modifier = Modifier, @@ -31,6 +36,8 @@ fun GroupItem( feedOnClick: (feed: Feed) -> Unit = {}, ) { var expanded by remember { mutableStateOf(isExpanded) } + val scope = rememberCoroutineScope() + val drawerState = LocalDrawerState.current Column( modifier = Modifier @@ -38,7 +45,16 @@ fun GroupItem( .padding(horizontal = 16.dp) .clip(RoundedCornerShape(32.dp)) .background(MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.14f)) - .clickable { groupOnClick() } + .combinedClickable( + onClick = { + groupOnClick() + }, + onLongClick = { + scope.launch { + drawerState.show() + } + } + ) .padding(top = 22.dp) ) { Row( diff --git a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/ResultViewPage.kt b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/ResultViewPage.kt index 2d707d7..d01228c 100644 --- a/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/ResultViewPage.kt +++ b/app/src/main/java/me/ash/reader/ui/page/home/feeds/subscribe/ResultViewPage.kt @@ -82,6 +82,7 @@ private fun Link( Text( text = text, color = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f), + style = MaterialTheme.typography.bodyMedium, ) } } diff --git a/app/src/main/java/me/ash/reader/ui/widget/BottomDrawer.kt b/app/src/main/java/me/ash/reader/ui/widget/BottomDrawer.kt new file mode 100644 index 0000000..7c72817 --- /dev/null +++ b/app/src/main/java/me/ash/reader/ui/widget/BottomDrawer.kt @@ -0,0 +1,73 @@ +package me.ash.reader.ui.widget + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetDefaults +import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun BottomDrawer( + modifier: Modifier = Modifier, + drawerState: ModalBottomSheetState = androidx.compose.material.rememberModalBottomSheetState( + ModalBottomSheetValue.Hidden + ), + content: @Composable () -> Unit = {}, +) { + androidx.compose.material.ModalBottomSheetLayout( + sheetState = drawerState, + sheetBackgroundColor = Color.Transparent, + sheetElevation = if (drawerState.isVisible) ModalBottomSheetDefaults.Elevation else 0.dp, + sheetContent = { + Row( + modifier = Modifier + .fillMaxWidth() + .clip( + RoundedCornerShape( + topStart = 28.0.dp, + topEnd = 28.0.dp, + bottomEnd = 0.0.dp, + bottomStart = 0.0.dp + ) + ) + .background(MaterialTheme.colorScheme.surface) + .padding(horizontal = 28.dp) + .navigationBarsPadding() + ) { + Box { + Row( + modifier = modifier + .padding(top = 8.dp) + .fillMaxWidth(), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, + ) { + Row( + modifier = modifier + .size(38.dp, 4.dp) + .background(MaterialTheme.colorScheme.outline.copy(alpha = 0.2f)) + .zIndex(1f) + ) {} + } + Column { + Spacer(modifier = Modifier.height(40.dp)) + content() + Spacer(modifier = Modifier.height(28.dp)) + } + } + } + }, + content = {} + ) +} \ No newline at end of file diff --git a/app/src/main/java/me/ash/reader/ui/widget/SelectionChip.kt b/app/src/main/java/me/ash/reader/ui/widget/SelectionChip.kt index 825d6d3..5f3d04b 100644 --- a/app/src/main/java/me/ash/reader/ui/widget/SelectionChip.kt +++ b/app/src/main/java/me/ash/reader/ui/widget/SelectionChip.kt @@ -1,5 +1,6 @@ package me.ash.reader.ui.widget +import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row @@ -39,6 +40,7 @@ fun SelectionChip( enabled: Boolean = true, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, shape: Shape = CircleShape, + border: BorderStroke? = null, selectedIcon: @Composable () -> Unit = { Icon( imageVector = Icons.Filled.CheckCircle, @@ -66,6 +68,7 @@ fun SelectionChip( selectedContentColor = MaterialTheme.colorScheme.onSurface, selectedLeadingIconColor = MaterialTheme.colorScheme.onSurface ), + border = border, interactionSource = interactionSource, enabled = enabled, selected = selected, diff --git a/build.gradle b/build.gradle index 71137c5..42dac33 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { ext { - compose_version = '1.2.0-alpha02' + compose_version = '1.2.0-alpha06' } dependencies {