damus

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

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 }