Merge branch 'master' into add-wallet-modal
This commit is contained in:
@@ -41,12 +41,19 @@ class RelayPool {
|
||||
}
|
||||
|
||||
func remove_handler(sub_id: String) {
|
||||
handlers = handlers.filter { $0.sub_id != sub_id }
|
||||
self.handlers = handlers.filter { $0.sub_id != sub_id }
|
||||
print("removing \(sub_id) handler, current: \(handlers.count)")
|
||||
}
|
||||
|
||||
func register_handler(sub_id: String, handler: @escaping (String, NostrConnectionEvent) -> ()) {
|
||||
|
||||
for handler in handlers {
|
||||
// don't add duplicate handlers
|
||||
if handler.sub_id == sub_id {
|
||||
return
|
||||
}
|
||||
}
|
||||
self.handlers.append(RelayHandler(sub_id: sub_id, callback: handler))
|
||||
print("registering \(sub_id) handler, current: \(self.handlers.count)")
|
||||
}
|
||||
|
||||
func remove_relay(_ relay_id: String) {
|
||||
@@ -125,8 +132,10 @@ class RelayPool {
|
||||
}
|
||||
|
||||
func unsubscribe(sub_id: String, to: [String]? = nil) {
|
||||
self.remove_handler(sub_id: sub_id)
|
||||
self.send(.unsubscribe(sub_id))
|
||||
if to == nil {
|
||||
self.remove_handler(sub_id: sub_id)
|
||||
}
|
||||
self.send(.unsubscribe(sub_id), to: to)
|
||||
}
|
||||
|
||||
func subscribe(sub_id: String, filters: [NostrFilter], handler: @escaping (String, NostrConnectionEvent) -> ()) {
|
||||
|
||||
@@ -15,13 +15,14 @@ let PRIVKEY_HRP = "nsec"
|
||||
struct Keypair {
|
||||
let pubkey: String
|
||||
let privkey: String?
|
||||
let pubkey_bech32: String
|
||||
let privkey_bech32: String?
|
||||
|
||||
var pubkey_bech32: String {
|
||||
return bech32_pubkey(pubkey)!
|
||||
}
|
||||
|
||||
var privkey_bech32: String? {
|
||||
return privkey.flatMap { bech32_privkey($0) }
|
||||
init(pubkey: String, privkey: String?) {
|
||||
self.pubkey = pubkey
|
||||
self.privkey = privkey
|
||||
self.pubkey_bech32 = bech32_pubkey(pubkey) ?? pubkey
|
||||
self.privkey_bech32 = privkey.flatMap { bech32_privkey($0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,11 @@ func isHttpsUrl(_ string: String) -> Bool {
|
||||
return urlTest.evaluate(with: string)
|
||||
}
|
||||
|
||||
struct NIP05 {
|
||||
let username: String
|
||||
let host: String
|
||||
}
|
||||
|
||||
func isImage(_ urlString: String) -> Bool {
|
||||
let imageTypes = ["image/jpg", "image/jpeg", "image/png", "image/gif", "image/tiff", "image/bmp", "image/webp"]
|
||||
|
||||
@@ -95,6 +100,14 @@ struct EditMetadataView: View {
|
||||
}
|
||||
}
|
||||
|
||||
var nip05_parts: NIP05? {
|
||||
let parts = nip05.split(separator: "@")
|
||||
guard parts.count == 2 else {
|
||||
return nil
|
||||
}
|
||||
return NIP05(username: String(parts[0]), host: String(parts[1]))
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
@@ -149,13 +162,17 @@ struct EditMetadataView: View {
|
||||
}
|
||||
|
||||
Section(content: {
|
||||
TextField("example.com", text: $nip05)
|
||||
TextField("jb55@jb55.com", text: $nip05)
|
||||
.autocorrectionDisabled(true)
|
||||
.textInputAutocapitalization(.never)
|
||||
}, header: {
|
||||
Text("NIP-05 Verification")
|
||||
}, footer: {
|
||||
Text("\(name)@\(nip05) will be used for verification")
|
||||
if let parts = nip05_parts {
|
||||
Text("'\(parts.username)' at '\(parts.host)' will be used for verification")
|
||||
} else {
|
||||
Text("'\(nip05)' is an invalid nip05 identifier. It should look like an email.")
|
||||
}
|
||||
})
|
||||
|
||||
Button("Save") {
|
||||
|
||||
@@ -88,12 +88,12 @@ struct EventActionBar: View {
|
||||
}
|
||||
.padding(.top, 1)
|
||||
.alert("Boost", isPresented: $confirm_boost) {
|
||||
Button("Boost") {
|
||||
send_boost()
|
||||
}
|
||||
Button("Cancel") {
|
||||
confirm_boost = false
|
||||
}
|
||||
Button("Boost") {
|
||||
send_boost()
|
||||
}
|
||||
} message: {
|
||||
Text("Are you sure you want to boost this post?")
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ struct EventView: View {
|
||||
VStack(alignment: .leading) {
|
||||
let prof_model = ProfileModel(pubkey: event.pubkey, damus: damus)
|
||||
let follow_model = FollowersModel(damus_state: damus, target: event.pubkey)
|
||||
let prof = damus.profiles.lookup(id: event.pubkey)
|
||||
let booster_profile = ProfileView(damus_state: damus, profile: prof_model, followers: follow_model)
|
||||
|
||||
NavigationLink(destination: booster_profile) {
|
||||
@@ -86,11 +87,9 @@ struct EventView: View {
|
||||
Image(systemName: "arrow.2.squarepath")
|
||||
.font(.footnote.weight(.bold))
|
||||
.foregroundColor(Color.gray)
|
||||
if let prof = damus.profiles.lookup(id: event.pubkey) {
|
||||
Text(Profile.displayName(profile: prof, pubkey: event.pubkey))
|
||||
ProfileName(pubkey: event.pubkey, profile: prof, contacts: damus.contacts, show_friend_confirmed: true)
|
||||
.font(.footnote.weight(.bold))
|
||||
.foregroundColor(Color.gray)
|
||||
}
|
||||
Text("Boosted")
|
||||
.font(.footnote.weight(.bold))
|
||||
.foregroundColor(Color.gray)
|
||||
@@ -214,7 +213,7 @@ extension View {
|
||||
Button {
|
||||
UIPasteboard.general.string = event_to_json(ev: event)
|
||||
} label: {
|
||||
Label("Copy Note", systemImage: "note")
|
||||
Label("Copy Note JSON", systemImage: "note")
|
||||
}
|
||||
|
||||
Button {
|
||||
|
||||
@@ -34,16 +34,16 @@ func pfp_line_width(_ h: Highlight) -> CGFloat {
|
||||
|
||||
struct InnerProfilePicView: View {
|
||||
@Environment(\.redactionReasons) private var reasons
|
||||
|
||||
|
||||
let url: URL?
|
||||
let pubkey: String
|
||||
let size: CGFloat
|
||||
let highlight: Highlight
|
||||
|
||||
|
||||
var PlaceholderColor: Color {
|
||||
return id_to_color(pubkey)
|
||||
}
|
||||
|
||||
|
||||
var Placeholder: some View {
|
||||
PlaceholderColor
|
||||
.frame(width: size, height: size)
|
||||
@@ -51,7 +51,7 @@ struct InnerProfilePicView: View {
|
||||
.overlay(Circle().stroke(highlight_color(highlight), lineWidth: pfp_line_width(highlight)))
|
||||
.padding(2)
|
||||
}
|
||||
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if reasons.isEmpty {
|
||||
@@ -74,7 +74,6 @@ struct InnerProfilePicView: View {
|
||||
.clipShape(Circle())
|
||||
.overlay(Circle().stroke(highlight_color(highlight), lineWidth: pfp_line_width(highlight)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct ProfilePicView: View {
|
||||
|
||||
@@ -113,6 +113,7 @@ struct EditButton: View {
|
||||
|
||||
struct ProfileView: View {
|
||||
let damus_state: DamusState
|
||||
let zoom_size: CGFloat = 350
|
||||
|
||||
@State private var selected_tab: ProfileTab = .posts
|
||||
@StateObject var profile: ProfileModel
|
||||
@@ -120,6 +121,7 @@ struct ProfileView: View {
|
||||
@State private var showingEditProfile = false
|
||||
@State var showingSelectWallet: Bool = false
|
||||
@State var inv: String = ""
|
||||
@State var is_zoomed: Bool = false
|
||||
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
@@ -169,6 +171,12 @@ struct ProfileView: View {
|
||||
|
||||
HStack(alignment: .center) {
|
||||
ProfilePicView(pubkey: profile.pubkey, size: PFP_SIZE, highlight: .custom(Color.black, 2), profiles: damus_state.profiles)
|
||||
.onTapGesture {
|
||||
is_zoomed.toggle()
|
||||
}
|
||||
.sheet(isPresented: $is_zoomed) {
|
||||
ProfilePicView(pubkey: profile.pubkey, size: zoom_size, highlight: .custom(Color.black, 2), profiles: damus_state.profiles)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
|
||||
@@ -16,12 +16,13 @@ struct SearchHomeView: View {
|
||||
var SearchInput: some View {
|
||||
ZStack(alignment: .leading) {
|
||||
HStack{
|
||||
TextField("", text: $search)
|
||||
TextField("Search...", text: $search)
|
||||
.padding(8)
|
||||
.padding(.leading, 35)
|
||||
.autocorrectionDisabled(true)
|
||||
.textInputAutocapitalization(.never)
|
||||
Label("", systemImage: "xmark.square")
|
||||
Text("Cancel")
|
||||
.foregroundColor(.blue)
|
||||
.padding(EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 10.0))
|
||||
.opacity((search == "") ? 0.0 : 1.0)
|
||||
.onTapGesture {
|
||||
@@ -70,7 +71,9 @@ struct SearchHomeView: View {
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
|
||||
var body: some View {
|
||||
MainContent
|
||||
VStack {
|
||||
MainContent
|
||||
}
|
||||
.safeAreaInset(edge: .top) {
|
||||
VStack(spacing: 0) {
|
||||
SearchInput
|
||||
@@ -85,8 +88,6 @@ struct SearchHomeView: View {
|
||||
print("search change 1")
|
||||
}
|
||||
.onAppear {
|
||||
// TODO: This will always be empty when switching between tabs
|
||||
// We'll need to store these in
|
||||
if model.events.isEmpty {
|
||||
model.subscribe()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user