mirror of https://github.com/lukechilds/damus.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
5.6 KiB
156 lines
5.6 KiB
//
|
|
// SearchResultsView.swift
|
|
// damus
|
|
//
|
|
// Created by William Casarin on 2022-06-06.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
enum Search {
|
|
case profiles([(String, Profile)])
|
|
case hashtag(String)
|
|
case profile(String)
|
|
case note(String)
|
|
case hex(String)
|
|
}
|
|
|
|
struct SearchResultsView: View {
|
|
let damus_state: DamusState
|
|
@Binding var search: String
|
|
@State var result: Search? = nil
|
|
|
|
func ProfileSearchResult(pk: String, res: Profile) -> some View {
|
|
FollowUserView(target: .pubkey(pk), damus_state: damus_state)
|
|
}
|
|
|
|
var MainContent: some View {
|
|
ScrollView {
|
|
Group {
|
|
switch result {
|
|
case .profiles(let results):
|
|
LazyVStack {
|
|
ForEach(results, id: \.0) { prof in
|
|
ProfileSearchResult(pk: prof.0, res: prof.1)
|
|
}
|
|
}
|
|
case .hashtag(let ht):
|
|
let search_model = SearchModel(pool: damus_state.pool, search: .filter_hashtag([ht]))
|
|
let dst = SearchView(appstate: damus_state, search: search_model)
|
|
NavigationLink(destination: dst) {
|
|
Text("Search hashtag: #\(ht)", comment: "Navigation link to search hashtag.")
|
|
}
|
|
case .profile(let prof):
|
|
let decoded = try? bech32_decode(prof)
|
|
let hex = hex_encode(decoded!.data)
|
|
let prof_model = ProfileModel(pubkey: hex, damus: damus_state)
|
|
let f = FollowersModel(damus_state: damus_state, target: prof)
|
|
let dst = ProfileView(damus_state: damus_state, profile: prof_model, followers: f)
|
|
NavigationLink(destination: dst) {
|
|
Text("Goto profile \(prof)", comment: "Navigation link to go to profile.")
|
|
}
|
|
case .hex(let h):
|
|
let prof_model = ProfileModel(pubkey: h, damus: damus_state)
|
|
let f = FollowersModel(damus_state: damus_state, target: h)
|
|
let prof_view = ProfileView(damus_state: damus_state, profile: prof_model, followers: f)
|
|
let ev_view = BuildThreadV2View(
|
|
damus: damus_state,
|
|
event_id: h
|
|
)
|
|
|
|
VStack(spacing: 50) {
|
|
NavigationLink(destination: prof_view) {
|
|
Text("Goto profile \(h)", comment: "Navigation link to go to profile referenced by hex code.")
|
|
}
|
|
NavigationLink(destination: ev_view) {
|
|
Text("Goto post \(h)", comment: "Navigation link to go to post referenced by hex code.")
|
|
}
|
|
}
|
|
case .note(let nid):
|
|
let decoded = try? bech32_decode(nid)
|
|
let hex = hex_encode(decoded!.data)
|
|
let ev_view = BuildThreadV2View(
|
|
damus: damus_state,
|
|
event_id: hex
|
|
)
|
|
NavigationLink(destination: ev_view) {
|
|
Text("Goto post \(nid)", comment: "Navigation link to go to post referenced by note ID.")
|
|
}
|
|
case .none:
|
|
Text("none", comment: "No search results.")
|
|
}
|
|
}.padding(.horizontal)
|
|
}
|
|
}
|
|
|
|
func search_changed(_ new: String) {
|
|
guard new.count != 0 else {
|
|
return
|
|
}
|
|
|
|
if new.first! == "#" {
|
|
let ht = String(new.dropFirst())
|
|
self.result = .hashtag(ht)
|
|
return
|
|
}
|
|
|
|
if let _ = hex_decode(new), new.count == 64 {
|
|
self.result = .hex(new)
|
|
return
|
|
}
|
|
|
|
if new.starts(with: "npub") {
|
|
if let _ = try? bech32_decode(new) {
|
|
self.result = .profile(new)
|
|
return
|
|
}
|
|
}
|
|
|
|
if new.starts(with: "note") {
|
|
if let _ = try? bech32_decode(new) {
|
|
self.result = .note(new)
|
|
return
|
|
}
|
|
}
|
|
|
|
let profs = damus_state.profiles.profiles.enumerated()
|
|
let results: [(String, Profile)] = profs.reduce(into: []) { acc, els in
|
|
let pk = els.element.key
|
|
let prof = els.element.value.profile
|
|
let lowname = prof.name.map { $0.lowercased() }
|
|
let lownip05 = damus_state.profiles.is_validated(pk).map { $0.host.lowercased() }
|
|
let lowdisp = prof.display_name.map { $0.lowercased() }
|
|
let ok = new.count == 1 ?
|
|
((lowname?.starts(with: new) ?? false) ||
|
|
(lownip05?.starts(with: new) ?? false) ||
|
|
(lowdisp?.starts(with: new) ?? false)) : (pk.starts(with: new) || String(new.dropFirst()) == pk
|
|
|| lowname?.contains(new) ?? false
|
|
|| lownip05?.contains(new) ?? false
|
|
|| lowdisp?.contains(new) ?? false)
|
|
if ok {
|
|
acc.append((pk, prof))
|
|
}
|
|
}
|
|
|
|
self.result = .profiles(results)
|
|
}
|
|
|
|
var body: some View {
|
|
MainContent
|
|
.frame(maxHeight: .infinity)
|
|
.onAppear {
|
|
search_changed(search)
|
|
}
|
|
.onChange(of: search) { new in
|
|
search_changed(new)
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
struct SearchResultsView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
SearchResultsView(damus_state: test_damus_state(), s)
|
|
}
|
|
}
|
|
*/
|
|
|