Landing page redesign.

This commit is contained in:
flash 2021-08-28 17:06:14 +00:00
parent 6084e5ba5c
commit 813d3421bb
18 changed files with 911 additions and 292 deletions

View file

@ -21,7 +21,7 @@ body {
:root { :root {
--font-size: 12px; --font-size: 12px;
--line-height: 20px; --line-height: 20px;
--font-regular: Tahoma, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif; --font-regular: Verdana, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif;
--font-monospace: Consolas, 'Liberation Mono', Menlo, Courier, monospace; --font-monospace: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
--site-max-width: 1200px; --site-max-width: 1200px;

View file

@ -5,6 +5,7 @@
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
.footer__link:focus,
.footer__link:hover { .footer__link:hover {
text-decoration: underline; text-decoration: underline;
} }

View file

@ -55,7 +55,6 @@
.header__desktop__link:focus { .header__desktop__link:focus {
background-color: rgba(255, 255, 255, .2); background-color: rgba(255, 255, 255, .2);
} }
.header__desktop__link:active { .header__desktop__link:active {
background-color: rgba(255, 255, 255, .1); background-color: rgba(255, 255, 255, .1);
} }

View file

@ -0,0 +1,84 @@
.landingv2-footer {
flex: 0 0 auto;
--footer-background-mask-image: linear-gradient(180deg, transparent, var(--background-colour) 30px);
margin-top: 4px;
padding-top: 20px;
}
.landingv2-footer-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
mask-image: var(--footer-background-mask-image);
-webkit-mask-image: var(--footer-background-mask-image);
background: var(--background-pattern);
background-color: var(--header-accent-colour);
background-blend-mode: multiply;
}
.landingv2-footer-wrapper {
max-width: var(--site-max-width);
margin: 0 auto;
padding: 1em 4px;
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.landingv2-footer-navigation {}
.landingv2-footer-navigation a {
display: inline-block;
color: inherit;
text-decoration: none;
min-width: 200px;
cursor: pointer;
border-radius: 2px;
padding: 4px 10px;
margin: 1px 0;
transition: background-color .2s;
}
.landingv2-footer-navigation a:hover,
.landingv2-footer-navigation a:focus {
background-color: rgba(255, 255, 255, .2);
}
.landingv2-footer-navigation a:active {
background-color: rgba(255, 255, 255, .1);
}
.landingv2-footer-copyright {
text-align: right;
line-height: 1.8em;
font-size: .9em;
align-self: flex-end;
}
.landingv2-footer-copyright a {
color: inherit;
text-decoration: none;
}
.landingv2-footer-copyright a:focus,
.landingv2-footer-copyright a:hover {
text-decoration: underline;
}
@media(max-width: 800px) {
.landingv2-footer-wrapper {
grid-template-columns: 1fr;
}
.landingv2-footer-navigation {
text-align: center;
margin: 0 8px;
}
.landingv2-footer-navigation div {
display: inline-block;
}
.landingv2-footer-navigation a {
text-align: center;
min-width: 100px;
margin: 2px;
}
.landingv2-footer-copyright {
text-align: center;
}
}

View file

@ -0,0 +1,91 @@
.landingv2-header {
flex: 0 0 auto;
--header-background-mask-image: linear-gradient(0deg, transparent, var(--background-colour) 100px);
padding-bottom: 100px;
}
.landingv2-header-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--background-pattern);
background-color: var(--header-accent-colour);
background-blend-mode: multiply;
mask-image: var(--header-background-mask-image);
-webkit-mask-image: var(--header-background-mask-image);
}
.landingv2-header-content {
margin: 0 auto;
max-width: 800px;
}
.landingv2-welcome {
text-align: center;
margin: 10px;
}
.landingv2-welcome a {
color: inherit;
text-decoration: none;
}
.landingv2-welcome img {
max-width: 100%;
max-height: 100%;
vertical-align: middle;
}
.landingv2-header-menu {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 4px;
padding: 0 4px;
}
.landingv2-header-menu-link {
color: #fff;
text-decoration: none;
cursor: pointer;
border-radius: 2px;
background-color: var(--background-colour);
border: 1px solid var(--header-accent-colour);
transition: background-color .2s;
display: flex;
align-items: center;
min-height: 70px;
font-size: 1.4em;
padding: 10px 16px;
grid-column: 1;
}
.landingv2-header-menu-link:hover,
.landingv2-header-menu-link:focus {
background-color: var(--accent-colour);
}
.landingv2-auth-link {
font-size: 2em;
justify-content: center;
text-align: center;
grid-column: 2;
}
.landingv2-auth-link-login {
grid-row: 1 / span 2;
}
@media(max-width: 700px) {
.landingv2-header-menu {
grid-template-columns: 1fr;
}
.landingv2-auth-link {
grid-column: 1;
}
.landingv2-auth-link-login {
grid-row: 1;
min-height: 100px;
}
.landingv2-auth-link-register {
grid-row: 2;
}
}

View file

@ -0,0 +1,211 @@
.landingv2-content {
padding: 0 4px;
}
.landingv2-stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 40px;
margin: 40px;
}
.landingv2-stat {
display: flex;
align-items: center;
margin: 10px;
text-shadow: 0 1px 4px #000;
}
.landingv2-stat-icon {
font-size: 4em;
}
.landingv2-stat-value {
font-size: 2em;
text-align: right;
flex: 1 1 auto;
}
.landingv2-stat-value-num {
font-weight: 700;
}
.landingv2-forum {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 2px;
margin: 4px 0;
}
.landingv2-forum-topics {
background-color: var(--container-colour);
box-shadow: 0 1px 2px #0009;
text-shadow: 0 1px 4px #000;
overflow: hidden;
word-wrap: break-word;
}
.landingv2-forum-topics-list {
display: flex;
flex-direction: column;
margin: 5px;
overflow: hidden;
}
.landingv2-forum-topic {
border-radius: 2px;
background-color: rgba(17, 17, 17, .6);
transition: background-color .2s, box-shadow .2s, opacity .2s;
}
.landingv2-forum-topic:nth-child(even) {
background-color: rgba(25, 25, 25, .6);
}
.landingv2-forum-topic:hover,
.landingv2-forum-topic:focus {
background-color: rgba(34, 34, 34, .6);
box-shadow: 0 1px 4px #222;
}
.landingv2-forum-topic:not(:last-child) {
margin-bottom: 4px;
}
.landingv2-forum-topic-link {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
color: inherit;
text-decoration: none;
z-index: 200;
}
.landingv2-forum-topic-info {
z-index: 100;
display: flex;
padding: 5px;
align-items: center;
min-height: 40px;
pointer-events: none;
}
.landingv2-forum-topic-info-icon {
flex: 0 0 auto;
border-radius: 2px;
width: 30px;
height: 30px;
margin-right: 4px;
background-color: var(--accent-colour);
background-size: 60px 60px;
background-image: radial-gradient(ellipse at center, rgba(255, 255, 255, .2) 0%, rgba(0, 0, 0, .4) 100%);
box-shadow: 0 1px 4px #111;
font-size: 1.5em;
line-height: 1.5em;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
padding: 1px 1px 0 2px;
}
.landingv2-forum-topic-info-details {
margin: 0 4px;
flex: 1 1 auto;
display: flex;
justify-content: center;
flex-direction: column;
line-height: 1.6em;
overflow: hidden;
}
.landingv2-forum-topic-info-details-title {
font-size: 1.3em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.landingv2-forum-topic-info-stats {
font-size: .9em;
display: flex;
flex: 0 0 auto;
text-align: center;
min-width: 60px;
flex-direction: column;
}
.landingv2-forum-topic-info-stats-posts,
.landingv2-forum-topic-info-stats-views {
font-size: .9em;
line-height: 1.3em;
opacity: .7;
pointer-events: auto;
cursor: default;
}
.landingv2-forum-topic-info-stats-posts {
font-size: 1.4em;
opacity: 1;
}
.landingv2-news {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 2px;
}
.landingv2-news-post {
background-color: var(--container-colour);
box-shadow: 0 1px 2px #0009;
text-shadow: 0 1px 4px #000;
overflow: hidden;
word-wrap: break-word;
padding: 0 10px 10px 10px;
display: flex;
flex-direction: column;
}
.landingv2-news-post p {
flex: 1 1 auto;
}
.landingv2-news-post-options {
text-align: right;
}
.landingv2-online {
background-color: var(--container-colour);
box-shadow: 0 1px 2px #0009;
text-shadow: 0 1px 4px #000;
margin: 4px 0;
}
.landingv2-online-users {
scrollbar-width: thin;
overflow: auto;
}
.landingv2-online-inner {
display: flex;
padding: 2px;
}
.landingv2-online-avatar {
margin: 2px;
display: block;
flex: 0 0 auto;
}
@media(max-width: 1100px) {
.landingv2-stat {
margin: 0;
}
}
@media(max-width: 1024px) {
.landingv2-stats {
grid-template-columns: repeat(2, 1fr);
margin: 20px;
}
}
@media(max-width: 900px) {
.landingv2-forum,
.landingv2-news {
grid-template-columns: 1fr;
}
}
@media(max-width: 700px) {
.landingv2-stats {
grid-template-columns: 1fr;
}
}

View file

@ -3,14 +3,14 @@
If you need to reach us outside of this website, this is the page for you. Below are a few ways of contact. If you need to reach us outside of this website, this is the page for you. Below are a few ways of contact.
## E-mail ## E-mail
- [flash](mailto:me+flashii@flash.moe): Site Administrator - [flash](mailto:flashii@flash.moe): Site Administrator
## Twitter ## Twitter
- [@flashiinet](https://twitter.com/flashiinet): General updates and conversation. - [@flashiinet](https://twitter.com/flashiinet): General updates and conversation.
- [@flashiistatus](https://twitter.com/flashiistatus): Exclusively system status updates, posts by this accounts are generally retweeted by @flashiinet.
- [@smugwave](https://twitter.com/smugwave): Twitter of the owner, proceed with caution! - [@smugwave](https://twitter.com/smugwave): Twitter of the owner, proceed with caution!
## Source Code ## Source Code
- [Misuzu](https://github.com/flashwave/misuzu): Backend of the [website](https://flashii.net). - [Misuzu](https://github.com/flashwave/misuzu): Backend of the [website](https://flashii.net).
- [Sharp Chat](https://github.com/flashii/sharp-chat): Chat Server software. - [Sharp Chat](https://github.com/flashii/sharp-chat): Chat Server software.
- [Kuroko](https://github.com/flashii/kuroko): Chat web client hosted at [chat.flashii.net](https://chat.flashii.net).
- [Backup Manager](https://github.com/flashii/backup-manager): Program that runs every day at 12:00am UTC to back up any user generated content. - [Backup Manager](https://github.com/flashii/backup-manager): Program that runs every day at 12:00am UTC to back up any user generated content.

View file

@ -27,7 +27,7 @@ Exceptions may be granted for bot accounts.
There is a time and place for it, but Flashii is intended to be a footloose and fancy-free community. There is a time and place for it, but Flashii is intended to be a footloose and fancy-free community.
Moderator intervention will be used for petty shouting matches. Moderator intervention will be used for petty shouting matches.
1. **You must be at least 13 years of age on the Gregorian calendar.** 1. **You must be at least 18 years of age on the Gregorian calendar.**
When validating this a staff member will always ask this in a direct message, never in public channels. When validating this a staff member will always ask this in a direct message, never in public channels.
1. **Link shorteners are not allowed.** 1. **Link shorteners are not allowed.**

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View file

@ -13,76 +13,130 @@ use Misuzu\Users\UserSession;
final class HomeHandler extends Handler { final class HomeHandler extends Handler {
public function index(HttpResponse $response, HttpRequest $request): void { public function index(HttpResponse $response, HttpRequest $request): void {
if(Config::get('social.embed_linked', Config::TYPE_BOOL)) { if(UserSession::hasCurrent())
$linkedData = [ $this->home($response, $request);
else
$this->landing($response, $request);
}
public function landing(HttpResponse $response, HttpRequest $request): void {
$linkedData = Config::get('social.embed_linked', Config::TYPE_BOOL)
? [
'name' => Config::get('site.name', Config::TYPE_STR, 'Misuzu'), 'name' => Config::get('site.name', Config::TYPE_STR, 'Misuzu'),
'url' => Config::get('site.url', Config::TYPE_STR), 'url' => Config::get('site.url', Config::TYPE_STR),
'logo' => Config::get('site.ext_logo', Config::TYPE_STR), 'logo' => Config::get('site.ext_logo', Config::TYPE_STR),
'same_as' => Config::get('social.linked', Config::TYPE_ARR), 'same_as' => Config::get('social.linked', Config::TYPE_ARR),
]; ] : null;
$featuredNews = NewsPost::all(new Pagination(3), true);
$stats = DB::query(
'SELECT'
. ' (SELECT COUNT(`user_id`) FROM `msz_users` WHERE `user_deleted` IS NULL) AS `count_users_all`,'
. ' (SELECT COUNT(`user_id`) FROM `msz_users` WHERE `user_active` >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)) AS `count_users_online`,'
. ' (SELECT COUNT(`user_id`) FROM `msz_users` WHERE `user_active` >= DATE_SUB(NOW(), INTERVAL 24 HOUR)) AS `count_users_active`,'
. ' (SELECT COUNT(`comment_id`) FROM `msz_comments_posts` WHERE `comment_deleted` IS NULL) AS `count_comments`,'
. ' (SELECT COUNT(`topic_id`) FROM `msz_forum_topics` WHERE `topic_deleted` IS NULL) AS `count_forum_topics`,'
. ' (SELECT COUNT(`post_id`) FROM `msz_forum_posts` WHERE `post_deleted` IS NULL) AS `count_forum_posts`'
)->fetch();
$onlineUsers = DB::query(
'SELECT u.`user_id`, u.`username`, COALESCE(u.`user_colour`, r.`role_colour`) AS `user_colour`'
. ' FROM `msz_users` AS u'
. ' LEFT JOIN `msz_roles` AS r'
. ' ON r.`role_id` = u.`display_role`'
. ' WHERE u.`user_active` >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)'
. ' ORDER BY u.`user_active` DESC, RAND()'
. ' LIMIT 100'
)->fetchAll();
// TODO: don't hardcode forum ids
$featuredForums = Config::get('landing.forum_categories', Config::TYPE_ARR);
$popularTopics = [];
$activeTopics = [];
if(!empty($featuredForums)) {
$getPopularTopics = DB::prepare(
'SELECT t.`topic_id`, c.`forum_id`, t.`topic_title`, c.`forum_icon`, t.`topic_count_views`'
. ', (SELECT COUNT(*) FROM `msz_forum_posts` AS p WHERE p.`topic_id` = t.`topic_id` AND `post_deleted` IS NULL) AS `topic_count_posts`'
. ' FROM `msz_forum_topics` AS t'
. ' LEFT JOIN `msz_forum_categories` AS c ON c.`forum_id` = t.`forum_id`'
. ' WHERE c.`forum_id` IN (' . implode(',', $featuredForums) . ') AND `topic_deleted` IS NULL AND `topic_locked` IS NULL'
. ' ORDER BY (SELECT COUNT(*) FROM `msz_forum_posts` AS p WHERE p.`topic_id` = t.`topic_id` AND `post_deleted` IS NULL AND `post_created` > NOW() - INTERVAL 3 MONTH) DESC'
)->stmt;
$getPopularTopics->execute();
for($i = 0; $i < 10; ++$i) {
$topicInfo = $getPopularTopics->fetchObject();
if(empty($topicInfo))
break;
$popularTopics[] = $topicInfo;
} }
$getActiveTopics = DB::prepare(
'SELECT t.`topic_id`, c.`forum_id`, t.`topic_title`, c.`forum_icon`, t.`topic_count_views`'
. ', (SELECT COUNT(*) FROM `msz_forum_posts` AS p WHERE p.`topic_id` = t.`topic_id` AND `post_deleted` IS NULL) AS `topic_count_posts`'
. ', (SELECT MAX(`post_id`) FROM `msz_forum_posts` AS p WHERE p.`topic_id` = t.`topic_id` AND `post_deleted` IS NULL) AS `latest_post_id`'
. ' FROM `msz_forum_topics` AS t'
. ' LEFT JOIN `msz_forum_categories` AS c ON c.`forum_id` = t.`forum_id`'
. ' WHERE c.`forum_id` IN (' . implode(',', $featuredForums) . ') AND `topic_deleted` IS NULL AND `topic_locked` IS NULL'
. ' ORDER BY `topic_bumped` DESC'
)->stmt;
$getActiveTopics->execute();
for($i = 0; $i < 10; ++$i) {
$topicInfo = $getActiveTopics->fetchObject();
if(empty($topicInfo))
break;
$activeTopics[] = $topicInfo;
}
}
$response->setTemplate('home.landing', [
'statistics' => $stats,
'online_users' => $onlineUsers,
'featured_news' => $featuredNews,
'linked_data' => $linkedData,
'forum_popular' => $popularTopics,
'forum_active' => $activeTopics,
]);
}
public function home(HttpResponse $response, HttpRequest $request): void {
$featuredNews = NewsPost::all(new Pagination(5), true); $featuredNews = NewsPost::all(new Pagination(5), true);
$stats = DB::query(' $stats = DB::query(
SELECT 'SELECT'
( . ' (SELECT COUNT(`user_id`) FROM `msz_users` WHERE `user_deleted` IS NULL) AS `count_users_all`,'
SELECT COUNT(`user_id`) . ' (SELECT COUNT(`user_id`) FROM `msz_users` WHERE `user_active` >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)) AS `count_users_online`,'
FROM `msz_users` . ' (SELECT COUNT(`user_id`) FROM `msz_users` WHERE `user_active` >= DATE_SUB(NOW(), INTERVAL 24 HOUR)) AS `count_users_active`,'
WHERE `user_deleted` IS NULL . ' (SELECT COUNT(`comment_id`) FROM `msz_comments_posts` WHERE `comment_deleted` IS NULL) AS `count_comments`,'
) AS `count_users_all`, . ' (SELECT COUNT(`topic_id`) FROM `msz_forum_topics` WHERE `topic_deleted` IS NULL) AS `count_forum_topics`,'
( . ' (SELECT COUNT(`post_id`) FROM `msz_forum_posts` WHERE `post_deleted` IS NULL) AS `count_forum_posts`'
SELECT COUNT(`user_id`) )->fetch();
FROM `msz_users`
WHERE `user_active` >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)
) AS `count_users_online`,
(
SELECT COUNT(`user_id`)
FROM `msz_users`
WHERE `user_active` >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
) AS `count_users_active`,
(
SELECT COUNT(`comment_id`)
FROM `msz_comments_posts`
WHERE `comment_deleted` IS NULL
) AS `count_comments`,
(
SELECT COUNT(`topic_id`)
FROM `msz_forum_topics`
WHERE `topic_deleted` IS NULL
) AS `count_forum_topics`,
(
SELECT COUNT(`post_id`)
FROM `msz_forum_posts`
WHERE `post_deleted` IS NULL
) AS `count_forum_posts`
')->fetch();
$changelog = ChangelogChange::all(new Pagination(10)); $changelog = ChangelogChange::all(new Pagination(10));
$birthdays = !UserSession::hasCurrent() ? [] : User::byBirthdate(); $birthdays = User::byBirthdate();
$latestUser = !empty($birthdays) ? null : User::byLatest(); $latestUser = !empty($birthdays) ? null : User::byLatest();
$onlineUsers = DB::query(' $onlineUsers = DB::query(
SELECT 'SELECT u.`user_id`, u.`username`, COALESCE(u.`user_colour`, r.`role_colour`) AS `user_colour`'
u.`user_id`, u.`username`, . ' FROM `msz_users` AS u'
COALESCE(u.`user_colour`, r.`role_colour`) as `user_colour` . ' LEFT JOIN `msz_roles` AS r'
FROM `msz_users` as u . ' ON r.`role_id` = u.`display_role`'
LEFT JOIN `msz_roles` as r . ' WHERE u.`user_active` >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)'
ON r.`role_id` = u.`display_role` . ' ORDER BY u.`user_active` DESC, RAND()'
WHERE u.`user_active` >= DATE_SUB(NOW(), INTERVAL 5 MINUTE) . ' LIMIT 104'
ORDER BY u.`user_active` DESC )->fetchAll();
LIMIT 104
')->fetchAll();
$response->setTemplate('home.landing', [ $response->setTemplate('home.home', [
'statistics' => $stats, 'statistics' => $stats,
'latest_user' => $latestUser, 'latest_user' => $latestUser,
'online_users' => $onlineUsers, 'online_users' => $onlineUsers,
'birthdays' => $birthdays, 'birthdays' => $birthdays,
'featured_changelog' => $changelog, 'featured_changelog' => $changelog,
'featured_news' => $featuredNews, 'featured_news' => $featuredNews,
'linked_data' => $linkedData ?? null,
]); ]);
} }
} }

View file

@ -5,7 +5,7 @@
<title>Error 500</title> <title>Error 500</title>
<style type="text/css"> <style type="text/css">
body { body {
font: 12px/20px Tahoma, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif; font: 12px/20px Verdana, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif;
} }
</style> </style>
</head> </head>

View file

@ -5,7 +5,7 @@
<title>Error 503</title> <title>Error 503</title>
<style type="text/css"> <style type="text/css">
body { body {
font: 12px/20px Tahoma, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif; font: 12px/20px Verdana, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif;
} }
</style> </style>
</head> </head>

View file

@ -2,8 +2,6 @@
<div class="footer__background"></div> <div class="footer__background"></div>
<div class="footer__wrapper"> <div class="footer__wrapper">
{% autoescape false %} {% autoescape false %}
{% set git_tag = git_tag() %}
{% set git_branch = git_branch() %}
<div class="footer__copyright"> <div class="footer__copyright">
<a href="https://flash.moe" target="_blank" rel="noreferrer noopener" class="footer__link">Flashwave</a> <a href="https://flash.moe" target="_blank" rel="noreferrer noopener" class="footer__link">Flashwave</a>
2013-{{ ''|date('Y') }} / 2013-{{ ''|date('Y') }} /

View file

@ -1,104 +1,6 @@
{% from 'macros.twig' import avatar %} {% from 'macros.twig' import avatar %}
{% from '_layout/input.twig' import input_checkbox_raw %} {% from '_layout/input.twig' import input_checkbox_raw %}
{% set site_menu = [
{
'title': 'Home',
'url': '/',
'menu': [
{
'title': 'Members',
'url': url('user-list'),
},
{
'title': 'Changelog',
'url': url('changelog-index'),
},
{
'title': 'Contact',
'url': url('info', {'title': 'contact'}),
},
{
'title': 'Rules',
'url': url('info', {'title': 'rules'}),
},
{
'title': 'Twitter',
'url': 'https://twitter.com/flashiinet',
},
],
},
{
'title': 'News',
'url': url('news-index'),
},
{
'title': 'Forum',
'url': url('forum-index'),
'menu': [
{
'title': 'Leaderboard',
'url': url('forum-leaderboard'),
'display': current_user.legacyPerms.forum|default(0)|perms_check(constant('MSZ_PERM_FORUM_VIEW_LEADERBOARD')),
},
],
},
{
'title': 'Chat',
'url': 'https://chat.flashii.net',
},
] %}
{% set user_menu =
current_user is defined
? [
{
'title': 'Profile',
'url': url('user-profile', {'user': current_user.id}),
'icon': 'fas fa-user fa-fw',
},
{
'title': 'Settings',
'url': url('settings-index'),
'icon': 'fas fa-cog fa-fw',
},
{
'title': 'Search',
'url': url('search-index'),
'icon': 'fas fa-search fa-fw',
},
{
'title': 'Return to Site',
'url': site_link|default(url('index')),
'icon': 'fas fa-door-open fa-fw',
'display': has_manage_access and manage_menu is defined
},
{
'title': 'Manage',
'url': manage_link|default(url('manage-index')),
'icon': 'fas fa-door-closed fa-fw',
'display': has_manage_access and manage_menu is not defined
},
{
'title': 'Log out',
'url': url('auth-logout'),
'icon': 'fas fa-sign-out-alt fa-fw',
},
]
: [
{
'title': 'Register',
'url': url('auth-register'),
'icon': 'fas fa-user-plus fa-fw',
},
{
'title': 'Log in',
'url': url('auth-login'),
'icon': 'fas fa-sign-in-alt fa-fw',
},
]
%}
<nav class="header"> <nav class="header">
<div class="header__background"></div> <div class="header__background"></div>

128
templates/home/home.twig Normal file
View file

@ -0,0 +1,128 @@
{% extends 'home/master.twig' %}
{% from 'macros.twig' import container_title, avatar %}
{% from 'news/macros.twig' import news_preview %}
{% from 'changelog/macros.twig' import changelog_listing %}
{% set canonical_url = '/' %}
{% set landing_stats = [
{
icon: 'fas fa-users fa-fw',
name: 'Members',
value: statistics.count_users_all|number_format,
},
{
icon: 'fas fa-comment-dots fa-fw',
name: 'Comments',
value: statistics.count_comments|number_format,
},
{
icon: 'fas fa-user-check fa-fw',
name: 'Online',
value: statistics.count_users_online|number_format,
},
{
icon: 'fas fa-user-clock fa-fw',
name: 'Active (24 hr)',
value: statistics.count_users_active|number_format,
},
{
icon: 'fas fa-list fa-fw',
name: 'Topics',
value: statistics.count_forum_topics|number_format,
},
{
icon: 'fas fa-comments fa-fw',
name: 'Posts',
value: statistics.count_forum_posts|number_format,
},
] %}
{% block content %}
<div class="landing">
<div class="landing__sidebar">
<div class="container landing__container">
{{ container_title('<i class="fas fa-chart-bar fa-fw"></i> Statistics') }}
<div class="landing__statistics">
{% for stat in landing_stats %}
<div class="landing__statistic">
<div class="landing__statistic__name">
<i class="{{ stat.icon }}"></i> {{ stat.name }}
</div>
<div class="landing__statistic__value">
{{ stat.value }}
</div>
</div>
{% endfor %}
</div>
</div>
{% if online_users|length > 0 %}
<div class="container landing__container">
{{ container_title('<i class="fas fa-users fa-fw"></i> Currently Online') }}
<div class="landing__online">
{% for user in online_users %}
<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>
</div>
{% endif %}
{% if birthdays|length > 0 %}
<div class="container landing__container">
{{ container_title('<i class="fas fa-birthday-cake fa-fw"></i> Happy Birthday!') }}
{% for birthday in birthdays %}
<a class="landing__latest" style="--user-colour: {{ birthday.colour }}" href="{{ url('user-profile', {'user': birthday.id}) }}">
<div class="landing__latest__avatar">{{ avatar(birthday.id, 50, birthday.username) }}</div>
<div class="landing__latest__content">
<div class="landing__latest__username">
{{ birthday.username }}
</div>
{% if birthday.hasAge %}
<div class="landing__latest__joined">
Turned {{ birthday.age }} today!
</div>
{% endif %}
</div>
</a>
{% endfor %}
</div>
{% elseif latest_user is not null %}
<div class="container landing__container">
{{ container_title('<i class="fas fa-user-plus fa-fw"></i> Latest Member') }}
<a class="landing__latest" style="--user-colour: {{ latest_user.colour }}" href="{{ url('user-profile', {'user': latest_user.id}) }}">
<div class="landing__latest__avatar">{{ avatar(latest_user.id, 50, latest_user.username) }}</div>
<div class="landing__latest__content">
<div class="landing__latest__username">
{{ latest_user.username }}
</div>
<div class="landing__latest__joined">
Joined <time datetime="{{ latest_user.createdTime|date('c') }}" title="{{ latest_user.createdTime|date('r') }}">{{ latest_user.createdTime|time_diff }}</time>
</div>
</div>
</a>
</div>
{% endif %}
<div class="container landing__container">
{{ container_title('<i class="fas fa-wrench fa-fw"></i> Changelog', false, url('changelog-index')) }}
<div class="changelog__content">
{{ changelog_listing(featured_changelog, false, true) }}
</div>
</div>
</div>
<div class="landing__main">
{% for post in featured_news %}
{{ news_preview(post) }}
{% endfor %}
</div>
</div>
{% endblock %}

View file

@ -1 +0,0 @@
{% extends 'home/master.twig' %}

View file

@ -1,155 +1,205 @@
{% extends 'home/master.twig' %} {% extends 'home/master.twig' %}
{% from 'macros.twig' import container_title, avatar %} {% from 'macros.twig' import container_title, avatar %}
{% from 'news/macros.twig' import news_preview %}
{% from 'changelog/macros.twig' import changelog_listing %}
{% set canonical_url = '/' %} {% set canonical_url = '/' %}
{% block content %} {% set landing_stats = [
<div class="landing">
<div class="landing__sidebar">
<div class="container landing__container">
{{ container_title('<i class="fas fa-chart-bar fa-fw"></i> Statistics') }}
<div class="landing__statistics">
<div class="landing__statistic">
<div class="landing__statistic__name">
<i class="fas fa-users fa-fw"></i> Users
</div>
<div class="landing__statistic__value">
{{ statistics.count_users_all|number_format }}
</div>
</div>
<div class="landing__statistic">
<div class="landing__statistic__name">
<i class="fas fa-comment-dots fa-fw"></i> Comments
</div>
<div class="landing__statistic__value">
{{ statistics.count_comments|number_format }}
</div>
</div>
<div class="landing__statistic">
<div class="landing__statistic__name">
<i class="fas fa-user-check fa-fw"></i> Online
</div>
<div class="landing__statistic__value">
{{ statistics.count_users_online|number_format }}
</div>
</div>
<div class="landing__statistic">
<div class="landing__statistic__name">
<i class="fas fa-user-clock fa-fw"></i> Active (24 hr)
</div>
<div class="landing__statistic__value">
{{ statistics.count_users_active|number_format }}
</div>
</div>
<div class="landing__statistic">
<div class="landing__statistic__name">
<i class="fas fa-list fa-fw"></i> Topics
</div>
<div class="landing__statistic__value">
{{ statistics.count_forum_topics|number_format }}
</div>
</div>
<div class="landing__statistic">
<div class="landing__statistic__name">
<i class="fas fa-comments fa-fw"></i> Posts
</div>
<div class="landing__statistic__value">
{{ statistics.count_forum_posts|number_format }}
</div>
</div>
</div>
</div>
{% if online_users|length > 0 %}
<div class="container landing__container">
{{ container_title('<i class="fas fa-users fa-fw"></i> Online Users') }}
<div class="landing__online">
{% for user in online_users %}
<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>
</div>
{% endif %}
{% if birthdays|length > 0 %}
<div class="container landing__container">
{{ container_title('<i class="fas fa-birthday-cake fa-fw"></i> Happy Birthday!') }}
{% for birthday in birthdays %}
<a class="landing__latest" style="--user-colour: {{ birthday.colour }}" href="{{ url('user-profile', {'user': birthday.id}) }}">
<div class="landing__latest__avatar">{{ avatar(birthday.id, 50, birthday.username) }}</div>
<div class="landing__latest__content">
<div class="landing__latest__username">
{{ birthday.username }}
</div>
{% if birthday.hasAge %}
<div class="landing__latest__joined">
Turned {{ birthday.age }} today!
</div>
{% endif %}
</div>
</a>
{% endfor %}
</div>
{% elseif latest_user is not null %}
<div class="container landing__container">
{{ container_title('<i class="fas fa-user-plus fa-fw"></i> Newest User') }}
<a class="landing__latest" style="--user-colour: {{ latest_user.colour }}" href="{{ url('user-profile', {'user': latest_user.id}) }}">
<div class="landing__latest__avatar">{{ avatar(latest_user.id, 50, latest_user.username) }}</div>
<div class="landing__latest__content">
<div class="landing__latest__username">
{{ latest_user.username }}
</div>
<div class="landing__latest__joined">
Joined <time datetime="{{ latest_user.createdTime|date('c') }}" title="{{ latest_user.createdTime|date('r') }}">{{ latest_user.createdTime|time_diff }}</time>
</div>
</div>
</a>
</div>
{% endif %}
<div class="container landing__container">
{{ container_title('<i class="fas fa-wrench fa-fw"></i> Changelog', false, url('changelog-index')) }}
<div class="changelog__content">
{{ changelog_listing(featured_changelog, false, true) }}
</div>
</div>
</div>
<div class="landing__main">
{% for post in featured_news %}
{{ news_preview(post) }}
{% endfor %}
</div>
</div>
{% if linked_data is defined and linked_data is iterable %}
<script type="application/ld+json">
{ {
"@context": "http://schema.org", icon: 'fas fa-users fa-fw',
"@type": "Organization", name: 'members',
"name": "{{ linked_data.name }}", value: statistics.count_users_all|number_format,
"url": "{{ linked_data.url }}", },
"logo": "{{ linked_data.logo }}", {
"sameAs": [ icon: 'fas fa-user-check fa-fw',
"{{ linked_data.same_as|join('", "')|raw }}" name: 'online',
] value: statistics.count_users_online|number_format,
} },
</script> {
icon: 'fas fa-user-clock fa-fw',
name: 'active (24 hr)',
value: statistics.count_users_active|number_format,
},
{
icon: 'fas fa-list fa-fw',
name: 'topics',
value: statistics.count_forum_topics|number_format,
},
{
icon: 'fas fa-comments fa-fw',
name: 'posts',
value: statistics.count_forum_posts|number_format,
},
{
icon: 'fas fa-comment-dots fa-fw',
name: 'comments',
value: statistics.count_comments|number_format,
},
] %}
{% block main_header %}
<div class="landingv2-header">
<div class="landingv2-header-background"></div>
<div class="landingv2-header-content">
<div class="landingv2-welcome">
<a href="{{ url('index') }}">
<img src="/images/landing-logo.png" alt="{{ globals.site_name }}"/>
</a>
</div>
<div class="landingv2-header-menu">
{% for item in site_menu[1:] %}
{% if item.display is not defined or item.display %}
<a href="{{ item.url }}" class="landingv2-header-menu-link">{{ item.title }}</a>
{% endif %} {% endif %}
{% endfor %}
<a href="{{ url('auth-login') }}" class="landingv2-header-menu-link landingv2-auth-link landingv2-auth-link-login">
<div><i class="fas fa-sign-in-alt fa-fw"></i> Log in</div>
</a>
<a href="{{ url('auth-register') }}" class="landingv2-header-menu-link landingv2-auth-link landingv2-auth-link-register">
<div><i class="fas fa-user-plus fa-fw"></i> Register</div>
</a>
</div>
</div>
</div>
{% endblock %}
{% block main_footer %}
<footer class="landingv2-footer">
<div class="landingv2-footer-background"></div>
<div class="landingv2-footer-wrapper">
<div class="landingv2-footer-navigation">
{% for item in site_menu[0].menu %}
{% if item.display is not defined or item.display %}
<div>
<a href="{{ item.url }}">{{ item.title }}</a>
</div>
{% endif %}
{% endfor %}
</div>
<div class="landingv2-footer-copyright">
<div class="landingv2-footer-copyright-line">
<a href="https://flash.moe" target="_blank" rel="noreferrer noopener">Flashwave</a> 2013-{{ ''|date('Y') }}
</div>
<div class="landingv2-footer-copyright-line">
{% set git_branch = git_branch() %}
{% if git_branch != 'HEAD' %}
<a href="https://github.com/flashwave/misuzu/tree/{{ git_branch }}" target="_blank" rel="noreferrer noopener">{{ git_branch }}</a>
{% else %}
{% set git_tag = git_tag() %}
<a href="https://github.com/flashwave/misuzu/tree/{{ git_tag }}" target="_blank" rel="noreferrer noopener">{{ git_tag }}</a>
{% endif %}
# <a href="https://github.com/flashwave/misuzu/commit/{{ git_commit_hash(true) }}" target="_blank" rel="noreferrer noopener">{{ git_commit_hash() }}</a>
</div>
{% if constant('MSZ_DEBUG') or current_user.super|default(false) %}
<div class="landingv2-footer-copyright-line">
{{ sql_query_count()|number_format }} queries / {{ (startup_time() - startup_time(constant('MSZ_TPL_RENDER')))|number_format(5) }} load / {{ startup_time(constant('MSZ_TPL_RENDER'))|number_format(5) }} render / {{ startup_time()|number_format(5) }} total
</div>
{% endif %}
</div>
</div>
</footer>
{% endblock %}
{% block content %}
<div class="landingv2-content">
<div class="landingv2-stats">
{% for stat in landing_stats %}
<div class="landingv2-stat">
<div class="landingv2-stat-icon">
<i class="{{ stat.icon }}"></i>
</div>
<div class="landingv2-stat-value">
<span class="landingv2-stat-value-num">{{ stat.value }}</span> {{ stat.name }}
</div>
</div>
{% endfor %}
</div>
<div class="landingv2-forum">
<div class="landingv2-forum-topics landingv2-forum-topics-popular">
{{ container_title('<i class="fas fa-star fa-fw"></i> Popular Topics') }}
<div class="landingv2-forum-topics-list">
{% for topic in forum_popular %}
<div class="landingv2-forum-topic">
<a href="{{ url('forum-topic', {'topic': topic.topic_id}) }}" class="landingv2-forum-topic-link"></a>
<div class="landingv2-forum-topic-info">
<div class="landingv2-forum-topic-info-icon">
<i class="{{ topic.forum_icon|default('fas fa-comments fa-fw') }}"></i>
</div>
<div class="landingv2-forum-topic-info-details">
<div class="landingv2-forum-topic-info-details-title">
{{ topic.topic_title }}
</div>
</div>
<div class="landingv2-forum-topic-info-stats">
<div class="landingv2-forum-topic-info-stats-posts">{{ topic.topic_count_posts|number_format }}</div>
<div class="landingv2-forum-topic-info-stats-views">{{ topic.topic_count_views|number_format }}</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="landingv2-forum-topics landingv2-forum-topics-active">
{{ container_title('<i class="fas fa-wind fa-fw"></i> Active Topics') }}
<div class="landingv2-forum-topics-list">
{% for topic in forum_active %}
<div class="landingv2-forum-topic">
<a href="{{ url('forum-post', {'post': topic.latest_post_id}) }}" class="landingv2-forum-topic-link"></a>
<div class="landingv2-forum-topic-info">
<div class="landingv2-forum-topic-info-icon">
<i class="{{ topic.forum_icon|default('fas fa-comments fa-fw') }}"></i>
</div>
<div class="landingv2-forum-topic-info-details">
<div class="landingv2-forum-topic-info-details-title">
{{ topic.topic_title }}
</div>
</div>
<div class="landingv2-forum-topic-info-stats">
<div class="landingv2-forum-topic-info-stats-posts">{{ topic.topic_count_posts|number_format }}</div>
<div class="landingv2-forum-topic-info-stats-views">{{ topic.topic_count_views|number_format }}</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="landingv2-news">
{% for post in featured_news %}
<div class="landingv2-news-post markdown">
<h1>{{ post.title }}</h1>
<p>{{ post.parsedFirstParagraph|raw }}</p>
<div class="landingv2-news-post-options">
<a href="{{ url('news-post', {'post': post.id}) }}" class="landingv2-news-post-option">Continue reading</a>
| <a href="{{ url('news-post-comments', {'post': post.id}) }}" class="landingv2-news-post-option">
{{ not post.hasCommentsCategory or post.commentsCategory.postCount < 1 ? 'No' : post.commentsCategory.postCount|number_format }} comment{{ not post.hasCommentsCategory or post.commentsCategory.postCount != 1 ? 's' : '' }}</a>
| {{ post.createdTime|time_diff }}
</div>
</div>
{% endfor %}
</div>
{% if online_users|length > 0 %}
<div class="landingv2-online">
{{ container_title('<i class="fas fa-users fa-fw"></i> Currently Online') }}
<div class="landingv2-online-users">
<div class="landingv2-online-inner">
{% for user in online_users %}
<a href="{{ url('user-profile', {'user': user.user_id}) }}" class="landingv2-online-avatar" title="{{ user.username }}">
{{ avatar(user.user_id, 50, user.username) }}
</a>
{% endfor %}
</div>
</div>
</div>
{% endif %}
</div>
{% if linked_data is defined and linked_data is iterable %}
<script type="application/ld+json">{ "@context": "http://schema.org", "@type": "Organization", "name": "{{ linked_data.name }}", "url": "{{ linked_data.url }}", "logo": "{{ linked_data.logo }}", "sameAs": ["{{ linked_data.same_as|join('", "')|raw }}"] }</script>
{% endif %}
{% endblock %} {% endblock %}

View file

@ -27,7 +27,107 @@
</head> </head>
<body class="main{% if site_background is defined %} {{ site_background.classNames('main--bg-%s')|join(' ') }}{% endif %}" <body class="main{% if site_background is defined %} {{ site_background.classNames('main--bg-%s')|join(' ') }}{% endif %}"
style="{% if global_accent_colour is defined %}{{ global_accent_colour|html_colour('--accent-colour') }}{% endif %}" id="container"> style="{% if global_accent_colour is defined %}{{ global_accent_colour|html_colour('--accent-colour') }}{% endif %}" id="container">
{% set site_menu = [
{
'title': 'Home',
'url': url('index'),
'menu': [
{
'title': 'Members',
'url': url('user-list'),
'display': current_user is defined,
},
{
'title': 'Changelog',
'url': url('changelog-index'),
},
{
'title': 'Contact',
'url': url('info', {'title': 'contact'}),
},
{
'title': 'Rules',
'url': url('info', {'title': 'rules'}),
},
{
'title': 'Twitter',
'url': 'https://twitter.com/flashiinet',
},
],
},
{
'title': 'News',
'url': url('news-index'),
},
{
'title': 'Forum',
'url': url('forum-index'),
'menu': [
{
'title': 'Leaderboard',
'url': url('forum-leaderboard'),
'display': current_user.legacyPerms.forum|default(0)|perms_check(constant('MSZ_PERM_FORUM_VIEW_LEADERBOARD')),
},
],
},
{
'title': 'Chat',
'url': 'https://chat.flashii.net',
},
] %}
{% set user_menu =
current_user is defined
? [
{
'title': 'Profile',
'url': url('user-profile', {'user': current_user.id}),
'icon': 'fas fa-user fa-fw',
},
{
'title': 'Settings',
'url': url('settings-index'),
'icon': 'fas fa-cog fa-fw',
},
{
'title': 'Search',
'url': url('search-index'),
'icon': 'fas fa-search fa-fw',
},
{
'title': 'Return to Site',
'url': site_link|default(url('index')),
'icon': 'fas fa-door-open fa-fw',
'display': has_manage_access and manage_menu is defined
},
{
'title': 'Manage',
'url': manage_link|default(url('manage-index')),
'icon': 'fas fa-door-closed fa-fw',
'display': has_manage_access and manage_menu is not defined
},
{
'title': 'Log out',
'url': url('auth-logout'),
'icon': 'fas fa-sign-out-alt fa-fw',
},
]
: [
{
'title': 'Register',
'url': url('auth-register'),
'icon': 'fas fa-user-plus fa-fw',
},
{
'title': 'Log in',
'url': url('auth-login'),
'icon': 'fas fa-sign-in-alt fa-fw',
},
]
%}
{% block main_header %}
{% include '_layout/header.twig' %} {% include '_layout/header.twig' %}
{% endblock %}
<div class="main__wrapper"> <div class="main__wrapper">
{% if current_user.hasActiveWarning|default(false) %} {% if current_user.hasActiveWarning|default(false) %}
@ -45,7 +145,9 @@
{% endblock %} {% endblock %}
</div> </div>
{% block main_footer %}
{% include '_layout/footer.twig' %} {% include '_layout/footer.twig' %}
{% endblock %}
{% if current_user is defined %} {% if current_user is defined %}
<script type="application/json" id="js-user-info"> <script type="application/json" id="js-user-info">