diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/root/RootView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/root/RootView.kt
index 02567659d..9afd0ec0b 100644
--- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/root/RootView.kt
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/root/RootView.kt
@@ -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")
}
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/LogoHeader.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/LogoHeader.kt
new file mode 100644
index 000000000..e32491e03
--- /dev/null
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/LogoHeader.kt
@@ -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()
+ }
+}
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsScreen.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsScreen.kt
index 2f1714b92..22bc7b891 100644
--- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsScreen.kt
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsScreen.kt
@@ -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"
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/about/AboutScreen.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/about/AboutScreen.kt
new file mode 100644
index 000000000..9e0b1220c
--- /dev/null
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/about/AboutScreen.kt
@@ -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}"
+ }
+ }
+}
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/ManageAccount.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/account/AccountScreen.kt
similarity index 95%
rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/ManageAccount.kt
rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/account/AccountScreen.kt
index 2d9da4b58..57d8cde41 100644
--- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/ManageAccount.kt
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/account/AccountScreen.kt
@@ -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) {
diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/navigation/Routes.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/navigation/Routes.kt
index 62f1a780b..e10ee6e94 100644
--- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/navigation/Routes.kt
+++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/navigation/Routes.kt
@@ -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")
diff --git a/android/Omnivore/app/src/main/res/drawable/ic_omnivore.xml b/android/Omnivore/app/src/main/res/drawable/ic_omnivore.xml
new file mode 100644
index 000000000..8608e8300
--- /dev/null
+++ b/android/Omnivore/app/src/main/res/drawable/ic_omnivore.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/android/Omnivore/app/src/main/res/values/strings.xml b/android/Omnivore/app/src/main/res/values/strings.xml
index d1cce247c..d737b53fd 100644
--- a/android/Omnivore/app/src/main/res/values/strings.xml
+++ b/android/Omnivore/app/src/main/res/values/strings.xml
@@ -212,6 +212,11 @@
Manage Account
Logout
+
+ About
+ Version
+ What\'s new
+
Inbox
Non-Feed Items