Extract Scaffold component

This commit is contained in:
Ash 2022-05-18 05:41:21 +08:00
parent 27e8780d82
commit dcbb41f3ab
22 changed files with 487 additions and 524 deletions

View File

@ -0,0 +1,45 @@
package me.ash.reader.data.preference
import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import me.ash.reader.R
import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put
sealed class InitialFilterPreference(val value: Int) : Preference() {
object Starred : InitialFilterPreference(0)
object Unread : InitialFilterPreference(1)
object All : InitialFilterPreference(2)
override fun put(context: Context, scope: CoroutineScope) {
scope.launch {
context.dataStore.put(
DataStoreKeys.InitialFilter,
value
)
}
}
fun getDesc(context: Context): String =
when (this) {
Starred -> context.getString(R.string.starred)
Unread -> context.getString(R.string.unread)
All -> context.getString(R.string.all)
}
companion object {
val default = All
val values = listOf(Starred, Unread, All)
fun fromPreferences(preferences: Preferences) =
when (preferences[DataStoreKeys.InitialFilter.key]) {
0 -> Starred
1 -> Unread
2 -> All
else -> default
}
}
}

View File

@ -0,0 +1,42 @@
package me.ash.reader.data.preference
import android.content.Context
import androidx.datastore.preferences.core.Preferences
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import me.ash.reader.R
import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put
sealed class InitialPagePreference(val value: Int) : Preference() {
object FeedsPage : InitialPagePreference(0)
object FlowPage : InitialPagePreference(1)
override fun put(context: Context, scope: CoroutineScope) {
scope.launch {
context.dataStore.put(
DataStoreKeys.InitialPage,
value
)
}
}
fun getDesc(context: Context): String =
when (this) {
FeedsPage -> context.getString(R.string.feeds_page)
FlowPage -> context.getString(R.string.flow_page)
}
companion object {
val default = FeedsPage
val values = listOf(FeedsPage, FlowPage)
fun fromPreferences(preferences: Preferences) =
when (preferences[DataStoreKeys.InitialPage.key]) {
0 -> FeedsPage
1 -> FlowPage
else -> default
}
}
}

View File

@ -45,6 +45,9 @@ fun Preferences.toSettings(): Settings {
), ),
flowArticleListTonalElevation = FlowArticleListTonalElevationPreference.fromPreferences(this), flowArticleListTonalElevation = FlowArticleListTonalElevationPreference.fromPreferences(this),
initialPage = InitialPagePreference.fromPreferences(this),
initialFilter = InitialFilterPreference.fromPreferences(this),
languages = LanguagesPreference.fromPreferences(this), languages = LanguagesPreference.fromPreferences(this),
) )
} }

View File

@ -45,6 +45,9 @@ data class Settings(
val flowArticleListDateStickyHeader: FlowArticleListDateStickyHeaderPreference = FlowArticleListDateStickyHeaderPreference.default, val flowArticleListDateStickyHeader: FlowArticleListDateStickyHeaderPreference = FlowArticleListDateStickyHeaderPreference.default,
val flowArticleListTonalElevation: FlowArticleListTonalElevationPreference = FlowArticleListTonalElevationPreference.default, val flowArticleListTonalElevation: FlowArticleListTonalElevationPreference = FlowArticleListTonalElevationPreference.default,
val initialPage: InitialPagePreference = InitialPagePreference.default,
val initialFilter: InitialFilterPreference = InitialFilterPreference.default,
val languages: LanguagesPreference = LanguagesPreference.default, val languages: LanguagesPreference = LanguagesPreference.default,
) )
@ -94,6 +97,9 @@ fun SettingsProvider(
LocalFlowFilterBarPadding provides settings.flowFilterBarPadding, LocalFlowFilterBarPadding provides settings.flowFilterBarPadding,
LocalFlowFilterBarTonalElevation provides settings.flowFilterBarTonalElevation, LocalFlowFilterBarTonalElevation provides settings.flowFilterBarTonalElevation,
LocalInitialPage provides settings.initialPage,
LocalInitialFilter provides settings.initialFilter,
LocalLanguages provides settings.languages, LocalLanguages provides settings.languages,
) { ) {
content() content()
@ -156,5 +162,9 @@ val LocalFlowArticleListDateStickyHeader =
val LocalFlowArticleListTonalElevation = val LocalFlowArticleListTonalElevation =
compositionLocalOf<FlowArticleListTonalElevationPreference> { FlowArticleListTonalElevationPreference.default } compositionLocalOf<FlowArticleListTonalElevationPreference> { FlowArticleListTonalElevationPreference.default }
val LocalInitialPage = compositionLocalOf<InitialPagePreference> { InitialPagePreference.default }
val LocalInitialFilter =
compositionLocalOf<InitialFilterPreference> { InitialFilterPreference.default }
val LocalLanguages = val LocalLanguages =
compositionLocalOf<LanguagesPreference> { LanguagesPreference.default } compositionLocalOf<LanguagesPreference> { LanguagesPreference.default }

View File

@ -4,7 +4,6 @@ import android.os.Build
import android.view.SoundEffectConstants import android.view.SoundEffectConstants
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -34,8 +33,7 @@ fun FilterBar(
NavigationBar( NavigationBar(
modifier = Modifier modifier = Modifier
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(filterBarTonalElevation)) .background(MaterialTheme.colorScheme.surfaceColorAtElevation(filterBarTonalElevation)),
.navigationBarsPadding(),
tonalElevation = filterBarTonalElevation, tonalElevation = filterBarTonalElevation,
) { ) {
Spacer(modifier = Modifier.width(filterBarPadding)) Spacer(modifier = Modifier.width(filterBarPadding))

View File

@ -0,0 +1,69 @@
package me.ash.reader.ui.component.base
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import me.ash.reader.ui.ext.surfaceColorAtElevation
import me.ash.reader.ui.theme.palette.onDark
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Scaffold(
containerColor: Color = MaterialTheme.colorScheme.surface,
topBarTonalElevation: Dp = 0.dp,
containerTonalElevation: Dp = 0.dp,
navigationIcon: (@Composable () -> Unit)? = null,
actions: (@Composable RowScope.() -> Unit)? = null,
bottomBar: (@Composable () -> Unit)? = null,
floatingActionButton: (@Composable () -> Unit)? = null,
content: @Composable () -> Unit = {},
) {
androidx.compose.material3.Scaffold(
modifier = Modifier
.background(
MaterialTheme.colorScheme.surfaceColorAtElevation(
topBarTonalElevation,
color = containerColor
)
)
.statusBarsPadding()
.run {
if (bottomBar != null || floatingActionButton != null) {
navigationBarsPadding()
} else {
this
}
},
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
containerTonalElevation,
color = containerColor
) onDark MaterialTheme.colorScheme.surface,
topBar = {
if (navigationIcon != null || actions != null) {
SmallTopAppBar(
title = {},
colors = TopAppBarDefaults.smallTopAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
topBarTonalElevation, color = containerColor
),
),
navigationIcon = { navigationIcon?.invoke() },
actions = { actions?.invoke(this) },
)
}
},
content = { content() },
bottomBar = { bottomBar?.invoke() },
floatingActionButton = { floatingActionButton?.invoke() },
)
}

