damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 440e37c1d396134fb3124389a06a267aec486bea
parent 49283f2bb21ebcbfd0093b872c59308ec6d7d4f7
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 21 Sep 2023 08:30:23 -0400

filters: generalize ContentFilter

This simplifies our content filters so that it is a bit more flexible
for future additions.

Fixes: 0957cc896cc8 ("Add "Do not show #nsfw tagged posts" setting")

Diffstat:
Mdamus/ContentView.swift | 19++++++++++---------
Mdamus/Models/ContentFilters.swift | 42+++++++++++++++++++-----------------------
Mdamus/Views/SearchHomeView.swift | 10+++++-----
3 files changed, 34 insertions(+), 37 deletions(-)

diff --git a/damus/ContentView.swift b/damus/ContentView.swift @@ -82,12 +82,7 @@ struct ContentView: View { @StateObject var navigationCoordinator: NavigationCoordinator = NavigationCoordinator() @AppStorage("has_seen_suggested_users") private var hasSeenSuggestedUsers = false let sub_id = UUID().description - var damus_filter: DamusFilter { - get { - return DamusFilter(hide_nsfw_tagged_content: self.damus_state?.settings.hide_nsfw_tagged_content ?? true) - } - } - + @Environment(\.colorScheme) var colorScheme // connect retry timer @@ -97,7 +92,13 @@ struct ContentView: View { Text("Are you lost?", comment: "Text asking the user if they are lost in the app.") .id("what") } - + + func content_filter(_ fstate: FilterState) -> ((NostrEvent) -> Bool) { + var filters = ContentFilters.defaults(damus_state!.settings) + filters.append(fstate.filter) + return ContentFilters(filters: filters).filter + } + var PostingTimelineView: some View { VStack { ZStack { @@ -105,10 +106,10 @@ struct ContentView: View { // This is needed or else there is a bug when switching from the 3rd or 2nd tab to first. no idea why. mystery - contentTimelineView(filter: damus_filter.get_filter(.posts)) + contentTimelineView(filter: content_filter(.posts)) .tag(FilterState.posts) .id(FilterState.posts) - contentTimelineView(filter: damus_filter.get_filter(.posts_and_replies)) + contentTimelineView(filter: content_filter(.posts_and_replies)) .tag(FilterState.posts_and_replies) .id(FilterState.posts_and_replies) } diff --git a/damus/Models/ContentFilters.swift b/damus/Models/ContentFilters.swift @@ -7,15 +7,9 @@ import Foundation -protocol ContentFilter { - /// Function that implements the content filtering logic - /// - Parameter ev: The nostr event to be processed - /// - Returns: Must return `true` to show events, and return `false` to hide/filter events - func filter(ev: NostrEvent) -> Bool -} /// Simple filter to determine whether to show posts or all posts and replies. -enum FilterState : Int, ContentFilter { +enum FilterState : Int { case posts_and_replies = 1 case posts = 0 @@ -30,29 +24,31 @@ enum FilterState : Int, ContentFilter { } /// Simple filter to determine whether to show posts with #nsfw tags -struct NSFWTagFilter: ContentFilter { - func filter(ev: NostrEvent) -> Bool { +func nsfw_tag_filter(ev: NostrEvent) -> Bool { return ev.referenced_hashtags.first(where: { t in t.hashtag == "nsfw" }) == nil - } } /// Generic filter with various tweakable settings -struct DamusFilter: ContentFilter { - let hide_nsfw_tagged_content: Bool - +struct ContentFilters { + var filters: [(NostrEvent) -> Bool] + func filter(ev: NostrEvent) -> Bool { - if self.hide_nsfw_tagged_content { - return NSFWTagFilter().filter(ev: ev) - } - else { - return true + for filter in filters { + if !filter(ev) { + return false + } } + + return true } - - func get_filter(_ filter_state: FilterState) -> ((NostrEvent) -> Bool) { - return { ev in - return filter_state.filter(ev: ev) && self.filter(ev: ev) +} + +extension ContentFilters { + static func defaults(_ settings: UserSettingsStore) -> [(NostrEvent) -> Bool] { + var filters = Array<(NostrEvent) -> Bool>() + if settings.hide_nsfw_tagged_content { + filters.append(nsfw_tag_filter) } + return filters } - } diff --git a/damus/Views/SearchHomeView.swift b/damus/Views/SearchHomeView.swift @@ -14,10 +14,10 @@ struct SearchHomeView: View { @StateObject var model: SearchHomeModel @State var search: String = "" @FocusState private var isFocused: Bool - var damus_filter: DamusFilter { - get { - return DamusFilter(hide_nsfw_tagged_content: self.damus_state.settings.hide_nsfw_tagged_content) - } + + var content_filter: (NostrEvent) -> Bool { + let filters = ContentFilters.defaults(self.damus_state.settings) + return ContentFilters(filters: filters).filter } let preferredLanguages = Set(Locale.preferredLanguages.map { localeToLanguage($0) }) @@ -55,7 +55,7 @@ struct SearchHomeView: View { damus: damus_state, show_friend_icon: true, filter: { ev in - if !damus_filter.filter(ev: ev) { + if !content_filter(ev) { return false }