damus

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

commit 66641fc9ae21e46ae4a7623ca237a27ca7a17f18
parent 681e0f0be9dba3bbd3fe83005383dfec9bebf4a7
Author: Terry Yiu <963907+tyiu@users.noreply.github.com>
Date:   Mon, 17 Apr 2023 03:04:18 +0200

Add setting to hide reactions

Changelog-Added: Add setting to hide reactions

Diffstat:
Mdamus/ContentView.swift | 11+++++++----
Mdamus/Models/FollowingModel.swift | 2+-
Mdamus/Models/HomeModel.swift | 37++++++++++++++++++++++++-------------
Mdamus/Models/SearchHomeModel.swift | 2+-
Mdamus/Models/SearchModel.swift | 2+-
Mdamus/Models/ThreadModel.swift | 11++++++++---
Mdamus/Models/UserSettingsStore.swift | 7+++++++
Mdamus/Models/ZapsModel.swift | 2+-
Mdamus/Nostr/NostrFilter.swift | 6+++---
Mdamus/Util/Notifications.swift | 3+++
Mdamus/Views/ActionBar/EventActionBar.swift | 31++++++++++++++++++-------------
Mdamus/Views/ActionBar/EventDetailBar.swift | 2+-
Mdamus/Views/Settings/AppearanceSettingsView.swift | 8++++++++
MdamusTests/RequestTests.swift | 2+-
14 files changed, 84 insertions(+), 42 deletions(-)

