Cached relay metadata

This commit is contained in:
William Casarin
2023-02-09 15:56:26 -08:00
parent 10596ddb09
commit fe444228e6
12 changed files with 127 additions and 73 deletions

View File

@@ -287,14 +287,17 @@ struct ContentView: View {
}
}
Button(action: {
//isFilterVisible.toggle()
self.active_sheet = .filter
}) {
// checklist, checklist.checked, lisdt.bullet, list.bullet.circle, line.3.horizontal.decrease..., line.3.horizontail.decrease
Label("Filter", systemImage: "line.3.horizontal.decrease")
.foregroundColor(.gray)
//.contentShape(Rectangle())
// maybe expand this to other timelines in the future
if selected_timeline == .search {
Button(action: {
//isFilterVisible.toggle()
self.active_sheet = .filter
}) {
// checklist, checklist.checked, lisdt.bullet, list.bullet.circle, line.3.horizontal.decrease..., line.3.horizontail.decrease
Label("Filter", systemImage: "line.3.horizontal.decrease")
.foregroundColor(.gray)
//.contentShape(Rectangle())
}
}
}
}
@@ -585,8 +588,12 @@ struct ContentView: View {
func connect() {
let pool = RelayPool()
let metadatas = RelayMetadatas()
for relay in BOOTSTRAP_RELAYS {
if let url = URL(string: relay) {
add_new_relay(url: url, info: .rw, metadatas: metadatas, pool: pool)
}
add_relay(pool, relay)
}
@@ -603,7 +610,8 @@ struct ContentView: View {
zaps: Zaps(our_pubkey: pubkey),
lnurls: LNUrls(),
settings: UserSettingsStore(),
relay_filters: RelayFilters(our_pubkey: pubkey)
relay_filters: RelayFilters(our_pubkey: pubkey),
relay_metadata: metadatas
)
home.damus_state = self.damus_state!

View File

@@ -22,6 +22,7 @@ struct DamusState {
let lnurls: LNUrls
let settings: UserSettingsStore
let relay_filters: RelayFilters
let relay_metadata: RelayMetadatas
var pubkey: String {
return keypair.pubkey
@@ -33,6 +34,6 @@ struct DamusState {
static var empty: DamusState {
return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(our_pubkey: ""), tips: TipCounter(our_pubkey: ""), profiles: Profiles(), dms: DirectMessagesModel(our_pubkey: ""), previews: PreviewCache(), zaps: Zaps(our_pubkey: ""), lnurls: LNUrls(), settings: UserSettingsStore(), relay_filters: RelayFilters(our_pubkey: ""))
return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(our_pubkey: ""), tips: TipCounter(our_pubkey: ""), profiles: Profiles(), dms: DirectMessagesModel(our_pubkey: ""), previews: PreviewCache(), zaps: Zaps(our_pubkey: ""), lnurls: LNUrls(), settings: UserSettingsStore(), relay_filters: RelayFilters(our_pubkey: ""), relay_metadata: RelayMetadatas())
}
}

View File

@@ -51,11 +51,7 @@ class FollowersModel: ObservableObject {
if has_contact.contains(ev.pubkey) {
return
}
process_contact_event(
pool: damus_state.pool,
contacts: damus_state.contacts,
pubkey: damus_state.pubkey, ev: ev
)
process_contact_event(state: damus_state, ev: ev)
contacts?.append(ev.pubkey)
has_contact.insert(ev.pubkey)
}

View File

@@ -193,7 +193,7 @@ class HomeModel: ObservableObject {
}
func handle_contact_event(sub_id: String, relay_id: String, ev: NostrEvent) {
process_contact_event(pool: damus_state.pool, contacts: damus_state.contacts, pubkey: damus_state.pubkey, ev: ev)
process_contact_event(state: self.damus_state, ev: ev)
if sub_id == init_subid {
pool.send(.unsubscribe(init_subid), to: [relay_id])
@@ -643,31 +643,31 @@ func robohash(_ pk: String) -> String {
return "https://robohash.org/" + pk
}
func load_our_stuff(pool: RelayPool, contacts: Contacts, pubkey: String, ev: NostrEvent) {
guard ev.pubkey == pubkey else {
func load_our_stuff(state: DamusState, ev: NostrEvent) {
guard ev.pubkey == state.pubkey else {
return
}
// only use new stuff
if let current_ev = contacts.event {
if let current_ev = state.contacts.event {
guard ev.created_at > current_ev.created_at else {
return
}
}
let m_old_ev = contacts.event
contacts.event = ev
let m_old_ev = state.contacts.event
state.contacts.event = ev
load_our_contacts(contacts: contacts, our_pubkey: pubkey, m_old_ev: m_old_ev, ev: ev)
load_our_relays(contacts: contacts, our_pubkey: pubkey, pool: pool, m_old_ev: m_old_ev, ev: ev)
load_our_contacts(contacts: state.contacts, our_pubkey: state.pubkey, m_old_ev: m_old_ev, ev: ev)
load_our_relays(state: state, m_old_ev: m_old_ev, ev: ev)
}
func process_contact_event(pool: RelayPool, contacts: Contacts, pubkey: String, ev: NostrEvent) {
load_our_stuff(pool: pool, contacts: contacts, pubkey: pubkey, ev: ev)
add_contact_if_friend(contacts: contacts, ev: ev)
func process_contact_event(state: DamusState, ev: NostrEvent) {
load_our_stuff(state: state, ev: ev)
add_contact_if_friend(contacts: state.contacts, ev: ev)
}
func load_our_relays(contacts: Contacts, our_pubkey: String, pool: RelayPool, m_old_ev: NostrEvent?, ev: NostrEvent) {
func load_our_relays(state: DamusState, m_old_ev: NostrEvent?, ev: NostrEvent) {
let bootstrap_dict: [String: RelayInfo] = [:]
let old_decoded = m_old_ev.flatMap { decode_json_relays($0.content) } ?? BOOTSTRAP_RELAYS.reduce(into: bootstrap_dict) { (d, r) in
d[r] = .rw
@@ -695,10 +695,10 @@ func load_our_relays(contacts: Contacts, our_pubkey: String, pool: RelayPool, m_
changed = true
if new.contains(d) {
if let url = URL(string: d) {
try? pool.add_relay(url, info: decoded[d] ?? .rw)
add_new_relay(url: url, info: decoded[d] ?? .rw, metadatas: state.relay_metadata, pool: state.pool)
}
} else {
pool.remove_relay(d)
state.pool.remove_relay(d)
}
}
@@ -707,6 +707,51 @@ func load_our_relays(contacts: Contacts, our_pubkey: String, pool: RelayPool, m_
}
}
func add_new_relay(url: URL, info: RelayInfo, metadatas: RelayMetadatas, pool: RelayPool) {
try? pool.add_relay(url, info: info)
let relay_id = url.absoluteString
guard metadatas.lookup(relay_id: relay_id) == nil else {
return
}
Task.detached(priority: .background) {
guard let meta = try? await fetch_relay_metadata(relay_id: relay_id) else {
return
}
DispatchQueue.main.async {
metadatas.insert(relay_id: relay_id, metadata: meta)
}
}
}
func fetch_relay_metadata(relay_id: String) async throws -> RelayMetadata? {
var urlString = relay_id.replacingOccurrences(of: "wss://", with: "https://")
urlString = urlString.replacingOccurrences(of: "ws://", with: "http://")
guard let url = URL(string: urlString) else {
return nil
}
var request = URLRequest(url: url)
request.setValue("application/nostr+json", forHTTPHeaderField: "Accept")
var res: (Data, URLResponse)? = nil
res = try await URLSession.shared.data(for: request)
guard let data = res?.0 else {
return nil
}
let nip11 = try JSONDecoder().decode(RelayMetadata.self, from: data)
return nip11
}
func process_relay_metadata() {
}
func handle_incoming_dm(contacts: Contacts, prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: String, ev: NostrEvent) -> NewEventsBits? {
// hide blocked users
guard should_show_event(contacts: contacts, ev: ev) else {

View File

@@ -88,7 +88,7 @@ class ProfileModel: ObservableObject, Equatable {
}
func handle_profile_contact_event(_ ev: NostrEvent) {
process_contact_event(pool: damus.pool, contacts: damus.contacts, pubkey: damus.pubkey, ev: ev)
process_contact_event(state: damus, ev: ev)
// only use new stuff
if let current_ev = self.contacts {

View File

@@ -0,0 +1,20 @@
//
// RelayMetadatas.swift
// damus
//
// Created by William Casarin on 2023-02-09.
//
import Foundation
class RelayMetadatas {
private var metadata: [String: RelayMetadata] = [:]
func lookup(relay_id: String) -> RelayMetadata? {
return metadata[relay_id]
}
func insert(relay_id: String, metadata: RelayMetadata) {
self.metadata[relay_id] = metadata
}
}

View File

@@ -37,7 +37,7 @@ struct RecommendedRelayView: View {
guard let ev_after_add = add_relay(ev: ev_before_add, privkey: privkey, current_relays: damus.pool.descriptors, relay: relay, info: .rw) else {
return
}
process_contact_event(pool: damus.pool, contacts: damus.contacts, pubkey: damus.pubkey, ev: ev_after_add)
process_contact_event(state: damus, ev: ev_after_add)
damus.pool.send(.event(ev_after_add))
}
}

View File

@@ -67,7 +67,7 @@ struct RelayConfigView: View {
return
}
process_contact_event(pool: state.pool, contacts: state.contacts, pubkey: state.pubkey, ev: ev)
process_contact_event(state: state, ev: ev)
state.pool.send(.event(new_ev))
}

View File

@@ -10,10 +10,9 @@ import SwiftUI
struct RelayDetailView: View {
let state: DamusState
let relay: String
let nip11: RelayMetadata
@State private var errorString: String?
@State private var nip11: RelayMetadata?
@State var conn_color: Color
@Environment(\.dismiss) var dismiss
@@ -69,39 +68,7 @@ struct RelayDetailView: View {
.onReceive(handle_notify(.switched_timeline)) { notif in
dismiss()
}
.navigationTitle(nip11?.name ?? "")
.task {
var urlString = relay.replacingOccurrences(of: "wss://", with: "https://")
urlString = urlString.replacingOccurrences(of: "ws://", with: "http://")
guard let url = URL(string: urlString) else {
return
}
var request = URLRequest(url: url)
request.setValue("application/nostr+json", forHTTPHeaderField: "Accept")
var res: (Data, URLResponse)? = nil
do {
res = try await URLSession.shared.data(for: request)
} catch {
errorString = error.localizedDescription
return
}
guard let data = res?.0 else {
errorString = "Relay not responding to metadata request"
return
}
do {
let nip11 = try JSONDecoder().decode(RelayMetadata.self, from: data)
self.nip11 = nip11
} catch {
errorString = error.localizedDescription
}
}
.navigationTitle(nip11.name ?? "")
}
private func nipsList(nips: [Int]) -> AttributedString {
@@ -124,6 +91,7 @@ struct RelayDetailView: View {
struct RelayDetailView_Previews: PreviewProvider {
static var previews: some View {
RelayDetailView(state: test_damus_state(), relay: "wss://nostr.klabo.blog", conn_color: .green)
let metadata = RelayMetadata(name: "name", description: "desc", pubkey: "pubkey", contact: "contact", supported_nips: [1,2,3], software: "software", version: "version")
RelayDetailView(state: test_damus_state(), relay: "relay", nip11: metadata, conn_color: .green)
}
}

View File

@@ -34,9 +34,13 @@ struct RelayView: View {
Circle()
.frame(width: 8.0, height: 8.0)
.foregroundColor(conn_color)
NavigationLink {
RelayDetailView(state: state, relay: relay, conn_color: conn_color)
} label: {
if let meta = state.relay_metadata.lookup(relay_id: relay) {
NavigationLink {
RelayDetailView(state: state, relay: relay, nip11: meta, conn_color: conn_color)
} label: {
Text(relay)
}
} else {
Text(relay)
}
}
@@ -79,7 +83,7 @@ struct RelayView: View {
return
}
process_contact_event(pool: state.pool, contacts: state.contacts, pubkey: state.pubkey, ev: new_ev)
process_contact_event(state: state, ev: new_ev)
state.pool.send(.event(new_ev))
} label: {
Label(NSLocalizedString("Delete", comment: "Button to delete a relay server that the user connects to."), systemImage: "trash")