RelayFilters.swift (2678B)
1 // 2 // RelayFilters.swift 3 // damus 4 // 5 // Created by William Casarin on 2023-02-08. 6 // 7 8 import Foundation 9 10 struct RelayFilter: Hashable { 11 let timeline: Timeline 12 let relay_id: RelayURL 13 14 init(timeline: Timeline, relay_id: RelayURL) { 15 self.timeline = timeline 16 self.relay_id = relay_id 17 } 18 } 19 20 class RelayFilters { 21 private let our_pubkey: Pubkey 22 private var disabled: Set<RelayFilter> 23 24 func is_filtered(timeline: Timeline, relay_id: RelayURL) -> Bool { 25 let filter = RelayFilter(timeline: timeline, relay_id: relay_id) 26 let contains = disabled.contains(filter) 27 return contains 28 } 29 30 func remove(timeline: Timeline, relay_id: RelayURL) { 31 let filter = RelayFilter(timeline: timeline, relay_id: relay_id) 32 if !disabled.contains(filter) { 33 return 34 } 35 36 disabled.remove(filter) 37 save_relay_filters(our_pubkey, filters: disabled) 38 } 39 40 func insert(timeline: Timeline, relay_id: RelayURL) { 41 let filter = RelayFilter(timeline: timeline, relay_id: relay_id) 42 if disabled.contains(filter) { 43 return 44 } 45 46 disabled.insert(filter) 47 save_relay_filters(our_pubkey, filters: disabled) 48 } 49 50 init(our_pubkey: Pubkey) { 51 self.our_pubkey = our_pubkey 52 disabled = load_relay_filters(our_pubkey) ?? Set() 53 } 54 } 55 56 func save_relay_filters(_ pubkey: Pubkey, filters: Set<RelayFilter>) { 57 let key = pk_setting_key(pubkey, key: "relay_filters") 58 let arr = Array(filters.map { filter in "\(filter.timeline)\t\(filter.relay_id)" }) 59 UserDefaults.standard.set(arr, forKey: key) 60 } 61 62 func relay_filter_setting_key(_ pubkey: Pubkey) -> String { 63 return pk_setting_key(pubkey, key: "relay_filters") 64 } 65 66 func load_relay_filters(_ pubkey: Pubkey) -> Set<RelayFilter>? { 67 let key = relay_filter_setting_key(pubkey) 68 guard let filters = UserDefaults.standard.stringArray(forKey: key) else { 69 return nil 70 } 71 72 return filters.reduce(into: Set()) { s, str in 73 let parts = str.components(separatedBy: "\t") 74 guard parts.count == 2 else { 75 return 76 } 77 guard let timeline = Timeline.init(rawValue: parts[0]) else { 78 return 79 } 80 guard let relay_id = RelayURL(parts[1]) else { 81 return 82 } 83 let filter = RelayFilter(timeline: timeline, relay_id: relay_id) 84 s.insert(filter) 85 } 86 } 87 88 func determine_to_relays(pool: RelayPool, filters: RelayFilters) -> [RelayURL] { 89 return pool.our_descriptors 90 .map { $0.url } 91 .filter { !filters.is_filtered(timeline: .search, relay_id: $0) } 92 }