Merge 'ui: add ndb search to universe view #2464'
William Casarin (3):
search: use lazyvstack
search: expand search results to 128
ericholguin (1):
ui: add ndb search to universe view
This commit is contained in:
@@ -395,6 +395,9 @@
|
|||||||
50B5685329F97CB400A23243 /* CredentialHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B5685229F97CB400A23243 /* CredentialHandler.swift */; };
|
50B5685329F97CB400A23243 /* CredentialHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B5685229F97CB400A23243 /* CredentialHandler.swift */; };
|
||||||
50C3E08A2AA8E3F7006A4BC0 /* AVPlayer+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C3E0892AA8E3F7006A4BC0 /* AVPlayer+Additions.swift */; };
|
50C3E08A2AA8E3F7006A4BC0 /* AVPlayer+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C3E0892AA8E3F7006A4BC0 /* AVPlayer+Additions.swift */; };
|
||||||
50DA11262A16A23F00236234 /* Launch.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 50DA11252A16A23F00236234 /* Launch.storyboard */; };
|
50DA11262A16A23F00236234 /* Launch.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 50DA11252A16A23F00236234 /* Launch.storyboard */; };
|
||||||
|
5C0567582C8FBC560073F23A /* NDBSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C0567572C8FBC560073F23A /* NDBSearchView.swift */; };
|
||||||
|
5C0567592C8FBDE30073F23A /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2277EE92A089BD5006C3807 /* Router.swift */; };
|
||||||
|
5C05675A2C8FBDE70073F23A /* NDBSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C0567572C8FBC560073F23A /* NDBSearchView.swift */; };
|
||||||
5C0707D12A1ECB38004E7B51 /* DamusLogoGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C0707D02A1ECB38004E7B51 /* DamusLogoGradient.swift */; };
|
5C0707D12A1ECB38004E7B51 /* DamusLogoGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C0707D02A1ECB38004E7B51 /* DamusLogoGradient.swift */; };
|
||||||
5C14C29B2BBBA29C00079FD2 /* RelaySoftwareDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C14C29A2BBBA29C00079FD2 /* RelaySoftwareDetail.swift */; };
|
5C14C29B2BBBA29C00079FD2 /* RelaySoftwareDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C14C29A2BBBA29C00079FD2 /* RelaySoftwareDetail.swift */; };
|
||||||
5C14C29D2BBBA40B00079FD2 /* RelayAdminDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C14C29C2BBBA40B00079FD2 /* RelayAdminDetail.swift */; };
|
5C14C29D2BBBA40B00079FD2 /* RelayAdminDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C14C29C2BBBA40B00079FD2 /* RelayAdminDetail.swift */; };
|
||||||
@@ -928,7 +931,6 @@
|
|||||||
D73E5F782C6A9A5C007EB227 /* NdbNote+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D798D2272B085CDA00234419 /* NdbNote+.swift */; };
|
D73E5F782C6A9A5C007EB227 /* NdbNote+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D798D2272B085CDA00234419 /* NdbNote+.swift */; };
|
||||||
D73E5F792C6A9C4C007EB227 /* HomeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C63334F283D40E500B1C9C3 /* HomeModel.swift */; };
|
D73E5F792C6A9C4C007EB227 /* HomeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C63334F283D40E500B1C9C3 /* HomeModel.swift */; };
|
||||||
D73E5F7A2C6A9C55007EB227 /* NotificationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A3B162B02DCE5008BD568 /* NotificationFormatter.swift */; };
|
D73E5F7A2C6A9C55007EB227 /* NotificationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A3B162B02DCE5008BD568 /* NotificationFormatter.swift */; };
|
||||||
D73E5F7B2C6A9D0F007EB227 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2277EE92A089BD5006C3807 /* Router.swift */; };
|
|
||||||
D73E5F7C2C6A9D4F007EB227 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE827F7A08100C66700 /* ContentView.swift */; };
|
D73E5F7C2C6A9D4F007EB227 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE827F7A08100C66700 /* ContentView.swift */; };
|
||||||
D73E5F7F2C6AA066007EB227 /* DamusAliases.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73E5F7E2C6AA066007EB227 /* DamusAliases.swift */; };
|
D73E5F7F2C6AA066007EB227 /* DamusAliases.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73E5F7E2C6AA066007EB227 /* DamusAliases.swift */; };
|
||||||
D73E5F812C6AA07A007EB227 /* HighlighterExtensionAliases.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73E5F802C6AA07A007EB227 /* HighlighterExtensionAliases.swift */; };
|
D73E5F812C6AA07A007EB227 /* HighlighterExtensionAliases.swift in Sources */ = {isa = PBXBuildFile; fileRef = D73E5F802C6AA07A007EB227 /* HighlighterExtensionAliases.swift */; };
|
||||||
@@ -1834,6 +1836,7 @@
|
|||||||
50B5685229F97CB400A23243 /* CredentialHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CredentialHandler.swift; sourceTree = "<group>"; };
|
50B5685229F97CB400A23243 /* CredentialHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CredentialHandler.swift; sourceTree = "<group>"; };
|
||||||
50C3E0892AA8E3F7006A4BC0 /* AVPlayer+Additions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVPlayer+Additions.swift"; sourceTree = "<group>"; };
|
50C3E0892AA8E3F7006A4BC0 /* AVPlayer+Additions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVPlayer+Additions.swift"; sourceTree = "<group>"; };
|
||||||
50DA11252A16A23F00236234 /* Launch.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Launch.storyboard; sourceTree = "<group>"; };
|
50DA11252A16A23F00236234 /* Launch.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Launch.storyboard; sourceTree = "<group>"; };
|
||||||
|
5C0567572C8FBC560073F23A /* NDBSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NDBSearchView.swift; sourceTree = "<group>"; };
|
||||||
5C0707D02A1ECB38004E7B51 /* DamusLogoGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusLogoGradient.swift; sourceTree = "<group>"; };
|
5C0707D02A1ECB38004E7B51 /* DamusLogoGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusLogoGradient.swift; sourceTree = "<group>"; };
|
||||||
5C14C29A2BBBA29C00079FD2 /* RelaySoftwareDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySoftwareDetail.swift; sourceTree = "<group>"; };
|
5C14C29A2BBBA29C00079FD2 /* RelaySoftwareDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySoftwareDetail.swift; sourceTree = "<group>"; };
|
||||||
5C14C29C2BBBA40B00079FD2 /* RelayAdminDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayAdminDetail.swift; sourceTree = "<group>"; };
|
5C14C29C2BBBA40B00079FD2 /* RelayAdminDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayAdminDetail.swift; sourceTree = "<group>"; };
|
||||||
@@ -2966,6 +2969,7 @@
|
|||||||
children = (
|
children = (
|
||||||
4CCEB7AD29B53D260078AA28 /* SearchingEventView.swift */,
|
4CCEB7AD29B53D260078AA28 /* SearchingEventView.swift */,
|
||||||
4C9D6D1A2B1D35D7004E5CD9 /* PullDownSearch.swift */,
|
4C9D6D1A2B1D35D7004E5CD9 /* PullDownSearch.swift */,
|
||||||
|
5C0567572C8FBC560073F23A /* NDBSearchView.swift */,
|
||||||
);
|
);
|
||||||
path = Search;
|
path = Search;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -4034,6 +4038,7 @@
|
|||||||
5C0707D12A1ECB38004E7B51 /* DamusLogoGradient.swift in Sources */,
|
5C0707D12A1ECB38004E7B51 /* DamusLogoGradient.swift in Sources */,
|
||||||
4CDD1AE02A6B305F001CD4DF /* NdbTagElem.swift in Sources */,
|
4CDD1AE02A6B305F001CD4DF /* NdbTagElem.swift in Sources */,
|
||||||
4C5F9114283D694D0052CD1C /* FollowTarget.swift in Sources */,
|
4C5F9114283D694D0052CD1C /* FollowTarget.swift in Sources */,
|
||||||
|
5C0567582C8FBC560073F23A /* NDBSearchView.swift in Sources */,
|
||||||
D72341192B6864F200E1E135 /* DamusPurpleEnvironment.swift in Sources */,
|
D72341192B6864F200E1E135 /* DamusPurpleEnvironment.swift in Sources */,
|
||||||
4CF0ABD629817F5B00D66079 /* ReportView.swift in Sources */,
|
4CF0ABD629817F5B00D66079 /* ReportView.swift in Sources */,
|
||||||
4C1A9A2729DDE31900516EAC /* TranslationSettingsView.swift in Sources */,
|
4C1A9A2729DDE31900516EAC /* TranslationSettingsView.swift in Sources */,
|
||||||
@@ -4351,6 +4356,7 @@
|
|||||||
D73E5E7A2C6A97F4007EB227 /* EventCache.swift in Sources */,
|
D73E5E7A2C6A97F4007EB227 /* EventCache.swift in Sources */,
|
||||||
D73E5E7B2C6A97F4007EB227 /* DebouncedOnChange.swift in Sources */,
|
D73E5E7B2C6A97F4007EB227 /* DebouncedOnChange.swift in Sources */,
|
||||||
D73E5E7C2C6A97F4007EB227 /* ReplyCounter.swift in Sources */,
|
D73E5E7C2C6A97F4007EB227 /* ReplyCounter.swift in Sources */,
|
||||||
|
5C0567592C8FBDE30073F23A /* Router.swift in Sources */,
|
||||||
D73E5E7D2C6A97F4007EB227 /* CompatibleAttribute.swift in Sources */,
|
D73E5E7D2C6A97F4007EB227 /* CompatibleAttribute.swift in Sources */,
|
||||||
D73E5E7E2C6A97F4007EB227 /* Hashtags.swift in Sources */,
|
D73E5E7E2C6A97F4007EB227 /* Hashtags.swift in Sources */,
|
||||||
D73E5E7F2C6A97F4007EB227 /* LocalNotification.swift in Sources */,
|
D73E5E7F2C6A97F4007EB227 /* LocalNotification.swift in Sources */,
|
||||||
@@ -4636,7 +4642,6 @@
|
|||||||
D73E5E1B2C6A9672007EB227 /* LikeCounter.swift in Sources */,
|
D73E5E1B2C6A9672007EB227 /* LikeCounter.swift in Sources */,
|
||||||
D703D7A92C670E5A00A400EA /* refmap.c in Sources */,
|
D703D7A92C670E5A00A400EA /* refmap.c in Sources */,
|
||||||
D703D77B2C670BF000A400EA /* TableVerifier.swift in Sources */,
|
D703D77B2C670BF000A400EA /* TableVerifier.swift in Sources */,
|
||||||
D73E5F7B2C6A9D0F007EB227 /* Router.swift in Sources */,
|
|
||||||
D703D76D2C670B4500A400EA /* ZapDataModel.swift in Sources */,
|
D703D76D2C670B4500A400EA /* ZapDataModel.swift in Sources */,
|
||||||
D703D79D2C670E0700A400EA /* node_id.c in Sources */,
|
D703D79D2C670E0700A400EA /* node_id.c in Sources */,
|
||||||
D703D79B2C670E0000A400EA /* bech32_util.c in Sources */,
|
D703D79B2C670E0000A400EA /* bech32_util.c in Sources */,
|
||||||
@@ -4647,6 +4652,7 @@
|
|||||||
D703D76B2C670B3100A400EA /* Referenced.swift in Sources */,
|
D703D76B2C670B3100A400EA /* Referenced.swift in Sources */,
|
||||||
D703D7952C670DE600A400EA /* hash_u5.c in Sources */,
|
D703D7952C670DE600A400EA /* hash_u5.c in Sources */,
|
||||||
D703D7582C670A6000A400EA /* Id.swift in Sources */,
|
D703D7582C670A6000A400EA /* Id.swift in Sources */,
|
||||||
|
5C05675A2C8FBDE70073F23A /* NDBSearchView.swift in Sources */,
|
||||||
D703D76E2C670B4900A400EA /* NdbTagsIterator.swift in Sources */,
|
D703D76E2C670B4900A400EA /* NdbTagsIterator.swift in Sources */,
|
||||||
D703D7A02C670E1500A400EA /* take.c in Sources */,
|
D703D7A02C670E1500A400EA /* take.c in Sources */,
|
||||||
D703D7692C670B2600A400EA /* Block.swift in Sources */,
|
D703D7692C670B2600A400EA /* Block.swift in Sources */,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ enum Route: Hashable {
|
|||||||
case Reactions(reactions: EventsModel)
|
case Reactions(reactions: EventsModel)
|
||||||
case Zaps(target: ZapTarget)
|
case Zaps(target: ZapTarget)
|
||||||
case Search(search: SearchModel)
|
case Search(search: SearchModel)
|
||||||
|
case NDBSearch(results: Binding<[NostrEvent]>)
|
||||||
case EULA
|
case EULA
|
||||||
case Login
|
case Login
|
||||||
case CreateAccount
|
case CreateAccount
|
||||||
@@ -105,6 +106,8 @@ enum Route: Hashable {
|
|||||||
ZapsView(state: damusState, target: target)
|
ZapsView(state: damusState, target: target)
|
||||||
case .Search(let search):
|
case .Search(let search):
|
||||||
SearchView(appstate: damusState, search: search)
|
SearchView(appstate: damusState, search: search)
|
||||||
|
case .NDBSearch(let results):
|
||||||
|
NDBSearchView(damus_state: damusState, results: results)
|
||||||
case .EULA:
|
case .EULA:
|
||||||
EULAView(nav: navigationCoordinator)
|
EULAView(nav: navigationCoordinator)
|
||||||
case .Login:
|
case .Login:
|
||||||
@@ -200,6 +203,8 @@ enum Route: Hashable {
|
|||||||
case .Search(let search):
|
case .Search(let search):
|
||||||
hasher.combine("search")
|
hasher.combine("search")
|
||||||
hasher.combine(search.search)
|
hasher.combine(search.search)
|
||||||
|
case .NDBSearch(let results):
|
||||||
|
hasher.combine("results")
|
||||||
case .EULA:
|
case .EULA:
|
||||||
hasher.combine("eula")
|
hasher.combine("eula")
|
||||||
case .Login:
|
case .Login:
|
||||||
|
|||||||
53
damus/Views/Search/NDBSearchView.swift
Normal file
53
damus/Views/Search/NDBSearchView.swift
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// NDBSearchView.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by eric on 9/9/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct NDBSearchView: View {
|
||||||
|
|
||||||
|
let damus_state: DamusState
|
||||||
|
@Binding var results: [NostrEvent]
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView {
|
||||||
|
if results.count > 0 {
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
Image("search")
|
||||||
|
Text("Top hits", comment: "A label indicating that the notes being displayed below it are all top note search results")
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
|
LazyVStack {
|
||||||
|
ForEach(results, id: \.self) { note in
|
||||||
|
EventView(damus: damus_state, event: note)
|
||||||
|
.onTapGesture {
|
||||||
|
let event = note.get_inner_event(cache: damus_state.events) ?? note
|
||||||
|
let thread = ThreadModel(event: event, damus_state: damus_state)
|
||||||
|
damus_state.nav.push(route: Route.Thread(thread: thread))
|
||||||
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
|
|
||||||
|
ThiccDivider()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if results.count == 0 {
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
Image("search")
|
||||||
|
Text("No results", comment: "A label indicating that note search resulted in no results")
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,8 +18,8 @@ struct PullDownSearchView: View {
|
|||||||
let on_cancel: () -> Void
|
let on_cancel: () -> Void
|
||||||
|
|
||||||
func do_search(query: String) {
|
func do_search(query: String) {
|
||||||
let limit = 16
|
let limit = 128
|
||||||
var note_keys = state.ndb.text_search(query: query, limit: limit, order: .newest_first)
|
let note_keys = state.ndb.text_search(query: query, limit: limit, order: .newest_first)
|
||||||
var res = [NostrEvent]()
|
var res = [NostrEvent]()
|
||||||
// TODO: fix duplicate results from search
|
// TODO: fix duplicate results from search
|
||||||
var keyset = Set<NoteKey>()
|
var keyset = Set<NoteKey>()
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct MultiSearch {
|
struct MultiSearch {
|
||||||
|
let text: String
|
||||||
let hashtag: String
|
let hashtag: String
|
||||||
let profiles: [Pubkey]
|
let profiles: [Pubkey]
|
||||||
}
|
}
|
||||||
@@ -43,6 +44,7 @@ enum Search: Identifiable {
|
|||||||
struct InnerSearchResults: View {
|
struct InnerSearchResults: View {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
let search: Search?
|
let search: Search?
|
||||||
|
@Binding var results: [NostrEvent]
|
||||||
|
|
||||||
func ProfileSearchResult(pk: Pubkey) -> some View {
|
func ProfileSearchResult(pk: Pubkey) -> some View {
|
||||||
FollowUserView(target: .pubkey(pk), damus_state: damus_state)
|
FollowUserView(target: .pubkey(pk), damus_state: damus_state)
|
||||||
@@ -51,7 +53,35 @@ struct InnerSearchResults: View {
|
|||||||
func HashtagSearch(_ ht: String) -> some View {
|
func HashtagSearch(_ ht: String) -> some View {
|
||||||
let search_model = SearchModel(state: damus_state, search: .filter_hashtag([ht]))
|
let search_model = SearchModel(state: damus_state, search: .filter_hashtag([ht]))
|
||||||
return NavigationLink(value: Route.Search(search: search_model)) {
|
return NavigationLink(value: Route.Search(search: search_model)) {
|
||||||
Text("Search hashtag: #\(ht)", comment: "Navigation link to search hashtag.")
|
HStack {
|
||||||
|
Image("search")
|
||||||
|
Text("#\(ht)", comment: "Navigation link to search hashtag.")
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 15)
|
||||||
|
.padding(.vertical, 5)
|
||||||
|
.background(DamusColors.neutral1)
|
||||||
|
.cornerRadius(20)
|
||||||
|
.overlay(
|
||||||
|
RoundedRectangle(cornerRadius: 20)
|
||||||
|
.stroke(DamusColors.neutral3, lineWidth: 1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TextSearch(_ txt: String) -> some View {
|
||||||
|
return NavigationLink(value: Route.NDBSearch(results: $results)) {
|
||||||
|
HStack {
|
||||||
|
Image("search")
|
||||||
|
Text("Notes", comment: "Navigation link to search text.")
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 15)
|
||||||
|
.padding(.vertical, 5)
|
||||||
|
.background(DamusColors.neutral1)
|
||||||
|
.cornerRadius(20)
|
||||||
|
.overlay(
|
||||||
|
RoundedRectangle(cornerRadius: 20)
|
||||||
|
.stroke(DamusColors.neutral3, lineWidth: 1)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +118,11 @@ struct InnerSearchResults: View {
|
|||||||
case .naddr(let naddr):
|
case .naddr(let naddr):
|
||||||
SearchingEventView(state: damus_state, search_type: .naddr(naddr))
|
SearchingEventView(state: damus_state, search_type: .naddr(naddr))
|
||||||
case .multi(let multi):
|
case .multi(let multi):
|
||||||
VStack {
|
VStack(alignment: .leading) {
|
||||||
HashtagSearch(multi.hashtag)
|
HStack {
|
||||||
|
HashtagSearch(multi.hashtag)
|
||||||
|
TextSearch(multi.text)
|
||||||
|
}
|
||||||
ProfilesSearch(multi.profiles)
|
ProfilesSearch(multi.profiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,10 +137,47 @@ struct SearchResultsView: View {
|
|||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
@Binding var search: String
|
@Binding var search: String
|
||||||
@State var result: Search? = nil
|
@State var result: Search? = nil
|
||||||
|
@State var results: [NostrEvent] = []
|
||||||
|
let debouncer: Debouncer = Debouncer(interval: 0.25)
|
||||||
|
|
||||||
|
func do_search(query: String) {
|
||||||
|
let limit = 128
|
||||||
|
var note_keys = damus_state.ndb.text_search(query: query, limit: limit, order: .newest_first)
|
||||||
|
var res = [NostrEvent]()
|
||||||
|
// TODO: fix duplicate results from search
|
||||||
|
var keyset = Set<NoteKey>()
|
||||||
|
|
||||||
|
// try reverse because newest first is a bit buggy on partial searches
|
||||||
|
if note_keys.count == 0 {
|
||||||
|
// don't touch existing results if there are no new ones
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
guard let txn = NdbTxn(ndb: damus_state.ndb) else { return }
|
||||||
|
for note_key in note_keys {
|
||||||
|
guard let note = damus_state.ndb.lookup_note_by_key_with_txn(note_key, txn: txn) else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !keyset.contains(note_key) {
|
||||||
|
let owned_note = note.to_owned()
|
||||||
|
res.append(owned_note)
|
||||||
|
keyset.insert(note_key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let res_ = res
|
||||||
|
|
||||||
|
Task { @MainActor [res_] in
|
||||||
|
results = res_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
InnerSearchResults(damus_state: damus_state, search: result)
|
InnerSearchResults(damus_state: damus_state, search: result, results: $results)
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
.frame(maxHeight: .infinity)
|
.frame(maxHeight: .infinity)
|
||||||
@@ -119,6 +189,13 @@ struct SearchResultsView: View {
|
|||||||
guard let txn = NdbTxn.init(ndb: damus_state.ndb) else { return }
|
guard let txn = NdbTxn.init(ndb: damus_state.ndb) else { return }
|
||||||
self.result = search_for_string(profiles: damus_state.profiles, contacts: damus_state.contacts, search: search, txn: txn)
|
self.result = search_for_string(profiles: damus_state.profiles, contacts: damus_state.contacts, search: search, txn: txn)
|
||||||
}
|
}
|
||||||
|
.onChange(of: search) { query in
|
||||||
|
debouncer.debounce {
|
||||||
|
Task.detached {
|
||||||
|
do_search(query: query)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +251,7 @@ func search_for_string<Y>(profiles: Profiles, contacts: Contacts, search new: St
|
|||||||
return .naddr(naddr)
|
return .naddr(naddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
let multisearch = MultiSearch(hashtag: make_hashtagable(searchQuery), profiles: search_profiles(profiles: profiles, contacts: contacts, search: new, txn: txn))
|
let multisearch = MultiSearch(text: new, hashtag: make_hashtagable(searchQuery), profiles: search_profiles(profiles: profiles, contacts: contacts, search: new, txn: txn))
|
||||||
return .multi(multisearch)
|
return .multi(multisearch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ class Ndb {
|
|||||||
return NdbNote(note: note_p, size: size, owned: false, key: key)
|
return NdbNote(note: note_p, size: size, owned: false, key: key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func text_search(query: String, limit: Int = 32, order: NdbSearchOrder = .newest_first) -> [NoteKey] {
|
func text_search(query: String, limit: Int = 128, order: NdbSearchOrder = .newest_first) -> [NoteKey] {
|
||||||
guard let txn = NdbTxn(ndb: self) else { return [] }
|
guard let txn = NdbTxn(ndb: self) else { return [] }
|
||||||
var results = ndb_text_search_results()
|
var results = ndb_text_search_results()
|
||||||
let res = query.withCString { q in
|
let res = query.withCString { q in
|
||||||
@@ -253,6 +253,113 @@ class Ndb {
|
|||||||
case 18: note_ids.append(results.results.18.key.note_id)
|
case 18: note_ids.append(results.results.18.key.note_id)
|
||||||
case 19: note_ids.append(results.results.19.key.note_id)
|
case 19: note_ids.append(results.results.19.key.note_id)
|
||||||
case 20: note_ids.append(results.results.20.key.note_id)
|
case 20: note_ids.append(results.results.20.key.note_id)
|
||||||
|
case 21: note_ids.append(results.results.21.key.note_id)
|
||||||
|
case 22: note_ids.append(results.results.22.key.note_id)
|
||||||
|
case 23: note_ids.append(results.results.23.key.note_id)
|
||||||
|
case 24: note_ids.append(results.results.24.key.note_id)
|
||||||
|
case 25: note_ids.append(results.results.25.key.note_id)
|
||||||
|
case 26: note_ids.append(results.results.26.key.note_id)
|
||||||
|
case 27: note_ids.append(results.results.27.key.note_id)
|
||||||
|
case 28: note_ids.append(results.results.28.key.note_id)
|
||||||
|
case 29: note_ids.append(results.results.29.key.note_id)
|
||||||
|
case 30: note_ids.append(results.results.30.key.note_id)
|
||||||
|
case 31: note_ids.append(results.results.31.key.note_id)
|
||||||
|
case 32: note_ids.append(results.results.32.key.note_id)
|
||||||
|
case 33: note_ids.append(results.results.33.key.note_id)
|
||||||
|
case 34: note_ids.append(results.results.34.key.note_id)
|
||||||
|
case 35: note_ids.append(results.results.35.key.note_id)
|
||||||
|
case 36: note_ids.append(results.results.36.key.note_id)
|
||||||
|
case 37: note_ids.append(results.results.37.key.note_id)
|
||||||
|
case 38: note_ids.append(results.results.38.key.note_id)
|
||||||
|
case 39: note_ids.append(results.results.39.key.note_id)
|
||||||
|
case 40: note_ids.append(results.results.40.key.note_id)
|
||||||
|
case 41: note_ids.append(results.results.41.key.note_id)
|
||||||
|
case 42: note_ids.append(results.results.42.key.note_id)
|
||||||
|
case 43: note_ids.append(results.results.43.key.note_id)
|
||||||
|
case 44: note_ids.append(results.results.44.key.note_id)
|
||||||
|
case 45: note_ids.append(results.results.45.key.note_id)
|
||||||
|
case 46: note_ids.append(results.results.46.key.note_id)
|
||||||
|
case 47: note_ids.append(results.results.47.key.note_id)
|
||||||
|
case 48: note_ids.append(results.results.48.key.note_id)
|
||||||
|
case 49: note_ids.append(results.results.49.key.note_id)
|
||||||
|
case 50: note_ids.append(results.results.50.key.note_id)
|
||||||
|
case 51: note_ids.append(results.results.51.key.note_id)
|
||||||
|
case 52: note_ids.append(results.results.52.key.note_id)
|
||||||
|
case 53: note_ids.append(results.results.53.key.note_id)
|
||||||
|
case 54: note_ids.append(results.results.54.key.note_id)
|
||||||
|
case 55: note_ids.append(results.results.55.key.note_id)
|
||||||
|
case 56: note_ids.append(results.results.56.key.note_id)
|
||||||
|
case 57: note_ids.append(results.results.57.key.note_id)
|
||||||
|
case 58: note_ids.append(results.results.58.key.note_id)
|
||||||
|
case 59: note_ids.append(results.results.59.key.note_id)
|
||||||
|
case 60: note_ids.append(results.results.60.key.note_id)
|
||||||
|
case 61: note_ids.append(results.results.61.key.note_id)
|
||||||
|
case 62: note_ids.append(results.results.62.key.note_id)
|
||||||
|
case 63: note_ids.append(results.results.63.key.note_id)
|
||||||
|
case 64: note_ids.append(results.results.64.key.note_id)
|
||||||
|
case 65: note_ids.append(results.results.65.key.note_id)
|
||||||
|
case 66: note_ids.append(results.results.66.key.note_id)
|
||||||
|
case 67: note_ids.append(results.results.67.key.note_id)
|
||||||
|
case 68: note_ids.append(results.results.68.key.note_id)
|
||||||
|
case 69: note_ids.append(results.results.69.key.note_id)
|
||||||
|
case 70: note_ids.append(results.results.70.key.note_id)
|
||||||
|
case 71: note_ids.append(results.results.71.key.note_id)
|
||||||
|
case 72: note_ids.append(results.results.72.key.note_id)
|
||||||
|
case 73: note_ids.append(results.results.73.key.note_id)
|
||||||
|
case 74: note_ids.append(results.results.74.key.note_id)
|
||||||
|
case 75: note_ids.append(results.results.75.key.note_id)
|
||||||
|
case 76: note_ids.append(results.results.76.key.note_id)
|
||||||
|
case 77: note_ids.append(results.results.77.key.note_id)
|
||||||
|
case 78: note_ids.append(results.results.78.key.note_id)
|
||||||
|
case 79: note_ids.append(results.results.79.key.note_id)
|
||||||
|
case 80: note_ids.append(results.results.80.key.note_id)
|
||||||
|
case 81: note_ids.append(results.results.81.key.note_id)
|
||||||
|
case 82: note_ids.append(results.results.82.key.note_id)
|
||||||
|
case 83: note_ids.append(results.results.83.key.note_id)
|
||||||
|
case 84: note_ids.append(results.results.84.key.note_id)
|
||||||
|
case 85: note_ids.append(results.results.85.key.note_id)
|
||||||
|
case 86: note_ids.append(results.results.86.key.note_id)
|
||||||
|
case 87: note_ids.append(results.results.87.key.note_id)
|
||||||
|
case 88: note_ids.append(results.results.88.key.note_id)
|
||||||
|
case 89: note_ids.append(results.results.89.key.note_id)
|
||||||
|
case 90: note_ids.append(results.results.90.key.note_id)
|
||||||
|
case 91: note_ids.append(results.results.91.key.note_id)
|
||||||
|
case 92: note_ids.append(results.results.92.key.note_id)
|
||||||
|
case 93: note_ids.append(results.results.93.key.note_id)
|
||||||
|
case 94: note_ids.append(results.results.94.key.note_id)
|
||||||
|
case 95: note_ids.append(results.results.95.key.note_id)
|
||||||
|
case 96: note_ids.append(results.results.96.key.note_id)
|
||||||
|
case 97: note_ids.append(results.results.97.key.note_id)
|
||||||
|
case 98: note_ids.append(results.results.98.key.note_id)
|
||||||
|
case 99: note_ids.append(results.results.99.key.note_id)
|
||||||
|
case 100: note_ids.append(results.results.100.key.note_id)
|
||||||
|
case 101: note_ids.append(results.results.101.key.note_id)
|
||||||
|
case 102: note_ids.append(results.results.102.key.note_id)
|
||||||
|
case 103: note_ids.append(results.results.103.key.note_id)
|
||||||
|
case 104: note_ids.append(results.results.104.key.note_id)
|
||||||
|
case 105: note_ids.append(results.results.105.key.note_id)
|
||||||
|
case 106: note_ids.append(results.results.106.key.note_id)
|
||||||
|
case 107: note_ids.append(results.results.107.key.note_id)
|
||||||
|
case 108: note_ids.append(results.results.108.key.note_id)
|
||||||
|
case 109: note_ids.append(results.results.109.key.note_id)
|
||||||
|
case 110: note_ids.append(results.results.110.key.note_id)
|
||||||
|
case 111: note_ids.append(results.results.111.key.note_id)
|
||||||
|
case 112: note_ids.append(results.results.112.key.note_id)
|
||||||
|
case 113: note_ids.append(results.results.113.key.note_id)
|
||||||
|
case 114: note_ids.append(results.results.114.key.note_id)
|
||||||
|
case 115: note_ids.append(results.results.115.key.note_id)
|
||||||
|
case 116: note_ids.append(results.results.116.key.note_id)
|
||||||
|
case 117: note_ids.append(results.results.117.key.note_id)
|
||||||
|
case 118: note_ids.append(results.results.118.key.note_id)
|
||||||
|
case 119: note_ids.append(results.results.119.key.note_id)
|
||||||
|
case 120: note_ids.append(results.results.120.key.note_id)
|
||||||
|
case 121: note_ids.append(results.results.121.key.note_id)
|
||||||
|
case 122: note_ids.append(results.results.122.key.note_id)
|
||||||
|
case 123: note_ids.append(results.results.123.key.note_id)
|
||||||
|
case 124: note_ids.append(results.results.124.key.note_id)
|
||||||
|
case 125: note_ids.append(results.results.125.key.note_id)
|
||||||
|
case 126: note_ids.append(results.results.126.key.note_id)
|
||||||
|
case 127: note_ids.append(results.results.127.key.note_id)
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user