rename and format settings files

This commit is contained in:
Stefano Sansone
2024-02-22 16:05:05 +00:00
parent c064979832
commit ddb85a4f6e
7 changed files with 291 additions and 283 deletions

View File

@ -17,7 +17,7 @@ import app.omnivore.omnivore.feature.library.SearchView
import app.omnivore.omnivore.feature.library.SearchViewModel
import app.omnivore.omnivore.feature.save.SaveViewModel
import app.omnivore.omnivore.feature.settings.PolicyWebView
import app.omnivore.omnivore.feature.settings.SettingsView
import app.omnivore.omnivore.feature.settings.SettingsScreen
import app.omnivore.omnivore.feature.settings.SettingsViewModel
import app.omnivore.omnivore.navigation.Routes
@ -84,7 +84,7 @@ fun PrimaryNavigator(
}
composable(Routes.Settings.route) {
SettingsView(
SettingsScreen(
loginViewModel = loginViewModel,
settingsViewModel = settingsViewModel,
navController = navController

View File

@ -12,31 +12,29 @@ import com.google.android.gms.auth.api.signin.GoogleSignInOptions
@Composable
fun LogoutDialog(onClose: (Boolean) -> Unit) {
val context = LocalContext.current
val context = LocalContext.current
AlertDialog(
onDismissRequest = { onClose(false) },
title = { Text(text = stringResource(R.string.logout_dialog_title)) },
text = {
Text(stringResource(R.string.logout_dialog_confirm_msg))
},
confirmButton = {
Button(onClick = {
// Sign out google users
val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.build()
AlertDialog(onDismissRequest = { onClose(false) },
title = { Text(text = stringResource(R.string.logout_dialog_title)) },
text = {
Text(stringResource(R.string.logout_dialog_confirm_msg))
},
confirmButton = {
Button(onClick = {
// Sign out google users
val signInOptions =
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).build()
val googleSignIn = GoogleSignIn.getClient(context, signInOptions)
googleSignIn.signOut()
onClose(true)
}) {
Text(stringResource(R.string.logout_dialog_action_confirm))
}
},
dismissButton = {
Button(onClick = { onClose(false) }) {
Text(stringResource(R.string.logout_dialog_action_cancel))
}
}
)
val googleSignIn = GoogleSignIn.getClient(context, signInOptions)
googleSignIn.signOut()
onClose(true)
}) {
Text(stringResource(R.string.logout_dialog_action_confirm))
}
},
dismissButton = {
Button(onClick = { onClose(false) }) {
Text(stringResource(R.string.logout_dialog_action_cancel))
}
})
}

View File

@ -31,8 +31,7 @@ fun ManageAccountDialog(onDismiss: () -> Unit, settingsViewModel: SettingsViewMo
Surface(
shape = RoundedCornerShape(16.dp),
color = Color.White,
modifier = Modifier
.height(300.dp)
modifier = Modifier.height(300.dp)
) {
ManageAccountView(settingsViewModel = settingsViewModel)
}
@ -42,26 +41,23 @@ fun ManageAccountDialog(onDismiss: () -> Unit, settingsViewModel: SettingsViewMo
@Composable
fun ManageAccountView(settingsViewModel: SettingsViewModel) {
Column(
modifier = Modifier
.padding(top = 6.dp, start = 6.dp, end = 6.dp, bottom = 6.dp)
modifier = Modifier.padding(top = 6.dp, start = 6.dp, end = 6.dp, bottom = 6.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 12.dp, bottom = 12.dp),
.fillMaxWidth()
.padding(top = 12.dp, bottom = 12.dp),
horizontalArrangement = Arrangement.Center
) {
Text(stringResource(R.string.manage_account_title))
}
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
modifier = Modifier.verticalScroll(rememberScrollState())
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.clickable(onClick = { settingsViewModel.resetDataCache() })
modifier = Modifier.clickable(onClick = { settingsViewModel.resetDataCache() })
) {
Text(stringResource(R.string.manage_account_action_reset_data_cache))
Spacer(modifier = Modifier.weight(1.0F))

View File

@ -8,70 +8,70 @@ import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.*
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.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.viewinterop.AndroidView
import androidx.navigation.NavHostController
import app.omnivore.omnivore.navigation.Routes
import app.omnivore.omnivore.R
import app.omnivore.omnivore.navigation.Routes
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter", "SetJavaScriptEnabled")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PolicyWebView(navController: NavHostController, url: String) {
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(R.string.policy_webview_title)) },
actions = {
IconButton(onClick = { navController.navigate(Routes.Settings.route) }) {
Icon(
imageVector = Icons.Default.Settings,
contentDescription = null
)
}
}, colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
)
}
) {
val isDarkMode = isSystemInDarkTheme()
Box {
AndroidView(factory = {
WebView(it).apply {
if (isDarkMode) {
setBackgroundColor(Color.Transparent.hashCode())
}
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
settings.javaScriptEnabled = true
settings.allowContentAccess = true
settings.allowFileAccess = true
settings.domStorageEnabled = true
alpha = 0.0f
webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
view?.animate()?.alpha(1.0f)?.duration = 200
Scaffold(topBar = {
TopAppBar(title = { Text(stringResource(R.string.policy_webview_title)) }, actions = {
IconButton(onClick = { navController.navigate(Routes.Settings.route) }) {
Icon(
imageVector = Icons.Default.Settings, contentDescription = null
)
}
}
}, colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
)
}) {
val isDarkMode = isSystemInDarkTheme()
Box {
AndroidView(factory = {
WebView(it).apply {
if (isDarkMode) {
setBackgroundColor(Color.Transparent.hashCode())
}
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
)
settings.javaScriptEnabled = true
settings.allowContentAccess = true
settings.allowFileAccess = true
settings.domStorageEnabled = true
alpha = 0.0f
webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
view?.animate()?.alpha(1.0f)?.duration = 200
}
}
// val themeID = if (isDarkMode) "Gray" else "LightGray"
// loadUrl(url, mutableMapOf("Set-Cookie" to "theme=$themeID; Max-Age=31536000;"))
loadUrl(url, mutableMapOf())
loadUrl(url, mutableMapOf())
}
}, update = {})
}
}, update = {}
)
}
}
}

