{% macro avatar(username, size="24px", selector_type="username") -%}
<img
    title="{{ username }}'s avatar"
    src="/api/v1/auth/user/{{ username }}/avatar?selector_type={{ selector_type }}"
    alt="@{{ username }}"
    class="avatar shadow"
    loading="lazy"
    style="--size: {{ size }}"
/>
{%- endmacro %} {% macro community_avatar(id, community=false, size="24px") -%}
{% if community %}
<img
    src="/api/v1/communities/{{ id }}/avatar"
    alt="{{ community.title }}'s avatar"
    class="avatar shadow"
    loading="lazy"
    style="--size: {{ size }}"
/>
{% else %}
<img
    src="/api/v1/communities/{{ id }}/avatar"
    alt="{{ id }}'s avatar"
    class="avatar shadow"
    loading="lazy"
    style="--size: {{ size }}"
/>
{% endif %} {%- endmacro %} {% macro banner(username,
border_radius="var(--radius)") -%}
<img
    title="{{ username }}'s banner"
    src="/api/v1/auth/user/{{ username }}/banner"
    alt="@{{ username }}'s banner"
    class="banner shadow w-full"
    loading="lazy"
    style="border-radius: {{ border_radius }};"
/>
{%- endmacro %} {% macro community_banner(id, community=false) -%} {% if
community %}
<img
    src="/api/v1/communities/{{ id }}/banner"
    alt="{{ community.title }}'s banner"
    class="banner shadow"
    loading="lazy"
/>
{% else %}
<img
    src="/api/v1/communities/{{ id }}/banner"
    alt="{{ id }}'s banner"
    class="banner shadow"
    loading="lazy"
/>
{% endif %} {%- endmacro %} {% macro community_listing_card(community) -%}
<a
    class="card secondary w-full flex items-center gap-4"
    href="/community/{{ community.title }}"
>
    {{ components::community_avatar(id=community.id, community=community,
    size="48px") }}
    <div class="flex flex-col">
        <h3 class="name lg:long">{{ community.context.display_name }}</h3>
        <span class="fade"><b>{{ community.member_count }}</b> members</span>
    </div>
</a>
{%- endmacro %} {% macro username(user) -%}
<div style="display: contents">
    {% if user.settings.display_name %} {{ user.settings.display_name }} {% else
    %} {{ user.username }} {% endif %}
</div>
{%- endmacro %} {% macro likes(id, asset_type, likes=0, dislikes=0) -%}
<button
    title="Like"
    class="camo small"
    hook_element="reaction.like"
    onclick="trigger('me::react', [event.target, '{{ id }}', '{{ asset_type }}', true])"
>
    {{ icon "heart" }} {% if likes > 0 %}
    <span>{{ likes }}</span>
    {% endif %}
</button>

<button
    title="Dislike"
    class="camo small"
    hook_element="reaction.dislike"
    onclick="trigger('me::react', [event.target, '{{ id }}', '{{ asset_type }}', false])"
>
    {{ icon "heart-crack" }} {% if dislikes > 0 %}
    <span>{{ dislikes }}</span>
    {% endif %}
</button>
{%- endmacro %} {% macro full_username(user) -%}
<div class="flex">
    <a href="/@{{ user.username }}" class="flush" style="font-weight: 600">
        {{ components::username(user=user) }}
    </a>

    {{ components::online_indicator(user=user) }} {% if user.is_verified %}
    <span
        title="Verified"
        style="color: var(--color-primary)"
        class="flex items-center"
    >
        {{ icon "badge-check" }}
    </span>
    {% endif %}
</div>
{%- endmacro %} {% macro repost(repost, post, owner, secondary=false,
community=false, show_community=true, can_manage_post=false) -%}
<div style="display: contents">
    <!-- prettier-ignore -->
    <div style="display: none" id="repost-content:{{ post.id }}">
        {% if repost %}
            {{ components::post(post=repost[1], owner=repost[0], secondary=not secondary, community=false, show_community=false, can_manage_post=false) }}
        {% else %}
            <div class="card tertiary red flex items-center gap-2">
                {{ icon "frown" }}
                <span>Could not find original post...</span>
            </div>
        {% endif %}
    </div>

    {{ components::post(post=post, owner=owner, secondary=secondary,
    community=community, show_community=show_community,
    can_manage_post=can_manage_post) }}

    <script>
        document.getElementById("post-content:{{ post.id }}").innerHTML +=
            document.getElementById("repost-content:{{ post.id }}").innerHTML;
        document.getElementById("repost-content:{{ post.id }}").remove();

        document
            .getElementById("post:{{ post.id }}")
            .querySelector(".avatar")
            .setAttribute("style", "--size: 24px");

        document
            .getElementById("post:{{ post.id }}")
            .querySelector(".name")
            .parentElement.prepend(
                document
                    .getElementById("post:{{ post.id }}")
                    .querySelector(".avatar"),
            );
    </script>
