post.rs (2382B)
1 use nostrdb::{Note, NoteBuilder, NoteReply}; 2 use std::collections::HashSet; 3 4 pub struct NewPost { 5 pub content: String, 6 pub account: usize, 7 } 8 9 impl NewPost { 10 pub fn to_note(&self, seckey: &[u8; 32]) -> Note { 11 NoteBuilder::new() 12 .kind(1) 13 .content(&self.content) 14 .sign(seckey) 15 .build() 16 .expect("note should be ok") 17 } 18 19 pub fn to_reply(&self, seckey: &[u8; 32], replying_to: &Note) -> Note { 20 let builder = NoteBuilder::new().kind(1).content(&self.content); 21 22 let nip10 = NoteReply::new(replying_to.tags()); 23 24 let mut builder = if let Some(root) = nip10.root() { 25 builder 26 .start_tag() 27 .tag_str("e") 28 .tag_str(&hex::encode(root.id)) 29 .tag_str("") 30 .tag_str("root") 31 .start_tag() 32 .tag_str("e") 33 .tag_str(&hex::encode(replying_to.id())) 34 .tag_str("") 35 .tag_str("reply") 36 .sign(seckey) 37 } else { 38 // we're replying to a post that isn't in a thread, 39 // just add a single reply-to-root tag 40 builder 41 .start_tag() 42 .tag_str("e") 43 .tag_str(&hex::encode(replying_to.id())) 44 .tag_str("") 45 .tag_str("root") 46 .sign(seckey) 47 }; 48 49 let mut seen_p: HashSet<&[u8; 32]> = HashSet::new(); 50 51 builder = builder 52 .start_tag() 53 .tag_str("p") 54 .tag_str(&hex::encode(replying_to.pubkey())); 55 56 seen_p.insert(replying_to.pubkey()); 57 58 for tag in replying_to.tags() { 59 if tag.count() < 2 { 60 continue; 61 } 62 63 if tag.get_unchecked(0).variant().str() != Some("p") { 64 continue; 65 } 66 67 let id = if let Some(id) = tag.get_unchecked(1).variant().id() { 68 id 69 } else { 70 continue; 71 }; 72 73 if seen_p.contains(id) { 74 continue; 75 } 76 77 seen_p.insert(id); 78 79 builder = builder.start_tag().tag_str("p").tag_str(&hex::encode(id)); 80 } 81 82 builder 83 .sign(seckey) 84 .build() 85 .expect("expected build to work") 86 } 87 }