Moved some of the comments javascript stuff to typescript.

This commit is contained in:
flash 2018-11-15 23:53:52 +01:00
parent 89afab2d96
commit b84121e277
8 changed files with 149 additions and 63 deletions

View file

@ -0,0 +1,66 @@
let globalCommentLock = false;
function commentsLocked(): boolean
{
return globalCommentLock;
}
function commentsRequestLock(): boolean
{
if (commentsLocked())
return false;
globalCommentLock = true;
return true;
}
function commentsFreeLock(): void
{
globalCommentLock = false;
}
interface CommentDeletionInfo {
comment_id: number;
error: string;
message: string;
}
function commentDelete(ev: Event)
{
if (!checkUserPerm('comments', CommentPermission.Delete) || !commentsRequestLock())
return;
const xhr: XMLHttpRequest = new XMLHttpRequest(),
target: HTMLAnchorElement = ev.target as HTMLAnchorElement;
xhr.addEventListener('readystatechange', () => {
if (xhr.readyState !== 4)
return;
commentsFreeLock();
var json: CommentDeletionInfo = JSON.parse(xhr.responseText) as CommentDeletionInfo,
message = json.error || json.message;
if (message)
alert(message);
else {
var elem = document.getElementById('comment-' + json.comment_id);
if (elem)
elem.parentNode.removeChild(elem);
}
});
xhr.open('GET', target.dataset.href);
xhr.setRequestHeader('X-Misuzu-XHR', 'comments');
xhr.send();
}
function commentsInit() {
const commentDeletes: HTMLCollectionOf<HTMLAnchorElement> = document.getElementsByClassName('comment__action--delete') as HTMLCollectionOf<HTMLAnchorElement>;
for (var i = 0; i < commentDeletes.length; i++) {
commentDeletes[i].onclick = commentDelete;
commentDeletes[i].dataset.href = commentDeletes[i].href;
commentDeletes[i].href = 'javascript:void(0);';
}
}

View file

@ -1,6 +0,0 @@
interface CurrentUserInfo {
user_id: number;
username: string;
user_background_settings: number;
user_colour: number;
}

View file

@ -0,0 +1,26 @@
enum CommentPermission {
Create = 1,
EditOwn = 1 << 1,
EditAny = 1 << 2,
Edit = EditOwn | EditAny,
DeleteOwn = 1 << 3,
DeleteAny = 1 << 4,
Delete = DeleteOwn | DeleteAny,
Pin = 1 << 5,
Lock = 1 << 6,
Vote = 1 << 7,
}
function checkPerm(perms: number, perm: number): boolean {
return (perms & perm) > 0;
}
function checkUserPerm(set: string, perm: number): boolean {
const perms: number = getCurrentUser(set + '_perms') as number;
if (!perms) {
return false;
}
return checkPerm(perms, perm);
}

46
assets/typescript/User.ts Normal file
View file

@ -0,0 +1,46 @@
interface CurrentUserInfo {
user_id: number;
username: string;
user_background_settings: number;
user_colour: number;
colour: Colour;
}
let userInfo: CurrentUserInfo;
function getRawCurrentUserInfo(): CurrentUserInfo
{
const userInfoElement: HTMLDivElement = document.getElementById('js-user-info') as HTMLDivElement;
if (!userInfoElement)
return null;
return JSON.parse(userInfoElement.textContent) as CurrentUserInfo;
}
function refreshCurrentUserInfo(): void
{
userInfo = getRawCurrentUserInfo();
if (userInfo)
userInfo.colour = new Colour(userInfo.user_colour);
}
function getCurrentUser(attribute: string = null)
{
if (attribute) {
if (!userInfo) {
return '';
}
return userInfo[attribute] || '';
}
return userInfo || null;
}
function userInit(): void
{
refreshCurrentUserInfo();
console.log(`You are ${getCurrentUser('username')} with user id ${getCurrentUser('user_id')} and colour ${getCurrentUser('colour').hex}.`);
}

View file

@ -1,11 +1,12 @@
/// <reference path="CurrentUserInfo.ts" />
/// <reference path="User.ts" />
/// <reference path="Colour.ts" />
/// <reference path="Support.ts" />
/// <reference path="Permissions.ts" />
/// <reference path="Comments.ts" />
declare const timeago: any;
declare const hljs: any;
let userInfo: CurrentUserInfo;
let loginFormAvatarTimeout: number = 0;
// Initialisation process.
@ -13,15 +14,7 @@ window.addEventListener('load', () => {
timeago().render(document.querySelectorAll('time'));
hljs.initHighlighting();
const userInfoElement: HTMLDivElement = document.getElementById('user-info') as HTMLDivElement;
if (userInfoElement) {
userInfo = JSON.parse(userInfoElement.textContent) as CurrentUserInfo;
const colour: Colour = new Colour(userInfo.user_colour);
console.log(`You are ${userInfo.username} with user id ${userInfo.user_id} and colour ${colour.hex}.`);
}
userInit();
const changelogChangeAction: HTMLDivElement = document.querySelector('.changelog__change__action') as HTMLDivElement;
@ -43,6 +36,8 @@ window.addEventListener('load', () => {
loginUsername.addEventListener('keyup', () => loginFormUpdateAvatar(loginAvatar, loginUsername));
}
}
commentsInit();
});
function loginFormUpdateAvatar(avatarElement: HTMLElement, usernameElement: HTMLInputElement, force: boolean = false): void {

View file

@ -305,6 +305,10 @@ MIG;
');
$getUserDisplayInfo->bindValue('user_id', $mszUserId);
$userDisplayInfo = $getUserDisplayInfo->execute() ? $getUserDisplayInfo->fetch(\PDO::FETCH_ASSOC) : [];
if ($userDisplayInfo) {
$userDisplayInfo['comments_perms'] = perms_get_user(MSZ_PERMS_COMMENTS, $mszUserId);
}
}
csrf_init(

View file

@ -203,54 +203,9 @@
commentForms[i].onsubmit = commentPost;
}
}
if (typeof commentDelete === 'function') { // can delete
var commentDeletes = document.getElementsByClassName('comment__action--delete');
for (var i = 0; i < commentDeletes.length; i++) {
commentDeletes[i].onclick = commentDelete;
commentDeletes[i].dataset.href = commentDeletes[i].href;
commentDeletes[i].href = 'javascript:void(0);';
}
}
});
</script>
{% if perms.can_delete %}
<script>
var commentDeleteLock = false;
function commentDelete(ev)
{
if (commentDeleteLock)
return;
commentDeleteLock = true;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState !== 4)
return;
commentDeleteLock = false;
var json = JSON.parse(this.responseText),
message = json.error || json.message;
if (message)
alert(message);
else {
var elem = document.getElementById('comment-' + json.comment_id);
if (elem)
elem.parentNode.removeChild(elem);
}
};
xhr.open('GET', ev.target.dataset.href);
xhr.setRequestHeader('X-Misuzu-XHR', 'comments');
xhr.send();
}
</script>
{% endif %}
{% if perms.can_comment %}
<script>
var commentPostLock = false;

View file

@ -31,7 +31,7 @@
{% include '_layout/footer.twig' %}
{% if current_user is defined %}
<script type="application/json" id="user-info">
<script type="application/json" id="js-user-info">
{{ current_user|json_encode|raw }}
</script>
{% endif %}