Browse Source

Recommended relay view

Changelog-Changed: Show recommended relays in config. Currently just a fixed set.
post-button-style
William Casarin 2 years ago
parent
commit
14a3a352d6
  1. 4
      damus.xcodeproj/project.pbxproj
  2. 1
      damus/ContentView.swift
  3. 6
      damus/Models/Contacts.swift
  4. 23
      damus/Models/HomeModel.swift
  5. 31
      damus/Views/ConfigView.swift
  6. 37
      damus/Views/RecommendedRelayView.swift
  7. 17
      damus/Views/RelayView.swift

4
damus.xcodeproj/project.pbxproj

@ -109,6 +109,7 @@
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */; };
4CACA9D5280C31E100D9BBE8 /* ReplyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */; };
4CACA9DC280C38C000D9BBE8 /* Profiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CACA9DB280C38C000D9BBE8 /* Profiles.swift */; };
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */; };
4CD7641B28A1641400B6928F /* EndBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD7641A28A1641400B6928F /* EndBlock.swift */; };
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F8CC281352B30009DFBB /* Notifications.swift */; };
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */; };
@ -288,6 +289,7 @@
4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineView.swift; sourceTree = "<group>"; };
4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyView.swift; sourceTree = "<group>"; };
4CACA9DB280C38C000D9BBE8 /* Profiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Profiles.swift; sourceTree = "<group>"; };
4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendedRelayView.swift; sourceTree = "<group>"; };
4CD7641A28A1641400B6928F /* EndBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EndBlock.swift; sourceTree = "<group>"; };
4CE4F8CC281352B30009DFBB /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigView.swift; sourceTree = "<group>"; };
@ -486,6 +488,7 @@
E990020E2955F837003BBC5A /* EditMetadataView.swift */,
BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */,
E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */,
4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */,
);
path = Views;
sourceTree = "<group>";
@ -860,6 +863,7 @@
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */,
4C3AC79B28306D7B00E1F516 /* Contacts.swift in Sources */,
4C3EA63D28FF52D600C48A62 /* bolt11.c in Sources */,
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */,
4C5F9118283D88E40052CD1C /* FollowingModel.swift in Sources */,
4C3EA67D28FFBBA300C48A62 /* InvoicesView.swift in Sources */,
4C363A8E28236FE4006E126D /* NoteContentView.swift in Sources */,

1
damus/ContentView.swift

