Implement NIP-27 link detection for "npub1", "nevent1" and "note1"

This commit is contained in:
bu5hm4nn 2023-03-27 18:20:11 -06:00
parent c14dbac8b2
commit f47a55d100

View File

@ -4,7 +4,7 @@ use crate::globals::GLOBALS;
use eframe::egui;
use egui::{RichText, Ui};
use linkify::{LinkFinder, LinkKind};
use nostr_types::{IdHex, Tag};
use nostr_types::{IdHex, Tag, EventPointer, Id, PublicKey};
/// returns None or a repost
pub(super) fn render_content(
@ -42,16 +42,7 @@ pub(super) fn render_content(
if let Some(tag) = note.event.tags.get(num) {
match tag {
Tag::Pubkey { pubkey, .. } => {
let nam = match GLOBALS.people.get(pubkey) {
Some(p) => match p.name() {
Some(n) => format!("@{}", n),
None => format!("@{}", GossipUi::pubkey_short(pubkey)),
},
None => format!("@{}", GossipUi::pubkey_short(pubkey)),
};
if ui.link(&nam).clicked() {
app.set_page(Page::Person(pubkey.to_owned()));
};
render_profile_link(app, ui, pubkey);
}
Tag::Event { id, .. } => {
let mut render_link = true;
@ -86,15 +77,7 @@ pub(super) fn render_content(
if ui.cursor().min.x > ui.max_rect().min.y {
ui.end_row();
}
let idhex: IdHex = (*id).into();
let nam = format!("#{}", GossipUi::hex_id_short(&idhex));
if ui.link(&nam).clicked() {
app.set_page(Page::Feed(FeedKind::Thread {
id: *id,
referenced_by: note.event.id,
}));
};
render_event_link(app, ui, note, id);
}
}
Tag::Hashtag(s) => {
@ -113,10 +96,42 @@ pub(super) fn render_content(
}
pos = mat.end();
}
if as_deleted {
ui.label(RichText::new(&s[pos..]).strikethrough());
let rest = &s[pos..];
// implement NIP-27 nostr: links that include NIP-19 bech32 references
if rest.contains("nostr:") {
let regx = regex::Regex::new(r"(?i:nostr:[[:alnum:]]+)").unwrap();
let mut nospos = 0;
for mat in regx.find_iter(rest) {
ui.label(&s[nospos..mat.start()]); // print whatever comes before the match
let mut link_parsed = false;
let link = &s[mat.start() + 6..mat.end()];
if link.starts_with("note1") {
if let Ok(id) = Id::try_from_bech32_string(link) {
render_event_link(app, ui, note, &id);
link_parsed = true;
}
} else if link.starts_with("nevent1") {
if let Ok(ep) = EventPointer::try_from_bech32_string(link) {
render_event_link(app, ui, note, &ep.id);
link_parsed = true;
}
} else if link.starts_with("npub1") {
if let Ok(pk) = PublicKey::try_from_bech32_string(link) {
render_profile_link(app, ui, &pk.into());
link_parsed = true;
}
}
if link_parsed == false {
ui.label( format!("nostr:{}", link) );
}
nospos = mat.end();
}
} else {
ui.label(&s[pos..]);
if as_deleted {
ui.label(RichText::new(rest).strikethrough());
} else {
ui.label(rest);
}
}
}
}
@ -125,3 +140,28 @@ pub(super) fn render_content(
append_repost
}
fn render_profile_link(app: &mut GossipUi, ui: &mut Ui, pubkey: &gossip_relay_picker::PublicKeyHex)
{
let nam = match GLOBALS.people.get(pubkey) {
Some(p) => match p.name() {
Some(n) => format!("@{}", n),
None => format!("@{}", GossipUi::pubkey_short(pubkey)),
},
None => format!("@{}", GossipUi::pubkey_short(pubkey)),
};
if ui.link(&nam).clicked() {
app.set_page(Page::Person(pubkey.to_owned()));
};
}
fn render_event_link(app: &mut GossipUi, ui: &mut Ui, note: &NoteData, id: &Id) {
let idhex: IdHex = (*id).into();
let nam = format!("#{}", GossipUi::hex_id_short(&idhex));
if ui.link(&nam).clicked() {
app.set_page(Page::Feed(FeedKind::Thread {
id: *id,
referenced_by: note.event.id,
}));
};
}