feat: support NIP22 for comment
This commit is contained in:
@@ -71,11 +71,11 @@ pub async fn get_meta_from_event(content: String) -> Result<Meta, ()> {
|
||||
#[specta::specta]
|
||||
pub async fn get_replies(id: String, state: State<'_, Nostr>) -> Result<Vec<RichEvent>, String> {
|
||||
let client = &state.client;
|
||||
let event_id = EventId::parse(&id).map_err(|err| err.to_string())?;
|
||||
|
||||
let event_id = EventId::parse(&id).map_err(|err| err.to_string())?;
|
||||
let filter = Filter::new()
|
||||
.kinds(vec![Kind::TextNote, Kind::Custom(1111)])
|
||||
.event(event_id);
|
||||
.kind(Kind::Comment)
|
||||
.custom_tag(SingleLetterTag::uppercase(Alphabet::E), [event_id]);
|
||||
|
||||
let mut events = Events::new(&[filter.clone()]);
|
||||
|
||||
@@ -523,39 +523,31 @@ pub async fn reply(content: String, to: String, state: State<'_, Nostr>) -> Resu
|
||||
Err(e) => return Err(e.to_string()),
|
||||
};
|
||||
|
||||
// Detect root event from reply
|
||||
let root_ids: Vec<&EventId> = reply_to
|
||||
// Find root event from reply
|
||||
let root_tag = reply_to
|
||||
.tags
|
||||
.filter_standardized(TagKind::e())
|
||||
.filter_map(|t| match t {
|
||||
TagStandard::Event {
|
||||
event_id, marker, ..
|
||||
} => {
|
||||
if let Some(mkr) = marker {
|
||||
match mkr {
|
||||
Marker::Root => Some(event_id),
|
||||
Marker::Reply => Some(event_id),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
Some(event_id)
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
.find(TagKind::SingleLetter(SingleLetterTag::uppercase(
|
||||
Alphabet::E,
|
||||
)));
|
||||
|
||||
// Get root event if exist
|
||||
let root = match root_ids.first() {
|
||||
Some(&id) => client
|
||||
.database()
|
||||
.event_by_id(id)
|
||||
.await
|
||||
.map_err(|err| err.to_string())?,
|
||||
let root = match root_tag {
|
||||
Some(tag) => match tag.content() {
|
||||
Some(content) => {
|
||||
let id = EventId::parse(content).map_err(|err| err.to_string())?;
|
||||
|
||||
client
|
||||
.database()
|
||||
.event_by_id(&id)
|
||||
.await
|
||||
.map_err(|err| err.to_string())?
|
||||
}
|
||||
None => None,
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let builder = EventBuilder::text_note_reply(content, &reply_to, root.as_ref(), None)
|
||||
let builder = EventBuilder::comment(content, &reply_to, root.as_ref(), None)
|
||||
.add_tags(tags)
|
||||
.pow(DEFAULT_DIFFICULTY);
|
||||
|
||||
|
||||
@@ -105,28 +105,27 @@ pub async fn create_column(
|
||||
});
|
||||
}
|
||||
} else if let Ok(event_id) = EventId::parse(&id) {
|
||||
let is_thread = payload.url().to_string().contains("events");
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let state = webview.state::<Nostr>();
|
||||
let client = &state.client;
|
||||
|
||||
if is_thread {
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let state = webview.state::<Nostr>();
|
||||
let client = &state.client;
|
||||
let subscription_id = SubscriptionId::new(webview.label());
|
||||
|
||||
let subscription_id = SubscriptionId::new(webview.label());
|
||||
let filter = Filter::new()
|
||||
.custom_tag(
|
||||
SingleLetterTag::uppercase(Alphabet::E),
|
||||
[event_id],
|
||||
)
|
||||
.kind(Kind::Comment)
|
||||
.since(Timestamp::now());
|
||||
|
||||
let filter = Filter::new()
|
||||
.event(event_id)
|
||||
.kinds(vec![Kind::TextNote, Kind::Custom(1111)])
|
||||
.since(Timestamp::now());
|
||||
|
||||
if let Err(e) = client
|
||||
.subscribe_with_id(subscription_id, vec![filter], None)
|
||||
.await
|
||||
{
|
||||
println!("Subscription error: {}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
if let Err(e) = client
|
||||
.subscribe_with_id(subscription_id, vec![filter], None)
|
||||
.await
|
||||
{
|
||||
println!("Subscription error: {}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +56,6 @@ pub fn create_tags(content: &str) -> Vec<Tag> {
|
||||
// Get words
|
||||
let words: Vec<_> = content.split_whitespace().collect();
|
||||
|
||||
// Get mentions
|
||||
let mentions = words
|
||||
.iter()
|
||||
.filter(|&&word| ["nostr:", "@"].iter().any(|&el| word.starts_with(el)))
|
||||
.map(|&s| s.to_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Get hashtags
|
||||
let hashtags = words
|
||||
.iter()
|
||||
@@ -70,6 +63,13 @@ pub fn create_tags(content: &str) -> Vec<Tag> {
|
||||
.map(|&s| s.to_string().replace("#", "").to_lowercase())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Get mentions
|
||||
let mentions = words
|
||||
.iter()
|
||||
.filter(|&&word| ["nostr:", "@"].iter().any(|&el| word.starts_with(el)))
|
||||
.map(|&s| s.to_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for mention in mentions {
|
||||
let entity = mention.replace("nostr:", "").replace('@', "");
|
||||
|
||||
@@ -92,8 +92,11 @@ pub fn create_tags(content: &str) -> Vec<Tag> {
|
||||
}
|
||||
if entity.starts_with("note") {
|
||||
if let Ok(event_id) = EventId::from_bech32(&entity) {
|
||||
let hex = event_id.to_hex();
|
||||
let tag = Tag::parse(&["e", &hex, "", "mention"]).unwrap();
|
||||
let tag = Tag::from_standardized(TagStandard::Quote {
|
||||
event_id,
|
||||
relay_url: None,
|
||||
public_key: None,
|
||||
});
|
||||
tags.push(tag);
|
||||
} else {
|
||||
continue;
|
||||
@@ -101,14 +104,12 @@ pub fn create_tags(content: &str) -> Vec<Tag> {
|
||||
}
|
||||
if entity.starts_with("nevent") {
|
||||
if let Ok(event) = Nip19Event::from_bech32(&entity) {
|
||||
let hex = event.event_id.to_hex();
|
||||
let relay = event.clone().relays.into_iter().next().unwrap_or("".into());
|
||||
let tag = Tag::parse(&["e", &hex, &relay, "mention"]).unwrap();
|
||||
|
||||
if let Some(author) = event.author {
|
||||
let tag = Tag::public_key(author);
|
||||
tags.push(tag);
|
||||
}
|
||||
let relay_url = event.relays.first().map(UncheckedUrl::from);
|
||||
let tag = Tag::from_standardized(TagStandard::Quote {
|
||||
event_id: event.event_id,
|
||||
relay_url,
|
||||
public_key: event.author,
|
||||
});
|
||||
|
||||
tags.push(tag);
|
||||
} else {
|
||||
|
||||
@@ -236,8 +236,8 @@ fn main() {
|
||||
// Config
|
||||
let opts = Options::new()
|
||||
.gossip(true)
|
||||
.max_avg_latency(Duration::from_millis(500))
|
||||
.timeout(Duration::from_secs(5));
|
||||
.max_avg_latency(Duration::from_secs(2))
|
||||
.timeout(Duration::from_secs(10));
|
||||
|
||||
// Setup nostr client
|
||||
let client = ClientBuilder::default()
|
||||
@@ -532,7 +532,7 @@ fn main() {
|
||||
if let Err(e) = handle_clone.emit("metadata", event.as_json()) {
|
||||
println!("Emit error: {}", e)
|
||||
}
|
||||
} else if event.kind == Kind::TextNote {
|
||||
} else if event.kind == Kind::Comment {
|
||||
let payload = RichEvent {
|
||||
raw: event.as_json(),
|
||||
parsed: if event.kind == Kind::TextNote {
|
||||
@@ -544,7 +544,7 @@ fn main() {
|
||||
|
||||
if let Err(e) = handle_clone.emit_to(
|
||||
EventTarget::labeled(subscription_id.to_string()),
|
||||
"event",
|
||||
"comment",
|
||||
payload,
|
||||
) {
|
||||
println!("Emit error: {}", e)
|
||||
|
||||
Reference in New Issue
Block a user