Add DM button to profile
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
@@ -123,7 +123,8 @@ struct ContentView: View {
|
||||
.navigationTitle("Notifications")
|
||||
|
||||
case .dms:
|
||||
DirectMessagesView(damus_state: damus_state!, dms: $home.dms)
|
||||
DirectMessagesView(damus_state: damus_state!)
|
||||
.environmentObject(home.dms)
|
||||
|
||||
case .none:
|
||||
EmptyView()
|
||||
@@ -345,7 +346,8 @@ struct ContentView: View {
|
||||
contacts: Contacts(),
|
||||
tips: TipCounter(our_pubkey: pubkey),
|
||||
image_cache: ImageCache(),
|
||||
profiles: Profiles()
|
||||
profiles: Profiles(),
|
||||
dms: home.dms
|
||||
)
|
||||
home.damus_state = self.damus_state!
|
||||
|
||||
|
||||
@@ -16,12 +16,13 @@ struct DamusState {
|
||||
let tips: TipCounter
|
||||
let image_cache: ImageCache
|
||||
let profiles: Profiles
|
||||
let dms: DirectMessagesModel
|
||||
|
||||
var pubkey: String {
|
||||
return keypair.pubkey
|
||||
}
|
||||
|
||||
static var empty: DamusState {
|
||||
return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(), tips: TipCounter(our_pubkey: ""), image_cache: ImageCache(), profiles: Profiles())
|
||||
return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(), tips: TipCounter(our_pubkey: ""), image_cache: ImageCache(), profiles: Profiles(), dms: DirectMessagesModel())
|
||||
}
|
||||
}
|
||||
|
||||
20
damus/Models/DirectMessageModel.swift
Normal file
20
damus/Models/DirectMessageModel.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// DirectMessageModel.swift
|
||||
// damus
|
||||
//
|
||||
// Created by William Casarin on 2022-07-03.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class DirectMessageModel: ObservableObject {
|
||||
@Published var events: [NostrEvent]
|
||||
|
||||
init(events: [NostrEvent]) {
|
||||
self.events = events
|
||||
}
|
||||
|
||||
init() {
|
||||
self.events = []
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,26 @@
|
||||
import Foundation
|
||||
|
||||
class DirectMessagesModel: ObservableObject {
|
||||
@Published var events: [(String, [NostrEvent])] = []
|
||||
@Published var dms: [(String, DirectMessageModel)] = []
|
||||
@Published var loading: Bool = false
|
||||
|
||||
func lookup_or_create(_ pubkey: String) -> DirectMessageModel {
|
||||
if let dm = lookup(pubkey) {
|
||||
return dm
|
||||
}
|
||||
|
||||
let new = DirectMessageModel()
|
||||
dms.append((pubkey, new))
|
||||
return new
|
||||
}
|
||||
|
||||
func lookup(_ pubkey: String) -> DirectMessageModel? {
|
||||
for dm in dms {
|
||||
if pubkey == dm.0 {
|
||||
return dm.1
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class HomeModel: ObservableObject {
|
||||
|
||||
@Published var new_events: NewEventsBits = NewEventsBits()
|
||||
@Published var notifications: [NostrEvent] = []
|
||||
@Published var dms: [(String, [NostrEvent])] = []
|
||||
@Published var dms: DirectMessagesModel = DirectMessagesModel()
|
||||
@Published var events: [NostrEvent] = []
|
||||
@Published var loading: Bool = false
|
||||
@Published var signal: SignalModel = SignalModel()
|
||||
@@ -372,10 +372,10 @@ class HomeModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
for (pk, _) in dms {
|
||||
for (pk, _) in dms.dms {
|
||||
if pk == the_pk {
|
||||
found = true
|
||||
inserted = insert_uniq_sorted_event(events: &(dms[i].1), new_ev: ev) {
|
||||
inserted = insert_uniq_sorted_event(events: &(dms.dms[i].1.events), new_ev: ev) {
|
||||
$0.created_at < $1.created_at
|
||||
}
|
||||
|
||||
@@ -386,14 +386,18 @@ class HomeModel: ObservableObject {
|
||||
|
||||
if !found {
|
||||
inserted = true
|
||||
dms.append((the_pk, [ev]))
|
||||
let model = DirectMessageModel(events: [ev])
|
||||
dms.dms.append((the_pk, model))
|
||||
}
|
||||
|
||||
if inserted {
|
||||
handle_last_event(ev: ev, timeline: .dms)
|
||||
|
||||
dms = dms.sorted { a, b in
|
||||
a.1.last!.created_at > b.1.last!.created_at
|
||||
dms.dms = dms.dms.sorted { a, b in
|
||||
if a.1.events.count > 0 && b.1.events.count > 0 {
|
||||
return a.1.events.last!.created_at > b.1.events.last!.created_at
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,15 +10,15 @@ import SwiftUI
|
||||
struct DMChatView: View {
|
||||
let damus_state: DamusState
|
||||
let pubkey: String
|
||||
@Binding var events: [NostrEvent]
|
||||
@EnvironmentObject var dms: DirectMessageModel
|
||||
@State var message: String = ""
|
||||
|
||||
var Messages: some View {
|
||||
ScrollViewReader { scroller in
|
||||
ScrollView {
|
||||
VStack(alignment: .leading) {
|
||||
ForEach(Array(zip(events, events.indices)), id: \.0.id) { (ev, ind) in
|
||||
DMView(event: events[ind], damus_state: damus_state)
|
||||
ForEach(Array(zip(dms.events, dms.events.indices)), id: \.0.id) { (ev, ind) in
|
||||
DMView(event: dms.events[ind], damus_state: damus_state)
|
||||
.event_context_menu(ev)
|
||||
}
|
||||
Color.white.opacity(0)
|
||||
@@ -125,11 +125,11 @@ struct DMChatView: View {
|
||||
struct DMChatView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let ev = NostrEvent(content: "hi", pubkey: "pubkey", kind: 1, tags: [])
|
||||
let evs = Binding<[NostrEvent]>.init(
|
||||
get: { [ev] },
|
||||
set: { _ in })
|
||||
|
||||
DMChatView(damus_state: test_damus_state(), pubkey: "pubkey", events: evs)
|
||||
let model = DirectMessageModel(events: [ev])
|
||||
|
||||
DMChatView(damus_state: test_damus_state(), pubkey: "pubkey")
|
||||
.environmentObject(model)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,26 +9,33 @@ import SwiftUI
|
||||
|
||||
struct DirectMessagesView: View {
|
||||
let damus_state: DamusState
|
||||
@Binding var dms: [(String, [NostrEvent])]
|
||||
@EnvironmentObject var model: DirectMessagesModel
|
||||
|
||||
var MainContent: some View {
|
||||
ScrollView {
|
||||
VStack {
|
||||
ForEach(dms, id: \.0) { tup in
|
||||
let evs = Binding<[NostrEvent]>.init(
|
||||
get: { tup.1 },
|
||||
set: { _ in }
|
||||
)
|
||||
let chat = DMChatView(damus_state: damus_state, pubkey: tup.0, events: evs)
|
||||
NavigationLink(destination: chat) {
|
||||
EventView(damus: damus_state, event: tup.1.last!, pubkey: tup.0)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
ForEach(model.dms, id: \.0) { tup in
|
||||
MaybeEvent(tup)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func MaybeEvent(_ tup: (String, DirectMessageModel)) -> some View {
|
||||
Group {
|
||||
if let ev = tup.1.events.last {
|
||||
let chat = DMChatView(damus_state: damus_state, pubkey: tup.0)
|
||||
.environmentObject(tup.1)
|
||||
NavigationLink(destination: chat) {
|
||||
EventView(damus: damus_state, event: ev, pubkey: tup.0)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
MainContent
|
||||
.navigationTitle("Encrypted DMs")
|
||||
@@ -41,12 +48,8 @@ struct DirectMessagesView_Previews: PreviewProvider {
|
||||
pubkey: "pubkey",
|
||||
kind: 4,
|
||||
tags: [])
|
||||
let dms = Binding<[(String, [NostrEvent])]>.init(
|
||||
get: {
|
||||
return [ ("pubkey", [ ev ]) ]
|
||||
},
|
||||
set: { _ in }
|
||||
)
|
||||
DirectMessagesView(damus_state: test_damus_state(), dms: dms)
|
||||
let model = DirectMessageModel(events: [ev])
|
||||
DirectMessagesView(damus_state: test_damus_state())
|
||||
.environmentObject(model)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ struct NoteContentView: View {
|
||||
let md_opts: AttributedString.MarkdownParsingOptions =
|
||||
.init(interpretedSyntax: .inlineOnlyPreservingWhitespace)
|
||||
|
||||
guard var txt = try? AttributedString(markdown: content, options: md_opts) else {
|
||||
guard let txt = try? AttributedString(markdown: content, options: md_opts) else {
|
||||
return Text(content)
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,16 @@ struct ProfileView: View {
|
||||
|
||||
//@EnvironmentObject var profile: ProfileModel
|
||||
|
||||
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)
|
||||
return NavigationLink(destination: dmview) {
|
||||
Label("", systemImage: "text.bubble")
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
|
||||
var TopSection: some View {
|
||||
VStack(alignment: .leading) {
|
||||
let data = damus_state.profiles.lookup(id: profile.pubkey)
|
||||
@@ -86,6 +96,9 @@ struct ProfileView: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
DMButton
|
||||
.padding([.trailing], 20)
|
||||
|
||||
FollowButtonView(target: profile.get_follow_target(), follow_state: damus_state.contacts.follow_state(profile.pubkey))
|
||||
}
|
||||
|
||||
@@ -162,7 +175,7 @@ struct ProfileView_Previews: PreviewProvider {
|
||||
|
||||
func test_damus_state() -> DamusState {
|
||||
let pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"
|
||||
let damus = DamusState(pool: RelayPool(), keypair: Keypair(pubkey: pubkey, privkey: "privkey"), likes: EventCounter(our_pubkey: pubkey), boosts: EventCounter(our_pubkey: pubkey), contacts: Contacts(), tips: TipCounter(our_pubkey: pubkey), image_cache: ImageCache(), profiles: Profiles())
|
||||
let damus = DamusState(pool: RelayPool(), keypair: Keypair(pubkey: pubkey, privkey: "privkey"), likes: EventCounter(our_pubkey: pubkey), boosts: EventCounter(our_pubkey: pubkey), contacts: Contacts(), tips: TipCounter(our_pubkey: pubkey), image_cache: ImageCache(), profiles: Profiles(), dms: DirectMessagesModel())
|
||||
|
||||
let prof = Profile(name: "damus", display_name: "Damus", about: "iOS app!", picture: "https://damus.io/img/logo.png")
|
||||
let tsprof = TimestampedProfile(profile: prof, timestamp: 0)
|
||||
|
||||
Reference in New Issue
Block a user