VERY basic topic viewer exist now yeet

This commit is contained in:
flash 2018-05-20 22:12:45 +02:00
parent 9aa5ed140e
commit 1559c5bf40
17 changed files with 224 additions and 116 deletions

View file

@ -58,11 +58,9 @@
}
&__stats {
text-align: right;
text-align: center;
flex-grow: 0;
flex-shrink: 0;
font-style: italic;
font-family: Verdana, Arial, Helvetica, sans-serif;
@media (max-width: @mio-forum-listing-mobile) {
display: none;

View file

@ -30,7 +30,11 @@
flex-grow: 1;
flex-shrink: 1;
padding: 0 2px;
}
&__info,
&__activity {
&__datetime,
&__title {
&__link {
text-decoration: none;
@ -50,7 +54,7 @@
font-size: .9em;
line-height: 1.3em;
&__username {
&__name {
color: inherit;
font-weight: 700;
text-decoration: none;
@ -79,18 +83,22 @@
&__stats {
text-align: center;
padding-left: 1px;
}
&__last-post {
&__activity {
min-width: 200px;
padding-left: 3px;
}
&__stats,
&__last-post {
&__activity {
display: inline-flex;
flex-direction: column;
justify-content: center;
flex-shrink: 0;
flex-grow: 0;
border-left: 1px solid #9475b2;
padding-left: 1px;
}
}
}

View file

@ -1,6 +1,7 @@
.news__list {
margin: 0;
margin-bottom: 2px;
box-shadow: initial;
&__item {
text-decoration: none;

View file

@ -1,5 +1,6 @@
.news__preview {
margin: 0;
box-shadow: initial;
&:not(:last-child) {
margin-bottom: 2px;

View file

@ -1,8 +1,8 @@
.news__pagination {
border: 1px solid #9475b2;
.pagination {
list-style: none;
display: flex;
padding: 1px;
border: 1px solid #9475b2;
&__separator {
flex-grow: 1;
@ -15,7 +15,7 @@
height: 20px;
width: 20px;
&:not(:last-child){
&:not(:last-child) {
margin-right: 1px;
}

View file

@ -1,54 +1,4 @@
.settings__pagination {
list-style: none;
display: flex;
max-width: 400px;
margin: 2px auto;
padding: 1px;
border: 1px solid #9475b2;
&__separator {
flex-grow: 1;
flex-shrink: 1;
}
&__option {
background: #9475b2;
color: #306;
height: 20px;
width: 20px;
&:not(:last-child){
margin-right: 1px;
}
&--disabled {
color: #383838;
background: #777;
}
@media (max-width: @mio-news-mobile) {
height: 30px;
width: 30px;
font-size: 1.5em;
line-height: 1.5em;
}
}
&__link {
display: block;
width: 100%;
height: 100%;
text-align: center;
text-decoration: none;
color: inherit;
&--prev,
&--next,
&--first,
&--last,
&--active,
&:hover {
font-weight: bold;
}
}
}

View file

@ -45,11 +45,12 @@ body {
@import "classes/avatar";
@import "classes/container";
@import "classes/heading";
@import "classes/navigation";
@import "classes/pagination";
// Specific styles
@import "classes/footer";
@import "classes/header";
@import "classes/navigation";
@import "classes/profile";
// Settings
@ -65,7 +66,6 @@ body {
// News
@import "classes/news/container";
@import "classes/news/list";
@import "classes/news/pagination";
@import "classes/news/preview";
@import "classes/news/sidebar";
@import "classes/news/post"; // post needs to be able to override sidebar

View file

@ -67,8 +67,7 @@ switch ($mode) {
$auth_login_error = '';
while ($_SERVER['REQUEST_METHOD'] === 'POST') {
$ipAddressObj = IPAddress::remote();
$ipAddress = $ipAddressObj->getString();
$ipAddress = IPAddress::remote()->getString();
if (!isset($_POST['username'], $_POST['password'])) {
$auth_login_error = "You didn't fill all the forms!";
@ -127,12 +126,19 @@ switch ($mode) {
$createSession = $db->prepare('
INSERT INTO `msz_sessions`
(`user_id`, `session_ip`, `user_agent`, `session_key`, `created_at`, `expires_on`)
(
`user_id`, `session_ip`, `session_country`,
`user_agent`, `session_key`, `created_at`, `expires_on`
)
VALUES
(:user_id, INET6_ATON(:session_ip), :user_agent, :session_key, NOW(), NOW() + INTERVAL 1 MONTH)
(
:user_id, INET6_ATON(:session_ip), :session_country,
:user_agent, :session_key, NOW(), NOW() + INTERVAL 1 MONTH
)
');
$createSession->bindValue('user_id', $userId);
$createSession->bindValue('session_ip', $ipAddress);
$createSession->bindValue('session_country', get_country_code($ipAddress));
$createSession->bindValue('user_agent', $user_agent);
$createSession->bindValue('session_key', $sessionKey);

View file

@ -112,15 +112,14 @@ $getBreadcrumb = $db->prepare('
while ($lastParent > 0) {
$getBreadcrumb->bindValue('forum_id', $lastParent);
$breadcrumb = $getBreadcrumb->execute() ? $getBreadcrumb->fetch() : [];
if (!$getBreadcrumb->execute()) {
if (!$breadcrumb) {
break;
}
$parentForum = $getBreadcrumb->fetch();
$breadcrumbs[$parentForum['forum_name']] = '/forum/forum.php?f=' . $parentForum['forum_id'];
$lastParent = $parentForum['forum_parent'];
$breadcrumbs[$breadcrumb['forum_name']] = '/forum/forum.php?f=' . $breadcrumb['forum_id'];
$lastParent = $breadcrumb['forum_parent'];
}
$breadcrumbs['Forums'] = '/forum/';

View file

@ -3,4 +3,81 @@ use Misuzu\Database;
require_once __DIR__ . '/../../misuzu.php';
echo $app->getTemplating()->render('forum.topic');
$db = Database::connection();
$templating = $app->getTemplating();
$postId = (int)($_GET['p'] ?? 0);
$topicId = (int)($_GET['t'] ?? 0);
$postsOffset = max((int)($_GET['o'] ?? 0), 0);
$postsRange = max(min((int)($_GET['r'] ?? 10), 25), 5);
// find topic id
if ($topicId < 1 && $postId > 0) {
$getTopicId = $db->prepare('
SELECT `topic_id`
FROM `msz_forum_posts`
WHERE `post_id` = :post_id
');
$getTopicId->bindValue('post_id', $postId);
$topicId = $getTopicId->execute() ? (int)$getTopicId->fetchColumn() : 0;
}
$getTopic = $db->prepare('
SELECT
t.`topic_id`, t.`forum_id`, t.`topic_title`, t.`topic_type`, t.`topic_status`,
(
SELECT MIN(p.`post_id`)
FROM `msz_forum_posts` as p
WHERE p.`topic_id` = t.`topic_id`
) as `topic_first_post_id`
FROM `msz_forum_topics` as t
WHERE t.`topic_id` = :topic_id
AND t.`topic_deleted` IS NULL
');
$getTopic->bindValue('topic_id', $topicId);
$topic = $getTopic->execute() ? $getTopic->fetch() : false;
if (!$topic) {
http_response_code(404);
echo $templating->render('errors.404');
return;
}
$getPosts = $db->prepare('
SELECT
`post_id`, `post_text`, `post_created`
FROM `msz_forum_posts`
WHERE `topic_id` = :topic_id
AND `post_deleted` IS NULL
');
$getPosts->bindValue('topic_id', $topic['topic_id']);
$posts = $getPosts->execute() ? $getPosts->fetchAll() : [];
$lastParent = $topic['forum_id'];
$breadcrumbs = [];
$getBreadcrumb = $db->prepare('
SELECT `forum_id`, `forum_name`, `forum_parent`
FROM `msz_forum_categories`
WHERE `forum_id` = :forum_id
');
while ($lastParent > 0) {
$getBreadcrumb->bindValue('forum_id', $lastParent);
$breadcrumb = $getBreadcrumb->execute() ? $getBreadcrumb->fetch() : [];
if (!$breadcrumb) {
break;
}
$breadcrumbs[$breadcrumb['forum_name']] = '/forum/forum.php?f=' . $breadcrumb['forum_id'];
$lastParent = $breadcrumb['forum_parent'];
}
$breadcrumbs['Forums'] = '/forum/';
$breadcrumbs = array_reverse($breadcrumbs);
echo $templating->render('forum.topic', [
'topic_breadcrumbs' => $breadcrumbs,
'topic_info' => $topic,
'topic_posts' => $posts,
]);

View file

@ -1,6 +1,6 @@
{% extends '@mio/forum/master.twig' %}
{% from '@mio/macros.twig' import navigation %}
{% from '@mio/forum/macros.twig' import forum_category_listing, forum_topic_listing %}
{% from '@mio/macros.twig' import navigation, paginate %}
{% from '@mio/forum/macros.twig' import forum_category_listing, forum_topic_listing, forum_category_buttons %}
{% set title = forum_info.forum_name %}
{% set canonical_url = '/forum/forum.php?f=' ~ forum_info.forum_id %}
@ -13,7 +13,14 @@
{% endif %}
{% if forum_info.forum_type == 0 %}
{% set fcbuttons = forum_category_buttons(forum_info) %}
{% set fcpagination = paginate(forum_topics|length, 20, 0, canonical_url) %}
{{ fcbuttons }}
{{ fcpagination }}
{{ forum_topic_listing(forum_topics) }}
{{ fcpagination }}
{{ fcbuttons }}
{% endif %}
{{ navigation(mio_navigation, '/forum/') }}

View file

@ -24,4 +24,3 @@
{{ navigation(mio_navigation, '/forum/') }}
{% endblock %}

View file

@ -17,25 +17,33 @@
</div>
{% endmacro %}
{% macro forum_category_entry(forum, forum_icon) %}
{% set forum_icon = forum_icon|default(null) %}
{% macro forum_category_buttons(forum) %}
<div class="forum__actions forum__actions__content">
<a class="input__button forum__actions__button">New Topic</a>
</div>
{% endmacro %}
{% if forum_icon is null %}
{% macro forum_category_entry(forum, forum_type, forum_read, forum_icon) %}
{% set forum_type = forum_type|default(null) %}
{% set forum_read = forum_read|default(true) ? 'read' : 'unread' %}
{% set forum_icon = forum_icon|default('https://static.flash.moe/images/forum-icons/forum-%s-%s.png') %}
{% if forum_type is null %}
{% if forum.forum_archived is defined and forum.forum_archived %}
{% set forum_icon = 'https://static.flash.moe/images/forum-icons/forum-archive-%s.png' %}
{% elseif forum.forum_type is defined %}
{% set forum_type = 'archive' %}
{% elseif forum.forum_type is defined and forum.forum_type != 0 %}
{% if forum.forum_type == 2 %}
{% set forum_icon = 'https://static.flash.moe/images/forum-icons/forum-link-%s.png' %}
{% set forum_type = 'link' %}
{% elseif forum.forum_type == 1 %}
{% set forum_icon = 'https://static.flash.moe/images/forum-icons/forum-category-%s.png' %}
{% set forum_type = 'category' %}
{% endif %}
{% else %}
{% set forum_type = 'default' %}
{% endif %}
{% set forum_icon = forum_icon|default('https://static.flash.moe/images/forum-icons/forum-default-%s.png') %}
{% endif %}
<div class="forum__listing__entry">
<img src="{{ forum_icon|format('read') }}" alt="read" class="forum__listing__entry__icon">
<img src="{{ forum_icon|format(forum_type, forum_read) }}" alt="read" class="forum__listing__entry__icon">
<div class="forum__listing__entry__info">
<a href="/forum/forum.php?f={{ forum.forum_id }}" class="forum__listing__entry__title">{{ forum.forum_name }}</a>
@ -113,7 +121,7 @@
</div>
{% if topic.author_id is not null %}
<div class="forum__topics__entry__info__author">
by <a href="/profile.php?u={{ topic.author_id }}" class="forum__topics__entry__info__author__username" style="color:{{ topic.author_colour|colour_get_css }}">
by <a href="/profile.php?u={{ topic.author_id }}" class="forum__topics__entry__info__author__name" style="color:{{ topic.author_colour|colour_get_css }}">
{{ topic.author_name }}
</a>
</div>
@ -129,15 +137,46 @@
</div>
</div>
<div class="forum__topics__entry__last-post">
<div class="forum__topics__entry__last-post__author">
by <a href="/profile.php?u={{ topic.author_id }}" class="forum__topics__entry__last-post__author" style="color:{{ topic.author_colour|colour_get_css }}">
<div class="forum__topics__entry__activity">
<div class="forum__topics__entry__activity__datetime">
<a href="/forum/topic.php?p={{ topic.topic_last_post_id }}#p{{ topic.topic_last_post_id }}" class="forum__topics__entry__activity__datetime__link">
{{ topic.topic_first_post_created }}
</a>
</div>
{% if topic.topic_last_user_id is not null %}
<div class="forum__topics__entry__activity__author">
by <a href="/profile.php?u={{ topic.topic_last_user_id }}" class="forum__topics__entry__activity__author__name" style="color:{{ topic.author_colour|colour_get_css }}">
{{ topic.author_name }}
</a>
</div>
<div class="forum__topics__entry__last-post__date">
5 years ago
</div>
{% endif %}
</div>
</div>
{% endmacro %}
{% macro forum_post_listing(posts, opening_post_id) %}
{% from _self import forum_post_entry %}
{% if posts|length > 0 %}
{% for post in posts %}
{{ forum_post_entry(post, post.post_id == opening_post_id) }}
{% endfor %}
{% else %}
<div class="container">
<div class="container__title">Information</div>
<div class="container__content">
This topic has no associated posts.
</div>
</div>
{% endif %}
{% endmacro %}
{% macro forum_post_entry(post, is_opening_post) %}
{% set is_opening_post = is_opening_post|default(false) %}
<div class="container" id="p{{ post.post_id }}">
<div class="container__content">
{{ post.post_text }}
</div>
</div>
{% endmacro %}

View file

@ -0,0 +1,20 @@
{% extends '@mio/forum/master.twig' %}
{% from '@mio/macros.twig' import navigation, paginate %}
{% from '@mio/forum/macros.twig' import forum_post_listing %}
{% set title = topic_info.topic_title %}
{% set canonical_url = '/forum/topic.php?t=' ~ topic_info.topic_id %}
{% block content %}
{{ navigation(topic_breadcrumbs, topic_breadcrumbs|last, true, null, 'left') }}
<div class="container">
<div class="container__title">
{{ topic_info.topic_title }}
</div>
</div>
{{ forum_post_listing(topic_posts, topic_info.topic_first_post_id) }}
{{ navigation(mio_navigation, '/forum/') }}
{% endblock %}

View file

@ -17,10 +17,13 @@
</ul>
{% endmacro %}
{% macro pagination_class(className, classPrefix) %}{{ className }}{% if classPrefix|length > 0 %} {{ classPrefix ~ className }}{% endif %}{% endmacro %}
{% macro paginate(itemCount, itemRange, currentOffset, baseUrl, classPrefix, alwaysRender, useRanges, offsetParam, pageRange) %}
{% set alwaysRender = alwaysRender|default(false) %}
{% if alwaysRender or itemCount > itemRange %}
{% from _self import pagination_class %}
{% set classPrefix = classPrefix|default('') %}
{% set separator = '%3F' in baseUrl|default('')|url_encode ? '&' : '?' %}
{% set baseUrl = baseUrl ~ separator %}
@ -30,69 +33,69 @@
{% set offsetParam = offsetParam|default(useRanges ? 'o' : 'p') %}
{% set pageRange = pageRange|default(3) %}
<ul class="{{ classPrefix }}pagination">
<ul class="{{ pagination_class('pagination', classPrefix) }}">
{% if currentPage < 1 %}
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--first {{ classPrefix }}pagination__option--disabled">
<span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--first">
<li class="{{ pagination_class('pagination__option', classPrefix) }} {{ pagination_class('pagination__option--first', classPrefix) }} {{ pagination_class('pagination__option--disabled', classPrefix) }}">
<span class="{{ pagination_class('pagination__link', classPrefix) }} {{ pagination_class('pagination__link--first', classPrefix) }}">
&laquo;
</span>
</li>
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--prev {{ classPrefix }}pagination__option--disabled">
<span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--prev">
<li class="{{ pagination_class('pagination__option', classPrefix) }} {{ pagination_class('pagination__option--prev', classPrefix) }} {{ pagination_class('pagination__option--disabled', classPrefix) }}">
<span class="{{ pagination_class('pagination__link', classPrefix) }} {{ pagination_class('pagination__link--prev', classPrefix) }}">
&lsaquo;
</span>
</li>
{% else %}
{% set firstUrl = baseUrl|slice(0, (baseUrl|length) - (separator|length)) %}
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--first">
<a href="{{ firstUrl }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--first" rel="first">
<li class="{{ pagination_class('pagination__option', classPrefix) }} {{ pagination_class('pagination__option--first', classPrefix) }}">
<a href="{{ firstUrl }}" class="{{ pagination_class('pagination__link', classPrefix) }} {{ pagination_class('pagination__link--first', classPrefix) }}" rel="first">
&laquo;
</a>
</li>
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--prev">
<a href="{{ currentPage < 2 ? firstUrl : baseUrl ~ offsetParam ~ '=' ~ (useRanges ? ((currentPage - 1) * itemRange) : currentPage) }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--prev" rel="prev">
<li class="{{ pagination_class('pagination__option', classPrefix) }} {{ pagination_class('pagination__option--prev', classPrefix) }}">
<a href="{{ currentPage < 2 ? firstUrl : baseUrl ~ offsetParam ~ '=' ~ (useRanges ? ((currentPage - 1) * itemRange) : currentPage) }}" class="{{ pagination_class('pagination__link', classPrefix) }} {{ pagination_class('pagination__link--prev', classPrefix) }}" rel="prev">
&lsaquo;
</a>
</li>
{% endif %}
<li class="{{ classPrefix }}pagination__separator"></li>
<li class="{{ pagination_class('pagination__separator', classPrefix) }}"></li>
{% set paginationStart = currentPage - pageRange %}
{% set paginationStop = currentPage + pageRange %}
{% for i in paginationStart..paginationStop %}
{% if i >= 0 and i < pageCount %}
<li class="{{ classPrefix }}pagination__option{{ currentPage == i ? ' ' ~ classPrefix ~ 'pagination__option--active' : '' }}">
<a href="{{ baseUrl ~ offsetParam ~ '=' ~ (useRanges ? i * itemRange : i + 1) }}" class="{{ classPrefix }}pagination__link{{ currentPage == i ? ' ' ~ classPrefix ~ 'pagination__link--active' : '' }}">
<li class="{{ pagination_class('pagination__option', classPrefix) }}{{ currentPage == i ? ' ' ~ pagination_class('pagination__option--active', classPrefix) : '' }}">
<a href="{{ baseUrl ~ offsetParam ~ '=' ~ (useRanges ? i * itemRange : i + 1) }}" class="{{ pagination_class('pagination__link', classPrefix) }}{{ currentPage == i ? ' ' ~ pagination_class('pagination__link--active', classPrefix) : '' }}">
{{ i + 1 }}
</a>
</li>
{% endif %}
{% endfor %}
<li class="{{ classPrefix }}pagination__separator"></li>
<li class="{{ pagination_class('pagination__separator', classPrefix) }}"></li>
{% if currentPage >= pageCount - 1 %}
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--next {{ classPrefix }}pagination__option--disabled">
<span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--next">
<li class="{{ pagination_class('pagination__option', classPrefix) }} {{ pagination_class('pagination__option--next', classPrefix) }} {{ pagination_class('pagination__option--disabled', classPrefix) }}">
<span class="{{ pagination_class('pagination__link', classPrefix) }} {{ pagination_class('pagination__link--next', classPrefix) }}">
&rsaquo;
</span>
</li>
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--last {{ classPrefix }}pagination__option--disabled">
<span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--last">
<li class="{{ pagination_class('pagination__option', classPrefix) }} {{ pagination_class('pagination__option--last', classPrefix) }} {{ pagination_class('pagination__option--disabled', classPrefix) }}">
<span class="{{ pagination_class('pagination__link', classPrefix) }} {{ pagination_class('pagination__link--last', classPrefix) }}">
&raquo;
</span>
</li>
{% else %}
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--next">
<a href="{{ baseUrl ~ offsetParam ~ '=' ~ (useRanges ? ((currentPage + 1) * itemRange) : currentPage + 2) }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--next" rel="next">
<li class="{{ pagination_class('pagination__option', classPrefix) }} {{ pagination_class('pagination__option--next', classPrefix) }}">
<a href="{{ baseUrl ~ offsetParam ~ '=' ~ (useRanges ? ((currentPage + 1) * itemRange) : currentPage + 2) }}" class="{{ pagination_class('pagination__link', classPrefix) }} {{ pagination_class('pagination__link--next', classPrefix) }}" rel="next">
&rsaquo;
</a>
</li>
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--last">
<a href="{{ baseUrl ~ offsetParam ~ '=' ~ (useRanges ? ((pageCount - 1) * itemRange) : pageCount) }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--last" rel="last">
<li class="{{ pagination_class('pagination__option', classPrefix) }} {{ pagination_class('pagination__option--last', classPrefix) }}">
<a href="{{ baseUrl ~ offsetParam ~ '=' ~ (useRanges ? ((pageCount - 1) * itemRange) : pageCount) }}" class="{{ pagination_class('pagination__link', classPrefix) }} {{ pagination_class('pagination__link--last', classPrefix) }}" rel="last">
&raquo;
</a>
</li>

View file

@ -39,7 +39,7 @@
</div>
</div>
{% endif %}
{{ paginate(category.posts_count, posts_take, posts_offset, '/news.php?c=' ~ category.category_id, 'news__') }}
{{ paginate(category.posts_count, posts_take, posts_offset, '/news.php?c=' ~ category.category_id) }}
</div>
</div>
</div>

View file

@ -34,7 +34,7 @@
{% endfor %}
</div>
</div>
{{ paginate(posts_count, posts_take, posts_offset, '/news.php', 'news__') }}
{{ paginate(posts_count, posts_take, posts_offset, '/news.php') }}
</div>
</div>
</div>