diff --git a/damus/ContentView.swift b/damus/ContentView.swift @@ -467,13 +467,13 @@ struct ContentView: View { self.damus_state?.pool.connect_to_disconnected() } .onReceive(handle_notify(.new_mutes)) { notif in - home.filter_muted() + home.filter_events() } .onReceive(handle_notify(.mute_thread)) { notif in - home.filter_muted() + home.filter_events() } .onReceive(handle_notify(.unmute_thread)) { notif in - home.filter_muted() + home.filter_events() } .onReceive(handle_notify(.local_notification)) { notif in @@ -498,6 +498,9 @@ struct ContentView: View { open_event(ev: target) } } + .onReceive(handle_notify(.hide_reactions)) { notif in + home.filter_events() + } .alert(NSLocalizedString("Deleted Account", comment: "Alert message to indicate this is a deleted account"), isPresented: $is_deleted_account) { Button(NSLocalizedString("Logout", comment: "Button to close the alert that informs that the current account has been deleted.")) { is_deleted_account = false @@ -841,7 +844,7 @@ func find_event(state: DamusState, evid: String, search_type: SearchType, find_f var filter = search_type == .event ? NostrFilter.filter_ids([ evid ]) : NostrFilter.filter_authors([ evid ]) if search_type == .profile { - filter.kinds = [0] + filter.kinds = [NostrKind.metadata.rawValue] } filter.limit = 1 diff --git a/damus/Models/FollowingModel.swift b/damus/Models/FollowingModel.swift @@ -22,7 +22,7 @@ class FollowingModel { } func get_filter() -> NostrFilter { - var f = NostrFilter.filter_kinds([0]) + var f = NostrFilter.filter_kinds([NostrKind.metadata.rawValue]) f.authors = self.contacts.reduce(into: Array<String>()) { acc, pk in // don't fetch profiles we already have if damus_state.profiles.lookup(id: pk) != nil { diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift @@ -52,7 +52,7 @@ class HomeModel: ObservableObject { init() { self.damus_state = DamusState.empty - filter_muted() + filter_events() self.setup_debouncer() } @@ -192,7 +192,7 @@ class HomeModel: ObservableObject { func handle_channel_meta(_ ev: NostrEvent) { } - func filter_muted() { + func filter_events() { events.filter { ev in !damus_state.contacts.is_muted(ev.pubkey) } @@ -203,7 +203,8 @@ class HomeModel: ObservableObject { notifications.filter { ev in !damus_state.contacts.is_muted(ev.pubkey) && - !damus_state.muted_threads.isMutedThread(ev, privkey: damus_state.keypair.privkey) + !damus_state.muted_threads.isMutedThread(ev, privkey: damus_state.keypair.privkey) && + (ev.kind != NostrKind.like.rawValue || !damus_state.settings.hide_reactions) } } @@ -258,6 +259,10 @@ class HomeModel: ObservableObject { return } + if damus_state.settings.hide_reactions { + return + } + switch damus_state.likes.add_event(ev, target: e.ref_id) { case .already_counted: break @@ -353,13 +358,13 @@ class HomeModel: ObservableObject { var friends = damus_state.contacts.get_friend_list() friends.append(damus_state.pubkey) - var contacts_filter = NostrFilter.filter_kinds([0]) + var contacts_filter = NostrFilter.filter_kinds([NostrKind.metadata.rawValue]) contacts_filter.authors = friends - var our_contacts_filter = NostrFilter.filter_kinds([3, 0]) + var our_contacts_filter = NostrFilter.filter_kinds([NostrKind.contacts.rawValue, NostrKind.metadata.rawValue]) our_contacts_filter.authors = [damus_state.pubkey] - var our_blocklist_filter = NostrFilter.filter_kinds([30000]) + var our_blocklist_filter = NostrFilter.filter_kinds([NostrKind.list.rawValue]) our_blocklist_filter.parameter = ["mute"] our_blocklist_filter.authors = [damus_state.pubkey] @@ -378,21 +383,27 @@ class HomeModel: ObservableObject { our_dms_filter.authors = [ damus_state.pubkey ] // TODO: separate likes? - var home_filter = NostrFilter.filter_kinds([ + var home_filter_kinds = [ NostrKind.text.rawValue, - NostrKind.like.rawValue, - NostrKind.boost.rawValue, - ]) + NostrKind.boost.rawValue + ] + if !damus_state.settings.hide_reactions { + home_filter_kinds.append(NostrKind.like.rawValue) + } + var home_filter = NostrFilter.filter_kinds(home_filter_kinds) // include our pubkey as well even if we're not technically a friend home_filter.authors = friends home_filter.limit = 500 - var notifications_filter = NostrFilter.filter_kinds([ + var notifications_filter_kinds = [ NostrKind.text.rawValue, - NostrKind.like.rawValue, NostrKind.boost.rawValue, NostrKind.zap.rawValue, - ]) + ] + if !damus_state.settings.hide_reactions { + notifications_filter_kinds.append(NostrKind.like.rawValue) + } + var notifications_filter = NostrFilter.filter_kinds(notifications_filter_kinds) notifications_filter.pubkeys = [damus_state.pubkey] notifications_filter.limit = 500 diff --git a/damus/Models/SearchHomeModel.swift b/damus/Models/SearchHomeModel.swift @@ -24,7 +24,7 @@ class SearchHomeModel: ObservableObject { } func get_base_filter() -> NostrFilter { - var filter = NostrFilter.filter_kinds([1, 42]) + var filter = NostrFilter.filter_kinds([NostrKind.text.rawValue, NostrKind.chat.rawValue]) filter.limit = self.limit filter.until = Int64(Date.now.timeIntervalSince1970) return filter diff --git a/damus/Models/SearchModel.swift b/damus/Models/SearchModel.swift @@ -33,7 +33,7 @@ class SearchModel: ObservableObject { func subscribe() { // since 1 month search.limit = self.limit - search.kinds = [1,5,7] + search.kinds = [NostrKind.text.rawValue, NostrKind.delete.rawValue, NostrKind.like.rawValue] //likes_filter.ids = ref_events.referenced_ids! diff --git a/damus/Models/ThreadModel.swift b/damus/Models/ThreadModel.swift @@ -77,18 +77,23 @@ class ThreadModel: ObservableObject { var meta_events = NostrFilter() var event_filter = NostrFilter() var ref_events = NostrFilter() - //var likes_filter = NostrFilter.filter_kinds(7]) let thread_id = event.thread_id(privkey: nil) ref_events.referenced_ids = [thread_id, event.id] - ref_events.kinds = [1] + ref_events.kinds = [NostrKind.text.rawValue] ref_events.limit = 1000 event_filter.ids = [thread_id, event.id] meta_events.referenced_ids = [event.id] - meta_events.kinds = [9735, 1, 6, 7] + + var kinds = [NostrKind.zap.rawValue, NostrKind.text.rawValue, NostrKind.boost.rawValue] + if !damus_state.settings.hide_reactions { + kinds.append(NostrKind.like.rawValue) + } + meta_events.kinds = kinds + meta_events.limit = 1000 /* diff --git a/damus/Models/UserSettingsStore.swift b/damus/Models/UserSettingsStore.swift @@ -202,6 +202,12 @@ class UserSettingsStore: ObservableObject { } } + @Published var hide_reactions: Bool { + didSet { + UserDefaults.standard.set(hide_reactions, forKey: "hide_reactions") + } + } + @Published var translation_service: TranslationService { didSet { UserDefaults.standard.set(translation_service.rawValue, forKey: "translation_service") @@ -296,6 +302,7 @@ class UserSettingsStore: ObservableObject { disable_animation = should_disable_image_animation() auto_translate = UserDefaults.standard.object(forKey: "auto_translate") as? Bool ?? true show_only_preferred_languages = UserDefaults.standard.object(forKey: "show_only_preferred_languages") as? Bool ?? false + hide_reactions = UserDefaults.standard.object(forKey: "hide_reactions") as? Bool ?? false // Note from @tyiu: // Default translation service is disabled by default for now until we gain some confidence that it is working well in production. diff --git a/damus/Models/ZapsModel.swift b/damus/Models/ZapsModel.swift @@ -22,7 +22,7 @@ class ZapsModel: ObservableObject { } func subscribe() { - var filter = NostrFilter.filter_kinds([9735]) + var filter = NostrFilter.filter_kinds([NostrKind.zap.rawValue]) switch target { case .profile(let profile_id): filter.pubkeys = [profile_id] diff --git a/damus/Nostr/NostrFilter.swift b/damus/Nostr/NostrFilter.swift @@ -41,7 +41,7 @@ struct NostrFilter: Codable, Equatable { } public static var filter_text: NostrFilter { - return filter_kinds([1]) + return filter_kinds([NostrKind.text.rawValue]) } public static func filter_ids(_ ids: [String]) -> NostrFilter { @@ -49,11 +49,11 @@ struct NostrFilter: Codable, Equatable { } public static var filter_profiles: NostrFilter { - return filter_kinds([0]) + return filter_kinds([NostrKind.metadata.rawValue]) } public static var filter_contacts: NostrFilter { - return filter_kinds([3]) + return filter_kinds([NostrKind.contacts.rawValue]) } public static func filter_authors(_ authors: [String]) -> NostrFilter { diff --git a/damus/Util/Notifications.swift b/damus/Util/Notifications.swift @@ -113,6 +113,9 @@ extension Notification.Name { static var local_notification: Notification.Name { return Notification.Name("local_notification") } + static var hide_reactions: Notification.Name { + return Notification.Name("hide_reactions") + } } func handle_notify(_ name: Notification.Name) -> NotificationCenter.Publisher { diff --git a/damus/Views/ActionBar/EventActionBar.swift b/damus/Views/ActionBar/EventActionBar.swift @@ -30,6 +30,7 @@ struct EventActionBar: View { @State var show_share_action: Bool = false @ObservedObject var bar: ActionBarModel + @ObservedObject var settings: UserSettingsStore @Environment(\.colorScheme) var colorScheme @@ -38,6 +39,7 @@ struct EventActionBar: View { self.event = event self.test_lnurl = test_lnurl _bar = ObservedObject(wrappedValue: bar ?? make_actionbar_model(ev: event.id, damus: damus_state)) + _settings = ObservedObject(wrappedValue: damus_state.settings) } var lnurl: String? { @@ -72,22 +74,25 @@ struct EventActionBar: View { .font(.footnote.weight(.medium)) .foregroundColor(bar.boosted ? Color.green : Color.gray) } - Spacer() - - HStack(spacing: 4) { - LikeButton(liked: bar.liked) { - if bar.liked { - notify(.delete, bar.our_like) - } else { - send_like() + + if !settings.hide_reactions { + Spacer() + + HStack(spacing: 4) { + LikeButton(liked: bar.liked) { + if bar.liked { + notify(.delete, bar.our_like) + } else { + send_like() + } } + + Text(verbatim: "\(bar.likes > 0 ? "\(bar.likes)" : "")") + .font(.footnote.weight(.medium)) + .nip05_colorized(gradient: bar.liked) } - - Text(verbatim: "\(bar.likes > 0 ? "\(bar.likes)" : "")") - .font(.footnote.weight(.medium)) - .nip05_colorized(gradient: bar.liked) } - + if let lnurl = self.lnurl { Spacer() ZapButton(damus_state: damus_state, event: event, lnurl: lnurl, bar: bar) diff --git a/damus/Views/ActionBar/EventDetailBar.swift b/damus/Views/ActionBar/EventDetailBar.swift @@ -32,7 +32,7 @@ struct EventDetailBar: View { .buttonStyle(PlainButtonStyle()) } - if bar.likes > 0 { + if bar.likes > 0 && !state.settings.hide_reactions { NavigationLink(destination: ReactionsView(damus_state: state, model: ReactionsModel(state: state, target: target))) { let noun = Text(verbatim: "\(reactionsCountString(bar.likes))").foregroundColor(.gray) Text("\(Text("\(bar.likes)").font(.body.bold())) \(noun)", comment: "Sentence composed of 2 variables to describe how many reactions there are on a post. In source English, the first variable is the number of reactions, and the second variable is 'Reaction' or 'Reactions'.") diff --git a/damus/Views/Settings/AppearanceSettingsView.swift b/damus/Views/Settings/AppearanceSettingsView.swift @@ -14,6 +14,14 @@ struct AppearanceSettingsView: View { var body: some View { Form { + Section(header: Text(NSLocalizedString("Reactions", comment: "Section header for reaction settings"))) { + Toggle(NSLocalizedString("Hide Reactions", comment: "Setting to hide reactions."), isOn: $settings.hide_reactions) + .toggleStyle(.switch) + .onChange(of: settings.hide_reactions) { newVal in + notify(.hide_reactions, newVal) + } + } + Section(header: Text(NSLocalizedString("Text Truncation", comment: "Section header for damus text truncation user configuration"))) { Toggle(NSLocalizedString("Truncate timeline text", comment: "Setting to truncate text in timeline"), isOn: $settings.truncate_timeline_text) .toggleStyle(.switch) diff --git a/damusTests/RequestTests.swift b/damusTests/RequestTests.swift @@ -30,7 +30,7 @@ final class RequestTests: XCTestCase { } func testMakeSubscriptionRequest() { - let filter = NostrFilter(kinds: [3], limit: 1, authors: ["d9fa34214aa9d151c4f4db843e9c2af4f246bab4205137731f91bcfa44d66a62"]) + let filter = NostrFilter(kinds: [NostrKind.contacts.rawValue], limit: 1, authors: ["d9fa34214aa9d151c4f4db843e9c2af4f246bab4205137731f91bcfa44d66a62"]) let subscribe = NostrSubscribe(filters: [filter], sub_id: "31C737B7-C8F9-41DD-8707-325974F279A4") let result = make_nostr_req(.subscribe(subscribe)) let expectedResult = "[\"REQ\",\"31C737B7-C8F9-41DD-8707-325974F279A4\",{\"kinds\":[3],\"authors\":[\"d9fa34214aa9d151c4f4db843e9c2af4f246bab4205137731f91bcfa44d66a62\"],\"limit\":1}]"