View File

@ -1,175 +0,0 @@
package app.omnivore.omnivore.feature.settings
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
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.navigation.Routes
import app.omnivore.omnivore.feature.auth.LoginViewModel
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsView(
loginViewModel: LoginViewModel,
settingsViewModel: SettingsViewModel,
navController: NavHostController,
) {
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(R.string.settings_view_title)) },
actions = {
IconButton(onClick = { navController.navigate(Routes.Library.route) }) {
Icon(
imageVector = Icons.Default.Home,
contentDescription = null
)
}
}, colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
)
}
) { paddingValues ->
SettingsViewContent(
loginViewModel = loginViewModel,
settingsViewModel = settingsViewModel,
navController = navController,
modifier = Modifier
.padding(
top = paddingValues.calculateTopPadding(),
bottom = paddingValues.calculateBottomPadding()
)
)
}
}
@Composable
fun SettingsViewContent(loginViewModel: LoginViewModel, settingsViewModel: SettingsViewModel, navController: NavHostController, modifier: Modifier) {
val showLogoutDialog = remember { mutableStateOf(false) }
val showManageAccountDialog = remember { mutableStateOf(false ) }
Box(
modifier = modifier.fillMaxSize()
) {
val version = "Omnivore Version: " + BuildConfig.VERSION_NAME
Column(
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.Start,
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
.padding(horizontal = 6.dp)
.verticalScroll(rememberScrollState())
) {
SettingRow(text = stringResource(R.string.settings_view_setting_row_documentation)) {
navController.navigate(Routes.Documentation.route)
}
RowDivider()
SettingRow(text = stringResource(R.string.settings_view_setting_row_feedback)) {
settingsViewModel.presentIntercom()
}
RowDivider()
SettingRow(text = stringResource(R.string.settings_view_setting_row_privacy_policy)) {
navController.navigate(Routes.PrivacyPolicy.route)
}
RowDivider()
SettingRow(text = stringResource(R.string.settings_view_setting_row_terms_and_conditions)) {
navController.navigate(Routes.TermsAndConditions.route)
}
SectionSpacer()
SettingRow(text = stringResource(R.string.settings_view_setting_row_manage_account)) {
showManageAccountDialog.value = true
}
RowDivider()
SettingRow(text = stringResource(R.string.settings_view_setting_row_logout), includeIcon = false) {
showLogoutDialog.value = true
}
RowDivider()
Text(
text = version,
fontSize = 12.sp,
modifier = Modifier
.padding(15.dp)
)
}
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 RowDivider() {
Divider(
modifier = Modifier.padding(horizontal = 12.dp),
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f)
)
}
@Composable
private fun SectionSpacer() {
RowDivider()
Spacer(Modifier.height(60.dp))
RowDivider()
}
@Composable
private fun SettingRow(text: String, includeIcon: Boolean = true, tapAction: () -> Unit) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clickable { tapAction() }
) {
Text(
text = text,
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(16.dp),
style = MaterialTheme.typography.titleMedium
)
if (includeIcon) {
Icon(
painter = painterResource(id = R.drawable.chevron_right),
contentDescription = null
)
}
}
}

View File

