Huge refactor to add better structure to the project. Separating features with their associated view and model structure. This should be better organization and will allow us to improve the overall architecture in the future. I forsee many more improvements that can follow this change. e.g. MVVM Arch As well as cleaning up duplicate, unused, functionality. Many files have global functions that can also be moved or be renamed. damus/ ├── Features/ │ ├── <Feature>/ │ │ ├── Views/ │ │ └── Models/ ├── Shared/ │ ├── Components/ │ ├── Media/ │ ├── Buttons/ │ ├── Extensions/ │ ├── Empty Views/ │ ├── ErrorHandling/ │ ├── Modifiers/ │ └── Utilities/ ├── Core/ │ ├── Nostr/ │ ├── NIPs/ │ ├── DIPs/ │ ├── Types/ │ ├── Networking/ │ └── Storage/ Signed-off-by: ericholguin <ericholguin@apache.org>
99 lines
2.7 KiB
Swift
99 lines
2.7 KiB
Swift
//
|
||
// RelayURL.swift
|
||
// damus
|
||
//
|
||
// Created by Daniel D’Aquino on 2023-09-29.
|
||
//
|
||
|
||
import Foundation
|
||
|
||
public struct RelayURL: Hashable, Equatable, Codable, CodingKeyRepresentable, Identifiable, Comparable, CustomStringConvertible {
|
||
private(set) var url: URL
|
||
|
||
public var id: URL {
|
||
return url
|
||
}
|
||
|
||
public var description: String {
|
||
return self.absoluteString
|
||
}
|
||
|
||
public var absoluteString: String {
|
||
return url.absoluteString
|
||
}
|
||
|
||
init?(_ str: String) {
|
||
var trimmed_url_str = str
|
||
while trimmed_url_str.hasSuffix("/") {
|
||
trimmed_url_str.removeLast()
|
||
}
|
||
|
||
guard let url = URL(string: trimmed_url_str) else {
|
||
return nil
|
||
}
|
||
|
||
guard let scheme = url.scheme else {
|
||
return nil
|
||
}
|
||
|
||
guard scheme == "ws" || scheme == "wss" else {
|
||
return nil
|
||
}
|
||
|
||
self.url = url
|
||
}
|
||
|
||
// MARK: - Codable
|
||
public init(from decoder: Decoder) throws {
|
||
let container = try decoder.singleValueContainer()
|
||
let urlString = try container.decode(String.self)
|
||
guard let instance = RelayURL(urlString) else {
|
||
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid URL string.")
|
||
}
|
||
self = instance
|
||
}
|
||
|
||
public func encode(to encoder: Encoder) throws {
|
||
var container = encoder.singleValueContainer()
|
||
try container.encode(url.absoluteString)
|
||
}
|
||
|
||
// MARK: - CodingKeyRepresentable
|
||
// CodingKeyRepresentable conformance is necessary to ensure that
|
||
// a dictionary with type "[RelayURL: T] where T: Codable" can be encoded into a keyed container
|
||
// e.g. `{<URL>: <VALUE>, <URL>: <VALUE>}` instead of `[<URL>, <VALUE>, <URL>, <VALUE>]`, which is Swift's default for non-string-keyed dictionaries
|
||
|
||
public var codingKey: CodingKey {
|
||
return StringKey(stringValue: self.url.absoluteString)
|
||
}
|
||
|
||
public init?<T>(codingKey: T) where T : CodingKey {
|
||
self.init(codingKey.stringValue)
|
||
}
|
||
|
||
// MARK: - Equatable
|
||
public static func == (lhs: RelayURL, rhs: RelayURL) -> Bool {
|
||
return lhs.url == rhs.url
|
||
}
|
||
|
||
// MARK: - Hashable
|
||
public func hash(into hasher: inout Hasher) {
|
||
hasher.combine(self.url)
|
||
}
|
||
|
||
// MARK: - Comparable
|
||
public static func < (lhs: RelayURL, rhs: RelayURL) -> Bool {
|
||
return lhs.url.absoluteString < rhs.url.absoluteString
|
||
}
|
||
|
||
}
|
||
|
||
private struct StringKey: CodingKey {
|
||
var stringValue: String
|
||
init(stringValue: String) {
|
||
self.stringValue = stringValue
|
||
}
|
||
var intValue: Int? { return nil }
|
||
init?(intValue: Int) { return nil }
|
||
}
|