search: add damus search ui

This commit is contained in:
William Casarin
2023-12-03 22:13:46 -08:00
parent 0a9ac9cb0d
commit 4bf8a68c9c
4 changed files with 120 additions and 13 deletions

View File

@@ -67,7 +67,7 @@ struct ContentView: View {
@Environment(\.scenePhase) var scenePhase
@State var active_sheet: Sheets? = nil
@State var damus_state: DamusState? = nil
@State var damus_state: DamusState!
@SceneStorage("ContentView.selected_timeline") var selected_timeline: Timeline = .home
@State var muting: Pubkey? = nil
@State var confirm_mute: Bool = false
@@ -133,10 +133,8 @@ struct ContentView: View {
}
func contentTimelineView(filter: (@escaping (NostrEvent) -> Bool)) -> some View {
ZStack {
if let damus = self.damus_state {
TimelineView<AnyView>(events: home.events, loading: .constant(false), damus: damus, show_friend_icon: false, filter: filter)
}
TimelineView(events: home.events, loading: .constant(false), damus: damus_state, show_friend_icon: false, filter: filter) {
PullDownSearchView(state: damus_state, on_cancel: {})
}
}
@@ -202,12 +200,8 @@ struct ContentView: View {
func MaybeReportView(target: ReportTarget) -> some View {
Group {
if let damus_state {
if let keypair = damus_state.keypair.to_full() {
ReportView(postbox: damus_state.postbox, target: target, keypair: keypair)
} else {
EmptyView()
}
if let keypair = damus_state.keypair.to_full() {
ReportView(postbox: damus_state.postbox, target: target, keypair: keypair)
} else {
EmptyView()
}

View File

@@ -0,0 +1,110 @@
//
// PullDownSearch.swift
// damus
//
// Created by William Casarin on 2023-12-03.
//
import Foundation
import SwiftUI
struct PullDownSearchView: View {
@State private var search_text = ""
@State private var results: [NostrEvent] = []
@State private var is_active: Bool = false
let state: DamusState
let on_cancel: () -> Void
var body: some View {
VStack(alignment: .leading) {
HStack {
TextField("Search", text: $search_text)
.textFieldStyle(RoundedBorderTextFieldStyle())
.onChange(of: search_text) { newValue in
Task.detached {
let note_keys = state.ndb.text_search(query: newValue, limit: 16)
var res = [NostrEvent]()
// TODO: fix duplicate results from search
var keyset = Set<NoteKey>()
do {
let txn = NdbTxn(ndb: state.ndb)
for note_key in note_keys {
guard let note = 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_
}
}
}
.onTapGesture {
is_active = true
}
if is_active {
Button(action: {
search_text = ""
end_editing()
on_cancel()
}, label: {
Text("Cancel")
})
}
}
.padding()
if results.count > 0 {
HStack {
Image("search")
Text(NSLocalizedString("Top hits", comment: "A label indicating that the notes being displayed below it are all top note search results"))
Spacer()
}
.padding(.horizontal)
.foregroundColor(.secondary)
ForEach(results, id: \.self) { note in
EventView(damus: state, event: note)
.onTapGesture {
let event = note.get_inner_event(cache: state.events) ?? note
let thread = ThreadModel(event: event, damus_state: state)
state.nav.push(route: Route.Thread(thread: thread))
}
}
HStack {
Image("notes.fill")
Text(NSLocalizedString("Notes", comment: "A label indicating that the notes being displayed below it are from a timeline, not search results"))
Spacer()
}
.foregroundColor(.secondary)
.padding(.horizontal)
} else if results.count == 0 && !search_text.isEmpty {
HStack {
Image("search")
Text(NSLocalizedString("No results", comment: "A label indicating that note search resulted in no results"))
Spacer()
}
.padding(.horizontal)
.foregroundColor(.secondary)
}
}
}
}
struct PullDownSearchView_Previews: PreviewProvider {
static var previews: some View {
PullDownSearchView(state: test_damus_state, on_cancel: {})
}
}

View File

@@ -79,7 +79,7 @@ struct SearchHomeView: View {
AnyView(VStack {
SuggestedHashtagsView(damus_state: damus_state, max_items: 5, events: model.events)
HStack {
Image(systemName: "bubble.fill")
Image("notes.fill")
Text(NSLocalizedString("All recent notes", comment: "A label indicating that the notes being displayed below it are all recent notes"))
Spacer()
}