notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

post.rs (3147B)


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