Removed the existing, broken follow system.

This commit is contained in:
flash 2021-08-28 20:25:01 +00:00
parent 813d3421bb
commit 50dee8eeb4
17 changed files with 64 additions and 663 deletions

View file

@ -15,7 +15,6 @@ var Misuzu = function() {
Misuzu.CSRF.init();
Misuzu.Urls.loadFromDocument();
Misuzu.User.refreshLocalUser();
Misuzu.UserRelations.init();
Misuzu.FormUtils.initDataRequestMethod();
Misuzu.initQuickSubmit();
Misuzu.Comments.init();

View file

@ -1,104 +0,0 @@
Misuzu.UserRelations = {};
Misuzu.UserRelations.Type = DefineEnum({ none: 0, follow: 1, });
Misuzu.UserRelations.init = function() {
var buttons = document.getElementsByClassName('js-user-relation-action');
for(var i = 0; i < buttons.length; ++i) {
switch(buttons[i].tagName.toLowerCase()) {
case 'a':
buttons[i].removeAttribute('href');
buttons[i].removeAttribute('target');
buttons[i].removeAttribute('rel');
break;
}
buttons[i].addEventListener('click', Misuzu.UserRelations.setRelationHandler);
}
};
Misuzu.UserRelations.setRelation = function(user, type, onSuccess, onFailure) {
var xhr = new XMLHttpRequest;
xhr.addEventListener('readystatechange', function() {
if(xhr.readyState !== 4)
return;
Misuzu.CSRF.setToken(xhr.getResponseHeader('X-Misuzu-CSRF'));
var json = JSON.parse(xhr.responseText),
message = json.error || json.message;
if(message && onFailure)
onFailure(message);
else if(!message && onSuccess)
onSuccess(json);
});
xhr.open('GET', Misuzu.Urls.format('user-relation-create', [Misuzu.Urls.v('user', user), Misuzu.Urls.v('type', type)]));
xhr.setRequestHeader('X-Misuzu-XHR', 'user_relation');
xhr.setRequestHeader('X-Misuzu-CSRF', Misuzu.CSRF.getToken());
xhr.send();
};
Misuzu.UserRelations.ICO_ADD = 'fas fa-user-plus';
Misuzu.UserRelations.ICO_REM = 'fas fa-user-minus';
Misuzu.UserRelations.ICO_BUS = 'fas fa-spinner fa-pulse';
Misuzu.UserRelations.BTN_BUS = 'input__button--busy';
Misuzu.UserRelations.setRelationHandler = function(ev) {
var target = this,
userId = parseInt(target.dataset.relationUser),
relationType = parseInt(target.dataset.relationType),
isButton = target.classList.contains('input__button'),
icon = target.querySelector('[class^="fa"]');
if(isButton) {
if(target.classList.contains(Misuzu.UserRelations.BTN_BUS))
return;
target.classList.add(Misuzu.UserRelations.BTN_BUS);
}
if(icon)
icon.className = Misuzu.UserRelations.ICO_BUS;
Misuzu.UserRelations.setRelation(
userId,
relationType,
function(info) {
target.classList.remove(Misuzu.UserRelations.BTN_BUS);
switch(info.relation_type) {
case Misuzu.UserRelations.Type.none:
if(isButton) {
if(target.classList.contains('input__button--destroy'))
target.classList.remove('input__button--destroy');
target.textContent = 'Follow';
}
if(icon) {
icon.className = Misuzu.UserRelations.ICO_ADD;
target.title = 'Follow';
}
target.dataset.relationType = Misuzu.UserRelations.Type.follow.toString();
break;
case Misuzu.UserRelations.Type.follow:
if(isButton) {
if(!target.classList.contains('input__button--destroy'))
target.classList.add('input__button--destroy');
target.textContent = 'Unfollow';
}
if(icon) {
icon.className = Misuzu.UserRelations.ICO_REM;
target.title = 'Unfollow';
}
target.dataset.relationType = Misuzu.UserRelations.Type.none.toString();
break;
}
},
function(msg) {
target.classList.remove(Misuzu.UserRelations.BTN_BUS);
Misuzu.showMessageBox(msg);
}
);
};

View file

@ -0,0 +1,33 @@
<?php
namespace Misuzu\DatabaseMigrations\NukeRelationsTable;
use PDO;
function migrate_up(PDO $conn): void {
$conn->exec("DROP TABLE `msz_user_relations`");
}
function migrate_down(PDO $conn): void {
$conn->exec("
CREATE TABLE `msz_user_relations` (
`user_id` INT(10) UNSIGNED NOT NULL,
`subject_id` INT(10) UNSIGNED NOT NULL,
`relation_type` TINYINT(3) UNSIGNED NOT NULL,
`relation_created` TIMESTAMP NOT NULL DEFAULT current_timestamp(),
UNIQUE INDEX `user_relations_unique` (`user_id`, `subject_id`) USING BTREE,
INDEX `user_relations_subject_id_foreign` (`subject_id`) USING BTREE,
INDEX `user_relations_type_index` (`relation_type`) USING BTREE,
INDEX `user_relations_created_index` (`relation_created`) USING BTREE,
CONSTRAINT `user_relations_subject_id_foreign`
FOREIGN KEY (`subject_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT `user_relations_user_id_foreign`
FOREIGN KEY (`user_id`)
REFERENCES `msz_users` (`user_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) COLLATE='utf8mb4_bin' ENGINE=InnoDB;
");
}

View file

@ -160,10 +160,6 @@ $statistics = DB::query('
SELECT COUNT(`user_id`)
FROM `msz_users_password_resets`
) AS `stat_user_password_resets`,
(
SELECT COUNT(`user_id`)
FROM `msz_user_relations`
) AS `stat_user_relations`,
(
SELECT COUNT(`warning_id`)
FROM `msz_user_warnings`

View file

@ -53,16 +53,6 @@ $orderFields = [
'default-dir' => 'desc',
'title' => 'Forum Posts',
],
'following' => [
'column' => '`user_count_following`',
'default-dir' => 'desc',
'title' => 'Following',
],
'followers' => [
'column' => '`user_count_followers`',
'default-dir' => 'desc',
'title' => 'Followers',
],
];
if(empty($orderBy)) {
@ -111,31 +101,7 @@ $getUsers = DB::prepare(sprintf(
FROM `msz_forum_posts`
WHERE `user_id` = u.`user_id`
AND `post_deleted` IS NULL
) AS `user_count_posts`,
(
SELECT COUNT(`subject_id`)
FROM `msz_user_relations`
WHERE `user_id` = u.`user_id`
AND `relation_type` = %4$d
) AS `user_count_following`,
(
SELECT COUNT(`user_id`)
FROM `msz_user_relations`
WHERE `subject_id` = u.`user_id`
AND `relation_type` = %4$d
) AS `user_count_followers`,
(
SELECT `relation_type` = %4$d
FROM `msz_user_relations`
WHERE `user_id` = `current_user_id`
AND `subject_id` = u.`user_id`
) AS `user_is_following`,
(
SELECT `relation_type` = %4$d
FROM `msz_user_relations`
WHERE `user_id` = u.`user_id`
AND `subject_id` = `current_user_id`
) AS `user_is_follower`
) AS `user_count_posts`
FROM `msz_users` AS u
LEFT JOIN `msz_roles` AS r
ON r.`role_id` = u.`display_role`
@ -144,12 +110,11 @@ $getUsers = DB::prepare(sprintf(
WHERE ur.`role_id` = :role_id
%1$s
ORDER BY %2$s %3$s
LIMIT %5$d, %6$d
LIMIT %4$d, %5$d
',
$canManageUsers ? '' : 'AND u.`user_deleted` IS NULL',
$orderFields[$orderBy]['column'],
$orderDir,
\Misuzu\Users\UserRelation::TYPE_FOLLOW,
$pagination->getOffset(),
$pagination->getRange()
));

View file

@ -262,7 +262,7 @@ if($isEditing) {
}
}
$profileStats = DB::prepare(sprintf('
$profileStats = DB::prepare('
SELECT (
SELECT COUNT(`topic_id`)
FROM `msz_forum_topics`
@ -285,64 +285,16 @@ $profileStats = DB::prepare(sprintf('
FROM `msz_comments_posts`
WHERE `user_id` = u.`user_id`
AND `comment_deleted` IS NULL
) AS `comments_count`,
(
SELECT COUNT(`user_id`)
FROM `msz_user_relations`
WHERE `subject_id` = u.`user_id`
AND `relation_type` = %1$d
) AS `followers_count`,
(
SELECT COUNT(`subject_id`)
FROM `msz_user_relations`
WHERE `user_id` = u.`user_id`
AND `relation_type` = %1$d
) AS `following_count`
) AS `comments_count`
FROM `msz_users` AS u
WHERE `user_id` = :user_id
', \Misuzu\Users\UserRelation::TYPE_FOLLOW))->bind('user_id', $profileUser->getId())->fetch();
')->bind('user_id', $profileUser->getId())->fetch();
switch($profileMode) {
default:
echo render_error(404);
return;
case 'following':
$template = 'profile.relations';
$pagination = new Pagination($profileUser->getFollowingCount(), 15);
if(!$pagination->hasValidOffset()) {
echo render_error(404);
return;
}
Template::set([
'title' => $profileUser->getUsername() . ' / following',
'canonical_url' => url('user-profile-following', ['user' => $profileUser->getId()]),
'profile_users' => $profileUser->getFollowing($pagination),
'profile_relation_pagination' => $pagination,
'relation_prop' => 'subject',
]);
break;
case 'followers':
$template = 'profile.relations';
$pagination = new Pagination($profileUser->getFollowersCount(), 15);
if(!$pagination->hasValidOffset()) {
echo render_error(404);
return;
}
Template::set([
'title' => $profileUser->getUsername() . ' / followers',
'canonical_url' => url('user-profile-followers', ['user' => $profileUser->getId()]),
'profile_users' => $profileUser->getFollowers($pagination),
'profile_relation_pagination' => $pagination,
'relation_prop' => 'user',
]);
break;
case 'forum-topics':
$template = 'profile.topics';
$topicsCount = forum_topic_count_user($profileUser->getId(), $currentUserId);

View file

@ -1,80 +0,0 @@
<?php
namespace Misuzu;
use Misuzu\Config;
use Misuzu\Users\User;
use Misuzu\Users\UserNotFoundException;
use Misuzu\Users\UserRelation;
require_once '../misuzu.php';
// basing whether or not this is an xhr request on whether a referrer header is present
// this page is never directy accessed, under normal circumstances
$redirect = !empty($_SERVER['HTTP_REFERER']) && empty($_SERVER['HTTP_X_MISUZU_XHR']) ? $_SERVER['HTTP_REFERER'] : '';
$isXHR = !$redirect;
if($isXHR) {
header('Content-Type: application/json; charset=utf-8');
} elseif(!is_local_url($redirect)) {
echo render_info('Possible request forgery detected.', 403);
return;
}
if(!CSRF::validateRequest()) {
echo render_info_or_json($isXHR, "Couldn't verify this request, please refresh the page and try again.", 403);
return;
}
header(CSRF::header());
$currentUser = User::getCurrent();
if($currentUser === null) {
echo render_info_or_json($isXHR, 'You must be logged in to manage relations.', 401);
return;
}
if($currentUser->isBanned()) {
echo render_info_or_json($isXHR, 'You have been banned, check your profile for more information.', 403);
return;
}
$subjectId = !empty($_GET['u']) && is_string($_GET['u']) ? (int)$_GET['u'] : 0;
$relationType = isset($_GET['m']) && is_string($_GET['m']) ? (int)$_GET['m'] : -1;
if($relationType < 0) {
echo render_info_or_json($isXHR, 'Invalid relation type.', 400);
return;
}
$relationType = $relationType > 0 ? UserRelation::TYPE_FOLLOW : UserRelation::TYPE_NONE;
try {
$subjectInfo = User::byId($subjectId);
} catch(UserNotFoundException $ex) {
echo render_info_or_json($isXHR, "That user doesn't exist.", 400);
return;
}
if($relationType > 0)
$subjectInfo->addFollower($currentUser);
else
$subjectInfo->removeRelation($currentUser);
if(in_array($subjectInfo->getId(), Config::get('relations.replicate', Config::TYPE_ARR))) {
if($relationType > 0)
$currentUser->addFollower($subjectInfo);
else
$currentUser->removeRelation($subjectInfo);
}
if(!$isXHR) {
redirect($redirect);
return;
}
echo json_encode([
'user_id' => $currentUser->getId(),
'subject_id' => $subjectInfo->getId(),
'relation_type' => $relationType,
]);

View file

@ -13,11 +13,8 @@ if(!empty($searchQuery)) {
$forumPosts = forum_post_search($searchQuery);
$newsPosts = NewsPost::bySearchQuery($searchQuery);
$findUsers = DB::prepare(sprintf(
'
SELECT
:current_user_id AS `current_user_id`,
u.`user_id`, u.`username`, u.`user_country`,
$findUsers = DB::prepare('
SELECT u.`user_id`, u.`username`, u.`user_country`,
u.`user_created`, u.`user_active`, r.`role_id`,
COALESCE(u.`user_title`, r.`role_title`) AS `user_title`,
COALESCE(u.`user_colour`, r.`role_colour`) AS `user_colour`,
@ -32,31 +29,7 @@ if(!empty($searchQuery)) {
FROM `msz_forum_posts`
WHERE `user_id` = u.`user_id`
AND `post_deleted` IS NULL
) AS `user_count_posts`,
(
SELECT COUNT(`subject_id`)
FROM `msz_user_relations`
WHERE `user_id` = u.`user_id`
AND `relation_type` = %1$d
) AS `user_count_following`,
(
SELECT COUNT(`user_id`)
FROM `msz_user_relations`
WHERE `subject_id` = u.`user_id`
AND `relation_type` = %1$d
) AS `user_count_followers`,
(
SELECT `relation_type` = %1$d
FROM `msz_user_relations`
WHERE `user_id` = `current_user_id`
AND `subject_id` = u.`user_id`
) AS `user_is_following`,
(
SELECT `relation_type` = %1$d
FROM `msz_user_relations`
WHERE `user_id` = u.`user_id`
AND `subject_id` = `current_user_id`
) AS `user_is_follower`
) AS `user_count_posts`
FROM `msz_users` AS u
LEFT JOIN `msz_roles` AS r
ON r.`role_id` = u.`display_role`
@ -64,11 +37,8 @@ if(!empty($searchQuery)) {
ON ur.`user_id` = u.`user_id`
WHERE LOWER(u.`username`) LIKE CONCAT("%%", LOWER(:query), "%%")
GROUP BY u.`user_id`
',
\Misuzu\Users\UserRelation::TYPE_FOLLOW
));
');
$findUsers->bind('query', $searchQuery);
$findUsers->bind('current_user_id', User::hasCurrent() ? User::getCurrent()->getId() : 0);
$users = $findUsers->fetchAll();
}

View file

@ -64,7 +64,6 @@ if(isset($_POST['action']) && is_string($_POST['action'])) {
db_to_zip($archive, $currentUserId, 'users.json', 'SELECT *, NULL AS `password`, NULL AS `user_totp_key`, INET6_NTOA(`register_ip`) AS `register_ip`, INET6_NTOA(`last_ip`) AS `last_ip` FROM `msz_users` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'users_password_resets.json', 'SELECT *, INET6_NTOA(`reset_ip`) AS `reset_ip` FROM `msz_users_password_resets` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'user_chat_tokens.json', 'SELECT * FROM `msz_user_chat_tokens` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'user_relations.json', 'SELECT * FROM `msz_user_relations` WHERE `user_id` = :user_id_1 OR `subject_id` = :user_id_2', 2);
db_to_zip($archive, $currentUserId, 'user_roles.json', 'SELECT * FROM `msz_user_roles` WHERE `user_id` = :user_id');
db_to_zip($archive, $currentUserId, 'user_warnings.json', 'SELECT *, INET6_NTOA(`user_ip`) AS `user_ip`, NULL AS `issuer_id`, NULL AS `issuer_ip`, NULL AS `warning_note_private` FROM `msz_user_warnings` WHERE `user_id` = :user_id');

View file

@ -54,8 +54,6 @@ class User implements HasRankInterface, JsonSerializable {
public const ORDER_ACTIVE = 'last-online';
public const ORDER_FORUM_TOPICS = 'forum-topics';
public const ORDER_FORUM_POSTS = 'forum-posts';
public const ORDER_FOLLOWING = 'following';
public const ORDER_FOLLOWERS = 'followers';
// Database fields
private $user_id = -1;
@ -537,68 +535,6 @@ class User implements HasRankInterface, JsonSerializable {
return array_key_exists($role->getId(), $this->getRoleRelations());
}
/*************
* RELATIONS *
*************/
private $relationCache = [];
private $relationFollowingCount = -1;
private $relationFollowersCount = -1;
public function getRelation(self $other): UserRelation {
if(isset($this->relationCache[$other->getId()]))
return $this->relationCache[$other->getId()];
return $this->relationCache[$other->getId()] = UserRelation::byUserAndSubject($this, $other);
}
public function getRelationString(self $other): string {
if($other->getId() === $this->getId())
return 'self';
$from = $this->getRelation($other);
$to = $other->getRelation($this);
if($from->isFollow() && $to->isFollow())
return 'mutual';
if($from->isFollow())
return 'following';
if($to->isFollow())
return 'followed';
return 'none';
}
public function getRelationTime(self $other): int {
if($other->getId() === $this->getId())
return -1;
$from = $this->getRelation($other);
$to = $other->getRelation($this);
return max($from->getCreationTime(), $to->getCreationTime());
}
public function addFollower(self $other): void {
UserRelation::create($other, $this, UserRelation::TYPE_FOLLOW);
unset($this->relationCache[$other->getId()]);
}
public function removeRelation(self $other): void {
UserRelation::destroy($other, $this);
unset($this->relationCache[$other->getId()]);
}
public function getFollowers(?Pagination $pagination = null): array {
return UserRelation::bySubject($this, UserRelation::TYPE_FOLLOW, $pagination);
}
public function getFollowersCount(): int {
if($this->relationFollowersCount < 0)
$this->relationFollowersCount = UserRelation::countBySubject($this, UserRelation::TYPE_FOLLOW);
return $this->relationFollowersCount;
}
public function getFollowing(?Pagination $pagination = null): array {
return UserRelation::byUser($this, UserRelation::TYPE_FOLLOW, $pagination);
}
public function getFollowingCount(): int {
if($this->relationFollowingCount < 0)
$this->relationFollowingCount = UserRelation::countByUser($this, UserRelation::TYPE_FOLLOW);
return $this->relationFollowingCount;
}
/***************
* FORUM STATS *
***************/

View file

@ -1,165 +0,0 @@
<?php
namespace Misuzu\Users;
use Misuzu\DB;
use Misuzu\Pagination;
class UserRelation {
public const TYPE_NONE = 0;
public const TYPE_FOLLOW = 1;
// Database fields
private $user_id = -1;
private $subject_id = -1;
private $relation_type = 0;
private $relation_created = null;
private $user = null;
private $subject = null;
public const TABLE = 'user_relations';
private const QUERY_SELECT = 'SELECT %1$s FROM `' . DB::PREFIX . self::TABLE . '` AS '. self::TABLE;
private const SELECT = '%1$s.`user_id`, %1$s.`subject_id`, %1$s.`relation_type`'
. ', UNIX_TIMESTAMP(%1$s.`relation_created`) AS `relation_created`';
public function getUserId(): int {
return $this->user_id < 1 ? -1 : $this->user_id;
}
public function getUser(): User {
if($this->user === null)
$this->user = User::byId($this->getUserId());
return $this->user;
}
public function getSubjectId(): int {
return $this->subject_id < 1 ? -1 : $this->subject_id;
}
public function getSubject(): User {
if($this->subject === null)
$this->subject = User::byId($this->getSubjectId());
return $this->subject;
}
public function getType(): int {
return $this->relation_type;
}
public function isNone(): bool {
return $this->getType() === self::TYPE_NONE;
}
public function isFollow(): bool {
return $this->getType() === self::TYPE_FOLLOW;
}
public function getCreationTime(): int {
return $this->relation_created === null ? -1 : $this->relation_created;
}
public static function destroy(User $user, User $subject): void {
DB::prepare('DELETE FROM `' . DB::PREFIX . self::TABLE . '` WHERE `user_id` = :user AND `subject_id` = :subject')
->bind('user', $user->getId())
->bind('subject', $subject->getId())
->execute();
}
public static function create(User $user, User $subject, int $type): void {
if($type === self::TYPE_NONE) {
self::destroy($user, $subject);
return;
}
DB::prepare(
'REPLACE INTO `' . DB::PREFIX . self::TABLE . '` (`user_id`, `subject_id`, `relation_type`)'
. ' VALUES (:user, :subject, :type)'
) ->bind('user', $user->getId())
->bind('subject', $subject->getId())
->bind('type', $type)
->execute();
}
private static function countQueryBase(): string {
return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE));
}
public static function countByUser(User $user, ?int $type = null): int {
$count = DB::prepare(
self::countQueryBase()
. ' WHERE `user_id` = :user'
. ($type === null ? '' : ' AND `relation_type` = :type')
) ->bind('user', $user->getId());
if($type !== null)
$count->bind('type', $type);
return (int)$count->fetchColumn();
}
public static function countBySubject(User $subject, ?int $type = null): int {
$count = DB::prepare(
self::countQueryBase()
. ' WHERE `subject_id` = :subject'
. ($type === null ? '' : ' AND `relation_type` = :type')
) ->bind('subject', $subject->getId());
if($type !== null)
$count->bind('type', $type);
return (int)$count->fetchColumn();
}
private static function byQueryBase(): string {
return sprintf(self::QUERY_SELECT, sprintf(self::SELECT, self::TABLE));
}
public static function byUserAndSubject(User $user, User $subject): self {
$object = DB::prepare(self::byQueryBase() . ' WHERE `user_id` = :user AND `subject_id` = :subject')
->bind('user', $user->getId())
->bind('subject', $subject->getId())
->fetchObject(self::class);
if(!$object) {
$fake = new static;
$fake->user_id = $user->getId();
$fake->user = $user;
$fake->subject_id = $subject->getId();
$fake->subject = $subject;
return $fake;
}
return $object;
}
public static function byUser(User $user, ?int $type = null, ?Pagination $pagination = null): array {
$query = self::byQueryBase()
. ' WHERE `user_id` = :user'
. ($type === null ? '' : ' AND `relation_type` = :type')
. ' ORDER BY `relation_created` DESC';
if($pagination !== null)
$query .= ' LIMIT :range OFFSET :offset';
$get = DB::prepare($query)
->bind('user', $user->getId());
if($type !== null)
$get->bind('type', $type);
if($pagination !== null)
$get->bind('range', $pagination->getRange())
->bind('offset', $pagination->getOffset());
return $get->fetchObjects(self::class);
}
public static function bySubject(User $subject, ?int $type = null, ?Pagination $pagination = null): array {
$query = self::byQueryBase()
. ' WHERE `subject_id` = :subject'
. ($type === null ? '' : ' AND `relation_type` = :type')
. ' ORDER BY `relation_created` DESC';
if($pagination !== null)
$query .= ' LIMIT :range OFFSET :offset';
$get = DB::prepare($query)
->bind('subject', $subject->getId());
if($type !== null)
$get->bind('type', $type);
if($pagination !== null)
$get->bind('range', $pagination->getRange())
->bind('offset', $pagination->getOffset());
return $get->fetchObjects(self::class);
}
}

View file

@ -67,8 +67,6 @@ define('MSZ_URLS', [
'user-list' => ['/members.php', ['r' => '<role>', 'ss' => '<sort>', 'sd' => '<direction>', 'p' => '<page>']],
'user-profile' => ['/profile.php', ['u' => '<user>']],
'user-profile-following' => ['/profile.php', ['u' => '<user>', 'm' => 'following']],
'user-profile-followers' => ['/profile.php', ['u' => '<user>', 'm' => 'followers']],
'user-profile-forum-topics' => ['/profile.php', ['u' => '<user>', 'm' => 'forum-topics']],
'user-profile-forum-posts' => ['/profile.php', ['u' => '<user>', 'm' => 'forum-posts']],
'user-profile-edit' => ['/profile.php', ['u' => '<user>', 'edit' => '1']],
@ -77,10 +75,6 @@ define('MSZ_URLS', [
'user-avatar' => ['/assets/avatar/<user>', ['res' => '<res>']],
'user-background' => ['/assets/profile-background/<user>'],
'user-relation-create' => ['/relations.php', ['u' => '<user>', 'm' => '<type>', 'csrf' => '{csrf}']],
'user-relation-none' => ['/relations.php', ['u' => '<user>', 'm' => '[\Misuzu\Users\UserRelation::TYPE_NONE]', 'csrf' => '{csrf}']],
'user-relation-follow' => ['/relations.php', ['u' => '<user>', 'm' => '[\Misuzu\Users\UserRelation::TYPE_FOLLOW]', 'csrf' => '{csrf}']],
'settings-index' => ['/settings'],
'settings-account' => ['/settings/account.php'],
'settings-sessions' => ['/settings/sessions.php'],

View file

@ -25,7 +25,7 @@
<p class="auth__register__paragraph">By creating an account you agree to the <a href="{{ url('info', {'title': 'rules'}) }}" class="auth__register__link">rules</a>.</p>
<p class="auth__register__paragraph">Engaging in borderline illegal activity on platforms provided by Flashii will result in a permanent ban, as described by Global Rule 5.</p>
<p class="auth__register__paragraph">You are not allowed to have more than one account unless given explicit permission, as described by Global Rule 6.</p>
<p class="auth__register__paragraph">You must be at least 13 years of age to use this website, as described by Global Rule 8.</p>
<p class="auth__register__paragraph">You must be at least 18 years of age to use this website, as described by Global Rule 8.</p>
</div>
{% endif %}

View file

@ -35,7 +35,6 @@
'stat_login_attempts_failed': 'Failed Login Attempts',
'stat_user_sessions': 'Active User Sessions',
'stat_user_password_resets': 'Pending Password Resets',
'stat_user_relations': 'User Relations',
'stat_user_warnings': 'User Warnings',
} %}

View file

@ -56,18 +56,6 @@
</div>
{% endif %}
</div>
{% if profile_viewer is not null and profile_user.id != profile_viewer.id and profile_user.relationString(profile_viewer) != 'none' %}
<div class="profile__header__details__relation" title="Since {{ profile_user.relationTime(profile_viewer)|date('r') }}">
{% if profile_user.relationString(profile_viewer) == 'mutual' %}
Mutual Friends
{% elseif profile_user.relationString(profile_viewer) == 'followed' %}
You Follow
{% elseif profile_user.relationString(profile_viewer) == 'following' %}
Follows You
{% endif %}
</div>
{% endif %}
</div>
<div class="profile__header__options">
@ -81,14 +69,6 @@
{% elseif profile_can_edit %}
<a href="{{ url('user-profile-edit', {'user': profile_user.id}) }}" class="input__button profile__header__action">Edit Profile</a>
{% endif %}
{% if current_user is defined and current_user.id|default(0) != profile_user.id and not profile_is_editing %}
{% if profile_user.relationString(profile_viewer) != 'following' %}
<a href="{{ url('user-relation-none', {'user': profile_user.id}) }}" class="input__button input__button--destroy profile__header__action js-user-relation-action" data-relation-user="{{ profile_user.id }}" data-relation-type="0">Unfollow</a>
{% else %}
<a href="{{ url('user-relation-follow', {'user': profile_user.id}) }}" class="input__button profile__header__action js-user-relation-action" data-relation-user="{{ profile_user.id }}" data-relation-type="1">Follow</a>
{% endif %}
{% endif %}
{% else %}
<a href="{{ url('user-profile', {'user': profile_user.id}) }}" class="input__button profile__header__action">Return</a>
{% endif %}

View file

@ -17,18 +17,6 @@
'is_date': true,
'value': profile_user.activeTime,
},
{
'title': 'Following',
'value': profile_stats.following_count,
'url': url('user-profile-following', {'user': profile_user.id}),
'active': profile_mode == 'following',
},
{
'title': 'Followers',
'value': profile_stats.followers_count,
'url': url('user-profile-followers', {'user': profile_user.id}),
'active': profile_mode == 'followers',
},
{
'title': 'Topics',
'value': profile_stats.forum_topic_count,

View file

@ -47,28 +47,6 @@
<div class="usercard__container">
<div class="usercard__stats">
{% if user.followingCount > 0 %}
<a class="usercard__stat" href="{{ url('user-profile-following', {'user': user.id}) }}">
<div class="usercard__stat__name">
Following
</div>
<div class="usercard__stat__value">
{{ user.followingCount|number_format }}
</div>
</a>
{% endif %}
{% if user.followersCount > 0 %}
<a class="usercard__stat" href="{{ url('user-profile-followers', {'user': user.id}) }}">
<div class="usercard__stat__name">
Followers
</div>
<div class="usercard__stat__value">
{{ user.followersCount|number_format }}
</div>
</a>
{% endif %}
{% if user.forumTopicCount > 0 %}
<a class="usercard__stat" href="{{ url('user-profile-forum-topics', {'user': user.id}) }}">
<div class="usercard__stat__name">
@ -112,14 +90,6 @@
<a class="usercard__action" href="{{ url('user-profile', {'user': user.id}) }}" title="View Profile">
<i class="fas fa-user"></i>
</a>
{% if current_user is not null %}
{% set is_following = current_user.relationString(user) in ['mutual', 'following'] %}
<a class="usercard__action js-user-relation-action" href="{{ url('user-relation-follow', {'user': user.id}) }}" title="{{ is_following ? 'Unfollow' : 'Follow' }}"
data-relation-user="{{ user.id }}" data-relation-type="{{ is_following ? 0 : 1 }}">
<i class="fas fa-user-{{ is_following ? 'minus' : 'plus' }}"></i>
</a>
{% endif %}
</div>
</div>
</div>
@ -164,28 +134,6 @@
<div class="usercard__container">
<div class="usercard__stats">
{% if user.user_count_following|default(0) > 0 %}
<a class="usercard__stat" href="{{ url('user-profile-following', {'user': user.user_id}) }}">
<div class="usercard__stat__name">
Following
</div>
<div class="usercard__stat__value">
{{ user.user_count_following|number_format }}
</div>
</a>
{% endif %}
{% if user.user_count_followers|default(0) > 0 %}
<a class="usercard__stat" href="{{ url('user-profile-followers', {'user': user.user_id}) }}">
<div class="usercard__stat__name">
Followers
</div>
<div class="usercard__stat__value">
{{ user.user_count_followers|number_format }}
</div>
</a>
{% endif %}
{% if user.user_count_topics|default(0) > 0 %}
<a class="usercard__stat" href="{{ url('user-profile-forum-topics', {'user': user.user_id}) }}">
<div class="usercard__stat__name">
@ -233,15 +181,6 @@
<a class="usercard__action" href="{{ url('user-profile', {'user': user.user_id}) }}" title="View Profile">
<i class="fas fa-user"></i>
</a>
{% if user.current_user_id|default(0) != 0 and user.current_user_id != user.user_id %}
{% set is_following = user.user_is_following|default(false) %}
<a class="usercard__action js-user-relation-action" href="{{ url('user-relation-follow', {'user': user.user_id}) }}" title="{{ is_following ? 'Unfollow' : 'Follow' }}"
data-relation-user="{{ user.user_id }}" data-relation-type="{{ is_following ? 0 : 1 }}">
<i class="fas fa-user-{{ is_following ? 'minus' : 'plus' }}"></i>
</a>
{% endif %}
</div>
</div>
</div>