SearchHomeView working

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2022-06-06 19:26:44 -07:00
parent 2fc6e7ef22
commit dff12702f5
6 changed files with 187 additions and 6 deletions

View File

@@ -104,7 +104,7 @@ struct ContentView: View {
}
switch selected_timeline {
case .search:
SearchHomeView()
SearchHomeView(damus_state: damus_state!, model: SearchHomeModel(pool: damus_state!.pool) )
case .home:
PostingTimelineView

View File

@@ -0,0 +1,60 @@
//
// SearchHomeModel.swift
// damus
//
// Created by William Casarin on 2022-06-06.
//
import Foundation
/// The data model for the SearchHome view, typically something global-like
class SearchHomeModel: ObservableObject {
@Published var events: [NostrEvent] = []
let pool: RelayPool
let sub_id = UUID().description
let limit: UInt32 = 1000
init(pool: RelayPool) {
self.pool = pool
}
func get_base_filter() -> NostrFilter {
var filter = NostrFilter.filter_text
filter.limit = self.limit
filter.until = Int64(Date.now.timeIntervalSince1970)
return filter
}
func subscribe() {
pool.subscribe(sub_id: sub_id, filters: [get_base_filter()], handler: handle_event)
}
func unsubscribe() {
pool.unsubscribe(sub_id: sub_id)
}
func handle_event(relay_id: String, conn_ev: NostrConnectionEvent) {
switch conn_ev {
case .ws_event:
break
case .nostr_event(let event):
switch event {
case .event(let sub_id, let ev):
guard sub_id == self.sub_id else {
return
}
guard self.events.count <= limit else {
return
}
if ev.kind == NostrKind.text.rawValue {
let _ = insert_uniq_sorted_event(events: &events, new_ev: ev) {
$0.created_at > $1.created_at
}
}
case .notice(let msg):
print("search home notice: \(msg)")
}
}
}
}

View File

@@ -6,15 +6,68 @@
//
import SwiftUI
import CryptoKit
struct SearchHomeView: View {
let damus_state: DamusState
@StateObject var model: SearchHomeModel
@State var search: String = ""
var SearchInput: some View {
ZStack(alignment: .leading) {
TextField("", text: $search)
.padding(5)
.padding(.leading, 35)
.textInputAutocapitalization(.never)
Label("", systemImage: "magnifyingglass")
.padding(.leading, 10)
}
.background {
RoundedRectangle(cornerRadius: 20)
.foregroundColor(.gray.opacity(0.2))
}
.padding()
}
var GlobalContent: some View {
TimelineView(events: $model.events, damus: damus_state)
}
var SearchContent: some View {
SearchResultsView(damus_state: damus_state, search: $search)
}
var MainContent: some View {
Group {
if search.isEmpty {
GlobalContent
} else {
SearchContent
}
}
}
var body: some View {
Text("Search Home")
VStack {
SearchInput
MainContent
}
.onAppear {
model.subscribe()
}
.onDisappear {
model.unsubscribe()
}
}
}
struct SearchHomeView_Previews: PreviewProvider {
static var previews: some View {
SearchHomeView()
let state = test_damus_state()
SearchHomeView(
damus_state: state,
model: SearchHomeModel(pool: state.pool)
)
}
}

View File

@@ -0,0 +1,57 @@
//
// SearchResultsView.swift
// damus
//
// Created by William Casarin on 2022-06-06.
//
import SwiftUI
struct SearchResultsView: View {
let damus_state: DamusState
@Binding var search: String
@State var results: [(String, Profile)] = []
func ProfileSearchResult(pk: String, res: Profile) -> some View {
FollowUserView(target: .pubkey(pk), damus_state: damus_state)
}
var MainContent: some View {
VStack {
ForEach(results, id: \.0) { prof in
ProfileSearchResult(pk: prof.0, res: prof.1)
}
Spacer()
}
}
func search_changed(_ new: String) {
let profs = damus_state.profiles.profiles.enumerated()
self.results = 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 lowdisp = prof.display_name.map { $0.lowercased() }
let ok = new == pk || String(new.dropFirst()) == pk
|| lowname?.contains(new) ?? false
|| lowdisp?.contains(new) ?? false
if ok {
acc.append((pk, prof))
}
}
}
var body: some View {
MainContent
.frame(maxHeight: .infinity)
.onChange(of: search) { new in search_changed(new) }
}
}
struct SearchResultsView_Previews: PreviewProvider {
static var previews: some View {
let search = Binding<String>.init(get: { "jb55" }, set: { _ in })
SearchResultsView(damus_state: test_damus_state(), search: search)
}
}

View File

@@ -37,10 +37,13 @@ func describe_search(_ filter: NostrFilter) -> String {
return "Search"
}
/*
struct SearchView_Previews: PreviewProvider {
static var previews: some View {
SearchView()
let test_state = test_damus_state()
let filter = NostrFilter.filter_hashtag(["bitcoin"])
let pool = test_state.pool
let model = SearchModel(pool: pool, search: filter)
SearchView(appstate: test_state, search: model)
}
}
*/