synpad 0.1.0

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

// Static emoji arrays to avoid lifetime issues in RSX
static FREQUENT: &[&str] = &["😀", "😂", "âĪïļ", "👍", "🎉", "ðŸ”Ĩ", "😍", "🙏"];
static SMILEYS: &[&str] = &[
    "😀", "😃", "😄", "😁", "😆", "😅", "ðŸĪĢ", "😂",
    "🙂", "🙃", "😉", "😊", "😇", "ðŸĨ°", "😍", "ðŸĪĐ",
    "😘", "😗", "😚", "😙", "ðŸĨē", "😋", "😛", "😜",
    "ðŸĪŠ", "😝", "ðŸĪ‘", "ðŸĪ—", "ðŸĪ­", "ðŸĪŦ", "ðŸĪ”", "ðŸŦĄ",
];
static GESTURES: &[&str] = &[
    "👍", "👎", "👌", "ðŸĪŒ", "ðŸĪ", "✌ïļ", "ðŸĪž", "ðŸŦ°",
    "ðŸĪŸ", "ðŸĪ˜", "ðŸĪ™", "👈", "👉", "👆", "👇", "☝ïļ",
    "👋", "ðŸĪš", "🖐ïļ", "✋", "🖖", "👏", "🙌", "ðŸŦķ",
];

/// Emoji picker popup component.
#[component]
pub fn EmojiPicker(
    on_select: EventHandler<String>,
    on_close: EventHandler<()>,
) -> Element {
    let mut search = use_signal(|| String::new());

    rsx! {
        div {
            class: "emoji-picker",

            div {
                class: "emoji-picker__search",
                input {
                    r#type: "text",
                    placeholder: "Search emoji...",
                    value: "{search}",
                    oninput: move |evt| search.set(evt.value()),
                    autofocus: true,
                }
            }

            div {
                class: "emoji-picker__categories",

                // Frequently used
                div {
                    class: "emoji-picker__section",
                    h4 { class: "emoji-picker__section-title", "Frequently Used" }
                    div {
                        class: "emoji-picker__grid",
                        for emoji in FREQUENT.iter() {
                            {
                                let emoji_str = emoji.to_string();
                                rsx! {
                                    button {
                                        class: "emoji-picker__emoji",
                                        onclick: move |_| on_select.call(emoji_str.clone()),
                                        "{emoji}"
                                    }
                                }
                            }
                        }
                    }
                }

                // Smileys
                div {
                    class: "emoji-picker__section",
                    h4 { class: "emoji-picker__section-title", "Smileys" }
                    div {
                        class: "emoji-picker__grid",
                        for emoji in SMILEYS.iter() {
                            {
                                let emoji_str = emoji.to_string();
                                rsx! {
                                    button {
                                        class: "emoji-picker__emoji",
                                        onclick: move |_| on_select.call(emoji_str.clone()),
                                        "{emoji}"
                                    }
                                }
                            }
                        }
                    }
                }

                // Gestures
                div {
                    class: "emoji-picker__section",
                    h4 { class: "emoji-picker__section-title", "Gestures" }
                    div {
                        class: "emoji-picker__grid",
                        for emoji in GESTURES.iter() {
                            {
                                let emoji_str = emoji.to_string();
                                rsx! {
                                    button {
                                        class: "emoji-picker__emoji",
                                        onclick: move |_| on_select.call(emoji_str.clone()),
                                        "{emoji}"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}