</div>
{%- endmacro %} {% macro post(post, owner, question=false, secondary=false,
community=false, show_community=true, can_manage_post=false) -%} {% if community
and show_community and community.id != config.town_square or question %}
<div class="card-nest">
    {% if question %} {{ components::question(question=question[0],
    owner=question[1]) }} {% else %}
    <div class="card small">
        <a
            href="/api/v1/communities/find/{{ post.community }}"
            class="flush flex gap-1 items-center"
        >
            {{ components::community_avatar(id=post.community,
            community=community) }}
            <b>
                <!-- prettier-ignore -->
                {% if community.context.display_name %}
                    {{ community.context.display_name }}
                {% else %}
                    {{ community.title }}
                {% endif %}
            </b>

            {% if post.context.is_pinned or post.context.is_profile_pinned %} {{
            icon "pin" }} {% endif %}
        </a>
    </div>
    {% endif %} {% endif %}
    <div
        class="card flex flex-col gap-2 {% if secondary %}secondary{% endif %}"
        id="post:{{ post.id }}"
    >
        <div class="w-full flex gap-2">
            <a href="/@{{ owner.username }}">
                {{ components::avatar(username=owner.username, size="52px",
                selector_type="username") }}
            </a>

            <div class="flex flex-col w-full gap-1">
                <div class="flex flex-wrap gap-2 items-center">
                    <span class="name"
                        >{{ components::full_username(user=owner) }}</span
                    >

                    {% if post.context.edited != 0 %}
                    <div class="flex">
                        <span class="fade date">{{ post.context.edited }}</span>
                        <sup title="Edited">*</sup>
                    </div>
                    {% else %}
                    <span class="fade date">{{ post.created }}</span>
                    {% endif %} {% if post.context.is_nsfw %}
                    <span
                        title="NSFW post"
                        class="flex items-center"
                        style="color: var(--color-primary)"
                    >
                        {{ icon "square-asterisk" }}
                    </span>
                    {% endif %} {% if post.context.repost and
                    post.context.repost.reposting %}
                    <span
                        title="Repost"
                        class="flex items-center"
                        style="color: var(--color-primary)"
                    >
                        {{ icon "repeat-2" }}
                    </span>
                    {% endif %} {% if post.community == config.town_square %}
                    <span
                        title="Posted to profile"
                        class="flex items-center"
                        style="color: var(--color-primary)"
                    >
                        {{ icon "user-round" }}
                    </span>
                    {% endif %}
                </div>

                <span id="post-content:{{ post.id }}" class="no_p_margin"
                    >{{ post.content|markdown|safe }}</span
                >
            </div>
        </div>

        <div class="flex justify-between items-center gap-2 w-full">
            {% if user %}
            <div
                class="flex gap-1 reactions_box"
                hook="check_reactions"
                hook-arg:id="{{ post.id }}"
            >
                <!-- prettier-ignore -->
                {% if post.context.reactions_enabled %}
                    {% if post.content|length > 0 %}
                        {{ components::likes(id=post.id, asset_type="Post", likes=post.likes, dislikes=post.dislikes) }}
                    {% endif %}
                {% endif %}

                {% if post.context.repost and post.context.repost.reposting %}
                <a
                    href="/post/{{ post.context.repost.reposting }}"
                    class="button small camo"
                    title='{{ text "communities:label.expand_original" }}'
                >
                    {{ icon "expand" }}
                </a>
                {% endif %}
            </div>
            {% else %}
            <div></div>
            {% endif %}

            <div class="flex gap-1 buttons_box">
                <a href="/post/{{ post.id }}" class="button camo small">
                    {{ icon "message-circle" }}
                    <span>{{ post.comment_count }}</span>
                </a>

                <a
                    href="/post/{{ post.id }}"
                    class="button camo small"
                    target="_blank"
                >
                    {{ icon "external-link" }}
                </a>

                {% if user %}
                <div class="dropdown">
                    <button
                        class="camo small"
                        onclick="trigger('atto::hooks::dropdown', [event])"
                        exclude="dropdown"
                    >
                        {{ icon "ellipsis" }}
                    </button>

                    <div class="inner">
                        {% if config.town_square and
                        post.context.reposts_enabled %}
                        <b class="title">{{ text "general:label.share" }}</b>
                        <button
                            onclick="trigger('me::repost', ['{{ post.id }}', '', '{{ config.town_square }}'])"
                        >
                            {{ icon "repeat-2" }}
                            <span>{{ text "communities:label.repost" }}</span>
                        </button>

                        <button
                            onclick="window.REPOST_ID = '{{ post.id }}'; document.getElementById('quote_dialog').showModal()"
                        >
                            {{ icon "quote" }}
                            <span
                                >{{ text "communities:label.quote_post" }}</span
                            >
                        </button>
                        {% endif %} {% if user.id != post.owner %}
                        <b class="title">{{ text "general:label.safety" }}</b>
                        <button
                            class="red"
                            onclick="trigger('me::report', ['{{ post.id }}', 'post'])"
                        >
                            {{ icon "flag" }}
                            <span>{{ text "general:action.report" }}</span>
                        </button>
                        {% endif %} {% if (user.id == post.owner) or is_helper
                        or can_manage_post %}
                        <b class="title">{{ text "general:action.manage" }}</b>
                        {% if user.id == post.owner %}
                        <a href="/post/{{ post.id }}#/edit">
                            {{ icon "pen" }}
                            <span
                                >{{ text "communities:label.edit_content"
                                }}</span
                            >
                        </a>
                        {% endif %}

                        <a href="/post/{{ post.id }}#/configure">
                            {{ icon "settings" }}
                            <span
                                >{{ text "communities:action.configure" }}</span
                            >
                        </a>

                        <button
                            class="red"
                            onclick="trigger('me::remove_post', ['{{ post.id }}'])"
                        >
                            {{ icon "trash" }}
                            <span>{{ text "general:action.delete" }}</span>
                        </button>
                        {% endif %}
                    </div>
                </div>
                {% endif %}
            </div>
        </div>
    </div>
    {% if community and show_community and community.id != config.town_square or
    question %}
