damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

SearchView.swift (5700B)


      1 //
      2 //  SearchView.swift
      3 //  damus
      4 //
      5 //  Created by William Casarin on 2022-05-09.
      6 //
      7 
      8 import SwiftUI
      9 
     10 struct SearchView: View {
     11     let appstate: DamusState
     12     @ObservedObject var search: SearchModel
     13     @Environment(\.dismiss) var dismiss
     14     @State var is_hashtag_muted: Bool = false
     15 
     16     var content_filter: (NostrEvent) -> Bool {
     17         let filters = ContentFilters.defaults(damus_state: self.appstate)
     18         return ContentFilters(filters: filters).filter
     19     }
     20 
     21     let height: CGFloat = 250.0
     22 
     23     var body: some View {
     24         TimelineView(events: search.events, loading: $search.loading, damus: appstate, show_friend_icon: true, filter: content_filter) {
     25             ZStack(alignment: .leading) {
     26                 DamusBackground(maxHeight: height)
     27                     .mask(LinearGradient(gradient: Gradient(colors: [.black, .black, .black, .clear]), startPoint: .top, endPoint: .bottom))
     28                 SearchHeaderView(state: appstate, described: described_search)
     29                     .padding(.leading, 30)
     30                     .padding(.top, 100)
     31             }
     32         }
     33         .ignoresSafeArea()
     34         .onReceive(handle_notify(.switched_timeline)) { obj in
     35             dismiss()
     36         }
     37         .onAppear() {
     38             search.subscribe()
     39         }
     40         .onDisappear() {
     41             search.unsubscribe()
     42         }
     43         .onReceive(handle_notify(.new_mutes)) { notif in
     44             search.filter_muted()
     45 
     46             if let hashtag_string = search.search.hashtag?.first,
     47                notif.contains(MuteItem.hashtag(Hashtag(hashtag: hashtag_string), nil)) {
     48                 is_hashtag_muted = true
     49             }
     50         }
     51         .onReceive(handle_notify(.new_unmutes)) { unmutes in
     52             if let hashtag_string = search.search.hashtag?.first,
     53                unmutes.contains(MuteItem.hashtag(Hashtag(hashtag: hashtag_string), nil)) {
     54                 is_hashtag_muted = false
     55             }
     56         }
     57         .toolbar {
     58             if let hashtag = search.search.hashtag?.first {
     59                 ToolbarItem(placement: .topBarTrailing) {
     60                     Menu {
     61                         if is_hashtag_muted {
     62                             Button {
     63                                 guard
     64                                     let full_keypair = appstate.keypair.to_full(),
     65                                     let existing_mutelist = appstate.mutelist_manager.event,
     66                                     let mutelist = remove_from_mutelist(keypair: full_keypair, prev: existing_mutelist, to_remove: .hashtag(Hashtag(hashtag: hashtag), nil))
     67                                 else {
     68                                     return
     69                                 }
     70 
     71                                 appstate.mutelist_manager.set_mutelist(mutelist)
     72                                 appstate.postbox.send(mutelist)
     73                             } label: {
     74                                 Text("Unmute Hashtag", comment: "Label represnting a button that the user can tap to unmute a given hashtag so they start seeing it in their feed again.")
     75                             }
     76                         } else {
     77                             MuteDurationMenu { duration in
     78                                 mute_hashtag(hashtag_string: hashtag, expiration_time: duration?.date_from_now)
     79                             } label: {
     80                                 Text("Mute Hashtag", comment: "Label represnting a button that the user can tap to mute a given hashtag so they don't see it in their feed anymore.")
     81                             }
     82                         }
     83                     } label: {
     84                         Image(systemName: "ellipsis")
     85                     }
     86                 }
     87             }
     88         }
     89         .onAppear {
     90             if let hashtag_string = search.search.hashtag?.first {
     91                 is_hashtag_muted = (appstate.mutelist_manager.event?.mute_list ?? []).contains(MuteItem.hashtag(Hashtag(hashtag: hashtag_string), nil))
     92             }
     93         }
     94     }
     95 
     96     func mute_hashtag(hashtag_string: String, expiration_time: Date?) {
     97         let existing_mutelist = appstate.mutelist_manager.event
     98 
     99         guard
    100             let full_keypair = appstate.keypair.to_full(),
    101             let mutelist = create_or_update_mutelist(keypair: full_keypair, mprev: existing_mutelist, to_add: .hashtag(Hashtag(hashtag: hashtag_string), expiration_time))
    102         else {
    103             return
    104         }
    105 
    106         appstate.mutelist_manager.set_mutelist(mutelist)
    107         appstate.postbox.send(mutelist)
    108     }
    109 
    110     var described_search: DescribedSearch {
    111         return describe_search(search.search)
    112     }
    113 }
    114 
    115 enum DescribedSearch: CustomStringConvertible {
    116     case hashtag(String)
    117     case unknown
    118 
    119     var is_hashtag: String? {
    120         switch self {
    121         case .hashtag(let ht):
    122             return ht
    123         case .unknown:
    124             return nil
    125         }
    126     }
    127 
    128     var description: String {
    129         switch self {
    130         case .hashtag(let s):
    131             return "#" + s
    132         case .unknown:
    133             return NSLocalizedString("Search", comment: "Default title for the search screen when it is in an unknown state.")
    134         }
    135     }
    136 }
    137 
    138 func describe_search(_ filter: NostrFilter) -> DescribedSearch {
    139     if let hashtags = filter.hashtag {
    140         if hashtags.count >= 1 {
    141             return .hashtag(hashtags[0])
    142         }
    143     }
    144 
    145     return .unknown
    146 }
    147 
    148 struct SearchView_Previews: PreviewProvider {
    149     static var previews: some View {
    150         let test_state = test_damus_state
    151         let filter = NostrFilter(hashtag: ["bitcoin"])
    152         
    153         let model = SearchModel(state: test_state, search: filter)
    154         
    155         SearchView(appstate: test_state, search: model)
    156     }
    157 }