Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add account preference to filter bot posts from timelines #4846

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,345 changes: 1,345 additions & 0 deletions app/schemas/com.keylesspalace.tusky.db.AppDatabase/66.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ class AccountPreferencesFragment : PreferenceFragmentCompat() {
isSingleLineTitle = false
preferenceDataStore = accountPreferenceDataStore
}

switchPreference {
key = PrefKeys.FILTER_BOTS
setTitle(R.string.pref_title_filter_bots)
isSingleLineTitle = false
preferenceDataStore = accountPreferenceDataStore
}
}
preferenceCategory(R.string.pref_title_per_timeline_preferences) {
preference {
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,16 @@
},
// Note: Starting with version 54, database versions in Tusky are always even.
// This is to reserve odd version numbers for use by forks.
version = 64,
version = 66,
autoMigrations = {
@AutoMigration(from = 48, to = 49),
@AutoMigration(from = 49, to = 50, spec = AppDatabase.MIGRATION_49_50.class),
@AutoMigration(from = 50, to = 51),
@AutoMigration(from = 51, to = 52),
@AutoMigration(from = 53, to = 54), // hasDirectMessageBadge in AccountEntity
@AutoMigration(from = 56, to = 58), // translationEnabled in InstanceEntity/InstanceInfoEntity
@AutoMigration(from = 62, to = 64) // filterV2Available in InstanceEntity
@AutoMigration(from = 62, to = 64), // filterV2Available in InstanceEntity
@AutoMigration(from = 64, to = 66), // filterBots in AccountEntity
}
)
public abstract class AppDatabase extends RoomDatabase {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ data class AccountEntity(
/** True if content behind a content warning is shown by default */
var alwaysOpenSpoiler: Boolean = false,

/** Filter timeline posts by bots */
@ColumnInfo(defaultValue = "0")
var filterBots: Boolean = false,

/**
* True if the "Download media previews" preference is true. This implies
* that media previews are shown as well as downloaded.
Expand Down
14 changes: 13 additions & 1 deletion app/src/main/java/com/keylesspalace/tusky/network/FilterModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.util.Log
import at.connyduck.calladapter.networkresult.fold
import at.connyduck.calladapter.networkresult.getOrElse
import com.keylesspalace.tusky.components.instanceinfo.InstanceInfoRepository
import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.entity.Filter
import com.keylesspalace.tusky.entity.FilterV1
import com.keylesspalace.tusky.entity.Status
Expand All @@ -21,10 +22,12 @@ import javax.inject.Inject
*/
class FilterModel @Inject constructor(
private val instanceInfoRepo: InstanceInfoRepository,
private val api: MastodonApi
private val api: MastodonApi,
private val accountManager: AccountManager,
) {
private var pattern: Pattern? = null
private var v1 = false
private var filterBots: Boolean = false
private lateinit var kind: Filter.Kind

/**
Expand All @@ -33,6 +36,11 @@ class FilterModel @Inject constructor(
*/
suspend fun init(kind: Filter.Kind): Boolean {
this.kind = kind
filterBots = when (kind) {
Filter.Kind.HOME,
Filter.Kind.PUBLIC -> accountManager.activeAccount?.filterBots ?: false
else -> false
}

if (instanceInfoRepo.isFilterV2Supported()) {
// nothing to do - Instance supports V2 so posts are filtered by the server
Expand Down Expand Up @@ -67,6 +75,10 @@ class FilterModel @Inject constructor(
}

fun shouldFilterStatus(status: Status): Filter.Action {
if (filterBots && status.account.bot) {
return Filter.Action.HIDE
}

if (v1) {
// Patterns are expensive and thread-safe, matchers are neither.
val matcher = pattern?.matcher("") ?: return Filter.Action.NONE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class AccountPreferenceDataStore @Inject constructor(
PrefKeys.TAB_FILTER_HOME_BOOSTS -> account.isShowHomeBoosts
PrefKeys.TAB_FILTER_HOME_REPLIES -> account.isShowHomeReplies
PrefKeys.TAB_SHOW_HOME_SELF_BOOSTS -> account.isShowHomeSelfBoosts
PrefKeys.FILTER_BOTS -> account.filterBots
else -> defValue
}
}
Expand All @@ -37,6 +38,7 @@ class AccountPreferenceDataStore @Inject constructor(
PrefKeys.TAB_FILTER_HOME_BOOSTS -> account.isShowHomeBoosts = value
PrefKeys.TAB_FILTER_HOME_REPLIES -> account.isShowHomeReplies = value
PrefKeys.TAB_SHOW_HOME_SELF_BOOSTS -> account.isShowHomeSelfBoosts = value
PrefKeys.FILTER_BOTS -> account.filterBots = value
}

accountManager.saveAccount(account)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ object PrefKeys {
const val MEDIA_PREVIEW_ENABLED = "mediaPreviewEnabled"
const val ALWAYS_SHOW_SENSITIVE_MEDIA = "alwaysShowSensitiveMedia"
const val ALWAYS_OPEN_SPOILER = "alwaysOpenSpoiler"
const val FILTER_BOTS = "filterBots"

const val NOTIFICATIONS_ENABLED = "notificationsEnabled"
const val NOTIFICATION_ALERT_LIGHT = "notificationAlertLight"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@
<string name="pref_title_http_proxy_server">HTTP proxy server</string>
<string name="pref_title_http_proxy_port">HTTP proxy port</string>
<string name="pref_title_http_proxy_port_message">Port should be between %1$d and %2$d</string>
<string name="pref_title_filter_bots">Hide posts by bot accounts</string>
<string name="pref_summary_http_proxy_disabled">Disabled</string>
<string name="pref_summary_http_proxy_missing">&lt;not set></string>
<string name="pref_summary_http_proxy_invalid">&lt;invalid></string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/test/java/com/keylesspalace/tusky/FilterV1Test.kt
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class FilterV1Test {
onBlocking { isFilterV2Supported() } doReturn false
}

filterModel = FilterModel(instanceInfoRepo, api)
filterModel = FilterModel(instanceInfoRepo, api, mock())
runBlocking {
filterModel.init(Filter.Kind.HOME)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class ViewThreadViewModelTest {
onBlocking { isFilterV2Supported() } doReturn false
}
eventHub = EventHub()
val filterModel = FilterModel(instanceInfoRepo, api)
val filterModel = FilterModel(instanceInfoRepo, api, mock())
val timelineCases = TimelineCases(api, eventHub)
val accountManager: AccountManager = mock {
on { activeAccount } doReturn AccountEntity(
Expand Down
Loading