diff --git a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index 43124fee9..baa47ed90 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -10,6 +10,7 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.GLOBAL_FOLLOWS import com.vitorpamplona.amethyst.model.KIND3_FOLLOWS import com.vitorpamplona.amethyst.model.RelaySetupInfo +import com.vitorpamplona.amethyst.model.Settings import com.vitorpamplona.amethyst.model.hexToByteArray import com.vitorpamplona.amethyst.service.HttpClient import com.vitorpamplona.amethyst.service.model.ContactListEvent @@ -67,6 +68,8 @@ private object PrefKeys { const val WARN_ABOUT_REPORTS = "warn_about_reports" const val FILTER_SPAM_FROM_STRANGERS = "filter_spam_from_strangers" const val LAST_READ_PER_ROUTE = "last_read_route_per_route" + const val AUTOMATICALLY_SHOW_IMAGES = "automatically_show_images" + const val AUTOMATICALLY_START_PLAYBACK = "automatically_start_playback" val LAST_READ: (String) -> String = { route -> "last_read_route_$route" } } @@ -236,6 +239,21 @@ object LocalPreferences { putBoolean(PrefKeys.SHOW_SENSITIVE_CONTENT, account.showSensitiveContent!!) } }.apply() + + val globalPrefs = encryptedPreferences() + globalPrefs.edit().apply { + if (account.settings.automaticallyShowImages == null) { + remove(PrefKeys.AUTOMATICALLY_SHOW_IMAGES) + } else { + putBoolean(PrefKeys.AUTOMATICALLY_SHOW_IMAGES, account.settings.automaticallyShowImages!!) + } + + if (account.settings.automaticallyStartPlayback == null) { + remove(PrefKeys.AUTOMATICALLY_START_PLAYBACK) + } else { + putBoolean(PrefKeys.AUTOMATICALLY_START_PLAYBACK, account.settings.automaticallyStartPlayback!!) + } + }.apply() } fun loadFromEncryptedStorage(): Account? { @@ -340,6 +358,21 @@ object LocalPreferences { mapOf() } + val settings = Settings(null, null) + encryptedPreferences().apply { + settings.automaticallyShowImages = if (contains(PrefKeys.AUTOMATICALLY_SHOW_IMAGES)) { + getBoolean(PrefKeys.AUTOMATICALLY_SHOW_IMAGES, false) + } else { + null + } + + settings.automaticallyStartPlayback = if (contains(PrefKeys.AUTOMATICALLY_START_PLAYBACK)) { + getBoolean(PrefKeys.AUTOMATICALLY_START_PLAYBACK, false) + } else { + null + } + } + val a = Account( loggedIn = Persona(privKey = privKey?.hexToByteArray(), pubKey = pubKey.hexToByteArray()), followingChannels = followingChannels, @@ -366,7 +399,8 @@ object LocalPreferences { showSensitiveContent = showSensitiveContent, warnAboutPostsWithReports = warnAboutReports, filterSpamFromStrangers = filterSpam, - lastReadPerRoute = lastReadPerRoute + lastReadPerRoute = lastReadPerRoute, + settings = settings ) return a diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index b1a5c9a7f..4e48823cc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -73,7 +73,8 @@ class Account( var showSensitiveContent: Boolean? = null, var warnAboutPostsWithReports: Boolean = true, var filterSpamFromStrangers: Boolean = true, - var lastReadPerRoute: Map = mapOf() + var lastReadPerRoute: Map = mapOf(), + var settings: Settings = Settings(null, null) ) { var transientHiddenUsers: Set = setOf() @@ -85,6 +86,13 @@ class Account( var userProfileCache: User? = null + fun updateGlobalSettings(automaticallyShowImages: Boolean?, automaticallyStartPlayback: Boolean?) { + settings.automaticallyStartPlayback = automaticallyStartPlayback + settings.automaticallyShowImages = automaticallyShowImages + live.invalidateData() + saveable.invalidateData() + } + fun updateOptOutOptions(warnReports: Boolean, filterSpam: Boolean) { warnAboutPostsWithReports = warnReports filterSpamFromStrangers = filterSpam diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt index dc8ccdf41..448afd677 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Settings.kt @@ -1,4 +1,9 @@ package com.vitorpamplona.amethyst.model -class Settings { -} \ No newline at end of file +import androidx.compose.runtime.Stable + +@Stable +class Settings( + var automaticallyShowImages: Boolean?, + var automaticallyStartPlayback: Boolean? +) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 6456340a9..91082ac97 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -40,6 +40,10 @@ class AccountViewModel(val account: Account) : ViewModel() { val userFollows: LiveData = account.userProfile().live().follows.map { it } val userRelays: LiveData = account.userProfile().live().relays.map { it } + fun updateGlobalSettings(automaticallyShowImages: Boolean?, automaticallyStartPlayback: Boolean?) { + account.updateGlobalSettings(automaticallyShowImages, automaticallyStartPlayback) + } + fun isWriteable(): Boolean { return account.isWriteable() } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt index 5c8c7b1f1..a0d937843 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SettingsScreen.kt @@ -1,7 +1,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material.Button import androidx.compose.material.DropdownMenuItem import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExposedDropdownMenuBox @@ -13,38 +17,95 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp +import com.vitorpamplona.amethyst.LocalPreferences +import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.StdPadding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch @Composable fun SettingsScreen( accountViewModel: AccountViewModel, nav: (String) -> Unit ) { - val listItems = arrayOf("Always", "Wifi-only", "Never") - val selectedItem = remember { - mutableStateOf(listItems[0]) + val scope = rememberCoroutineScope() + val selectedItens = arrayOf("Always", "Wifi-only", "Never") + val settings = accountViewModel.account.settings + val index = if (settings.automaticallyShowImages == null) { 0 } else { + if (settings.automaticallyShowImages == true) 1 else 2 + } + val videoIndex = if (settings.automaticallyStartPlayback == null) { 0 } else { + if (settings.automaticallyShowImages == true) 1 else 2 + } + val selectedItem = remember { + mutableStateOf(selectedItens[index]) + } + val selectedVideoItem = remember { + mutableStateOf(selectedItens[videoIndex]) } - val context = LocalContext.current Column( - StdPadding + StdPadding, + horizontalAlignment = Alignment.CenterHorizontally ) { Section("Account preferences") Section("Application preferences") + Text( "Media", fontWeight = FontWeight.Bold ) + DropDownSettings( selectedItem = selectedItem, - listItems = listItems + listItems = selectedItens, + title = "Automatically load images/gifs" ) + + Spacer(modifier = DoubleVertSpacer) + + DropDownSettings( + selectedItem = selectedVideoItem, + listItems = selectedItens, + title = "Automatically play videos" + ) + + Row( + Modifier.fillMaxWidth(), + Arrangement.Center + ) { + Button( + onClick = { + val automaticallyShowImages = when (selectedItens.indexOf(selectedItem.value)) { + 1 -> true + 2 -> false + else -> null + } + val automaticallyStartPlayback = when (selectedItens.indexOf(selectedVideoItem.value)) { + 1 -> true + 2 -> false + else -> null + } + scope.launch(Dispatchers.IO) { + accountViewModel.updateGlobalSettings(automaticallyShowImages, automaticallyStartPlayback) + LocalPreferences.saveToEncryptedStorage(accountViewModel.account) + ServiceManager.pause() + ServiceManager.start(context) + } + } + ) { + Text(text = "Save") + } + } } } @@ -52,7 +113,8 @@ fun SettingsScreen( @Composable fun DropDownSettings( selectedItem: MutableState, - listItems: Array + listItems: Array, + title: String ) { var expanded by remember { mutableStateOf(false) @@ -64,10 +126,11 @@ fun DropDownSettings( } ) { TextField( + modifier = Modifier.fillMaxWidth(), value = selectedItem.value, onValueChange = {}, readOnly = true, - label = { Text(text = "Automatically load images/gifs") }, + label = { Text(text = title) }, trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon( expanded = expanded @@ -81,10 +144,12 @@ fun DropDownSettings( onDismissRequest = { expanded = false } ) { listItems.forEach { selectedOption -> - DropdownMenuItem(onClick = { - selectedItem.value = selectedOption - expanded = false - }) { + DropdownMenuItem( + onClick = { + selectedItem.value = selectedOption + expanded = false + } + ) { Text(text = selectedOption) } }