notedeck

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

post.rs (3368B)


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