mirror of
git://jb55.com/damus
synced 2024-09-30 00:40:45 +00:00
nip19: add search functionality for naddr, nprofile & nevent
The user is able to search for naddr, nprofile & nevent bech32 entities. Additionally, these entities and others are able to have prefixes such as damus:nostr: and damus.io links. Closes: https://github.com/damus-io/damus/issues/1841 Closes: https://github.com/damus-io/damus/issues/1650 Changelog-Added: Add ability to search for naddr, nprofiles, nevents Lightning-url: LNURL1DP68GURN8GHJ7EM9W3SKCCNE9E3K7MF0D3H82UNVWQHKWUN9V4HXGCTHDC6RZVGR8SW3G Signed-off-by: kernelkind <kernelkind@gmail.com> Reviewed-by: William Casarin <jb55@jb55.com> Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
a4a0465605
commit
0650a62791
@ -614,6 +614,7 @@
|
||||
D7FB10A72B0C371A00FA8D42 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C2B10272A7B0F5C008AA43E /* Log.swift */; };
|
||||
D7FF94002AC7AC5300FD969D /* RelayURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7FF93FF2AC7AC5200FD969D /* RelayURL.swift */; };
|
||||
E02B54182B4DFADA0077FF42 /* Bech32ObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E02B54172B4DFADA0077FF42 /* Bech32ObjectTests.swift */; };
|
||||
E04A37C62B544F090029650D /* URIParsing.swift in Sources */ = {isa = PBXBuildFile; fileRef = E04A37C52B544F090029650D /* URIParsing.swift */; };
|
||||
E4FA1C032A24BB7F00482697 /* SearchSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FA1C022A24BB7F00482697 /* SearchSettingsView.swift */; };
|
||||
E990020F2955F837003BBC5A /* EditMetadataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E990020E2955F837003BBC5A /* EditMetadataView.swift */; };
|
||||
E9E4ED0B295867B900DD7078 /* ThreadView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E4ED0A295867B900DD7078 /* ThreadView.swift */; };
|
||||
@ -1377,6 +1378,7 @@
|
||||
D7EDED322B12ACAE0018B19C /* DamusUserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusUserDefaults.swift; sourceTree = "<group>"; };
|
||||
D7FF93FF2AC7AC5200FD969D /* RelayURL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayURL.swift; sourceTree = "<group>"; };
|
||||
E02B54172B4DFADA0077FF42 /* Bech32ObjectTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bech32ObjectTests.swift; sourceTree = "<group>"; };
|
||||
E04A37C52B544F090029650D /* URIParsing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URIParsing.swift; sourceTree = "<group>"; };
|
||||
E4FA1C022A24BB7F00482697 /* SearchSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchSettingsView.swift; sourceTree = "<group>"; };
|
||||
E990020E2955F837003BBC5A /* EditMetadataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditMetadataView.swift; sourceTree = "<group>"; };
|
||||
E9E4ED0A295867B900DD7078 /* ThreadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadView.swift; sourceTree = "<group>"; };
|
||||
@ -2055,6 +2057,7 @@
|
||||
4C7FF7D628233637009601DB /* Util */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E04A37C52B544F090029650D /* URIParsing.swift */,
|
||||
4C1D4FB02A7958E60024F453 /* VersionInfo.swift */,
|
||||
4C7D09612A098D0E00943473 /* WalletConnect.swift */,
|
||||
4C198DF329F88D23004C165C /* Images */,
|
||||
@ -3297,6 +3300,7 @@
|
||||
50B5685329F97CB400A23243 /* CredentialHandler.swift in Sources */,
|
||||
643EA5C8296B764E005081BB /* RelayFilterView.swift in Sources */,
|
||||
F71694EC2A662292001F4053 /* SuggestedUsersViewModel.swift in Sources */,
|
||||
E04A37C62B544F090029650D /* URIParsing.swift in Sources */,
|
||||
4C3EA67D28FFBBA300C48A62 /* InvoicesView.swift in Sources */,
|
||||
4C363A8E28236FE4006E126D /* NoteContentView.swift in Sources */,
|
||||
4C2B10282A7B0F5C008AA43E /* Log.swift in Sources */,
|
||||
|
@ -55,14 +55,6 @@ func parse_hexstr(_ p: Parser, len: Int) -> String? {
|
||||
return String(substring(p.str, start: start, end: p.pos))
|
||||
}
|
||||
|
||||
func decode_universal_link(_ s: String) -> NostrLink? {
|
||||
var uri = s.replacingOccurrences(of: "https://damus.io/r/", with: "")
|
||||
uri = uri.replacingOccurrences(of: "https://damus.io/", with: "")
|
||||
uri = uri.replacingOccurrences(of: "/", with: "")
|
||||
|
||||
return decode_nostr_bech32_uri(uri)
|
||||
}
|
||||
|
||||
func decode_nostr_bech32_uri(_ s: String) -> NostrLink? {
|
||||
guard let obj = Bech32Object.parse(s) else {
|
||||
return nil
|
||||
@ -90,19 +82,7 @@ func decode_nostr_bech32_uri(_ s: String) -> NostrLink? {
|
||||
}
|
||||
|
||||
func decode_nostr_uri(_ s: String) -> NostrLink? {
|
||||
if s.starts(with: "https://damus.io/") {
|
||||
return decode_universal_link(s)
|
||||
}
|
||||
|
||||
var uri = s
|
||||
uri = uri.replacingOccurrences(of: "nostr://", with: "")
|
||||
uri = uri.replacingOccurrences(of: "nostr:", with: "")
|
||||
|
||||
// Fix for non-latin characters resulting in second colon being encoded
|
||||
uri = uri.replacingOccurrences(of: "damus:t%3A", with: "t:")
|
||||
|
||||
uri = uri.replacingOccurrences(of: "damus://", with: "")
|
||||
uri = uri.replacingOccurrences(of: "damus:", with: "")
|
||||
let uri = remove_nostr_uri_prefix(s)
|
||||
|
||||
let parts = uri.split(separator: ":")
|
||||
.reduce(into: Array<String>()) { acc, str in
|
||||
|
34
damus/Util/URIParsing.swift
Normal file
34
damus/Util/URIParsing.swift
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// URIParsing.swift
|
||||
// damus
|
||||
//
|
||||
// Created by KernelKind on 1/13/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
private func remove_damus_uri_prefix(_ s: String) -> String {
|
||||
var uri = s.replacingOccurrences(of: "https://damus.io/r/", with: "")
|
||||
uri = uri.replacingOccurrences(of: "https://damus.io/", with: "")
|
||||
uri = uri.replacingOccurrences(of: "/", with: "")
|
||||
|
||||
return uri
|
||||
}
|
||||
|
||||
func remove_nostr_uri_prefix(_ s: String) -> String {
|
||||
if s.starts(with: "https://damus.io/") {
|
||||
return remove_damus_uri_prefix(s)
|
||||
}
|
||||
|
||||
var uri = s
|
||||
uri = uri.replacingOccurrences(of: "nostr://", with: "")
|
||||
uri = uri.replacingOccurrences(of: "nostr:", with: "")
|
||||
|
||||
// Fix for non-latin characters resulting in second colon being encoded
|
||||
uri = uri.replacingOccurrences(of: "damus:t%3A", with: "t:")
|
||||
|
||||
uri = uri.replacingOccurrences(of: "damus://", with: "")
|
||||
uri = uri.replacingOccurrences(of: "damus:", with: "")
|
||||
|
||||
return uri
|
||||
}
|
@ -18,6 +18,7 @@ enum SearchType: Equatable {
|
||||
case event(NoteId)
|
||||
case profile(Pubkey)
|
||||
case nip05(String)
|
||||
case naddr(NAddr)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@ -35,6 +36,8 @@ struct SearchingEventView: View {
|
||||
return "Profile"
|
||||
case .event:
|
||||
return "Note"
|
||||
case .naddr:
|
||||
return "Naddr"
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,6 +92,14 @@ struct SearchingEventView: View {
|
||||
}
|
||||
self.search_state = .found_profile(pubkey)
|
||||
}
|
||||
case .naddr(let naddr):
|
||||
naddrLookup(damus_state: state, naddr: naddr) { res in
|
||||
guard let res = res else {
|
||||
self.search_state = .not_found
|
||||
return
|
||||
}
|
||||
self.search_state = .found(res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,9 @@ enum Search: Identifiable {
|
||||
case nip05(String)
|
||||
case hex(Data)
|
||||
case multi(MultiSearch)
|
||||
case nevent(NEvent)
|
||||
case naddr(NAddr)
|
||||
case nprofile(NProfile)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@ -30,6 +33,9 @@ enum Search: Identifiable {
|
||||
case .nip05: return "nip05"
|
||||
case .hex: return "hex"
|
||||
case .multi: return "multi"
|
||||
case .nevent: return "nevent"
|
||||
case .naddr: return "naddr"
|
||||
case .nprofile: return "nprofile"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -62,27 +68,25 @@ struct InnerSearchResults: View {
|
||||
switch search {
|
||||
case .profiles(let results):
|
||||
ProfilesSearch(results)
|
||||
|
||||
case .hashtag(let ht):
|
||||
HashtagSearch(ht)
|
||||
|
||||
case .nip05(let addr):
|
||||
SearchingEventView(state: damus_state, search_type: .nip05(addr))
|
||||
|
||||
case .profile(let pubkey):
|
||||
SearchingEventView(state: damus_state, search_type: .profile(pubkey))
|
||||
|
||||
case .hex(let h):
|
||||
|
||||
VStack(spacing: 10) {
|
||||
SearchingEventView(state: damus_state, search_type: .event(NoteId(h)))
|
||||
|
||||
SearchingEventView(state: damus_state, search_type: .profile(Pubkey(h)))
|
||||
}
|
||||
|
||||
}
|
||||
case .note(let nid):
|
||||
SearchingEventView(state: damus_state, search_type: .event(nid))
|
||||
|
||||
case .nevent(let nevent):
|
||||
SearchingEventView(state: damus_state, search_type: .event(nevent.noteid))
|
||||
case .nprofile(let nprofile):
|
||||
SearchingEventView(state: damus_state, search_type: .profile(nprofile.author))
|
||||
case .naddr(let naddr):
|
||||
SearchingEventView(state: damus_state, search_type: .naddr(naddr))
|
||||
case .multi(let multi):
|
||||
VStack {
|
||||
HashtagSearch(multi.hashtag)
|
||||
@ -142,21 +146,35 @@ func search_for_string<Y>(profiles: Profiles, search new: String, txn: NdbTxn<Y>
|
||||
return .hashtag(make_hashtagable(new))
|
||||
}
|
||||
|
||||
if let new = hex_decode_id(new) {
|
||||
let searchQuery = remove_nostr_uri_prefix(new)
|
||||
|
||||
if let new = hex_decode_id(searchQuery) {
|
||||
return .hex(new)
|
||||
}
|
||||
|
||||
if new.starts(with: "npub") {
|
||||
if let decoded = bech32_pubkey_decode(new) {
|
||||
if searchQuery.starts(with: "npub") {
|
||||
if let decoded = bech32_pubkey_decode(searchQuery) {
|
||||
return .profile(decoded)
|
||||
}
|
||||
}
|
||||
|
||||
if new.starts(with: "note"), let decoded = try? bech32_decode(new) {
|
||||
if searchQuery.starts(with: "note"), let decoded = try? bech32_decode(searchQuery) {
|
||||
return .note(NoteId(decoded.data))
|
||||
}
|
||||
|
||||
let multisearch = MultiSearch(hashtag: make_hashtagable(new), profiles: search_profiles(profiles: profiles, search: new, txn: txn))
|
||||
if searchQuery.starts(with: "nevent"), case let .nevent(nevent) = Bech32Object.parse(searchQuery) {
|
||||
return .nevent(nevent)
|
||||
}
|
||||
|
||||
if searchQuery.starts(with: "nprofile"), case let .nprofile(nprofile) = Bech32Object.parse(searchQuery) {
|
||||
return .nprofile(nprofile)
|
||||
}
|
||||
|
||||
if searchQuery.starts(with: "naddr"), case let .naddr(naddr) = Bech32Object.parse(searchQuery) {
|
||||
return .naddr(naddr)
|
||||
}
|
||||
|
||||
let multisearch = MultiSearch(hashtag: make_hashtagable(searchQuery), profiles: search_profiles(profiles: profiles, search: new, txn: txn))
|
||||
return .multi(multisearch)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user