@ -16,6 +16,7 @@ var BOOTSTRAP_RELAYS = [
"wss://relay.nostr.bg",
"wss://nostr.oxtr.dev",
"wss://nostr.v0l.io",
"wss://nostr-2.zebedee.cloud",
]
struct TimestampedProfile {

6
damus/Models/Contacts.swift

@ -144,6 +144,7 @@ func remove_relay(ev: NostrEvent, current_relays: [RelayDescriptor], privkey: St
relays.removeValue(forKey: relay)
print("remove_relay \(relays)")
guard let content = encode_json(relays) else {
return nil
}
@ -154,10 +155,9 @@ func remove_relay(ev: NostrEvent, current_relays: [RelayDescriptor], privkey: St
return new_ev
}
func add_relay(ev: NostrEvent, privkey: String, relay: String, info: RelayInfo) -> NostrEvent? {
let damus_relay = RelayDescriptor(url: URL(string: "wss://relay.damus.io")!, info: .rw)
func add_relay(ev: NostrEvent, privkey: String, current_relays: [RelayDescriptor], relay: String, info: RelayInfo) -> NostrEvent? {
var relays = ensure_relay_info(relays: current_relays, content: ev.content)
var relays = ensure_relay_info(relays: [damus_relay], content: ev.content)
guard relays.index(forKey: relay) == nil else {
return nil
}

23
damus/Models/HomeModel.swift

@ -623,26 +623,3 @@ func load_our_relays(contacts: Contacts, our_pubkey: String, pool: RelayPool, m_
}
func remove_bootstrap_nodes(_ damus_state: DamusState) {
guard let contacts = damus_state.contacts.event else {
return
}
guard let relays = decode_json_relays(contacts.content) else {
return
}
let descriptors = relays.reduce(into: []) { arr, kv in
guard let url = URL(string: kv.key) else {
return
}
arr.append(RelayDescriptor(url: url, info: kv.value))
}
for relay in BOOTSTRAP_RELAYS {
if !(descriptors.contains { ($0 as! RelayDescriptor).url.absoluteString == relay }) {
damus_state.pool.remove_relay(relay)
}
}
}

31
damus/Views/ConfigView.swift

@ -18,11 +18,14 @@ struct ConfigView: View {
@State var privkey_copied: Bool = false
@State var pubkey_copied: Bool = false
@State var relays: [RelayDescriptor]
let generator = UIImpactFeedbackGenerator(style: .light)
init(state: DamusState) {
self.state = state
_privkey = State(initialValue: self.state.keypair.privkey_bech32 ?? "")
_relays = State(initialValue: state.pool.descriptors)
}
// TODO: (jb55) could be more general but not gonna worry about it atm
@ -38,12 +41,28 @@ struct ConfigView: View {
}
}
var recommended: [RelayDescriptor] {
let rs: [RelayDescriptor] = []
return BOOTSTRAP_RELAYS.reduce(into: rs) { (xs, x) in
if let _ = state.pool.get_relay(x) {
} else {
xs.append(RelayDescriptor(url: URL(string: x)!, info: .rw))
}
}
}
var body: some View {
ZStack(alignment: .leading) {
Form {
Section("Relays") {
List(Array(state.pool.relays), id: \.descriptor.url) { relay in
RelayView(state: state, relay: relay.descriptor.url.absoluteString)
List(Array(relays), id: \.url) { relay in
RelayView(state: state, relay: relay.url.absoluteString)
}
}
Section("Recommended Relays") {
List(recommended, id: \.url) { r in
RecommendedRelayView(damus: state, relay: r.url.absoluteString)
}
}
@ -133,17 +152,21 @@ struct ConfigView: View {
state.pool.connect(to: [new_relay])
guard let new_ev = add_relay(ev: ev, privkey: privkey, relay: new_relay, info: info) else {
guard let new_ev = add_relay(ev: ev, privkey: privkey, current_relays: state.pool.descriptors, relay: new_relay, info: info) else {
return
}
state.contacts.event = new_ev
process_contact_event(pool: state.pool, contacts: state.contacts, pubkey: state.pubkey, ev: ev)
state.pool.send(.event(new_ev))
}
}
.onReceive(handle_notify(.switched_timeline)) { _ in
dismiss()
}
.onReceive(handle_notify(.relays_changed)) { _ in
self.relays = state.pool.descriptors
}
}
}

37
damus/Views/RecommendedRelayView.swift

@ -0,0 +1,37 @@
//
// RecommendedRelayView.swift
// damus
//
// Created by William Casarin on 2022-12-29.
//
import SwiftUI
struct RecommendedRelayView: View {
let damus: DamusState
let relay: String
var body: some View {
HStack {
Text(relay)
Spacer()
if let ev = damus.contacts.event {
if let privkey = damus.keypair.privkey {
Button("Add") {
guard let ev = add_relay(ev: ev, 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)
damus.pool.send(.event(ev))
}
}
}
}
}
}
struct RecommendedRelayView_Previews: PreviewProvider {
static var previews: some View {
RecommendedRelayView(damus: test_damus_state(), relay: "wss://relay.damus.io")
}
}

17
damus/Views/RelayView.swift

@ -44,6 +44,17 @@ struct RelayView: View {
}
.swipeActions {
if let privkey = state.keypair.privkey {
RemoveAction(privkey: privkey)
}
}
.contextMenu {
if let privkey = state.keypair.privkey {
RemoveAction(privkey: privkey)
}
}
}
func RemoveAction(privkey: String) -> some View {
Button {
guard let ev = state.contacts.event else {
return
@ -54,15 +65,17 @@ struct RelayView: View {
return
}
state.contacts.event = new_ev
process_contact_event(pool: state.pool, contacts: state.contacts, pubkey: state.pubkey, ev: new_ev)
state.pool.send(.event(new_ev))
} label: {
Label("Delete", systemImage: "trash")
}
.tint(.red)
}
}
}
fileprivate func remove_action() {
}

Loading…
Cancel
Save