928 lines
47 KiB
Twig
928 lines
47 KiB
Twig
{% macro forum_category_listing(forums, title, colour, id, icon) %}
|
|
{% if forums is iterable %}
|
|
{% from _self import forum_category_listing_old %}
|
|
{{ forum_category_listing_old(forums, title, colour, id, icon) }}
|
|
{% else %}
|
|
{% from _self import forum_category_listing_new %}
|
|
{{ forum_category_listing_new(forums, title, colour) }}
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro forum_category_listing_new(category, user, title) %}
|
|
{% from _self import forum_category_entry %}
|
|
{% from 'macros.twig' import container_title %}
|
|
|
|
{% if category.canView(user) %}
|
|
{% set children = category.children(user) %}
|
|
|
|
{% if children is not empty or category.isCategoryForum %}
|
|
{% set icon = title is not empty ? 'fas fa-folder fa-fw' : category.icon %}
|
|
<div class="container forum__categories"
|
|
{% if not category.colour.inherit %}style="--accent-colour: {{ category.colour }}"{% endif %}
|
|
{% if not category.isRoot %}id="{{ category.id }}"{% endif %}>
|
|
{{ container_title('<span class="' ~ icon ~ '"></span> ' ~ title|default(category.name)) }}
|
|
|
|
{% if children is empty %}
|
|
<div class="forum__categories__empty">
|
|
This category is empty.
|
|
</div>
|
|
{% else %}
|
|
<div class="forum__categories__list">
|
|
{% for category in children %}
|
|
{{ forum_category_entry(category, user) }}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro forum_category_listing_old(forums, title, colour, id, icon) %}
|
|
{% from _self import forum_category_entry %}
|
|
{% from 'macros.twig' import container_title %}
|
|
|
|
<div class="container forum__categories"
|
|
{% if colour is not null %}style="{{ colour|html_colour('--accent-colour') }}"{% endif %}
|
|
{% if id|length > 0 %}id="{{ id }}"{% endif %}>
|
|
{{ container_title('<span class="' ~ icon|default('fas fa-folder fa-fw') ~ '"></span> ' ~ title) }}
|
|
|
|
{% if forums|length > 0 %}
|
|
<div class="forum__categories__list">
|
|
{% for forum in forums %}
|
|
{{ forum_category_entry(forum) }}
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="forum__categories__empty">
|
|
This category is empty.
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_header(info, is_top, title_url, actions, is_topic, title) %}
|
|
<div class="container forum__header">
|
|
{% set parents = info.parentTree %}
|
|
<div class="forum__header__breadcrumbs">
|
|
{% for parent in parents %}
|
|
<a href="{{ parent.url }}" class="forum__header__breadcrumb">{{ parent.name }}</a>
|
|
<div class="forum__header__breadcrumb__separator">
|
|
<i class="fas fa-chevron-right"></i>
|
|
</div>
|
|
{% endfor %}
|
|
{% if not is_top or is_topic %}
|
|
<a href="{{ info.url }}" class="forum__header__breadcrumb">{{ info.name }}</a>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if is_top %}
|
|
{% if title_url|length > 0 %}
|
|
<a class="forum__header__title" href="{{ title_url }}">
|
|
{{ title|default(info.name) }}
|
|
</a>
|
|
{% else %}
|
|
<div class="forum__header__title forum__header__title--fill">
|
|
{{ title|default(info.name) }}
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
{% if actions is iterable and actions|length > 0 %}
|
|
<div class="forum__header__actions">
|
|
{% for action in actions %}
|
|
{% if action.display is not defined or action.display %}
|
|
<a class="forum__header__action{% if action.class is defined %}{{ action.class }}{% endif %}" href="{{ action.url }}"{% if action.method is defined %} data-msz-method="{{ action.method }}"{% endif %}>
|
|
{{ action.html|raw }}
|
|
</a>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_category_tools(category, perms, pagination_info) %}
|
|
{% set can_topic = not category.isArchived and perms|perms_check(constant('MSZ_FORUM_PERM_CREATE_TOPIC')) %}
|
|
{% set pag = pagination_info.render(url('forum-category', {'forum': category.id})) %}
|
|
|
|
{% if can_topic or pag|trim|length > 0 %}
|
|
<div class="container forum__actions">
|
|
<div class="forum__actions__buttons">
|
|
{% if can_topic %}
|
|
<a href="{{ url('forum-topic-new', {'forum': category.id}) }}" class="input__button forum__actions__button">{{ category.canHavePriorityVotes ? 'New Request' : 'New Topic' }}</a>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="forum__actions__pagination">
|
|
{{ pag|raw }}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro forum_topic_tools(info, pagination_info, can_reply) %}
|
|
{% set pag = pagination_info.render('forum-topic', {'t': info.topic_id|default(info.id)}, 'page') %}
|
|
|
|
{% if can_reply or pag|length > 0 %}
|
|
<div class="container forum__actions">
|
|
<div class="forum__actions__buttons">
|
|
{% if can_reply %}
|
|
<a href="{{ url('forum-reply-new', {'topic': info.topic_id|default(info.id)}) }}" class="input__button">Reply</a>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="forum__actions__pagination">
|
|
{{ pag|raw }}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro forum_category_entry(forum, forum_unread, forum_icon) %}
|
|
{% if forum.forum_id is defined %}
|
|
{% from _self import forum_category_entry_old %}
|
|
{{ forum_category_entry_old(forum, forum_unread, forum_icon) }}
|
|
{% else %}
|
|
{% from _self import forum_category_entry_new %}
|
|
{{ forum_category_entry_new(forum, forum_unread) }}
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro forum_category_entry_new(category, user) %}
|
|
{% from 'macros.twig' import avatar %}
|
|
|
|
<div class="forum__category">
|
|
<a href="{{ url('forum-category', {'forum': category.id}) }}" class="forum__category__link"></a>
|
|
|
|
<div class="forum__category__container">
|
|
<div class="forum__category__icon forum__category__icon--{{ user is null or category.hasRead(user) ? '' : 'un' }}read">
|
|
<span class="{{ category.icon }}"></span>
|
|
</div>
|
|
|
|
<div class="forum__category__details">
|
|
<div class="forum__category__title">
|
|
{{ category.name }}
|
|
</div>
|
|
|
|
{% if category.hasDescription %}
|
|
<div class="forum__category__description">
|
|
{{ category.parsedDescription|raw }}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if category.children is not empty %}
|
|
<div class="forum__category__subforums">
|
|
{% for child in category.children %}
|
|
{% if child.canView(user) %}
|
|
<a href="{{ url('forum-category', {'forum': child.id}) }}"
|
|
class="forum__category__subforum{% if user is not null and not child.hasRead(user) %} forum__category__subforum--unread{% endif %}">
|
|
{{ child.name }}
|
|
</a>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if category.isLink %}
|
|
{% if category.shouldCountLinkClicks %}
|
|
<div class="forum__category__stats">
|
|
<div class="forum__category__stat" title="Clicks">{{ category.linkClicks|number_format }}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% elseif category.canHaveChildren %}
|
|
<div class="forum__category__stats">
|
|
<div class="forum__category__stat" title="Topics">{{ category.topicCount|number_format }}</div>
|
|
<div class="forum__category__stat" title="Posts">{{ category.postCount|number_format }}</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if category.canHaveTopics or category.shouldCountLinkClicks %}
|
|
<div class="forum__category__activity{% if category.shouldCountLinkClicks %} forum__category__activity--empty{% endif %}">
|
|
{% if not category.isLink %}
|
|
{% set topic = category.latestTopic(user) %}
|
|
{% set post = topic.lastPost|default(null) %}
|
|
{% if topic is empty or topic.lastPost is empty %}
|
|
<div class="forum__category__activity__none">
|
|
There are no posts in this forum yet.
|
|
</div>
|
|
{% else %}
|
|
<div class="forum__category__activity__details">
|
|
<a class="forum__category__activity__post"
|
|
href="{{ url('forum-post', {'post': post.id, 'post_fragment': 'p' ~ post.id}) }}">
|
|
{{ topic.title }}
|
|
</a>
|
|
|
|
<div class="forum__category__activity__info">
|
|
<time datetime="{{ post.createdTime|date('c') }}"
|
|
title="{{ post.createdTime|date('r') }}">{{ post.createdTime|time_diff }}</time>
|
|
{% if post.hasUser %}
|
|
by
|
|
<a href="{{ url('user-profile', {'user': post.user.id}) }}" class="forum__category__username"
|
|
style="--user-colour: {{ post.user.colour }}">
|
|
{{ post.user.username }}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
{% if post.hasUser %}
|
|
<a href="{{ url('user-profile', {'user': post.user.id}) }}" class="avatar forum__category__avatar">
|
|
{{ avatar(post.user.id, 40, post.user.username) }}
|
|
</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_category_entry_old(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 %}
|
|
{% if forum.forum_icon is defined and forum.forum_icon is not empty %}
|
|
{% set forum_icon = forum.forum_icon %}
|
|
{% elseif forum.forum_archived is defined and forum.forum_archived %}
|
|
{% set forum_icon = 'fas fa-archive fa-fw' %}
|
|
{% elseif forum.forum_type is defined and forum.forum_type != constant('\\Misuzu\\Forum\\ForumCategory::TYPE_DISCUSSION') %}
|
|
{% if forum.forum_type == constant('\\Misuzu\\Forum\\ForumCategory::TYPE_FEATURE') %}
|
|
{% set forum_icon = 'fas fa-star fa-fw' %}
|
|
{% elseif forum.forum_type == constant('\\Misuzu\\Forum\\ForumCategory::TYPE_LINK') %}
|
|
{% set forum_icon = 'fas fa-link fa-fw' %}
|
|
{% elseif forum.forum_type == constant('\\Misuzu\\Forum\\ForumCategory::TYPE_CATEGORY') %}
|
|
{% set forum_icon = 'fas fa-folder fa-fw' %}
|
|
{% endif %}
|
|
{% else %}
|
|
{% set forum_icon = 'fas fa-comments fa-fw' %}
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
<div class="forum__category">
|
|
<a href="{{ url('forum-category', {'forum': forum.forum_id}) }}" class="forum__category__link"></a>
|
|
|
|
<div class="forum__category__container">
|
|
<div class="forum__category__icon forum__category__icon--{{ forum_unread }}">
|
|
<span class="{{ forum_icon }}"></span>
|
|
</div>
|
|
|
|
<div class="forum__category__details">
|
|
<div class="forum__category__title">
|
|
{{ forum.forum_name }}
|
|
</div>
|
|
|
|
<div class="forum__category__description">
|
|
{{ forum.forum_description|nl2br }}
|
|
</div>
|
|
|
|
{% if forum.forum_subforums is defined and forum.forum_subforums|length > 0 %}
|
|
<div class="forum__category__subforums">
|
|
{% for subforum in forum.forum_subforums %}
|
|
<a href="{{ url('forum-category', {'forum': subforum.forum_id}) }}"
|
|
class="forum__category__subforum{% if subforum.forum_unread %} forum__category__subforum--unread{% endif %}">
|
|
{{ subforum.forum_name }}
|
|
</a>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if forum.forum_type == constant('\\Misuzu\\Forum\\ForumCategory::TYPE_LINK') %}
|
|
{% if forum.forum_link_clicks is not null %}
|
|
<div class="forum__category__stats">
|
|
<div class="forum__category__stat" title="Clicks">{{ forum.forum_link_clicks|number_format }}</div>
|
|
</div>
|
|
{% endif %}
|
|
{% elseif forum.forum_type in constant('\\Misuzu\\Forum\\ForumCategory::HAS_CHILDREN') %}
|
|
<div class="forum__category__stats">
|
|
<div class="forum__category__stat" title="Topics">{{ forum.forum_count_topics|number_format }}</div>
|
|
<div class="forum__category__stat" title="Posts">{{ forum.forum_count_posts|number_format }}</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if forum.forum_type in constant('\\Misuzu\\Forum\\ForumCategory::HAS_TOPICS') or forum.forum_link_clicks is not null %}
|
|
<div class="forum__category__activity{% if forum.forum_link_clicks is not null %} forum__category__activity--empty{% endif %}">
|
|
{% if forum.forum_type != constant('\\Misuzu\\Forum\\ForumCategory::TYPE_LINK') %}
|
|
{% if forum.recent_topic_id is not defined %}
|
|
<div class="forum__category__activity__none">
|
|
There are no posts in this forum yet.
|
|
</div>
|
|
{% else %}
|
|
<div class="forum__category__activity__details">
|
|
<a class="forum__category__activity__post"
|
|
href="{{ url('forum-post', {'post': forum.recent_post_id, 'post_fragment': 'p' ~ forum.recent_post_id}) }}">
|
|
{{ forum.recent_topic_title }}
|
|
</a>
|
|
|
|
<div class="forum__category__activity__info">
|
|
<time datetime="{{ forum.recent_post_created|date('c') }}"
|
|
title="{{ forum.recent_post_created|date('r') }}">{{ forum.recent_post_created|time_diff }}</time>
|
|
{% if forum.recent_post_user_id is not null %}
|
|
by
|
|
<a href="{{ url('user-profile', {'user': forum.recent_post_user_id}) }}" class="forum__category__username"
|
|
style="{{ forum.recent_post_user_colour|html_colour }}">
|
|
{{ forum.recent_post_username }}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</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">
|
|
{{ avatar(forum.recent_post_user_id, 40, forum.recent_post_username) }}
|
|
</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_topic_locked(locked, archived) %}
|
|
{% if locked|default(0) > 0 is not null or archived %}
|
|
<div class="container forum__status">
|
|
<div class="forum__status__icon">
|
|
<div class="forum__status__icon__background"></div>
|
|
<i class="fas fa-{{ archived ? 'archive' : 'lock' }}"></i>
|
|
</div>
|
|
<div class="forum__status__text">
|
|
{% if archived %}
|
|
This topic has been <span class="forum__status__emphasis">archived</span>.
|
|
{% else %}
|
|
This topic was locked
|
|
<time class="forum__status__emphasis" datetime="{{ locked|date('c') }}" title="{{ locked|date('r') }}">{{ locked|time_diff }}</time>.
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro forum_topic_listing(topics, title, user) %}
|
|
{% from _self import forum_topic_entry %}
|
|
{% from 'macros.twig' import container_title %}
|
|
|
|
<div class="container forum__topics">
|
|
{{ container_title('<i class="fas fa-comments fa-fw"></i> ' ~ title|default('Topics')) }}
|
|
|
|
<div class="forum__topics__list">
|
|
{% if topics|length > 0 %}
|
|
{% for topic in topics %}
|
|
{{ forum_topic_entry(topic, user) }}
|
|
{% endfor %}
|
|
{% else %}
|
|
<div class="forum__topics__empty">
|
|
There are no topics in this forum.
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_topic_entry(topic, topic_icon, topic_unread) %}
|
|
{% if topic.getId is defined %}
|
|
{% from _self import forum_topic_entry_new %}
|
|
{{ forum_topic_entry_new(topic, topic_icon) }}
|
|
{% else %}
|
|
{% from _self import forum_topic_entry_old %}
|
|
{{ forum_topic_entry_old(topic, topic_icon, topic_unread) }}
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro forum_topic_entry_new(topic, user) %}
|
|
{% from 'macros.twig' import avatar %}
|
|
|
|
<div class="forum__topic{% if topic.deleted %} forum__topic--deleted{% elseif topic.locked and not topic.important %} forum__topic--locked{% endif %}">
|
|
<a href="{{ url('forum-topic', {'topic': topic.id}) }}" class="forum__topic__link"></a>
|
|
|
|
<div class="forum__topic__container">
|
|
<div class="forum__topic__icon forum__topic__icon--{{ user is null or topic.hasRead(user) ? '' : 'un' }}read{% if topic.hasPriorityVoting %} forum__topic__icon--wide{% endif %}">
|
|
<i class="{{ topic.icon(user) }}{% if topic.hasPriorityVoting %} forum__topic__icon--faded{% endif %}"></i>
|
|
|
|
{% if topic.hasPriorityVoting %}
|
|
<div class="forum__topic__icon__priority">{{ topic.priority|number_format }}</div>
|
|
{% endif %}
|
|
|
|
{% if topic.hasParticipated(user) %}
|
|
<div class="forum__topic__icon__participated" title="You have posted in this topic"></div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="forum__topic__details">
|
|
<div class="forum__topic__title">
|
|
<span class="forum__topic__title__inner">
|
|
{{ topic.title }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="forum__topic__info">
|
|
{% if topic.user is not empty %}
|
|
by <a href="{{ url('user-profile', {'user': topic.user.id}) }}"
|
|
class="forum__topic__username"
|
|
style="--user-colour: {{ topic.user.colour }}">{{ topic.user.username }}</a>,
|
|
|
|
{% endif %}
|
|
<time datetime="{{ topic.createdTime|date('c') }}" title="{{ topic.createdTime|date('r') }}">{{ topic.createdTime|time_diff }}</time>
|
|
</div>
|
|
|
|
{% set pages = topic.pageCount %}
|
|
|
|
{% if pages > 1 %}
|
|
<div class="forum__topic__pagination">
|
|
{% for i in 1..pages|clamp(0, 3) %}
|
|
<a href="{{ url('forum-topic', {'topic': topic.id, 'page': i}) }}" class="forum__topic__pagination__item">
|
|
{{ i }}
|
|
</a>
|
|
{% endfor %}
|
|
{% if pages > 3 %}
|
|
{% if pages > 6 %}
|
|
<div class="forum__topic__pagination__separator">
|
|
<i class="fas fa-ellipsis-h"></i>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% for i in (pages - 2)|clamp(4, pages)..pages %}
|
|
<a href="{{ url('forum-topic', {'topic': topic.id, 'page': i}) }}" class="forum__topic__pagination__item">
|
|
{{ i }}
|
|
</a>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="forum__topic__stats">
|
|
<div class="forum__topic__stat" title="Posts">{{ topic.postCount|number_format }}</div>
|
|
<div class="forum__topic__stat" title="Views">{{ topic.viewCount|number_format }}</div>
|
|
</div>
|
|
|
|
<div class="forum__topic__activity">
|
|
{% set post = topic.lastPost %}
|
|
{% if post is not null %}
|
|
<div class="forum__topic__activity__details">
|
|
{% if post.user is not empty %}
|
|
<a href="{{ url('user-profile', {'user': post.user.id}) }}" class="forum__topic__username"
|
|
style="--user-colour: {{ post.user.colour }}">{{ post.user.username }}</a>
|
|
{% endif %}
|
|
|
|
<a class="forum__topic__activity__post"
|
|
href="{{ url('forum-post', {'post': post.id, 'post_fragment': 'p' ~ post.id}) }}">
|
|
<time datetime="{{ post.createdTime|date('c') }}"
|
|
title="{{ post.createdTime|date('r') }}">{{ post.createdTime|time_diff }}</time>
|
|
</a>
|
|
</div>
|
|
|
|
{% if post.user is not empty %}
|
|
<a href="{{ url('user-profile', {'user': post.user.id}) }}" class="forum__topic__avatar">
|
|
{{ avatar(post.user.id, 30, post.user.username) }}
|
|
</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_topic_entry_old(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('\\Misuzu\\Forum\\ForumTopic::TYPE_STICKY') or topic.topic_type == constant('\\Misuzu\\Forum\\ForumTopic::TYPE_ANNOUNCEMENT') or topic.topic_type == constant('\\Misuzu\\Forum\\ForumTopic::TYPE_GLOBAL_ANNOUNCEMENT') %}
|
|
{% set has_priority_voting = topic.forum_type in constant('\\Misuzu\\Forum\\ForumCategory::HAS_PRIORITY_VOTES') %}
|
|
|
|
{% if topic_icon is null %}
|
|
{% if topic.topic_deleted is defined and topic.topic_deleted is not null %}
|
|
{% set topic_icon = 'fas fa-trash-alt' %}
|
|
{% elseif topic.topic_type is defined and topic.topic_type != constant('\\Misuzu\\Forum\\ForumTopic::DISCUSSION') %}
|
|
{% if topic.topic_type == constant('\\Misuzu\\Forum\\ForumTopic::TYPE_ANNOUNCEMENT') or topic.topic_type == constant('\\Misuzu\\Forum\\ForumTopic::GLOBAL_ANNOUNCEMENT') %}
|
|
{% set topic_icon = 'fas fa-bullhorn' %}
|
|
{% elseif topic.topic_type == constant('\\Misuzu\\Forum\\ForumTopic::STICKY') %}
|
|
{% set topic_icon = 'fas fa-thumbtack' %}
|
|
{% endif %}
|
|
{% elseif topic.topic_locked is defined and topic.topic_locked is not null %}
|
|
{% set topic_icon = 'fas fa-lock' %}
|
|
{% elseif has_priority_voting %}
|
|
{% set topic_icon = 'far fa-star' %}
|
|
{% else %}
|
|
{% set topic_icon = (topic_unread ? 'fas' : 'far') ~ ' fa-comment' %}
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
<div class="forum__topic{% if topic.topic_deleted is not null %} forum__topic--deleted{% elseif topic.topic_locked is not null and not topic_important %} forum__topic--locked{% endif %}">
|
|
<a href="{{ url('forum-topic', {'topic': topic.topic_id}) }}" class="forum__topic__link"></a>
|
|
|
|
<div class="forum__topic__container">
|
|
<div class="forum__topic__icon forum__topic__icon--{{ topic_unread ? 'unread' : 'read' }}{% if has_priority_voting %} forum__topic__icon--wide{% endif %}">
|
|
<i class="{{ topic_icon }} fa-fw{% if has_priority_voting %} forum__topic__icon--faded{% endif %}"></i>
|
|
|
|
{% if has_priority_voting %}
|
|
<div class="forum__topic__icon__priority">{{ topic.topic_priority|number_format }}</div>
|
|
{% endif %}
|
|
|
|
{% if topic.topic_participated %}
|
|
<div class="forum__topic__icon__participated" title="You have posted in this topic"></div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="forum__topic__details">
|
|
<div class="forum__topic__title">
|
|
<span class="forum__topic__title__inner">
|
|
{{ topic.topic_title }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="forum__topic__info">
|
|
{% if topic.author_id is not null %}
|
|
by <a
|
|
href="{{ url('user-profile', {'user': topic.author_id}) }}"
|
|
class="forum__topic__username"
|
|
style="{{ topic.author_colour|html_colour }}">{{ topic.author_name }}</a>,
|
|
|
|
{% endif %}
|
|
<time datetime="{{ topic.topic_created|date('c') }}" title="{{ topic.topic_created|date('r') }}">{{ topic.topic_created|time_diff }}</time>
|
|
</div>
|
|
|
|
{% if topic.topic_pages|default(0) > 1 %}
|
|
<div class="forum__topic__pagination">
|
|
{% for i in 1..topic.topic_pages|clamp(0, 3) %}
|
|
<a href="{{ url('forum-topic', {'topic': topic.topic_id, 'page': i}) }}" class="forum__topic__pagination__item">
|
|
{{ i }}
|
|
</a>
|
|
{% endfor %}
|
|
{% if topic.topic_pages > 3 %}
|
|
{% if topic.topic_pages > 6 %}
|
|
<div class="forum__topic__pagination__separator">
|
|
<i class="fas fa-ellipsis-h"></i>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% for i in (topic.topic_pages - 2)|clamp(4, topic.topic_pages)..topic.topic_pages %}
|
|
<a href="{{ url('forum-topic', {'topic': topic.topic_id, 'page': i}) }}" class="forum__topic__pagination__item">
|
|
{{ i }}
|
|
</a>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="forum__topic__stats">
|
|
<div class="forum__topic__stat" title="Posts">{{ topic.topic_count_posts|number_format }}</div>
|
|
<div class="forum__topic__stat" title="Views">{{ topic.topic_count_views|number_format }}</div>
|
|
</div>
|
|
|
|
<div class="forum__topic__activity">
|
|
<div class="forum__topic__activity__details">
|
|
{% if topic.respondent_id is not null %}
|
|
<a href="{{ url('user-profile', {'user': topic.respondent_id}) }}" class="forum__topic__username"
|
|
style="{{ topic.respondent_colour|html_colour }}">{{ topic.respondent_name }}</a>
|
|
{% endif %}
|
|
|
|
<a class="forum__topic__activity__post"
|
|
href="{{ url('forum-post', {'post': topic.response_id, 'post_fragment': 'p' ~ topic.response_id}) }}">
|
|
<time datetime="{{ topic.response_created|date('c') }}"
|
|
title="{{ topic.response_created|date('r') }}">{{ topic.response_created|time_diff }}</time>
|
|
</a>
|
|
</div>
|
|
|
|
{% if topic.respondent_id is not null %}
|
|
<a href="{{ url('user-profile', {'user': topic.respondent_id}) }}" class="forum__topic__avatar">
|
|
{{ avatar(topic.respondent_id, 30, topic.respondent_name) }}
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_post_listing(posts, user_id, perms) %}
|
|
{% from _self import forum_post_entry %}
|
|
|
|
{% for post in posts %}
|
|
{{ forum_post_entry(post, user_id, perms) }}
|
|
{% endfor %}
|
|
{% endmacro %}
|
|
|
|
{% macro forum_post_entry(post, user_id, perms) %}
|
|
{% if post.getId is defined %}
|
|
{% from _self import forum_post_entry_new %}
|
|
{{ forum_post_entry_new(post, user_id, perms) }}
|
|
{% else %}
|
|
{% from _self import forum_post_entry_old %}
|
|
{{ forum_post_entry_old(post, user_id, perms) }}
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro forum_post_entry_new(post, user, perms) %}
|
|
{% from 'macros.twig' import avatar %}
|
|
{% set can_post = perms|perms_check(constant('MSZ_FORUM_PERM_CREATE_POST')) %}
|
|
{% set can_edit = perms|perms_check(constant('MSZ_FORUM_PERM_EDIT_ANY_POST')) or (
|
|
perms|perms_check(constant('MSZ_FORUM_PERM_EDIT_POST'))
|
|
and post.canBeEdited(user)
|
|
) %}
|
|
{% set can_delete = not post.isOpeningPost and (
|
|
perms|perms_check(constant('MSZ_FORUM_PERM_DELETE_ANY_POST')) or (
|
|
perms|perms_check(constant('MSZ_FORUM_PERM_DELETE_POST'))
|
|
and post.canBeDeleted(user)
|
|
)
|
|
) %}
|
|
|
|
<div class="container forum__post{% if post.deleted %} forum__post--deleted{% endif %}" id="p{{ post.id }}" style="{% if post.hasUser %}--accent-colour: {{ post.user.colour }}{% endif %}">
|
|
<div class="forum__post__info">
|
|
<div class="forum__post__info__background"></div>
|
|
<div class="forum__post__info__content">
|
|
{% if post.hasUser %}
|
|
<a class="forum__post__avatar" href="{{ url('user-profile', {'user': post.user.id}) }}">
|
|
{{ avatar(post.user.id, 120, post.user.username) }}
|
|
</a>
|
|
|
|
<a class="forum__post__username" href="{{ url('user-profile', {'user': post.user.id}) }}">{{ post.user.username }}</a>
|
|
|
|
{% if post.user.hasTitle %}
|
|
<div class="forum__post__usertitle">{{ post.user.title }}</div>
|
|
{% endif %}
|
|
|
|
<div class="forum__post__icons">
|
|
<div class="flag flag--{{ post.user.country|lower }}" title="{{ post.user.countryName }}"></div>
|
|
<div class="forum__post__posts-count">{{ post.user.forumPostCount|number_format }} posts</div>
|
|
</div>
|
|
|
|
{% if post.isTopicAuthor %}
|
|
<div class="forum__post__badge forum__post__badge--original-poster">
|
|
<div class="forum__post__badge__desktop">Original Poster</div>
|
|
<div class="forum__post__badge__mobile">OP</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="forum__post__joined">
|
|
joined <time datetime="{{ post.user.createdTime|date('c') }}" title="{{ post.user.createdTime|date('r') }}">{{ post.user.createdTime|time_diff }}</time>
|
|
</div>
|
|
{% else %}
|
|
<div class="forum__post__username">Deleted User</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="forum__post__content">
|
|
{% set post_link = url(post.isOpeningPost ? 'forum-topic' : 'forum-post', {'topic': post.topic.id, 'post': post.id, 'post_fragment': 'p%d'|format(post.id)}) %}
|
|
|
|
<div class="forum__post__details">
|
|
<a class="forum__post__datetime" href="{{ post_link }}">
|
|
<time datetime="{{ post.createdTime|date('c') }}" title="{{ post.createdTime|date('r') }}">{{ post.createdTime|time_diff }}</time>
|
|
{% if post.isEdited %}
|
|
(edited <time datetime="{{ post.editedTime|date('c') }}" title="{{ post.editedTime|date('r') }}">{{ post.editedTime|time_diff }}</time>)
|
|
{% endif %}
|
|
</a>
|
|
|
|
<a class="forum__post__id" href="{{ post_link }}">
|
|
#{{ post.id }}
|
|
</a>
|
|
</div>
|
|
|
|
<div class="forum__post__text {{ post.bodyClasses }}">
|
|
{{ post.parsedBody|raw }}
|
|
</div>
|
|
|
|
{% if can_post or can_edit or can_delete %}
|
|
<div class="forum__post__actions">
|
|
{% if post.deleted %}
|
|
<a href="{{ url('forum-post-restore', {'post': post.id}) }}" class="forum__post__action forum__post__action--restore"><i class="fas fa-magic fa-fw"></i> Restore</a>
|
|
<a href="{{ url('forum-post-nuke', {'post': post.id}) }}" class="forum__post__action forum__post__action--nuke"><i class="fas fa-radiation-alt fa-fw"></i> Permanently Delete</a>
|
|
{% else %}
|
|
{# if can_post %}
|
|
<a href="{{ url('forum-post-quote', {'post': post.id}) }}" class="forum__post__action forum__post__action--quote"><i class="fas fa-quote-left fa-fw"></i> Quote</a>
|
|
{% endif #}
|
|
{% if can_edit %}
|
|
<a href="{{ url('forum-post-edit', {'post': post.id}) }}" class="forum__post__action forum__post__action--edit"><i class="fas fa-edit fa-fw"></i> Edit</a>
|
|
{% endif %}
|
|
{% if can_delete %}
|
|
<a href="{{ url('forum-post-delete', {'post': post.id}) }}" class="forum__post__action forum__post__action--delete"><i class="far fa-trash-alt fa-fw"></i> Delete</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if post.shouldDisplaySignature and post.user.hasForumSignature %}
|
|
<div class="forum__post__signature {{ post.user.forumSignatureClasses }}">
|
|
{{ post.user.forumSignatureParsed|raw }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_post_entry_old(post, user_id, perms) %}
|
|
{% from 'macros.twig' import avatar %}
|
|
{% set is_deleted = post.post_deleted is not null %}
|
|
{% set can_post = perms|perms_check(constant('MSZ_FORUM_PERM_CREATE_POST')) %}
|
|
{% set can_edit = perms|perms_check(constant('MSZ_FORUM_PERM_EDIT_ANY_POST')) or (
|
|
user_id == post.poster_id
|
|
and perms|perms_check(constant('MSZ_FORUM_PERM_EDIT_POST'))
|
|
) %}
|
|
{% set can_delete = not post.is_opening_post and (
|
|
perms|perms_check(constant('MSZ_FORUM_PERM_DELETE_ANY_POST')) or (
|
|
user_id == post.poster_id
|
|
and perms|perms_check(constant('MSZ_FORUM_PERM_DELETE_POST'))
|
|
and post.post_created|date('U') > ''|date('U') - constant('\\Misuzu\\Forum\\ForumPost::DELETE_AGE_LIMIT')
|
|
)
|
|
) %}
|
|
|
|
<div class="container forum__post{% if is_deleted %} forum__post--deleted{% endif %}" id="p{{ post.post_id }}" style="{{ post.poster_colour|html_colour('--accent-colour') }}">
|
|
<div class="forum__post__info">
|
|
<div class="forum__post__info__background"></div>
|
|
<div class="forum__post__info__content">
|
|
{% if post.poster_id is not null %}
|
|
<a class="forum__post__avatar" href="{{ url('user-profile', {'user': post.poster_id}) }}">
|
|
{{ avatar(post.poster_id, 120, post.poster_name) }}
|
|
</a>
|
|
|
|
<a class="forum__post__username" href="{{ url('user-profile', {'user': post.poster_id}) }}">{{ post.poster_name }}</a>
|
|
|
|
{% if post.poster_title|length > 0 %}
|
|
<div class="forum__post__usertitle">{{ post.poster_title }}</div>
|
|
{% endif %}
|
|
|
|
<div class="forum__post__icons">
|
|
<div class="flag flag--{{ post.poster_country|lower }}" title="{{ post.poster_country|country_name }}"></div>
|
|
<div class="forum__post__posts-count">{{ post.poster_post_count|number_format }} posts</div>
|
|
</div>
|
|
|
|
{% if post.is_original_poster %}
|
|
<div class="forum__post__badge forum__post__badge--original-poster">
|
|
<div class="forum__post__badge__desktop">Original Poster</div>
|
|
<div class="forum__post__badge__mobile">OP</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="forum__post__joined">
|
|
joined <time datetime="{{ post.poster_joined|date('c') }}" title="{{ post.poster_joined|date('r') }}">{{ post.poster_joined|time_diff }}</time>
|
|
</div>
|
|
{% else %}
|
|
<div class="forum__post__username">Deleted User</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="forum__post__content">
|
|
{% set post_link = url(post.is_opening_post ? 'forum-topic' : 'forum-post', {'topic': post.topic_id, 'post': post.post_id, 'post_fragment': 'p%d'|format(post.post_id)}) %}
|
|
|
|
<div class="forum__post__details">
|
|
<a class="forum__post__datetime" href="{{ post_link }}">
|
|
<time datetime="{{ post.post_created|date('c') }}" title="{{ post.post_created|date('r') }}">{{ post.post_created|time_diff }}</time>
|
|
{% if post.post_edited is not null %}
|
|
(edited <time datetime="{{ post.post_edited|date('c') }}" title="{{ post.post_edited|date('r') }}">{{ post.post_edited|time_diff }}</time>)
|
|
{% endif %}
|
|
</a>
|
|
|
|
<a class="forum__post__id" href="{{ post_link }}">
|
|
#{{ post.post_id }}
|
|
</a>
|
|
</div>
|
|
|
|
<div class="forum__post__text{% if post.post_parse == constant('\\Misuzu\\Parsers\\Parser::MARKDOWN') %} markdown{% endif %}">
|
|
{{ post.post_text|escape|parse_text(post.post_parse)|raw }}
|
|
</div>
|
|
|
|
{% if can_post or can_edit or can_delete %}
|
|
<div class="forum__post__actions">
|
|
{% if is_deleted %}
|
|
<a href="{{ url('forum-post-restore', {'post': post.post_id}) }}" class="forum__post__action forum__post__action--restore"><i class="fas fa-magic fa-fw"></i> Restore</a>
|
|
<a href="{{ url('forum-post-nuke', {'post': post.post_id}) }}" class="forum__post__action forum__post__action--nuke"><i class="fas fa-radiation-alt fa-fw"></i> Permanently Delete</a>
|
|
{% else %}
|
|
{# if can_post %}
|
|
<a href="{{ url('forum-post-quote', {'post': post.post_id}) }}" class="forum__post__action forum__post__action--quote"><i class="fas fa-quote-left fa-fw"></i> Quote</a>
|
|
{% endif #}
|
|
{% if can_edit %}
|
|
<a href="{{ url('forum-post-edit', {'post': post.post_id}) }}" class="forum__post__action forum__post__action--edit"><i class="fas fa-edit fa-fw"></i> Edit</a>
|
|
{% endif %}
|
|
{% if can_delete %}
|
|
<a href="{{ url('forum-post-delete', {'post': post.post_id}) }}" class="forum__post__action forum__post__action--delete"><i class="far fa-trash-alt fa-fw"></i> Delete</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if post.post_display_signature and post.poster_signature_content|length > 0 %}
|
|
<div class="forum__post__signature{% if post.poster_signature_parser == constant('\\Misuzu\\Parsers\\Parser::MARKDOWN') %} markdown{% endif %}">
|
|
{{ post.poster_signature_content|escape|parse_text(post.poster_signature_parser)|raw }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_poll(poll, user) %}
|
|
{% from '_layout/input.twig' import input_csrf, input_hidden, input_checkbox, input_checkbox_raw %}
|
|
|
|
{% set can_vote = poll.canVoteOnPoll(user) %}
|
|
{% set results_available = poll.hasVoted(user) or poll.hasExpired or poll.canPreviewResults %}
|
|
{% set options_available = not poll.hasExpired and (poll.canChangeVote or not poll.hasVoted(user)) %}
|
|
{% set display_results = poll.hasVoted(user) or poll.hasExpired %}
|
|
|
|
<div class="forum__poll">
|
|
{% if results_available %}
|
|
{% if options_available %}
|
|
{{ input_checkbox_raw('', display_results, 'forum__poll__toggle', '', false, {'id':'forum-poll-toggle'}) }}
|
|
{% endif %}
|
|
|
|
<div class="container forum__poll__container forum__poll__container--results">
|
|
<div class="forum__poll__results">
|
|
{% for option in poll.options %}
|
|
<div class="forum__poll__result{% if option.hasVotedFor(user) %} forum__poll__result--voted{% endif %}">
|
|
<div class="forum__poll__result__background" style="width: {{ option.percentage * 100 }}%"></div>
|
|
<div class="forum__poll__result__container">
|
|
<div class="forum__poll__result__text">{{ option.text }}</div>
|
|
<div class="forum__poll__result__votes">{{ option.votes|number_format }}</div>
|
|
<div class="forum__poll__result__percent">{{ (option.percentage * 100)|number_format(2) }}%</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<div class="forum__poll__remaining">
|
|
This poll got <span class="forum__poll__remaining__num">{{ poll.votes|number_format }} vote{{ poll.votes == 1 ? '' : 's' }}</span>
|
|
</div>
|
|
|
|
{% if poll.canExpire %}
|
|
<div class="forum__poll__expires">
|
|
Polling {{ poll.hasExpired ? 'closed' : 'will close' }} <time class="forum__poll__expires__datetime" datetime="{{ poll.expiresTime|date('c') }}" title="{{ poll.expiresTime|date('r') }}">{{ poll.expiresTime|time_diff }}</time>.
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if options_available %}
|
|
<div class="forum__poll__buttons">
|
|
<label class="input__button forum__poll__button" for="forum-poll-toggle">Vote</label>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if options_available %}
|
|
<form method="post" action="{{ url('forum-poll-vote') }}" class="container forum__poll__container forum__poll__container--poll js-forum-poll"
|
|
data-poll-id="{{ poll.id }}" data-poll-max-votes="{{ poll.maxVotes }}">
|
|
{{ input_csrf() }}
|
|
{{ input_hidden('poll[id]', poll.id) }}
|
|
|
|
<div class="forum__poll__options">
|
|
{% for option in poll.options %}
|
|
{{ input_checkbox(
|
|
'poll[answers][]',
|
|
option.text, option.hasVotedFor(user), 'forum__poll__option',
|
|
option.id, poll.maxVotes <= 1,
|
|
null, not can_vote
|
|
) }}
|
|
{% endfor %}
|
|
</div>
|
|
|
|
{% if can_vote and poll.maxVotes > 1 %}
|
|
<div class="forum__poll__remaining js-forum-poll-remaining">
|
|
You have <span class="forum__poll__remaining__num">
|
|
<span class="js-forum-poll-remaining-count">{{ poll.maxVotes }}</span> vote<span class="js-forum-poll-remaining-plural">s</span>
|
|
</span> remaining.
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if poll.canExpire %}
|
|
<div class="forum__poll__expires">
|
|
Polling {{ poll.hasExpired ? 'closed' : 'will close' }} <time class="forum__poll__expires__datetime" datetime="{{ poll.expiresTime|date('c') }}" title="{{ poll.expiresTime|date('r') }}">{{ poll.expiresTime|time_diff }}</time>.
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="forum__poll__buttons">
|
|
{% if can_vote %}
|
|
<button class="input__button forum__poll__button">Vote</button>
|
|
{% endif %}
|
|
{% if results_available %}
|
|
<label class="input__button forum__poll__button" for="forum-poll-toggle">Results</label>
|
|
{% endif %}
|
|
</div>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro forum_priority_votes(topic, user) %}
|
|
<div class="container forum__priority">
|
|
<div class="forum__priority__votes">
|
|
{% for vote in topic.priorityVotes %}
|
|
<div title="{{ vote.user.username }} ({{ vote.priority|number_format }})" class="forum__priority__vote" style="--user-colour: {{ vote.user.colour }}">
|
|
{% for i in 1..vote.priority %}
|
|
<span class="forum__priority__star fas fa-star fa-fw"></span>
|
|
{% endfor %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
{% if topic.canVoteOnPriority(user) %}
|
|
<div class="forum__priority__input">
|
|
<a class="input__button" href="{{ url('forum-topic-priority', {'topic': topic.id}) }}">
|
|
Vote for this feature
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endmacro %}
|