</div>
{% endif %} {%- endmacro %} {% macro notification(notification) -%}
<div class="w-full card-nest">
    <div class="card small notif_title flex items-center">
        {% if not notification.read %}
        <svg
            width="24"
            height="24"
            viewBox="0 0 24 24"
            style="fill: var(--color-link)"
        >
            <circle cx="12" cy="12" r="6"></circle>
        </svg>
        {% endif %}
        <b class="no_p_margin">{{ notification.title|markdown|safe }}</b>
    </div>

    <div class="card notif_content flex flex-col gap-2">
        <span class="no_p_margin"
            >{{ notification.content|markdown|safe }}</span
        >

        <div class="card secondary w-full flex flex-wrap gap-2">
            {% if notification.read %}
            <button
                class="tertiary"
                onclick="trigger('me::update_notification_read_status', ['{{ notification.id }}', false])"
            >
                {{ icon "undo" }}
                <span>{{ text "notifs:action.mark_as_unread" }}</span>
            </button>
            {% else %}
            <button
                class="green tertiary"
                onclick="trigger('me::update_notification_read_status', ['{{ notification.id }}', true])"
            >
                {{ icon "check" }}
                <span>{{ text "notifs:action.mark_as_read" }}</span>
            </button>
            {% endif %}

            <button
                class="red tertiary"
                onclick="trigger('me::remove_notification', ['{{ notification.id }}'])"
            >
                {{ icon "trash" }}
                <span>{{ text "general:action.delete" }}</span>
            </button>
        </div>
    </div>
</div>
{%- endmacro %} {% macro user_card(user) -%}
<a class="card-nest w-full" href="/@{{ user.username }}">
    <div class="card small" style="padding: 0">
        {{ components::banner(username=user.username, border_radius="0px") }}
    </div>

    <div class="card secondary flex items-center gap-4">
        {{ components::avatar(username=user.username, size="48px") }}
        <div class="flex items-center">
            <b>{{ components::username(user=user) }}</b>
            {{ components::online_indicator(user=user) }}
        </div>
    </div>
</a>
{%- endmacro %} {% macro pagination(page=0, items=0, key="", value="") -%}
<div class="flex justify-between gap-2 w-full">
    {% if page > 0 %}
    <a
        class="button quaternary"
        href="?page={{ page - 1 }}{{ key }}{{ value }}"
    >
        {{ icon "arrow-left" }}
        <span>{{ text "general:link.previous" }}</span>
    </a>
    {% else %}
    <div></div>
    {% endif %} {% if items != 0 %}
    <a
        class="button quaternary"
        href="?page={{ page + 1 }}{{ key }}{{ value }}"
    >
        <span>{{ text "general:link.next" }}</span>
        {{ icon "arrow-right"}}
    </a>
    {% endif %}