View File

@ -85,7 +85,7 @@ sealed class DataStoreKeys<T> {
object NewVersionSize : DataStoreKeys<String>() { object NewVersionSize : DataStoreKeys<String>() {
override val key: Preferences.Key<String> override val key: Preferences.Key<String>
get() = stringPreferencesKey("newVersionSize") get() = stringPreferencesKey("newVersionSizeString")
} }
object NewVersionDownloadUrl : DataStoreKeys<String>() { object NewVersionDownloadUrl : DataStoreKeys<String>() {

View File

@ -21,13 +21,13 @@ 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.SettingsPage import me.ash.reader.ui.page.settings.SettingsPage
import me.ash.reader.ui.page.settings.color.ColorAndStyle import me.ash.reader.ui.page.settings.color.ColorAndStylePage
import me.ash.reader.ui.page.settings.color.DarkTheme import me.ash.reader.ui.page.settings.color.DarkThemePage
import me.ash.reader.ui.page.settings.color.feeds.FeedsPageStyle import me.ash.reader.ui.page.settings.color.feeds.FeedsPageStylePage
import me.ash.reader.ui.page.settings.color.flow.FlowPageStyle import me.ash.reader.ui.page.settings.color.flow.FlowPageStylePage
import me.ash.reader.ui.page.settings.interaction.Interaction import me.ash.reader.ui.page.settings.interaction.InteractionPage
import me.ash.reader.ui.page.settings.languages.Languages import me.ash.reader.ui.page.settings.languages.LanguagesPage
import me.ash.reader.ui.page.settings.tips.TipsAndSupport import me.ash.reader.ui.page.settings.tips.TipsAndSupportPage
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
@ -124,31 +124,31 @@ fun HomeEntry(
// Color & Style // Color & Style
animatedComposable(route = RouteName.COLOR_AND_STYLE) { animatedComposable(route = RouteName.COLOR_AND_STYLE) {
ColorAndStyle(navController) ColorAndStylePage(navController)
} }
animatedComposable(route = RouteName.DARK_THEME) { animatedComposable(route = RouteName.DARK_THEME) {
DarkTheme(navController) DarkThemePage(navController)
} }
animatedComposable(route = RouteName.FEEDS_PAGE_STYLE) { animatedComposable(route = RouteName.FEEDS_PAGE_STYLE) {
FeedsPageStyle(navController) FeedsPageStylePage(navController)
} }
animatedComposable(route = RouteName.FLOW_PAGE_STYLE) { animatedComposable(route = RouteName.FLOW_PAGE_STYLE) {
FlowPageStyle(navController) FlowPageStylePage(navController)
} }
// Interaction // Interaction
animatedComposable(route = RouteName.INTERACTION) { animatedComposable(route = RouteName.INTERACTION) {
Interaction(navController) InteractionPage(navController)
} }
// Languages // Languages
animatedComposable(route = RouteName.LANGUAGES) { animatedComposable(route = RouteName.LANGUAGES) {
Languages(navController = navController) LanguagesPage(navController = navController)
} }
// Tips & Support // Tips & Support
animatedComposable(route = RouteName.TIPS_AND_SUPPORT) { animatedComposable(route = RouteName.TIPS_AND_SUPPORT) {
TipsAndSupport(navController) TipsAndSupportPage(navController)
} }
} }
} }

