Merge improved mute functionality from Charlie

This merge adds a bunch of new features from charlie's work on the new
mutelist changes:

- Muted words

- Mute performance optimizations

- New mute list UI

I needed to make a few changes to fix the tests in this merge. Otherwise
it seems to work ok!

Thank to Charlie for getting all of this working after many rounds of
review!

* branch `mute` of https://github.com/damus-io/damus:
  mute: fix bug with duplicate Indefinite items in MuteDurationMenu
  mute: fix mute hashtag from search view if no existing mutelist
  mute: integrate new MutelistManager
  mute: adding MutelistManager.swift
  mute: add maybe_get_content function to NdbNote
  mute: fix bug where mutes can't be added without existing mutelist
  mute: fix issue with not being able to change mute duration
  mute: don't mutate string when adding hashtag
  mute: implement fast MuteItem decoder
  tags: add u64 decoding function
  mute: migrating muted_threads to new mute list
  mute: adding ability to mute hashtag from SearchView
  mute: updating UI to support new mute list
  mute: adding filtering support for MuteItem events
  mute: receiving New Mute List Type
  mute: migrate Lists.swift to use new MuteItem
  mute: add new UI views for new mute list
  mute: adding new structs/enums for new mute list

Changelog-Added: Add ability to mute words, add new mutelist interface (Charlie)
This commit is contained in:
William Casarin
2024-02-26 11:31:56 -08:00
44 changed files with 1076 additions and 333 deletions

View File

@@ -73,7 +73,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
@@ -384,8 +384,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
@@ -563,7 +563,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)
@@ -581,13 +581,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: .pubkey(pubkey))
let muting,
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: muting)
else {
return
}
damus_state?.contacts.set_mutelist(mutelist)
ds.mutelist_manager.set_mutelist(mutelist)
ds.postbox.send(mutelist)
confirm_overwrite_mutelist = false
@@ -606,25 +606,25 @@ struct ContentView: View {
return
}
if ds.contacts.mutelist == nil {
if ds.mutelist_manager.event == nil {
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: .pubkey(pubkey)) else {
guard let ev = create_or_update_mutelist(keypair: keypair, mprev: ds.mutelist_manager.event, to_add: muting) else {
return
}
damus_state?.contacts.set_mutelist(ev)
ds.mutelist_manager.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)
@@ -697,6 +697,7 @@ struct ContentView: View {
likes: EventCounter(our_pubkey: pubkey),
boosts: EventCounter(our_pubkey: pubkey),
contacts: Contacts(our_pubkey: pubkey),
mutelist_manager: MutelistManager(),
profiles: Profiles(ndb: ndb),
dms: home.dms,
previews: PreviewCache(),
@@ -711,7 +712,6 @@ struct ContentView: View {
postbox: PostBox(pool: pool),
bootstrap_relays: bootstrap_relays,
replies: ReplyCounter(our_pubkey: pubkey),
muted_threads: MutedThreadsManager(keypair: keypair),
wallet: WalletModel(settings: settings),
nav: self.navigationCoordinator,
music: MusicController(onChange: music_changed),
@@ -1153,7 +1153,7 @@ func on_open_url(state: DamusState, url: URL, result: @escaping (OpenResult?) ->
result(.event(ev))
}
case .hashtag(let ht):
result(.filter(.filter_hashtag([ht.string()])))
result(.filter(.filter_hashtag([ht.hashtag])))
case .param, .quote:
// doesn't really make sense here
break