Moves Content Sensitivity setting to the Security filter screen
This commit is contained in:
@@ -1144,11 +1144,16 @@ class Account(
|
||||
|
||||
fun isWriteable(): Boolean = settings.isWriteable()
|
||||
|
||||
fun updateOptOutOptions(
|
||||
warnReports: Boolean,
|
||||
filterSpam: Boolean,
|
||||
): Boolean {
|
||||
if (settings.updateOptOutOptions(warnReports, filterSpam)) {
|
||||
fun updateWarnReports(warnReports: Boolean): Boolean {
|
||||
if (settings.updateWarnReports(warnReports)) {
|
||||
sendNewAppSpecificData()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun updateFilterSpam(filterSpam: Boolean): Boolean {
|
||||
if (settings.updateFilterSpam(filterSpam)) {
|
||||
if (!settings.syncedSettings.security.filterSpamFromStrangers.value) {
|
||||
transientHiddenUsers.update {
|
||||
emptySet()
|
||||
|
||||
@@ -538,11 +538,16 @@ class AccountSettings(
|
||||
return false
|
||||
}
|
||||
|
||||
fun updateOptOutOptions(
|
||||
warnReports: Boolean,
|
||||
filterSpam: Boolean,
|
||||
): Boolean =
|
||||
if (syncedSettings.security.updateOptOutOptions(warnReports, filterSpam)) {
|
||||
fun updateWarnReports(warnReports: Boolean): Boolean =
|
||||
if (syncedSettings.security.updateWarnReports(warnReports)) {
|
||||
saveAccountSettings()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
fun updateFilterSpam(filterSpam: Boolean): Boolean =
|
||||
if (syncedSettings.security.updateFilterSpam(filterSpam)) {
|
||||
saveAccountSettings()
|
||||
true
|
||||
} else {
|
||||
|
||||
@@ -190,17 +190,17 @@ class AccountSecurityPreferences(
|
||||
return false
|
||||
}
|
||||
|
||||
// ---
|
||||
// filters
|
||||
// ---
|
||||
fun updateOptOutOptions(
|
||||
warnReports: Boolean,
|
||||
filterSpam: Boolean,
|
||||
): Boolean =
|
||||
if (warnAboutPostsWithReports != warnReports || filterSpam != filterSpamFromStrangers.value) {
|
||||
fun updateWarnReports(warnReports: Boolean): Boolean =
|
||||
if (warnAboutPostsWithReports != warnReports) {
|
||||
warnAboutPostsWithReports = warnReports
|
||||
filterSpamFromStrangers.tryEmit(filterSpam)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
fun updateFilterSpam(filterSpam: Boolean): Boolean =
|
||||
if (filterSpam != filterSpamFromStrangers.value) {
|
||||
filterSpamFromStrangers.tryEmit(filterSpam)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
||||
@@ -149,3 +149,33 @@ fun parseBooleanType(screenCode: Int): BooleanType =
|
||||
BooleanType.ALWAYS
|
||||
}
|
||||
}
|
||||
|
||||
enum class WarningType(
|
||||
val prefCode: Boolean?,
|
||||
val screenCode: Int,
|
||||
val resourceId: Int,
|
||||
) {
|
||||
WARN(null, 0, R.string.content_warning_see_warnings_option),
|
||||
SHOW(true, 1, R.string.content_warning_show_all_sensitive_content_option),
|
||||
HIDE(false, 2, R.string.content_warning_hide_all_sensitive_content_option),
|
||||
}
|
||||
|
||||
fun parseWarningType(screenCode: Int): WarningType =
|
||||
when (screenCode) {
|
||||
WarningType.WARN.screenCode -> WarningType.WARN
|
||||
WarningType.SHOW.screenCode -> WarningType.SHOW
|
||||
WarningType.HIDE.screenCode -> WarningType.HIDE
|
||||
else -> {
|
||||
WarningType.WARN
|
||||
}
|
||||
}
|
||||
|
||||
fun parseWarningType(code: Boolean?): WarningType =
|
||||
when (code) {
|
||||
WarningType.WARN.prefCode -> WarningType.WARN
|
||||
WarningType.HIDE.prefCode -> WarningType.HIDE
|
||||
WarningType.SHOW.prefCode -> WarningType.SHOW
|
||||
else -> {
|
||||
WarningType.WARN
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,34 +324,6 @@ fun NoteDropDownMenu(
|
||||
)
|
||||
}
|
||||
HorizontalDivider(thickness = DividerThickness)
|
||||
if (state.showSensitiveContent == null || state.showSensitiveContent == true) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringRes(R.string.content_warning_hide_all_sensitive_content)) },
|
||||
onClick = {
|
||||
accountViewModel.hideSensitiveContent()
|
||||
onDismiss()
|
||||
},
|
||||
)
|
||||
}
|
||||
if (state.showSensitiveContent == null || state.showSensitiveContent == false) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringRes(R.string.content_warning_show_all_sensitive_content)) },
|
||||
onClick = {
|
||||
accountViewModel.disableContentWarnings()
|
||||
onDismiss()
|
||||
},
|
||||
)
|
||||
}
|
||||
if (state.showSensitiveContent != null) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringRes(R.string.content_warning_see_warnings)) },
|
||||
onClick = {
|
||||
accountViewModel.seeContentWarnings()
|
||||
onDismiss()
|
||||
},
|
||||
)
|
||||
}
|
||||
HorizontalDivider(thickness = DividerThickness)
|
||||
if (state.isLoggedUser) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringRes(R.string.request_deletion)) },
|
||||
|
||||
+11
-19
@@ -52,6 +52,7 @@ import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.PublicChatChannel
|
||||
import com.vitorpamplona.amethyst.model.UrlCachedPreviewer
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.model.WarningType
|
||||
import com.vitorpamplona.amethyst.model.observables.CreatedAtComparator
|
||||
import com.vitorpamplona.amethyst.service.CashuProcessor
|
||||
import com.vitorpamplona.amethyst.service.CashuToken
|
||||
@@ -886,21 +887,9 @@ class AccountViewModel(
|
||||
|
||||
fun isFollowing(user: HexKey): Boolean = account.isFollowing(user)
|
||||
|
||||
fun hideSensitiveContent() {
|
||||
fun updateContentWarnings(value: WarningType) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
account.updateShowSensitiveContent(false)
|
||||
}
|
||||
}
|
||||
|
||||
fun disableContentWarnings() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
account.updateShowSensitiveContent(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun seeContentWarnings() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
account.updateShowSensitiveContent(null)
|
||||
account.updateShowSensitiveContent(value.prefCode)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,12 +913,15 @@ class AccountViewModel(
|
||||
|
||||
fun filterSpamFromStrangers() = account.settings.syncedSettings.security.filterSpamFromStrangers
|
||||
|
||||
fun updateOptOutOptions(
|
||||
warnReports: Boolean,
|
||||
filterSpam: Boolean,
|
||||
) {
|
||||
fun updateWarnReports(warnReports: Boolean) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
if (account.updateOptOutOptions(warnReports, filterSpam)) {
|
||||
account.updateWarnReports(warnReports)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateFilterSpam(filterSpam: Boolean) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
if (account.updateFilterSpam(filterSpam)) {
|
||||
LocalCache.antiSpam.active = filterSpamFromStrangers().value
|
||||
}
|
||||
}
|
||||
|
||||
+79
-26
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
@@ -33,11 +34,11 @@ import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.ScrollableTabRow
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -64,6 +65,8 @@ import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.WarningType
|
||||
import com.vitorpamplona.amethyst.model.parseWarningType
|
||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.observeAccountIsHiddenWord
|
||||
import com.vitorpamplona.amethyst.ui.feeds.RefresheableBox
|
||||
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
|
||||
@@ -72,6 +75,8 @@ import com.vitorpamplona.amethyst.ui.navigation.TopBarWithBackButton
|
||||
import com.vitorpamplona.amethyst.ui.note.elements.AddButton
|
||||
import com.vitorpamplona.amethyst.ui.screen.RefreshingFeedUserFeedView
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TextSpinner
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.TitleExplainer
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.dal.HiddenAccountsFeedViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.dal.HiddenWordsFeedViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.settings.dal.SpammerAccountsFeedViewModel
|
||||
@@ -80,9 +85,12 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||
import com.vitorpamplona.amethyst.ui.theme.ButtonPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.HorzPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size15dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.TabRowHeight
|
||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
@@ -153,35 +161,17 @@ fun SecurityFiltersScreen(
|
||||
},
|
||||
accountViewModel = accountViewModel,
|
||||
) {
|
||||
Column(Modifier.padding(it).fillMaxHeight()) {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(it)
|
||||
.fillMaxHeight(),
|
||||
) {
|
||||
val pagerState = rememberPagerState { 3 }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
var warnAboutReports by remember { mutableStateOf(accountViewModel.account.settings.syncedSettings.security.warnAboutPostsWithReports) }
|
||||
var filterSpam by remember { mutableStateOf(accountViewModel.account.settings.syncedSettings.security.filterSpamFromStrangers.value) }
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Checkbox(
|
||||
checked = warnAboutReports,
|
||||
onCheckedChange = {
|
||||
warnAboutReports = it
|
||||
accountViewModel.updateOptOutOptions(warnAboutReports, filterSpam)
|
||||
},
|
||||
)
|
||||
HeaderOptions(accountViewModel)
|
||||
|
||||
Text(stringRes(R.string.warn_when_posts_have_reports_from_your_follows))
|
||||
}
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Checkbox(
|
||||
checked = filterSpam,
|
||||
onCheckedChange = {
|
||||
filterSpam = it
|
||||
accountViewModel.updateOptOutOptions(warnAboutReports, filterSpam)
|
||||
},
|
||||
)
|
||||
|
||||
Text(stringRes(R.string.filter_spam_from_strangers))
|
||||
}
|
||||
HorizontalDivider()
|
||||
|
||||
ScrollableTabRow(
|
||||
containerColor = MaterialTheme.colorScheme.background,
|
||||
@@ -218,6 +208,69 @@ fun SecurityFiltersScreen(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HeaderOptions(accountViewModel: AccountViewModel) {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(top = Size10dp, bottom = Size10dp, start = Size15dp, end = Size15dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = spacedBy(10.dp),
|
||||
) {
|
||||
SettingsRow(
|
||||
R.string.warn_when_posts_have_reports_from_your_follows_title,
|
||||
R.string.warn_when_posts_have_reports_from_your_follows_explainer,
|
||||
) {
|
||||
var warnAboutReports by remember { mutableStateOf(accountViewModel.account.settings.syncedSettings.security.warnAboutPostsWithReports) }
|
||||
|
||||
Switch(
|
||||
checked = warnAboutReports,
|
||||
onCheckedChange = {
|
||||
warnAboutReports = it
|
||||
accountViewModel.updateWarnReports(warnAboutReports)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
SettingsRow(
|
||||
R.string.filter_spam_from_strangers_title,
|
||||
R.string.filter_spam_from_strangers_explainer,
|
||||
) {
|
||||
var filterSpam by remember { mutableStateOf(accountViewModel.account.settings.syncedSettings.security.filterSpamFromStrangers.value) }
|
||||
|
||||
Switch(
|
||||
checked = filterSpam,
|
||||
onCheckedChange = {
|
||||
filterSpam = it
|
||||
accountViewModel.updateFilterSpam(filterSpam)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
SettingsRow(
|
||||
R.string.show_sensitive_content_title,
|
||||
R.string.show_sensitive_content_explainer,
|
||||
) {
|
||||
var sensitive by remember { mutableStateOf(accountViewModel.account.settings.syncedSettings.security.showSensitiveContent.value) }
|
||||
|
||||
val selectedItens =
|
||||
persistentListOf(
|
||||
TitleExplainer(stringRes(WarningType.WARN.resourceId)),
|
||||
TitleExplainer(stringRes(WarningType.SHOW.resourceId)),
|
||||
TitleExplainer(stringRes(WarningType.HIDE.resourceId)),
|
||||
)
|
||||
|
||||
TextSpinner(
|
||||
label = "",
|
||||
placeholder = selectedItens[parseWarningType(sensitive).screenCode].title,
|
||||
options = selectedItens,
|
||||
onSelect = {
|
||||
accountViewModel.updateContentWarnings(parseWarningType(it))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HiddenWordsFeed(
|
||||
hiddenWordsViewModel: HiddenWordsFeedViewModel,
|
||||
|
||||
@@ -585,10 +585,21 @@
|
||||
<string name="content_warning_show_all_sensitive_content">Always show sensitive content</string>
|
||||
<string name="content_warning_see_warnings">Always show content warnings</string>
|
||||
|
||||
<string name="content_warning_hide_all_sensitive_content_option">Hide</string>
|
||||
<string name="content_warning_show_all_sensitive_content_option">Show</string>
|
||||
<string name="content_warning_see_warnings_option">Warn</string>
|
||||
|
||||
<string name="recommended_apps">Recommends: </string>
|
||||
<string name="filter_spam_from_strangers">Filter spam from strangers</string>
|
||||
<string name="warn_when_posts_have_reports_from_your_follows">Warn when posts have reports from your follows</string>
|
||||
|
||||
<string name="filter_spam_from_strangers_title">Filter spam</string>
|
||||
<string name="filter_spam_from_strangers_explainer">Hides posts from strangers that were exactly the same for 5 or more times</string>
|
||||
<string name="warn_when_posts_have_reports_from_your_follows_title">Warn on reports</string>
|
||||
<string name="warn_when_posts_have_reports_from_your_follows_explainer">Shows a warning message when posts have 5 or more reports your follows</string>
|
||||
<string name="show_sensitive_content_title">Show sensitive content</string>
|
||||
<string name="show_sensitive_content_explainer">Shows a warning message when the author of the post marked it as sensitive</string>
|
||||
|
||||
<string name="new_reaction_symbol">New Reaction Symbol</string>
|
||||
<string name="no_reaction_type_setup_long_press_to_change">No reaction types pre-selected for this user. Long press on the heart button to change</string>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user