mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
add about screen
This commit is contained in:
parent
9944acd63c
commit
dd6860908b
8 changed files with 248 additions and 75 deletions
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
11
android/Omnivore/app/src/main/res/drawable/ic_omnivore.xml
Normal file
11
android/Omnivore/app/src/main/res/drawable/ic_omnivore.xml
Normal 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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue