Add FeedOptionDrawer

This commit is contained in:
Ash 2022-03-24 17:13:05 +08:00
parent ada579377b
commit eda76f4445
10 changed files with 406 additions and 168 deletions

View File

@ -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'

View File

@ -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<ModalBottomSheetState> {
error("CompositionLocal LocalDrawerState not present")
}
@OptIn(ExperimentalAnimationApi::class, androidx.compose.material.ExperimentalMaterialApi::class)
@Composable
fun HomeEntry() {
val navController = rememberAnimatedNavController()
@ -32,10 +42,14 @@ 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())
}
Box {
CompositionLocalProvider(
LocalDrawerState provides rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
) {
Column(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) {
Row(
modifier = Modifier
@ -137,6 +151,9 @@ fun HomeEntry() {
.fillMaxWidth()
)
}
FeedOptionDrawer(drawerState = LocalDrawerState.current)
}
}
}
}
}

View File

@ -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
},
)
},
)
}
}
}

View File

@ -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
},

View File

@ -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,6 +96,7 @@ fun HomePage(
}
}
Box {
Column {
ViewPager(
modifier = Modifier.weight(1f),
@ -154,4 +159,6 @@ fun HomePage(
},
)
}
FeedOptionDrawer(drawerState = drawerState)
}
}

View File

@ -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(

View File

@ -82,6 +82,7 @@ private fun Link(
Text(
text = text,
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.7f),
style = MaterialTheme.typography.bodyMedium,
)
}
}

View File

@ -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 = {}
)
}

View File

@ -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,

View File

@ -1,6 +1,6 @@
buildscript {
ext {
compose_version = '1.2.0-alpha02'
compose_version = '1.2.0-alpha06'
}
dependencies {