synpad 0.1.0

A full-featured Matrix chat client built with Dioxus
use dioxus::prelude::*;

/// URL preview card that shows metadata fetched from a linked URL.
#[component]
pub fn UrlPreviewCard(url: String) -> Element {
    let mut preview_data = use_signal(|| Option::<UrlPreviewData>::None);
    let mut loading = use_signal(|| true);
    let mut failed = use_signal(|| false);

    let url_for_fetch = url.clone();
    use_effect(move || {
        let url = url_for_fetch.clone();
        spawn(async move {
            // Use Matrix content repo URL preview endpoint
            // In a real implementation, you'd call:
            // GET /_matrix/media/v3/preview_url?url=<url>
            // For now, we show a simple link card
            tokio::time::sleep(std::time::Duration::from_millis(100)).await;

            // Placeholder: extract domain from URL for display
            if let Ok(parsed) = url::Url::parse(&url) {
                let domain = parsed.host_str().unwrap_or("").to_string();
                let title = parsed.path().split('/').last().unwrap_or("").to_string();
                preview_data.set(Some(UrlPreviewData {
                    url: url.clone(),
                    title: if title.is_empty() { domain.clone() } else { title },
                    description: None,
                    image_url: None,
                    site_name: Some(domain),
                }));
            } else {
                failed.set(true);
            }
            loading.set(false);
        });
    });

    if *failed.read() || *loading.read() {
        return rsx! {};
    }

    let data_cloned = preview_data.read().clone();
    if let Some(data) = data_cloned {
        let title = data.title.clone();
        let desc = data.description.clone();
        let site = data.site_name.clone();
        let href = data.url.clone();
        let img_url = data.image_url.clone();

        rsx! {
            a {
                class: "url-preview",
                href: "{href}",
                target: "_blank",
                rel: "noopener noreferrer",

                if let Some(ref img) = img_url {
                    img {
                        class: "url-preview__image",
                        src: "{img}",
                        alt: "",
                    }
                }
                div {
                    class: "url-preview__info",
                    if let Some(ref site) = site {
                        span { class: "url-preview__site", "{site}" }
                    }
                    span { class: "url-preview__title", "{title}" }
                    if let Some(ref desc) = desc {
                        span { class: "url-preview__description", "{desc}" }
                    }
                }
            }
        }
    } else {
        rsx! {}
    }
}

/// Data for a URL preview.
#[derive(Clone, Debug)]
struct UrlPreviewData {
    url: String,
    title: String,
    description: Option<String>,
    image_url: Option<String>,
    site_name: Option<String>,
}