mirror of
git://jb55.com/damus
synced 2024-09-30 00:40:45 +00:00
Revert "Move the Block helper type to its own file"
This fixes the broken tests
This reverts commit 286ae68fd6
.
This commit is contained in:
parent
7255481705
commit
f30f93f65c
@ -375,7 +375,6 @@
|
|||||||
643EA5C8296B764E005081BB /* RelayFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643EA5C7296B764E005081BB /* RelayFilterView.swift */; };
|
643EA5C8296B764E005081BB /* RelayFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643EA5C7296B764E005081BB /* RelayFilterView.swift */; };
|
||||||
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647D9A8C2968520300A295DE /* SideMenuView.swift */; };
|
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647D9A8C2968520300A295DE /* SideMenuView.swift */; };
|
||||||
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FBD06E296255C400D9D3B2 /* Theme.swift */; };
|
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FBD06E296255C400D9D3B2 /* Theme.swift */; };
|
||||||
7527271E2A93FF0100214108 /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7527271D2A93FF0100214108 /* Block.swift */; };
|
|
||||||
7C60CAEF298471A1009C80D6 /* CoreSVG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C60CAEE298471A1009C80D6 /* CoreSVG.swift */; };
|
7C60CAEF298471A1009C80D6 /* CoreSVG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C60CAEE298471A1009C80D6 /* CoreSVG.swift */; };
|
||||||
7C902AE32981D55B002AB16E /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */; };
|
7C902AE32981D55B002AB16E /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */; };
|
||||||
7C95CAEE299DCEF1009DCB67 /* KFOptionSetter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */; };
|
7C95CAEE299DCEF1009DCB67 /* KFOptionSetter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */; };
|
||||||
@ -934,7 +933,6 @@
|
|||||||
643EA5C7296B764E005081BB /* RelayFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayFilterView.swift; sourceTree = "<group>"; };
|
643EA5C7296B764E005081BB /* RelayFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayFilterView.swift; sourceTree = "<group>"; };
|
||||||
647D9A8C2968520300A295DE /* SideMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenuView.swift; sourceTree = "<group>"; };
|
647D9A8C2968520300A295DE /* SideMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenuView.swift; sourceTree = "<group>"; };
|
||||||
64FBD06E296255C400D9D3B2 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
64FBD06E296255C400D9D3B2 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
||||||
7527271D2A93FF0100214108 /* Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Block.swift; sourceTree = "<group>"; };
|
|
||||||
7C60CAEE298471A1009C80D6 /* CoreSVG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreSVG.swift; sourceTree = "<group>"; };
|
7C60CAEE298471A1009C80D6 /* CoreSVG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreSVG.swift; sourceTree = "<group>"; };
|
||||||
7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableScrollView.swift; sourceTree = "<group>"; };
|
7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableScrollView.swift; sourceTree = "<group>"; };
|
||||||
7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KFOptionSetter+.swift"; sourceTree = "<group>"; };
|
7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KFOptionSetter+.swift"; sourceTree = "<group>"; };
|
||||||
@ -1607,7 +1605,6 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4CC14FED2A73FCBB007AEB17 /* Ids */,
|
4CC14FED2A73FCBB007AEB17 /* Ids */,
|
||||||
7527271D2A93FF0100214108 /* Block.swift */,
|
|
||||||
);
|
);
|
||||||
path = Types;
|
path = Types;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2423,7 +2420,6 @@
|
|||||||
7CFF6317299FEFE5005D382A /* SelectableText.swift in Sources */,
|
7CFF6317299FEFE5005D382A /* SelectableText.swift in Sources */,
|
||||||
4CA352A82A76B37E003BB08B /* NewMutesNotify.swift in Sources */,
|
4CA352A82A76B37E003BB08B /* NewMutesNotify.swift in Sources */,
|
||||||
4CFF8F6929CC9ED1008DB934 /* ImageContainerView.swift in Sources */,
|
4CFF8F6929CC9ED1008DB934 /* ImageContainerView.swift in Sources */,
|
||||||
7527271E2A93FF0100214108 /* Block.swift in Sources */,
|
|
||||||
4C54AA0729A540BA003E4487 /* NotificationsModel.swift in Sources */,
|
4C54AA0729A540BA003E4487 /* NotificationsModel.swift in Sources */,
|
||||||
4C12536C2A76D4B00004F4B8 /* RepostedNotify.swift in Sources */,
|
4C12536C2A76D4B00004F4B8 /* RepostedNotify.swift in Sources */,
|
||||||
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */,
|
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */,
|
||||||
|
@ -27,7 +27,7 @@ func parsed_blocks_finish(bs: inout note_blocks, tags: TagsSequence?) -> Blocks
|
|||||||
while (i < bs.num_blocks) {
|
while (i < bs.num_blocks) {
|
||||||
let block = bs.blocks[i]
|
let block = bs.blocks[i]
|
||||||
|
|
||||||
if let converted = Block(block, tags: tags) {
|
if let converted = convert_block(block, tags: tags) {
|
||||||
out.append(converted)
|
out.append(converted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,11 +123,147 @@ struct LightningInvoice<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Block: Equatable {
|
||||||
|
static func == (lhs: Block, rhs: Block) -> Bool {
|
||||||
|
switch (lhs, rhs) {
|
||||||
|
case (.text(let a), .text(let b)):
|
||||||
|
return a == b
|
||||||
|
case (.mention(let a), .mention(let b)):
|
||||||
|
return a == b
|
||||||
|
case (.hashtag(let a), .hashtag(let b)):
|
||||||
|
return a == b
|
||||||
|
case (.url(let a), .url(let b)):
|
||||||
|
return a == b
|
||||||
|
case (.invoice(let a), .invoice(let b)):
|
||||||
|
return a.string == b.string
|
||||||
|
case (_, _):
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case text(String)
|
||||||
|
case mention(Mention<MentionRef>)
|
||||||
|
case hashtag(String)
|
||||||
|
case url(URL)
|
||||||
|
case invoice(Invoice)
|
||||||
|
case relay(String)
|
||||||
|
|
||||||
|
var is_invoice: Invoice? {
|
||||||
|
if case .invoice(let invoice) = self {
|
||||||
|
return invoice
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var is_hashtag: String? {
|
||||||
|
if case .hashtag(let htag) = self {
|
||||||
|
return htag
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var is_url: URL? {
|
||||||
|
if case .url(let url) = self {
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var is_text: String? {
|
||||||
|
if case .text(let txt) = self {
|
||||||
|
return txt
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var is_note_mention: Bool {
|
||||||
|
if case .mention(let mention) = self,
|
||||||
|
case .note = mention.ref {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var is_mention: Mention<MentionRef>? {
|
||||||
|
if case .mention(let m) = self {
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func render_blocks(blocks: [Block]) -> String {
|
||||||
|
return blocks.reduce("") { str, block in
|
||||||
|
switch block {
|
||||||
|
case .mention(let m):
|
||||||
|
if let idx = m.index {
|
||||||
|
return str + "#[\(idx)]"
|
||||||
|
}
|
||||||
|
|
||||||
|
switch m.ref {
|
||||||
|
case .pubkey(let pk): return str + "nostr:\(pk.npub)"
|
||||||
|
case .note(let note_id): return str + "nostr:\(note_id.bech32)"
|
||||||
|
}
|
||||||
|
case .relay(let relay):
|
||||||
|
return str + relay
|
||||||
|
case .text(let txt):
|
||||||
|
return str + txt
|
||||||
|
case .hashtag(let htag):
|
||||||
|
return str + "#" + htag
|
||||||
|
case .url(let url):
|
||||||
|
return str + url.absoluteString
|
||||||
|
case .invoice(let inv):
|
||||||
|
return str + inv.string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Blocks: Equatable {
|
struct Blocks: Equatable {
|
||||||
let words: Int
|
let words: Int
|
||||||
let blocks: [Block]
|
let blocks: [Block]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func strblock_to_string(_ s: str_block_t) -> String? {
|
||||||
|
let len = s.end - s.start
|
||||||
|
let bytes = Data(bytes: s.start, count: len)
|
||||||
|
return String(bytes: bytes, encoding: .utf8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func convert_block(_ b: block_t, tags: TagsSequence?) -> Block? {
|
||||||
|
if b.type == BLOCK_HASHTAG {
|
||||||
|
guard let str = strblock_to_string(b.block.str) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return .hashtag(str)
|
||||||
|
} else if b.type == BLOCK_TEXT {
|
||||||
|
guard let str = strblock_to_string(b.block.str) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return .text(str)
|
||||||
|
} else if b.type == BLOCK_MENTION_INDEX {
|
||||||
|
return convert_mention_index_block(ind: Int(b.block.mention_index), tags: tags)
|
||||||
|
} else if b.type == BLOCK_URL {
|
||||||
|
return convert_url_block(b.block.str)
|
||||||
|
} else if b.type == BLOCK_INVOICE {
|
||||||
|
return convert_invoice_block(b.block.invoice)
|
||||||
|
} else if b.type == BLOCK_MENTION_BECH32 {
|
||||||
|
return convert_mention_bech32_block(b.block.mention_bech32)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convert_url_block(_ b: str_block) -> Block? {
|
||||||
|
guard let str = strblock_to_string(b) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
guard let url = URL(string: str) else {
|
||||||
|
return .text(str)
|
||||||
|
}
|
||||||
|
return .url(url)
|
||||||
|
}
|
||||||
|
|
||||||
func maybe_pointee<T>(_ p: UnsafeMutablePointer<T>!) -> T? {
|
func maybe_pointee<T>(_ p: UnsafeMutablePointer<T>!) -> T? {
|
||||||
guard p != nil else {
|
guard p != nil else {
|
||||||
return nil
|
return nil
|
||||||
@ -190,6 +326,75 @@ func format_msats(_ msat: Int64, locale: Locale = Locale.current) -> String {
|
|||||||
return String(format: format, locale: locale, sats.decimalValue as NSDecimalNumber, formattedSats)
|
return String(format: format, locale: locale, sats.decimalValue as NSDecimalNumber, formattedSats)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convert_invoice_block(_ b: invoice_block) -> Block? {
|
||||||
|
guard let invstr = strblock_to_string(b.invstr) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard var b11 = maybe_pointee(b.bolt11) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let description = convert_invoice_description(b11: b11) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let amount: Amount = maybe_pointee(b11.msat).map { .specific(Int64($0.millisatoshis)) } ?? .any
|
||||||
|
let payment_hash = Data(bytes: &b11.payment_hash, count: 32)
|
||||||
|
let created_at = b11.timestamp
|
||||||
|
|
||||||
|
tal_free(b.bolt11)
|
||||||
|
return .invoice(Invoice(description: description, amount: amount, string: invstr, expiry: b11.expiry, payment_hash: payment_hash, created_at: created_at))
|
||||||
|
}
|
||||||
|
|
||||||
|
func convert_mention_bech32_block(_ b: mention_bech32_block) -> Block?
|
||||||
|
{
|
||||||
|
switch b.bech32.type {
|
||||||
|
case NOSTR_BECH32_NOTE:
|
||||||
|
let note = b.bech32.data.note;
|
||||||
|
let note_id = NoteId(Data(bytes: note.event_id, count: 32))
|
||||||
|
return .mention(.any(.note(note_id)))
|
||||||
|
|
||||||
|
case NOSTR_BECH32_NEVENT:
|
||||||
|
let nevent = b.bech32.data.nevent;
|
||||||
|
let note_id = NoteId(Data(bytes: nevent.event_id, count: 32))
|
||||||
|
return .mention(.any(.note(note_id)))
|
||||||
|
|
||||||
|
case NOSTR_BECH32_NPUB:
|
||||||
|
let npub = b.bech32.data.npub
|
||||||
|
let pubkey = Pubkey(Data(bytes: npub.pubkey, count: 32))
|
||||||
|
return .mention(.any(.pubkey(pubkey)))
|
||||||
|
|
||||||
|
case NOSTR_BECH32_NSEC:
|
||||||
|
let nsec = b.bech32.data.nsec
|
||||||
|
let privkey = Privkey(Data(bytes: nsec.nsec, count: 32))
|
||||||
|
guard let pubkey = privkey_to_pubkey(privkey: privkey) else { return nil }
|
||||||
|
return .mention(.any(.pubkey(pubkey)))
|
||||||
|
|
||||||
|
case NOSTR_BECH32_NPROFILE:
|
||||||
|
let nprofile = b.bech32.data.nprofile
|
||||||
|
let pubkey = Pubkey(Data(bytes: nprofile.pubkey, count: 32))
|
||||||
|
return .mention(.any(.pubkey(pubkey)))
|
||||||
|
|
||||||
|
case NOSTR_BECH32_NRELAY:
|
||||||
|
let nrelay = b.bech32.data.nrelay
|
||||||
|
guard let relay_str = strblock_to_string(nrelay.relay) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return .relay(relay_str)
|
||||||
|
|
||||||
|
case NOSTR_BECH32_NADDR:
|
||||||
|
// TODO: wtf do I do with this
|
||||||
|
guard let naddr = strblock_to_string(b.str) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return .text("nostr:" + naddr)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func convert_invoice_description(b11: bolt11) -> InvoiceDescription? {
|
func convert_invoice_description(b11: bolt11) -> InvoiceDescription? {
|
||||||
if let desc = b11.description {
|
if let desc = b11.description {
|
||||||
return .description(String(cString: desc))
|
return .description(String(cString: desc))
|
||||||
@ -202,6 +407,24 @@ func convert_invoice_description(b11: bolt11) -> InvoiceDescription? {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convert_mention_index_block(ind: Int, tags: TagsSequence?) -> Block?
|
||||||
|
{
|
||||||
|
guard let tags,
|
||||||
|
ind >= 0,
|
||||||
|
ind + 1 <= tags.count
|
||||||
|
else {
|
||||||
|
return .text("#[\(ind)]")
|
||||||
|
}
|
||||||
|
|
||||||
|
let tag = tags[ind]
|
||||||
|
|
||||||
|
guard let mention = MentionRef.from_tag(tag: tag) else {
|
||||||
|
return .text("#[\(ind)]")
|
||||||
|
}
|
||||||
|
|
||||||
|
return .mention(.any(mention, index: ind))
|
||||||
|
}
|
||||||
|
|
||||||
func find_tag_ref(type: String, id: String, tags: [[String]]) -> Int? {
|
func find_tag_ref(type: String, id: String, tags: [[String]]) -> Int? {
|
||||||
var i: Int = 0
|
var i: Int = 0
|
||||||
for tag in tags {
|
for tag in tags {
|
||||||
@ -251,9 +474,7 @@ func post_to_event(post: NostrPost, keypair: FullKeypair) -> NostrEvent? {
|
|||||||
let tags = post.references.map({ r in r.tag }) + post.tags
|
let tags = post.references.map({ r in r.tag }) + post.tags
|
||||||
let post_blocks = parse_post_blocks(content: post.content)
|
let post_blocks = parse_post_blocks(content: post.content)
|
||||||
let post_tags = make_post_tags(post_blocks: post_blocks, tags: tags)
|
let post_tags = make_post_tags(post_blocks: post_blocks, tags: tags)
|
||||||
let content = post_tags.blocks
|
let content = render_blocks(blocks: post_tags.blocks)
|
||||||
.map(\.asString)
|
|
||||||
.joined(separator: "")
|
|
||||||
return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: post.kind.rawValue, tags: post_tags.tags)
|
return NostrEvent(content: content, keypair: keypair.to_keypair(), kind: post.kind.rawValue, tags: post_tags.tags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,214 +0,0 @@
|
|||||||
//
|
|
||||||
// Block.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by Kyle Roucis on 2023-08-21.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
|
|
||||||
fileprivate extension String {
|
|
||||||
/// Failable initializer to build a Swift.String from a C-backed `str_block_t`.
|
|
||||||
init?(_ s: str_block_t) {
|
|
||||||
let len = s.end - s.start
|
|
||||||
let bytes = Data(bytes: s.start, count: len)
|
|
||||||
self.init(bytes: bytes, encoding: .utf8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a block of data stored by the NOSTR protocol. This can be
|
|
||||||
/// simple text, a hashtag, a url, a relay reference, a mention ref and
|
|
||||||
/// potentially more in the future.
|
|
||||||
enum Block: Equatable {
|
|
||||||
static func == (lhs: Block, rhs: Block) -> Bool {
|
|
||||||
switch (lhs, rhs) {
|
|
||||||
case (.text(let a), .text(let b)):
|
|
||||||
return a == b
|
|
||||||
case (.mention(let a), .mention(let b)):
|
|
||||||
return a == b
|
|
||||||
case (.hashtag(let a), .hashtag(let b)):
|
|
||||||
return a == b
|
|
||||||
case (.url(let a), .url(let b)):
|
|
||||||
return a == b
|
|
||||||
case (.invoice(let a), .invoice(let b)):
|
|
||||||
return a.string == b.string
|
|
||||||
case (_, _):
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case text(String)
|
|
||||||
case mention(Mention<MentionRef>)
|
|
||||||
case hashtag(String)
|
|
||||||
case url(URL)
|
|
||||||
case invoice(Invoice)
|
|
||||||
case relay(String)
|
|
||||||
}
|
|
||||||
extension Block {
|
|
||||||
/// Failable initializer for the C-backed type `block_t`. This initializer will inspect
|
|
||||||
/// the underlying block type and build the appropriate enum value as needed.
|
|
||||||
init?(_ block: block_t, tags: TagsSequence? = nil) {
|
|
||||||
switch block.type {
|
|
||||||
case BLOCK_HASHTAG:
|
|
||||||
guard let str = String(block.block.str) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
self = .hashtag(str)
|
|
||||||
case BLOCK_TEXT:
|
|
||||||
guard let str = String(block.block.str) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
self = .text(str)
|
|
||||||
case BLOCK_MENTION_INDEX:
|
|
||||||
guard let b = Block(index: Int(block.block.mention_index), tags: tags) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
self = b
|
|
||||||
case BLOCK_URL:
|
|
||||||
guard let b = Block(block.block.str) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
self = b
|
|
||||||
case BLOCK_INVOICE:
|
|
||||||
guard let b = Block(invoice: block.block.invoice) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
self = b
|
|
||||||
case BLOCK_MENTION_BECH32:
|
|
||||||
guard let b = Block(bech32: block.block.mention_bech32) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
self = b
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fileprivate extension Block {
|
|
||||||
/// Failable initializer for the C-backed type `str_block_t`.
|
|
||||||
init?(_ b: str_block_t) {
|
|
||||||
guard let str = String(b) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if let url = URL(string: str) {
|
|
||||||
self = .url(url)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self = .text(str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fileprivate extension Block {
|
|
||||||
/// Failable initializer for a block index and a tag sequence.
|
|
||||||
init?(index: Int, tags: TagsSequence? = nil) {
|
|
||||||
guard let tags,
|
|
||||||
index >= 0,
|
|
||||||
index + 1 <= tags.count
|
|
||||||
else {
|
|
||||||
self = .text("#[\(index)]")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let tag = tags[index]
|
|
||||||
|
|
||||||
if let mention = MentionRef.from_tag(tag: tag) {
|
|
||||||
self = .mention(.any(mention, index: index))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self = .text("#[\(index)]")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fileprivate extension Block {
|
|
||||||
/// Failable initializer for the C-backed type `invoice_block_t`.
|
|
||||||
init?(invoice: invoice_block_t) {
|
|
||||||
guard let invstr = String(invoice.invstr) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
guard var b11 = maybe_pointee(invoice.bolt11) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let description = convert_invoice_description(b11: b11) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
let amount: Amount = maybe_pointee(b11.msat).map { .specific(Int64($0.millisatoshis)) } ?? .any
|
|
||||||
let payment_hash = Data(bytes: &b11.payment_hash, count: 32)
|
|
||||||
let created_at = b11.timestamp
|
|
||||||
|
|
||||||
tal_free(invoice.bolt11)
|
|
||||||
self = .invoice(Invoice(description: description, amount: amount, string: invstr, expiry: b11.expiry, payment_hash: payment_hash, created_at: created_at))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fileprivate extension Block {
|
|
||||||
/// Failable initializer for the C-backed type `mention_bech32_block_t`. This initializer will inspect the
|
|
||||||
/// bech32 type code and build the appropriate enum type.
|
|
||||||
init?(bech32 b: mention_bech32_block_t) {
|
|
||||||
switch b.bech32.type {
|
|
||||||
case NOSTR_BECH32_NOTE:
|
|
||||||
let note = b.bech32.data.note;
|
|
||||||
let note_id = NoteId(Data(bytes: note.event_id, count: 32))
|
|
||||||
self = .mention(.any(.note(note_id)))
|
|
||||||
case NOSTR_BECH32_NEVENT:
|
|
||||||
let nevent = b.bech32.data.nevent;
|
|
||||||
let note_id = NoteId(Data(bytes: nevent.event_id, count: 32))
|
|
||||||
self = .mention(.any(.note(note_id)))
|
|
||||||
case NOSTR_BECH32_NPUB:
|
|
||||||
let npub = b.bech32.data.npub
|
|
||||||
let pubkey = Pubkey(Data(bytes: npub.pubkey, count: 32))
|
|
||||||
self = .mention(.any(.pubkey(pubkey)))
|
|
||||||
case NOSTR_BECH32_NSEC:
|
|
||||||
let nsec = b.bech32.data.nsec
|
|
||||||
let privkey = Privkey(Data(bytes: nsec.nsec, count: 32))
|
|
||||||
guard let pubkey = privkey_to_pubkey(privkey: privkey) else { return nil }
|
|
||||||
self = .mention(.any(.pubkey(pubkey)))
|
|
||||||
case NOSTR_BECH32_NPROFILE:
|
|
||||||
let nprofile = b.bech32.data.nprofile
|
|
||||||
let pubkey = Pubkey(Data(bytes: nprofile.pubkey, count: 32))
|
|
||||||
self = .mention(.any(.pubkey(pubkey)))
|
|
||||||
case NOSTR_BECH32_NRELAY:
|
|
||||||
let nrelay = b.bech32.data.nrelay
|
|
||||||
guard let relay_str = String(nrelay.relay) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
self = .relay(relay_str)
|
|
||||||
case NOSTR_BECH32_NADDR:
|
|
||||||
// TODO: wtf do I do with this
|
|
||||||
guard let naddr = String(b.str) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
self = .text("nostr:" + naddr)
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extension Block {
|
|
||||||
var asString: String {
|
|
||||||
switch self {
|
|
||||||
case .mention(let m):
|
|
||||||
if let idx = m.index {
|
|
||||||
return "#[\(idx)]"
|
|
||||||
}
|
|
||||||
|
|
||||||
switch m.ref {
|
|
||||||
case .pubkey(let pk): return "nostr:\(pk.npub)"
|
|
||||||
case .note(let note_id): return "nostr:\(note_id.bech32)"
|
|
||||||
}
|
|
||||||
case .relay(let relay):
|
|
||||||
return relay
|
|
||||||
case .text(let txt):
|
|
||||||
return txt
|
|
||||||
case .hashtag(let htag):
|
|
||||||
return "#" + htag
|
|
||||||
case .url(let url):
|
|
||||||
return url.absoluteString
|
|
||||||
case .invoice(let inv):
|
|
||||||
return inv.string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -393,7 +393,7 @@ func decode_bolt11(_ s: String) -> Invoice? {
|
|||||||
|
|
||||||
let block = bs.blocks[0]
|
let block = bs.blocks[0]
|
||||||
|
|
||||||
guard let converted = Block(block) else {
|
guard let converted = convert_block(block, tags: nil) else {
|
||||||
blocks_free(&bs)
|
blocks_free(&bs)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -130,9 +130,7 @@ struct DMChatView: View, KeyboardReadable {
|
|||||||
func send_message() {
|
func send_message() {
|
||||||
let tags = [["p", pubkey.hex()]]
|
let tags = [["p", pubkey.hex()]]
|
||||||
let post_blocks = parse_post_blocks(content: dms.draft)
|
let post_blocks = parse_post_blocks(content: dms.draft)
|
||||||
let content = post_blocks
|
let content = render_blocks(blocks: post_blocks)
|
||||||
.map(\.asString)
|
|
||||||
.joined(separator: "")
|
|
||||||
|
|
||||||
guard let dm = create_dm(content, to_pk: pubkey, tags: tags, keypair: damus_state.keypair) else {
|
guard let dm = create_dm(content, to_pk: pubkey, tags: tags, keypair: damus_state.keypair) else {
|
||||||
print("error creating dm")
|
print("error creating dm")
|
||||||
|
@ -445,15 +445,7 @@ func render_blocks(blocks bs: Blocks, profiles: Profiles) -> NoteArtifactsSepara
|
|||||||
let blocks = bs.blocks
|
let blocks = bs.blocks
|
||||||
|
|
||||||
let one_note_ref = blocks
|
let one_note_ref = blocks
|
||||||
.filter({
|
.filter({ $0.is_note_mention })
|
||||||
if case .mention(let mention) = $0,
|
|
||||||
case .note = mention.ref {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.count == 1
|
.count == 1
|
||||||
|
|
||||||
var ind: Int = -1
|
var ind: Int = -1
|
||||||
|
@ -34,7 +34,7 @@ final class LongPostTests: XCTestCase {
|
|||||||
XCTAssertEqual(subid, "subid")
|
XCTAssertEqual(subid, "subid")
|
||||||
XCTAssertTrue(ev.should_show_event)
|
XCTAssertTrue(ev.should_show_event)
|
||||||
XCTAssertTrue(!ev.too_big)
|
XCTAssertTrue(!ev.too_big)
|
||||||
XCTAssertTrue(should_show_event(contacts: contacts, ev: ev))
|
XCTAssertTrue(should_show_event(privkey: test_keypair.privkey, hellthreads: test_damus_state().muted_threads, contacts: contacts, ev: ev))
|
||||||
XCTAssertTrue(validate_event(ev: ev) == .ok )
|
XCTAssertTrue(validate_event(ev: ev) == .ok )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,15 +415,7 @@ extension NdbNote {
|
|||||||
// Rely on Apple's NLLanguageRecognizer to tell us which language it thinks the note is in
|
// Rely on Apple's NLLanguageRecognizer to tell us which language it thinks the note is in
|
||||||
// and filter on only the text portions of the content as URLs and hashtags confuse the language recognizer.
|
// and filter on only the text portions of the content as URLs and hashtags confuse the language recognizer.
|
||||||
let originalBlocks = self.blocks(privkey).blocks
|
let originalBlocks = self.blocks(privkey).blocks
|
||||||
let originalOnlyText = originalBlocks.compactMap {
|
let originalOnlyText = originalBlocks.compactMap { $0.is_text }.joined(separator: " ")
|
||||||
if case .text(let txt) = $0 {
|
|
||||||
return txt
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.joined(separator: " ")
|
|
||||||
|
|
||||||
// Only accept language recognition hypothesis if there's at least a 50% probability that it's accurate.
|
// Only accept language recognition hypothesis if there's at least a 50% probability that it's accurate.
|
||||||
let languageRecognizer = NLLanguageRecognizer()
|
let languageRecognizer = NLLanguageRecognizer()
|
||||||
|
Loading…
Reference in New Issue
Block a user