Goodbye background-image hacks!

This commit is contained in:
flash 2019-09-28 21:21:23 +02:00
parent b9f3938b9a
commit 0661ca5918
20 changed files with 128 additions and 87 deletions

View file

@ -2,13 +2,13 @@
flex-shrink: 0;
background-color: @background-colour;
background-color: var(--background-colour);
background-size: cover;
background-repeat: no-repeat;
background-position: center;
display: block;
border: 0;
border-radius: 5%;
box-sizing: content-box;
box-shadow: 0 1px 4px #111;
vertical-align: middle;
max-width: 100%;
max-height: 100%;
overflow: hidden;
}

View file

@ -209,11 +209,12 @@ function commentConstruct(comment: CommentPostInfo, layer: number = 0): HTMLElem
const commentElement: HTMLDivElement = <div class="comment" id={"comment-" + comment.comment_id}>
<div class="comment__container">
<a class="avatar comment__avatar" href={urlFormat('user-profile', [{name:'user',value:comment.user_id}])}
style={"background-image: url('{0}')".replace('{0}', urlFormat('user-avatar', [
<a class="comment__avatar" href={urlFormat('user-profile', [{name:'user',value:comment.user_id}])}>
<img class="avatar" alt={comment.username} width={layer <= 1 ? 50 : 40} height={layer <= 1 ? 50 : 40} src={urlFormat('user-avatar', [
{ name: 'user', value: comment.user_id },
{ name: 'res', value: layer < 1 ? 100 : 80 }
]))}></a>
{ name: 'res', value: layer <= 1 ? 100 : 80 }
])}/>
</a>
<div class="comment__content">
<div class="comment__info">
<a class="comment__user comment__user--link" href={urlFormat('user-profile', [{name:'user',value:comment.user_id}])}
@ -231,12 +232,13 @@ function commentConstruct(comment: CommentPostInfo, layer: number = 0): HTMLElem
<input type="checkbox" id={"comment-reply-toggle-" + comment.comment_id} class="comment__reply-toggle" />
<form id={"comment-reply-" + comment.comment_id} class="comment comment--input comment--reply" method="post"
action="javascript:void(0);" onSubmit={commentPostEventHandler}>
<input type="hidden" name="csrf" value={getCSRFToken()} />
<input type="hidden" name="comment[category]" value={comment.category_id} />
<input type="hidden" name="csrf[comments]" value={getCSRFToken()} />
<input type="hidden" name="comment[reply]" value={comment.comment_id} />
<div class="comment__container">
<div class="avatar comment__avatar"
style={"background-image: url('{0}')".replace('{0}', urlFormat('user-avatar', [{name:'user',value:comment.user_id},{name:'res',value:80}]))}></div>
<div class="avatar comment__avatar">
<img class="avatar" width="40" height="40" src={urlFormat('user-avatar', [{name:'user',value:comment.user_id},{name:'res',value:80}])}/>
</div>
<div class="comment__content">
<div class="comment__info"></div>
<textarea class="comment__text input__textarea comment__text--input" name="comment[text]" placeholder="Share your extensive insights..." onKeyDown={commentInputEventHandler}></textarea>

View file

