SearchHomeView.swift (5067B)
1 // 2 // SearchHomeView.swift 3 // damus 4 // 5 // Created by William Casarin on 2022-05-19. 6 // 7 8 import SwiftUI 9 import CryptoKit 10 import NaturalLanguage 11 12 struct SearchHomeView: View { 13 let damus_state: DamusState 14 @StateObject var model: SearchHomeModel 15 @State var search: String = "" 16 @FocusState private var isFocused: Bool 17 18 var content_filter: (NostrEvent) -> Bool { 19 let filters = ContentFilters.defaults(damus_state: self.damus_state) 20 return ContentFilters(filters: filters).filter 21 } 22 23 let preferredLanguages = Set(Locale.preferredLanguages.map { localeToLanguage($0) }) 24 25 var SearchInput: some View { 26 HStack { 27 HStack{ 28 Image("search") 29 .foregroundColor(.gray) 30 TextField(NSLocalizedString("Search...", comment: "Placeholder text to prompt entry of search query."), text: $search) 31 .autocorrectionDisabled(true) 32 .textInputAutocapitalization(.never) 33 .focused($isFocused) 34 } 35 .padding(10) 36 .background(.secondary.opacity(0.2)) 37 .cornerRadius(20) 38 39 if(!search.isEmpty) { 40 Text("Cancel", comment: "Cancel out of search view.") 41 .foregroundColor(.accentColor) 42 .padding(EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 10.0)) 43 .onTapGesture { 44 self.search = "" 45 isFocused = false 46 } 47 } 48 } 49 } 50 51 var GlobalContent: some View { 52 return TimelineView<AnyView>( 53 events: model.events, 54 loading: $model.loading, 55 damus: damus_state, 56 show_friend_icon: true, 57 filter: { ev in 58 if !content_filter(ev) { 59 return false 60 } 61 62 let event_muted = damus_state.mutelist_manager.is_event_muted(ev) 63 if event_muted { 64 return false 65 } 66 67 if damus_state.settings.show_only_preferred_languages == false { 68 return true 69 } 70 71 // If we can't determine the note's language with 50%+ confidence, lean on the side of caution and show it anyway. 72 let note_lang = damus_state.events.get_cache_data(ev.id).translations_model.note_language 73 guard let note_lang else { 74 return true 75 } 76 77 return preferredLanguages.contains(note_lang) 78 }, 79 content: { 80 AnyView(VStack { 81 SuggestedHashtagsView(damus_state: damus_state, max_items: 5, events: model.events) 82 83 Divider() 84 .frame(height: 1) 85 86 HStack { 87 Image("notes.fill") 88 Text("All recent notes", comment: "A label indicating that the notes being displayed below it are all recent notes") 89 Spacer() 90 } 91 .foregroundColor(.secondary) 92 .padding(.top, 20) 93 .padding(.horizontal) 94 }) 95 } 96 ) 97 .refreshable { 98 // Fetch new information by unsubscribing and resubscribing to the relay 99 model.unsubscribe() 100 model.subscribe() 101 } 102 } 103 104 var SearchContent: some View { 105 SearchResultsView(damus_state: damus_state, search: $search) 106 .refreshable { 107 // Fetch new information by unsubscribing and resubscribing to the relay 108 model.unsubscribe() 109 model.subscribe() 110 } 111 } 112 113 var MainContent: some View { 114 Group { 115 if search.isEmpty { 116 GlobalContent 117 } else { 118 SearchContent 119 } 120 } 121 } 122 123 @Environment(\.colorScheme) var colorScheme 124 125 var body: some View { 126 VStack { 127 MainContent 128 } 129 .safeAreaInset(edge: .top, spacing: 0) { 130 VStack(spacing: 0) { 131 SearchInput 132 //.frame(maxWidth: 275) 133 .padding() 134 Divider() 135 .frame(height: 1) 136 } 137 .background(colorScheme == .dark ? Color.black : Color.white) 138 } 139 .onReceive(handle_notify(.new_mutes)) { _ in 140 self.model.filter_muted() 141 } 142 .onAppear { 143 if model.events.events.isEmpty { 144 model.subscribe() 145 } 146 } 147 .onDisappear { 148 model.unsubscribe() 149 } 150 } 151 } 152 153 struct SearchHomeView_Previews: PreviewProvider { 154 static var previews: some View { 155 let state = test_damus_state 156 SearchHomeView(damus_state: state, model: SearchHomeModel(damus_state: state)) 157 } 158 }