mirror of
git://jb55.com/damus
synced 2024-09-19 19:46:51 +00:00
Search hashtags automatically
Changelog-Changed: Search hashtags automatically
This commit is contained in:
parent
4f459d128a
commit
8eb013f1f7
@ -87,6 +87,8 @@ class SearchModel: ObservableObject {
|
||||
return
|
||||
}
|
||||
|
||||
self.loading = false
|
||||
|
||||
if sub_id == self.sub_id {
|
||||
load_profiles(profiles_subid: self.profiles_subid, relay_id: relay_id, load: .from_events(self.events.all_events), damus_state: state)
|
||||
}
|
||||
|
@ -7,82 +7,132 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
enum Search {
|
||||
struct MultiSearch {
|
||||
let hashtag: String
|
||||
let profiles: [SearchedUser]
|
||||
}
|
||||
|
||||
enum Search: Identifiable {
|
||||
case profiles([SearchedUser])
|
||||
case hashtag(String)
|
||||
case profile(String)
|
||||
case note(String)
|
||||
case nip05(String)
|
||||
case hex(String)
|
||||
case multi(MultiSearch)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
case .profiles: return "profiles"
|
||||
case .hashtag: return "hashtag"
|
||||
case .profile: return "profile"
|
||||
case .note: return "note"
|
||||
case .nip05: return "nip05"
|
||||
case .hex: return "hex"
|
||||
case .multi: return "multi"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SearchResultsView: View {
|
||||
struct AnySearchResultsView: View {
|
||||
let damus_state: DamusState
|
||||
@Binding var search: String
|
||||
let searches: [Search]
|
||||
|
||||
@State var result: Search? = nil
|
||||
var body: some View {
|
||||
VStack {
|
||||
ForEach(searches) { r in
|
||||
InnerSearchResults(damus_state: damus_state, search: r)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InnerSearchResults: View {
|
||||
let damus_state: DamusState
|
||||
let search: Search?
|
||||
|
||||
func ProfileSearchResult(pk: String) -> 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) { prof in
|
||||
ProfileSearchResult(pk: prof.pubkey)
|
||||
}
|
||||
}
|
||||
case .hashtag(let ht):
|
||||
let search_model = SearchModel(state: damus_state, 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 .nip05(let addr):
|
||||
SearchingEventView(state: damus_state, evid: addr, search_type: .nip05)
|
||||
|
||||
case .profile(let prof):
|
||||
let decoded = try? bech32_decode(prof)
|
||||
let hex = hex_encode(decoded!.data)
|
||||
|
||||
SearchingEventView(state: damus_state, evid: hex, search_type: .profile)
|
||||
case .hex(let h):
|
||||
//let prof_view = ProfileView(damus_state: damus_state, pubkey: h)
|
||||
//let ev_view = ThreadView(damus: damus_state, event_id: h)
|
||||
|
||||
VStack(spacing: 10) {
|
||||
SearchingEventView(state: damus_state, evid: h, search_type: .event)
|
||||
|
||||
SearchingEventView(state: damus_state, evid: h, search_type: .profile)
|
||||
}
|
||||
|
||||
case .note(let nid):
|
||||
let decoded = try? bech32_decode(nid)
|
||||
let hex = hex_encode(decoded!.data)
|
||||
|
||||
SearchingEventView(state: damus_state, evid: hex, search_type: .event)
|
||||
case .none:
|
||||
Text("none", comment: "No search results.")
|
||||
}
|
||||
func HashtagSearch(_ ht: String) -> some View {
|
||||
let search_model = SearchModel(state: damus_state, search: .filter_hashtag([ht]))
|
||||
let dst = SearchView(appstate: damus_state, search: search_model)
|
||||
return NavigationLink(destination: dst) {
|
||||
Text("Search hashtag: #\(ht)", comment: "Navigation link to search hashtag.")
|
||||
}
|
||||
}
|
||||
|
||||
func ProfilesSearch(_ results: [SearchedUser]) -> some View {
|
||||
return LazyVStack {
|
||||
ForEach(results) { prof in
|
||||
ProfileSearchResult(pk: prof.pubkey)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
MainContent
|
||||
.frame(maxHeight: .infinity)
|
||||
.onAppear {
|
||||
self.result = search_for_string(profiles: damus_state.profiles, search)
|
||||
}
|
||||
.onChange(of: search) { new in
|
||||
self.result = search_for_string(profiles: damus_state.profiles, new)
|
||||
Group {
|
||||
switch search {
|
||||
case .profiles(let results):
|
||||
ProfilesSearch(results)
|
||||
|
||||
case .hashtag(let ht):
|
||||
HashtagSearch(ht)
|
||||
|
||||
case .nip05(let addr):
|
||||
SearchingEventView(state: damus_state, evid: addr, search_type: .nip05)
|
||||
|
||||
case .profile(let prof):
|
||||
let decoded = try? bech32_decode(prof)
|
||||
let hex = hex_encode(decoded!.data)
|
||||
|
||||
SearchingEventView(state: damus_state, evid: hex, search_type: .profile)
|
||||
case .hex(let h):
|
||||
//let prof_view = ProfileView(damus_state: damus_state, pubkey: h)
|
||||
//let ev_view = ThreadView(damus: damus_state, event_id: h)
|
||||
|
||||
VStack(spacing: 10) {
|
||||
SearchingEventView(state: damus_state, evid: h, search_type: .event)
|
||||
|
||||
SearchingEventView(state: damus_state, evid: h, search_type: .profile)
|
||||
}
|
||||
|
||||
case .note(let nid):
|
||||
let decoded = try? bech32_decode(nid)
|
||||
let hex = hex_encode(decoded!.data)
|
||||
|
||||
SearchingEventView(state: damus_state, evid: hex, search_type: .event)
|
||||
case .multi(let multi):
|
||||
VStack {
|
||||
HashtagSearch(multi.hashtag)
|
||||
ProfilesSearch(multi.profiles)
|
||||
}
|
||||
|
||||
case .none:
|
||||
Text("none", comment: "No search results.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SearchResultsView: View {
|
||||
let damus_state: DamusState
|
||||
@Binding var search: String
|
||||
@State var result: Search? = nil
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
InnerSearchResults(damus_state: damus_state, search: result)
|
||||
.padding()
|
||||
}
|
||||
.frame(maxHeight: .infinity)
|
||||
.onAppear {
|
||||
self.result = search_for_string(profiles: damus_state.profiles, search)
|
||||
}
|
||||
.onChange(of: search) { new in
|
||||
self.result = search_for_string(profiles: damus_state.profiles, new)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,8 +157,7 @@ func search_for_string(profiles: Profiles, _ new: String) -> Search? {
|
||||
}
|
||||
|
||||
if new.first! == "#" {
|
||||
let ht = String(new.dropFirst().filter{$0 != " "})
|
||||
return .hashtag(ht)
|
||||
return .hashtag(make_hashtagable(new))
|
||||
}
|
||||
|
||||
if hex_decode(new) != nil, new.count == 64 {
|
||||
@ -127,7 +176,21 @@ func search_for_string(profiles: Profiles, _ new: String) -> Search? {
|
||||
}
|
||||
}
|
||||
|
||||
return .profiles(search_profiles(profiles: profiles, search: new))
|
||||
let multisearch = MultiSearch(hashtag: make_hashtagable(new), profiles: search_profiles(profiles: profiles, search: new))
|
||||
return .multi(multisearch)
|
||||
}
|
||||
|
||||
func make_hashtagable(_ str: String) -> String {
|
||||
var new = str
|
||||
guard str.utf8.count > 0 else {
|
||||
return str
|
||||
}
|
||||
|
||||
if new.hasPrefix("#") {
|
||||
new = String(new.dropFirst())
|
||||
}
|
||||
|
||||
return String(new.filter{$0 != " "})
|
||||
}
|
||||
|
||||
func search_profiles(profiles: Profiles, search: String) -> [SearchedUser] {
|
||||
|
Loading…
Reference in New Issue
Block a user