add about screen

This commit is contained in:
Stefano Sansone 2024-02-23 00:08:07 +00:00
parent 9944acd63c
commit dd6860908b
8 changed files with 248 additions and 75 deletions

View file

@ -18,6 +18,7 @@ import app.omnivore.omnivore.feature.library.SearchViewModel
import app.omnivore.omnivore.feature.save.SaveViewModel
import app.omnivore.omnivore.feature.settings.SettingsScreen
import app.omnivore.omnivore.feature.settings.SettingsViewModel
import app.omnivore.omnivore.feature.settings.about.AboutScreen
import app.omnivore.omnivore.feature.web.WebViewScreen
import app.omnivore.omnivore.navigation.Routes
@ -91,6 +92,13 @@ fun PrimaryNavigator(
)
}
composable(Routes.About.route) {
AboutScreen(
navController = navController,
settingsViewModel = settingsViewModel
)
}
composable(Routes.Documentation.route) {
WebViewScreen(navController = navController, url = "https://docs.omnivore.app")
}

View file

@ -0,0 +1,34 @@
package app.omnivore.omnivore.feature.settings
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import app.omnivore.omnivore.R
@Composable
fun LogoHeader() {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
painter = painterResource(R.drawable.ic_omnivore),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
.padding(vertical = 56.dp)
.size(64.dp),
)
HorizontalDivider()
}
}

View file

@ -1,7 +1,7 @@
package app.omnivore.omnivore.feature.settings
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
@ -11,7 +11,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@ -24,13 +23,15 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import app.omnivore.omnivore.BuildConfig
import app.omnivore.omnivore.R
import app.omnivore.omnivore.feature.auth.LoginViewModel
import app.omnivore.omnivore.feature.settings.account.ManageAccountDialog
import app.omnivore.omnivore.navigation.Routes
@OptIn(ExperimentalMaterial3Api::class)
@ -46,7 +47,8 @@ internal fun SettingsScreen(
navigationIcon = {
IconButton(onClick = { navController.navigateUp() }) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = null
imageVector = Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = null
)
}
@ -76,90 +78,90 @@ fun SettingsViewContent(
val showManageAccountDialog = remember { mutableStateOf(false) }
val state = rememberLazyListState()
val version = "Omnivore Version: " + BuildConfig.VERSION_NAME
LazyColumn(
state = state,
contentPadding = paddingValues,
) {
LazyColumn(
state = state,
contentPadding = paddingValues,
) {
item {
SettingRow(text = stringResource(R.string.settings_view_setting_row_documentation)) {
navController.navigate(Routes.Documentation.route)
}
}
item {
SettingRow(text = stringResource(R.string.settings_view_setting_row_feedback)) {
settingsViewModel.presentIntercom()
}
}
item {
SettingRow(text = stringResource(R.string.settings_view_setting_row_privacy_policy)) {
navController.navigate(Routes.PrivacyPolicy.route)
}
}
item {
SettingRow(text = stringResource(R.string.settings_view_setting_row_terms_and_conditions)) {
navController.navigate(Routes.TermsAndConditions.route)
}
}
item { HorizontalDivider() }
item {
SettingRow(text = stringResource(R.string.settings_view_setting_row_manage_account)) {
showManageAccountDialog.value = true
}
}
item {
SettingRow(
text = stringResource(R.string.settings_view_setting_row_logout)
) {
showLogoutDialog.value = true
}
}
item {
Text(
text = version, fontSize = 12.sp, modifier = Modifier.padding(15.dp)
)
item {
SettingRow(title = stringResource(R.string.settings_view_setting_row_manage_account)) {
showManageAccountDialog.value = true
}
}
if (showLogoutDialog.value) {
LogoutDialog { performLogout ->
if (performLogout) {
loginViewModel.logout()
}
showLogoutDialog.value = false
item {
SettingRow(
title = stringResource(R.string.settings_view_setting_row_logout)
) {
showLogoutDialog.value = true
}
}
if (showManageAccountDialog.value) {
ManageAccountDialog(
onDismiss = { showManageAccountDialog.value = false },
settingsViewModel = settingsViewModel
)
item {
SettingRow(title = stringResource(R.string.about_view_title)) {
navController.navigate(Routes.About.route)
}
}
}
if (showLogoutDialog.value) {
LogoutDialog { performLogout ->
if (performLogout) {
loginViewModel.logout()
}
showLogoutDialog.value = false
}
}
if (showManageAccountDialog.value) {
ManageAccountDialog(
onDismiss = { showManageAccountDialog.value = false },
settingsViewModel = settingsViewModel
)
}
}
@Composable
private fun SettingRow(text: String, tapAction: () -> Unit) {
Row(horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
internal fun SettingRow(
title: String, subtitle: String? = null, onClick: (() -> Unit)?
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable { tapAction() }) {
Text(
text = text,
.clickable(enabled = onClick != null, onClick = { onClick?.invoke() })
.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(16.dp)
)
.weight(1f)
.padding(vertical = SettingsVerticalPadding)
) {
Text(
modifier = Modifier.padding(horizontal = SettingsHorizontalPadding),
text = title,
overflow = TextOverflow.Ellipsis,
maxLines = 2,
style = MaterialTheme.typography.titleLarge,
fontSize = SettingsTitleFontSize,
)
if (!subtitle.isNullOrBlank()) {
Text(
text = subtitle,
modifier = Modifier
.padding(horizontal = SettingsHorizontalPadding)
.alpha(SettingsSecondaryItemAlpha),
style = MaterialTheme.typography.bodySmall,
maxLines = 10,
)
}
}
}
}
internal val SettingsHorizontalPadding = 16.dp
internal val SettingsVerticalPadding = 16.dp
internal const val SettingsSecondaryItemAlpha = .78f
internal val SettingsTitleFontSize = 16.sp
internal const val RELEASE_URL = "https://github.com/omnivore-app/omnivore/releases"

View file

@ -0,0 +1,111 @@
package app.omnivore.omnivore.feature.settings.about
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.navigation.NavHostController
import app.omnivore.omnivore.BuildConfig
import app.omnivore.omnivore.R
import app.omnivore.omnivore.feature.settings.LogoHeader
import app.omnivore.omnivore.feature.settings.RELEASE_URL
import app.omnivore.omnivore.feature.settings.SettingRow
import app.omnivore.omnivore.feature.settings.SettingsViewModel
import app.omnivore.omnivore.navigation.Routes
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun AboutScreen(
navController: NavHostController,
settingsViewModel: SettingsViewModel
) {
val uriHandler = LocalUriHandler.current
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(R.string.about_view_title)) },
navigationIcon = {
IconButton(onClick = { navController.navigateUp() }) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = null
)
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.background
),
)
},
) { contentPadding ->
LazyColumn(
contentPadding = contentPadding,
) {
item {
LogoHeader()
}
item {
SettingRow(
title = stringResource(R.string.about_view_row_version),
subtitle = getVersionName(),
onClick = { },
)
}
item {
SettingRow(
title = stringResource(R.string.about_view_row_whats_new),
onClick = { uriHandler.openUri(RELEASE_URL) },
)
}
item {
SettingRow(title = stringResource(R.string.settings_view_setting_row_documentation)) {
navController.navigate(Routes.Documentation.route)
}
}
item {
SettingRow(title = stringResource(R.string.settings_view_setting_row_feedback)) {
settingsViewModel.presentIntercom()
}
}
item {
SettingRow(title = stringResource(R.string.settings_view_setting_row_privacy_policy)) {
navController.navigate(Routes.PrivacyPolicy.route)
}
}
item {
SettingRow(title = stringResource(R.string.settings_view_setting_row_terms_and_conditions)) {
navController.navigate(Routes.TermsAndConditions.route)
}
}
}
}
}
fun getVersionName(): String {
return when {
BuildConfig.DEBUG -> {
"Debug ${BuildConfig.VERSION_NAME}"
}
else -> {
"Stable ${BuildConfig.VERSION_NAME}"
}
}
}

