mute: integrate new MutelistManager
This patch is slightly large (I think still within the guidelines tho) , but also pretty straightforward. I thought for a while about how I could split this up in a straightforward way, and I couldn’t come up with anything without breaking intermediate builds. - Deleted a lot of old/unnecessary code (ie. the Collection extension for MuteItem, since we’re now using the MutelistManager sets) - Changed damus_state.contacts to damus_state.mutelist_manager for all mute list manager work - Updated MutelistView to take advantage of new code (this is probably the largest change in this patch) Lighting-Address: fishcharlie@strike.me Signed-off-by: Charlie Fish <contact@charlie.fish> Reviewed-by: William Casarin <jb55@jb55.com> Link: 20240210163650.42884-4-contact@charlie.fish Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
committed by
William Casarin
parent
a9baef7a21
commit
1d4d2b0204
@@ -20,7 +20,7 @@ struct DMChatView: View, KeyboardReadable {
|
||||
ScrollViewReader { scroller in
|
||||
ScrollView {
|
||||
LazyVStack(alignment: .leading) {
|
||||
ForEach(Array(zip(dms.events, dms.events.indices)), id: \.0.id) { (ev, ind) in
|
||||
ForEach(Array(zip(dms.events, dms.events.indices)).filter { should_show_event(state: damus_state, ev: $0.0, keypair: damus_state.keypair)}, id: \.0.id) { (ev, ind) in
|
||||
DMView(event: dms.events[ind], damus_state: damus_state)
|
||||
.contextMenu{MenuItems(damus_state: damus_state, event: ev, target_pubkey: ev.pubkey, profileModel: ProfileModel(pubkey: ev.pubkey, damus: damus_state))}
|
||||
}
|
||||
|
||||
@@ -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(.user(dm.pubkey, nil))
|
||||
return damus_state.settings.friend_filter.filter(contacts: damus_state.contacts, pubkey: dm.pubkey) && !damus_state.mutelist_manager.is_muted(.user(dm.pubkey, nil))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ struct DirectMessagesView: View {
|
||||
|
||||
func MaybeEvent(_ model: DirectMessageModel) -> some View {
|
||||
Group {
|
||||
if let ev = model.events.last {
|
||||
if let ev = model.events.last(where: { should_show_event(state: damus_state, ev: $0, keypair: damus_state.keypair) }) {
|
||||
EventView(damus: damus_state, event: ev, pubkey: model.pubkey, options: options)
|
||||
.onTapGesture {
|
||||
self.model.set_active_dm_model(model)
|
||||
|
||||
@@ -55,7 +55,7 @@ struct MenuItems: View {
|
||||
let bookmarked = damus_state.bookmarks.isBookmarked(event)
|
||||
self._isBookmarked = State(initialValue: bookmarked)
|
||||
|
||||
let muted_thread = (damus_state.contacts.mutelist?.mute_list?.event_muted_reason(event) != nil)
|
||||
let muted_thread = damus_state.mutelist_manager.is_event_muted(event)
|
||||
self._isMutedThread = State(initialValue: muted_thread)
|
||||
|
||||
self.damus_state = damus_state
|
||||
@@ -111,11 +111,11 @@ struct MenuItems: View {
|
||||
if event.known_kind != .dm {
|
||||
MuteDurationMenu { duration in
|
||||
if let full_keypair = self.damus_state.keypair.to_full(),
|
||||
let new_mutelist_ev = toggle_from_mutelist(keypair: full_keypair, prev: damus_state.contacts.mutelist, to_toggle: .thread(event.thread_id(keypair: damus_state.keypair), duration?.date_from_now)) {
|
||||
damus_state.contacts.set_mutelist(new_mutelist_ev)
|
||||
let new_mutelist_ev = toggle_from_mutelist(keypair: full_keypair, prev: damus_state.mutelist_manager.event, to_toggle: .thread(event.thread_id(keypair: damus_state.keypair), duration?.date_from_now)) {
|
||||
damus_state.mutelist_manager.set_mutelist(new_mutelist_ev)
|
||||
damus_state.postbox.send(new_mutelist_ev)
|
||||
}
|
||||
let muted = (damus_state.contacts.mutelist?.mute_list?.event_muted_reason(event) != nil)
|
||||
let muted = damus_state.mutelist_manager.is_event_muted(event)
|
||||
isMutedThread = muted
|
||||
} label: {
|
||||
let imageName = isMutedThread ? "mute" : "mute"
|
||||
|
||||
@@ -27,7 +27,7 @@ struct EventMutingContainerView<Content: View>: View {
|
||||
self.damus_state = damus_state
|
||||
self.event = event
|
||||
self.content = content()
|
||||
self._shown = State(initialValue: should_show_event(contacts: damus_state.contacts, ev: event))
|
||||
self._shown = State(initialValue: should_show_event(state: damus_state, ev: event))
|
||||
}
|
||||
|
||||
init(damus_state: DamusState, event: NostrEvent, muteBox: @escaping MuteBoxViewClosure, @ViewBuilder content: () -> Content) {
|
||||
@@ -36,7 +36,7 @@ struct EventMutingContainerView<Content: View>: View {
|
||||
}
|
||||
|
||||
var should_mute: Bool {
|
||||
return !should_show_event(contacts: damus_state.contacts, ev: event)
|
||||
return !should_show_event(state: damus_state, ev: event)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@@ -54,14 +54,14 @@ struct EventMutingContainerView<Content: View>: View {
|
||||
}
|
||||
}
|
||||
.onReceive(handle_notify(.new_mutes)) { mutes in
|
||||
let new_muted_event_reason = mutes.event_muted_reason(event)
|
||||
let new_muted_event_reason = damus_state.mutelist_manager.event_muted_reason(event)
|
||||
if new_muted_event_reason != nil {
|
||||
shown = false
|
||||
muted_reason = new_muted_event_reason
|
||||
}
|
||||
}
|
||||
.onReceive(handle_notify(.new_unmutes)) { unmutes in
|
||||
if unmutes.event_muted_reason(event) != nil {
|
||||
if damus_state.mutelist_manager.event_muted_reason(event) != nil {
|
||||
shown = true
|
||||
muted_reason = nil
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ struct AddMuteItemView: View {
|
||||
|
||||
// Actually update & relay the new mute list
|
||||
if let mute_item {
|
||||
let existing_mutelist = state.contacts.mutelist
|
||||
let existing_mutelist = state.mutelist_manager.event
|
||||
|
||||
guard
|
||||
let full_keypair = state.keypair.to_full(),
|
||||
@@ -81,7 +81,7 @@ struct AddMuteItemView: View {
|
||||
return
|
||||
}
|
||||
|
||||
state.contacts.set_mutelist(mutelist)
|
||||
state.mutelist_manager.set_mutelist(mutelist)
|
||||
state.postbox.send(mutelist)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,16 @@ import SwiftUI
|
||||
|
||||
struct MutelistView: View {
|
||||
let damus_state: DamusState
|
||||
@State var mutelist_items: Set<MuteItem> = Set<MuteItem>()
|
||||
@State var show_add_muteitem: Bool = false
|
||||
|
||||
@State var users: [MuteItem] = []
|
||||
@State var hashtags: [MuteItem] = []
|
||||
@State var threads: [MuteItem] = []
|
||||
@State var words: [MuteItem] = []
|
||||
|
||||
func RemoveAction(item: MuteItem) -> some View {
|
||||
Button {
|
||||
guard let mutelist = damus_state.contacts.mutelist,
|
||||
guard let mutelist = damus_state.mutelist_manager.event,
|
||||
let keypair = damus_state.keypair.to_full(),
|
||||
let new_ev = remove_from_mutelist(keypair: keypair,
|
||||
prev: mutelist,
|
||||
@@ -23,74 +27,88 @@ struct MutelistView: View {
|
||||
return
|
||||
}
|
||||
|
||||
damus_state.contacts.set_mutelist(new_ev)
|
||||
damus_state.mutelist_manager.set_mutelist(new_ev)
|
||||
damus_state.postbox.send(new_ev)
|
||||
mutelist_items = new_ev.mute_list ?? Set<MuteItem>()
|
||||
updateMuteItems()
|
||||
} label: {
|
||||
Label(NSLocalizedString("Delete", comment: "Button to remove a user from their mutelist."), image: "delete")
|
||||
}
|
||||
.tint(.red)
|
||||
}
|
||||
|
||||
func updateMuteItems() {
|
||||
users = Array(damus_state.mutelist_manager.users)
|
||||
hashtags = Array(damus_state.mutelist_manager.hashtags)
|
||||
threads = Array(damus_state.mutelist_manager.threads)
|
||||
words = Array(damus_state.mutelist_manager.words)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
List {
|
||||
Section(NSLocalizedString("Users", comment: "Section header title for a list of muted users.")) {
|
||||
ForEach(mutelist_items.users, id: \.self) { pubkey in
|
||||
UserViewRow(damus_state: damus_state, pubkey: pubkey)
|
||||
.id(pubkey)
|
||||
.swipeActions {
|
||||
RemoveAction(item: .user(pubkey, nil))
|
||||
}
|
||||
.onTapGesture {
|
||||
damus_state.nav.push(route: Route.ProfileByKey(pubkey: pubkey))
|
||||
}
|
||||
ForEach(users, id: \.self) { user in
|
||||
if case let MuteItem.user(pubkey, _) = user {
|
||||
UserViewRow(damus_state: damus_state, pubkey: pubkey)
|
||||
.id(pubkey)
|
||||
.swipeActions {
|
||||
RemoveAction(item: .user(pubkey, nil))
|
||||
}
|
||||
.onTapGesture {
|
||||
damus_state.nav.push(route: Route.ProfileByKey(pubkey: pubkey))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Section(NSLocalizedString("Hashtags", comment: "Section header title for a list of hashtags that are muted.")) {
|
||||
ForEach(mutelist_items.hashtags, id: \.hashtag) { hashtag in
|
||||
Text("#\(hashtag.hashtag)")
|
||||
.id(hashtag.hashtag)
|
||||
.swipeActions {
|
||||
RemoveAction(item: .hashtag(hashtag, nil))
|
||||
}
|
||||
.onTapGesture {
|
||||
damus_state.nav.push(route: Route.Search(search: SearchModel.init(state: damus_state, search: NostrFilter(hashtag: [hashtag.hashtag]))))
|
||||
}
|
||||
ForEach(hashtags, id: \.self) { item in
|
||||
if case let MuteItem.hashtag(hashtag, _) = item {
|
||||
Text("#\(hashtag.hashtag)")
|
||||
.id(hashtag.hashtag)
|
||||
.swipeActions {
|
||||
RemoveAction(item: .hashtag(hashtag, nil))
|
||||
}
|
||||
.onTapGesture {
|
||||
damus_state.nav.push(route: Route.Search(search: SearchModel.init(state: damus_state, search: NostrFilter(hashtag: [hashtag.hashtag]))))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Section(NSLocalizedString("Words", comment: "Section header title for a list of words that are muted.")) {
|
||||
ForEach(mutelist_items.words, id: \.self) { word in
|
||||
Text("\(word)")
|
||||
.id(word)
|
||||
.swipeActions {
|
||||
RemoveAction(item: .word(word, nil))
|
||||
}
|
||||
ForEach(words, id: \.self) { item in
|
||||
if case let MuteItem.word(word, _) = item {
|
||||
Text("\(word)")
|
||||
.id(word)
|
||||
.swipeActions {
|
||||
RemoveAction(item: .word(word, nil))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Section(NSLocalizedString("Threads", comment: "Section header title for a list of threads that are muted.")) {
|
||||
ForEach(mutelist_items.threads, id: \.self) { note_id in
|
||||
if let event = damus_state.events.lookup(note_id) {
|
||||
EventView(damus: damus_state, event: event)
|
||||
.id(note_id.hex())
|
||||
.swipeActions {
|
||||
RemoveAction(item: .thread(note_id, nil))
|
||||
}
|
||||
} else {
|
||||
Text(NSLocalizedString("Error retrieving muted event", comment: "Text for an item that application failed to retrieve the muted event for."))
|
||||
ForEach(threads, id: \.self) { item in
|
||||
if case let MuteItem.thread(note_id, _) = item {
|
||||
if let event = damus_state.events.lookup(note_id) {
|
||||
EventView(damus: damus_state, event: event)
|
||||
.id(note_id.hex())
|
||||
.swipeActions {
|
||||
RemoveAction(item: .thread(note_id, nil))
|
||||
}
|
||||
} else {
|
||||
Text(NSLocalizedString("Error retrieving muted event", comment: "Text for an item that application failed to retrieve the muted event for."))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle(NSLocalizedString("Muted", comment: "Navigation title of view to see list of muted users & phrases."))
|
||||
.onAppear {
|
||||
mutelist_items = damus_state.contacts.mutelist?.mute_list ?? Set<MuteItem>()
|
||||
updateMuteItems()
|
||||
}
|
||||
.onReceive(handle_notify(.new_mutes)) { new_mutes in
|
||||
mutelist_items = mutelist_items.union(new_mutes)
|
||||
updateMuteItems()
|
||||
}
|
||||
.onReceive(handle_notify(.new_unmutes)) { new_unmutes in
|
||||
mutelist_items = mutelist_items.subtracting(new_unmutes)
|
||||
updateMuteItems()
|
||||
}
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .topBarTrailing) {
|
||||
@@ -115,11 +133,6 @@ struct MutelistView: View {
|
||||
|
||||
struct MutelistView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
MutelistView(damus_state: test_damus_state, mutelist_items: Set([
|
||||
.user(test_note.pubkey, nil),
|
||||
.hashtag(Hashtag(hashtag: "test"), nil),
|
||||
.word("test", nil),
|
||||
.thread(test_note.id, nil)
|
||||
]))
|
||||
MutelistView(damus_state: test_damus_state)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,11 +179,11 @@ struct ProfileView: View {
|
||||
notify(.report(.user(profile.pubkey)))
|
||||
}
|
||||
|
||||
if damus_state.contacts.is_muted(.user(profile.pubkey, nil)) {
|
||||
if damus_state.mutelist_manager.is_muted(.user(profile.pubkey, nil)) {
|
||||
Button(NSLocalizedString("Unmute", comment: "Button to unmute a profile.")) {
|
||||
guard
|
||||
let keypair = damus_state.keypair.to_full(),
|
||||
let mutelist = damus_state.contacts.mutelist
|
||||
let mutelist = damus_state.mutelist_manager.event
|
||||
else {
|
||||
return
|
||||
}
|
||||
@@ -192,7 +192,7 @@ struct ProfileView: View {
|
||||
return
|
||||
}
|
||||
|
||||
damus_state.contacts.set_mutelist(new_ev)
|
||||
damus_state.mutelist_manager.set_mutelist(new_ev)
|
||||
damus_state.postbox.send(new_ev)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -59,7 +59,7 @@ struct SearchHomeView: View {
|
||||
return false
|
||||
}
|
||||
|
||||
let event_muted = damus_state.contacts.mutelist?.mute_list?.event_muted_reason(ev) != nil
|
||||
let event_muted = damus_state.mutelist_manager.is_event_muted(ev)
|
||||
if event_muted {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -62,13 +62,13 @@ struct SearchView: View {
|
||||
Button {
|
||||
guard
|
||||
let full_keypair = appstate.keypair.to_full(),
|
||||
let existing_mutelist = appstate.contacts.mutelist,
|
||||
let existing_mutelist = appstate.mutelist_manager.event,
|
||||
let mutelist = remove_from_mutelist(keypair: full_keypair, prev: existing_mutelist, to_remove: .hashtag(Hashtag(hashtag: hashtag), nil))
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
appstate.contacts.set_mutelist(mutelist)
|
||||
appstate.mutelist_manager.set_mutelist(mutelist)
|
||||
appstate.postbox.send(mutelist)
|
||||
} label: {
|
||||
Text("Unmute Hashtag", comment: "Label represnting a button that the user can tap to unmute a given hashtag so they start seeing it in their feed again.")
|
||||
@@ -88,7 +88,7 @@ struct SearchView: View {
|
||||
}
|
||||
.onAppear {
|
||||
if let hashtag_string = search.search.hashtag?.first {
|
||||
is_hashtag_muted = (appstate.contacts.mutelist?.mute_list ?? []).contains(MuteItem.hashtag(Hashtag(hashtag: hashtag_string), nil))
|
||||
is_hashtag_muted = (appstate.mutelist_manager.event?.mute_list ?? []).contains(MuteItem.hashtag(Hashtag(hashtag: hashtag_string), nil))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,13 +96,13 @@ struct SearchView: View {
|
||||
func mute_hashtag(hashtag_string: String, expiration_time: Date?) {
|
||||
guard
|
||||
let full_keypair = appstate.keypair.to_full(),
|
||||
let existing_mutelist = appstate.contacts.mutelist,
|
||||
let existing_mutelist = appstate.mutelist_manager.event,
|
||||
let mutelist = create_or_update_mutelist(keypair: full_keypair, mprev: existing_mutelist, to_add: .hashtag(Hashtag(hashtag: hashtag_string), expiration_time))
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
appstate.contacts.set_mutelist(mutelist)
|
||||
appstate.mutelist_manager.set_mutelist(mutelist)
|
||||
appstate.postbox.send(mutelist)
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ struct SideMenuView: View {
|
||||
}
|
||||
}
|
||||
|
||||
NavigationLink(value: Route.MuteList(mutelist_items: damus_state.contacts.mutelist?.mute_list ?? Set<MuteItem>())) {
|
||||
NavigationLink(value: Route.MuteList) {
|
||||
navLabel(title: NSLocalizedString("Muted", comment: "Sidebar menu label for muted users view."), img: "mute")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user