use super::route_prelude::*;
use crate::nostru;
#[derive(Template)]
#[template(path = "dm_conversation.gmi", escape = "txt")]
pub struct ConversationTemplate {
pub rumors: Vec<UnsignedEvent>,
}
#[derive(Template)]
#[template(path = "dm_history.gmi", escape = "txt")]
pub struct DmHistoryTemplate {
pub rumors: Vec<(UnsignedEvent, Option<Metadata>)>,
}
pub async fn person_send_dm(ctx: RouteContext) -> Response {
let params = ctx.parameters.clone();
let Some(user) = ugate(ctx.certificate).await else {
return resp_nocert();
};
let Some(npub) = params.get("npub") else {
return resp_invalid_params();
};
let Ok(pubkey) = PublicKey::parse(npub) else {
return resp_invalid_params();
};
if let Some(text) = dec_urlq(&ctx.url) {
match user.client.send_private_msg(pubkey, text, []).await {
Ok(_) => Response::success("Sent !"),
Err(err) => Response::temporary_failure(format!("{err}")),
}
} else {
Response::input(t!("dm_prompt"))
}
}
pub async fn person_dm_conversation(
ctx: RouteContext,
user: &'static mut CaracalUser,
) -> Response {
let params = ctx.parameters.clone();
let Some(npub) = params.get("npub") else {
return resp_invalid_params();
};
let Ok(pubkey) = PublicKey::parse(npub) else {
return resp_invalid_params();
};
let sub = Filter::new()
.kind(Kind::GiftWrap)
.pubkey(user.signer.get_public_key().await.unwrap());
let Ok(events) =
user.client.fetch_events(sub, Duration::from_secs(10)).await
else {
return Response::temporary_failure("ERR");
};
let mut rumors: Vec<UnsignedEvent> = Vec::new();
for ev in events {
let Ok(UnwrappedGift { rumor, sender }) =
user.client.unwrap_gift_wrap(&ev).await
else {
continue;
};
if sender != pubkey {
continue;
}
if rumor.kind == Kind::PrivateDirectMessage {
rumors.push(rumor);
}
}
Response::success(WindTemplate::render(ConversationTemplate { rumors }))
}
pub async fn dm_all(
_ctx: RouteContext,
user: &'static mut CaracalUser,
) -> Response {
let sub = Filter::new()
.kind(Kind::GiftWrap)
.pubkey(user.signer.get_public_key().await.unwrap());
let Ok(events) =
user.client.fetch_events(sub, Duration::from_secs(3)).await
else {
return Response::temporary_failure("ERR");
};
let mut rumors = Vec::new();
for event in events {
let Ok(UnwrappedGift { rumor, sender }) =
user.client.unwrap_gift_wrap(&event).await
else {
continue;
};
let metadata = nostru::fetch_user_metadata(&user.client, sender).await;
if rumor.kind == Kind::PrivateDirectMessage {
rumors.push((rumor, metadata));
}
}
Response::success(WindTemplate::render(DmHistoryTemplate { rumors }))
}