tetratto/crates/app/src/public/html/profile/base.html

381 lines
17 KiB
HTML
Raw Normal View History

{% extends "root.html" %} {% block head %}
<title>{{ profile.username }} - {{ config.name }}</title>
<meta name="og:title" content="{{ profile.username }}" />
<meta
name="description"
content="View @{{ profile.username }}'s profile on {{ config.name }}!"
/>
<meta
name="og:description"
content="View @{{ profile.username }}'s profile on {{ config.name }}!"
/>
<meta property="og:type" content="profile" />
<meta property="profile:username" content="{{ profile.username }}" />
<meta
name="og:image"
content="{{ config.host|safe }}/api/v1/auth/user/{{ profile.username }}/avatar?selector_type=username"
/>
<meta
name="twitter:image"
content="{{ config.host|safe }}/api/v1/auth/user/{{ profile.username }}/avatar?selector_type=username"
/>
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="{{ profile.username }}" />
<meta
name="twitter:description"
content="View @{{ profile.username }}'s profile on {{ config.name }}!"
/>
{% endblock %} {% block body %} {{ macros::nav() }}
<article>
2025-03-31 19:31:36 -04:00
<div class="content_container flex flex-col gap-4">
{{ components::banner(username=profile.username) }}
<div class="w-full flex gap-4 flex-collapse">
<div
class="lhs flex flex-col gap-2 sm:w-full"
style="width: 22rem; min-width: 22rem"
>
<div class="card-nest w-full">
<div class="card flex gap-2" id="user_avatar_and_name">
{{
components::avatar(username=profile.username,size="72px")
}}
<div class="flex flex-col">
<!-- prettier-ignore -->
<h3 id="username" class="username flex items-center gap-2 flex-wrap w-full">
2025-04-03 17:42:03 -04:00
<span class="name shorter">{{ components::username(user=profile) }}</span>
2025-05-18 16:43:56 -04:00
{% if profile.is_verified -%}
<span title="Verified" style="color: var(--color-primary);" class="flex items-center">
{{ icon "badge-check" }}
</span>
2025-05-18 16:43:56 -04:00
{%- endif %}
2025-04-06 13:43:12 -04:00
2025-05-18 16:43:56 -04:00
{% if profile.permissions|has_supporter -%}
2025-04-06 13:43:12 -04:00
<span title="Supporter" style="color: var(--color-primary);" class="flex items-center">
{{ icon "star" }}
</span>
2025-05-18 16:43:56 -04:00
{%- endif %}
2025-05-18 16:43:56 -04:00
{% if profile.permissions|has_staff_badge -%}
<span title="Staff" style="color: var(--color-primary);" class="flex items-center">
{{ icon "shield-user" }}
</span>
2025-05-18 16:43:56 -04:00
{%- endif %}
</h3>
<span class="fade">{{ profile.username }}</span>
</div>
</div>
2025-04-10 18:16:52 -04:00
<div
class="card flex flex-col items-center gap-2"
id="social"
>
2025-05-18 16:43:56 -04:00
{% if profile.settings.status -%}
<p>{{ profile.settings.status }}</p>
2025-05-18 16:43:56 -04:00
{%- endif %}
<div class="w-full flex">
<a
2025-03-31 22:35:11 -04:00
href="/@{{ profile.username }}/followers"
class="w-full flex justify-center items-center gap-2"
>
<h4>{{ profile.follower_count }}</h4>
<span>{{ text "auth:label.followers" }}</span>
</a>
<a
2025-03-31 22:35:11 -04:00
href="/@{{ profile.username }}/following"
class="w-full flex justify-center items-center gap-2"
>
<h4>{{ profile.following_count }}</h4>
<span>{{ text "auth:label.following" }}</span>
</a>
</div>
2025-04-10 18:16:52 -04:00
2025-05-18 16:43:56 -04:00
{% if is_following_you -%}
2025-04-10 18:16:52 -04:00
<b
class="notification chip w-content flex items-center gap-2"
>
{{ icon "heart" }}
<span>Follows you</span>
</b>
2025-05-18 16:43:56 -04:00
{%- endif %}
</div>
</div>
<div class="card-nest flex flex-col">
<div id="bio" class="card small no_p_margin">
{{ profile.settings.biography|markdown|safe }}
</div>
<div class="card flex flex-col gap-2">
<!-- prettier-ignore -->
<div style="display: contents;">
2025-05-18 16:43:56 -04:00
{% if profile.connections.Spotify and profile.connections.Spotify[0].data.name -%}
{{ components::spotify_playing(state=profile.connections.Spotify[1]) }}
{% elif profile.connections.LastFm and profile.connections.LastFm[0].data.name %}
2025-04-26 19:23:30 -04:00
{{ components::last_fm_playing(state=profile.connections.LastFm[1]) }}
2025-05-18 16:43:56 -04:00
{%- endif %}
</div>
<div class="w-full flex justify-between items-center">
<span class="notification chip">ID</span>
<button
title="Copy"
onclick="trigger('atto::copy_text', ['{{ profile.id }}'])"
class="camo small"
>
{{ icon "copy" }}
</button>
</div>
<div class="w-full flex justify-between items-center">
<span class="notification chip">Joined</span>
<span class="date">{{ profile.created }}</span>
</div>
2025-04-02 14:11:01 -04:00
2025-04-12 22:25:54 -04:00
<div class="w-full flex justify-between items-center">
<span class="notification chip">Posts</span>
<span>{{ profile.post_count }}</span>
</div>
2025-04-02 14:11:01 -04:00
{% if not profile.settings.private_last_seen or is_self
or is_helper %}
<div class="w-full flex justify-between items-center">
<span class="notification chip">Last seen</span>
2025-04-02 14:19:37 -04:00
<div class="flex">
{{ components::online_indicator(user=profile) }}
<span class="date">
{{ profile.last_seen }}
</span>
</div>
2025-04-02 14:11:01 -04:00
</div>
2025-05-18 16:43:56 -04:00
{%- endif %}
</div>
</div>
2025-05-18 16:43:56 -04:00
{% if not is_self and user -%}
<div class="card-nest">
<div class="card small">
<b>{{ text "auth:label.relationship" }}</b>
</div>
<div class="card flex gap-2 flex-wrap">
2025-05-18 16:43:56 -04:00
{% if not is_blocking -%}
<button
onclick="toggle_follow_user(event)"
2025-05-18 21:17:56 -04:00
class="{% if is_following %} hidden{% endif %}"
atto_tag="user.follow"
>
{{ icon "user-plus" }}
2025-04-19 18:59:55 -04:00
<span>{{ text "auth:action.follow" }}</span>
</button>
<button
onclick="toggle_follow_user(event)"
2025-05-18 21:17:56 -04:00
class="quaternary red{% if not is_following %} hidden{% endif %}"
atto_tag="user.unfollow"
>
{{ icon "user-minus" }}
2025-04-19 18:59:55 -04:00
<span>{{ text "auth:action.unfollow" }}</span>
</button>
<button
onclick="toggle_block_user()"
class="quaternary red"
>
{{ icon "shield" }}
2025-04-19 18:59:55 -04:00
<span>{{ text "auth:action.block" }}</span>
</button>
{% else %}
<button
onclick="toggle_block_user()"
class="quaternary red"
>
{{ icon "shield-off" }}
2025-04-19 18:59:55 -04:00
<span>{{ text "auth:action.unblock" }}</span>
</button>
2025-05-18 16:43:56 -04:00
{%- endif %} {% if not user.settings.private_chats or
2025-04-27 23:11:37 -04:00
is_following_you %}
<button
onclick="create_group_chat()"
class="quaternary"
>
{{ icon "message-circle" }}
<span>{{ text "auth:action.message" }}</span>
</button>
2025-05-18 16:43:56 -04:00
{%- endif %} {% if is_helper -%}
2025-04-06 13:43:12 -04:00
<a
href="/mod_panel/profile/{{ profile.id }}"
class="button quaternary"
>
{{ icon "shield" }}
<span>{{ text "general:action.manage" }}</span>
</a>
2025-05-18 16:43:56 -04:00
{%- endif %}
<script>
2025-04-27 23:11:37 -04:00
globalThis.create_group_chat = async () => {
fetch("/api/v1/channels/group", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "{{ user.username }} & {{ profile.username }}",
members: ["{{ profile.id }}"],
}),
})
.then((res) => res.json())
.then((res) => {
trigger("atto::toast", [
res.ok ? "success" : "error",
res.message,
]);
if (res.ok) {
window.location.href = `/chats/0/${res.payload}`;
}
});
};
globalThis.toggle_follow_user = async (e) => {
await trigger("atto::debounce", [
"users::follow",
]);
fetch(
2025-04-04 21:42:08 -04:00
"/api/v1/auth/user/{{ profile.id }}/follow",
{
method: "POST",
},
)
.then((res) => res.json())
.then((res) => {
trigger("atto::toast", [
res.ok ? "success" : "error",
res.message,
]);
if (
e.target.getAttribute(
"atto_tag",
) === "user.follow"
) {
document
.querySelector(
'[atto_tag="user.follow"]',
)
.classList.add("hidden");
document
.querySelector(
'[atto_tag="user.unfollow"]',
)
.classList.remove("hidden");
} else {
document
.querySelector(
'[atto_tag="user.unfollow"]',
)
.classList.add("hidden");
document
.querySelector(
'[atto_tag="user.follow"]',
)
.classList.remove("hidden");
}
});
};
globalThis.toggle_block_user = async () => {
if (
!(await trigger("atto::confirm", [
"Are you sure you would like to do this?",
]))
) {
return;
}
fetch(
2025-04-04 21:42:08 -04:00
"/api/v1/auth/user/{{ profile.id }}/block",
{
method: "POST",
},
)
.then((res) => res.json())
.then((res) => {
trigger("atto::toast", [
res.ok ? "success" : "error",
res.message,
]);
});
};
</script>
</div>
</div>
2025-05-18 16:43:56 -04:00
{%- endif %} {% if not profile.settings.private_communities or
is_self or is_helper %}
<div class="card-nest">
<div class="card small flex gap-2 items-center">
{{ icon "users-round" }}
<span>{{ text "auth:label.joined_communities" }}</span>
</div>
<div class="card flex flex-wrap gap-2">
{% for community in communities %}
<a href="/community/{{ community.title }}">
{{ components::community_avatar(id=community.id,
community=community, size="48px") }}
</a>
{% endfor %}
</div>
</div>
2025-05-18 16:43:56 -04:00
{%- endif %}
2025-04-27 23:11:37 -04:00
<div class="flex flex-col gap-2" id="connections">
{% for key, value in profile.connections %} {% if
value[0].data.name and value[0].show_on_profile %}
<a
class="card small flush flex items-center justify-between gap-2"
href="{{ components::connection_url(key=key, value=value) }}"
>
<div class="flex items-center gap-2">
{{ components::connection_icon(key=key) }}
<b>{{ value[0].data.name }}</b>
</div>
<button class="camo small">
{{ icon "external-link" }}
</button>
</a>
2025-05-18 16:43:56 -04:00
{%- endif %} {% endfor %}
2025-04-27 23:11:37 -04:00
</div>
</div>
<div class="rhs w-full flex flex-col gap-4">
2025-04-06 13:43:12 -04:00
{% block content %}{% endblock %}
</div>
</div>
</div>
</article>
2025-05-18 16:43:56 -04:00
{% if not is_self and profile.settings.warning -%}
<script>
setTimeout(() => {
// check for warning
trigger("warnings::open", [
"{{ profile.id }}",
"{{ warning_hash }}",
"?warning=true",
]);
}, 150);
</script>
2025-05-18 16:43:56 -04:00
{%- endif %} {% if not use_user_theme -%} {{ components::theme(user=profile,
theme_preference=profile.settings.profile_theme) }} {%- endif %} {% endblock %}