Files
damus/damus/Features/Search/Views/SearchHomeView.swift
Daniel D’Aquino 578d47356d Make RelayPool private to NostrNetworkManager and migrate usages
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
2025-09-24 14:06:02 -07:00

148 lines
4.9 KiB
Swift

//
// SearchHomeView.swift
// damus
//
// Created by William Casarin on 2022-05-19.
//
import SwiftUI
import CryptoKit
import NaturalLanguage
struct SearchHomeView: View {
let damus_state: DamusState
@StateObject var model: SearchHomeModel
@State var search: String = ""
@FocusState private var isFocused: Bool
@State var loadingTask: Task<Void, Never>?
func content_filter(_ fstate: FilterState) -> ((NostrEvent) -> Bool) {
var filters = ContentFilters.defaults(damus_state: damus_state)
filters.append(fstate.filter)
return ContentFilters(filters: filters).filter
}
var SearchInput: some View {
HStack {
HStack{
Image("search")
.foregroundColor(.gray)
TextField(NSLocalizedString("Search...", comment: "Placeholder text to prompt entry of search query."), text: $search)
.autocorrectionDisabled(true)
.textInputAutocapitalization(.never)
.focused($isFocused)
}
.padding(10)
.background(.secondary.opacity(0.2))
.cornerRadius(20)
if(!search.isEmpty) {
Text("Cancel", comment: "Cancel out of search view.")
.foregroundColor(.accentColor)
.padding(EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 10.0))
.onTapGesture {
self.search = ""
isFocused = false
}
}
}
}
var GlobalContent: some View {
return TimelineView<AnyView>(
events: model.events,
loading: $model.loading,
damus: damus_state,
show_friend_icon: true,
filter:content_filter(FilterState.posts),
content: {
AnyView(VStack(alignment: .leading) {
HStack {
Image(systemName: "sparkles")
.foregroundStyle(PinkGradient)
Text("Follow Packs", comment: "A label indicating that the items below it are follow packs")
.foregroundStyle(PinkGradient)
}
.padding(.top)
.padding(.horizontal)
FollowPackTimelineView<AnyView>(events: model.events, loading: $model.loading, damus: damus_state, show_friend_icon: true,filter:content_filter(FilterState.follow_list)
).padding(.bottom)
Divider()
.frame(height: 1)
HStack {
Image("notes.fill")
Text("All recent notes", comment: "A label indicating that the notes being displayed below it are all recent notes")
Spacer()
}
.foregroundColor(.secondary)
.padding(.top, 20)
.padding(.horizontal)
}.padding(.bottom, 50))
}
)
.refreshable {
// Fetch new information by unsubscribing and resubscribing to the relay
loadingTask?.cancel()
loadingTask = Task { await model.load() }
}
}
var SearchContent: some View {
SearchResultsView(damus_state: damus_state, search: $search)
.refreshable {
// Fetch new information by unsubscribing and resubscribing to the relay
loadingTask?.cancel()
loadingTask = Task { await model.load() }
}
}
var MainContent: some View {
Group {
if search.isEmpty {
GlobalContent
} else {
SearchContent
}
}
}
@Environment(\.colorScheme) var colorScheme
var body: some View {
VStack {
MainContent
}
.safeAreaInset(edge: .top, spacing: 0) {
VStack(spacing: 0) {
SearchInput
//.frame(maxWidth: 275)
.padding()
Divider()
.frame(height: 1)
}
.background(colorScheme == .dark ? Color.black : Color.white)
}
.onReceive(handle_notify(.new_mutes)) { _ in
self.model.filter_muted()
}
.onAppear {
if model.events.events.isEmpty {
loadingTask = Task { await model.load() }
}
}
.onDisappear {
loadingTask?.cancel()
}
}
}
struct SearchHomeView_Previews: PreviewProvider {
static var previews: some View {
let state = test_damus_state
SearchHomeView(damus_state: state, model: SearchHomeModel(damus_state: state))
}
}