{% extends "root.html" %} {% block head %}
<title>Chats - {{ config.name }}</title>
{% endblock %} {% block body %} {{ macros::nav(selected="chats") }}
<nav class="chats_nav">
    <button
        class="flex gap-2 items-center active"
        onclick="toggle_sidebars(event)"
    >
        {{ icon "panel-left" }} {% if community %}
        <b class="name shorter">
            {% if community.context.display_name %} {{
            community.context.display_name }} {% else %} {{ community.title }}
            {% endif %}
        </b>
        {% else %}
        <b>{{ text "chats:label.my_chats" }}</b>
        {% endif %}
    </button>
</nav>

<div class="flex">
    <div
        class="sidebar flex flex-col items-center gap-2"
        id="community_list"
        style="width: var(--list-bar-width)"
    >
        <a
            href="/chats/0/0"
            class="button quaternary channel_icon {% if selected_community == 0 %}selected{% endif %}"
            data-turbo="false"
        >
            {{ icon "message-circle" }}
        </a>

        {% for community in communities %} {% if community.id != 0 %}
        <a
            href="/chats/{{ community.id }}/0"
            class="button quaternary channel_icon {% if selected_community == community.id %}selected{% endif %}"
            data-turbo="false"
        >
            {{ components::community_avatar(id=community.id,
            community=community, size="48px") }}
        </a>
        {% endif %} {% endfor %}
    </div>

    <div class="sidebar flex flex-col gap-2" id="channels_list">
        <div class="title flex justify-between">
            {% if community %}
            <b class="name shorter">
                {% if community.context.display_name %} {{
                community.context.display_name }} {% else %} {{ community.title
                }} {% endif %}
            </b>
            {% else %}
            <b>{{ text "chats:label.my_chats" }}</b>
            {% endif %}
            <div class="dropdown">
                <button
                    class="camo small"
                    onclick="trigger('atto::hooks::dropdown', [event])"
                    exclude="dropdown"
                >
                    {{ icon "ellipsis" }}
                </button>

                <div class="inner">
                    <a href="/community/{{ selected_community }}">
                        {{ icon "book-heart" }}
                        <span
                            >{{ text "communities:label.show_community" }}</span
                        >
                    </a>

                    {% if can_manage_channels %}
                    <a href="/community/{{ selected_community }}/manage">
                        {{ icon "settings" }}
                        <span>{{ text "general:action.manage" }}</span>
                    </a>
                    {% endif %}
                </div>
            </div>
        </div>

        {% if can_manage_channels %}
        <a
            class="button w-full justify-start quaternary"
            href="/community/{{ selected_community }}/manage#/channels"
        >
            {{ icon "plus" }}
            <span>{{ text "communities:action.create_channel" }}</span>
        </a>
        {% endif %}

        <turbo-frame
            id="channels_list_frame"
            src="/chats/{{ selected_community }}/{{ selected_channel }}/_channels"
            target="_top"
        ></turbo-frame>
    </div>

    {% if channel %}
    <div class="w-full flex flex-col gap-2" id="stream" style="padding: 1rem">
        <turbo-frame
            id="stream_body_frame"
            src="/chats/{{ selected_community }}/{{ selected_channel }}/_stream?page={{ page }}"
            target="_top"
        ></turbo-frame>

        <form
            class="card flex flex-row gap-2"
            onsubmit="create_message_from_form(event)"
        >
            <textarea
                type="text"
                name="content"
                id="content"
                placeholder="message {{ channel.title }}"
                required
                minlength="2"
                maxlength="2048"
                style="min-height: 48px !important; height: 48px"
            ></textarea>

            <button class="camo send_button" title="Send">
                {{ icon "send-horizontal" }}
            </button>
        </form>
    </div>
    {% endif %}

    <style>
        :root {
            --list-bar-width: 64px;
            --channels-bar-width: 256px;
        }

        html,
        body {
            overflow: hidden;
        }

        .name.shortest {
            max-width: 165px;
            overflow-wrap: normal;
        }

        .send_button {
            width: 48px;
            height: 48px;
        }

        .send_button .icon {
            width: 2em;
            height: 2em;
        }

        a.channel_icon {
            width: 48px;
            height: 48px;
            min-height: 48px;
        }

        a.channel_icon .icon {
            min-width: 24px;
            height: 24px;
        }

        a.channel_icon.small {
            width: 24px;
            height: 24px;
            min-height: 24px;
        }

        a.channel_icon.small .icon {
            min-width: 12px;
            height: 12px;
        }

        a.channel_icon:has(img) {
            padding: 0;
        }

        a.channel_icon img {
            min-width: 48px;
            min-height: 48px;
        }

        a.channel_icon img,
        a.channel_icon:has(.icon) {
            transition:
                outline 0.25s,
                background 0.15s !important;
        }

        a.channel_icon:not(.selected):hover img,
        a.channel_icon:not(.selected):hover:has(.icon) {
            outline: solid 1px var(--color-text);
        }
        a.channel_icon.selected img,
        a.channel_icon.selected:has(.icon) {
            outline: solid 2px var(--color-text);
        }

        nav {
            background: var(--color-raised);
            color: var(--color-text-raised) !important;
            height: 42px;
            position: sticky !important;
        }

        nav::after {
            display: block;
            position: absolute;
            background: var(--color-super-lowered);
            height: 1px;
            width: calc(100% - var(--list-bar-width));
            bottom: 0;
            left: var(--list-bar-width);
            content: "";
        }

        nav .content_container {
            max-width: 100% !important;
            width: 100%;
        }

        .chats_nav {
            display: none;
            padding: 0;
        }

        .chats_nav button {
            justify-content: flex-start;
            width: 100% !important;
            flex-direction: row !important;
            font-size: 16px !important;
            margin-top: -4px;
        }

        .chats_nav button svg {
            margin-right: 1rem;
        }

        .sidebar {
            background: var(--color-raised);
            color: var(--color-text-raised);
            border-right: solid 1px var(--color-super-lowered);
            padding: 0.4rem;
            width: max-content;
            height: calc(100dvh - 42px);
            overflow: auto;
            transition: left 0.15s;
        }

        .sidebar .title {
            padding: 1rem;
            border-bottom: solid 1px var(--color-super-lowered);
        }

        .sidebar#channels_list {
            width: var(--channels-bar-width);
            background: var(--color-surface);
            color: var(--color-text);
        }

        #stream {
            width: calc(
                100dvw - var(--list-bar-width) - var(--channels-bar-width)
            ) !important;
            height: calc(100dvh - 42px);
        }

        .message {
            transition: background 0.15s;
            box-shadow: none;
        }

        .message:hover {
            background: var(--color-raised);
        }

        .message:hover .hidden,
        .message:focus .hidden,
        .message:active .hidden {
            display: flex !important;
        }

        turbo-frame {
            display: contents;
        }

        @media screen and (max-width: 900px) {
            body:not(.sidebars_shown) .sidebar {
                position: absolute;
                left: -200%;
            }

            body.sidebars_shown .sidebar {
                position: absolute;
            }

            #stream {
                width: 100dvw !important;
                height: calc(100dvh - 42px * 2);
            }

            nav::after {
                width: 100dvw;
                left: 0;
            }

            .chats_nav {
                display: flex;
            }
        }
    </style>

    <script>
        window.CURRENT_PAGE = Number.parseInt("{{ page }}");
        window.CHAT_PROPS = {
            selected_community: "{{ selected_community }}",
            selected_channel: "{{ selected_channel }}",
            membership_role: Number.parseInt("{{ membership_role }}"),
        };

        window.SIDEBARS_OPEN = false;
        if (new URLSearchParams(window.location.search).get("nav") === "true") {
            window.SIDEBARS_OPEN = true;
        }

        if (
            window.SIDEBARS_OPEN &&
            !document.body.classList.contains("sidebars_shown")
        ) {
            toggle_sidebars();
            window.SIDEBARS_OPEN = true;
        }

        for (const anchor of document.querySelectorAll("[data-turbo=false]")) {
            anchor.href += `?nav=${window.SIDEBARS_OPEN}`;
        }

        function toggle_sidebars() {
            window.SIDEBARS_OPEN = !window.SIDEBARS_OPEN;

            for (const anchor of document.querySelectorAll(
                "[data-turbo=false]",
            )) {
                anchor.href = anchor.href.replace(
                    `?nav=${!window.SIDEBARS_OPEN}`,
                    `?nav=${window.SIDEBARS_OPEN}`,
                );
            }

            const community_list = document.getElementById("community_list");
            const channels_list = document.getElementById("channels_list");

            if (document.body.classList.contains("sidebars_shown")) {
                // hide
                document.body.classList.remove("sidebars_shown");
                community_list.style.left = "-200%";
                channels_list.style.left = "-200%";
            } else {
                // show
                document.body.classList.add("sidebars_shown");
                community_list.style.left = "0";
                channels_list.style.left = "var(--list-bar-width)";
            }
        }

        globalThis.kick_member = async (cid, uid) => {
            if (
                !(await trigger("atto::confirm", [
                    "Are you sure you would like to do this?",
                ]))
            ) {
                return;
            }

            fetch(`/api/v1/channels/${cid}/kick`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify({
                    member: uid,
                }),
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger("atto::toast", [
                        res.ok ? "success" : "error",
                        res.message,
                    ]);
                });
        };

        globalThis.delete_channel = async (id) => {
            if (
                !(await trigger("atto::confirm", [
                    "Are you sure you would like to do this?",
                ]))
            ) {
                return;
            }

            fetch(`/api/v1/channels/${id}`, {
                method: "DELETE",
            })
                .then((res) => res.json())
                .then((res) => {
                    trigger("atto::toast", [
                        res.ok ? "success" : "error",
                        res.message,
                    ]);
                });
        };
    </script>

    <script id="socket_init" data-turbo-permanent="true">
        globalThis.socket_init = () => {
            if (window.socket) {
                window.socket.send("Close");
                window.socket.close();
                window.socket = undefined;
                console.log("closed lingering");
            }

            if (window.CHAT_PROPS.selected_community !== "0") {
                const endpoint = `${window.location.origin.replace("http", "ws")}/api/v1/_connect/${window.CHAT_PROPS.selected_community}`;
                const socket = new WebSocket(endpoint);
                window.socket = socket;
                window.socket_id = window.CHAT_PROPS.selected_community;
            } else {
                const endpoint = `${window.location.origin.replace("http", "ws")}/api/v1/_connect/${window.CHAT_PROPS.selected_channel}`;
                const socket = new WebSocket(endpoint);
                window.socket = socket;
                window.socket_id = window.CHAT_PROPS.selected_channel;
            }

            window.socket.addEventListener("open", () => {
                // auth
                window.socket.send(
                    JSON.stringify({
                        method: "Headers",
                        data: JSON.stringify({
                            // SocketHeaders
                            user: "{{ user.id }}",
                            is_channel: window.SUBSCRIBE_CHANNEL,
                        }),
                    }),
                );
            });

            setTimeout(() => {
                window.socket.addEventListener("message", async (event) => {
                    if (event.data === "Ping") {
                        return socket.send("Pong");
                    }

                    const msg = JSON.parse(event.data);
                    const [channel_id, data] = JSON.parse(msg.data);

                    if (msg.method === "Message" && window.CURRENT_PAGE === 0) {
                        if (channel_id !== window.CHAT_PROPS.selected_channel) {
                            // message not for us... maybe send notification later
                            // something like /api/v1/messages/{id}/mark_unread
                            return;
                        }

                        if (document.getElementById("stream_body")) {
                            const element = document.createElement("div");
                            element.style.display = "contents";
                            element.innerHTML = await (
                                await fetch(
                                    `/chats/${window.CHAT_PROPS.selected_community}/${window.CHAT_PROPS.selected_channel}/_render`,
                                    {
                                        method: "POST",
                                        headers: {
                                            "Content-Type": "application/json",
                                        },
                                        body: JSON.stringify({
                                            data: msg.data,
                                        }),
                                    },
                                )
                            ).text();

                            document
                                .getElementById("stream_body")
                                .prepend(element);
                            clean_text();
                        } else {
                            console.log("abandoned remote");
                            socket.close();
                        }
                    } else if (msg.method === "Delete") {
                        if (document.getElementById(`message-${data.id}`)) {
                            document
                                .getElementById(`message-${data.id}`)
                                .remove();
                        }
                    }
                });

                globalThis.create_message_from_form = async (e) => {
                    e.preventDefault();
                    await trigger("atto::debounce", ["messages::create"]);

                    fetch("/api/v1/messages", {
                        method: "POST",
                        headers: {
                            "Content-Type": "application/json",
                        },
                        body: JSON.stringify({
                            content: e.target.content.value,
                            channel: window.CHAT_PROPS.selected_channel,
                        }),
                    })
                        .then((res) => res.json())
                        .then((res) => {
                            if (!res.ok) {
                                trigger("atto::toast", ["error", res.message]);
                            }

                            e.target.reset();
                        });
                };

                globalThis.delete_message = async (id) => {
                    if (
                        !(await trigger("atto::confirm", [
                            "Are you sure you would like to do this?",
                        ]))
                    ) {
                        return;
                    }

                    fetch(`/api/v1/messages/${id}`, {
                        method: "DELETE",
                    })
                        .then((res) => res.json())
                        .then((res) => {
                            trigger("atto::toast", [
                                res.ok ? "success" : "error",
                                res.message,
                            ]);
                        });
                };

                const clean_text = () => {
                    trigger("atto::clean_date_codes");
                    trigger("atto::hooks::online_indicator");
                };

                document.addEventListener(
                    "turbo:before-frame-render",
                    (event) => {
                        setTimeout(clean_text, 50);
                    },
                );

                setTimeout(clean_text, 150);
            }, 250);
        };
    </script>

    {% if selected_channel %}
    <script>
        window.SUBSCRIBE_CHANNEL = "{{ selected_community }}" === "0";

        setTimeout(() => {
            if (!window.SUBSCRIBE_CHANNEL) {
                // sub community
                if (window.socket_id !== "{{ selected_community }}") {
                    socket_init();
                }
            } else {
                // sub channel
                if (window.socket_id !== "{{ selected_channel }}") {
                    socket_init();
                }
            }
        }, 100);
    </script>
    {% endif %}
</div>
{% endblock %}