add option to opt-out from automatic spam and report filters

This commit is contained in:
greenart7c3
2023-06-09 08:28:05 -03:00
parent b3e2b78415
commit f0638b1766
7 changed files with 57 additions and 2 deletions

View File

@@ -61,6 +61,7 @@ private object PrefKeys {
const val USE_PROXY = "use_proxy" const val USE_PROXY = "use_proxy"
const val PROXY_PORT = "proxy_port" const val PROXY_PORT = "proxy_port"
const val SHOW_SENSITIVE_CONTENT = "show_sensitive_content" const val SHOW_SENSITIVE_CONTENT = "show_sensitive_content"
const val OPT_OUT_FILTERS = "opt_out_filters"
val LAST_READ: (String) -> String = { route -> "last_read_route_$route" } val LAST_READ: (String) -> String = { route -> "last_read_route_$route" }
} }
@@ -217,6 +218,7 @@ object LocalPreferences {
putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog) putBoolean(PrefKeys.HIDE_BLOCK_ALERT_DIALOG, account.hideBlockAlertDialog)
putBoolean(PrefKeys.USE_PROXY, account.proxy != null) putBoolean(PrefKeys.USE_PROXY, account.proxy != null)
putInt(PrefKeys.PROXY_PORT, account.proxyPort) putInt(PrefKeys.PROXY_PORT, account.proxyPort)
putBoolean(PrefKeys.OPT_OUT_FILTERS, account.optOutFromFilters)
if (account.showSensitiveContent == null) { if (account.showSensitiveContent == null) {
remove(PrefKeys.SHOW_SENSITIVE_CONTENT) remove(PrefKeys.SHOW_SENSITIVE_CONTENT)
@@ -306,6 +308,7 @@ object LocalPreferences {
} else { } else {
null null
} }
val optOutFromFilters = getBoolean(PrefKeys.OPT_OUT_FILTERS, false)
val a = Account( val a = Account(
Persona(privKey = privKey?.hexToByteArray(), pubKey = pubKey.hexToByteArray()), Persona(privKey = privKey?.hexToByteArray(), pubKey = pubKey.hexToByteArray()),
@@ -327,7 +330,8 @@ object LocalPreferences {
latestContactList, latestContactList,
proxy, proxy,
proxyPort, proxyPort,
showSensitiveContent showSensitiveContent,
optOutFromFilters
) )
return a return a

View File

@@ -0,0 +1,9 @@
package com.vitorpamplona.amethyst
object OptOutFromFilters {
var optOutFromFilters: Boolean = false
fun start(optOut: Boolean) {
optOutFromFilters = optOut
}
}

View File

@@ -36,6 +36,7 @@ object ServiceManager {
// Resets Proxy Use // Resets Proxy Use
HttpClient.start(account) HttpClient.start(account)
OptOutFromFilters.start(account?.optOutFromFilters ?: false)
Coil.setImageLoader { Coil.setImageLoader {
ImageLoader.Builder(context).components { ImageLoader.Builder(context).components {
if (Build.VERSION.SDK_INT >= 28) { if (Build.VERSION.SDK_INT >= 28) {

View File

@@ -6,6 +6,7 @@ import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.core.os.ConfigurationCompat import androidx.core.os.ConfigurationCompat
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import com.vitorpamplona.amethyst.OptOutFromFilters
import com.vitorpamplona.amethyst.service.FileHeader import com.vitorpamplona.amethyst.service.FileHeader
import com.vitorpamplona.amethyst.service.NostrLnZapPaymentResponseDataSource import com.vitorpamplona.amethyst.service.NostrLnZapPaymentResponseDataSource
import com.vitorpamplona.amethyst.service.model.* import com.vitorpamplona.amethyst.service.model.*
@@ -66,7 +67,8 @@ class Account(
var backupContactList: ContactListEvent? = null, var backupContactList: ContactListEvent? = null,
var proxy: Proxy?, var proxy: Proxy?,
var proxyPort: Int, var proxyPort: Int,
var showSensitiveContent: Boolean? = null var showSensitiveContent: Boolean? = null,
var optOutFromFilters: Boolean = false
) { ) {
var transientHiddenUsers: Set<String> = setOf() var transientHiddenUsers: Set<String> = setOf()
@@ -77,6 +79,13 @@ class Account(
var userProfileCache: User? = null var userProfileCache: User? = null
fun updateOptOutFromFilters(value: Boolean) {
optOutFromFilters = value
OptOutFromFilters.start(optOutFromFilters)
live.invalidateData()
saveable.invalidateData()
}
fun userProfile(): User { fun userProfile(): User {
return userProfileCache ?: run { return userProfileCache ?: run {
val myUser: User = LocalCache.getOrCreateUser(loggedIn.pubKey.toHexKey()) val myUser: User = LocalCache.getOrCreateUser(loggedIn.pubKey.toHexKey())
@@ -1057,12 +1066,19 @@ class Account(
} }
fun isAcceptable(user: User): Boolean { fun isAcceptable(user: User): Boolean {
if (optOutFromFilters) {
return !isHidden(user) && // if user hasn't hided this author
user.reportsBy(userProfile()).isEmpty() // if user has not reported this post
}
return !isHidden(user) && // if user hasn't hided this author return !isHidden(user) && // if user hasn't hided this author
user.reportsBy(userProfile()).isEmpty() && // if user has not reported this post user.reportsBy(userProfile()).isEmpty() && // if user has not reported this post
user.countReportAuthorsBy(followingKeySet()) < 5 user.countReportAuthorsBy(followingKeySet()) < 5
} }
fun isAcceptableDirect(note: Note): Boolean { fun isAcceptableDirect(note: Note): Boolean {
if (optOutFromFilters) {
return note.reportsBy(userProfile()).isEmpty()
}
return note.reportsBy(userProfile()).isEmpty() && // if user has not reported this post return note.reportsBy(userProfile()).isEmpty() && // if user has not reported this post
note.countReportAuthorsBy(followingKeySet()) < 5 // if it has 5 reports by reliable users note.countReportAuthorsBy(followingKeySet()) < 5 // if it has 5 reports by reliable users
} }

View File

@@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.model
import android.util.Log import android.util.Log
import android.util.LruCache import android.util.LruCache
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import com.vitorpamplona.amethyst.OptOutFromFilters
import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.service.model.Event import com.vitorpamplona.amethyst.service.model.Event
import com.vitorpamplona.amethyst.service.nip19.Nip19 import com.vitorpamplona.amethyst.service.nip19.Nip19
@@ -20,6 +21,8 @@ class AntiSpamFilter {
fun isSpam(event: Event, relay: Relay?): Boolean { fun isSpam(event: Event, relay: Relay?): Boolean {
checkNotInMainThread() checkNotInMainThread()
if (OptOutFromFilters.optOutFromFilters) return false
val idHex = event.id val idHex = event.id
// if short message, ok // if short message, ok

View File

@@ -2,10 +2,12 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material.Checkbox
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Tab import androidx.compose.material.Tab
import androidx.compose.material.TabRow import androidx.compose.material.TabRow
@@ -15,7 +17,11 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -23,6 +29,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.screen.NostrHiddenAccountsFeedViewModel import com.vitorpamplona.amethyst.ui.screen.NostrHiddenAccountsFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.RefreshingFeedUserFeedView import com.vitorpamplona.amethyst.ui.screen.RefreshingFeedUserFeedView
@@ -67,6 +74,20 @@ fun HiddenUsersScreen(
Column(modifier = Modifier.padding(start = 10.dp, end = 10.dp)) { Column(modifier = Modifier.padding(start = 10.dp, end = 10.dp)) {
val pagerState = rememberPagerState() val pagerState = rememberPagerState()
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
var checked by remember { mutableStateOf(accountViewModel.account.optOutFromFilters) }
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = checked,
onCheckedChange = {
checked = it
accountViewModel.account.updateOptOutFromFilters(checked)
LocalPreferences.saveToEncryptedStorage(accountViewModel.account)
}
)
Text(stringResource(R.string.opt_out_from_filters))
}
TabRow( TabRow(
backgroundColor = MaterialTheme.colors.background, backgroundColor = MaterialTheme.colors.background,

View File

@@ -412,4 +412,5 @@
<string name="content_warning_see_warnings">Always show content warnings</string> <string name="content_warning_see_warnings">Always show content warnings</string>
<string name="recommended_apps">Recommends: </string> <string name="recommended_apps">Recommends: </string>
<string name="opt_out_from_filters">Opt-out from automatic filters</string>
</resources> </resources>