commit b5a3697d78df9fdf9116f6dc22582ab725aeb8ea
parent 247270f3d3efdd3eb4f17da56dcfae60d9b68a93
Author: William Casarin <jb55@jb55.com>
Date: Sat, 15 Apr 2023 12:41:00 -0700
Refactor direct messages model
We can track the pubkey in the DirectMessageModel instead of having a
janky tuple.
Diffstat:
8 files changed, 74 insertions(+), 58 deletions(-)
diff --git a/damus/ContentView.swift b/damus/ContentView.swift
@@ -183,7 +183,7 @@ struct ContentView: View {
NotificationsView(state: damus, notifications: home.notifications)
case .dms:
- DirectMessagesView(damus_state: damus_state!)
+ DirectMessagesView(damus_state: damus_state!, model: damus_state!.dms)
case .none:
EmptyView()
diff --git a/damus/Models/DirectMessageModel.swift b/damus/Models/DirectMessageModel.swift
@@ -16,6 +16,8 @@ class DirectMessageModel: ObservableObject {
@Published var draft: String
+ let pubkey: String
+
var is_request: Bool
var our_pubkey: String
@@ -29,17 +31,19 @@ class DirectMessageModel: ObservableObject {
return true
}
- init(events: [NostrEvent], our_pubkey: String) {
+ init(events: [NostrEvent], our_pubkey: String, pubkey: String) {
self.events = events
self.is_request = false
self.our_pubkey = our_pubkey
self.draft = ""
+ self.pubkey = pubkey
}
- init(our_pubkey: String) {
+ init(our_pubkey: String, pubkey: String) {
self.events = []
self.is_request = false
self.our_pubkey = our_pubkey
self.draft = ""
+ self.pubkey = pubkey
}
}
diff --git a/damus/Models/DirectMessagesModel.swift b/damus/Models/DirectMessagesModel.swift
@@ -8,20 +8,43 @@
import Foundation
class DirectMessagesModel: ObservableObject {
- @Published var dms: [(String, DirectMessageModel)] = []
+ @Published var dms: [DirectMessageModel] = []
@Published var loading: Bool = false
+ @Published var open_dm: Bool = false
+ @Published private(set) var active_model: DirectMessageModel = DirectMessageModel(our_pubkey: "", pubkey: "")
let our_pubkey: String
init(our_pubkey: String) {
self.our_pubkey = our_pubkey
}
- var message_requests: [(String, DirectMessageModel)] {
- return dms.filter { dm in dm.1.is_request }
+ var message_requests: [DirectMessageModel] {
+ return dms.filter { dm in dm.is_request }
}
- var friend_dms: [(String, DirectMessageModel)] {
- return dms.filter { dm in !dm.1.is_request }
+ var friend_dms: [DirectMessageModel] {
+ return dms.filter { dm in !dm.is_request }
+ }
+
+ func set_active_dm_model(_ model: DirectMessageModel) {
+ self.active_model = model
+ }
+
+ func open_dm_by_pk(_ pubkey: String) {
+ self.set_active_dm(pubkey)
+ self.open_dm = true
+ }
+
+ func open_dm_by_model(_ model: DirectMessageModel) {
+ self.set_active_dm_model(model)
+ self.open_dm = true
+ }
+
+ func set_active_dm(_ pubkey: String) {
+ for model in self.dms where model.pubkey == pubkey {
+ self.set_active_dm_model(model)
+ break
+ }
}
func lookup_or_create(_ pubkey: String) -> DirectMessageModel {
@@ -29,15 +52,15 @@ class DirectMessagesModel: ObservableObject {
return dm
}
- let new = DirectMessageModel(our_pubkey: our_pubkey)
- dms.append((pubkey, new))
+ let new = DirectMessageModel(our_pubkey: our_pubkey, pubkey: pubkey)
+ dms.append(new)
return new
}
func lookup(_ pubkey: String) -> DirectMessageModel? {
for dm in dms {
- if pubkey == dm.0 {
- return dm.1
+ if pubkey == dm.pubkey {
+ return dm
}
}
diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift
@@ -198,7 +198,7 @@ class HomeModel: ObservableObject {
func filter_muted() {
events.filter { !damus_state.contacts.is_muted($0.pubkey) && !damus_state.muted_threads.isMutedThread($0, privkey: self.damus_state.keypair.privkey) }
- self.dms.dms = dms.dms.filter { !damus_state.contacts.is_muted($0.0) }
+ self.dms.dms = dms.dms.filter { !damus_state.contacts.is_muted($0.pubkey) }
notifications.filter_and_build_notifications(damus_state)
}
@@ -316,7 +316,7 @@ class HomeModel: ObservableObject {
case .eose(let sub_id):
if sub_id == dms_subid {
- var dms = dms.dms.flatMap { $0.1.events }
+ var dms = dms.dms.flatMap { $0.events }
dms.append(contentsOf: incoming_dms)
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, load: .from_events(dms), damus_state: damus_state)
} else if sub_id == notifications_subid {
@@ -851,10 +851,10 @@ func handle_incoming_dm(ev: NostrEvent, our_pubkey: String, dms: DirectMessagesM
}
}
- for (pk, _) in dms.dms {
- if pk == the_pk {
+ for model in dms.dms {
+ if model.pubkey == the_pk {
found = true
- inserted = insert_uniq_sorted_event(events: &(dms.dms[i].1.events), new_ev: ev) {
+ inserted = insert_uniq_sorted_event(events: &(dms.dms[i].events), new_ev: ev) {
$0.created_at < $1.created_at
}
@@ -864,8 +864,8 @@ func handle_incoming_dm(ev: NostrEvent, our_pubkey: String, dms: DirectMessagesM
}
if !found {
- let model = DirectMessageModel(events: [ev], our_pubkey: our_pubkey)
- dms.dms.append((the_pk, model))
+ let model = DirectMessageModel(events: [ev], our_pubkey: our_pubkey, pubkey: the_pk)
+ dms.dms.append(model)
inserted = true
}
@@ -892,8 +892,8 @@ func handle_incoming_dms(prev_events: NewEventsBits, dms: DirectMessagesModel, o
}
if inserted {
- dms.dms = dms.dms.filter({ $0.1.events.count > 0 }).sorted { a, b in
- return a.1.events.last!.created_at > b.1.events.last!.created_at
+ dms.dms = dms.dms.filter({ $0.events.count > 0 }).sorted { a, b in
+ return a.events.last!.created_at > b.events.last!.created_at
}
}
diff --git a/damus/Views/DMChatView.swift b/damus/Views/DMChatView.swift
@@ -9,10 +9,13 @@ import SwiftUI
struct DMChatView: View {
let damus_state: DamusState
- let pubkey: String
- @EnvironmentObject var dms: DirectMessageModel
+ @ObservedObject var dms: DirectMessageModel
@State var showPrivateKeyWarning: Bool = false
-
+
+ var pubkey: String {
+ dms.pubkey
+ }
+
var Messages: some View {
ScrollViewReader { scroller in
ScrollView {
@@ -177,10 +180,9 @@ struct DMChatView_Previews: PreviewProvider {
static var previews: some View {
let ev = NostrEvent(content: "hi", pubkey: "pubkey", kind: 1, tags: [])
- let model = DirectMessageModel(events: [ev], our_pubkey: "pubkey")
+ let model = DirectMessageModel(events: [ev], our_pubkey: "pubkey", pubkey: "the_pk")
- DMChatView(damus_state: test_damus_state(), pubkey: "pubkey")
- .environmentObject(model)
+ DMChatView(damus_state: test_damus_state(), dms: model)
}
}
diff --git a/damus/Views/DirectMessagesView.swift b/damus/Views/DirectMessagesView.swift
@@ -16,22 +16,12 @@ struct DirectMessagesView: View {
let damus_state: DamusState
@State var dm_type: DMType = .friend
- @State var open_dm: Bool = false
- @State var pubkey: String
@ObservedObject var model: DirectMessagesModel
- @State var active_model: DirectMessageModel = DirectMessageModel(our_pubkey: "")
-
- init(damus_state: DamusState) {
- self.damus_state = damus_state
- self._model = ObservedObject(initialValue: damus_state.dms)
- self.pubkey = damus_state.pubkey
- }
func MainContent(requests: Bool) -> some View {
ScrollView {
- let chat = DMChatView(damus_state: damus_state, pubkey: pubkey)
- .environmentObject(active_model)
- NavigationLink(destination: chat, isActive: $open_dm) {
+ let chat = DMChatView(damus_state: damus_state, dms: model.active_model)
+ NavigationLink(destination: chat, isActive: $model.open_dm) {
EmptyView()
}
LazyVStack(spacing: 0) {
@@ -39,7 +29,7 @@ struct DirectMessagesView: View {
EmptyTimelineView()
} else {
let dms = requests ? model.message_requests : model.friend_dms
- ForEach(dms, id: \.0) { tup in
+ ForEach(dms, id: \.pubkey) { tup in
MaybeEvent(tup)
.padding(.top, 10)
@@ -60,14 +50,12 @@ struct DirectMessagesView: View {
return [.truncate_content, .no_action_bar, .no_translate]
}
- func MaybeEvent(_ tup: (String, DirectMessageModel)) -> some View {
+ func MaybeEvent(_ model: DirectMessageModel) -> some View {
Group {
- if let ev = tup.1.events.last {
- EventView(damus: damus_state, event: ev, pubkey: tup.0, options: options)
+ if let ev = model.events.last {
+ EventView(damus: damus_state, event: ev, pubkey: model.pubkey, options: options)
.onTapGesture {
- pubkey = tup.0
- active_model = tup.1
- open_dm = true
+ self.model.open_dm_by_model(model)
}
} else {
EmptyView()
@@ -107,6 +95,6 @@ struct DirectMessagesView_Previews: PreviewProvider {
kind: 4,
tags: [])
let ds = test_damus_state()
- DirectMessagesView(damus_state: ds)
+ DirectMessagesView(damus_state: ds, model: ds.dms)
}
}
diff --git a/damus/Views/Profile/ProfileView.swift b/damus/Views/Profile/ProfileView.swift
@@ -271,8 +271,7 @@ struct ProfileView: View {
var dmButton: some View {
let dm_model = damus_state.dms.lookup_or_create(profile.pubkey)
- let dmview = DMChatView(damus_state: damus_state, pubkey: profile.pubkey)
- .environmentObject(dm_model)
+ let dmview = DMChatView(damus_state: damus_state, dms: dm_model)
return NavigationLink(destination: dmview) {
Image(systemName: "bubble.left.circle")
.profile_button_style(scheme: colorScheme)
diff --git a/damusTests/DMTests.swift b/damusTests/DMTests.swift
@@ -51,55 +51,55 @@ final class DMTests: XCTestCase {
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob])
XCTAssertEqual(model.dms.count, 1)
- XCTAssertEqual(model.dms[0].0, bob.pubkey)
+ XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let bob_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 1)!
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice])
XCTAssertEqual(model.dms.count, 1)
- XCTAssertEqual(model.dms[0].0, bob.pubkey)
+ XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let alice_to_bob_2 = create_dm("hi bob", to_pk: bob.pubkey, tags: [["p", bob.pubkey]], keypair: alice, created_at: now + 2)!
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob_2])
XCTAssertEqual(model.dms.count, 1)
- XCTAssertEqual(model.dms[0].0, bob.pubkey)
+ XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let fiatjaf_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: fiatjaf, created_at: now+5)!
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [fiatjaf_to_alice])
XCTAssertEqual(model.dms.count, 2)
- XCTAssertEqual(model.dms[0].0, fiatjaf.pubkey)
+ XCTAssertEqual(model.dms[0].pubkey, fiatjaf.pubkey)
let dave_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: dave, created_at: now + 10)!
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [dave_to_alice])
XCTAssertEqual(model.dms.count, 3)
- XCTAssertEqual(model.dms[0].0, dave.pubkey)
+ XCTAssertEqual(model.dms[0].pubkey, dave.pubkey)
let bob_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 15)!
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_2])
XCTAssertEqual(model.dms.count, 3)
- XCTAssertEqual(model.dms[0].0, bob.pubkey)
+ XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let charlie_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: charlie, created_at: now + 20)!
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice])
XCTAssertEqual(model.dms.count, 4)
- XCTAssertEqual(model.dms[0].0, charlie.pubkey)
+ XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)
let bob_to_alice_3 = create_dm("hi alice 3", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 25)!
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_3])
XCTAssertEqual(model.dms.count, 4)
- XCTAssertEqual(model.dms[0].0, bob.pubkey)
+ XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
let charlie_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: charlie, created_at: now + 30)!
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice_2])
XCTAssertEqual(model.dms.count, 4)
- XCTAssertEqual(model.dms[0].0, charlie.pubkey)
+ XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)
}
}