Refactor direct messages model
We can track the pubkey in the DirectMessageModel instead of having a janky tuple.
This commit is contained in:
@@ -183,7 +183,7 @@ struct ContentView: View {
|
|||||||
NotificationsView(state: damus, notifications: home.notifications)
|
NotificationsView(state: damus, notifications: home.notifications)
|
||||||
|
|
||||||
case .dms:
|
case .dms:
|
||||||
DirectMessagesView(damus_state: damus_state!)
|
DirectMessagesView(damus_state: damus_state!, model: damus_state!.dms)
|
||||||
|
|
||||||
case .none:
|
case .none:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ class DirectMessageModel: ObservableObject {
|
|||||||
|
|
||||||
@Published var draft: String
|
@Published var draft: String
|
||||||
|
|
||||||
|
let pubkey: String
|
||||||
|
|
||||||
var is_request: Bool
|
var is_request: Bool
|
||||||
var our_pubkey: String
|
var our_pubkey: String
|
||||||
|
|
||||||
@@ -29,17 +31,19 @@ class DirectMessageModel: ObservableObject {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
init(events: [NostrEvent], our_pubkey: String) {
|
init(events: [NostrEvent], our_pubkey: String, pubkey: String) {
|
||||||
self.events = events
|
self.events = events
|
||||||
self.is_request = false
|
self.is_request = false
|
||||||
self.our_pubkey = our_pubkey
|
self.our_pubkey = our_pubkey
|
||||||
self.draft = ""
|
self.draft = ""
|
||||||
|
self.pubkey = pubkey
|
||||||
}
|
}
|
||||||
|
|
||||||
init(our_pubkey: String) {
|
init(our_pubkey: String, pubkey: String) {
|
||||||
self.events = []
|
self.events = []
|
||||||
self.is_request = false
|
self.is_request = false
|
||||||
self.our_pubkey = our_pubkey
|
self.our_pubkey = our_pubkey
|
||||||
self.draft = ""
|
self.draft = ""
|
||||||
|
self.pubkey = pubkey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,20 +8,43 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class DirectMessagesModel: ObservableObject {
|
class DirectMessagesModel: ObservableObject {
|
||||||
@Published var dms: [(String, DirectMessageModel)] = []
|
@Published var dms: [DirectMessageModel] = []
|
||||||
@Published var loading: Bool = false
|
@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
|
let our_pubkey: String
|
||||||
|
|
||||||
init(our_pubkey: String) {
|
init(our_pubkey: String) {
|
||||||
self.our_pubkey = our_pubkey
|
self.our_pubkey = our_pubkey
|
||||||
}
|
}
|
||||||
|
|
||||||
var message_requests: [(String, DirectMessageModel)] {
|
var message_requests: [DirectMessageModel] {
|
||||||
return dms.filter { dm in dm.1.is_request }
|
return dms.filter { dm in dm.is_request }
|
||||||
}
|
}
|
||||||
|
|
||||||
var friend_dms: [(String, DirectMessageModel)] {
|
var friend_dms: [DirectMessageModel] {
|
||||||
return dms.filter { dm in !dm.1.is_request }
|
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 {
|
func lookup_or_create(_ pubkey: String) -> DirectMessageModel {
|
||||||
@@ -29,15 +52,15 @@ class DirectMessagesModel: ObservableObject {
|
|||||||
return dm
|
return dm
|
||||||
}
|
}
|
||||||
|
|
||||||
let new = DirectMessageModel(our_pubkey: our_pubkey)
|
let new = DirectMessageModel(our_pubkey: our_pubkey, pubkey: pubkey)
|
||||||
dms.append((pubkey, new))
|
dms.append(new)
|
||||||
return new
|
return new
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookup(_ pubkey: String) -> DirectMessageModel? {
|
func lookup(_ pubkey: String) -> DirectMessageModel? {
|
||||||
for dm in dms {
|
for dm in dms {
|
||||||
if pubkey == dm.0 {
|
if pubkey == dm.pubkey {
|
||||||
return dm.1
|
return dm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ class HomeModel: ObservableObject {
|
|||||||
|
|
||||||
func filter_muted() {
|
func filter_muted() {
|
||||||
events.filter { !damus_state.contacts.is_muted($0.pubkey) && !damus_state.muted_threads.isMutedThread($0, privkey: self.damus_state.keypair.privkey) }
|
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)
|
notifications.filter_and_build_notifications(damus_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +316,7 @@ class HomeModel: ObservableObject {
|
|||||||
case .eose(let sub_id):
|
case .eose(let sub_id):
|
||||||
|
|
||||||
if sub_id == dms_subid {
|
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)
|
dms.append(contentsOf: incoming_dms)
|
||||||
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, load: .from_events(dms), damus_state: damus_state)
|
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, load: .from_events(dms), damus_state: damus_state)
|
||||||
} else if sub_id == notifications_subid {
|
} 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 {
|
for model in dms.dms {
|
||||||
if pk == the_pk {
|
if model.pubkey == the_pk {
|
||||||
found = true
|
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
|
$0.created_at < $1.created_at
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -864,8 +864,8 @@ func handle_incoming_dm(ev: NostrEvent, our_pubkey: String, dms: DirectMessagesM
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
let model = DirectMessageModel(events: [ev], our_pubkey: our_pubkey)
|
let model = DirectMessageModel(events: [ev], our_pubkey: our_pubkey, pubkey: the_pk)
|
||||||
dms.dms.append((the_pk, model))
|
dms.dms.append(model)
|
||||||
inserted = true
|
inserted = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,8 +892,8 @@ func handle_incoming_dms(prev_events: NewEventsBits, dms: DirectMessagesModel, o
|
|||||||
}
|
}
|
||||||
|
|
||||||
if inserted {
|
if inserted {
|
||||||
dms.dms = dms.dms.filter({ $0.1.events.count > 0 }).sorted { a, b in
|
dms.dms = dms.dms.filter({ $0.events.count > 0 }).sorted { a, b in
|
||||||
return a.1.events.last!.created_at > b.1.events.last!.created_at
|
return a.events.last!.created_at > b.events.last!.created_at
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,13 @@ import SwiftUI
|
|||||||
|
|
||||||
struct DMChatView: View {
|
struct DMChatView: View {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
let pubkey: String
|
@ObservedObject var dms: DirectMessageModel
|
||||||
@EnvironmentObject var dms: DirectMessageModel
|
|
||||||
@State var showPrivateKeyWarning: Bool = false
|
@State var showPrivateKeyWarning: Bool = false
|
||||||
|
|
||||||
|
var pubkey: String {
|
||||||
|
dms.pubkey
|
||||||
|
}
|
||||||
|
|
||||||
var Messages: some View {
|
var Messages: some View {
|
||||||
ScrollViewReader { scroller in
|
ScrollViewReader { scroller in
|
||||||
ScrollView {
|
ScrollView {
|
||||||
@@ -177,10 +180,9 @@ struct DMChatView_Previews: PreviewProvider {
|
|||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let ev = NostrEvent(content: "hi", pubkey: "pubkey", kind: 1, tags: [])
|
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")
|
DMChatView(damus_state: test_damus_state(), dms: model)
|
||||||
.environmentObject(model)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,22 +16,12 @@ struct DirectMessagesView: View {
|
|||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
|
|
||||||
@State var dm_type: DMType = .friend
|
@State var dm_type: DMType = .friend
|
||||||
@State var open_dm: Bool = false
|
|
||||||
@State var pubkey: String
|
|
||||||
@ObservedObject var model: DirectMessagesModel
|
@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 {
|
func MainContent(requests: Bool) -> some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
let chat = DMChatView(damus_state: damus_state, pubkey: pubkey)
|
let chat = DMChatView(damus_state: damus_state, dms: model.active_model)
|
||||||
.environmentObject(active_model)
|
NavigationLink(destination: chat, isActive: $model.open_dm) {
|
||||||
NavigationLink(destination: chat, isActive: $open_dm) {
|
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
LazyVStack(spacing: 0) {
|
LazyVStack(spacing: 0) {
|
||||||
@@ -39,7 +29,7 @@ struct DirectMessagesView: View {
|
|||||||
EmptyTimelineView()
|
EmptyTimelineView()
|
||||||
} else {
|
} else {
|
||||||
let dms = requests ? model.message_requests : model.friend_dms
|
let dms = requests ? model.message_requests : model.friend_dms
|
||||||
ForEach(dms, id: \.0) { tup in
|
ForEach(dms, id: \.pubkey) { tup in
|
||||||
MaybeEvent(tup)
|
MaybeEvent(tup)
|
||||||
.padding(.top, 10)
|
.padding(.top, 10)
|
||||||
|
|
||||||
@@ -60,14 +50,12 @@ struct DirectMessagesView: View {
|
|||||||
return [.truncate_content, .no_action_bar, .no_translate]
|
return [.truncate_content, .no_action_bar, .no_translate]
|
||||||
}
|
}
|
||||||
|
|
||||||
func MaybeEvent(_ tup: (String, DirectMessageModel)) -> some View {
|
func MaybeEvent(_ model: DirectMessageModel) -> some View {
|
||||||
Group {
|
Group {
|
||||||
if let ev = tup.1.events.last {
|
if let ev = model.events.last {
|
||||||
EventView(damus: damus_state, event: ev, pubkey: tup.0, options: options)
|
EventView(damus: damus_state, event: ev, pubkey: model.pubkey, options: options)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
pubkey = tup.0
|
self.model.open_dm_by_model(model)
|
||||||
active_model = tup.1
|
|
||||||
open_dm = true
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
EmptyView()
|
EmptyView()
|
||||||
@@ -107,6 +95,6 @@ struct DirectMessagesView_Previews: PreviewProvider {
|
|||||||
kind: 4,
|
kind: 4,
|
||||||
tags: [])
|
tags: [])
|
||||||
let ds = test_damus_state()
|
let ds = test_damus_state()
|
||||||
DirectMessagesView(damus_state: ds)
|
DirectMessagesView(damus_state: ds, model: ds.dms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -271,8 +271,7 @@ struct ProfileView: View {
|
|||||||
|
|
||||||
var dmButton: some View {
|
var dmButton: some View {
|
||||||
let dm_model = damus_state.dms.lookup_or_create(profile.pubkey)
|
let dm_model = damus_state.dms.lookup_or_create(profile.pubkey)
|
||||||
let dmview = DMChatView(damus_state: damus_state, pubkey: profile.pubkey)
|
let dmview = DMChatView(damus_state: damus_state, dms: dm_model)
|
||||||
.environmentObject(dm_model)
|
|
||||||
return NavigationLink(destination: dmview) {
|
return NavigationLink(destination: dmview) {
|
||||||
Image(systemName: "bubble.left.circle")
|
Image(systemName: "bubble.left.circle")
|
||||||
.profile_button_style(scheme: colorScheme)
|
.profile_button_style(scheme: colorScheme)
|
||||||
|
|||||||
@@ -51,55 +51,55 @@ final class DMTests: XCTestCase {
|
|||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob])
|
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 1)
|
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)!
|
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])
|
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 1)
|
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)!
|
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])
|
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.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)!
|
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])
|
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [fiatjaf_to_alice])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 2)
|
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)!
|
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])
|
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [dave_to_alice])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 3)
|
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)!
|
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])
|
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.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)!
|
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])
|
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 4)
|
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)!
|
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])
|
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.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)!
|
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])
|
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.count, 4)
|
||||||
XCTAssertEqual(model.dms[0].0, charlie.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user