2022-09-13 13:14:49 +00:00
{% extends 'profile/master.twig' %}
{% from 'macros.twig' import container_title %}
{% from '_layout/input.twig' import input_hidden , input_csrf , input_text , input_checkbox , input_file , input_file_raw , input_select %}
{% if profile_user is defined %}
{% set canonical_url = url ( 'user-profile' , { 'user' : profile_user .id } ) %}
2023-08-02 22:12:47 +00:00
{% set title = profile_user .name %}
2022-09-13 13:14:49 +00:00
{% else %}
{% set title = 'User not found!' %}
{% endif %}
{% block content %}
{% if profile_is_editing %}
<form class="profile" method="post" action=" {{ url ( 'user-profile' , { 'user' : profile_user .id } ) }} " enctype="multipart/form-data">
2023-08-06 19:09:59 +00:00
{{ input_csrf ( ) }}
2022-09-13 13:14:49 +00:00
{% if perms .edit_avatar %}
{{ input_file_raw ( 'avatar[file]' , 'profile__hidden' , [ 'image/png' , 'image/jpeg' , 'image/gif' ] , { 'id' :'avatar-selection' } ) }}
<script>
function updateAvatarPreview(name, url, preview) {
url = url || " {{ url ( 'user-avatar' , { 'user' : profile_user .id , 'res' : 2 4 0 } ) | raw }} ";
preview = preview || document.getElementById('avatar-preview');
preview.src = url;
preview.title = name;
}
document.getElementById('avatar-selection').addEventListener('change', function (ev) {
updateAvatarPreview(ev.target.files[0].name, URL.createObjectURL(ev.target.files[0]));
});
</script>
{% endif %}
{% else %}
<div class="profile">
{% endif %}
{% include 'profile/_layout/header.twig' %}
{% if profile_is_editing %}
<div class="container profile__container profile__guidelines">
<ul class="profile__guidelines__section">
<li class="profile__guidelines__line profile__guidelines__line--header">General</li>
<li class="profile__guidelines__line">Keep things sane and generally suitable for all ages.</li>
<li class="profile__guidelines__line">Make sure to adhere to the <a href=" {{ url ( 'info' , { 'title' : 'rules' } ) }} " class="profile__guidelines__link">rules</a>.</li>
</ul>
{% if perms .edit_avatar %}
<ul class="profile__guidelines__section">
<li class="profile__guidelines__line profile__guidelines__line--header">Avatar</li>
2023-08-31 21:33:34 +00:00
<li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis"> {{ profile_avatar_info .maxBytes | format_filesize }} </span> file size limit.</li>
2023-08-02 22:12:47 +00:00
<li class="profile__guidelines__line">May not be larger than <span class="profile__guidelines__emphasis"> {{ profile_avatar_info .maxWidth }} x {{ profile_avatar_info .maxHeight }} </span>.</li>
2022-09-13 13:14:49 +00:00
<li class="profile__guidelines__line">Will be centre cropped and scaled to at most <span class="profile__guidelines__emphasis">240x240</span>.</li>
2023-07-05 23:09:28 +00:00
<li class="profile__guidelines__line">Animated GIF images are allowed.</li>
2022-09-13 13:14:49 +00:00
</ul>
{% endif %}
{% if perms .edit_background %}
<ul class="profile__guidelines__section">
<li class="profile__guidelines__line profile__guidelines__line--header">Background</li>
2023-08-31 21:33:34 +00:00
<li class="profile__guidelines__line">May not exceed the <span class="profile__guidelines__emphasis"> {{ profile_background_info .maxBytes | format_filesize }} </span> file size limit.</li>
2023-08-02 22:12:47 +00:00
<li class="profile__guidelines__line">May not be larger than <span class="profile__guidelines__emphasis"> {{ profile_background_info .maxWidth }} x {{ profile_background_info .maxHeight }} </span>.</li>
2023-07-05 23:09:28 +00:00
<li class="profile__guidelines__line">GIF images, in general, are only allowed when tiling.</li>
2022-09-13 13:14:49 +00:00
</ul>
{% endif %}
</div>
{% endif %}
{% if profile_notices | length > 0 %}
<div class="warning">
<div class="warning__content">
{% for notice in profile_notices %}
<p> {{ notice }} </p>
{% endfor %}
</div>
</div>
{% endif %}
<div class="profile__content">
2023-07-25 15:03:25 +00:00
{% set show_profile_fields = not profile_is_guest and ( profile_is_editing ? perms .edit_profile : profile_fields_display_values | default ( [ ] ) is not empty ) %}
2022-09-13 13:14:49 +00:00
{% set show_background_settings = profile_is_editing and perms .edit_background %}
{% set show_birthdate = profile_is_editing and perms .edit_birthdate %}
2024-02-13 21:22:56 +00:00
{% set show_active_forum_info = not profile_is_guest and not profile_is_deleted and not profile_is_editing and profile_active_topic_info .id | default ( 0 ) > 0 %}
2023-07-26 22:43:50 +00:00
{% set show_warnings = profile_warnings is defined and profile_warnings | length > 0 %}
{% set show_sidebar = ( not profile_is_banned or profile_can_edit ) and ( profile_is_guest or show_profile_fields or show_background_settings or show_birthdate or show_active_forum_info or show_warnings ) %}
2022-09-13 13:14:49 +00:00
{% if show_sidebar %}
<div class="profile__content__side">
{% if show_background_settings %}
<div class="container profile__container profile__background-settings">
{{ container_title ( 'Background' ) }}
<div class="profile__background-settings__content">
{{ input_file ( 'background[file]' , '' , [ 'image/png' , 'image/jpeg' , 'image/gif' ] , { 'id' :'background-selection' } ) }}
{{ input_checkbox ( 'background[attach]' , 'None' , true , '' , 0 , true , { 'onchange' :'profileChangeBackgroundAttach(this.value)' } ) }}
{% for key , value in background_attachments %}
2023-08-02 22:12:47 +00:00
{{ input_checkbox ( 'background[attach]' , value , key == profile_background_info .attachment , '' , key , true , { 'onchange' :'profileChangeBackgroundAttach(this.value)' } ) }}
2022-09-13 13:14:49 +00:00
{% endfor %}
2023-08-02 22:12:47 +00:00
{{ input_checkbox ( 'background[attr][blend]' , 'Blend' , profile_background_info .blend , '' , '' , false , { 'onchange' :'profileToggleBackgroundAttr(\'blend\', this.checked)' } ) }}
{{ input_checkbox ( 'background[attr][slide]' , 'Slide' , profile_background_info .slide , '' , '' , false , { 'onchange' :'profileToggleBackgroundAttr(\'slide\', this.checked)' } ) }}
2022-09-13 13:14:49 +00:00
</div>
</div>
{% endif %}
2023-08-02 22:12:47 +00:00
{% if profile_is_guest and not profile_is_deleted %}
2022-09-13 13:14:49 +00:00
<div class="container profile__container">
<div class="profile__accounts__notice">
You must <a href=" {{ url ( 'auth-login' ) }} " class="profile__accounts__link">log in</a> to view full profiles!
</div>
</div>
{% elseif show_profile_fields %}
<div class="container profile__container profile__accounts">
{{ container_title ( 'Elsewhere' ) }}
<div class="profile__accounts__content">
2023-07-20 19:36:43 +00:00
{% for fieldInfo in profile_fields_infos %}
{% if profile_is_editing or profile_fields_display_values [ fieldInfo .name ] is defined %}
<label class="profile__accounts__item">
<div class="profile__accounts__title">
{{ fieldInfo .title }}
2022-09-13 13:14:49 +00:00
</div>
2023-07-20 19:36:43 +00:00
{% if profile_is_editing %}
{{ input_text ( 'profile[' ~ fieldInfo .name ~ ']' , 'profile__accounts__input' , profile_fields_raw_values [ fieldInfo .name ] | default ( '' ) ) }}
{% else %}
<div class="profile__accounts__value">
{% if profile_fields_link_values [ fieldInfo .name ] is defined %}
<a href=" {{ profile_fields_link_values [ fieldInfo .name ] }} " class="profile__accounts__link" target="_blank" rel="noreferrer noopener"> {{ profile_fields_display_values [ fieldInfo .name ] }} </a>
{% else %}
{{ profile_fields_display_values [ fieldInfo .name ] }}
{% endif %}
</div>
{% endif %}
</label>
{% endif %}
2022-09-13 13:14:49 +00:00
{% endfor %}
</div>
</div>
{% endif %}
2023-02-10 09:04:15 +00:00
{% if show_active_forum_info %}
<div class="container profile__container profile__forum-activity">
{{ container_title ( 'Forum Activity' ) }}
<div class="profile__forum-activity__content">
2023-08-28 14:45:32 +00:00
{% if profile_active_category_info is defined and profile_active_category_info is not empty %}
2023-02-10 09:04:15 +00:00
<div class="profile__forum-activity__category">
<div class="profile__forum-activity__leader">
Most active category
</div>
<div class="forum__category">
2023-08-28 01:17:34 +00:00
<a href=" {{ url ( 'forum-category' , { 'forum' : profile_active_category_info .id } ) }} " class="forum__category__link"></a>
2023-02-10 09:04:15 +00:00
<div class="forum__category__container">
<div class="forum__category__icon">
2023-08-28 01:17:34 +00:00
<span class=" {{ profile_active_category_info .iconForDisplay }} "></span>
2023-02-10 09:04:15 +00:00
</div>
<div class="forum__category__details">
<div class="forum__category__title">
2023-08-28 01:17:34 +00:00
{{ profile_active_category_info .name }}
2023-02-10 09:04:15 +00:00
</div>
<div class="forum__category__description">
2023-08-28 01:17:34 +00:00
{{ profile_active_category_stats .postCount | number_format }} post {{ profile_active_category_stats .postCount == 1 ? '' : 's' }}
/ {{ ( ( profile_active_category_stats .postCount / profile_stats .forum_post_count ) * 1 0 0 ) | number_format ( 2 ) }} % of total posts
2023-02-10 09:04:15 +00:00
</div>
</div>
</div>
</div>
</div>
{% endif %}
2023-08-28 14:45:32 +00:00
{% if profile_active_topic_info is defined and profile_active_topic_info is not empty %}
2023-02-10 09:04:15 +00:00
<div class="profile__forum-activity__topic">
<div class="profile__forum-activity__leader">
Most active topic
</div>
2024-11-30 04:09:29 +00:00
<div class="forum__topic {% if profile_active_topic_info .locked %} forum__topic--locked {% endif %} ">
2023-08-28 01:17:34 +00:00
<a href=" {{ url ( 'forum-topic' , { 'topic' : profile_active_topic_info .id } ) }} " class="forum__topic__link"></a>
2023-02-10 09:04:15 +00:00
<div class="forum__topic__container">
<div class="forum__topic__icon">
2023-08-28 01:17:34 +00:00
<i class=" {{ profile_active_topic_info .iconForDisplay }} fa-fw"></i>
2023-02-10 09:04:15 +00:00
</div>
<div class="forum__topic__details">
<div class="forum__topic__title">
<span class="forum__topic__title__inner">
2023-08-28 01:17:34 +00:00
{{ profile_active_topic_info .title }}
2023-02-10 09:04:15 +00:00
</span>
</div>
<div class="forum__topic__info">
2023-08-28 01:17:34 +00:00
{{ profile_active_topic_stats .postCount | number_format }} post {{ profile_active_topic_stats .postCount == 1 ? '' : 's' }}
/ {{ ( ( profile_active_topic_stats .postCount / profile_stats .forum_post_count ) * 1 0 0 ) | number_format ( 2 ) }} % of total posts
2023-02-10 09:04:15 +00:00
</div>
</div>
</div>
</div>
</div>
{% endif %}
</div>
</div>
{% endif %}
2022-09-13 13:14:49 +00:00
{% if show_birthdate %}
<div class="container profile__container profile__birthdate">
{{ container_title ( 'Birthdate' ) }}
<div class="profile__birthdate__content">
<div class="profile__birthdate__date">
<label class="profile__birthdate__label">
<div class="profile__birthdate__title">
Day
</div>
2023-08-02 22:12:47 +00:00
{{ input_select ( 'birthdate[day]' , [ '-' ] | merge ( range ( 1 , 3 1 ) ) , profile_user .hasBirthdate ? profile_user .birthdate .day : 0 , '' , '' , true , 'profile__birthdate__select profile__birthdate__select--day' ) }}
2022-09-13 13:14:49 +00:00
</label>
<label class="profile__birthdate__label">
<div class="profile__birthdate__title">
Month
</div>
2023-08-02 22:12:47 +00:00
{{ input_select ( 'birthdate[month]' , [ '-' ] | merge ( range ( 1 , 1 2 ) ) , profile_user .hasBirthdate ? profile_user .birthdate .month : 0 , '' , '' , true , 'profile__birthdate__select profile__birthdate__select--month' ) }}
2022-09-13 13:14:49 +00:00
</label>
</div>
<div class="profile__birthdate__year">
<label class="profile__birthdate__label">
<div class="profile__birthdate__title">
Year (may be left empty)
</div>
2023-08-02 22:12:47 +00:00
{{ input_select ( 'birthdate[year]' , [ '-' ] | merge ( range ( null | date ( 'Y' ) , null | date ( 'Y' ) - 1 0 0 ) ) , profile_user .birthdate .year | default ( 0 ) , '' , '' , true , 'profile__birthdate__select profile__birthdate__select--year' ) }}
2022-09-13 13:14:49 +00:00
</label>
</div>
</div>
</div>
{% endif %}
2023-07-26 22:43:50 +00:00
{% if show_warnings %}
<div class="container profile__container" style="--accent-colour: #c84;">
{{ container_title ( 'Warnings' ) }}
<div class="profile__warnings">
{% for warning in profile_warnings %}
<div class="profile__warnings__item">
<div class="profile__warnings__datetime">
<time datetime=" {{ warning .createdTime | date ( 'c' ) }} " title=" {{ warning .createdTime | date ( 'r' ) }} "> {{ warning .createdTime | time_format }} </time>
</div>
<div class="profile__warnings__body">
{% for line in warning .bodyLines %}
<p> {{ line }} </p>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
2022-09-13 13:14:49 +00:00
</div>
{% endif %}
{% if profile_user is defined %}
<div class="profile__content__main">
2024-11-30 04:09:29 +00:00
{% if ( not profile_is_banned or profile_can_edit ) and ( ( profile_is_editing and perms .edit_about ) or profile_user .aboutBody is not empty ) %}
2022-09-13 13:14:49 +00:00
<div class="container profile__container profile__about" id="about">
2023-08-02 22:12:47 +00:00
{{ container_title ( 'About ' ~ profile_user .name ) }}
2022-09-13 13:14:49 +00:00
{% if profile_is_editing %}
<div class="profile__signature__editor">
2024-11-30 04:09:29 +00:00
{{ input_select ( 'about[parser]' , constant ( '\\Misuzu\\Parsers\\Parser::NAMES' ) , profile_user .aboutBodyParser , '' , '' , false , 'profile__about__select' ) }}
<textarea name="about[text]" class="input__textarea profile__about__text" id="about-textarea"> {{ profile_user .aboutBody }} </textarea>
2022-09-13 13:14:49 +00:00
</div>
{% else %}
2024-11-30 04:09:29 +00:00
<div class="profile__about__content {% if profile_is_editing %} profile__about__content--edit {% elseif profile_user .isAboutBodyMarkdown %} markdown {% endif %} ">
{{ profile_user .aboutBody | escape | parse_text ( profile_user .aboutBodyParser ) | raw }}
2022-09-13 13:14:49 +00:00
</div>
{% endif %}
</div>
{% endif %}
2024-11-30 04:09:29 +00:00
{% if ( not profile_is_banned or profile_can_edit ) and ( ( profile_is_editing and perms .edit_signature ) or profile_user .signatureBody is not empty ) %}
2022-09-13 13:14:49 +00:00
<div class="container profile__container profile__signature" id="signature">
{{ container_title ( 'Signature' ) }}
{% if profile_is_editing %}
<div class="profile__signature__editor">
2024-11-30 04:09:29 +00:00
{{ input_select ( 'signature[parser]' , constant ( '\\Misuzu\\Parsers\\Parser::NAMES' ) , profile_user .signatureBodyParser , '' , '' , false , 'profile__signature__select' ) }}
<textarea name="signature[text]" class="input__textarea profile__signature__text" id="signature-textarea"> {{ profile_user .signatureBody }} </textarea>
2022-09-13 13:14:49 +00:00
</div>
{% else %}
2024-11-30 04:09:29 +00:00
<div class="profile__signature__content {% if profile_is_editing %} profile__signature__content--edit {% elseif profile_user .isSignatureBodyMarkdown %} markdown {% endif %} ">
{{ profile_user .signatureBody | escape | parse_text ( profile_user .signatureBodyParser ) | raw }}
2022-09-13 13:14:49 +00:00
</div>
{% endif %}
</div>
{% endif %}
{% endif %}
</div>
</div>
{% if profile_is_editing %}
</form>
<script>
let profilePreviousBackground = null;
function profileToggleBackground(checked) {
let currentBg = document.body.style.getPropertyValue('--background-image');
if(currentBg != 'initial' && checked) {
profilePreviousBackground = currentBg;
currentBg = 'initial';
} else if(currentBg == 'initial' && !checked) {
currentBg = profilePreviousBackground;
}
document.body.style.setProperty('--background-image', currentBg);
}
function profileChangeBackgroundAttach(mode) {
const modes = {
1: 'cover',
2: 'stretch',
3: 'tile',
4: 'contain',
};
profileToggleBackground(mode == 0);
for(let i = 1; i <= Object.keys(modes).length; i++)
document.body.classList.remove('main--bg-' + modes[i]);
if(!modes[mode])
return;
document.body.classList.add('main--bg-' + modes[mode]);
}
function profileToggleBackgroundAttr(attr, mode) {
let className = '';
switch(attr) {
case 'blend':
className = 'main--bg-blend';
break;
case 'slide':
className = 'main--bg-slide';
break;
}
if(className) {
if(mode)
document.body.classList.add(className);
else
document.body.classList.remove(className);
}
}
document.getElementById('background-selection').addEventListener('change', ev => {
const image = new Image();
image.src = URL.createObjectURL(ev.target.files[0]);
image.addEventListener('load', () => {
document.body.style.setProperty('--background-image', 'url(%)'.replace('%', image.src));
document.body.style.setProperty('--background-width', '%px'.replace('%', image.width));
document.body.style.setProperty('--background-height', '%px'.replace('%', image.height));
});
});
</script>
{% else %}
</div>
{% endif %}
{% endblock %}