From fb2ef90ec51c47c801d290f2f6ff2289121cbeb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Wed, 13 Aug 2025 13:23:42 +0200 Subject: [PATCH] [feature] support blur filter action (#4371) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull request implements the `blur` value of `filter_action` for status filtering. It was introduced by Mastodon 4.4.0. [Related docs update](https://github.com/mastodon/documentation/pull/1620) Signed-off-by: nicole mikołajczyk Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4371 Reviewed-by: kim Co-authored-by: nicole mikołajczyk Co-committed-by: nicole mikołajczyk --- internal/api/model/filterv2.go | 2 ++ internal/filter/status/api.go | 2 ++ internal/filter/status/status.go | 4 ++-- internal/gtsmodel/filter.go | 6 ++++++ internal/typeutils/frontendtointernal.go | 2 ++ internal/typeutils/internaltofrontend.go | 2 ++ internal/validate/formvalidation.go | 6 ++++-- 7 files changed, 20 insertions(+), 4 deletions(-) diff --git a/internal/api/model/filterv2.go b/internal/api/model/filterv2.go index 26b1b22b3..98a83fc74 100644 --- a/internal/api/model/filterv2.go +++ b/internal/api/model/filterv2.go @@ -69,6 +69,8 @@ const ( FilterActionWarn FilterAction = "warn" // FilterActionHide filters will remove this status from API results. FilterActionHide FilterAction = "hide" + // FilterActionBlur filters will include this status in API results indicating the media attachments should be hidden/blurred. + FilterActionBlur FilterAction = "blur" ) // FilterKeyword represents text to filter within a v2 filter. diff --git a/internal/filter/status/api.go b/internal/filter/status/api.go index 1d6684b59..bca82a15e 100644 --- a/internal/filter/status/api.go +++ b/internal/filter/status/api.go @@ -100,6 +100,8 @@ func toAPIFilterAction(m gtsmodel.FilterAction) apimodel.FilterAction { return apimodel.FilterActionWarn case gtsmodel.FilterActionHide: return apimodel.FilterActionHide + case gtsmodel.FilterActionBlur: + return apimodel.FilterActionBlur } return apimodel.FilterActionNone } diff --git a/internal/filter/status/status.go b/internal/filter/status/status.go index e38131ae3..572f669d5 100644 --- a/internal/filter/status/status.go +++ b/internal/filter/status/status.go @@ -208,8 +208,8 @@ func (f *Filter) getStatusFilterResults( var apiResult *apimodel.FilterResult switch filter.Action { - case gtsmodel.FilterActionWarn: - // For filter action WARN get all possible filter matches against status. + case gtsmodel.FilterActionWarn, gtsmodel.FilterActionBlur: + // For filter action WARN or BLUR get all possible filter matches against status. keywordMatches, statusMatches := getFilterMatches(filter, status.ID, fields) if len(keywordMatches) == 0 && len(statusMatches) == 0 { continue diff --git a/internal/gtsmodel/filter.go b/internal/gtsmodel/filter.go index 1d457d878..522456b39 100644 --- a/internal/gtsmodel/filter.go +++ b/internal/gtsmodel/filter.go @@ -205,6 +205,10 @@ const ( // FilterActionHide means that the status should // be removed from timeline results entirely. FilterActionHide FilterAction = 2 + + // FilterActionWarn means that the status should + // be shown with its media attachments hidden/blurred. + FilterActionBlur FilterAction = 3 ) // String returns human-readable form of FilterAction. @@ -216,6 +220,8 @@ func (act FilterAction) String() string { return "warn" case FilterActionHide: return "hide" + case FilterActionBlur: + return "blur" default: panic(fmt.Sprintf("invalid filter action: %d", act)) } diff --git a/internal/typeutils/frontendtointernal.go b/internal/typeutils/frontendtointernal.go index 239527eb1..412da7257 100644 --- a/internal/typeutils/frontendtointernal.go +++ b/internal/typeutils/frontendtointernal.go @@ -70,6 +70,8 @@ func APIFilterActionToFilterAction(m apimodel.FilterAction) gtsmodel.FilterActio return gtsmodel.FilterActionWarn case apimodel.FilterActionHide: return gtsmodel.FilterActionHide + case apimodel.FilterActionBlur: + return gtsmodel.FilterActionBlur } return gtsmodel.FilterActionNone } diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go index a4cb1c0e1..ab15d7425 100644 --- a/internal/typeutils/internaltofrontend.go +++ b/internal/typeutils/internaltofrontend.go @@ -2500,6 +2500,8 @@ func filterActionToAPIFilterAction(m gtsmodel.FilterAction) apimodel.FilterActio return apimodel.FilterActionWarn case gtsmodel.FilterActionHide: return apimodel.FilterActionHide + case gtsmodel.FilterActionBlur: + return apimodel.FilterActionBlur } return apimodel.FilterActionNone } diff --git a/internal/validate/formvalidation.go b/internal/validate/formvalidation.go index 42c231491..ce4d6c292 100644 --- a/internal/validate/formvalidation.go +++ b/internal/validate/formvalidation.go @@ -383,14 +383,16 @@ func FilterContexts(contexts []apimodel.FilterContext) error { func FilterAction(action apimodel.FilterAction) error { switch action { case apimodel.FilterActionWarn, - apimodel.FilterActionHide: + apimodel.FilterActionHide, + apimodel.FilterActionBlur: return nil } return fmt.Errorf( - "filter action '%s' was not recognized, valid options are '%s', '%s'", + "filter action '%s' was not recognized, valid options are '%s', '%s', '%s'", action, apimodel.FilterActionWarn, apimodel.FilterActionHide, + apimodel.FilterActionBlur, ) }