</div>
{%- endmacro %} {% macro online_indicator(user) -%} {% if not
user.settings.private_last_seen or is_helper %}
<div
    class="online_indicator"
    style="display: contents"
    hook="online_indicator"
    hook-arg:last_seen="{{ user.last_seen }}"
>
    <div style="display: none" hook_ui_ident="online" title="Online">
        <svg
            width="24"
            height="24"
            viewBox="0 0 24 24"
            style="fill: var(--color-green)"
        >
            <circle cx="12" cy="12" r="6"></circle>
        </svg>
    </div>

    <div style="display: none" hook_ui_ident="idle" title="Idle">
        <svg
            width="24"
            height="24"
            viewBox="0 0 24 24"
            style="fill: var(--color-yellow)"
        >
            <circle cx="12" cy="12" r="6"></circle>
        </svg>
    </div>

    <div style="display: none" hook_ui_ident="offline" title="Offline">
        <svg
            width="24"
            height="24"
            viewBox="0 0 24 24"
            style="fill: hsl(0, 0%, 50%)"
        >
            <circle cx="12" cy="12" r="6"></circle>
        </svg>
    </div>
</div>
{% else %}
<div title="Offline" style="display: contents">
    <svg
        width="24"
        height="24"
        viewBox="0 0 24 24"
        style="fill: hsl(0, 0%, 50%)"
    >
        <circle cx="12" cy="12" r="6"></circle>
    </svg>
</div>
{% endif %} {%- endmacro %} {% macro theme(user, theme_preference) -%} {% if
user %} {% if user.settings.theme_hue %}
<style>
    :root, * {
        --hue: {{ user.settings.theme_hue }} !important;
    }
</style>
{% endif %} {% if user.settings.theme_sat %}
<style>
    :root, * {
        --sat: {{ user.settings.theme_sat }} !important;
    }
</style>
{% endif %} {% if user.settings.theme_lit %}
<style>
    :root, * {
        --lit: {{ user.settings.theme_lit }} !important;
    }
</style>
{% endif %} {% if theme_preference %}
<script>
    function match_user_theme() {
        const pref = "{{ theme_preference }}".toLowerCase();

        if (pref === "auto") {
            return;
        }

        document.documentElement.className = pref;
    }

    setTimeout(() => {
        match_user_theme();
    }, 150);
</script>
{% endif %}
<!-- prettier-ignore -->
<div style="display: none;">
    {{ components::theme_color(color=user.settings.theme_color_surface, css="color-surface") }}
    {{ components::theme_color(color=user.settings.theme_color_text, css="color-text") }}
    {{ components::theme_color(color=user.settings.theme_color_text_link, css="color-link") }}

    {{ components::theme_color(color=user.settings.theme_color_lowered, css="color-lowered") }}
    {{ components::theme_color(color=user.settings.theme_color_text_lowered, css="color-text-lowered") }}
    {{ components::theme_color(color=user.settings.theme_color_super_lowered, css="color-super-lowered") }}

    {{ components::theme_color(color=user.settings.theme_color_raised, css="color-raised") }}
    {{ components::theme_color(color=user.settings.theme_color_text_raised, css="color-text-raised") }}
    {{ components::theme_color(color=user.settings.theme_color_super_raised, css="color-super-raised") }}

    {{ components::theme_color(color=user.settings.theme_color_primary, css="color-primary") }}
    {{ components::theme_color(color=user.settings.theme_color_text_primary, css="color-text-primary") }}
    {{ components::theme_color(color=user.settings.theme_color_primary_lowered, css="color-primary-lowered") }}

    {{ components::theme_color(color=user.settings.theme_color_secondary, css="color-secondary") }}
    {{ components::theme_color(color=user.settings.theme_color_text_secondary, css="color-text-secondary") }}
    {{ components::theme_color(color=user.settings.theme_color_secondary_lowered, css="color-secondary-lowered") }}

    {% if user.permissions|has_supporter %}
    <style>{{ user.settings.theme_custom_css }}</style>
    {% endif %}
</div>
{% endif %} {%- endmacro %} {% macro theme_color(color, css) -%} {% if color %}
<!-- prettier-ignore -->
<style>
    :root,
    * {
        --{{ css }}: {{ color|color }} !important;
    }
