From 7aaea97de0d946ffadaf874c23ba52f137fe265c Mon Sep 17 00:00:00 2001 From: Charlie Fish Date: Wed, 17 Jan 2024 18:17:40 -0700 Subject: [PATCH] mute: adding filtering support for MuteItem events This patch depends on: Receiving New Mute List Type - Changes NewMutesNotify, NewUnmutesNotify & MuteNotify to use MuteItem instead of Pubkey - Changes is_muted in Contacts.swift to take in a MuteItem instead of a Pubkey - A lot of changes here were just modifying callers of that to accept the new parameter type Related: https://github.com/damus-io/damus/issues/1718 Related: https://github.com/damus-io/damus/issues/856 Lighting Address: fishcharlie@strike.me Signed-off-by: Charlie Fish Reviewed-by: William Casarin Signed-off-by: William Casarin --- damus/ContentView.swift | 22 +++++++++---------- damus/Models/Contacts.swift | 18 +++++++-------- damus/Models/HomeModel.swift | 14 +++++------- damus/Models/NotificationsManager.swift | 11 +++------- damus/Notify/MuteNotify.swift | 6 ++--- damus/Notify/NewMutesNotify.swift | 4 ++-- damus/Notify/NewUnmutesNotify.swift | 4 ++-- damus/Views/DirectMessagesView.swift | 2 +- damus/Views/Events/EventMenu.swift | 2 +- .../Events/EventMutingContainerView.swift | 5 +++-- damus/Views/Profile/ProfileView.swift | 4 ++-- 11 files changed, 43 insertions(+), 49 deletions(-) diff --git a/damus/ContentView.swift b/damus/ContentView.swift index 3fd0608d..92e08482 100644 --- a/damus/ContentView.swift +++ b/damus/ContentView.swift @@ -71,7 +71,7 @@ struct ContentView: View { @State var active_sheet: Sheets? = nil @State var damus_state: DamusState! @SceneStorage("ContentView.selected_timeline") var selected_timeline: Timeline = .home - @State var muting: Pubkey? = nil + @State var muting: MuteItem? = nil @State var confirm_mute: Bool = false @State var hide_bar: Bool = false @State var user_muted_confirm: Bool = false @@ -366,8 +366,8 @@ struct ContentView: View { .onReceive(handle_notify(.report)) { target in self.active_sheet = .report(target) } - .onReceive(handle_notify(.mute)) { pubkey in - self.muting = pubkey + .onReceive(handle_notify(.mute)) { mute_item in + self.muting = mute_item self.confirm_mute = true } .onReceive(handle_notify(.attached_wallet)) { nwc in @@ -526,7 +526,7 @@ struct ContentView: View { user_muted_confirm = false } }, message: { - if let pubkey = self.muting { + if case let .user(pubkey, _) = self.muting { let profile_txn = damus_state!.profiles.lookup(id: pubkey) let profile = profile_txn?.unsafeUnownedValue let name = Profile.displayName(profile: profile, pubkey: pubkey).username.truncate(maxLength: 50) @@ -544,13 +544,13 @@ struct ContentView: View { Button(NSLocalizedString("Yes, Overwrite", comment: "Text of button that confirms to overwrite the existing mutelist.")) { guard let ds = damus_state, let keypair = ds.keypair.to_full(), - let pubkey = muting, - let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: .user(pubkey, nil)) + let muting, + let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: muting) else { return } - damus_state?.contacts.set_mutelist(mutelist) + ds.contacts.set_mutelist(mutelist) ds.postbox.send(mutelist) confirm_overwrite_mutelist = false @@ -573,21 +573,21 @@ struct ContentView: View { confirm_overwrite_mutelist = true } else { guard let keypair = ds.keypair.to_full(), - let pubkey = muting + let muting else { return } - guard let ev = create_or_update_mutelist(keypair: keypair, mprev: ds.contacts.mutelist, to_add: .user(pubkey, nil)) else { + guard let ev = create_or_update_mutelist(keypair: keypair, mprev: ds.contacts.mutelist, to_add: muting) else { return } - damus_state?.contacts.set_mutelist(ev) + ds.contacts.set_mutelist(ev) ds.postbox.send(ev) } } }, message: { - if let pubkey = muting { + if case let .user(pubkey, _) = muting { let profile_txn = damus_state?.profiles.lookup(id: pubkey) let profile = profile_txn?.unsafeUnownedValue let name = Profile.displayName(profile: profile, pubkey: pubkey).username.truncate(maxLength: 50) diff --git a/damus/Models/Contacts.swift b/damus/Models/Contacts.swift index 5829ed9c..28e11438 100644 --- a/damus/Models/Contacts.swift +++ b/damus/Models/Contacts.swift @@ -13,7 +13,7 @@ class Contacts { private var friend_of_friends: Set = Set() /// Tracks which friends are friends of a given pubkey. private var pubkey_to_our_friends = [Pubkey : Set]() - private var muted: Set = Set() + private var muted: Set = Set() let our_pubkey: Pubkey var event: NostrEvent? @@ -23,20 +23,20 @@ class Contacts { self.our_pubkey = our_pubkey } - func is_muted(_ pk: Pubkey) -> Bool { - return muted.contains(pk) + func is_muted(_ item: MuteItem) -> Bool { + return muted.contains(item) } - + func set_mutelist(_ ev: NostrEvent) { let oldlist = self.mutelist self.mutelist = ev - let old = oldlist.map({ ev in Set(ev.referenced_pubkeys) }) ?? Set() - let new = Set(ev.referenced_pubkeys) + let old: Set = oldlist?.mute_list ?? Set() + let new: Set = ev.mute_list ?? Set() let diff = old.symmetricDifference(new) - var new_mutes = Set() - var new_unmutes = Set() + var new_mutes = Set() + var new_unmutes = Set() for d in diff { if new.contains(d) { @@ -47,7 +47,7 @@ class Contacts { } // TODO: set local mutelist here - self.muted = Set(ev.referenced_pubkeys) + self.muted = ev.mute_list ?? Set() if new_mutes.count > 0 { notify(.new_mutes(new_mutes)) diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift index 850b6b7b..e44fb66c 100644 --- a/damus/Models/HomeModel.swift +++ b/damus/Models/HomeModel.swift @@ -278,11 +278,11 @@ class HomeModel { func filter_events() { events.filter { ev in - !damus_state.contacts.is_muted(ev.pubkey) + !damus_state.contacts.is_muted(.user(ev.pubkey, nil)) } self.dms.dms = dms.dms.filter { ev in - !damus_state.contacts.is_muted(ev.pubkey) + !damus_state.contacts.is_muted(.user(ev.pubkey, nil)) } notifications.filter { ev in @@ -290,7 +290,8 @@ class HomeModel { return false } - return !damus_state.contacts.is_muted(ev.pubkey) && !damus_state.muted_threads.isMutedThread(ev, keypair: damus_state.keypair) + let event_muted = damus_state.contacts.mutelist?.mute_list?.event_muted_reason(ev) != nil + return !event_muted } } @@ -1093,11 +1094,8 @@ func should_show_event(event: NostrEvent, damus_state: DamusState) -> Bool { } func should_show_event(keypair: Keypair, hellthreads: MutedThreadsManager, contacts: Contacts, ev: NostrEvent) -> Bool { - if contacts.is_muted(ev.pubkey) { - return false - } - - if hellthreads.isMutedThread(ev, keypair: keypair) { + let event_muted = contacts.mutelist?.mute_list?.event_muted_reason(ev) != nil + if event_muted { return false } diff --git a/damus/Models/NotificationsManager.swift b/damus/Models/NotificationsManager.swift index 6a832362..5718f56c 100644 --- a/damus/Models/NotificationsManager.swift +++ b/damus/Models/NotificationsManager.swift @@ -36,16 +36,11 @@ func should_display_notification(state: HeadlessDamusState, event ev: NostrEvent return false } - // Don't show notifications from muted threads. - if state.muted_threads.isMutedThread(ev, keypair: state.keypair) { + // Don't show notifications that match mute list. + if state.contacts.mutelist?.mute_list?.event_muted_reason(ev) != nil { return false } - - // Don't show notifications from muted users - if state.contacts.is_muted(ev.pubkey) { - return false - } - + // Don't show notifications for old events guard ev.age < EVENT_MAX_AGE_FOR_NOTIFICATION else { return false diff --git a/damus/Notify/MuteNotify.swift b/damus/Notify/MuteNotify.swift index db15e519..77263fbb 100644 --- a/damus/Notify/MuteNotify.swift +++ b/damus/Notify/MuteNotify.swift @@ -8,8 +8,8 @@ import Foundation struct MuteNotify: Notify { - typealias Payload = Pubkey - var payload: Payload + typealias Payload = MuteItem + var payload: MuteItem } extension NotifyHandler { @@ -19,7 +19,7 @@ extension NotifyHandler { } extension Notifications { - static func mute(_ target: Pubkey) -> Notifications { + static func mute(_ target: MuteItem) -> Notifications { .init(.init(payload: target)) } } diff --git a/damus/Notify/NewMutesNotify.swift b/damus/Notify/NewMutesNotify.swift index bd3ae75d..201ae4f3 100644 --- a/damus/Notify/NewMutesNotify.swift +++ b/damus/Notify/NewMutesNotify.swift @@ -8,7 +8,7 @@ import Foundation struct NewMutesNotify: Notify { - typealias Payload = Set + typealias Payload = Set var payload: Payload } @@ -19,7 +19,7 @@ extension NotifyHandler { } extension Notifications { - static func new_mutes(_ pubkeys: Set) -> Notifications { + static func new_mutes(_ pubkeys: Set) -> Notifications { .init(.init(payload: pubkeys)) } } diff --git a/damus/Notify/NewUnmutesNotify.swift b/damus/Notify/NewUnmutesNotify.swift index d5bf0f6c..a5c85ae1 100644 --- a/damus/Notify/NewUnmutesNotify.swift +++ b/damus/Notify/NewUnmutesNotify.swift @@ -8,7 +8,7 @@ import Foundation struct NewUnmutesNotify: Notify { - typealias Payload = Set + typealias Payload = Set var payload: Payload } @@ -19,7 +19,7 @@ extension NotifyHandler { } extension Notifications { - static func new_unmutes(_ pubkeys: Set) -> Notifications { + static func new_unmutes(_ pubkeys: Set) -> Notifications { .init(.init(payload: pubkeys)) } } diff --git a/damus/Views/DirectMessagesView.swift b/damus/Views/DirectMessagesView.swift index 2ff3da74..6d3cfacc 100644 --- a/damus/Views/DirectMessagesView.swift +++ b/damus/Views/DirectMessagesView.swift @@ -39,7 +39,7 @@ struct DirectMessagesView: View { func filter_dms(dms: [DirectMessageModel]) -> [DirectMessageModel] { return dms.filter({ dm in - return damus_state.settings.friend_filter.filter(contacts: damus_state.contacts, pubkey: dm.pubkey) && !damus_state.contacts.is_muted(dm.pubkey) + return damus_state.settings.friend_filter.filter(contacts: damus_state.contacts, pubkey: dm.pubkey) && !damus_state.contacts.is_muted(.user(dm.pubkey, nil)) }) } diff --git a/damus/Views/Events/EventMenu.swift b/damus/Views/Events/EventMenu.swift index 8728c9a6..3d368e4a 100644 --- a/damus/Views/Events/EventMenu.swift +++ b/damus/Views/Events/EventMenu.swift @@ -142,7 +142,7 @@ struct MenuItems: View { } Button(role: .destructive) { - notify(.mute(target_pubkey)) + notify(.mute(.user(target_pubkey, nil))) } label: { Label(NSLocalizedString("Mute user", comment: "Context menu option for muting users."), image: "mute") } diff --git a/damus/Views/Events/EventMutingContainerView.swift b/damus/Views/Events/EventMutingContainerView.swift index e8b7cb41..69ac71fd 100644 --- a/damus/Views/Events/EventMutingContainerView.swift +++ b/damus/Views/Events/EventMutingContainerView.swift @@ -49,12 +49,13 @@ struct EventMutingContainerView: View { } } .onReceive(handle_notify(.new_mutes)) { mutes in - if mutes.contains(event.pubkey) { + let new_muted_event_reason = mutes.event_muted_reason(event) + if new_muted_event_reason != nil { shown = false } } .onReceive(handle_notify(.new_unmutes)) { unmutes in - if unmutes.contains(event.pubkey) { + if unmutes.event_muted_reason(event) != nil { shown = true } } diff --git a/damus/Views/Profile/ProfileView.swift b/damus/Views/Profile/ProfileView.swift index 647a8183..c858e3a3 100644 --- a/damus/Views/Profile/ProfileView.swift +++ b/damus/Views/Profile/ProfileView.swift @@ -179,7 +179,7 @@ struct ProfileView: View { notify(.report(.user(profile.pubkey))) } - if damus_state.contacts.is_muted(profile.pubkey) { + if damus_state.contacts.is_muted(.user(profile.pubkey, nil)) { Button(NSLocalizedString("Unmute", comment: "Button to unmute a profile.")) { guard let keypair = damus_state.keypair.to_full(), @@ -197,7 +197,7 @@ struct ProfileView: View { } } else { Button(NSLocalizedString("Mute", comment: "Button to mute a profile."), role: .destructive) { - notify(.mute(profile.pubkey)) + notify(.mute(.user(profile.pubkey, nil))) } } }