View file

@ -1,4 +1,4 @@
package app.omnivore.omnivore.feature.settings
package app.omnivore.omnivore.feature.settings.account
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@ -24,6 +24,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import app.omnivore.omnivore.R
import app.omnivore.omnivore.feature.settings.SettingsViewModel
@Composable
fun ManageAccountDialog(onDismiss: () -> Unit, settingsViewModel: SettingsViewModel) {

View file

@ -3,6 +3,7 @@ package app.omnivore.omnivore.navigation
sealed class Routes(val route: String) {
object Library : Routes("Library")
object Settings : Routes("Settings")
object About : Routes("About")
object Search : Routes("Search")
object Documentation : Routes("Documentation")
object PrivacyPolicy : Routes("PrivacyPolicy")

View file

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:pathData="M84.86,53.22C84.86,55.2 84.38,57.6 83.89,59.69V59.71L83.89,59.72C83.29,62.16 81.89,64.33 79.91,65.88C77.93,67.42 75.49,68.26 72.98,68.26H72.84C66.49,68.26 62.49,63.05 62.49,57.21V48.85L57.76,55.86L57.5,56.07C56.52,56.89 55.28,57.34 54,57.34C52.72,57.34 51.48,56.89 50.5,56.07L50.24,55.87L45.37,48.76V66H40.72V47.23C40.72,43.68 44.93,41.61 47.73,44.1L47.94,44.29L53.64,52.61C53.75,52.66 53.87,52.69 53.99,52.69C54.12,52.69 54.23,52.66 54.34,52.61L59.93,44.33L60.18,44.12C62.84,41.91 67.14,43.58 67.14,47.3V57.21C67.14,61 69.55,63.61 72.84,63.61H72.98C76.02,63.61 78.64,61.55 79.37,58.62C79.86,56.54 80.21,54.61 80.21,53.24C80.14,38.26 67.47,26.82 52.13,27.86C39.2,28.75 28.75,39.2 27.85,52.14C27.6,55.72 28.09,59.32 29.3,62.71C30.5,66.1 32.38,69.2 34.84,71.83C37.29,74.45 40.26,76.55 43.55,77.98C46.85,79.41 50.41,80.15 54,80.14V84.79C49.77,84.8 45.58,83.93 41.7,82.24C37.82,80.56 34.33,78.09 31.44,75C28.55,71.91 26.33,68.26 24.91,64.27C23.5,60.28 22.92,56.05 23.21,51.82C24.27,36.56 36.56,24.27 51.81,23.21C69.69,22.01 84.78,35.42 84.86,53.22Z"
android:fillColor="#FFFFFF"
tools:ignore="VectorPath" />
</vector>

View file

@ -212,6 +212,11 @@
<string name="settings_view_setting_row_manage_account">Manage Account</string>
<string name="settings_view_setting_row_logout">Logout</string>
<!-- AboutView -->
<string name="about_view_title">About</string>
<string name="about_view_row_version">Version</string>
<string name="about_view_row_whats_new">What\'s new</string>
<!-- stock filters -->
<string name="library_filter_inbox">Inbox</string>
<string name="library_filter_non_feed">Non-Feed Items</string>