View File

@ -1,11 +1,9 @@
package me.ash.reader.ui.page.home.feeds package me.ash.reader.ui.page.home.feeds
import android.annotation.SuppressLint
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.core.* import androidx.compose.animation.core.*
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
@ -15,7 +13,8 @@ import androidx.compose.material.icons.outlined.KeyboardArrowRight
import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.rounded.Add import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.Refresh import androidx.compose.material.icons.rounded.Refresh
import androidx.compose.material3.* import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate import androidx.compose.ui.draw.rotate
@ -38,7 +37,6 @@ import me.ash.reader.ui.component.base.Subtitle
import me.ash.reader.ui.ext.collectAsStateValue import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.findActivity import me.ash.reader.ui.ext.findActivity
import me.ash.reader.ui.ext.getCurrentVersion import me.ash.reader.ui.ext.getCurrentVersion
import me.ash.reader.ui.ext.surfaceColorAtElevation
import me.ash.reader.ui.page.common.RouteName import me.ash.reader.ui.page.common.RouteName
import me.ash.reader.ui.page.home.FilterState import me.ash.reader.ui.page.home.FilterState
import me.ash.reader.ui.page.home.HomeViewAction import me.ash.reader.ui.page.home.HomeViewAction
@ -48,11 +46,9 @@ import me.ash.reader.ui.page.home.feeds.drawer.group.GroupOptionDrawer
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeDialog import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeDialog
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewAction import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewAction
import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel import me.ash.reader.ui.page.home.feeds.subscribe.SubscribeViewModel
import me.ash.reader.ui.theme.palette.onDark
@SuppressLint("FlowOperatorInvokedInComposition")
@OptIn( @OptIn(
ExperimentalMaterial3Api::class, com.google.accompanist.pager.ExperimentalPagerApi::class, com.google.accompanist.pager.ExperimentalPagerApi::class,
androidx.compose.foundation.ExperimentalFoundationApi::class androidx.compose.foundation.ExperimentalFoundationApi::class
) )
@Composable @Composable
@ -119,52 +115,38 @@ fun FeedsPage(
context.findActivity()?.moveTaskToBack(false) context.findActivity()?.moveTaskToBack(false)
} }
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier topBarTonalElevation = topBarTonalElevation.value.dp,
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(topBarTonalElevation.value.dp)) containerTonalElevation = groupListTonalElevation.value.dp,
.statusBarsPadding(), navigationIcon = {
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( FeedbackIconButton(
groupListTonalElevation.value.dp modifier = Modifier.size(20.dp),
) onDark MaterialTheme.colorScheme.surface, imageVector = Icons.Outlined.Settings,
topBar = { contentDescription = stringResource(R.string.settings),
SmallTopAppBar( tint = MaterialTheme.colorScheme.onSurface,
colors = TopAppBarDefaults.smallTopAppBarColors( showBadge = newVersion.whetherNeedUpdate(currentVersion, skipVersion),
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( ) {
topBarTonalElevation.value.dp navController.navigate(RouteName.SETTINGS) {
), launchSingleTop = true
),
title = {},
navigationIcon = {
FeedbackIconButton(
modifier = Modifier.size(20.dp),
imageVector = Icons.Outlined.Settings,
contentDescription = stringResource(R.string.settings),
tint = MaterialTheme.colorScheme.onSurface,
showBadge = newVersion.whetherNeedUpdate(currentVersion, skipVersion),
) {
navController.navigate(RouteName.SETTINGS) {
launchSingleTop = true
}
}
},
actions = {
FeedbackIconButton(
modifier = Modifier.rotate(if (isSyncing) angle else 0f),
imageVector = Icons.Rounded.Refresh,
contentDescription = stringResource(R.string.refresh),
tint = MaterialTheme.colorScheme.onSurface,
) {
if (!isSyncing) homeViewModel.dispatch(HomeViewAction.Sync)
}
FeedbackIconButton(
imageVector = Icons.Rounded.Add,
contentDescription = stringResource(R.string.subscribe),
tint = MaterialTheme.colorScheme.onSurface,
) {
subscribeViewModel.dispatch(SubscribeViewAction.Show)
}
} }
) }
},
actions = {
FeedbackIconButton(
modifier = Modifier.rotate(if (isSyncing) angle else 0f),
imageVector = Icons.Rounded.Refresh,
contentDescription = stringResource(R.string.refresh),
tint = MaterialTheme.colorScheme.onSurface,
) {
if (!isSyncing) homeViewModel.dispatch(HomeViewAction.Sync)
}
FeedbackIconButton(
imageVector = Icons.Rounded.Add,
contentDescription = stringResource(R.string.subscribe),
tint = MaterialTheme.colorScheme.onSurface,
) {
subscribeViewModel.dispatch(SubscribeViewAction.Show)
}
}, },
content = { content = {
LazyColumn { LazyColumn {

View File

@ -2,7 +2,6 @@ package me.ash.reader.ui.page.home.flow
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.animation.* import androidx.compose.animation.*
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
@ -10,7 +9,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowBack import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.DoneAll import androidx.compose.material.icons.rounded.DoneAll
import androidx.compose.material.icons.rounded.Search import androidx.compose.material.icons.rounded.Search
import androidx.compose.material3.* import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
@ -33,15 +32,12 @@ import me.ash.reader.ui.component.base.DisplayText
import me.ash.reader.ui.component.base.FeedbackIconButton import me.ash.reader.ui.component.base.FeedbackIconButton
import me.ash.reader.ui.component.base.SwipeRefresh import me.ash.reader.ui.component.base.SwipeRefresh
import me.ash.reader.ui.ext.collectAsStateValue import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.surfaceColorAtElevation
import me.ash.reader.ui.page.common.RouteName import me.ash.reader.ui.page.common.RouteName
import me.ash.reader.ui.page.home.FilterState import me.ash.reader.ui.page.home.FilterState
import me.ash.reader.ui.page.home.HomeViewAction import me.ash.reader.ui.page.home.HomeViewAction
import me.ash.reader.ui.page.home.HomeViewModel import me.ash.reader.ui.page.home.HomeViewModel
import me.ash.reader.ui.theme.palette.onDark
@OptIn( @OptIn(
ExperimentalMaterial3Api::class,
com.google.accompanist.pager.ExperimentalPagerApi::class, com.google.accompanist.pager.ExperimentalPagerApi::class,
androidx.compose.ui.ExperimentalComposeUiApi::class, androidx.compose.ui.ExperimentalComposeUiApi::class,
) )
@ -105,75 +101,61 @@ fun FlowPage(
onSearch = false onSearch = false
} }
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier topBarTonalElevation = topBarTonalElevation.value.dp,
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(topBarTonalElevation.value.dp)) containerTonalElevation = articleListTonalElevation.value.dp,
.statusBarsPadding(), navigationIcon = {
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( FeedbackIconButton(
articleListTonalElevation.value.dp imageVector = Icons.Rounded.ArrowBack,
) onDark MaterialTheme.colorScheme.surface, contentDescription = stringResource(R.string.back),
topBar = { tint = MaterialTheme.colorScheme.onSurface
SmallTopAppBar( ) {
title = {}, onSearch = false
colors = TopAppBarDefaults.smallTopAppBarColors( if (navController.previousBackStackEntry == null) {
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( navController.navigate(RouteName.FEEDS) {
topBarTonalElevation.value.dp launchSingleTop = true
), }
), } else {
navigationIcon = { navController.popBackStack()
FeedbackIconButton( }
imageVector = Icons.Rounded.ArrowBack, }
contentDescription = stringResource(R.string.back), },
tint = MaterialTheme.colorScheme.onSurface actions = {
) { AnimatedVisibility(
visible = !filterState.filter.isStarred(),
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically(),
) {
FeedbackIconButton(
imageVector = Icons.Rounded.DoneAll,
contentDescription = stringResource(R.string.mark_all_as_read),
tint = if (markAsRead) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onSurface
},
) {
scope.launch {
viewState.listState.scrollToItem(0)
markAsRead = !markAsRead
onSearch = false onSearch = false
if (navController.previousBackStackEntry == null) {
navController.navigate(RouteName.FEEDS) {
launchSingleTop = true
}
} else {
navController.popBackStack()
}
}
},
actions = {
AnimatedVisibility(
visible = !filterState.filter.isStarred(),
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically(),
) {
FeedbackIconButton(
imageVector = Icons.Rounded.DoneAll,
contentDescription = stringResource(R.string.mark_all_as_read),
tint = if (markAsRead) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onSurface
},
) {
scope.launch {
viewState.listState.scrollToItem(0)
markAsRead = !markAsRead
onSearch = false
}
}
}
FeedbackIconButton(
imageVector = Icons.Rounded.Search,
contentDescription = stringResource(R.string.search),
tint = if (onSearch) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onSurface
},
) {
scope.launch {
viewState.listState.scrollToItem(0)
onSearch = !onSearch
}
} }
} }
) }
FeedbackIconButton(
imageVector = Icons.Rounded.Search,
contentDescription = stringResource(R.string.search),
tint = if (onSearch) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onSurface
},
) {
scope.launch {
viewState.listState.scrollToItem(0)
onSearch = !onSearch
}
}
}, },
content = { content = {
SwipeRefresh( SwipeRefresh(

View File

@ -11,7 +11,10 @@ import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Share import androidx.compose.material.icons.outlined.Share
import androidx.compose.material.icons.rounded.Close import androidx.compose.material.icons.rounded.Close
import androidx.compose.material3.* import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -28,7 +31,6 @@ import me.ash.reader.ui.component.reader.reader
import me.ash.reader.ui.ext.collectAsStateValue import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.drawVerticalScrollbar import me.ash.reader.ui.ext.drawVerticalScrollbar
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ReadPage( fun ReadPage(
navController: NavHostController, navController: NavHostController,
@ -54,9 +56,7 @@ fun ReadPage(
} }
} }
Scaffold( me.ash.reader.ui.component.base.Scaffold(
containerColor = MaterialTheme.colorScheme.surface,
topBar = {},
content = { content = {
Box(Modifier.fillMaxSize()) { Box(Modifier.fillMaxSize()) {
Box( Box(
@ -102,8 +102,7 @@ fun ReadPage(
) )
} }
} }
}, }
bottomBar = {}
) )
} }

