1
0
mirror of git://jb55.com/damus synced 2024-09-19 11:43:44 +00:00

edit relays

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin 2022-06-09 13:47:25 -07:00
parent e104de6431
commit 6de7d7ae58
7 changed files with 329 additions and 36 deletions

View File

@ -77,6 +77,9 @@
4CACA9D5280C31E100D9BBE8 /* ReplyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */; };
4CACA9DC280C38C000D9BBE8 /* Profiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CACA9DB280C38C000D9BBE8 /* Profiles.swift */; };
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F8CC281352B30009DFBB /* Notifications.swift */; };
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */; };
4CE4F9E1285287B800C00DD9 /* TextFieldAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9E0285287B800C00DD9 /* TextFieldAlert.swift */; };
4CE4F9E328528C5200C00DD9 /* AddRelayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */; };
4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE627F7A08100C66700 /* damusApp.swift */; };
4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE827F7A08100C66700 /* ContentView.swift */; };
4CE6DEEB27F7A08200C66700 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4CE6DEEA27F7A08200C66700 /* Assets.xcassets */; };
@ -185,6 +188,9 @@
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>"; };
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>"; };
4CE4F9E0285287B800C00DD9 /* TextFieldAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldAlert.swift; sourceTree = "<group>"; };
4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRelayView.swift; sourceTree = "<group>"; };
4CE6DEE327F7A08100C66700 /* damus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = damus.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CE6DEE627F7A08100C66700 /* damusApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = damusApp.swift; sourceTree = "<group>"; };
4CE6DEE827F7A08100C66700 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
@ -297,6 +303,8 @@
4C285C8D28399BFD008A31F1 /* SaveKeysView.swift */,
4C90BD17283A9EE5008EE7EF /* LoginView.swift */,
4C5C7E69284EDE2E00A22DF5 /* SearchResultsView.swift */,
4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */,
4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */,
);
path = Views;
sourceTree = "<group>";
@ -336,6 +344,14 @@
path = Util;
sourceTree = "<group>";
};
4CE4F9DF285287A000C00DD9 /* Components */ = {
isa = PBXGroup;
children = (
4CE4F9E0285287B800C00DD9 /* TextFieldAlert.swift */,
);
path = Components;
sourceTree = "<group>";
};
4CE6DEDA27F7A08100C66700 = {
isa = PBXGroup;
children = (
@ -360,6 +376,7 @@
4CE6DEE527F7A08100C66700 /* damus */ = {
isa = PBXGroup;
children = (
4CE4F9DF285287A000C00DD9 /* Components */,
4C7FF7D628233637009601DB /* Util */,
4C0A3F8D280F63FF000448DE /* Models */,
4C75EFAB28049CC80006080F /* Nostr */,
@ -551,6 +568,7 @@
4C363A8A28236B57006E126D /* MentionView.swift in Sources */,
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */,
4C285C8428385690008A31F1 /* CreateAccountView.swift in Sources */,
4CE4F9E1285287B800C00DD9 /* TextFieldAlert.swift in Sources */,
4C363AA828297703006E126D /* InsertSort.swift in Sources */,
4C285C86283892E7008A31F1 /* CreateAccountModel.swift in Sources */,
4C363A8C28236B92006E126D /* PubkeyView.swift in Sources */,
@ -571,10 +589,12 @@
4C477C9E282C3A4800033AA3 /* TipCounter.swift in Sources */,
4C0A3F91280F6528000448DE /* ChatView.swift in Sources */,
4C75EFA627FF87A20006080F /* Nostr.swift in Sources */,
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */,
4C285C8E28399BFE008A31F1 /* SaveKeysView.swift in Sources */,
4C75EFB328049D640006080F /* NostrEvent.swift in Sources */,
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */,
4C363A8428233689006E126D /* Parser.swift in Sources */,
4CE4F9E328528C5200C00DD9 /* AddRelayView.swift in Sources */,
4C363A9A28283854006E126D /* Reply.swift in Sources */,
4C90BD18283A9EE5008EE7EF /* LoginView.swift in Sources */,
4C3BEFDC281DCE6100B3DE84 /* Liked.swift in Sources */,

View File

@ -0,0 +1,61 @@
//
// TextFieldAlert.swift
// damus
//
// Created by William Casarin on 2022-06-09.
//
import SwiftUI
struct TextFieldAlert<Presenting>: View where Presenting: View {
@Binding var isShowing: Bool
@Binding var text: String
let presenting: Presenting
let title: String
var body: some View {
GeometryReader { (deviceSize: GeometryProxy) in
ZStack {
self.presenting
.disabled(isShowing)
VStack {
Text(self.title)
TextField("Relay", text: self.$text)
Divider()
HStack {
Button(action: {
withAnimation {
self.isShowing.toggle()
}
}) {
Text("Dismiss")
}
}
}
.padding()
.background(Color.white)
.frame(
width: deviceSize.size.width*0.7,
height: deviceSize.size.height*0.7
)
.shadow(radius: 1)
.opacity(self.isShowing ? 1 : 0)
}
}
}
}
extension View {
func textFieldAlert(isShowing: Binding<Bool>,
text: Binding<String>,
title: String) -> some View {
TextFieldAlert(isShowing: isShowing,
text: text,
presenting: self,
title: title)
}
}

View File

@ -63,7 +63,7 @@ struct ContentView: View {
var LoadingContainer: some View {
VStack {
HStack {
HStack(alignment: .center) {
Spacer()
if home.signal.signal != home.signal.max_signal {
@ -71,6 +71,11 @@ struct ContentView: View {
.font(.callout)
.foregroundColor(.gray)
}
NavigationLink(destination: ConfigView(state: damus_state!)) {
Label("", systemImage: "gear")
}
.buttonStyle(PlainButtonStyle())
}
Spacer()
@ -91,36 +96,32 @@ struct ContentView: View {
}
func MainContent(damus: DamusState) -> some View {
NavigationView {
VStack {
NavigationLink(destination: MaybeProfileView, isActive: $profile_open) {
EmptyView()
}
NavigationLink(destination: MaybeThreadView, isActive: $thread_open) {
EmptyView()
}
NavigationLink(destination: MaybeSearchView, isActive: $search_open) {
EmptyView()
}
switch selected_timeline {
case .search:
SearchHomeView(damus_state: damus_state!, model: SearchHomeModel(pool: damus_state!.pool) )
case .home:
PostingTimelineView
case .notifications:
TimelineView(events: $home.notifications, damus: damus)
.navigationTitle("Notifications")
case .none:
EmptyView()
}
VStack {
NavigationLink(destination: MaybeProfileView, isActive: $profile_open) {
EmptyView()
}
NavigationLink(destination: MaybeThreadView, isActive: $thread_open) {
EmptyView()
}
NavigationLink(destination: MaybeSearchView, isActive: $search_open) {
EmptyView()
}
switch selected_timeline {
case .search:
SearchHomeView(damus_state: damus_state!, model: SearchHomeModel(pool: damus_state!.pool) )
case .home:
PostingTimelineView
case .notifications:
TimelineView(events: $home.notifications, damus: damus)
.navigationTitle("Notifications")
case .none:
EmptyView()
}
.navigationBarTitle("Damus", displayMode: .inline)
}
.navigationViewStyle(.stack)
.navigationBarTitle("Damus", displayMode: .inline)
}
var MaybeSearchView: some View {
@ -159,12 +160,13 @@ struct ContentView: View {
var body: some View {
VStack {
if let damus = self.damus_state {
ZStack {
NavigationView {
MainContent(damus: damus)
.padding([.bottom], -8.0)
LoadingContainer
.toolbar {
LoadingContainer
}
}
.navigationViewStyle(.stack)
}
TabBar(new_notifications: $home.new_notifications, selected: $selected_timeline, action: switch_timeline)

View File

@ -138,14 +138,52 @@ func decode_json_relays(_ content: String) -> [String: RelayInfo]? {
return decode_json(content)
}
/*
func remove_relay(ev: NostrEvent, privkey: String, relay: String) -> NostrEvent? {
let damus_relay = RelayDescriptor(url: URL(string: "wss://relay.damus.io")!, info: .rw)
var relays = ensure_relay_info(relays: [damus_relay], content: ev.content)
guard relays.index(forKey: relay) != nil else {
return nil
}
relays.removeValue(forKey: relay)
guard let content = encode_json(relays) else {
return nil
}
let new_ev = NostrEvent(content: content, pubkey: ev.pubkey, kind: 3, tags: ev.tags)
new_ev.calculate_id()
new_ev.sign(privkey: privkey)
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)
var relays = ensure_relay_info(relays: [damus_relay], content: ev.content)
guard relays.index(forKey: relay) == nil else {
return nil
}
relays[relay] = info
guard let content = encode_json(relays) else {
return nil
}
let new_ev = NostrEvent(content: content, pubkey: ev.pubkey, kind: 3, tags: ev.tags)
new_ev.calculate_id()
new_ev.sign(privkey: privkey)
return new_ev
}
func ensure_relay_info(relays: [RelayDescriptor], content: String) -> [String: RelayInfo] {
guard let relay_info = decode_json_relays(content) else {
return make_contact_relays(relays)
}
return relay_info
}
*/
func follow_with_existing_contacts(our_pubkey: String, our_contacts: NostrEvent, follow: ReferencedId) -> NostrEvent? {
// don't update if we're already following

View File

@ -165,7 +165,7 @@ class NostrEvent: Codable, Identifiable, CustomStringConvertible {
public var is_local: Bool {
return (self.flags & 1) != 0
}
init(content: String, pubkey: String, kind: Int = 1, tags: [[String]] = []) {
self.id = ""
self.sig = ""
@ -176,6 +176,17 @@ class NostrEvent: Codable, Identifiable, CustomStringConvertible {
self.tags = tags
self.created_at = Int64(Date().timeIntervalSince1970)
}
init(from: NostrEvent) {
self.id = from.id
self.sig = from.sig
self.content = from.content
self.pubkey = from.pubkey
self.kind = from.kind
self.tags = from.tags
self.created_at = from.created_at
}
func calculate_id() {
self.id = calculate_event_id(ev: self)

View File

@ -0,0 +1,55 @@
//
// AddRelayView.swift
// damus
//
// Created by William Casarin on 2022-06-09.
//
import SwiftUI
struct AddRelayView: View {
@Binding var show_add_relay: Bool
@Binding var relay: String
let action: (String?) -> Void
var body: some View {
VStack(alignment: .leading) {
Form {
Section("Add Relay") {
TextField("wss://some.relay.com", text: $relay)
.textInputAutocapitalization(.never)
}
}
VStack {
HStack {
Button("Cancel") {
show_add_relay = false
action(nil)
}
.contentShape(Rectangle())
Spacer()
Button("Add") {
show_add_relay = false
action(relay)
}
.buttonStyle(.borderedProminent)
.contentShape(Rectangle())
}
.padding()
}
}
}
}
struct AddRelayView_Previews: PreviewProvider {
@State static var show: Bool = true
@State static var relay: String = ""
static var previews: some View {
AddRelayView(show_add_relay: $show, relay: $relay, action: {_ in })
}
}

View File

@ -0,0 +1,106 @@
//
// ConfigView.swift
// damus
//
// Created by William Casarin on 2022-06-09.
//
import SwiftUI
struct ConfigView: View {
let state: DamusState
@Environment(\.dismiss) var dismiss
@State var show_add_relay: Bool = false
@State var new_relay: String = ""
func Relay(_ ev: NostrEvent, relay: String) -> some View {
return Text(relay)
.swipeActions {
if let privkey = state.keypair.privkey {
Button {
guard let new_ev = remove_relay( ev: ev, privkey: privkey, relay: relay) else {
return
}
state.contacts.event = new_ev
state.pool.send(.event(new_ev))
} label: {
Label("Delete", systemImage: "trash")
}
.tint(.red)
}
}
}
var body: some View {
ZStack(alignment: .leading) {
Form {
if let ev = state.contacts.event {
Section("Relays") {
if let relays = decode_json_relays(ev.content) {
List(Array(relays.keys.sorted()), id: \.self) { relay in
Relay(ev, relay: relay)
}
}
}
}
}
VStack {
HStack {
Spacer()
Button(action: { show_add_relay = true }) {
Label("", systemImage: "plus")
.foregroundColor(.accentColor)
.padding()
}
}
Spacer()
}
}
.navigationTitle("Settings")
.navigationBarTitleDisplayMode(.large)
.sheet(isPresented: $show_add_relay) {
AddRelayView(show_add_relay: $show_add_relay, relay: $new_relay) { _ in
guard let url = URL(string: new_relay) else {
return
}
guard let ev = state.contacts.event else {
return
}
guard let privkey = state.keypair.privkey else {
return
}
let info = RelayInfo.rw
guard (try? state.pool.add_relay(url, info: info)) != nil else {
return
}
state.pool.connect(to: [new_relay])
guard let new_ev = add_relay(ev: ev, privkey: privkey, relay: new_relay, info: info) else {
return
}
state.contacts.event = new_ev
state.pool.send(.event(new_ev))
}
}
.onReceive(handle_notify(.switched_timeline)) { _ in
dismiss()
}
}
}
struct ConfigView_Previews: PreviewProvider {
static var previews: some View {
ConfigView(state: test_damus_state())
}
}