Add initial page and initial filter settings
This commit is contained in:
parent
e7332c606b
commit
86bd1b467c
|
@ -7,11 +7,11 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BlockButtonRadios(
|
fun BlockRadioGroupButton(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
selected: Int = 0,
|
selected: Int = 0,
|
||||||
onSelected: (Int) -> Unit,
|
onSelected: (Int) -> Unit,
|
||||||
items: List<BlockButtonRadiosItem> = listOf(),
|
itemRadioGroups: List<BlockRadioGroupButtonItem> = listOf(),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
@ -20,11 +20,11 @@ fun BlockButtonRadios(
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
items.forEachIndexed { index, item ->
|
itemRadioGroups.forEachIndexed { index, item ->
|
||||||
BlockButton(
|
BlockButton(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(end = if (item == items.last()) 0.dp else 8.dp),
|
.padding(end = if (item == itemRadioGroups.last()) 0.dp else 8.dp),
|
||||||
text = item.text,
|
text = item.text,
|
||||||
selected = selected == index,
|
selected = selected == index,
|
||||||
) {
|
) {
|
||||||
|
@ -34,11 +34,11 @@ fun BlockButtonRadios(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
items[selected].content()
|
itemRadioGroups[selected].content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class BlockButtonRadiosItem(
|
data class BlockRadioGroupButtonItem(
|
||||||
val text: String,
|
val text: String,
|
||||||
val onClick: () -> Unit = {},
|
val onClick: () -> Unit = {},
|
||||||
val content: @Composable () -> Unit,
|
val content: @Composable () -> Unit,
|
||||||
|
|
84
app/src/main/java/me/ash/reader/ui/component/RadioDialog.kt
Normal file
84
app/src/main/java/me/ash/reader/ui/component/RadioDialog.kt
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
package me.ash.reader.ui.component
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.RadioButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.text.style.BaselineShift
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPagerApi::class, ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun RadioDialog(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
visible: Boolean = false,
|
||||||
|
title: String = "",
|
||||||
|
options: List<RadioDialogOption> = emptyList(),
|
||||||
|
onDismissRequest: () -> Unit = {},
|
||||||
|
) {
|
||||||
|
Dialog(
|
||||||
|
modifier = modifier,
|
||||||
|
visible = visible,
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
title = {
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
style = MaterialTheme.typography.titleLarge,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
LazyColumn {
|
||||||
|
items(options) { option ->
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clip(CircleShape)
|
||||||
|
.clickable {
|
||||||
|
option.onClick()
|
||||||
|
onDismissRequest()
|
||||||
|
},
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
RadioButton(selected = option.selected, onClick = {
|
||||||
|
option.onClick()
|
||||||
|
onDismissRequest()
|
||||||
|
})
|
||||||
|
Text(
|
||||||
|
modifier = Modifier.padding(start = 6.dp),
|
||||||
|
text = option.text,
|
||||||
|
style = MaterialTheme.typography.bodyLarge.copy(
|
||||||
|
baselineShift = BaselineShift.None
|
||||||
|
),
|
||||||
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
confirmButton = {},
|
||||||
|
dismissButton = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class RadioDialogOption(
|
||||||
|
val text: String = "",
|
||||||
|
val selected: Boolean = false,
|
||||||
|
val onClick: () -> Unit = {},
|
||||||
|
)
|
|
@ -35,6 +35,10 @@ val Context.themeIndex: Int
|
||||||
get() = this.dataStore.get(DataStoreKeys.ThemeIndex) ?: 5
|
get() = this.dataStore.get(DataStoreKeys.ThemeIndex) ?: 5
|
||||||
val Context.customPrimaryColor: String
|
val Context.customPrimaryColor: String
|
||||||
get() = this.dataStore.get(DataStoreKeys.CustomPrimaryColor) ?: ""
|
get() = this.dataStore.get(DataStoreKeys.CustomPrimaryColor) ?: ""
|
||||||
|
val Context.initialPage: Int
|
||||||
|
get() = this.dataStore.get(DataStoreKeys.InitialPage) ?: 0
|
||||||
|
val Context.initialFilter: Int
|
||||||
|
get() = this.dataStore.get(DataStoreKeys.InitialFilter) ?: 2
|
||||||
|
|
||||||
suspend fun <T> DataStore<Preferences>.put(dataStoreKeys: DataStoreKeys<T>, value: T) {
|
suspend fun <T> DataStore<Preferences>.put(dataStoreKeys: DataStoreKeys<T>, value: T) {
|
||||||
this.edit {
|
this.edit {
|
||||||
|
@ -124,4 +128,14 @@ sealed class DataStoreKeys<T> {
|
||||||
override val key: Preferences.Key<String>
|
override val key: Preferences.Key<String>
|
||||||
get() = stringPreferencesKey("customPrimaryColor")
|
get() = stringPreferencesKey("customPrimaryColor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object InitialPage : DataStoreKeys<Int>() {
|
||||||
|
override val key: Preferences.Key<Int>
|
||||||
|
get() = intPreferencesKey("initialPage")
|
||||||
|
}
|
||||||
|
|
||||||
|
object InitialFilter : DataStoreKeys<Int>() {
|
||||||
|
override val key: Preferences.Key<Int>
|
||||||
|
get() = intPreferencesKey("initialFilter")
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,17 +13,17 @@ import androidx.paging.compose.collectAsLazyPagingItems
|
||||||
import com.google.accompanist.navigation.animation.AnimatedNavHost
|
import com.google.accompanist.navigation.animation.AnimatedNavHost
|
||||||
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
|
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import me.ash.reader.ui.ext.animatedComposable
|
import me.ash.reader.data.entity.Filter
|
||||||
import me.ash.reader.ui.ext.collectAsStateValue
|
import me.ash.reader.ui.ext.*
|
||||||
import me.ash.reader.ui.ext.findActivity
|
import me.ash.reader.ui.page.home.HomeViewAction
|
||||||
import me.ash.reader.ui.ext.isFirstLaunch
|
|
||||||
import me.ash.reader.ui.page.home.HomeViewModel
|
import me.ash.reader.ui.page.home.HomeViewModel
|
||||||
import me.ash.reader.ui.page.home.feeds.FeedsPage
|
import me.ash.reader.ui.page.home.feeds.FeedsPage
|
||||||
import me.ash.reader.ui.page.home.flow.FlowPage
|
import me.ash.reader.ui.page.home.flow.FlowPage
|
||||||
import me.ash.reader.ui.page.home.read.ReadPage
|
import me.ash.reader.ui.page.home.read.ReadPage
|
||||||
import me.ash.reader.ui.page.settings.ColorAndStyle
|
|
||||||
import me.ash.reader.ui.page.settings.SettingsPage
|
import me.ash.reader.ui.page.settings.SettingsPage
|
||||||
import me.ash.reader.ui.page.settings.TipsAndSupport
|
import me.ash.reader.ui.page.settings.color.ColorAndStyle
|
||||||
|
import me.ash.reader.ui.page.settings.interaction.Interaction
|
||||||
|
import me.ash.reader.ui.page.settings.tips.TipsAndSupport
|
||||||
import me.ash.reader.ui.page.startup.StartupPage
|
import me.ash.reader.ui.page.startup.StartupPage
|
||||||
import me.ash.reader.ui.theme.AppTheme
|
import me.ash.reader.ui.theme.AppTheme
|
||||||
import me.ash.reader.ui.theme.LocalUseDarkTheme
|
import me.ash.reader.ui.theme.LocalUseDarkTheme
|
||||||
|
@ -33,12 +33,11 @@ import me.ash.reader.ui.theme.LocalUseDarkTheme
|
||||||
fun HomeEntry(
|
fun HomeEntry(
|
||||||
homeViewModel: HomeViewModel = hiltViewModel(),
|
homeViewModel: HomeViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
val viewState = homeViewModel.viewState.collectAsStateValue()
|
val viewState = homeViewModel.viewState.collectAsStateValue()
|
||||||
|
val filterState = homeViewModel.filterState.collectAsStateValue()
|
||||||
val pagingItems = viewState.pagingData.collectAsLazyPagingItems()
|
val pagingItems = viewState.pagingData.collectAsLazyPagingItems()
|
||||||
|
|
||||||
AppTheme {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val useDarkTheme = LocalUseDarkTheme.current
|
|
||||||
val navController = rememberAnimatedNavController()
|
val navController = rememberAnimatedNavController()
|
||||||
|
|
||||||
val intent by rememberSaveable { mutableStateOf(context.findActivity()?.intent) }
|
val intent by rememberSaveable { mutableStateOf(context.findActivity()?.intent) }
|
||||||
|
@ -48,15 +47,45 @@ fun HomeEntry(
|
||||||
intent?.replaceExtras(null)
|
intent?.replaceExtras(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
when (context.initialPage) {
|
||||||
|
1 -> {
|
||||||
|
navController.navigate(RouteName.FLOW) {
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Other initial pages
|
||||||
|
}
|
||||||
|
|
||||||
|
homeViewModel.dispatch(
|
||||||
|
HomeViewAction.ChangeFilter(
|
||||||
|
filterState.copy(
|
||||||
|
filter = when (context.initialFilter) {
|
||||||
|
0 -> Filter.Starred
|
||||||
|
1 -> Filter.Unread
|
||||||
|
2 -> Filter.All
|
||||||
|
else -> Filter.All
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(openArticleId) {
|
LaunchedEffect(openArticleId) {
|
||||||
if (openArticleId.isNotEmpty()) {
|
if (openArticleId.isNotEmpty()) {
|
||||||
|
navController.navigate(RouteName.FLOW) {
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
navController.navigate("${RouteName.READING}/${openArticleId}") {
|
navController.navigate("${RouteName.READING}/${openArticleId}") {
|
||||||
popUpTo(RouteName.FEEDS)
|
launchSingleTop = true
|
||||||
}
|
}
|
||||||
openArticleId = ""
|
openArticleId = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppTheme {
|
||||||
|
val useDarkTheme = LocalUseDarkTheme.current
|
||||||
|
|
||||||
rememberSystemUiController().run {
|
rememberSystemUiController().run {
|
||||||
setStatusBarColor(Color.Transparent, !useDarkTheme)
|
setStatusBarColor(Color.Transparent, !useDarkTheme)
|
||||||
setSystemBarsColor(Color.Transparent, !useDarkTheme)
|
setSystemBarsColor(Color.Transparent, !useDarkTheme)
|
||||||
|
@ -90,6 +119,9 @@ fun HomeEntry(
|
||||||
animatedComposable(route = RouteName.COLOR_AND_STYLE) {
|
animatedComposable(route = RouteName.COLOR_AND_STYLE) {
|
||||||
ColorAndStyle(navController)
|
ColorAndStyle(navController)
|
||||||
}
|
}
|
||||||
|
animatedComposable(route = RouteName.INTERACTION) {
|
||||||
|
Interaction(navController)
|
||||||
|
}
|
||||||
animatedComposable(route = RouteName.TIPS_AND_SUPPORT) {
|
animatedComposable(route = RouteName.TIPS_AND_SUPPORT) {
|
||||||
TipsAndSupport(navController)
|
TipsAndSupport(navController)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,5 +7,6 @@ object RouteName {
|
||||||
const val READING = "reading"
|
const val READING = "reading"
|
||||||
const val SETTINGS = "settings"
|
const val SETTINGS = "settings"
|
||||||
const val COLOR_AND_STYLE = "color_and_style"
|
const val COLOR_AND_STYLE = "color_and_style"
|
||||||
|
const val INTERACTION = "interaction"
|
||||||
const val TIPS_AND_SUPPORT = "tips_and_support"
|
const val TIPS_AND_SUPPORT = "tips_and_support"
|
||||||
}
|
}
|
|
@ -4,7 +4,6 @@ import androidx.lifecycle.ViewModel
|
||||||
import androidx.paging.*
|
import androidx.paging.*
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
import com.google.accompanist.pager.PagerState
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
|
@ -25,7 +24,7 @@ class HomeViewModel @Inject constructor(
|
||||||
private val stringsRepository: StringsRepository,
|
private val stringsRepository: StringsRepository,
|
||||||
@ApplicationScope
|
@ApplicationScope
|
||||||
private val applicationScope: CoroutineScope,
|
private val applicationScope: CoroutineScope,
|
||||||
workManager: WorkManager,
|
private val workManager: WorkManager,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val _viewState = MutableStateFlow(HomeViewState())
|
private val _viewState = MutableStateFlow(HomeViewState())
|
||||||
|
@ -115,7 +114,6 @@ data class FilterState(
|
||||||
|
|
||||||
@OptIn(ExperimentalPagerApi::class)
|
@OptIn(ExperimentalPagerApi::class)
|
||||||
data class HomeViewState(
|
data class HomeViewState(
|
||||||
val pagerState: PagerState = PagerState(0),
|
|
||||||
val pagingData: Flow<PagingData<FlowItemView>> = emptyFlow(),
|
val pagingData: Flow<PagingData<FlowItemView>> = emptyFlow(),
|
||||||
val searchContent: String = "",
|
val searchContent: String = "",
|
||||||
)
|
)
|
||||||
|
|
|
@ -132,7 +132,7 @@ fun FeedsPage(
|
||||||
showBadge = latestVersion.whetherNeedUpdate(currentVersion, skipVersion),
|
showBadge = latestVersion.whetherNeedUpdate(currentVersion, skipVersion),
|
||||||
) {
|
) {
|
||||||
navController.navigate(RouteName.SETTINGS) {
|
navController.navigate(RouteName.SETTINGS) {
|
||||||
popUpTo(RouteName.FEEDS)
|
launchSingleTop = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -271,7 +271,7 @@ private fun filterChange(
|
||||||
homeViewModel.dispatch(HomeViewAction.ChangeFilter(filterState))
|
homeViewModel.dispatch(HomeViewAction.ChangeFilter(filterState))
|
||||||
if (isNavigate) {
|
if (isNavigate) {
|
||||||
navController.navigate(RouteName.FLOW) {
|
navController.navigate(RouteName.FLOW) {
|
||||||
popUpTo(RouteName.FEEDS)
|
launchSingleTop = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -113,8 +113,14 @@ fun FlowPage(
|
||||||
tint = MaterialTheme.colorScheme.onSurface
|
tint = MaterialTheme.colorScheme.onSurface
|
||||||
) {
|
) {
|
||||||
onSearch = false
|
onSearch = false
|
||||||
|
if(navController.previousBackStackEntry == null) {
|
||||||
|
navController.navigate(RouteName.FEEDS) {
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
navController.popBackStack()
|
navController.popBackStack()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
|
@ -241,7 +247,7 @@ fun FlowPage(
|
||||||
) {
|
) {
|
||||||
onSearch = false
|
onSearch = false
|
||||||
navController.navigate("${RouteName.READING}/${it.article.id}") {
|
navController.navigate("${RouteName.READING}/${it.article.id}") {
|
||||||
popUpTo(RouteName.FLOW)
|
launchSingleTop = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
|
|
|
@ -27,6 +27,9 @@ import me.ash.reader.ui.ext.DataStoreKeys
|
||||||
import me.ash.reader.ui.ext.dataStore
|
import me.ash.reader.ui.ext.dataStore
|
||||||
import me.ash.reader.ui.ext.getCurrentVersion
|
import me.ash.reader.ui.ext.getCurrentVersion
|
||||||
import me.ash.reader.ui.page.common.RouteName
|
import me.ash.reader.ui.page.common.RouteName
|
||||||
|
import me.ash.reader.ui.page.settings.tips.UpdateDialog
|
||||||
|
import me.ash.reader.ui.page.settings.tips.UpdateViewAction
|
||||||
|
import me.ash.reader.ui.page.settings.tips.UpdateViewModel
|
||||||
import me.ash.reader.ui.theme.palette.onLight
|
import me.ash.reader.ui.theme.palette.onLight
|
||||||
|
|
||||||
@SuppressLint("FlowOperatorInvokedInComposition")
|
@SuppressLint("FlowOperatorInvokedInComposition")
|
||||||
|
@ -120,7 +123,7 @@ fun SettingsPage(
|
||||||
icon = Icons.Outlined.Palette,
|
icon = Icons.Outlined.Palette,
|
||||||
) {
|
) {
|
||||||
navController.navigate(RouteName.COLOR_AND_STYLE) {
|
navController.navigate(RouteName.COLOR_AND_STYLE) {
|
||||||
popUpTo(RouteName.SETTINGS)
|
launchSingleTop = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,8 +132,11 @@ fun SettingsPage(
|
||||||
title = stringResource(R.string.interaction),
|
title = stringResource(R.string.interaction),
|
||||||
desc = stringResource(R.string.interaction_desc),
|
desc = stringResource(R.string.interaction_desc),
|
||||||
icon = Icons.Outlined.TouchApp,
|
icon = Icons.Outlined.TouchApp,
|
||||||
enable = false,
|
) {
|
||||||
) {}
|
navController.navigate(RouteName.INTERACTION) {
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
SelectableSettingGroupItem(
|
SelectableSettingGroupItem(
|
||||||
|
@ -147,7 +153,7 @@ fun SettingsPage(
|
||||||
icon = Icons.Outlined.TipsAndUpdates,
|
icon = Icons.Outlined.TipsAndUpdates,
|
||||||
) {
|
) {
|
||||||
navController.navigate(RouteName.TIPS_AND_SUPPORT) {
|
navController.navigate(RouteName.TIPS_AND_SUPPORT) {
|
||||||
popUpTo(RouteName.SETTINGS)
|
launchSingleTop = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package me.ash.reader.ui.page.settings
|
package me.ash.reader.ui.page.settings.color
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
@ -30,6 +30,7 @@ import kotlinx.coroutines.launch
|
||||||
import me.ash.reader.R
|
import me.ash.reader.R
|
||||||
import me.ash.reader.ui.component.*
|
import me.ash.reader.ui.component.*
|
||||||
import me.ash.reader.ui.ext.*
|
import me.ash.reader.ui.ext.*
|
||||||
|
import me.ash.reader.ui.page.settings.SettingItem
|
||||||
import me.ash.reader.ui.svg.PALETTE
|
import me.ash.reader.ui.svg.PALETTE
|
||||||
import me.ash.reader.ui.svg.SVGString
|
import me.ash.reader.ui.svg.SVGString
|
||||||
import me.ash.reader.ui.theme.LocalUseDarkTheme
|
import me.ash.reader.ui.theme.LocalUseDarkTheme
|
||||||
|
@ -101,11 +102,11 @@ fun ColorAndStyle(
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
BlockButtonRadios(
|
BlockRadioGroupButton(
|
||||||
selected = radioButtonSelected,
|
selected = radioButtonSelected,
|
||||||
onSelected = { radioButtonSelected = it },
|
onSelected = { radioButtonSelected = it },
|
||||||
items = listOf(
|
itemRadioGroups = listOf(
|
||||||
BlockButtonRadiosItem(
|
BlockRadioGroupButtonItem(
|
||||||
text = stringResource(R.string.wallpaper_colors),
|
text = stringResource(R.string.wallpaper_colors),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
) {
|
) {
|
||||||
|
@ -120,7 +121,7 @@ fun ColorAndStyle(
|
||||||
themeIndexPrefix = 5,
|
themeIndexPrefix = 5,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
BlockButtonRadiosItem(
|
BlockRadioGroupButtonItem(
|
||||||
text = stringResource(R.string.basic_colors),
|
text = stringResource(R.string.basic_colors),
|
||||||
onClick = {},
|
onClick = {},
|
||||||
) {
|
) {
|
|
@ -0,0 +1,168 @@
|
||||||
|
package me.ash.reader.ui.page.settings.interaction
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.ArrowBack
|
||||||
|
import androidx.compose.material3.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import me.ash.reader.R
|
||||||
|
import me.ash.reader.ui.component.*
|
||||||
|
import me.ash.reader.ui.ext.DataStoreKeys
|
||||||
|
import me.ash.reader.ui.ext.dataStore
|
||||||
|
import me.ash.reader.ui.ext.put
|
||||||
|
import me.ash.reader.ui.page.settings.SettingItem
|
||||||
|
import me.ash.reader.ui.theme.palette.onLight
|
||||||
|
|
||||||
|
@SuppressLint("FlowOperatorInvokedInComposition")
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun Interaction(
|
||||||
|
navController: NavHostController,
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val view = LocalView.current
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
var initialPageDialogVisible by remember { mutableStateOf(false) }
|
||||||
|
var initialFilterDialogVisible by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val initialPage = context.dataStore.data
|
||||||
|
.map { it[DataStoreKeys.InitialPage.key] ?: 0 }
|
||||||
|
.collectAsState(initial = 0).value
|
||||||
|
|
||||||
|
val initialFilter = context.dataStore.data
|
||||||
|
.map { it[DataStoreKeys.InitialFilter.key] ?: 2 }
|
||||||
|
.collectAsState(initial = 2).value
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface)
|
||||||
|
.statusBarsPadding()
|
||||||
|
.navigationBarsPadding(),
|
||||||
|
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
|
||||||
|
topBar = {
|
||||||
|
SmallTopAppBar(
|
||||||
|
colors = TopAppBarDefaults.smallTopAppBarColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface
|
||||||
|
),
|
||||||
|
title = {},
|
||||||
|
navigationIcon = {
|
||||||
|
FeedbackIconButton(
|
||||||
|
imageVector = Icons.Rounded.ArrowBack,
|
||||||
|
contentDescription = stringResource(R.string.back),
|
||||||
|
tint = MaterialTheme.colorScheme.onSurface
|
||||||
|
) {
|
||||||
|
navController.popBackStack()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions = {}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
content = {
|
||||||
|
LazyColumn {
|
||||||
|
item {
|
||||||
|
DisplayText(text = stringResource(R.string.interaction), desc = "")
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Subtitle(
|
||||||
|
modifier = Modifier.padding(horizontal = 24.dp),
|
||||||
|
text = stringResource(R.string.on_start),
|
||||||
|
)
|
||||||
|
SettingItem(
|
||||||
|
title = stringResource(R.string.initial_page),
|
||||||
|
desc = when (initialPage) {
|
||||||
|
0 -> stringResource(R.string.feeds_page)
|
||||||
|
1 -> stringResource(R.string.flow_page)
|
||||||
|
else -> ""
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
initialPageDialogVisible = true
|
||||||
|
},
|
||||||
|
) {}
|
||||||
|
SettingItem(
|
||||||
|
title = stringResource(R.string.initial_filter),
|
||||||
|
desc = when (initialFilter) {
|
||||||
|
0 -> stringResource(R.string.starred)
|
||||||
|
1 -> stringResource(R.string.unread)
|
||||||
|
2 -> stringResource(R.string.all)
|
||||||
|
else -> ""
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
initialFilterDialogVisible = true
|
||||||
|
},
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
RadioDialog(
|
||||||
|
visible = initialPageDialogVisible,
|
||||||
|
title = stringResource(R.string.initial_page),
|
||||||
|
options = listOf(
|
||||||
|
RadioDialogOption(
|
||||||
|
text = stringResource(R.string.feeds_page),
|
||||||
|
selected = initialPage == 0,
|
||||||
|
) {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
context.dataStore.put(DataStoreKeys.InitialPage, 0)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RadioDialogOption(
|
||||||
|
text = stringResource(R.string.flow_page),
|
||||||
|
selected = initialPage == 1,
|
||||||
|
) {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
context.dataStore.put(DataStoreKeys.InitialPage, 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
initialPageDialogVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioDialog(
|
||||||
|
visible = initialFilterDialogVisible,
|
||||||
|
title = stringResource(R.string.initial_filter),
|
||||||
|
options = listOf(
|
||||||
|
RadioDialogOption(
|
||||||
|
text = stringResource(R.string.starred),
|
||||||
|
selected = initialFilter == 0,
|
||||||
|
) {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
context.dataStore.put(DataStoreKeys.InitialFilter, 0)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RadioDialogOption(
|
||||||
|
text = stringResource(R.string.unread),
|
||||||
|
selected = initialFilter == 1,
|
||||||
|
) {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
context.dataStore.put(DataStoreKeys.InitialFilter, 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RadioDialogOption(
|
||||||
|
text = stringResource(R.string.all),
|
||||||
|
selected = initialFilter == 2,
|
||||||
|
) {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
context.dataStore.put(DataStoreKeys.InitialFilter, 2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
initialFilterDialogVisible = false
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package me.ash.reader.ui.page.settings
|
package me.ash.reader.ui.page.settings.tips
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
|
@ -1,4 +1,4 @@
|
||||||
package me.ash.reader.ui.page.settings
|
package me.ash.reader.ui.page.settings.tips
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
|
@ -1,4 +1,4 @@
|
||||||
package me.ash.reader.ui.page.settings
|
package me.ash.reader.ui.page.settings.tips
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
|
@ -102,7 +102,9 @@ fun StartupPage(
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
ExtendedFloatingActionButton(
|
ExtendedFloatingActionButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
navController.navigate(RouteName.FEEDS)
|
navController.navigate(RouteName.FEEDS) {
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
scope.launch {
|
scope.launch {
|
||||||
context.dataStore.put(DataStoreKeys.IsFirstLaunch, false)
|
context.dataStore.put(DataStoreKeys.IsFirstLaunch, false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
<string name="color_and_style">颜色和样式</string>
|
<string name="color_and_style">颜色和样式</string>
|
||||||
<string name="color_and_style_desc">主题、色彩系统、字体大小</string>
|
<string name="color_and_style_desc">主题、色彩系统、字体大小</string>
|
||||||
<string name="interaction">交互</string>
|
<string name="interaction">交互</string>
|
||||||
<string name="interaction_desc">布局、触感反馈</string>
|
<string name="interaction_desc">启动时、触感反馈</string>
|
||||||
<string name="languages">语言</string>
|
<string name="languages">语言</string>
|
||||||
<string name="languages_desc">英语、中文</string>
|
<string name="languages_desc">英语、中文</string>
|
||||||
<string name="tips_and_support">提示和支持</string>
|
<string name="tips_and_support">提示和支持</string>
|
||||||
|
@ -121,4 +121,7 @@
|
||||||
<string name="download_failure">下载失败</string>
|
<string name="download_failure">下载失败</string>
|
||||||
<string name="rate_limit">请求速率受限</string>
|
<string name="rate_limit">请求速率受限</string>
|
||||||
<string name="help">帮助</string>
|
<string name="help">帮助</string>
|
||||||
|
<string name="on_start">启动时</string>
|
||||||
|
<string name="initial_page">起始页面</string>
|
||||||
|
<string name="initial_filter">起始过滤条件</string>
|
||||||
</resources>
|
</resources>
|
|
@ -81,7 +81,7 @@
|
||||||
<string name="color_and_style">Color & style</string>
|
<string name="color_and_style">Color & style</string>
|
||||||
<string name="color_and_style_desc">Theme, color system, font size</string>
|
<string name="color_and_style_desc">Theme, color system, font size</string>
|
||||||
<string name="interaction">Interaction</string>
|
<string name="interaction">Interaction</string>
|
||||||
<string name="interaction_desc">Layout, haptic feedback</string>
|
<string name="interaction_desc">On start, haptic feedback</string>
|
||||||
<string name="languages">Languages</string>
|
<string name="languages">Languages</string>
|
||||||
<string name="languages_desc">English, Chinese</string>
|
<string name="languages_desc">English, Chinese</string>
|
||||||
<string name="tips_and_support">Tips & support</string>
|
<string name="tips_and_support">Tips & support</string>
|
||||||
|
@ -121,4 +121,7 @@
|
||||||
<string name="download_failure">Download failure</string>
|
<string name="download_failure">Download failure</string>
|
||||||
<string name="rate_limit">The request rate is limited</string>
|
<string name="rate_limit">The request rate is limited</string>
|
||||||
<string name="help">Help</string>
|
<string name="help">Help</string>
|
||||||
|
<string name="on_start">On Start</string>
|
||||||
|
<string name="initial_page">Initial Page</string>
|
||||||
|
<string name="initial_filter">Initial Filter</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user