Add nip05 search
Changelog-Added: Added ability to lookup users by nip05 identifiers
This commit is contained in:
69
damus/Util/DebouncedOnChange.swift
Normal file
69
damus/Util/DebouncedOnChange.swift
Normal file
@@ -0,0 +1,69 @@
|
||||
// https://github.com/Tunous/DebouncedOnChange/blob/5670ea13e8ad33e9cc3197f6d13ce492dc0e46ab/Sources/DebouncedOnChange/DebouncedChangeViewModifier.swift
|
||||
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
extension View {
|
||||
|
||||
/// Adds a modifier for this view that fires an action only when a time interval in seconds represented by
|
||||
/// `debounceTime` elapses between value changes.
|
||||
///
|
||||
/// Each time the value changes before `debounceTime` passes, the previous action will be cancelled and the next
|
||||
/// action /// will be scheduled to run after that time passes again. This mean that the action will only execute
|
||||
/// after changes to the value /// stay unmodified for the specified `debounceTime` in seconds.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - value: The value to check against when determining whether to run the closure.
|
||||
/// - debounceTime: The time in seconds to wait after each value change before running `action` closure.
|
||||
/// - action: A closure to run when the value changes.
|
||||
/// - Returns: A view that fires an action after debounced time when the specified value changes.
|
||||
public func onChange<Value>(
|
||||
of value: Value,
|
||||
debounceTime: TimeInterval,
|
||||
perform action: @escaping (_ newValue: Value) -> Void
|
||||
) -> some View where Value: Equatable {
|
||||
self.modifier(DebouncedChangeViewModifier(trigger: value, debounceTime: debounceTime, action: action))
|
||||
}
|
||||
}
|
||||
|
||||
private struct DebouncedChangeViewModifier<Value>: ViewModifier where Value: Equatable {
|
||||
let trigger: Value
|
||||
let debounceTime: TimeInterval
|
||||
let action: (Value) -> Void
|
||||
|
||||
@State private var debouncedTask: Task<Void, Never>?
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content.onChange(of: trigger) { value in
|
||||
debouncedTask?.cancel()
|
||||
debouncedTask = Task.delayed(seconds: debounceTime) { @MainActor in
|
||||
action(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Task {
|
||||
|
||||
/// Asynchronously runs the given `operation` in its own task after the specified number of `seconds`.
|
||||
///
|
||||
/// The operation will be executed after specified number of `seconds` passes. You can cancel the task earlier
|
||||
/// for the operation to be skipped.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - time: Delay time in seconds.
|
||||
/// - operation: The operation to execute.
|
||||
/// - Returns: Handle to the task which can be cancelled.
|
||||
@discardableResult
|
||||
public static func delayed(
|
||||
seconds: TimeInterval,
|
||||
operation: @escaping @Sendable () async -> Void
|
||||
) -> Self where Success == Void, Failure == Never {
|
||||
Self {
|
||||
do {
|
||||
try await Task<Never, Never>.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
|
||||
await operation()
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,11 +39,20 @@ enum NIP05Validation {
|
||||
case valid
|
||||
}
|
||||
|
||||
func validate_nip05(pubkey: String, nip05_str: String) async -> NIP05? {
|
||||
struct FetchedNIP05 {
|
||||
let response: NIP05Response
|
||||
let nip05: NIP05Response
|
||||
}
|
||||
|
||||
func fetch_nip05_str(nip05_str: String) async -> NIP05Response? {
|
||||
guard let nip05 = NIP05.parse(nip05_str) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return await fetch_nip05(nip05: nip05)
|
||||
}
|
||||
|
||||
func fetch_nip05(nip05: NIP05) async -> NIP05Response? {
|
||||
guard let url = nip05.url else {
|
||||
return nil
|
||||
}
|
||||
@@ -57,6 +66,18 @@ func validate_nip05(pubkey: String, nip05_str: String) async -> NIP05? {
|
||||
return nil
|
||||
}
|
||||
|
||||
return decoded
|
||||
}
|
||||
|
||||
func validate_nip05(pubkey: String, nip05_str: String) async -> NIP05? {
|
||||
guard let nip05 = NIP05.parse(nip05_str) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let decoded = await fetch_nip05(nip05: nip05) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
guard let stored_pk = decoded.names[nip05.username] else {
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user