EventRef.swift (3523B)
1 // 2 // EventRef.swift 3 // damus 4 // 5 // Created by William Casarin on 2022-05-08. 6 // 7 8 import Foundation 9 10 enum EventRef: Equatable { 11 case mention(Mention<NoteRef>) 12 case thread_id(NoteRef) 13 case reply(NoteRef) 14 case reply_to_root(NoteRef) 15 16 var is_mention: NoteRef? { 17 if case .mention(let m) = self { return m.ref } 18 return nil 19 } 20 21 var is_direct_reply: NoteRef? { 22 switch self { 23 case .mention: 24 return nil 25 case .thread_id: 26 return nil 27 case .reply(let refid): 28 return refid 29 case .reply_to_root(let refid): 30 return refid 31 } 32 } 33 34 var is_thread_id: NoteRef? { 35 switch self { 36 case .mention: 37 return nil 38 case .thread_id(let referencedId): 39 return referencedId 40 case .reply: 41 return nil 42 case .reply_to_root(let referencedId): 43 return referencedId 44 } 45 } 46 47 var is_reply: NoteRef? { 48 switch self { 49 case .mention: 50 return nil 51 case .thread_id: 52 return nil 53 case .reply(let refid): 54 return refid 55 case .reply_to_root(let refid): 56 return refid 57 } 58 } 59 } 60 61 func build_mention_indices(_ blocks: [Block], type: MentionType) -> Set<Int> { 62 return blocks.reduce(into: []) { acc, block in 63 switch block { 64 case .mention(let m): 65 if m.ref.key == type, let idx = m.index { 66 acc.insert(idx) 67 } 68 case .relay: 69 return 70 case .text: 71 return 72 case .hashtag: 73 return 74 case .url: 75 return 76 case .invoice: 77 return 78 } 79 } 80 } 81 82 func interp_event_refs_without_mentions(_ refs: [NoteRef]) -> [EventRef] { 83 if refs.count == 0 { 84 return [] 85 } 86 87 if refs.count == 1 { 88 return [.reply_to_root(refs[0])] 89 } 90 91 var evrefs: [EventRef] = [] 92 var first: Bool = true 93 for ref in refs { 94 if first { 95 evrefs.append(.thread_id(ref)) 96 first = false 97 } else { 98 evrefs.append(.reply(ref)) 99 } 100 } 101 return evrefs 102 } 103 104 func interp_event_refs_with_mentions(tags: Tags, mention_indices: Set<Int>) -> [EventRef] { 105 var mentions: [EventRef] = [] 106 var ev_refs: [NoteRef] = [] 107 var i: Int = 0 108 109 for tag in tags { 110 if let ref = NoteRef.from_tag(tag: tag) { 111 if mention_indices.contains(i) { 112 let mention = Mention<NoteRef>(index: i, ref: ref) 113 mentions.append(.mention(mention)) 114 } else { 115 ev_refs.append(ref) 116 } 117 } 118 i += 1 119 } 120 121 var replies = interp_event_refs_without_mentions(ev_refs) 122 replies.append(contentsOf: mentions) 123 return replies 124 } 125 126 func interpret_event_refs(blocks: [Block], tags: Tags) -> [EventRef] { 127 if tags.count == 0 { 128 return [] 129 } 130 131 /// build a set of indices for each event mention 132 let mention_indices = build_mention_indices(blocks, type: .e) 133 134 /// simpler case with no mentions 135 if mention_indices.count == 0 { 136 return interp_event_refs_without_mentions_ndb(References<NoteRef>(tags: tags)) 137 } 138 139 return interp_event_refs_with_mentions(tags: tags, mention_indices: mention_indices) 140 } 141 142 143 func event_is_reply(_ refs: [EventRef]) -> Bool { 144 return refs.contains { evref in 145 return evref.is_reply != nil 146 } 147 }