3891 better hashtag filtering (#3893)
Fixes #3891 (the first two observerations; the rest is either ok or has another issue)
This commit is contained in:
commit
b0150212c3
|
@ -27,6 +27,8 @@ import at.connyduck.calladapter.networkresult.fold
|
|||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.keylesspalace.tusky.appstore.EventHub
|
||||
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent
|
||||
import com.keylesspalace.tusky.components.filters.EditFilterActivity
|
||||
import com.keylesspalace.tusky.components.filters.FiltersActivity
|
||||
import com.keylesspalace.tusky.components.timeline.TimelineFragment
|
||||
import com.keylesspalace.tusky.components.timeline.viewmodel.TimelineViewModel.Kind
|
||||
import com.keylesspalace.tusky.databinding.ActivityStatuslistBinding
|
||||
|
@ -132,6 +134,8 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
{
|
||||
followTagItem?.isVisible = false
|
||||
unfollowTagItem?.isVisible = true
|
||||
|
||||
Snackbar.make(binding.root, getString(R.string.following_hashtag_success_format, tag), Snackbar.LENGTH_SHORT).show()
|
||||
},
|
||||
{
|
||||
Snackbar.make(binding.root, getString(R.string.error_following_hashtag_format, tag), Snackbar.LENGTH_SHORT).show()
|
||||
|
@ -152,6 +156,8 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
{
|
||||
followTagItem?.isVisible = true
|
||||
unfollowTagItem?.isVisible = false
|
||||
|
||||
Snackbar.make(binding.root, getString(R.string.unfollowing_hashtag_success_format, tag), Snackbar.LENGTH_SHORT).show()
|
||||
},
|
||||
{
|
||||
Snackbar.make(binding.root, getString(R.string.error_unfollowing_hashtag_format, tag), Snackbar.LENGTH_SHORT).show()
|
||||
|
@ -169,6 +175,7 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
*/
|
||||
private fun updateMuteTagMenuItems() {
|
||||
val tag = hashtag ?: return
|
||||
val hashedTag = "#$tag"
|
||||
|
||||
muteTagItem?.isVisible = true
|
||||
muteTagItem?.isEnabled = false
|
||||
|
@ -178,9 +185,8 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
mastodonApi.getFilters().fold(
|
||||
{ filters ->
|
||||
mutedFilter = filters.firstOrNull { filter ->
|
||||
filter.context.contains(Filter.Kind.HOME.kind) && filter.keywords.any {
|
||||
it.keyword == tag
|
||||
}
|
||||
// TODO shouldn't this be an exact match (only one keyword; exactly the hashtag)?
|
||||
filter.context.contains(Filter.Kind.HOME.kind) && filter.title == hashedTag
|
||||
}
|
||||
updateTagMuteState(mutedFilter != null)
|
||||
},
|
||||
|
@ -189,7 +195,7 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
mastodonApi.getFiltersV1().fold(
|
||||
{ filters ->
|
||||
mutedFilterV1 = filters.firstOrNull { filter ->
|
||||
tag == filter.phrase && filter.context.contains(FilterV1.HOME)
|
||||
hashedTag == filter.phrase && filter.context.contains(FilterV1.HOME)
|
||||
}
|
||||
updateTagMuteState(mutedFilterV1 != null)
|
||||
},
|
||||
|
@ -221,6 +227,9 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
val tag = hashtag ?: return true
|
||||
|
||||
lifecycleScope.launch {
|
||||
var filterCreateSuccess = false
|
||||
val hashedTag = "#$tag"
|
||||
|
||||
mastodonApi.createFilter(
|
||||
title = "#$tag",
|
||||
context = listOf(FilterV1.HOME),
|
||||
|
@ -228,10 +237,13 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
expiresInSeconds = null
|
||||
).fold(
|
||||
{ filter ->
|
||||
if (mastodonApi.addFilterKeyword(filterId = filter.id, keyword = tag, wholeWord = true).isSuccess) {
|
||||
mutedFilter = filter
|
||||
updateTagMuteState(true)
|
||||
if (mastodonApi.addFilterKeyword(filterId = filter.id, keyword = hashedTag, wholeWord = true).isSuccess) {
|
||||
// must be requested again; otherwise does not contain the keyword (but server does)
|
||||
mutedFilter = mastodonApi.getFilter(filter.id).getOrNull()
|
||||
|
||||
// TODO the preference key here ("home") is not meaningful; should probably be another event if any
|
||||
eventHub.dispatch(PreferenceChangedEvent(filter.context[0]))
|
||||
filterCreateSuccess = true
|
||||
} else {
|
||||
Snackbar.make(binding.root, getString(R.string.error_muting_hashtag_format, tag), Snackbar.LENGTH_SHORT).show()
|
||||
Log.e(TAG, "Failed to mute #$tag")
|
||||
|
@ -240,7 +252,7 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
{ throwable ->
|
||||
if (throwable is HttpException && throwable.code() == 404) {
|
||||
mastodonApi.createFilterV1(
|
||||
tag,
|
||||
hashedTag,
|
||||
listOf(FilterV1.HOME),
|
||||
irreversible = false,
|
||||
wholeWord = true,
|
||||
|
@ -248,8 +260,8 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
).fold(
|
||||
{ filter ->
|
||||
mutedFilterV1 = filter
|
||||
updateTagMuteState(true)
|
||||
eventHub.dispatch(PreferenceChangedEvent(filter.context[0]))
|
||||
filterCreateSuccess = true
|
||||
},
|
||||
{ throwable ->
|
||||
Snackbar.make(binding.root, getString(R.string.error_muting_hashtag_format, tag), Snackbar.LENGTH_SHORT).show()
|
||||
|
@ -262,6 +274,24 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
}
|
||||
}
|
||||
)
|
||||
|
||||
if (filterCreateSuccess) {
|
||||
updateTagMuteState(true)
|
||||
Snackbar.make(binding.root, getString(R.string.muting_hashtag_success_format, tag), Snackbar.LENGTH_LONG).apply {
|
||||
setAction(R.string.action_view_filter) {
|
||||
val intent = if (mutedFilter != null) {
|
||||
Intent(this@StatusListActivity, EditFilterActivity::class.java).apply {
|
||||
putExtra(EditFilterActivity.FILTER_TO_EDIT, mutedFilter)
|
||||
}
|
||||
} else {
|
||||
Intent(this@StatusListActivity, FiltersActivity::class.java)
|
||||
}
|
||||
|
||||
startActivityWithSlideInAnimation(intent)
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
@ -307,6 +337,8 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
|||
eventHub.dispatch(PreferenceChangedEvent(Filter.Kind.HOME.kind))
|
||||
mutedFilterV1 = null
|
||||
mutedFilter = null
|
||||
|
||||
Snackbar.make(binding.root, getString(R.string.unmuting_hashtag_success_format, tag), Snackbar.LENGTH_SHORT).show()
|
||||
},
|
||||
{ throwable ->
|
||||
Snackbar.make(binding.root, getString(R.string.error_unmuting_hashtag_format, tag), Snackbar.LENGTH_SHORT).show()
|
||||
|
|
|
@ -89,6 +89,11 @@ interface MastodonApi {
|
|||
@GET("api/v1/filters")
|
||||
suspend fun getFiltersV1(): NetworkResult<List<FilterV1>>
|
||||
|
||||
@GET("api/v2/filters/{filterId}")
|
||||
suspend fun getFilter(
|
||||
@Path("filterId") filterId: String
|
||||
): NetworkResult<Filter>
|
||||
|
||||
@GET("api/v2/filters")
|
||||
suspend fun getFilters(): NetworkResult<List<Filter>>
|
||||
|
||||
|
|
|
@ -614,6 +614,12 @@
|
|||
<string name="notifications_apply_filter">Filter notifications</string>
|
||||
<string name="filter_apply">Apply</string>
|
||||
|
||||
<string name="muting_hashtag_success_format">Muting hashtag #%s as a warning</string>
|
||||
<string name="unmuting_hashtag_success_format">Unmuting hashtag #%s</string>
|
||||
<string name="action_view_filter">View filter</string>
|
||||
<string name="following_hashtag_success_format">Now following hashtag #%s</string>
|
||||
<string name="unfollowing_hashtag_success_format">No longer following hashtag #%s</string>
|
||||
|
||||
<string name="compose_shortcut_long_label">Compose post</string>
|
||||
<string name="compose_shortcut_short_label">Compose</string>
|
||||
|
||||
|
|
Loading…
Reference in New Issue