caracal 0.3.1

Nostr client for Gemini
use nostr_sdk::prelude::*;
use std::time::Duration;
use windmark_titanesque::{context::RouteContext, response::Response};

use crate::aska::WindTemplate;
use crate::routes::gem;
use crate::user::CaracalUser;
use crate::{nostru, rendering};
use askama::Template;
use mdiu::Block;
use rust_i18n::t;

#[derive(Template, Clone)]
#[template(path = "inbox.gmi", escape = "txt")]
struct InboxTemplate {
    note_blocks: Vec<Block>,
}

pub async fn inbox(
    _ctx: RouteContext,
    user: &'static mut CaracalUser,
) -> Response {
    let mut note_blocks = vec![];

    let Ok(pubkey) = user.signer.get_public_key().await else {
        return Response::temporary_failure(t!("signer_error"));
    };

    let mentions_filter = Filter::new().kind(Kind::TextNote).pubkey(pubkey);

    let Ok(events) = user
        .client
        .fetch_combined_events(mentions_filter, Duration::from_secs(5))
        .await
    else {
        return Response::temporary_failure(t!("fetch_events_failed"));
    };

    for event in events {
        if let Ok(mut blks) = rendering::render_note(
            &user.client,
            &event,
            nostru::get_user_metadata(&user.client, event.pubkey).await,
            rendering::NoteRenderMode::Normal,
        )
        .await
        {
            note_blocks.append(&mut blks);
        }
    }

    Response::success(WindTemplate::render(InboxTemplate { note_blocks }))
}