View File

@ -1,14 +1,13 @@
package me.ash.reader.ui.page.settings package me.ash.reader.ui.page.settings
import android.annotation.SuppressLint
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.* import androidx.compose.material.icons.outlined.*
import androidx.compose.material.icons.rounded.ArrowBack import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.Close import androidx.compose.material.icons.rounded.Close
import androidx.compose.material3.* import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -33,8 +32,6 @@ import me.ash.reader.ui.page.settings.tips.UpdateViewAction
import me.ash.reader.ui.page.settings.tips.UpdateViewModel 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")
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun SettingsPage( fun SettingsPage(
navController: NavHostController, navController: NavHostController,
@ -45,27 +42,16 @@ fun SettingsPage(
val skipVersion = LocalSkipVersionNumber.current val skipVersion = LocalSkipVersionNumber.current
val currentVersion by remember { mutableStateOf(context.getCurrentVersion()) } val currentVersion by remember { mutableStateOf(context.getCurrentVersion()) }
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface)
.statusBarsPadding()
.navigationBarsPadding(),
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface, containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
topBar = { navigationIcon = {
SmallTopAppBar( FeedbackIconButton(
colors = TopAppBarDefaults.smallTopAppBarColors(containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface), imageVector = Icons.Rounded.ArrowBack,
title = {}, contentDescription = stringResource(R.string.back),
navigationIcon = { tint = MaterialTheme.colorScheme.onSurface
FeedbackIconButton( ) {
imageVector = Icons.Rounded.ArrowBack, navController.popBackStack()
contentDescription = stringResource(R.string.back), }
tint = MaterialTheme.colorScheme.onSurface
) {
navController.popBackStack()
}
},
actions = {}
)
}, },
content = { content = {
LazyColumn { LazyColumn {

View File

@ -37,7 +37,7 @@ import me.ash.reader.ui.theme.palette.dynamic.extractTonalPalettesFromUserWallpa
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun ColorAndStyle( fun ColorAndStylePage(
navController: NavHostController, navController: NavHostController,
) { ) {
val context = LocalContext.current val context = LocalContext.current
@ -50,29 +50,16 @@ fun ColorAndStyle(
val wallpaperTonalPalettes = extractTonalPalettesFromUserWallpaper() val wallpaperTonalPalettes = extractTonalPalettesFromUserWallpaper()
var radioButtonSelected by remember { mutableStateOf(if (themeIndex > 4) 0 else 1) } var radioButtonSelected by remember { mutableStateOf(if (themeIndex > 4) 0 else 1) }
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface)
.statusBarsPadding()
.navigationBarsPadding(),
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface, containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
topBar = { navigationIcon = {
SmallTopAppBar( FeedbackIconButton(
colors = TopAppBarDefaults.smallTopAppBarColors( imageVector = Icons.Rounded.ArrowBack,
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface contentDescription = stringResource(R.string.back),
), tint = MaterialTheme.colorScheme.onSurface
title = {}, ) {
navigationIcon = { navController.popBackStack()
FeedbackIconButton( }
imageVector = Icons.Rounded.ArrowBack,
contentDescription = stringResource(R.string.back),
tint = MaterialTheme.colorScheme.onSurface
) {
navController.popBackStack()
}
},
actions = {}
)
}, },
content = { content = {
LazyColumn { LazyColumn {

View File

@ -1,13 +1,12 @@
package me.ash.reader.ui.page.settings.color package me.ash.reader.ui.page.settings.color
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowBack import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material3.* import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -29,7 +28,7 @@ import me.ash.reader.ui.theme.palette.onLight
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun DarkTheme( fun DarkThemePage(
navController: NavHostController, navController: NavHostController,
) { ) {
val context = LocalContext.current val context = LocalContext.current
@ -37,29 +36,16 @@ fun DarkTheme(
val amoledDarkTheme = LocalAmoledDarkTheme.current val amoledDarkTheme = LocalAmoledDarkTheme.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface)
.statusBarsPadding()
.navigationBarsPadding(),
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface, containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
topBar = { navigationIcon = {
SmallTopAppBar( FeedbackIconButton(
colors = TopAppBarDefaults.smallTopAppBarColors( imageVector = Icons.Rounded.ArrowBack,
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface contentDescription = stringResource(R.string.back),
), tint = MaterialTheme.colorScheme.onSurface
title = {}, ) {
navigationIcon = { navController.popBackStack()
FeedbackIconButton( }
imageVector = Icons.Rounded.ArrowBack,
contentDescription = stringResource(R.string.back),
tint = MaterialTheme.colorScheme.onSurface
) {
navController.popBackStack()
}
},
actions = {}
)
}, },
content = { content = {
LazyColumn { LazyColumn {

View File

@ -10,7 +10,9 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Add import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.ArrowBack import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.Refresh import androidx.compose.material.icons.rounded.Refresh
import androidx.compose.material3.* import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -22,20 +24,19 @@ import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import me.ash.reader.R import me.ash.reader.R
import me.ash.reader.data.entity.Feed import me.ash.reader.data.entity.Feed
import me.ash.reader.data.model.Filter
import me.ash.reader.data.entity.Group import me.ash.reader.data.entity.Group
import me.ash.reader.data.model.Filter
import me.ash.reader.data.preference.* import me.ash.reader.data.preference.*
import me.ash.reader.ui.component.FilterBar
import me.ash.reader.ui.component.base.* import me.ash.reader.ui.component.base.*
import me.ash.reader.ui.ext.surfaceColorAtElevation import me.ash.reader.ui.ext.surfaceColorAtElevation
import me.ash.reader.ui.component.FilterBar
import me.ash.reader.ui.page.home.feeds.GroupItem import me.ash.reader.ui.page.home.feeds.GroupItem
import me.ash.reader.ui.page.settings.SettingItem import me.ash.reader.ui.page.settings.SettingItem
import me.ash.reader.ui.theme.palette.onDark import me.ash.reader.ui.theme.palette.onDark
import me.ash.reader.ui.theme.palette.onLight import me.ash.reader.ui.theme.palette.onLight
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun FeedsPageStyle( fun FeedsPageStylePage(
navController: NavHostController, navController: NavHostController,
) { ) {
val context = LocalContext.current val context = LocalContext.current
@ -57,29 +58,16 @@ fun FeedsPageStyle(
var filterBarPaddingValue: Int? by remember { mutableStateOf(filterBarPadding) } var filterBarPaddingValue: Int? by remember { mutableStateOf(filterBarPadding) }
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface)
.statusBarsPadding()
.navigationBarsPadding(),
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface, containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
topBar = { navigationIcon = {
SmallTopAppBar( FeedbackIconButton(
colors = TopAppBarDefaults.smallTopAppBarColors( imageVector = Icons.Rounded.ArrowBack,
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface contentDescription = stringResource(R.string.back),
), tint = MaterialTheme.colorScheme.onSurface
title = {}, ) {
navigationIcon = { navController.popBackStack()
FeedbackIconButton( }
imageVector = Icons.Rounded.ArrowBack,
contentDescription = stringResource(R.string.back),
tint = MaterialTheme.colorScheme.onSurface
) {
navController.popBackStack()
}
},
actions = {}
)
}, },
content = { content = {
LazyColumn { LazyColumn {

View File

@ -1,6 +1,5 @@
package me.ash.reader.ui.page.settings.color.flow package me.ash.reader.ui.page.settings.color.flow
import android.annotation.SuppressLint
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -11,7 +10,10 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowBack import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.DoneAll import androidx.compose.material.icons.rounded.DoneAll
import androidx.compose.material.icons.rounded.Search import androidx.compose.material.icons.rounded.Search
import androidx.compose.material3.* import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -27,19 +29,17 @@ import me.ash.reader.data.entity.ArticleWithFeed
import me.ash.reader.data.entity.Feed import me.ash.reader.data.entity.Feed
import me.ash.reader.data.model.Filter import me.ash.reader.data.model.Filter
import me.ash.reader.data.preference.* import me.ash.reader.data.preference.*
import me.ash.reader.ui.component.FilterBar
import me.ash.reader.ui.component.base.* import me.ash.reader.ui.component.base.*
import me.ash.reader.ui.ext.surfaceColorAtElevation import me.ash.reader.ui.ext.surfaceColorAtElevation
import me.ash.reader.ui.component.FilterBar
import me.ash.reader.ui.page.home.flow.ArticleItem import me.ash.reader.ui.page.home.flow.ArticleItem
import me.ash.reader.ui.page.settings.SettingItem import me.ash.reader.ui.page.settings.SettingItem
import me.ash.reader.ui.theme.palette.onDark import me.ash.reader.ui.theme.palette.onDark
import me.ash.reader.ui.theme.palette.onLight import me.ash.reader.ui.theme.palette.onLight
import java.util.* import java.util.*
@SuppressLint("FlowOperatorInvokedInComposition")
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun FlowPageStyle( fun FlowPageStylePage(
navController: NavHostController, navController: NavHostController,
) { ) {
val context = LocalContext.current val context = LocalContext.current
@ -66,29 +66,16 @@ fun FlowPageStyle(
var filterBarPaddingValue: Int? by remember { mutableStateOf(filterBarPadding) } var filterBarPaddingValue: Int? by remember { mutableStateOf(filterBarPadding) }
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface)
.statusBarsPadding()
.navigationBarsPadding(),
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface, containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
topBar = { navigationIcon = {
SmallTopAppBar( FeedbackIconButton(
colors = TopAppBarDefaults.smallTopAppBarColors( imageVector = Icons.Rounded.ArrowBack,
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface contentDescription = stringResource(R.string.back),
), tint = MaterialTheme.colorScheme.onSurface
title = {}, ) {
navigationIcon = { navController.popBackStack()
FeedbackIconButton( }
imageVector = Icons.Rounded.ArrowBack,
contentDescription = stringResource(R.string.back),
tint = MaterialTheme.colorScheme.onSurface
) {
navController.popBackStack()
}
},
actions = {}
)
}, },
content = { content = {
LazyColumn { LazyColumn {

View File

@ -1,164 +0,0 @@
package me.ash.reader.ui.page.settings.interaction
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.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
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.component.base.*
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
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Interaction(
navController: NavHostController,
) {
val context = LocalContext.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 {
context.dataStore.put(DataStoreKeys.InitialPage, 0)
}
},
RadioDialogOption(
text = stringResource(R.string.flow_page),
selected = initialPage == 1,
) {
scope.launch {
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 {
context.dataStore.put(DataStoreKeys.InitialFilter, 0)
}
},
RadioDialogOption(
text = stringResource(R.string.unread),
selected = initialFilter == 1,
) {
scope.launch {
context.dataStore.put(DataStoreKeys.InitialFilter, 1)
}
},
RadioDialogOption(
text = stringResource(R.string.all),
selected = initialFilter == 2,
) {
scope.launch {
context.dataStore.put(DataStoreKeys.InitialFilter, 2)
}
},
),
) {
initialFilterDialogVisible = false
}
}

View File

@ -0,0 +1,106 @@
package me.ash.reader.ui.page.settings.interaction
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import me.ash.reader.R
import me.ash.reader.data.preference.InitialFilterPreference
import me.ash.reader.data.preference.InitialPagePreference
import me.ash.reader.data.preference.LocalInitialFilter
import me.ash.reader.data.preference.LocalInitialPage
import me.ash.reader.ui.component.base.*
import me.ash.reader.ui.page.settings.SettingItem
import me.ash.reader.ui.theme.palette.onLight
@Composable
fun InteractionPage(
navController: NavHostController,
) {
val context = LocalContext.current
val initialPage = LocalInitialPage.current
val initialFilter = LocalInitialFilter.current
val scope = rememberCoroutineScope()
var initialPageDialogVisible by remember { mutableStateOf(false) }
var initialFilterDialogVisible by remember { mutableStateOf(false) }
me.ash.reader.ui.component.base.Scaffold(
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
navigationIcon = {
FeedbackIconButton(
imageVector = Icons.Rounded.ArrowBack,
contentDescription = stringResource(R.string.back),
tint = MaterialTheme.colorScheme.onSurface
) {
navController.popBackStack()
}
},
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 = initialPage.getDesc(context),
onClick = {
initialPageDialogVisible = true
},
) {}
SettingItem(
title = stringResource(R.string.initial_filter),
desc = initialFilter.getDesc(context),
onClick = {
initialFilterDialogVisible = true
},
) {}
}
}
}
)
RadioDialog(
visible = initialPageDialogVisible,
title = stringResource(R.string.initial_page),
options = InitialPagePreference.values.map {
RadioDialogOption(
text = it.getDesc(context),
selected = it == initialPage,
) {
it.put(context, scope)
}
},
) {
initialPageDialogVisible = false
}
RadioDialog(
visible = initialFilterDialogVisible,
title = stringResource(R.string.initial_filter),
options = InitialFilterPreference.values.map {
RadioDialogOption(
text = it.getDesc(context),
selected = it == initialFilter,
) {
it.put(context, scope)
}
},
) {
initialFilterDialogVisible = false
}
}

View File

@ -2,17 +2,17 @@ package me.ash.reader.ui.page.settings.languages
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.KeyboardArrowRight import androidx.compose.material.icons.outlined.KeyboardArrowRight
import androidx.compose.material.icons.outlined.Lightbulb import androidx.compose.material.icons.outlined.Lightbulb
import androidx.compose.material.icons.rounded.ArrowBack import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material3.* import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -31,36 +31,23 @@ import me.ash.reader.ui.theme.palette.onLight
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun Languages( fun LanguagesPage(
navController: NavHostController, navController: NavHostController,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val languages = LocalLanguages.current val languages = LocalLanguages.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface)
.statusBarsPadding()
.navigationBarsPadding(),
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface, containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
topBar = { navigationIcon = {
SmallTopAppBar( FeedbackIconButton(
colors = TopAppBarDefaults.smallTopAppBarColors( imageVector = Icons.Rounded.ArrowBack,
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface contentDescription = stringResource(R.string.back),
), tint = MaterialTheme.colorScheme.onSurface
title = {}, ) {
navigationIcon = { navController.popBackStack()
FeedbackIconButton( }
imageVector = Icons.Rounded.ArrowBack,
contentDescription = stringResource(R.string.back),
tint = MaterialTheme.colorScheme.onSurface
) {
navController.popBackStack()
}
},
actions = {}
)
}, },
content = { content = {
LazyColumn { LazyColumn {

View File

@ -42,15 +42,13 @@ import me.ash.reader.ui.ext.*
import me.ash.reader.ui.theme.palette.alwaysLight import me.ash.reader.ui.theme.palette.alwaysLight
import me.ash.reader.ui.theme.palette.onLight import me.ash.reader.ui.theme.palette.onLight
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun TipsAndSupport( fun TipsAndSupportPage(
navController: NavHostController, navController: NavHostController,
updateViewModel: UpdateViewModel = hiltViewModel(), updateViewModel: UpdateViewModel = hiltViewModel(),
) { ) {
val context = LocalContext.current val context = LocalContext.current
val view = LocalView.current val view = LocalView.current
val scope = rememberCoroutineScope()
var currentVersion by remember { mutableStateOf("") } var currentVersion by remember { mutableStateOf("") }
var clickTime by remember { mutableStateOf(System.currentTimeMillis() - 2000) } var clickTime by remember { mutableStateOf(System.currentTimeMillis() - 2000) }
var pressAMP by remember { mutableStateOf(16f) } var pressAMP by remember { mutableStateOf(16f) }
@ -63,38 +61,26 @@ fun TipsAndSupport(
currentVersion = context.getCurrentVersion().toString() currentVersion = context.getCurrentVersion().toString()
} }
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface)
.statusBarsPadding()
.navigationBarsPadding(),
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface, containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface,
topBar = { navigationIcon = {
SmallTopAppBar( FeedbackIconButton(
colors = TopAppBarDefaults.smallTopAppBarColors( imageVector = Icons.Rounded.ArrowBack,
containerColor = MaterialTheme.colorScheme.surface onLight MaterialTheme.colorScheme.inverseOnSurface contentDescription = stringResource(R.string.back),
), tint = MaterialTheme.colorScheme.onSurface
title = {}, ) {
navigationIcon = { navController.popBackStack()
FeedbackIconButton( }
imageVector = Icons.Rounded.ArrowBack, },
contentDescription = stringResource(R.string.back), actions = {
tint = MaterialTheme.colorScheme.onSurface FeedbackIconButton(
) { modifier = Modifier.size(20.dp),
navController.popBackStack() imageVector = Icons.Rounded.Balance,
} contentDescription = stringResource(R.string.open_source_licenses),
}, tint = MaterialTheme.colorScheme.onSurface
actions = { ) {
FeedbackIconButton( context.showToast(context.getString(R.string.coming_soon))
modifier = Modifier.size(20.dp), }
imageVector = Icons.Rounded.Balance,
contentDescription = stringResource(R.string.open_source_licenses),
tint = MaterialTheme.colorScheme.onSurface
) {
context.showToast(context.getString(R.string.coming_soon))
}
}
)
}, },
content = { content = {
LazyColumn( LazyColumn(

View File

@ -1,7 +1,6 @@
package me.ash.reader.ui.page.settings.tips package me.ash.reader.ui.page.settings.tips
import android.Manifest import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.provider.Settings import android.provider.Settings
@ -38,7 +37,6 @@ import me.ash.reader.ui.component.base.Dialog
import me.ash.reader.ui.ext.collectAsStateValue import me.ash.reader.ui.ext.collectAsStateValue
import me.ash.reader.ui.ext.installLatestApk import me.ash.reader.ui.ext.installLatestApk
@SuppressLint("FlowOperatorInvokedInComposition")
@Composable @Composable
fun UpdateDialog( fun UpdateDialog(
updateViewModel: UpdateViewModel = hiltViewModel(), updateViewModel: UpdateViewModel = hiltViewModel(),

View File

@ -2,8 +2,9 @@ package me.ash.reader.ui.page.startup
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import androidx.compose.foundation.background import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.CheckCircleOutline import androidx.compose.material.icons.rounded.CheckCircleOutline
@ -28,7 +29,6 @@ import me.ash.reader.ui.page.common.RouteName
import me.ash.reader.ui.svg.SVGString import me.ash.reader.ui.svg.SVGString
import me.ash.reader.ui.svg.WELCOME import me.ash.reader.ui.svg.WELCOME
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun StartupPage( fun StartupPage(
navController: NavHostController, navController: NavHostController,
@ -36,12 +36,7 @@ fun StartupPage(
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
Scaffold( me.ash.reader.ui.component.base.Scaffold(
modifier = Modifier
.background(MaterialTheme.colorScheme.surface)
.statusBarsPadding()
.navigationBarsPadding(),
topBar = {},
content = { content = {
LazyColumn { LazyColumn {
item { item {
@ -87,16 +82,7 @@ fun StartupPage(
} }
} }
}, },
bottomBar = { bottomBar = null,
// Row(
// modifier = Modifier
// .fillMaxWidth()
// .padding(24.dp),
// horizontalArrangement = Arrangement.End,
// verticalAlignment = Alignment.CenterVertically,
// ) {
// }
},
floatingActionButton = { floatingActionButton = {
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
onClick = { onClick = {