CHAnGELOG
This commit is contained in:
parent
2d7e55f103
commit
80f9c7d0dc
33 changed files with 886 additions and 95 deletions
224
assets/less/mio/classes/changelog.less
Normal file
224
assets/less/mio/classes/changelog.less
Normal file
|
@ -0,0 +1,224 @@
|
|||
@mio-changelog-mobile: 700px;
|
||||
|
||||
.changelog {
|
||||
display: flex;
|
||||
|
||||
@media (max-width: @mio-changelog-mobile) {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 1px;
|
||||
|
||||
@media (max-width: @mio-changelog-mobile) {
|
||||
border-bottom: 1px solid #9475b2;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
&__date {
|
||||
display: block;
|
||||
background: #9475b2;
|
||||
color: #306;
|
||||
font-weight: 700;
|
||||
margin-bottom: 1px;
|
||||
text-decoration: none;
|
||||
padding: 1px 3px;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&__user,
|
||||
&__action {
|
||||
display: inline-flex;
|
||||
color: inherit;
|
||||
flex: 0 0 auto;
|
||||
margin-right: 1px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
&__user {
|
||||
min-width: 100px;
|
||||
justify-content: left;
|
||||
padding-left: 4px;
|
||||
|
||||
@media (max-width: @mio-changelog-mobile) {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&__action {
|
||||
min-width: 80px;
|
||||
justify-content: right;
|
||||
padding-right: 4px;
|
||||
|
||||
@media (max-width: @mio-changelog-mobile) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&--light {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&__log {
|
||||
word-wrap: break-word;
|
||||
overflow: hidden;
|
||||
flex: 1 1 auto;
|
||||
margin-left: 2px;
|
||||
|
||||
@media (max-width: @mio-changelog-mobile) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&--link {
|
||||
color: inherit;
|
||||
text-decoration: underline dotted;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__change {
|
||||
|
||||
&__line {
|
||||
border: 1px solid #9475b2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
&__row,
|
||||
&__column {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&__column {
|
||||
flex-direction: column;
|
||||
|
||||
&--user-info {
|
||||
justify-content: space-between;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
&--change-info {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&__action {
|
||||
display: block;
|
||||
padding: 6px 2px;
|
||||
border-right: 1px solid #9475b2;
|
||||
writing-mode: sideways-lr;
|
||||
text-orientation: sideways;
|
||||
letter-spacing: 1px;
|
||||
|
||||
&--light {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&__log {
|
||||
padding: 4px 12px;
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
&__date {
|
||||
border: 1px solid #9475b2;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
margin-right: 1px;
|
||||
text-align: center;
|
||||
padding: 2px;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
&__user {
|
||||
border: 1px solid #9475b2;
|
||||
padding: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
margin: 1px;
|
||||
margin-left: 0;
|
||||
|
||||
&__info {
|
||||
margin: 2px 5px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
width: 120px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
&__avatar {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-right: 1px;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
&__text {
|
||||
margin: 1px 0;
|
||||
padding: 1px 3px;
|
||||
border-top: 1px solid #9475b2;
|
||||
font-size: 1.2em;
|
||||
line-height: 1.5em;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
&__tags {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&__tag {
|
||||
border: 1px solid #9475b2;
|
||||
margin-right: 1px;
|
||||
border-radius: 2px;
|
||||
|
||||
&__link {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
@flag-width: 16px;
|
||||
@flag-height: 11px;
|
||||
|
||||
.flag-position(@x, @y, @offsetX: 0px, @offsetY: 0px) {
|
||||
background-position: top -(@flag-height * @x) + @offsetX left -(@flag-width * @y) + @offsetY;
|
||||
.flag-position(@x, @y) {
|
||||
background-position: top -((@flag-height + 1) * @x) left -(@flag-width * @y);
|
||||
}
|
||||
|
||||
.flag {
|
||||
display: inline-block;
|
||||
width: @flag-width;
|
||||
height: @flag-height;
|
||||
background-image: url('https://static.flash.moe/images/flag-sprite-24.png');
|
||||
background-image: url('https://static.flash.moe/images/flag-sprite.png');
|
||||
background-repeat: no-repeat;
|
||||
font-size: 0;
|
||||
.flag-position(23, 23); // xx
|
||||
|
@ -118,8 +118,6 @@
|
|||
&--gw {.flag-position(6, 22);}
|
||||
&--gy {.flag-position(6, 24);}
|
||||
|
||||
&--hd {.flag-position(7, 3);}
|
||||
&--he {.flag-position(7, 4);}
|
||||
&--hk {.flag-position(7, 10);}
|
||||
&--hm {.flag-position(7, 12);}
|
||||
&--hn {.flag-position(7, 13);}
|
||||
|
@ -127,6 +125,8 @@
|
|||
&--ht {.flag-position(7, 19);}
|
||||
&--hu {.flag-position(7, 20);}
|
||||
|
||||
&--id {.flag-position(8, 3);}
|
||||
&--ie {.flag-position(8, 4);}
|
||||
&--il {.flag-position(8, 11);}
|
||||
&--in {.flag-position(8, 13);}
|
||||
&--io {.flag-position(8, 14);}
|
||||
|
@ -166,7 +166,7 @@
|
|||
&--ma {.flag-position(12, 0);}
|
||||
&--mc {.flag-position(12, 2);}
|
||||
&--md {.flag-position(12, 3);}
|
||||
&--me {.flag-position(12, 4, 1); height: 12px;}
|
||||
&--me {.flag-position(12, 4); height: 12px;}
|
||||
&--mg {.flag-position(12, 6);}
|
||||
&--mh {.flag-position(12, 7);}
|
||||
&--mk {.flag-position(12, 10);}
|
||||
|
|
|
@ -91,6 +91,10 @@
|
|||
|
||||
&__column {
|
||||
min-width: 80px;
|
||||
max-width: 200px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@media (max-width: @mio-profile-mobile) {
|
||||
min-width: auto;
|
||||
|
|
|
@ -84,3 +84,6 @@ body {
|
|||
// Member listing
|
||||
@import "classes/members/user";
|
||||
@import "classes/members/users";
|
||||
|
||||
// Changelog
|
||||
@import "classes/changelog";
|
||||
|
|
81
database/2018_07_06_031800_changelog_tables.php
Normal file
81
database/2018_07_06_031800_changelog_tables.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
namespace Misuzu\DatabaseMigrations\ChangelogTables;
|
||||
|
||||
use PDO;
|
||||
|
||||
function migrate_up(PDO $conn): void
|
||||
{
|
||||
$conn->exec("
|
||||
CREATE TABLE `msz_changelog_actions` (
|
||||
`action_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`action_name` VARCHAR(50) NOT NULL,
|
||||
`action_colour` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`action_class` VARCHAR(20) NOT NULL,
|
||||
PRIMARY KEY (`action_id`),
|
||||
UNIQUE INDEX `action_class_unique` (`action_class`)
|
||||
)
|
||||
");
|
||||
|
||||
$conn->exec("
|
||||
CREATE TABLE `msz_changelog_changes` (
|
||||
`change_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
|
||||
`action_id` INT(10) UNSIGNED NULL DEFAULT NULL,
|
||||
`change_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`change_log` VARCHAR(255) NOT NULL,
|
||||
`change_text` TEXT NULL,
|
||||
PRIMARY KEY (`change_id`),
|
||||
INDEX `changes_user_id_foreign` (`user_id`),
|
||||
INDEX `changes_action_id_foreign` (`action_id`),
|
||||
INDEX `changes_change_created_index` (`change_created`),
|
||||
CONSTRAINT `changes_action_id_foreign`
|
||||
FOREIGN KEY (`action_id`)
|
||||
REFERENCES `msz_changelog_actions` (`action_id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE SET NULL,
|
||||
CONSTRAINT `changes_user_id_foreign`
|
||||
FOREIGN KEY (`user_id`)
|
||||
REFERENCES `msz_users` (`user_id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE SET NULL
|
||||
)
|
||||
");
|
||||
|
||||
$conn->exec("
|
||||
CREATE TABLE `msz_changelog_tags` (
|
||||
`tag_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`tag_name` VARCHAR(255) NOT NULL,
|
||||
`tag_description` TEXT NULL,
|
||||
`tag_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`tag_id`),
|
||||
UNIQUE INDEX `tag_name` (`tag_name`)
|
||||
)
|
||||
");
|
||||
|
||||
$conn->exec("
|
||||
CREATE TABLE `msz_changelog_change_tags` (
|
||||
`change_id` INT(10) UNSIGNED NOT NULL,
|
||||
`tag_id` INT(10) UNSIGNED NOT NULL,
|
||||
INDEX `tag_id_foreign_key` (`tag_id`),
|
||||
INDEX `change_tag_constraint` (`change_id`, `tag_id`),
|
||||
CONSTRAINT `change_id_foreign_key`
|
||||
FOREIGN KEY (`change_id`)
|
||||
REFERENCES `msz_changelog_changes` (`change_id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT `tag_id_foreign_key`
|
||||
FOREIGN KEY (`tag_id`)
|
||||
REFERENCES `msz_changelog_tags` (`tag_id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE
|
||||
)
|
||||
");
|
||||
}
|
||||
|
||||
function migrate_down(PDO $conn): void
|
||||
{
|
||||
$conn->exec('DROP TABLE `msz_changelog_change_tags`');
|
||||
$conn->exec('DROP TABLE `msz_changelog_tags`');
|
||||
$conn->exec('DROP TABLE `msz_changelog_changes`');
|
||||
$conn->exec('DROP TABLE `msz_changelog_actions`');
|
||||
}
|
|
@ -4,6 +4,7 @@ namespace Misuzu;
|
|||
date_default_timezone_set('UTC');
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
require_once __DIR__ . '/src/changelog.php';
|
||||
require_once __DIR__ . '/src/colour.php';
|
||||
require_once __DIR__ . '/src/zalgo.php';
|
||||
require_once __DIR__ . '/src/Forum/forum.php';
|
||||
|
|
133
public/changelog.php
Normal file
133
public/changelog.php
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
use Misuzu\Database;
|
||||
|
||||
require_once __DIR__ . '/../misuzu.php';
|
||||
|
||||
$db = Database::connection();
|
||||
$tpl = $app->getTemplating();
|
||||
|
||||
$changelogOffset = max((int)($_GET['o'] ?? 0), 0);
|
||||
$changelogRange = 30;
|
||||
|
||||
$changelogChange = (int)($_GET['c'] ?? 0);
|
||||
$changelogDate = $_GET['d'] ?? '';
|
||||
|
||||
$tpl->vars([
|
||||
'changelog_offset' => $changelogOffset,
|
||||
'changelog_take' => $changelogRange,
|
||||
]);
|
||||
|
||||
if ($changelogChange > 0) {
|
||||
$getChange = $db->prepare('
|
||||
SELECT
|
||||
c.`change_id`, c.`change_created`, c.`change_log`, c.`change_text`,
|
||||
a.`action_name`, a.`action_colour`, a.`action_class`,
|
||||
u.`user_id`, u.`username`,
|
||||
DATE(`change_created`) as `change_date`,
|
||||
COALESCE(u.`user_title`, r.`role_title`) as `user_title`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`
|
||||
FROM `msz_changelog_changes` as c
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON u.`user_id` = c.`user_id`
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = u.`display_role`
|
||||
LEFT JOIN `msz_changelog_actions` as a
|
||||
ON a.`action_id` = c.`action_id`
|
||||
WHERE `change_id` = :change_id
|
||||
');
|
||||
$getChange->bindValue('change_id', $changelogChange);
|
||||
$change = $getChange->execute() ? $getChange->fetch(PDO::FETCH_ASSOC) : [];
|
||||
|
||||
if (!$change) {
|
||||
http_response_code(404);
|
||||
} else {
|
||||
$getTags = $db->prepare('
|
||||
SELECT
|
||||
t.`tag_id`, t.`tag_name`, t.`tag_description`
|
||||
FROM `msz_changelog_tags` as t
|
||||
LEFT JOIN `msz_changelog_change_tags` as ct
|
||||
ON ct.`tag_id` = t.`tag_id`
|
||||
WHERE ct.`change_id` = :change_id
|
||||
');
|
||||
$getTags->bindValue('change_id', $change['change_id']);
|
||||
$tags = $getTags->execute() ? $getTags->fetchAll(PDO::FETCH_ASSOC) : [];
|
||||
$tpl->var('tags', $tags);
|
||||
}
|
||||
|
||||
echo $tpl->render('changelog.change', compact('change'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($changelogDate)) {
|
||||
$dateParts = explode('-', $changelogDate, 3);
|
||||
|
||||
if (count($dateParts) !== 3 || !checkdate($dateParts[1], $dateParts[2], $dateParts[0])) {
|
||||
echo render_error(404);
|
||||
return;
|
||||
}
|
||||
|
||||
$getChanges = $db->prepare('
|
||||
SELECT
|
||||
c.`change_id`, c.`change_log`,
|
||||
a.`action_name`, a.`action_colour`, a.`action_class`,
|
||||
u.`user_id`, u.`username`,
|
||||
DATE(`change_created`) as `change_date`,
|
||||
!ISNULL(c.`change_text`) as `change_has_text`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`
|
||||
FROM `msz_changelog_changes` as c
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON u.`user_id` = c.`user_id`
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = u.`display_role`
|
||||
LEFT JOIN `msz_changelog_actions` as a
|
||||
ON a.`action_id` = c.`action_id`
|
||||
WHERE DATE(c.`change_created`) = :date
|
||||
GROUP BY `change_created`, `change_id`
|
||||
ORDER BY `change_created` DESC, `change_id` DESC
|
||||
');
|
||||
$getChanges->bindValue('date', $changelogDate);
|
||||
$changes = $getChanges->execute() ? $getChanges->fetchAll() : [];
|
||||
|
||||
// settings the response code to 404, but rendering our own page anyway.
|
||||
if (count($changes) < 1) {
|
||||
http_response_code(404);
|
||||
}
|
||||
|
||||
echo $tpl->render('changelog.date', [
|
||||
'changes' => $changes,
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$changesCount = (int)$db->query('
|
||||
SELECT COUNT(`change_id`)
|
||||
FROM `msz_changelog_changes`
|
||||
')->fetchColumn();
|
||||
|
||||
$getChanges = $db->prepare('
|
||||
SELECT
|
||||
c.`change_id`, c.`change_log`,
|
||||
a.`action_name`, a.`action_colour`, a.`action_class`,
|
||||
u.`user_id`, u.`username`,
|
||||
DATE(`change_created`) as `change_date`,
|
||||
!ISNULL(c.`change_text`) as `change_has_text`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`
|
||||
FROM `msz_changelog_changes` as c
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON u.`user_id` = c.`user_id`
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = u.`display_role`
|
||||
LEFT JOIN `msz_changelog_actions` as a
|
||||
ON a.`action_id` = c.`action_id`
|
||||
GROUP BY `change_created`, `change_id`
|
||||
ORDER BY `change_created` DESC, `change_id` DESC
|
||||
LIMIT :offset, :take
|
||||
');
|
||||
$getChanges->bindValue('offset', $changelogOffset);
|
||||
$getChanges->bindValue('take', $changelogRange);
|
||||
$changes = $getChanges->execute() ? $getChanges->fetchAll() : [];
|
||||
|
||||
echo $tpl->render('changelog.index', [
|
||||
'changes' => $changes,
|
||||
'changelog_count' => $changesCount,
|
||||
]);
|
|
@ -3,12 +3,25 @@ use Misuzu\Database;
|
|||
|
||||
require_once __DIR__ . '/../misuzu.php';
|
||||
|
||||
$config = $app->getConfig();
|
||||
$tpl = $app->getTemplating();
|
||||
|
||||
if ($config->get('Site', 'embed_linked_data', 'bool', false)) {
|
||||
$tpl->vars([
|
||||
'embed_linked_data' => true,
|
||||
'embed_name' => $config->get('Site', 'name'),
|
||||
'embed_url' => $config->get('Site', 'url'),
|
||||
'embed_logo' => $config->get('Site', 'external_logo'),
|
||||
'embed_same_as' => explode(',', $config->get('Site', 'social_media')),
|
||||
]);
|
||||
}
|
||||
|
||||
$featuredNews = Database::connection()
|
||||
->query('
|
||||
SELECT
|
||||
p.`post_id`, p.`post_title`, p.`post_text`, p.`created_at`,
|
||||
u.`user_id`, u.`username`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `display_colour`
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`
|
||||
FROM `msz_news_posts` as p
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON p.`user_id` = u.`user_id`
|
||||
|
@ -21,6 +34,6 @@ $featuredNews = Database::connection()
|
|||
|
||||
//var_dump(Database::connection()->query('SHOW SESSION STATUS LIKE "Questions"')->fetch()['Value']);
|
||||
|
||||
echo $app->getTemplating()->render('home.landing', [
|
||||
echo $tpl->render('home.landing', [
|
||||
'featured_news' => $featuredNews,
|
||||
]);
|
||||
|
|
|
@ -92,7 +92,7 @@ $getUsers = $db->prepare("
|
|||
u.`user_id`, u.`username`, u.`user_country`,
|
||||
u.`created_at` as `user_joined`, u.`last_seen` as `user_last_seen`,
|
||||
COALESCE(u.`user_title`, r.`role_title`) as `user_title`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `display_colour`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`,
|
||||
(
|
||||
SELECT COUNT(`topic_id`)
|
||||
FROM `msz_forum_topics`
|
||||
|
|
|
@ -22,7 +22,7 @@ if ($postId !== null) {
|
|||
p.`post_id`, p.`post_title`, p.`post_text`, p.`created_at`,
|
||||
c.`category_id`, c.`category_name`,
|
||||
u.`user_id`, u.`username`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `display_colour`
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`
|
||||
FROM `msz_news_posts` as p
|
||||
LEFT JOIN `msz_news_categories` as c
|
||||
ON p.`category_id` = c.`category_id`
|
||||
|
@ -68,7 +68,7 @@ if ($categoryId !== null) {
|
|||
p.`post_id`, p.`post_title`, p.`post_text`, p.`created_at`,
|
||||
c.`category_id`, c.`category_name`,
|
||||
u.`user_id`, u.`username`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `display_colour`
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`
|
||||
FROM `msz_news_posts` as p
|
||||
LEFT JOIN `msz_news_categories` as c
|
||||
ON p.`category_id` = c.`category_id`
|
||||
|
@ -134,7 +134,7 @@ $getPosts = $db->prepare('
|
|||
p.`post_id`, p.`post_title`, p.`post_text`, p.`created_at`,
|
||||
c.`category_id`, c.`category_name`,
|
||||
u.`user_id`, u.`username`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `display_colour`
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`
|
||||
FROM `msz_news_posts` as p
|
||||
LEFT JOIN `msz_news_categories` as c
|
||||
ON p.`category_id` = c.`category_id`
|
||||
|
|
|
@ -46,17 +46,22 @@ switch ($mode) {
|
|||
SELECT
|
||||
u.*,
|
||||
COALESCE(u.`user_title`, r.`role_title`) as `user_title`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `display_colour`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`,
|
||||
(
|
||||
SELECT COUNT(`topic_id`)
|
||||
FROM `msz_forum_topics` as t
|
||||
WHERE t.`user_id` = u.`user_id`
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `user_id` = u.`user_id`
|
||||
) as `forum_topic_count`,
|
||||
(
|
||||
SELECT COUNT(`post_id`)
|
||||
FROM `msz_forum_posts` as p
|
||||
WHERE p.`user_id` = u.`user_id`
|
||||
) as `forum_post_count`
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `user_id` = u.`user_id`
|
||||
) as `forum_post_count`,
|
||||
(
|
||||
SELECT COUNT(`change_id`)
|
||||
FROM `msz_changelog_changes`
|
||||
WHERE `user_id` = u.`user_id`
|
||||
) as `changelog_count`
|
||||
FROM `msz_users` as u
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = u.`display_role`
|
||||
|
|
|
@ -238,10 +238,13 @@ class Application extends ApplicationBase
|
|||
|
||||
$this->templatingInstance->addFilter('json_decode');
|
||||
$this->templatingInstance->addFilter('byte_symbol');
|
||||
$this->templatingInstance->addFilter('html_link');
|
||||
$this->templatingInstance->addFilter('html_colour');
|
||||
$this->templatingInstance->addFilter('country_name', 'get_country_name');
|
||||
$this->templatingInstance->addFilter('flip', 'array_flip');
|
||||
$this->templatingInstance->addFilter('first_paragraph');
|
||||
$this->templatingInstance->addFilter('colour_get_css');
|
||||
$this->templatingInstance->addFilter('colour_get_css_contrast');
|
||||
$this->templatingInstance->addFilter('colour_get_inherit');
|
||||
$this->templatingInstance->addFilter('colour_get_red');
|
||||
$this->templatingInstance->addFilter('colour_get_green');
|
||||
|
|
43
src/changelog.php
Normal file
43
src/changelog.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
use Misuzu\Database;
|
||||
|
||||
function changelog_action_add(string $name, ?int $colour = null, ?string $class = null): int
|
||||
{
|
||||
$dbc = Database::connection();
|
||||
|
||||
if ($colour === null) {
|
||||
$colour = colour_none();
|
||||
}
|
||||
|
||||
$class = preg_replace('#[^a-z]#', '', strtolower($class ?? $name));
|
||||
|
||||
$addAction = $dbc->prepare('
|
||||
INSERT INTO `msz_changelog_actions`
|
||||
(`action_name`, `action_colour`, `action_class`)
|
||||
VALUES
|
||||
(:action_name, :action_colour, :action_class)
|
||||
');
|
||||
$addAction->bindValue('action_name', $name);
|
||||
$addAction->bindValue('action_colour', $colour);
|
||||
$addAction->bindValue('action_class', $class);
|
||||
|
||||
return $addAction->execute() ? (int)$dbc->lastInsertId() : 0;
|
||||
}
|
||||
|
||||
function changelog_entry_create(int $userId, int $actionId, string $log, string $text = null): int
|
||||
{
|
||||
$dbc = Database::connection();
|
||||
|
||||
$createChange = $dbc->prepare('
|
||||
INSERT INTO `msz_changelog_changes`
|
||||
(`user_id`, `action_id`, `change_log`, `change_text`)
|
||||
VALUES
|
||||
(:user_id, :action_id, :change_log, :change_text)
|
||||
');
|
||||
$createChange->bindValue('user_id', $userId);
|
||||
$createChange->bindValue('action_id', $actionId);
|
||||
$createChange->bindValue('change_log', $log);
|
||||
$createChange->bindValue('change_text', $text);
|
||||
|
||||
return $createChange->execute() ? (int)$dbc->lastInsertId() : 0;
|
||||
}
|
|
@ -1,5 +1,9 @@
|
|||
<?php
|
||||
define('MSZ_COLOUR_INHERIT', 0x40000000);
|
||||
define('MSZ_COLOUR_READABILITY_THRESHOLD', 186);
|
||||
define('MSZ_COLOUR_LUMINANCE_WEIGHT_RED', 0.299);
|
||||
define('MSZ_COLOUR_LUMINANCE_WEIGHT_GREEN', 0.587);
|
||||
define('MSZ_COLOUR_LUMINANCE_WEIGHT_BLUE', 0.114);
|
||||
|
||||
function colour_create(): int
|
||||
{
|
||||
|
@ -62,6 +66,13 @@ function colour_set_blue(int &$colour, int $blue): void
|
|||
$colour |= $blue;
|
||||
}
|
||||
|
||||
function colour_get_luminance(int $colour): int
|
||||
{
|
||||
return MSZ_COLOUR_LUMINANCE_WEIGHT_RED * colour_get_red($colour)
|
||||
+ MSZ_COLOUR_LUMINANCE_WEIGHT_GREEN * colour_get_green($colour)
|
||||
+ MSZ_COLOUR_LUMINANCE_WEIGHT_BLUE * colour_get_blue($colour);
|
||||
}
|
||||
|
||||
function colour_get_hex(int $colour, string $format = '#%s'): string
|
||||
{
|
||||
return sprintf(
|
||||
|
@ -79,6 +90,21 @@ function colour_get_css(int $colour): string
|
|||
return colour_get_hex($colour);
|
||||
}
|
||||
|
||||
function colour_get_css_contrast(
|
||||
int $colour,
|
||||
string $dark = 'dark',
|
||||
string $light = 'light',
|
||||
bool $inheritIsDark = true
|
||||
): string {
|
||||
if (colour_get_inherit($colour)) {
|
||||
return $inheritIsDark ? $dark : $light;
|
||||
}
|
||||
|
||||
return colour_get_luminance($colour) > MSZ_COLOUR_READABILITY_THRESHOLD
|
||||
? $dark
|
||||
: $light;
|
||||
}
|
||||
|
||||
function colour_from_rgb(int &$colour, int $red, int $green, int $blue): bool
|
||||
{
|
||||
colour_set_red($colour, $red);
|
||||
|
|
41
utility.php
41
utility.php
|
@ -241,3 +241,44 @@ function render_error(int $code, string $template = 'errors.%d'): string
|
|||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function html_link(string $url, ?string $content = null, $attributes = []): string
|
||||
{
|
||||
$content = $content ?? $url;
|
||||
$attributes = array_merge(
|
||||
is_string($attributes) ? ['class' => $attributes] : $attributes,
|
||||
['href' => $url]
|
||||
);
|
||||
|
||||
if (strpos($url, '://') !== false) {
|
||||
$attributes['target'] = '_blank';
|
||||
$attributes['rel'] = 'noreferrer noopener';
|
||||
}
|
||||
|
||||
$html = '<a';
|
||||
|
||||
foreach ($attributes as $name => $value) {
|
||||
$value = str_replace('"', '\"', $value);
|
||||
$html .= " {$name}=\"{$value}\"";
|
||||
}
|
||||
|
||||
$html .= ">{$content}</a>";
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
function html_colour(int $colour, array $attribs = []): string
|
||||
{
|
||||
if (!$attribs) {
|
||||
$attribs['color'] = '%s';
|
||||
}
|
||||
|
||||
$css = '';
|
||||
$value = colour_get_css($colour);
|
||||
|
||||
foreach ($attribs as $name => $format) {
|
||||
$css .= $name . ':' . sprintf($format, $value) . ';';
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@
|
|||
<div class="header__user">
|
||||
<div class="header__menu">
|
||||
<input type="checkbox" id="menu-user-state" class="header__menu__state">
|
||||
<label for="menu-user-state" class="header__menu__toggle header__menu__toggle--profile" style="background-image:url('/profile.php?u={{ current_user.user_id }}&m=avatar');color:{{ current_user.colour|colour_get_css }}">{{ current_user.username }}</label>
|
||||
<label for="menu-user-state" class="header__menu__toggle header__menu__toggle--profile" style="background-image:url('/profile.php?u={{ current_user.user_id }}&m=avatar');{{ current_user.colour|html_colour }}">{{ current_user.username }}</label>
|
||||
<div class="header__menu__options header__menu__options--user">
|
||||
<div class="header__menu__section">
|
||||
<a class="header__menu__link" href="/profile.php?u={{ current_user.user_id }}">Profile</a>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{% block content %}
|
||||
<div class="container listing user-listing">
|
||||
{% for user in manage_users %}
|
||||
<a href="?v=view&u={{ user.user_id }}" class="listing__entry user-listing__entry"{% if not user.colour|colour_get_inherit %} style="border-color: {{ user.colour|colour_get_css }}"{% endif %}>
|
||||
<a href="?v=view&u={{ user.user_id }}" class="listing__entry user-listing__entry"{% if not user.colour|colour_get_inherit %} style="{{ user.colour|html_colour({'border-color':'%s'}) }}"{% endif %}>
|
||||
<div class="listing__entry__content user-listing__entry__content">
|
||||
<div class="user-listing__info">
|
||||
<div class="user-listing__username">
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<div class="container listing role-listing">
|
||||
{% for role in manage_roles %}
|
||||
<a href="?v=role&r={{ role.role_id }}" class="listing__entry role-listing__entry"{% if not role.role_colour|colour_get_inherit %} style="border-color: {{ role.role_colour|colour_get_css }}"{% endif %}>
|
||||
<a href="?v=role&r={{ role.role_id }}" class="listing__entry role-listing__entry"{% if not role.role_colour|colour_get_inherit %} style="{{ role.role_colour|html_colour({'border-color':'%s'}) }}"{% endif %}>
|
||||
<div class="listing__entry__content role-listing__entry__content">
|
||||
{{ role.role_name }}
|
||||
{{ role.users }} users
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div class="container">
|
||||
<h1 class="container__title">
|
||||
{% if edit_role is defined %}
|
||||
Editing <span style="color:{{ edit_role.role_colour|colour_get_css }}">{{ edit_role.role_name }}</span> ({{ edit_role.role_id }})
|
||||
Editing <span style="{{ edit_role.role_colour|html_colour }}">{{ edit_role.role_name }}</span> ({{ edit_role.role_id }})
|
||||
{% else %}
|
||||
Creating a new Role
|
||||
{% endif %}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{% block content %}
|
||||
<div class="container">
|
||||
<h1 class="container__title">
|
||||
Viewing <span style="color:{{ view_user.colour|colour_get_css }}">{{ view_user.username }}</span> ({{ view_user.user_id }})
|
||||
Viewing <span style="{{ view_user.colour|html_colour }}">{{ view_user.username }}</span> ({{ view_user.user_id }})
|
||||
</h1>
|
||||
|
||||
<label class="form__label">
|
||||
|
|
89
views/mio/changelog/change.twig
Normal file
89
views/mio/changelog/change.twig
Normal file
|
@ -0,0 +1,89 @@
|
|||
{% extends '@mio/changelog/master.twig' %}
|
||||
{% from '@mio/macros.twig' import navigation %}
|
||||
|
||||
{% set is_valid = change|length > 0 %}
|
||||
{% set title = 'Changelog » ' ~ (is_valid ? 'Change #' ~ change.change_id : 'Unknown Change') %}
|
||||
|
||||
{% if is_valid %}
|
||||
{% set canonical_url = '/changelog.php?c=' ~ change.change_id %}
|
||||
{% endif %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="container__title changelog">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div class="container__content changelog__content">
|
||||
{% if is_valid %}
|
||||
<div class="changelog__change" id="#c{{ change.change_id }}">
|
||||
<div class="changelog__change__line"
|
||||
style="{{ change.action_colour|html_colour({'border-color':'%s'}) }}">
|
||||
<div class="changelog__change__action {{ change.action_class is defined and change.action_class is not null ? ' changelog__change__action--' ~ change.action_class : '' }} changelog__change__action--{{ change.action_colour|colour_get_css_contrast }}"
|
||||
style="{{ change.action_colour|html_colour({'background-color':'%s','border-color':'%s'}) }}">
|
||||
{{ change.action_name }}
|
||||
</div>
|
||||
|
||||
<div class="changelog__change__log">
|
||||
{{ change.change_log }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="changelog__change__row">
|
||||
<div class="changelog__change__column changelog__change__column--user-info">
|
||||
<a class="changelog__change__user" href="/profile.php?u={{ change.user_id }}">
|
||||
<div class="avatar changelog__change__user__avatar"
|
||||
style="background-image:url('/profile.php?u={{ change.user_id }}&m=avatar')">
|
||||
</div>
|
||||
|
||||
<div class="changelog__change__user__info">
|
||||
<div class="changelog__change__user__name">
|
||||
{{ change.username }}
|
||||
</div>
|
||||
|
||||
<div class="changelog__change__user__title">
|
||||
{{ change.user_title }}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a class="changelog__change__date"
|
||||
href="/changelog.php?d={{ change.change_date }}">
|
||||
<time datetime="{{ change.change_created|date('c') }}"
|
||||
title="{{ change.change_created|date('r') }}">
|
||||
{{ change.change_created|time_diff }}
|
||||
</time>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="changelog__change__column changelog__change__column--change-info">
|
||||
<div class="changelog__change__text">
|
||||
{% if change.change_text|length >= 1 %}
|
||||
{{ change.change_text|md|raw }}
|
||||
{% else %}
|
||||
<p>This change has no additional notes.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<ul class="changelog__change__tags">
|
||||
{% for tag in tags %}
|
||||
<li class="changelog__change__tag"
|
||||
title="{{ tag.tag_description }}">
|
||||
<a href="/changelog.php?t={{ tag.tag_id }}" class="changelog__change__tag__link">
|
||||
{{ tag.tag_name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="changelog__none">
|
||||
The requested change could not be found.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ navigation(mio_navigation) }}
|
||||
{% endblock %}
|
23
views/mio/changelog/date.twig
Normal file
23
views/mio/changelog/date.twig
Normal file
|
@ -0,0 +1,23 @@
|
|||
{% extends '@mio/changelog/master.twig' %}
|
||||
{% from '@mio/macros.twig' import navigation, pagination %}
|
||||
{% from '@mio/changelog/macros.twig' import changelog_listing %}
|
||||
|
||||
{% set is_valid = changes|length > 0 %}
|
||||
{% set title = 'Changelog » ' ~ (is_valid ? changes[0].change_date : 'Unknown date') %}
|
||||
|
||||
{% if is_valid %}
|
||||
{% set canonical_url = '/changelog.php?d=' ~ changes[0].change_date %}
|
||||
{% endif %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="container__title">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div class="container__content changelog__content">
|
||||
{{ changelog_listing(changes, true) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ navigation(mio_navigation) }}
|
||||
{% endblock %}
|
20
views/mio/changelog/index.twig
Normal file
20
views/mio/changelog/index.twig
Normal file
|
@ -0,0 +1,20 @@
|
|||
{% extends '@mio/changelog/master.twig' %}
|
||||
{% from '@mio/macros.twig' import navigation, pagination %}
|
||||
{% from '@mio/changelog/macros.twig' import changelog_listing %}
|
||||
|
||||
{% set title = 'Changelog' %}
|
||||
{% set canonical_url = '/changelog.php' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="container__title">
|
||||
Changelog
|
||||
</div>
|
||||
<div class="container__content changelog__content">
|
||||
{{ changelog_listing(changes) }}
|
||||
{{ pagination(changelog_count, changelog_take, changelog_offset, '/changelog.php') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ navigation(mio_navigation) }}
|
||||
{% endblock %}
|
49
views/mio/changelog/macros.twig
Normal file
49
views/mio/changelog/macros.twig
Normal file
|
@ -0,0 +1,49 @@
|
|||
{% macro changelog_listing(changes, hide_dates) %}
|
||||
{% set hide_dates = hide_dates ? true : false %}
|
||||
{% set last_date = '' %}
|
||||
|
||||
{% from _self import changelog_entry %}
|
||||
|
||||
{% if changes|length > 0 %}
|
||||
{% for change in changes %}
|
||||
{% if not hide_dates and last_date != change.change_date %}
|
||||
{% set last_date = change.change_date %}
|
||||
|
||||
<a class="changelog__date" href="?d={{ last_date }}">
|
||||
{{ last_date }}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{{ changelog_entry(change) }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="changelog__none">
|
||||
There are no changes to display here.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro changelog_entry(change) %}
|
||||
{% set has_text = change.change_has_text|default(false)
|
||||
or (change.change_text is defined and change.change_text|length > 0)
|
||||
%}
|
||||
|
||||
<div class="changelog" id="cl{{ change.change_id }}">
|
||||
<a class="changelog__action{{ change.action_class is defined and change.action_class is not null ? ' changelog__action--' ~ change.action_class : '' }} changelog__action--{{ change.action_colour|colour_get_css_contrast }}"
|
||||
href="?c={{ change.change_id }}"
|
||||
{% if change.action_colour is defined %}style="{{ change.action_colour|html_colour({'background-color':'%s'}) }}"{% endif %}>
|
||||
{{ change.action_name|default('Unknown') }}
|
||||
</a>
|
||||
|
||||
<a class="changelog__user"
|
||||
href="/profile.php?u={{ change.user_id }}"
|
||||
style="{{ change.user_colour|html_colour }}">
|
||||
{{ change.username }}
|
||||
</a>
|
||||
|
||||
<a class="changelog__log{% if has_text %} changelog__log--link{% endif %}"
|
||||
{% if has_text %}href="?c={{ change.change_id }}"{% endif %}>
|
||||
{{ change.change_log }}
|
||||
</a>
|
||||
</div>
|
||||
{% endmacro %}
|
1
views/mio/changelog/master.twig
Normal file
1
views/mio/changelog/master.twig
Normal file
|
@ -0,0 +1 @@
|
|||
{% extends '@mio/master.twig' %}
|
|
@ -98,7 +98,7 @@
|
|||
{% if forum.recent_post_user_id is not null %}
|
||||
by <a
|
||||
href="/profile.php?u={{ forum.recent_post_user_id }}"
|
||||
style="color:{{ forum.recent_post_user_colour|colour_get_css }}"
|
||||
style="{{ forum.recent_post_user_colour|html_colour }}"
|
||||
class="forum__listing__entry__activity__user">{{ forum.recent_post_username }}</a>,
|
||||
{% endif %}
|
||||
<time
|
||||
|
@ -199,7 +199,7 @@
|
|||
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>,
|
||||
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>
|
||||
|
@ -226,7 +226,7 @@
|
|||
</div>
|
||||
{% if topic.respondent_id is not null %}
|
||||
<div class="forum__topics__entry__activity__author">
|
||||
by <a href="/profile.php?u={{ topic.respondent_id }}" class="forum__topics__entry__activity__author__name" style="color:{{ topic.respondent_colour|colour_get_css }}">
|
||||
by <a href="/profile.php?u={{ topic.respondent_id }}" class="forum__topics__entry__activity__author__name" style="{{ topic.respondent_colour|html_colour }}">
|
||||
{{ topic.respondent_name }}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -266,7 +266,7 @@
|
|||
</div>
|
||||
<div
|
||||
class="forum__post__author__username"
|
||||
style="color:{{ post.poster_colour|colour_get_css }}">{{ post.poster_name }}</div>
|
||||
style="{{ post.poster_colour|html_colour }}">{{ post.poster_name }}</div>
|
||||
</a>
|
||||
<div class="forum__post__author__joined">
|
||||
joined <time datetime="{{ post.poster_joined|date('c') }}" title="{{ post.poster_joined|date('r') }}">{{ post.poster_joined|time_diff }}</time>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends '@mio/home/master.twig' %}
|
||||
{% from '@mio/macros.twig' import navigation, link %}
|
||||
{% from '@mio/macros.twig' import navigation %}
|
||||
{% from '@mio/news/macros.twig' import news_preview %}
|
||||
|
||||
{% set canonical_url = '/' %}
|
||||
|
@ -26,5 +26,20 @@
|
|||
</div>
|
||||
|
||||
{{ navigation(mio_navigation, '/') }}
|
||||
|
||||
{% if embed_linked_data is defined and embed_linked_data %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "{{ embed_name }}",
|
||||
"url": "{{ embed_url }}",
|
||||
"logo": "{{ embed_logo }}",
|
||||
"sameAs": [
|
||||
"{{ embed_same_as|join('", "')|raw }}"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
{% macro link(url, content, class) %}
|
||||
{% spaceless %}
|
||||
<a href="{{ url }}" {% if '://' in url %} target="_blank" rel="noreferrer noopener"{% endif %} {% if class is defined %}class="{{ class }}"{% endif %}>{{ content|raw }}</a>
|
||||
{% endspaceless %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro navigation(links, current, top, fmt, align) %}
|
||||
{% set top = top|default(false) == true %}
|
||||
{% set align = align|default('centre') %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% from '@mio/macros.twig' import link, navigation %}
|
||||
{% from '@mio/macros.twig' import navigation %}
|
||||
|
||||
{% set mio_navigation = {
|
||||
'Home': '/',
|
||||
|
@ -65,17 +65,23 @@
|
|||
|
||||
<footer class="footer">
|
||||
<div class="footer__copyright">
|
||||
{{ link('https://flash.moe', 'flash.moe', 'footer__copyright__link') }} 2013-{{
|
||||
{{ 'https://flash.moe'|html_link('Flashwave', 'footer__copyright__link')|raw }} 2013-{{
|
||||
''|date('Y') }} /
|
||||
{{ link('https://github.com/flashwave/misuzu/tree/' ~ git_branch(), git_branch(), 'footer__copyright__link') }} # {{ link('https://github.com/flashwave/misuzu/commit/' ~ git_hash(true), git_hash(), 'footer__copyright__link') }}
|
||||
<span title="{{ git_hash(true) }}">
|
||||
{{ git_branch() }} # {{ git_hash() }}
|
||||
</span>
|
||||
{# link('https://github.com/flashwave/misuzu/tree/' ~ git_branch(), git_branch(), 'footer__copyright__link') }} # {{ link('https://github.com/flashwave/misuzu/commit/' ~ git_hash(true), git_hash(), 'footer__copyright__link') #}
|
||||
</div>
|
||||
|
||||
<div class="footer__links">
|
||||
{{ link('#', 'Terms of Service', 'footer__links__link') }} |
|
||||
{{ link('#', 'Rules', 'footer__links__link') }} |
|
||||
{{ link('#', 'Contact', 'footer__links__link') }} |
|
||||
{{ link('#', 'Status', 'footer__links__link') }} |
|
||||
{{ link('https://twitter.com/flashiinet', 'Twitter', 'footer__links__link') }}
|
||||
{% autoescape false %}
|
||||
{{ '#'|html_link('Terms of Service', 'footer__links__link') }} |
|
||||
{{ '#'|html_link('Rules', 'footer__links__link') }} |
|
||||
{{ '#'|html_link('Contact', 'footer__links__link') }} |
|
||||
{{ '#'|html_link('Status', 'footer__links__link') }} |
|
||||
{{ '/changelog.php'|html_link('Changelog', 'footer__links__link') }} |
|
||||
{{ 'https://twitter.com/flashiinet'|html_link('Twitter', 'footer__links__link') }}
|
||||
{% endautoescape %}
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
{{ post.created_at|time_diff }}
|
||||
</time>
|
||||
<a class="news__preview__user" href="/profile.php?u={{ post.user_id }}">
|
||||
<div class="news__preview__user__name" style="color:{{ post.display_colour|colour_get_css }}">
|
||||
<div class="news__preview__user__name" style="{{ post.user_colour|html_colour }}">
|
||||
{{ post.username }}
|
||||
</div>
|
||||
<div class="avatar news__preview__user__avatar" style="background-image:url('/profile.php?u={{ post.user_id }}&m=avatar')"></div>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<div class="news__sidebar news__post__details">
|
||||
<a class="news__post__detail news__post__user" href="/profile.php?u={{ post.user_id }}">
|
||||
<div class="news__post__username" style="color:{{ post.display_colour|colour_get_css }}">{{ post.username }}</div>
|
||||
<div class="news__post__username" style="{{ post.user_colour|html_colour }}">{{ post.username }}</div>
|
||||
<div class="avatar news__post__avatar" style="background-image:url('/profile.php?u={{ post.user_id }}&m=avatar');"></div>
|
||||
</a>
|
||||
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
{% block content %}
|
||||
<form onchange="this.submit()">
|
||||
<select class="input__select" name="r"
|
||||
style="color:{{ role.role_colour|colour_get_css }}">
|
||||
style="{{ role.role_colour|html_colour }}">
|
||||
{% for r in roles %}
|
||||
<option
|
||||
value="{{ r.role_id }}"
|
||||
style="color:{{ r.role_colour|colour_get_css }}"
|
||||
style="{{ r.role_colour|html_colour }}"
|
||||
{% if r.role_id == role.role_id %} selected{% endif %}>
|
||||
{{ r.role_name }}
|
||||
</option>
|
||||
|
@ -58,7 +58,7 @@
|
|||
<div class="members__user__info">
|
||||
<div
|
||||
class="members__user__name"
|
||||
style="color:{{ user.display_colour|colour_get_css }}">
|
||||
style="{{ user.user_colour|html_colour }}">
|
||||
{{ user.username }}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends '@mio/user/master.twig' %}
|
||||
{% from '@mio/macros.twig' import navigation, link %}
|
||||
{% from '@mio/macros.twig' import navigation %}
|
||||
|
||||
{% set image = '/profile.php?u=' ~ profile.user_id ~ '&m=avatar' %}
|
||||
{% set canonical_url = '/profile.php?u=' ~ profile.user_id %}
|
||||
|
@ -9,56 +9,57 @@
|
|||
{% set youtube_is_channel_id = profile.user_youtube|slice(0, 2) == 'UC' and profile.user_youtube|length == 24 %}
|
||||
|
||||
{% set profile_fields = {
|
||||
"twitter": {
|
||||
"title": "Twitter",
|
||||
"value": profile.user_twitter|escape,
|
||||
"link": "https://twitter.com/%s",
|
||||
"format": "@%s",
|
||||
'twitter': {
|
||||
'title': 'Twitter',
|
||||
'value': profile.user_twitter|escape,
|
||||
'link': 'https://twitter.com/%s',
|
||||
'format': '@%s',
|
||||
},
|
||||
"osu": {
|
||||
"title": "osu!",
|
||||
"value": profile.user_osu|escape,
|
||||
"link": "https://osu.ppy.sh/users/%s",
|
||||
'osu': {
|
||||
'title': 'osu!',
|
||||
'value': profile.user_osu|escape,
|
||||
'link': 'https://osu.ppy.sh/users/%s',
|
||||
},
|
||||
"website": {
|
||||
"title": "Website",
|
||||
"value": profile.user_website|escape,
|
||||
"link": "%s",
|
||||
'website': {
|
||||
'title': 'Website',
|
||||
'value': profile.user_website|escape,
|
||||
'link': '%s',
|
||||
'tooltip': '%s',
|
||||
},
|
||||
"youtube": {
|
||||
"title": "Youtube",
|
||||
"value": profile.user_youtube|escape,
|
||||
"link": "https://youtube.com/" ~ (youtube_is_channel_id ? "channel/" : '') ~ "%s",
|
||||
"format": youtube_is_channel_id ? "Channel" : "%s",
|
||||
'youtube': {
|
||||
'title': 'Youtube',
|
||||
'value': profile.user_youtube|escape,
|
||||
'link': 'https://youtube.com/' ~ (youtube_is_channel_id ? 'channel/' : '') ~ '%s',
|
||||
'format': youtube_is_channel_id ? 'Channel' : '%s',
|
||||
},
|
||||
"steam": {
|
||||
"title": "Steam",
|
||||
"value": profile.user_steam|escape,
|
||||
"link": "https://steamcommunity.com/id/%s",
|
||||
'steam': {
|
||||
'title': 'Steam',
|
||||
'value': profile.user_steam|escape,
|
||||
'link': 'https://steamcommunity.com/id/%s',
|
||||
},
|
||||
"twitchtv": {
|
||||
"title": "Twitch.tv",
|
||||
"value": profile.user_twitchtv|escape,
|
||||
"link": "https://twitch.tv/%s",
|
||||
'twitchtv': {
|
||||
'title': 'Twitch.tv',
|
||||
'value': profile.user_twitchtv|escape,
|
||||
'link': 'https://twitch.tv/%s',
|
||||
},
|
||||
"lastfm": {
|
||||
"title": "Last.fm",
|
||||
"value": profile.user_lastfm|escape,
|
||||
"link": "http://last.fm/user/%s",
|
||||
'lastfm': {
|
||||
'title': 'Last.fm',
|
||||
'value': profile.user_lastfm|escape,
|
||||
'link': 'http://last.fm/user/%s',
|
||||
},
|
||||
"github": {
|
||||
"title": "Github",
|
||||
"value": profile.user_github|escape,
|
||||
"link": "https://github.com/%s",
|
||||
'github': {
|
||||
'title': 'Github',
|
||||
'value': profile.user_github|escape,
|
||||
'link': 'https://github.com/%s',
|
||||
},
|
||||
"skype": {
|
||||
"title": "Skype",
|
||||
"value": profile.user_skype|escape,
|
||||
"link": "skype:%s?userinfo",
|
||||
'skype': {
|
||||
'title': 'Skype',
|
||||
'value': profile.user_skype|escape,
|
||||
'link': 'skype:%s?userinfo',
|
||||
},
|
||||
"discord": {
|
||||
"title": "Discord",
|
||||
"value": profile.user_discord|escape,
|
||||
'discord': {
|
||||
'title': 'Discord',
|
||||
'value': profile.user_discord|escape,
|
||||
},
|
||||
} %}
|
||||
|
||||
|
@ -74,7 +75,7 @@
|
|||
<div class="profile__info__block">
|
||||
{% if profile.user_title is not empty %}
|
||||
<div class="profile__info__row">
|
||||
<div class="profile__info__column profile__info__column--user-title" style="color:{{ profile.display_colour|colour_get_css }}">
|
||||
<div class="profile__info__column profile__info__column--user-title" style="{{ profile.user_colour|html_colour }}">
|
||||
{{ profile.user_title }}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -82,7 +83,7 @@
|
|||
|
||||
<div class="profile__info__row">
|
||||
<div class="profile__info__column profile__info__column--icons">
|
||||
<img class="profile__icon" src="https://static.flash.moe/flags/fff/{{ profile.user_country|lower }}.png" alt="{{ profile.user_country }}">
|
||||
<div class="flag flag--{{ profile.user_country|lower }} profile__icon">{{ profile.user_country }}</div>
|
||||
</div>
|
||||
<div class="profile__info__column profile__info__column--country">
|
||||
{{ profile.user_country|country_name }}
|
||||
|
@ -118,7 +119,7 @@
|
|||
Topics
|
||||
</div>
|
||||
<div class="profile__info__column profile__info__column--numeric">
|
||||
{{ profile.forum_topic_count }}
|
||||
{{ profile.forum_topic_count|number_format }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -127,26 +128,41 @@
|
|||
Posts
|
||||
</div>
|
||||
<div class="profile__info__column profile__info__column--numeric">
|
||||
{{ profile.forum_post_count }}
|
||||
{{ profile.forum_post_count|number_format }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if profile.changelog_count > 0 %}
|
||||
<div class="profile__info__block">
|
||||
<div class="profile__info__row">
|
||||
<div class="profile__info__column profile__info__column--heading">
|
||||
Changes
|
||||
</div>
|
||||
<div class="profile__info__column profile__info__column--numeric">
|
||||
{{ profile.changelog_count|number_format }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if app.hasActiveSession %}
|
||||
{% spaceless %}
|
||||
<div class="profile__info__section">
|
||||
<div class="profile__info__block profile__info__block--links">
|
||||
{% autoescape false %}
|
||||
{% for name, data in profile_fields %}
|
||||
{% if (data.display is defined ? data.display : true) and data.value|length > 0 %}
|
||||
<div class="profile__info__row profile__info__row--field-{{ name }}">
|
||||
<div class="profile__info__column profile__info__column--heading">
|
||||
{{ data.title }}
|
||||
</div>
|
||||
<div class="profile__info__column">
|
||||
<div class="profile__info__column"
|
||||
{% if data.tooltip is defined %}title="{{ data.tooltip|format(data.value)|raw }}"{% endif %}>
|
||||
{% set profile_field_value = (data.format is defined ? data.format : '%s')|format(data.value) %}
|
||||
{% if data.link is defined %}
|
||||
{{ link(data.link|format(data.value), profile_field_value, 'profile__account-link') }}
|
||||
{{ data.link|format(data.value)|html_link(profile_field_value, 'profile__account-link') }}
|
||||
{% else %}
|
||||
{{ profile_field_value }}
|
||||
{% endif %}
|
||||
|
@ -154,6 +170,7 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endautoescape %}
|
||||
</div>
|
||||
</div>
|
||||
{% endspaceless %}
|
||||
|
|
Loading…
Add table
Reference in a new issue