This patch redesigns the relay detail view. The first step needed to further improve how relays are viewed. In addition, Fees are added to the relay metadata to present to the user the admission, subscription, or publication fees a relay may have. There are various changes made, but mainly several relay details are moved outside of the main RelayDetail view for easier tracking and updates. With this design we will be able to add ratings and relay previews, as this patch is large enough I will submit that improvement in the future. iPhone 15 Pro Max (17.3.1) Dark Mode: https://i.nostr.build/VwVvq.png https://i.nostr.build/KGO0v.png iPhone SE (3rd generation) (16.4) Light Mode: https://i.nostr.build/M5V26.png https://i.nostr.build/gZKw3.png Changelog-Added: Relay fees metadata Changelog-Changed: Relay detail design Signed-off-by: ericholguin <ericholguin@apache.org> Signed-off-by: William Casarin <jb55@jb55.com>
159 lines
3.4 KiB
Swift
159 lines
3.4 KiB
Swift
//
|
|
// Relay.swift
|
|
// damus
|
|
//
|
|
// Created by William Casarin on 2022-04-11.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public struct RelayInfo: Codable {
|
|
let read: Bool?
|
|
let write: Bool?
|
|
|
|
init(read: Bool, write: Bool) {
|
|
self.read = read
|
|
self.write = write
|
|
}
|
|
|
|
static let rw = RelayInfo(read: true, write: true)
|
|
}
|
|
|
|
enum RelayVariant {
|
|
case regular
|
|
case ephemeral
|
|
case nwc
|
|
}
|
|
|
|
public struct RelayDescriptor {
|
|
let url: RelayURL
|
|
let info: RelayInfo
|
|
let variant: RelayVariant
|
|
|
|
init(url: RelayURL, info: RelayInfo, variant: RelayVariant = .regular) {
|
|
self.url = url
|
|
self.info = info
|
|
self.variant = variant
|
|
}
|
|
|
|
var ephemeral: Bool {
|
|
switch variant {
|
|
case .regular:
|
|
return false
|
|
case .ephemeral:
|
|
return true
|
|
case .nwc:
|
|
return true
|
|
}
|
|
}
|
|
|
|
static func nwc(url: RelayURL) -> RelayDescriptor {
|
|
return RelayDescriptor(url: url, info: .rw, variant: .nwc)
|
|
}
|
|
}
|
|
|
|
enum RelayFlags: Int {
|
|
case none = 0
|
|
case broken = 1
|
|
}
|
|
|
|
enum RelayAuthenticationError {
|
|
/// Only a public key was provided in keypair to sign challenge.
|
|
///
|
|
/// A private key is required to sign `auth` challenge.
|
|
case no_private_key
|
|
/// No keypair was provided to sign challenge.
|
|
case no_key
|
|
}
|
|
enum RelayAuthenticationState: Equatable {
|
|
/// No `auth` request has been made from this relay
|
|
case none
|
|
/// We have received an `auth` challenge, but have not yet replied to the challenge
|
|
case pending
|
|
/// We have received an `auth` challenge and replied with an `auth` event
|
|
case verified
|
|
/// We received an `auth` challenge but failed to reply to the challenge
|
|
case error(RelayAuthenticationError)
|
|
}
|
|
|
|
struct Limitations: Codable {
|
|
let payment_required: Bool?
|
|
|
|
static var empty: Limitations {
|
|
Limitations(payment_required: nil)
|
|
}
|
|
}
|
|
|
|
struct Admission: Codable {
|
|
let amount: Int64
|
|
let unit: String
|
|
}
|
|
|
|
struct Subscription: Codable {
|
|
let amount: Int64
|
|
let unit: String
|
|
let period: Int
|
|
}
|
|
|
|
struct Publication: Codable {
|
|
let kinds: [Int]
|
|
let amount: Int64
|
|
let unit: String
|
|
}
|
|
|
|
struct Fees: Codable {
|
|
let admission: [Admission]?
|
|
let subscription: [Subscription]?
|
|
let publication: [Publication]?
|
|
|
|
static var empty: Fees {
|
|
Fees(admission: nil, subscription: nil, publication: nil)
|
|
}
|
|
}
|
|
|
|
struct RelayMetadata: Codable {
|
|
let name: String?
|
|
let description: String?
|
|
let pubkey: Pubkey?
|
|
let contact: String?
|
|
let supported_nips: [Int]?
|
|
let software: String?
|
|
let version: String?
|
|
let limitation: Limitations?
|
|
let payments_url: String?
|
|
let icon: String?
|
|
let fees: Fees?
|
|
|
|
var is_paid: Bool {
|
|
return limitation?.payment_required ?? false
|
|
}
|
|
}
|
|
|
|
class Relay: Identifiable {
|
|
let descriptor: RelayDescriptor
|
|
let connection: RelayConnection
|
|
var authentication_state: RelayAuthenticationState
|
|
|
|
var flags: Int
|
|
|
|
init(descriptor: RelayDescriptor, connection: RelayConnection) {
|
|
self.flags = 0
|
|
self.descriptor = descriptor
|
|
self.connection = connection
|
|
self.authentication_state = RelayAuthenticationState.none
|
|
}
|
|
|
|
var is_broken: Bool {
|
|
return (flags & RelayFlags.broken.rawValue) == RelayFlags.broken.rawValue
|
|
}
|
|
|
|
var id: RelayURL {
|
|
return descriptor.url
|
|
}
|
|
|
|
}
|
|
|
|
enum RelayError: Error {
|
|
case RelayAlreadyExists
|
|
}
|