synpad 0.1.0

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

/// Slash command autocomplete popup.
#[component]
pub fn CommandAutocomplete(
    query: String,
    on_select: EventHandler<SlashCommand>,
) -> Element {
    let commands = get_available_commands();
    let filtered: Vec<SlashCommand> = commands
        .into_iter()
        .filter(|cmd| cmd.name.starts_with(&query))
        .collect();

    if filtered.is_empty() {
        return rsx! {};
    }

    rsx! {
        div {
            class: "command-autocomplete",
            for cmd in filtered.iter() {
                {
                    let cmd_name = cmd.name.clone();
                    let cmd_desc = cmd.description.clone();
                    let cmd_clone = cmd.clone();
                    rsx! {
                        button {
                            class: "command-autocomplete__item",
                            onclick: move |_| on_select.call(cmd_clone.clone()),
                            span {
                                class: "command-autocomplete__name",
                                "/{cmd_name}"
                            }
                            span {
                                class: "command-autocomplete__desc",
                                "{cmd_desc}"
                            }
                        }
                    }
                }
            }
        }
    }
}

/// A slash command definition.
#[derive(Clone, Debug, PartialEq)]
pub struct SlashCommand {
    pub name: String,
    pub description: String,
    pub usage: String,
}

/// Get the list of available slash commands.
fn get_available_commands() -> Vec<SlashCommand> {
    vec![
        SlashCommand {
            name: "me".into(),
            description: "Send an emote".into(),
            usage: "/me <message>".into(),
        },
        SlashCommand {
            name: "nick".into(),
            description: "Change your display name".into(),
            usage: "/nick <name>".into(),
        },
        SlashCommand {
            name: "topic".into(),
            description: "Set the room topic".into(),
            usage: "/topic <topic>".into(),
        },
        SlashCommand {
            name: "invite".into(),
            description: "Invite a user to the room".into(),
            usage: "/invite <user_id>".into(),
        },
        SlashCommand {
            name: "kick".into(),
            description: "Kick a user from the room".into(),
            usage: "/kick <user_id> [reason]".into(),
        },
        SlashCommand {
            name: "ban".into(),
            description: "Ban a user from the room".into(),
            usage: "/ban <user_id> [reason]".into(),
        },
        SlashCommand {
            name: "join".into(),
            description: "Join a room".into(),
            usage: "/join <room_alias>".into(),
        },
        SlashCommand {
            name: "leave".into(),
            description: "Leave the current room".into(),
            usage: "/leave".into(),
        },
        SlashCommand {
            name: "shrug".into(),
            description: "Prepend ¯\\_(ツ)_/¯ to your message".into(),
            usage: "/shrug [message]".into(),
        },
        SlashCommand {
            name: "tableflip".into(),
            description: "Prepend (╯°□°)╯︵ ┻━┻ to your message".into(),
            usage: "/tableflip [message]".into(),
        },
        SlashCommand {
            name: "unflip".into(),
            description: "Prepend ┬──┬ ノ( ゜-゜ノ) to your message".into(),
            usage: "/unflip [message]".into(),
        },
        SlashCommand {
            name: "lenny".into(),
            description: "Prepend ( ͡° ͜ʖ ͡°) to your message".into(),
            usage: "/lenny [message]".into(),
        },
        SlashCommand {
            name: "plain".into(),
            description: "Send as plain text (no markdown)".into(),
            usage: "/plain <message>".into(),
        },
        SlashCommand {
            name: "html".into(),
            description: "Send raw HTML message".into(),
            usage: "/html <html>".into(),
        },
        SlashCommand {
            name: "spoiler".into(),
            description: "Send a spoiler message".into(),
            usage: "/spoiler <message>".into(),
        },
        SlashCommand {
            name: "rainbow".into(),
            description: "Send a rainbow-colored message".into(),
            usage: "/rainbow <message>".into(),
        },
        SlashCommand {
            name: "rainbowme".into(),
            description: "Send a rainbow-colored emote".into(),
            usage: "/rainbowme <message>".into(),
        },
        SlashCommand {
            name: "confetti".into(),
            description: "Send a message with confetti effect".into(),
            usage: "/confetti <message>".into(),
        },
        SlashCommand {
            name: "fireworks".into(),
            description: "Send a message with fireworks effect".into(),
            usage: "/fireworks <message>".into(),
        },
        SlashCommand {
            name: "ignore".into(),
            description: "Ignore a user".into(),
            usage: "/ignore <user_id>".into(),
        },
        SlashCommand {
            name: "unignore".into(),
            description: "Unignore a user".into(),
            usage: "/unignore <user_id>".into(),
        },
        SlashCommand {
            name: "msg".into(),
            description: "Send a direct message to a user".into(),
            usage: "/msg <user_id> <message>".into(),
        },
        SlashCommand {
            name: "myroomnick".into(),
            description: "Set your display name in this room only".into(),
            usage: "/myroomnick <name>".into(),
        },
        SlashCommand {
            name: "myroomavatar".into(),
            description: "Set your avatar in this room only".into(),
            usage: "/myroomavatar <mxc_url>".into(),
        },
        SlashCommand {
            name: "roomavatar".into(),
            description: "Set the room avatar".into(),
            usage: "/roomavatar <mxc_url>".into(),
        },
        SlashCommand {
            name: "unban".into(),
            description: "Unban a user from the room".into(),
            usage: "/unban <user_id>".into(),
        },
        SlashCommand {
            name: "devtools".into(),
            description: "Open developer tools".into(),
            usage: "/devtools".into(),
        },
        SlashCommand {
            name: "converttodm".into(),
            description: "Convert room to a direct message".into(),
            usage: "/converttodm".into(),
        },
        SlashCommand {
            name: "converttoroom".into(),
            description: "Convert DM to a regular room".into(),
            usage: "/converttoroom".into(),
        },
        SlashCommand {
            name: "op".into(),
            description: "Set user power level".into(),
            usage: "/op <user_id> <level>".into(),
        },
        SlashCommand {
            name: "deop".into(),
            description: "Reset user power level to default".into(),
            usage: "/deop <user_id>".into(),
        },
        SlashCommand {
            name: "discardsession".into(),
            description: "Discard current encryption session".into(),
            usage: "/discardsession".into(),
        },
        SlashCommand {
            name: "addwidget".into(),
            description: "Add a widget by URL".into(),
            usage: "/addwidget <url>".into(),
        },
        SlashCommand {
            name: "upgraderoom".into(),
            description: "Upgrade room to a new version".into(),
            usage: "/upgraderoom <version>".into(),
        },
        SlashCommand {
            name: "jumptodate".into(),
            description: "Jump to a specific date".into(),
            usage: "/jumptodate <YYYY-MM-DD>".into(),
        },
        SlashCommand {
            name: "holdcall".into(),
            description: "Put the current call on hold".into(),
            usage: "/holdcall".into(),
        },
        SlashCommand {
            name: "unholdcall".into(),
            description: "Resume a held call".into(),
            usage: "/unholdcall".into(),
        },
        SlashCommand {
            name: "rainfall".into(),
            description: "Send a message with rainfall effect".into(),
            usage: "/rainfall <message>".into(),
        },
        SlashCommand {
            name: "snowfall".into(),
            description: "Send a message with snowfall effect".into(),
            usage: "/snowfall <message>".into(),
        },
        SlashCommand {
            name: "spaceinvaders".into(),
            description: "Send a message with space invaders effect".into(),
            usage: "/spaceinvaders <message>".into(),
        },
        SlashCommand {
            name: "whois".into(),
            description: "Show information about a user".into(),
            usage: "/whois <user_id>".into(),
        },
        SlashCommand {
            name: "rageshake".into(),
            description: "Submit a bug report".into(),
            usage: "/rageshake [description]".into(),
        },
        SlashCommand {
            name: "goto".into(),
            description: "Navigate to a room or event".into(),
            usage: "/goto <room_id_or_alias>".into(),
        },
    ]
}