damus

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

commit 5edb7df5c42dcbce8b2626df14f113098f1631d0
parent d559dd3a139bf5d02c63a3f5602b8a05ab094726
Author: William Casarin <jb55@jb55.com>
Date:   Fri, 27 Jan 2023 10:18:28 -0800

Mute events in threads

Changlog-Added: Mute events in threads

Diffstat:
Mdamus.xcodeproj/project.pbxproj | 4++++
Mdamus/Models/HomeModel.swift | 17+++++++++--------
Mdamus/Views/EventDetailView.swift | 4++--
Mdamus/Views/EventView.swift | 6+++---
Adamus/Views/Events/MutedEventView.swift | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdamus/Views/ReplyView.swift | 2+-
Mdamus/Views/ThreadV2View.swift | 39++++++++++++++++++++-------------------
Mdamus/Views/TimelineView.swift | 6+-----
8 files changed, 152 insertions(+), 38 deletions(-)

diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj @@ -166,6 +166,7 @@ 4CF0ABE12981A83900D66079 /* MutelistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE02981A83900D66079 /* MutelistView.swift */; }; 4CF0ABE32981BC7D00D66079 /* UserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE22981BC7D00D66079 /* UserView.swift */; }; 4CF0ABE52981EE0C00D66079 /* EULAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE42981EE0C00D66079 /* EULAView.swift */; }; + 4CF0ABE7298444FD00D66079 /* MutedEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE6298444FC00D66079 /* MutedEventView.swift */; }; 4CF0ABE929844AF100D66079 /* AnyCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE829844AF100D66079 /* AnyCodable.swift */; }; 4CF0ABEC29844B4700D66079 /* AnyDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABEB29844B4700D66079 /* AnyDecodable.swift */; }; 4CF0ABEE29844B5500D66079 /* AnyEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABED29844B5500D66079 /* AnyEncodable.swift */; }; @@ -422,6 +423,7 @@ 4CF0ABE02981A83900D66079 /* MutelistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutelistView.swift; sourceTree = "<group>"; }; 4CF0ABE22981BC7D00D66079 /* UserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserView.swift; sourceTree = "<group>"; }; 4CF0ABE42981EE0C00D66079 /* EULAView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EULAView.swift; sourceTree = "<group>"; }; + 4CF0ABE6298444FC00D66079 /* MutedEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutedEventView.swift; sourceTree = "<group>"; }; 4CF0ABE829844AF100D66079 /* AnyCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyCodable.swift; sourceTree = "<group>"; }; 4CF0ABEB29844B4700D66079 /* AnyDecodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyDecodable.swift; sourceTree = "<group>"; }; 4CF0ABED29844B5500D66079 /* AnyEncodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyEncodable.swift; sourceTree = "<group>"; }; @@ -715,6 +717,7 @@ 4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */, 4CC7AAF7297F1CEE00430951 /* EventProfile.swift */, 4CC7AAF9297F64AC00430951 /* EventMenu.swift */, + 4CF0ABE6298444FC00D66079 /* MutedEventView.swift */, ); path = Events; sourceTree = "<group>"; @@ -1061,6 +1064,7 @@ 4C3EA66828FF5F9900C48A62 /* hex.c in Sources */, E9E4ED0B295867B900DD7078 /* ThreadV2View.swift in Sources */, 4C3BEFDC281DCE6100B3DE84 /* Liked.swift in Sources */, + 4CF0ABE7298444FD00D66079 /* MutedEventView.swift in Sources */, 4CF0ABE12981A83900D66079 /* MutelistView.swift in Sources */, 4C75EFB128049D510006080F /* NostrResponse.swift in Sources */, 4CEE2AF7280B2DEA00AB5EEF /* ProfileName.swift in Sources */, diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift @@ -410,15 +410,8 @@ class HomeModel: ObservableObject { return ok } - func should_hide_event(_ ev: NostrEvent) -> Bool { - if damus_state.contacts.is_muted(ev.pubkey) { - return true - } - return !ev.should_show_event - } - func handle_text_event(sub_id: String, _ ev: NostrEvent) { - if should_hide_event(ev) { + if should_hide_event(contacts: damus_state.contacts, ev: ev) { return } @@ -726,3 +719,11 @@ func event_has_our_pubkey(_ ev: NostrEvent, our_pubkey: String) -> Bool { return false } + + +func should_hide_event(contacts: Contacts, ev: NostrEvent) -> Bool { + if contacts.is_muted(ev.pubkey) { + return true + } + return !ev.should_show_event +} diff --git a/damus/Views/EventDetailView.swift b/damus/Views/EventDetailView.swift @@ -71,8 +71,8 @@ struct EventDetailView: View { } toggle_thread_view() } - case .event(let ev, let highlight): - EventView(event: ev, has_action_bar: true, damus: damus) + case .event(let ev, let _): + EventView(damus: damus, event: ev, has_action_bar: true) .onTapGesture { if thread.initial_event.id == ev.id { toggle_thread_view() diff --git a/damus/Views/EventView.swift b/damus/Views/EventView.swift @@ -35,7 +35,7 @@ struct EventView: View { @EnvironmentObject var action_bar: ActionBarModel - init(event: NostrEvent, has_action_bar: Bool, damus: DamusState) { + init(damus: DamusState, event: NostrEvent, has_action_bar: Bool) { self.event = event self.has_action_bar = has_action_bar self.damus = damus @@ -222,9 +222,9 @@ struct EventView_Previews: PreviewProvider { */ EventView( + damus: test_damus_state(), event: test_event, - has_action_bar: true, - damus: test_damus_state() + has_action_bar: true ) } .padding() diff --git a/damus/Views/Events/MutedEventView.swift b/damus/Views/Events/MutedEventView.swift @@ -0,0 +1,112 @@ +// +// MutedEventView.swift +// damus +// +// Created by William Casarin on 2023-01-27. +// + +import SwiftUI + +struct MutedEventView: View { + let damus_state: DamusState + let event: NostrEvent + let scroller: ScrollViewProxy? + + let selected: Bool + @Binding var nav_target: String? + @Binding var navigating: Bool + @State var shown: Bool + @Environment(\.colorScheme) var colorScheme + + init(damus_state: DamusState, event: NostrEvent, scroller: ScrollViewProxy?, nav_target: Binding<String?>, navigating: Binding<Bool>, selected: Bool) { + self.damus_state = damus_state + self.event = event + self.scroller = scroller + self.selected = selected + self._nav_target = nav_target + self._navigating = navigating + self._shown = State(initialValue: !should_hide_event(contacts: damus_state.contacts, ev: event)) + } + + var should_mute: Bool { + return should_hide_event(contacts: damus_state.contacts, ev: event) + } + + var FillColor: Color { + colorScheme == .light ? Color("DamusLightGrey") : Color("DamusDarkGrey") + } + + var MutedBox: some View { + ZStack { + RoundedRectangle(cornerRadius: 20) + .foregroundColor(FillColor) + + HStack { + Text("Post from a user you've blocked") + Spacer() + Button(shown ? "Hide" : "Show") { + shown.toggle() + } + } + .padding(10) + } + } + + var Event: some View { + Group { + if selected { + SelectedEventView(damus: damus_state, event: event) + } else { + EventView(damus: damus_state, event: event, has_action_bar: true) + .onTapGesture { + nav_target = event.id + navigating = true + } + .onAppear { + // TODO: find another solution to prevent layout shifting and layout blocking on large responses + scroller?.scrollTo("main", anchor: .bottom) + } + } + } + } + + var body: some View { + Group { + if should_mute { + MutedBox + } + if shown { + Event + } + } + .onReceive(handle_notify(.new_mutes)) { notif in + guard let mutes = notif.object as? [String] else { + return + } + + if mutes.contains(event.pubkey) { + shown = false + } + } + .onReceive(handle_notify(.new_unmutes)) { notif in + guard let unmutes = notif.object as? [String] else { + return + } + + if unmutes.contains(event.pubkey) { + shown = true + } + } + } +} + +struct MutedEventView_Previews: PreviewProvider { + @State static var nav_target: String? = nil + @State static var navigating: Bool = false + + static var previews: some View { + + MutedEventView(damus_state: test_damus_state(), event: test_event, scroller: nil, nav_target: $nav_target, navigating: $navigating, selected: false) + .frame(width: .infinity, height: 50) + } +} diff --git a/damus/Views/ReplyView.swift b/damus/Views/ReplyView.swift @@ -45,7 +45,7 @@ struct ReplyView: View { ParticipantsView(damus_state: damus, references: $references, originalReferences: $originalReferences) } ScrollView { - EventView(event: replying_to, has_action_bar: false, damus: damus) + EventView(damus: damus, event: replying_to, has_action_bar: false) } PostView(replying_to: replying_to, references: references) } diff --git a/damus/Views/ThreadV2View.swift b/damus/Views/ThreadV2View.swift @@ -255,15 +255,13 @@ struct ThreadV2View: View { // MARK: - Parents events view VStack { ForEach(thread.parentEvents, id: \.id) { event in - EventView(event: event, has_action_bar: true, damus: damus) - .onTapGesture { - nav_target = event.id - navigating = true - } - .onAppear { - // TODO: find another solution to prevent layout shifting and layout blocking on large responses - reader.scrollTo("main", anchor: .bottom) - } + MutedEventView(damus_state: damus, + event: event, + scroller: reader, + nav_target: $nav_target, + navigating: $navigating, + selected: false + ) } }.background(GeometryReader { geometry in // get the height and width of the EventView view @@ -278,22 +276,25 @@ struct ThreadV2View: View { }) // MARK: - Actual event view - SelectedEventView( - damus: damus, - event: thread.current + MutedEventView( + damus_state: damus, + event: thread.current, + scroller: reader, + nav_target: $nav_target, + navigating: $navigating, + selected: true ).id("main") // MARK: - Responses of the actual event view ForEach(thread.childEvents, id: \.id) { event in - EventView( + MutedEventView( + damus_state: damus, event: event, - has_action_bar: true, - damus: damus + scroller: reader, + nav_target: $nav_target, + navigating: $navigating, + selected: false ) - .onTapGesture { - nav_target = event.id - navigating = true - } } }.padding() }.navigationBarTitle(NSLocalizedString("Thread", comment: "Navigation bar title for note thread.")) diff --git a/damus/Views/TimelineView.swift b/damus/Views/TimelineView.swift @@ -39,11 +39,7 @@ struct InnerTimelineView: View { EmptyTimelineView() } else { ForEach(events.filter(filter), id: \.id) { (ev: NostrEvent) in - //let tm = ThreadModel(event: inner_event_or_self(ev: ev), damus_state: damus) - //let is_chatroom = should_show_chatroom(ev) - //let tv = ThreadView(thread: tm, damus: damus, is_chatroom: is_chatroom) - - EventView(event: ev, has_action_bar: true, damus: damus) + EventView(damus: damus, event: ev, has_action_bar: true) .onTapGesture { nav_target = ev navigating = true