mute: updating UI to support new mute list
This patch depends on: Adding filtering support for MuteItem events - Gives more specific mute reason in EventMutedBoxView - Showing all types of mutes in MutelistView - Allowing for adding mutes directly from MutelistView - Allowing for choosing duration of mute in EventMenu 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 <contact@charlie.fish> Reviewed-by: William Casarin <jb55@jb55.com> Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
committed by
William Casarin
parent
61a9e44898
commit
75d66434f3
@@ -14,7 +14,7 @@ enum Route: Hashable {
|
|||||||
case Relay(relay: String, showActionButtons: Binding<Bool>)
|
case Relay(relay: String, showActionButtons: Binding<Bool>)
|
||||||
case RelayDetail(relay: String, metadata: RelayMetadata?)
|
case RelayDetail(relay: String, metadata: RelayMetadata?)
|
||||||
case Following(following: FollowingModel)
|
case Following(following: FollowingModel)
|
||||||
case MuteList(users: [Pubkey])
|
case MuteList(mutelist_items: Set<MuteItem>)
|
||||||
case RelayConfig
|
case RelayConfig
|
||||||
case Script(script: ScriptModel)
|
case Script(script: ScriptModel)
|
||||||
case Bookmarks
|
case Bookmarks
|
||||||
@@ -58,8 +58,8 @@ enum Route: Hashable {
|
|||||||
RelayDetailView(state: damusState, relay: relay, nip11: metadata)
|
RelayDetailView(state: damusState, relay: relay, nip11: metadata)
|
||||||
case .Following(let following):
|
case .Following(let following):
|
||||||
FollowingView(damus_state: damusState, following: following)
|
FollowingView(damus_state: damusState, following: following)
|
||||||
case .MuteList(let users):
|
case .MuteList(let mutelist_items):
|
||||||
MutelistView(damus_state: damusState, users: users)
|
MutelistView(damus_state: damusState, mutelist_items: mutelist_items)
|
||||||
case .RelayConfig:
|
case .RelayConfig:
|
||||||
RelayConfigView(state: damusState)
|
RelayConfigView(state: damusState)
|
||||||
case .Bookmarks:
|
case .Bookmarks:
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ struct DMChatView: View, KeyboardReadable {
|
|||||||
LazyVStack(alignment: .leading) {
|
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)), id: \.0.id) { (ev, ind) in
|
||||||
DMView(event: dms.events[ind], damus_state: damus_state)
|
DMView(event: dms.events[ind], damus_state: damus_state)
|
||||||
.contextMenu{MenuItems(event: ev, keypair: damus_state.keypair, target_pubkey: ev.pubkey, bookmarks: damus_state.bookmarks, muted_threads: damus_state.muted_threads, settings: damus_state.settings, profileModel: ProfileModel(pubkey: ev.pubkey, damus: damus_state))}
|
.contextMenu{MenuItems(damus_state: damus_state, event: ev, target_pubkey: ev.pubkey, profileModel: ProfileModel(pubkey: ev.pubkey, damus: damus_state))}
|
||||||
}
|
}
|
||||||
EndBlock(height: 1)
|
EndBlock(height: 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,21 +8,15 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct EventMenuContext: View {
|
struct EventMenuContext: View {
|
||||||
|
let damus_state: DamusState
|
||||||
let event: NostrEvent
|
let event: NostrEvent
|
||||||
let keypair: Keypair
|
|
||||||
let target_pubkey: Pubkey
|
let target_pubkey: Pubkey
|
||||||
let bookmarks: BookmarksManager
|
|
||||||
let muted_threads: MutedThreadsManager
|
|
||||||
let profileModel : ProfileModel
|
let profileModel : ProfileModel
|
||||||
@ObservedObject var settings: UserSettingsStore
|
|
||||||
|
|
||||||
init(damus: DamusState, event: NostrEvent) {
|
init(damus: DamusState, event: NostrEvent) {
|
||||||
|
self.damus_state = damus
|
||||||
self.event = event
|
self.event = event
|
||||||
self.keypair = damus.keypair
|
|
||||||
self.target_pubkey = event.pubkey
|
self.target_pubkey = event.pubkey
|
||||||
self.bookmarks = damus.bookmarks
|
|
||||||
self.muted_threads = damus.muted_threads
|
|
||||||
self._settings = ObservedObject(wrappedValue: damus.settings)
|
|
||||||
self.profileModel = ProfileModel(pubkey: target_pubkey, damus: damus)
|
self.profileModel = ProfileModel(pubkey: target_pubkey, damus: damus)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +28,7 @@ struct EventMenuContext: View {
|
|||||||
// Add our Menu button inside an overlay modifier to avoid affecting the rest of the layout around us.
|
// Add our Menu button inside an overlay modifier to avoid affecting the rest of the layout around us.
|
||||||
.overlay(
|
.overlay(
|
||||||
Menu {
|
Menu {
|
||||||
MenuItems(event: event, keypair: keypair, target_pubkey: target_pubkey, bookmarks: bookmarks, muted_threads: muted_threads, settings: settings, profileModel: profileModel)
|
MenuItems(damus_state: damus_state, event: event, target_pubkey: target_pubkey, profileModel: profileModel)
|
||||||
} label: {
|
} label: {
|
||||||
Color.clear
|
Color.clear
|
||||||
}
|
}
|
||||||
@@ -49,38 +43,31 @@ struct EventMenuContext: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct MenuItems: View {
|
struct MenuItems: View {
|
||||||
|
let damus_state: DamusState
|
||||||
let event: NostrEvent
|
let event: NostrEvent
|
||||||
let keypair: Keypair
|
|
||||||
let target_pubkey: Pubkey
|
let target_pubkey: Pubkey
|
||||||
let bookmarks: BookmarksManager
|
|
||||||
let muted_threads: MutedThreadsManager
|
|
||||||
let profileModel: ProfileModel
|
let profileModel: ProfileModel
|
||||||
|
|
||||||
@ObservedObject var settings: UserSettingsStore
|
|
||||||
|
|
||||||
@State private var isBookmarked: Bool = false
|
@State private var isBookmarked: Bool = false
|
||||||
@State private var isMutedThread: Bool = false
|
@State private var isMutedThread: Bool = false
|
||||||
|
|
||||||
init(event: NostrEvent, keypair: Keypair, target_pubkey: Pubkey, bookmarks: BookmarksManager, muted_threads: MutedThreadsManager, settings: UserSettingsStore, profileModel: ProfileModel) {
|
init(damus_state: DamusState, event: NostrEvent, target_pubkey: Pubkey, profileModel: ProfileModel) {
|
||||||
let bookmarked = bookmarks.isBookmarked(event)
|
let bookmarked = damus_state.bookmarks.isBookmarked(event)
|
||||||
self._isBookmarked = State(initialValue: bookmarked)
|
self._isBookmarked = State(initialValue: bookmarked)
|
||||||
|
|
||||||
let muted_thread = muted_threads.isMutedThread(event, keypair: keypair)
|
let muted_thread = (damus_state.contacts.mutelist?.mute_list?.event_muted_reason(event) != nil)
|
||||||
self._isMutedThread = State(initialValue: muted_thread)
|
self._isMutedThread = State(initialValue: muted_thread)
|
||||||
|
|
||||||
self.bookmarks = bookmarks
|
self.damus_state = damus_state
|
||||||
self.muted_threads = muted_threads
|
|
||||||
self.event = event
|
self.event = event
|
||||||
self.keypair = keypair
|
|
||||||
self.target_pubkey = target_pubkey
|
self.target_pubkey = target_pubkey
|
||||||
self.settings = settings
|
|
||||||
self.profileModel = profileModel
|
self.profileModel = profileModel
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
Group {
|
||||||
Button {
|
Button {
|
||||||
UIPasteboard.general.string = event.get_content(keypair)
|
UIPasteboard.general.string = event.get_content(damus_state.keypair)
|
||||||
} label: {
|
} label: {
|
||||||
Label(NSLocalizedString("Copy text", comment: "Context menu option for copying the text from an note."), image: "copy2")
|
Label(NSLocalizedString("Copy text", comment: "Context menu option for copying the text from an note."), image: "copy2")
|
||||||
}
|
}
|
||||||
@@ -97,7 +84,7 @@ struct MenuItems: View {
|
|||||||
Label(NSLocalizedString("Copy note ID", comment: "Context menu option for copying the ID of the note."), image: "note-book")
|
Label(NSLocalizedString("Copy note ID", comment: "Context menu option for copying the ID of the note."), image: "note-book")
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.developer_mode {
|
if damus_state.settings.developer_mode {
|
||||||
Button {
|
Button {
|
||||||
UIPasteboard.general.string = event_to_json(ev: event)
|
UIPasteboard.general.string = event_to_json(ev: event)
|
||||||
} label: {
|
} label: {
|
||||||
@@ -106,8 +93,8 @@ struct MenuItems: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
self.bookmarks.updateBookmark(event)
|
self.damus_state.bookmarks.updateBookmark(event)
|
||||||
isBookmarked = self.bookmarks.isBookmarked(event)
|
isBookmarked = self.damus_state.bookmarks.isBookmarked(event)
|
||||||
} label: {
|
} label: {
|
||||||
let imageName = isBookmarked ? "bookmark.fill" : "bookmark"
|
let imageName = isBookmarked ? "bookmark.fill" : "bookmark"
|
||||||
let removeBookmarkString = NSLocalizedString("Remove bookmark", comment: "Context menu option for removing a note bookmark.")
|
let removeBookmarkString = NSLocalizedString("Remove bookmark", comment: "Context menu option for removing a note bookmark.")
|
||||||
@@ -122,9 +109,13 @@ struct MenuItems: View {
|
|||||||
}
|
}
|
||||||
// Mute thread - relocated to below Broadcast, as to move further away from Add Bookmark to prevent accidental muted threads
|
// Mute thread - relocated to below Broadcast, as to move further away from Add Bookmark to prevent accidental muted threads
|
||||||
if event.known_kind != .dm {
|
if event.known_kind != .dm {
|
||||||
Button {
|
MuteDurationMenu { duration in
|
||||||
self.muted_threads.updateMutedThread(event)
|
if let full_keypair = self.damus_state.keypair.to_full(),
|
||||||
let muted = self.muted_threads.isMutedThread(event, keypair: self.keypair)
|
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)
|
||||||
|
damus_state.postbox.send(new_mutelist_ev)
|
||||||
|
}
|
||||||
|
let muted = (damus_state.contacts.mutelist?.mute_list?.event_muted_reason(event) != nil)
|
||||||
isMutedThread = muted
|
isMutedThread = muted
|
||||||
} label: {
|
} label: {
|
||||||
let imageName = isMutedThread ? "mute" : "mute"
|
let imageName = isMutedThread ? "mute" : "mute"
|
||||||
@@ -134,15 +125,15 @@ struct MenuItems: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Only allow reporting if logged in with private key and the currently viewed profile is not the logged in profile.
|
// Only allow reporting if logged in with private key and the currently viewed profile is not the logged in profile.
|
||||||
if keypair.pubkey != target_pubkey && keypair.privkey != nil {
|
if damus_state.keypair.pubkey != target_pubkey && damus_state.keypair.privkey != nil {
|
||||||
Button(role: .destructive) {
|
Button(role: .destructive) {
|
||||||
notify(.report(.note(ReportNoteTarget(pubkey: target_pubkey, note_id: event.id))))
|
notify(.report(.note(ReportNoteTarget(pubkey: target_pubkey, note_id: event.id))))
|
||||||
} label: {
|
} label: {
|
||||||
Label(NSLocalizedString("Report", comment: "Context menu option for reporting content."), image: "raising-hand")
|
Label(NSLocalizedString("Report", comment: "Context menu option for reporting content."), image: "raising-hand")
|
||||||
}
|
}
|
||||||
|
|
||||||
Button(role: .destructive) {
|
MuteDurationMenu { duration in
|
||||||
notify(.mute(.user(target_pubkey, nil)))
|
notify(.mute(.user(target_pubkey, duration?.date_from_now)))
|
||||||
} label: {
|
} label: {
|
||||||
Label(NSLocalizedString("Mute user", comment: "Context menu option for muting users."), image: "mute")
|
Label(NSLocalizedString("Mute user", comment: "Context menu option for muting users."), image: "mute")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,20 @@ import SwiftUI
|
|||||||
|
|
||||||
/// A container view that shows or hides provided content based on whether the given event should be muted or not, with built-in user controls to show or hide content, and an option to customize the muted box
|
/// A container view that shows or hides provided content based on whether the given event should be muted or not, with built-in user controls to show or hide content, and an option to customize the muted box
|
||||||
struct EventMutingContainerView<Content: View>: View {
|
struct EventMutingContainerView<Content: View>: View {
|
||||||
typealias MuteBoxViewClosure = ((_ shown: Binding<Bool>) -> AnyView)
|
typealias MuteBoxViewClosure = ((_ shown: Binding<Bool>, _ mutedReason: MuteItem?) -> AnyView)
|
||||||
|
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
let event: NostrEvent
|
let event: NostrEvent
|
||||||
let content: Content
|
let content: Content
|
||||||
var customMuteBox: MuteBoxViewClosure?
|
var customMuteBox: MuteBoxViewClosure?
|
||||||
|
|
||||||
|
/// Represents if the note itself should be shown.
|
||||||
|
///
|
||||||
|
/// By default this is the same as `should_show_event`. However, if the user taps the button to manually show a muted note, this can become out of sync with `should_show_event`.
|
||||||
@State var shown: Bool
|
@State var shown: Bool
|
||||||
|
|
||||||
|
@State var muted_reason: MuteItem?
|
||||||
|
|
||||||
init(damus_state: DamusState, event: NostrEvent, @ViewBuilder content: () -> Content) {
|
init(damus_state: DamusState, event: NostrEvent, @ViewBuilder content: () -> Content) {
|
||||||
self.damus_state = damus_state
|
self.damus_state = damus_state
|
||||||
self.event = event
|
self.event = event
|
||||||
@@ -38,10 +43,10 @@ struct EventMutingContainerView<Content: View>: View {
|
|||||||
Group {
|
Group {
|
||||||
if should_mute {
|
if should_mute {
|
||||||
if let customMuteBox {
|
if let customMuteBox {
|
||||||
customMuteBox($shown)
|
customMuteBox($shown, muted_reason)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EventMutedBoxView(shown: $shown)
|
EventMutedBoxView(shown: $shown, reason: muted_reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if shown {
|
if shown {
|
||||||
@@ -52,11 +57,13 @@ struct EventMutingContainerView<Content: View>: View {
|
|||||||
let new_muted_event_reason = mutes.event_muted_reason(event)
|
let new_muted_event_reason = mutes.event_muted_reason(event)
|
||||||
if new_muted_event_reason != nil {
|
if new_muted_event_reason != nil {
|
||||||
shown = false
|
shown = false
|
||||||
|
muted_reason = new_muted_event_reason
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onReceive(handle_notify(.new_unmutes)) { unmutes in
|
.onReceive(handle_notify(.new_unmutes)) { unmutes in
|
||||||
if unmutes.event_muted_reason(event) != nil {
|
if unmutes.event_muted_reason(event) != nil {
|
||||||
shown = true
|
shown = true
|
||||||
|
muted_reason = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,16 +72,21 @@ struct EventMutingContainerView<Content: View>: View {
|
|||||||
/// A box that instructs the user about a content that has been muted.
|
/// A box that instructs the user about a content that has been muted.
|
||||||
struct EventMutedBoxView: View {
|
struct EventMutedBoxView: View {
|
||||||
@Binding var shown: Bool
|
@Binding var shown: Bool
|
||||||
|
var reason: MuteItem?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
RoundedRectangle(cornerRadius: 20)
|
RoundedRectangle(cornerRadius: 20)
|
||||||
.foregroundColor(DamusColors.adaptableGrey)
|
.foregroundColor(DamusColors.adaptableGrey)
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
Text("Note from a user you've muted", comment: "Text to indicate that what is being shown is a note from a user who has been muted.")
|
if let reason {
|
||||||
|
Text("Note from a \(reason.title) you've muted", comment: "Text to indicate that what is being shown is a note which has been muted.")
|
||||||
|
} else {
|
||||||
|
Text("Note you've muted", comment: "Text to indicate that what is being shown is a note which has been muted.")
|
||||||
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
Button(shown ? NSLocalizedString("Hide", comment: "Button to hide a note from a user who has been muted.") : NSLocalizedString("Show", comment: "Button to show a note from a user who has been muted.")) {
|
Button(shown ? NSLocalizedString("Hide", comment: "Button to hide a note which has been muted.") : NSLocalizedString("Show", comment: "Button to show a note which has been muted.")) {
|
||||||
shown.toggle()
|
shown.toggle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,55 +9,117 @@ import SwiftUI
|
|||||||
|
|
||||||
struct MutelistView: View {
|
struct MutelistView: View {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
@State var users: [Pubkey]
|
@State var mutelist_items: Set<MuteItem> = Set<MuteItem>()
|
||||||
|
@State var show_add_muteitem: Bool = false
|
||||||
func RemoveAction(pubkey: Pubkey) -> some View {
|
|
||||||
|
func RemoveAction(item: MuteItem) -> some View {
|
||||||
Button {
|
Button {
|
||||||
guard let mutelist = damus_state.contacts.mutelist,
|
guard let mutelist = damus_state.contacts.mutelist,
|
||||||
let keypair = damus_state.keypair.to_full(),
|
let keypair = damus_state.keypair.to_full(),
|
||||||
let new_ev = remove_from_mutelist(keypair: keypair,
|
let new_ev = remove_from_mutelist(keypair: keypair,
|
||||||
prev: mutelist,
|
prev: mutelist,
|
||||||
to_remove: .user(pubkey, nil))
|
to_remove: item)
|
||||||
else {
|
else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
damus_state.contacts.set_mutelist(new_ev)
|
damus_state.contacts.set_mutelist(new_ev)
|
||||||
damus_state.postbox.send(new_ev)
|
damus_state.postbox.send(new_ev)
|
||||||
users = get_mutelist_users(new_ev)
|
mutelist_items = new_ev.mute_list ?? Set<MuteItem>()
|
||||||
} label: {
|
} label: {
|
||||||
Label(NSLocalizedString("Delete", comment: "Button to remove a user from their mutelist."), image: "delete")
|
Label(NSLocalizedString("Delete", comment: "Button to remove a user from their mutelist."), image: "delete")
|
||||||
}
|
}
|
||||||
.tint(.red)
|
.tint(.red)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List(users, id: \.self) { pubkey in
|
List {
|
||||||
UserViewRow(damus_state: damus_state, pubkey: pubkey)
|
Section(NSLocalizedString("Users", comment: "Section header title for a list of muted users.")) {
|
||||||
.id(pubkey)
|
ForEach(mutelist_items.users, id: \.self) { pubkey in
|
||||||
.swipeActions {
|
UserViewRow(damus_state: damus_state, pubkey: pubkey)
|
||||||
RemoveAction(pubkey: pubkey)
|
.id(pubkey)
|
||||||
|
.swipeActions {
|
||||||
|
RemoveAction(item: .user(pubkey, nil))
|
||||||
|
}
|
||||||
|
.onTapGesture {
|
||||||
|
damus_state.nav.push(route: Route.ProfileByKey(pubkey: pubkey))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.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]))))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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."))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.navigationTitle(NSLocalizedString("Muted Users", comment: "Navigation title of view to see list of muted users."))
|
.navigationTitle(NSLocalizedString("Muted", comment: "Navigation title of view to see list of muted users & phrases."))
|
||||||
.onAppear {
|
.onAppear {
|
||||||
users = get_mutelist_users(damus_state.contacts.mutelist)
|
mutelist_items = damus_state.contacts.mutelist?.mute_list ?? Set<MuteItem>()
|
||||||
|
}
|
||||||
|
.onReceive(handle_notify(.new_mutes)) { new_mutes in
|
||||||
|
mutelist_items = mutelist_items.union(new_mutes)
|
||||||
|
}
|
||||||
|
.onReceive(handle_notify(.new_unmutes)) { new_unmutes in
|
||||||
|
mutelist_items = mutelist_items.subtracting(new_unmutes)
|
||||||
|
}
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .topBarTrailing) {
|
||||||
|
Button {
|
||||||
|
self.show_add_muteitem = true
|
||||||
|
} label: {
|
||||||
|
Image(systemName: "plus")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sheet(isPresented: $show_add_muteitem, onDismiss: { self.show_add_muteitem = false }) {
|
||||||
|
if #available(iOS 16.0, *) {
|
||||||
|
AddMuteItemView(state: damus_state)
|
||||||
|
.presentationDetents([.height(300)])
|
||||||
|
.presentationDragIndicator(.visible)
|
||||||
|
} else {
|
||||||
|
AddMuteItemView(state: damus_state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func get_mutelist_users(_ mutelist: NostrEvent?) -> Array<Pubkey> {
|
|
||||||
guard let mutelist else { return [] }
|
|
||||||
return Array(mutelist.referenced_pubkeys)
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MutelistView_Previews: PreviewProvider {
|
struct MutelistView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
MutelistView(damus_state: test_damus_state, users: [test_note.pubkey, test_note.pubkey])
|
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)
|
||||||
|
]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,8 +196,11 @@ struct ProfileView: View {
|
|||||||
damus_state.postbox.send(new_ev)
|
damus_state.postbox.send(new_ev)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Button(NSLocalizedString("Mute", comment: "Button to mute a profile."), role: .destructive) {
|
MuteDurationMenu { duration in
|
||||||
notify(.mute(.user(profile.pubkey, nil)))
|
notify(.mute(.user(profile.pubkey, duration?.date_from_now)))
|
||||||
|
} label: {
|
||||||
|
Text(NSLocalizedString("Mute", comment: "Button to mute a profile."))
|
||||||
|
.foregroundStyle(.red)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ struct RepostedEvent: View {
|
|||||||
EventMutingContainerView(
|
EventMutingContainerView(
|
||||||
damus_state: damus,
|
damus_state: damus,
|
||||||
event: inner_ev,
|
event: inner_ev,
|
||||||
muteBox: { event_shown in
|
muteBox: { event_shown, muted_reason in
|
||||||
AnyView(
|
AnyView(
|
||||||
EventMutedBoxView(shown: event_shown)
|
EventMutedBoxView(shown: event_shown, reason: muted_reason)
|
||||||
.padding(.horizontal, 5) // Add a bit of horizontal padding to avoid the mute box from touching the edges of the screen
|
.padding(.horizontal, 5) // Add a bit of horizontal padding to avoid the mute box from touching the edges of the screen
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ struct SideMenuView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationLink(value: Route.MuteList(users: get_mutelist_users(damus_state.contacts.mutelist))) {
|
NavigationLink(value: Route.MuteList(mutelist_items: damus_state.contacts.mutelist?.mute_list ?? Set<MuteItem>())) {
|
||||||
navLabel(title: NSLocalizedString("Muted", comment: "Sidebar menu label for muted users view."), img: "mute")
|
navLabel(title: NSLocalizedString("Muted", comment: "Sidebar menu label for muted users view."), img: "mute")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ struct ThreadView: View {
|
|||||||
EventMutingContainerView(
|
EventMutingContainerView(
|
||||||
damus_state: state,
|
damus_state: state,
|
||||||
event: self.thread.event,
|
event: self.thread.event,
|
||||||
muteBox: { event_shown in
|
muteBox: { event_shown, muted_reason in
|
||||||
AnyView(
|
AnyView(
|
||||||
EventMutedBoxView(shown: event_shown)
|
EventMutedBoxView(shown: event_shown, reason: muted_reason)
|
||||||
.padding(5)
|
.padding(5)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user