@ -0,0 +1,189 @@
package app.omnivore.omnivore.feature.settings
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
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
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.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
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.navigation.Routes
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(
loginViewModel: LoginViewModel,
settingsViewModel: SettingsViewModel,
navController: NavHostController,
) {
Scaffold(topBar = {
TopAppBar(title = { Text(stringResource(R.string.settings_view_title)) }, actions = {
IconButton(onClick = { navController.navigate(Routes.Library.route) }) {
Icon(
imageVector = Icons.Default.Home, contentDescription = null
)
}
}, colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
)
}) { paddingValues ->
SettingsViewContent(
loginViewModel = loginViewModel,
settingsViewModel = settingsViewModel,
navController = navController,
modifier = Modifier.padding(
top = paddingValues.calculateTopPadding(),
bottom = paddingValues.calculateBottomPadding()
)
)
}
}
@Composable
fun SettingsViewContent(
loginViewModel: LoginViewModel,
settingsViewModel: SettingsViewModel,
navController: NavHostController,
modifier: Modifier
) {
val showLogoutDialog = remember { mutableStateOf(false) }
val showManageAccountDialog = remember { mutableStateOf(false) }
Box(
modifier = modifier.fillMaxSize()
) {
val version = "Omnivore Version: " + BuildConfig.VERSION_NAME
Column(
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.Start,
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
.padding(horizontal = 6.dp)
.verticalScroll(rememberScrollState())
) {
SettingRow(text = stringResource(R.string.settings_view_setting_row_documentation)) {
navController.navigate(Routes.Documentation.route)
}
RowDivider()
SettingRow(text = stringResource(R.string.settings_view_setting_row_feedback)) {
settingsViewModel.presentIntercom()
}
RowDivider()
SettingRow(text = stringResource(R.string.settings_view_setting_row_privacy_policy)) {
navController.navigate(Routes.PrivacyPolicy.route)
}
RowDivider()
SettingRow(text = stringResource(R.string.settings_view_setting_row_terms_and_conditions)) {
navController.navigate(Routes.TermsAndConditions.route)
}
SectionSpacer()
SettingRow(text = stringResource(R.string.settings_view_setting_row_manage_account)) {
showManageAccountDialog.value = true
}
RowDivider()
SettingRow(
text = stringResource(R.string.settings_view_setting_row_logout),
includeIcon = false
) {
showLogoutDialog.value = true
}
RowDivider()
Text(
text = version, fontSize = 12.sp, modifier = Modifier.padding(15.dp)
)
}
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 RowDivider() {
HorizontalDivider(
modifier = Modifier.padding(horizontal = 12.dp),
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f)
)
}
@Composable
private fun SectionSpacer() {
RowDivider()
Spacer(Modifier.height(60.dp))
RowDivider()
}
@Composable
private fun SettingRow(text: String, includeIcon: Boolean = true, tapAction: () -> Unit) {
Row(horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clickable { tapAction() }) {
Text(
text = text,
modifier = Modifier
.align(Alignment.CenterVertically)
.padding(16.dp),
style = MaterialTheme.typography.titleMedium
)
if (includeIcon) {
Icon(
painter = painterResource(id = R.drawable.chevron_right), contentDescription = null
)
}
}
}

View File

@ -2,11 +2,11 @@ package app.omnivore.omnivore.feature.settings
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.omnivore.omnivore.utils.DatastoreKeys
import app.omnivore.omnivore.core.datastore.DatastoreRepository
import app.omnivore.omnivore.core.data.DataService
import app.omnivore.omnivore.core.datastore.DatastoreRepository
import app.omnivore.omnivore.core.network.Networker
import app.omnivore.omnivore.core.network.viewer
import app.omnivore.omnivore.utils.DatastoreKeys
import dagger.hilt.android.lifecycle.HiltViewModel
import io.intercom.android.sdk.Intercom
import io.intercom.android.sdk.IntercomSpace
@ -15,26 +15,26 @@ import javax.inject.Inject
@HiltViewModel
class SettingsViewModel @Inject constructor(
private val networker: Networker,
private val dataService: DataService,
private val datastoreRepo: DatastoreRepository
): ViewModel() {
fun resetDataCache() {
viewModelScope.launch {
datastoreRepo.clearValue(DatastoreKeys.libraryLastSyncTimestamp)
dataService.clearDatabase()
}
}
fun presentIntercom() {
viewModelScope.launch {
val viewer = networker.viewer()
viewer?.let { v ->
v.intercomHash?.let { intercomHash ->
Intercom.client().setUserHash(intercomHash)
private val networker: Networker,
private val dataService: DataService,
private val datastoreRepo: DatastoreRepository
) : ViewModel() {
fun resetDataCache() {
viewModelScope.launch {
datastoreRepo.clearValue(DatastoreKeys.libraryLastSyncTimestamp)
dataService.clearDatabase()
}
}
fun presentIntercom() {
viewModelScope.launch {
val viewer = networker.viewer()
viewer?.let { v ->
v.intercomHash?.let { intercomHash ->
Intercom.client().setUserHash(intercomHash)
}
Intercom.client().present(space = IntercomSpace.Messages)
}
}
Intercom.client().present(space = IntercomSpace.Messages)
}
}
}
}