1
0
mirror of git://jb55.com/damus synced 2024-09-30 00:40:45 +00:00

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

@ -260,6 +260,7 @@
4C9B0DF32A65C46800CBDA21 /* ProfileEditButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9B0DF22A65C46800CBDA21 /* ProfileEditButton.swift */; };
4C9BB83129C0ED4F00FC4E37 /* DisplayName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */; };
4C9BB83429C12D9900FC4E37 /* EventProfileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83329C12D9900FC4E37 /* EventProfileName.swift */; };
4C9D6D1B2B1D35D7004E5CD9 /* PullDownSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9D6D1A2B1D35D7004E5CD9 /* PullDownSearch.swift */; };
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9F18E129AA9B6C008C55EC /* CustomizeZapView.swift */; };
4C9F18E429ABDE6D008C55EC /* MaybeAnonPfpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9F18E329ABDE6D008C55EC /* MaybeAnonPfpView.swift */; };
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */; };
@ -1057,6 +1058,7 @@
4C9B0DF22A65C46800CBDA21 /* ProfileEditButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEditButton.swift; sourceTree = "<group>"; };
4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayName.swift; sourceTree = "<group>"; };
4C9BB83329C12D9900FC4E37 /* EventProfileName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventProfileName.swift; sourceTree = "<group>"; };
4C9D6D1A2B1D35D7004E5CD9 /* PullDownSearch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PullDownSearch.swift; sourceTree = "<group>"; };
4C9F18E129AA9B6C008C55EC /* CustomizeZapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomizeZapView.swift; sourceTree = "<group>"; };
4C9F18E329ABDE6D008C55EC /* MaybeAnonPfpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MaybeAnonPfpView.swift; sourceTree = "<group>"; };
4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineView.swift; sourceTree = "<group>"; };
@ -2188,6 +2190,7 @@
children = (
4CCEB7AD29B53D260078AA28 /* SearchingEventView.swift */,
4CCEB7AF29B5415A0078AA28 /* SearchingProfileView.swift */,
4C9D6D1A2B1D35D7004E5CD9 /* PullDownSearch.swift */,
);
path = Search;
sourceTree = "<group>";
@ -2867,7 +2870,6 @@
4C32B9582A9AD44700DC3548 /* VeriferOptions.swift in Sources */,
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */,
4C30AC7629A5770900E2BD5A /* NotificationItemView.swift in Sources */,
BA3759972ABCCF360018D73B /* CameraPreview.swift in Sources */,
4C86F7C42A76C44C00EC0817 /* ZappingNotify.swift in Sources */,
4C363A8428233689006E126D /* Parser.swift in Sources */,
3AAA95CA298DF87B00F3D526 /* TranslationService.swift in Sources */,
@ -2952,6 +2954,7 @@
4CACA9DC280C38C000D9BBE8 /* Profiles.swift in Sources */,
4CE879582996C45300F758CC /* ZapsView.swift in Sources */,
4C30AC7429A5680900E2BD5A /* EventGroupView.swift in Sources */,
4C9D6D1B2B1D35D7004E5CD9 /* PullDownSearch.swift in Sources */,
4C633352283D419F00B1C9C3 /* SignalModel.swift in Sources */,
4CFF8F6D29CD022E008DB934 /* WideEventView.swift in Sources */,
9609F058296E220800069BF3 /* BannerImageView.swift in Sources */,

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()
}