@ -81,7 +81,7 @@ window.addEventListener('load', () => {
if(loginForms.length > 0) {
for(let i = 0; i < loginForms.length; i++) {
const loginForm: HTMLFormElement = loginForms[i],
loginAvatar: HTMLElement = loginForm.getElementsByClassName('js-login-avatar')[0] as HTMLElement,
loginAvatar: HTMLImageElement = loginForm.getElementsByClassName('js-login-avatar')[0] as HTMLImageElement,
loginUsername: HTMLInputElement = loginForm.getElementsByClassName('js-login-username')[0] as HTMLInputElement;
// Initial bump, in case anything is prefilled.
@ -111,26 +111,9 @@ window.addEventListener('load', () => {
commentsInit();
forumPostingInit();
forumPollsInit();
if(Math.round(Math.random() * 1000) > 900)
<img src="about:logo" onError={() => {
let ffxPos: number = -1000;
const ffx: HTMLElement = <a href="https://firefox.com" title="This PSA is brought to you by the van de Groep &amp; von Schnitzel Alliance For A Better Tomorrow."
style={`position: fixed; bottom: ${ffxPos}px; left: calc(50% - 234px);`}>
<img src="/images/ffbxexy.png" alt="Get Firefox!"/>
</a>;
const ffxInterval: number = setInterval(() => {
ffx.style.bottom = (ffxPos++).toString() + "px";
if(ffxPos >= 10)
clearInterval(ffxInterval);
}, 100);
document.body.append(ffx);
}}/>
});
function loginFormUpdateAvatar(avatarElement: HTMLElement, usernameElement: HTMLInputElement, force: boolean = false): void {
function loginFormUpdateAvatar(avatarElement: HTMLImageElement, usernameElement: HTMLInputElement, force: boolean = false): void {
if(!force) {
if(loginFormAvatarTimeout)
return;
@ -148,10 +131,10 @@ function loginFormUpdateAvatar(avatarElement: HTMLElement, usernameElement: HTML
if(xhr.readyState !== 4)
return;
avatarElement.style.backgroundImage = "url('{0}')".replace('{0}', urlFormat('user-avatar', [
{ name: 'user', value: xhr.responseText },
avatarElement.src = urlFormat('user-avatar', [
{ name: 'user', value: xhr.responseText.indexOf('<') !== -1 ? '0' : xhr.responseText },
{ name: 'res', value: 100 },
]));
]);
});
xhr.open('GET', urlFormat('auth-resolve-user', [{name: 'username', value: encodeURIComponent(usernameElement.value)}]));
xhr.send();

View file

@ -42,6 +42,8 @@ final class TwigMisuzu extends Twig_Extension {
new Twig_Function('warning_has_duration', 'user_warning_has_duration'),
new Twig_Function('url', 'url'),
new Twig_Function('url_list', 'url_list'),
new Twig_Function('html_tag', 'html_tag'),
new Twig_Function('html_avatar', 'html_avatar'),
new Twig_Function('changelog_action_name', 'changelog_action_name'),
new Twig_Function('forum_may_have_children', 'forum_may_have_children'),
new Twig_Function('forum_may_have_topics', 'forum_may_have_topics'),

View file

@ -1,6 +1,7 @@
{% macro comments_input(category, user, perms, reply_to) %}
{% set reply_mode = reply_to is not null %}
{% from 'macros.twig' import avatar %}
{% from '_layout/input.twig' import input_hidden, input_csrf, input_checkbox %}
<form class="comment comment--input{% if reply_mode %} comment--reply{% endif %}"
@ -14,8 +15,8 @@
{% endif %}
<div class="comment__container">
<div class="avatar comment__avatar"
style="background-image:url('{{ url('user-avatar', {'user':user.user_id, 'res': (reply_mode ? 80 : 100)}) }}')">
<div class="avatar comment__avatar">
{{ avatar(user.user_id, reply_mode ? 40 : 50, user.username) }}
</div>
<div class="comment__content">
<textarea
@ -40,6 +41,7 @@
{% endmacro %}
{% macro comments_entry(comment, indent, category, user, perms) %}
{% from 'macros.twig' import avatar %}
{% from '_layout/input.twig' import input_checkbox_raw %}
{% set is_deleted = comment.comment_deleted is not null %}
{% set hide_details = is_deleted and not perms.can_delete_any %}
@ -50,11 +52,12 @@
<div class="comment{% if is_deleted %} comment--deleted{% endif %}" id="comment-{{ comment.comment_id }}">
<div class="comment__container">
{% if hide_details %}
<div class="avatar comment__avatar" style="background-image:url('{{ url('user-avatar', {'res': indent > 1 ? 80 : 100}) }}')"></div>
<div class="comment__avatar">
{{ avatar(0, indent > 1 ? 40 : 50) }}
</div>
{% else %}
<a class="avatar comment__avatar"
href="{{ url('user-profile', {'user':comment.user_id}) }}"
style="background-image:url('{{ url('user-avatar', {'user': comment.user_id, 'res': indent > 1 ? 80 : 100}) }}')">
<a class="comment__avatar" href="{{ url('user-profile', {'user':comment.user_id}) }}">
{{ avatar(comment.user_id, indent > 1 ? 40 : 50, comment.username) }}
</a>
{% endif %}
<div class="comment__content">

View file

@ -1,3 +1,4 @@
{% from 'macros.twig' import avatar %}
{% from '_layout/input.twig' import input_checkbox_raw %}
{% set site_menu = [
@ -139,11 +140,13 @@
{% endfor %}
{% if current_user is defined %}
<a href="{{ url('user-profile', {'user': current_user.user_id}) }}" class="avatar header__desktop__user__avatar" title="{{ current_user.username }}"
style="background-image:url('{{ url('user-avatar', {'user': current_user.user_id, 'res': 120}) }}');{{ current_user.user_colour|html_colour }}"></a>
<a href="{{ url('user-profile', {'user': current_user.user_id}) }}" class="avatar header__desktop__user__avatar" title="{{ current_user.username }}" style="{{ current_user.user_colour|html_colour }}">
{{ avatar(current_user.user_id, 60, current_user.username) }}
</a>
{% else %}
<a href="{{ url('auth-login') }}" class="avatar header__desktop__user__avatar"
style="background-image:url('{{ url('user-avatar', {'res': 120}) }}');"></a>
<a href="{{ url('auth-login') }}" class="avatar header__desktop__user__avatar">
{{ avatar(0, 60, 'Log in') }}
</a>
{% endif %}
</div>
</div>
@ -158,8 +161,8 @@
{{ globals.site_name }}
</a>
<label class="header__mobile__icon avatar header__mobile__avatar" for="toggle-mobile-header"
style="background-image:url('{{ url('user-avatar', {'user': current_user.user_id|default(0), 'res': 80}) }}');">
<label class="header__mobile__icon header__mobile__avatar" for="toggle-mobile-header">
{{ avatar(current_user.user_id|default(0), 40, current_user.username|default('Log in')) }}
</label>
</div>

View file

@ -1,4 +1,5 @@
{% extends 'auth/master.twig' %}
{% from 'macros.twig' import avatar %}
{% from '_layout/input.twig' import input_hidden, input_csrf, input_text %}
{% set title = 'Login' %}
@ -11,7 +12,9 @@
<div class="container__title">
<div class="container__title__background"></div>
<div class="auth__login__header">
<div class="avatar auth__login__avatar js-login-avatar" style="background-image:url('{{ url('user-avatar', {'res': 200}) }}');"></div>
<div class="auth__login__avatar">
{{ avatar(0, 100, 'Avatar', {'class':'js-login-avatar'}) }}
</div>
</div>
</div>

View file

@ -1,5 +1,5 @@
{% extends 'changelog/master.twig' %}
{% from 'macros.twig' import container_title %}
{% from 'macros.twig' import container_title, avatar %}
{% from '_layout/comments.twig' import comments_section %}
{% set title = 'Changelog » Change #' ~ change.change_id %}
@ -40,9 +40,8 @@
<div class="changelog__change__info__content">
{% if change.user_id is not null %}
<div class="changelog__change__user">
<a class="avatar changelog__change__avatar"
style="background-image:url('{{ url('user-avatar', {'user': change.user_id, 'res': 120}) }}');"
href="{{ url('user-profile', {'user': change.user_id}) }}">
<a class="changelog__change__avatar" href="{{ url('user-profile', {'user': change.user_id}) }}">
{{ avatar(change.user_id, 60, change.username) }}
</a>
<div class="changelog__change__user__details">

View file

@ -1,4 +1,5 @@
{% extends 'forum/master.twig' %}
{% from 'macros.twig' import avatar %}
{% from 'forum/macros.twig' import forum_header %}
{% set title = 'Forum Leaderboard » ' ~ leaderboard_name %}
@ -35,7 +36,7 @@
<a href="{{ url('user-profile', {'user': user.user_id}) }}" class="forum__leaderboard__user__background"></a>
<div class="forum__leaderboard__user__content">
<div class="forum__leaderboard__user__rank">{{ user.rank|number_format }}</div>
<div class="avatar forum__leaderboard__user__avatar" style="background-image:url('{{ url('user-avatar', {'user': user.user_id, 'r': 80}) }}')"></div>
<div class="forum__leaderboard__user__avatar">{{ avatar(user.user_id, user.rank == 1 ? 50 : 40, user.username) }}</div>
<div class="forum__leaderboard__user__username">{{ user.username }}</div>
<div class="forum__leaderboard__user__posts">{{ user.posts|number_format }} posts</div>
</div>

View file

@ -108,6 +108,7 @@
{% endmacro %}
{% macro forum_category_entry(forum, forum_unread, forum_icon) %}
{% from 'macros.twig' import avatar %}
{% set forum_unread = forum_unread|default(forum.forum_unread|default(false)) ? 'unread' : 'read' %}
{% if forum_icon is empty %}
@ -198,9 +199,8 @@
</div>
{% if forum.recent_post_user_id is not null %}
<a href="{{ url('user-profile', {'user': forum.recent_post_user_id}) }}"
class="avatar forum__category__avatar"
style="background-image:url('{{ url('user-avatar', {'user': forum.recent_post_user_id, 'res': 80}) }}')">
<a href="{{ url('user-profile', {'user': forum.recent_post_user_id}) }}" class="avatar forum__category__avatar">
{{ avatar(forum.recent_post_user_id, 40, forum.recent_post_username) }}
</a>
{% endif %}
{% endif %}
@ -254,6 +254,7 @@
{% endmacro %}
{% macro forum_topic_entry(topic, topic_icon, topic_unread) %}
{% from 'macros.twig' import avatar %}
{% set topic_unread = topic_unread|default(topic.topic_unread|default(false)) %}
{% set topic_important = topic.topic_type == constant('MSZ_TOPIC_TYPE_STICKY') or topic.topic_type == constant('MSZ_TOPIC_TYPE_ANNOUNCEMENT') or topic.topic_type == constant('MSZ_TOPIC_TYPE_GLOBAL_ANNOUNCEMENT') %}
{% set has_priority_voting = forum_has_priority_voting(topic.forum_type) %}
@ -354,9 +355,8 @@
</div>
{% if topic.respondent_id is not null %}
<a href="{{ url('user-profile', {'user': topic.respondent_id}) }}"
class="avatar forum__topic__avatar"
style="background-image:url('{{ url('user-avatar', {'user': topic.respondent_id, 'res': 60}) }}')">
<a href="{{ url('user-profile', {'user': topic.respondent_id}) }}" class="forum__topic__avatar">
{{ avatar(topic.respondent_id, 30, topic.respondent_name) }}
</a>
{% endif %}
</div>

View file

@ -1,4 +1,5 @@
{% extends 'forum/master.twig' %}
{% from 'macros.twig' import avatar %}
{% from 'forum/macros.twig' import forum_header %}
{% from '_layout/input.twig' import input_hidden, input_csrf, input_text, input_button, input_select, input_checkbox %}
@ -46,7 +47,7 @@
<div class="forum__post__info">
<div class="forum__post__info__background"></div>
<div class="forum__post__info__content">
<span class="avatar forum__post__avatar" style="background-image:url('{{ url('user-avatar', {'user': posting_post.poster_id|default(current_user.user_id), 'res': 240}) }}');"></span>
<span class="forum__post__avatar">{{ avatar(posting_post.poster_id|default(current_user.user_id), 120, posting_post.poster_name|default(current_user.username)) }}</span>
<span class="forum__post__username">{{ posting_post.poster_name|default(current_user.username) }}</span>

View file

@ -1,5 +1,5 @@
{% extends 'home/master.twig' %}
{% from 'macros.twig' import container_title %}
{% from 'macros.twig' import container_title, avatar %}
{% from 'news/macros.twig' import news_preview %}
{% from 'changelog/macros.twig' import changelog_listing %}
@ -76,8 +76,8 @@
<div class="landing__online">
{% for user in online_users %}
<a href="{{ url('user-profile', {'user': user.user_id}) }}" class="avatar landing__online__user" style="{{ user.user_colour|html_colour }}; background-image: url('{{ url('user-avatar', {'user': user.user_id, 'res': 60}) }}');" title="{{ user.username }}">
{{ user.username }}
<a href="{{ url('user-profile', {'user': user.user_id}) }}" class="landing__online__user" title="{{ user.username }}">
{{ avatar(user.user_id, 30, user.username) }}
</a>
{% endfor %}
</div>
@ -89,8 +89,8 @@
{{ container_title('<i class="fas fa-birthday-cake fa-fw"></i> Happy Birthday!') }}
{% for birthday in birthdays %}
<a class="landing__latest" style="{# birthday.user_colour|html_colour #}" href="{{ url('user-profile', {'user': birthday.user_id}) }}">
<div class="avatar landing__latest__avatar" style="background-image: url('{{ url('user-avatar', {'user': birthday.user_id, 'res': 100}) }}')"></div>
<a class="landing__latest" href="{{ url('user-profile', {'user': birthday.user_id}) }}">
<div class="landing__latest__avatar">{{ avatar(birthday.user_id, 50, birthday.username) }}</div>
<div class="landing__latest__content">
<div class="landing__latest__username">
{{ birthday.username }}
@ -109,7 +109,7 @@
{{ container_title('<i class="fas fa-user-plus fa-fw"></i> Newest User') }}
<a class="landing__latest" style="{{ latest_user.user_colour|html_colour }}" href="{{ url('user-profile', {'user': latest_user.user_id}) }}">
<div class="avatar landing__latest__avatar" style="background-image: url('{{ url('user-avatar', {'user': latest_user.user_id, 'res': 100}) }}')"></div>
<div class="landing__latest__avatar">{{ avatar(latest_user.user_id, 50, latest_user.username) }}</div>
<div class="landing__latest__content">
<div class="landing__latest__username">
{{ latest_user.username }}

View file

@ -87,7 +87,6 @@
</div>
{% endmacro %}
{% macro avatar(user_id, resolution, alt_text) %}
{% set avatar_url = url('user-avatar', {'user': user_id, 'res': resolution * 2}) %}
<img class="avatar" src="{{ avatar_url }}" width="{{ resolution }}" height="{{ resolution }}" alt="{{ alt_text|default(avatar_url) }}">
{% macro avatar(user_id, resolution, alt_text, attributes) %}
{{ html_avatar(user_id, resolution, alt_text|default(''), attributes|default([]))|raw }}
{% endmacro %}

View file

@ -1,5 +1,5 @@
{% extends 'manage/users/master.twig' %}
{% from 'macros.twig' import pagination, container_title %}
{% from 'macros.twig' import pagination, container_title, avatar %}
{% set users_pagination = pagination(manage_users_pagination, url('manage-users')) %}
@ -19,7 +19,7 @@
<a href="{{ url('manage-user', {'user': user.user_id}) }}" class="manage__user-item__background"></a>
<div class="manage__user-item__container">
<div class="avatar manage__user-item__avatar" style="background-image: url('{{ url('user-avatar', {'user': user.user_id, 'res': 80}) }}')"></div>
<div class="manage__user-item__avatar">{{ avatar(user.user_id, 40, user.username) }}</div>
<div class="manage__user-item__info">
<div class="manage__user-item__name">
{{ user.username }}

View file

@ -1,5 +1,5 @@
{% macro news_preview(post) %}
{% from 'macros.twig' import container_title %}
{% from 'macros.twig' import container_title, avatar %}
<div class="container news__preview" style="{% if post.user_colour is not null %}{{ post.user_colour|html_colour }}{% endif %}">
<div class="news__preview__info">
@ -7,9 +7,8 @@
<div class="news__preview__info__content">
{% if post.user_id is not null %}
<div class="news__preview__user">
<a class="avatar news__preview__avatar"
style="background-image:url('{{ url('user-avatar', {'user': post.user_id, 'res': 120}) }}');"
href="{{ url('user-profile', {'user': post.user_id}) }}">
<a class="news__preview__avatar" href="{{ url('user-profile', {'user': post.user_id}) }}">
{{ avatar(post.user_id, 60, post.username) }}
</a>
<div class="news__preview__user__details">
@ -47,15 +46,16 @@
{% endmacro %}
{% macro news_post(post) %}
{% from 'macros.twig' import avatar %}
<div class="container news__post" style="{% if post.user_colour is not null %}{{ post.user_colour|html_colour('--accent-colour') }}{% endif %}">
<div class="news__post__info">
<div class="news__post__info__background"></div>
<div class="news__post__info__content">
{% if post.user_id is not null %}
<div class="news__post__user">
<a class="avatar news__post__avatar"
style="background-image:url('{{ url('user-avatar', {'user': post.user_id, 'res': 120}) }}');"
href="{{ url('user-profile', {'user': post.user_id}) }}">
<a class="news__post__avatar" href="{{ url('user-profile', {'user': post.user_id}) }}">
{{ avatar(post.user_id, 60, post.username) }}
</a>
<div class="news__post__user__details">

View file

@ -1,3 +1,4 @@
{% from 'macros.twig' import avatar %}
{% from '_layout/input.twig' import input_checkbox_raw %}
<div class="container profile__header">
@ -6,10 +7,9 @@
<div class="profile__header__details">
<div class="profile__header__avatar">
{% if profile_is_editing and perms.edit_avatar %}
<label class="avatar profile__header__avatar__image profile__header__avatar__image--edit"
style="background-image:url('{{ image }}')"
id="avatar-preview"
for="avatar-selection"></label>
<label class="profile__header__avatar__image profile__header__avatar__image--edit" for="avatar-selection">
{{ avatar(profile.user_id, 120, profile.username, {'id': 'avatar-preview'}) }}
</label>
<div class="profile__header__avatar__options">
<label class="input__button profile__header__avatar__option" for="avatar-selection">
@ -23,7 +23,9 @@
</label>
</div>
{% else %}
<div class="avatar profile__header__avatar__image" style="background-image:url('{{ image }}')"></div>
<div class="profile__header__avatar__image">
{{ avatar(profile.user_id|default(0), 120, profile.username|default('')) }}
</div>
{% endif %}
</div>

View file

@ -22,7 +22,7 @@
function updateAvatarPreview(name, url, preview) {
url = url || "{{ url('user-avatar', {'user': profile.user_id, 'res': 240})|raw }}";
preview = preview || document.getElementById('avatar-preview');
preview.style.backgroundImage = 'url(\'{0}\')'.replace('{0}', url);
preview.src = url;
preview.title = name;
}

View file

@ -1,7 +1,7 @@
{% extends 'master.twig' %}
{% if profile is defined %}
{% set image = url('user-avatar', {'user': profile.user_id, 'res': 240}) %}
{% set image = url('user-avatar', {'user': profile.user_id, 'res': 200}) %}
{% set manage_link = url('manage-user', {'user': profile.user_id}) %}
{% set stats = [
{

View file

@ -1,4 +1,6 @@
{% macro user_card(user) %}
{% from 'macros.twig' import avatar %}
<div class="usercard"{% if user.user_colour is defined %} style="{{ user.user_colour|html_colour('--accent-colour') }}"{% endif %}>
<div class="usercard__background"></div>
@ -6,8 +8,8 @@
<a class="usercard__header__link" href="{{ url('user-profile', {'user': user.user_id}) }}"></a>
<div class="usercard__header__container">
<div class="avatar usercard__header__avatar"
style="background-image:url('{{ url('user-avatar', {'user': user.user_id, 'res': 120}) }}')">
<div class="usercard__header__avatar">
{{ avatar(user.user_id, 60, user.username) }}
</div>
<div class="usercard__header__details">
@ -263,10 +265,12 @@
{% endmacro %}
{% macro user_account_log(data, strings) %}
{% from 'macros.twig' import avatar %}
<div class="settings__account-log" id="account-log-{{ data.log_id }}">
{% if data.user_id is defined %}
<a href="{{ url('user-profile', {'user': data.user_id}) }}" class="settings__account-log__user" style="{{ data.user_colour|html_colour }}">
<div class="avatar settings__account-log__user__avatar" style="background-image:url('{{ url('user-avatar', {'user': data.user_id, 'res': 40}) }}');"></div>
<div class="settings__account-log__user__avatar">{{ avatar(data.user_id, 20, data.username) }}</div>
<div class="settings__account-log__user__name">{{ data.username }}</div>
</a>
{% endif %}
@ -308,6 +312,7 @@
{% endmacro %}
{% macro user_profile_warning(warning, show_private_note, show_user_info, delete_csrf) %}
{% from 'macros.twig' import avatar %}
{% if warning.warning_type == constant('MSZ_WARN_SILENCE') %}
{% set warning_text = 'Silence' %}
{% set warning_class = 'silence' %}
@ -331,7 +336,9 @@
{% if warning.username is defined or warning.user_ip is defined %}
<div class="profile__warning__user">
{% if warning.username is defined %}
<div class="avatar profile__warning__user__avatar" style="background-image:url('{{ url('user-avatar', {'user': warning.user_id, 'res': 40}) }}');"></div>
<div class="profile__warning__user__avatar">
{{ avatar(warning.user_id, 20, warning.username) }}
</div>
<a class="profile__warning__user__username" href="{{ url('user-profile', {'user': warning.user_id}) }}">
{{ warning.username }}
</a>
@ -346,7 +353,9 @@
{% endif %}
<div class="profile__warning__user">
<div class="avatar profile__warning__user__avatar" style="background-image:url('{{ url('user-avatar', {'user': warning.issuer_id, 'res': 40}) }}');"></div>
<div class="profile__warning__user__avatar">
{{ avatar(warning.issuer_id, 20, warning.issuer_username) }}
</div>
<a class="profile__warning__user__username" href="{{ url('user-profile', {'user': warning.user_id}) }}">
{{ warning.issuer_username }}
</a>

View file

@ -149,3 +149,37 @@ function html_colour(?int $colour, $attribs = '--user-colour'): string {
return $css;
}
function html_avatar(int $userId, int $resolution, string $altText = '', array $attributes = []): string {
$attributes['src'] = url('user-avatar', ['user' => $userId, 'res' => $resolution * 2]);
$attributes['alt'] = $altText;
$attributes['class'] = trim('avatar ' . ($attributes['class'] ?? ''));
if(!isset($attributes['width']))
$attributes['width'] = $resolution;
if(!isset($attributes['height']))
$attributes['height'] = $resolution;
return html_tag('img', $attributes);
}
function html_tag(string $name, array $atrributes = [], ?bool $close = null, string $content = ''): string {
$html = '<' . $name;
foreach($atrributes as $key => $value) {
$html .= ' ' . $key;
if(!empty($value))
$html .= '="' . $value . '"';
}
if($close === false)
$html .= '/';
$html .= '>';
if($close === true)
$html .= $content . '</' . $name . '>';
return $html;
}