This change includes several source files related to NostrDB into the extension target as well, so that we can use it from that context (and thus enable more advanced push notification formatting and suppression) To make this change possible, I had to split some source files as well as to move some functions to different files, to ensure we don't have to pull too much unnecessary code into the extension. Testing ------- PASS Device: iPhone 15 Pro simulator iOS: 17.0.1 Damus: This commit Test steps: 1. Build DamusNotificationService. Should succeed. PASS 2. Build Damus (the app). PASS 3. Run app, scroll around some notes, go to a few different views, post a note. Should work as normal. PASS
148 lines
3.4 KiB
Swift
148 lines
3.4 KiB
Swift
//
|
|
// EventRef.swift
|
|
// damus
|
|
//
|
|
// Created by William Casarin on 2022-05-08.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
enum EventRef: Equatable {
|
|
case mention(Mention<NoteRef>)
|
|
case thread_id(NoteRef)
|
|
case reply(NoteRef)
|
|
case reply_to_root(NoteRef)
|
|
|
|
var is_mention: NoteRef? {
|
|
if case .mention(let m) = self { return m.ref }
|
|
return nil
|
|
}
|
|
|
|
var is_direct_reply: NoteRef? {
|
|
switch self {
|
|
case .mention:
|
|
return nil
|
|
case .thread_id:
|
|
return nil
|
|
case .reply(let refid):
|
|
return refid
|
|
case .reply_to_root(let refid):
|
|
return refid
|
|
}
|
|
}
|
|
|
|
var is_thread_id: NoteRef? {
|
|
switch self {
|
|
case .mention:
|
|
return nil
|
|
case .thread_id(let referencedId):
|
|
return referencedId
|
|
case .reply:
|
|
return nil
|
|
case .reply_to_root(let referencedId):
|
|
return referencedId
|
|
}
|
|
}
|
|
|
|
var is_reply: NoteRef? {
|
|
switch self {
|
|
case .mention:
|
|
return nil
|
|
case .thread_id:
|
|
return nil
|
|
case .reply(let refid):
|
|
return refid
|
|
case .reply_to_root(let refid):
|
|
return refid
|
|
}
|
|
}
|
|
}
|
|
|
|
func build_mention_indices(_ blocks: [Block], type: MentionType) -> Set<Int> {
|
|
return blocks.reduce(into: []) { acc, block in
|
|
switch block {
|
|
case .mention(let m):
|
|
if m.ref.key == type, let idx = m.index {
|
|
acc.insert(idx)
|
|
}
|
|
case .relay:
|
|
return
|
|
case .text:
|
|
return
|
|
case .hashtag:
|
|
return
|
|
case .url:
|
|
return
|
|
case .invoice:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func interp_event_refs_without_mentions(_ refs: [NoteRef]) -> [EventRef] {
|
|
if refs.count == 0 {
|
|
return []
|
|
}
|
|
|
|
if refs.count == 1 {
|
|
return [.reply_to_root(refs[0])]
|
|
}
|
|
|
|
var evrefs: [EventRef] = []
|
|
var first: Bool = true
|
|
for ref in refs {
|
|
if first {
|
|
evrefs.append(.thread_id(ref))
|
|
first = false
|
|
} else {
|
|
evrefs.append(.reply(ref))
|
|
}
|
|
}
|
|
return evrefs
|
|
}
|
|
|
|
func interp_event_refs_with_mentions(tags: Tags, mention_indices: Set<Int>) -> [EventRef] {
|
|
var mentions: [EventRef] = []
|
|
var ev_refs: [NoteRef] = []
|
|
var i: Int = 0
|
|
|
|
for tag in tags {
|
|
if let ref = NoteRef.from_tag(tag: tag) {
|
|
if mention_indices.contains(i) {
|
|
let mention = Mention<NoteRef>(index: i, ref: ref)
|
|
mentions.append(.mention(mention))
|
|
} else {
|
|
ev_refs.append(ref)
|
|
}
|
|
}
|
|
i += 1
|
|
}
|
|
|
|
var replies = interp_event_refs_without_mentions(ev_refs)
|
|
replies.append(contentsOf: mentions)
|
|
return replies
|
|
}
|
|
|
|
func interpret_event_refs(blocks: [Block], tags: Tags) -> [EventRef] {
|
|
if tags.count == 0 {
|
|
return []
|
|
}
|
|
|
|
/// build a set of indices for each event mention
|
|
let mention_indices = build_mention_indices(blocks, type: .e)
|
|
|
|
/// simpler case with no mentions
|
|
if mention_indices.count == 0 {
|
|
return interp_event_refs_without_mentions_ndb(References<NoteRef>(tags: tags))
|
|
}
|
|
|
|
return interp_event_refs_with_mentions(tags: tags, mention_indices: mention_indices)
|
|
}
|
|
|
|
|
|
func event_is_reply(_ refs: [EventRef]) -> Bool {
|
|
return refs.contains { evref in
|
|
return evref.is_reply != nil
|
|
}
|
|
}
|