</style>
{% endif %} {%- endmacro %} {% macro quote_form() -%} {% if config.town_square
and user %}
<div class="card-nest">
    <div class="card small flex flex-col">
        <div class="flex items-center gap-2">
            {{ icon "quote" }}
            <span>{{ text "communities:label.quote_post" }}</span>
        </div>
    </div>

    <form
        class="card flex flex-col gap-2"
        onsubmit="create_repost_from_form(event)"
    >
        <div class="flex flex-col gap-1">
            <label for="content">{{ text "communities:label.content" }}</label>
            <textarea
                type="text"
                name="content"
                id="content"
                placeholder="content"
                required
                minlength="2"
                maxlength="4096"
            ></textarea>
        </div>

        <button class="primary">{{ text "communities:action.create" }}</button>
    </form>
</div>

<script>
    async function create_repost_from_form(e) {
        e.preventDefault();
        await trigger("atto::debounce", ["posts::create"]);
        await trigger("me::repost", [
            window.REPOST_ID,
            e.target.content.value,
            "{{ config.town_square }}",
        ]);
    }
</script>
{% endif %} {%- endmacro %} {% macro question(question, owner,
show_community=true, secondary=false) -%}
<div class="card{% if secondary %} secondary{% endif %} flex gap-2">
    <a href="/@{{ owner.username }}">
        {{ components::avatar(username=owner.username, selector_type="username",
        size="52px") }}
    </a>

    <div class="flex flex-col gap-1">
        <div class="flex items-center gap-2 flex-wrap">
            <span class="name"
                >{{ components::full_username(user=owner) }}</span
            >

            <span class="date">{{ question.created }}</span>

            <span
                title="Question"
                class="flex items-center"
                style="color: var(--color-primary)"
            >
                {{ icon "message-circle-heart" }}
            </span>

            {% if question.community > 0 and show_community %}
            <a
                href="/api/v1/communities/find/{{ question.community }}"
                class="flex items-center"
            >
                {{ components::community_avatar(id=question.community,
                size="24px") }}
            </a>
            {% endif %} {% if question.is_global %}
            <a class="notification chip" href="/question/{{ question.id }}"
                >{{ question.answer_count }} answers</a
            >
            {% endif %}
        </div>

        <span class="no_p_margin" style="font-weight: 500"
            >{{ question.content|markdown|safe }}</span
        >

        <div class="flex gap-2 items-center justify-between"></div>
    </div>
</div>
{%- endmacro %} {% macro create_question_form(receiver="0", community="",
is_global=false) -%}
<div class="card-nest">
    <div class="card small flex items-center gap-2">
        {{ icon "message-circle-heart" }}
        <span>{{ text "requests:label.ask_question" }}</span>
    </div>

    <form
        class="card flex flex-col gap-2"
        onsubmit="create_question_from_form(event)"
    >
        <div class="flex flex-col gap-1">
            <label for="content">{{ text "communities:label.content" }}</label>
            <textarea
                type="text"
                name="content"
                id="content"
                placeholder="content"
                required
                minlength="2"
                maxlength="4096"
            ></textarea>
        </div>

        <button class="primary">{{ text "communities:action.create" }}</button>
    </form>
</div>

<script>
    async function create_question_from_form(e) {
        e.preventDefault();
        await trigger("atto::debounce", ["questions::create"]);
        fetch("/api/v1/questions", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                content: e.target.content.value,
                receiver: "{{ receiver }}",
                community: "{{ community }}",
                is_global: "{{ is_global }}" == "true",
            }),
        })
            .then((res) => res.json())
            .then((res) => {
                trigger("atto::toast", [
                    res.ok ? "success" : "error",
                    res.message,
                ]);

                if (res.ok) {
                    e.target.reset();
                }
            });
    }
</script>
{%- endmacro %} {% macro global_question(question, can_manage_questions=false,
secondary=false) -%}
<div class="card-nest">
    {{ components::question(question=question[0], owner=question[1],
    show_community=false) }}

    <div
        class="card flex flex-wrap gap-2{% if secondary %} secondary{% endif %}"
    >
        <a
            href="/question/{{ question[0].id }}"
            class="button quaternary small"
        >
            {{ icon "external-link" }} {% if user %}
            <span>{{ text "requests:label.answer" }}</span>
            {% else %}
            <span>{{ text "general:action.open" }}</span>
            {% endif %}
        </a>

        {% if user %} {% if can_manage_questions or is_helper or question[1].id
        == user.id %}
        <button
            class="quaternary small red"
            onclick="trigger('me::remove_question', ['{{ question[0].id }}'])"
        >
            {{ icon "trash" }}
            <span>{{ text "general:action.delete" }}</span>
        </button>
        {% endif %} {% endif %}
    </div>
</div>
{%- endmacro %}