diff --git a/assets/typescript/Comments.ts b/assets/typescript/Comments.ts new file mode 100644 index 00000000..8888d819 --- /dev/null +++ b/assets/typescript/Comments.ts @@ -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 = document.getElementsByClassName('comment__action--delete') as HTMLCollectionOf; + + 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);'; + } +} diff --git a/assets/typescript/CurrentUserInfo.ts b/assets/typescript/CurrentUserInfo.ts deleted file mode 100644 index fd62aeed..00000000 --- a/assets/typescript/CurrentUserInfo.ts +++ /dev/null @@ -1,6 +0,0 @@ -interface CurrentUserInfo { - user_id: number; - username: string; - user_background_settings: number; - user_colour: number; -} diff --git a/assets/typescript/Permissions.ts b/assets/typescript/Permissions.ts new file mode 100644 index 00000000..87bee89c --- /dev/null +++ b/assets/typescript/Permissions.ts @@ -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); +} diff --git a/assets/typescript/User.ts b/assets/typescript/User.ts new file mode 100644 index 00000000..449abc58 --- /dev/null +++ b/assets/typescript/User.ts @@ -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}.`); +} diff --git a/assets/typescript/misuzu.ts b/assets/typescript/misuzu.ts index dd80df51..c7da76c4 100644 --- a/assets/typescript/misuzu.ts +++ b/assets/typescript/misuzu.ts @@ -1,11 +1,12 @@ -/// +/// /// /// +/// +/// 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 { diff --git a/misuzu.php b/misuzu.php index f69acf63..1b29306d 100644 --- a/misuzu.php +++ b/misuzu.php @@ -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( diff --git a/templates/_layout/comments.twig b/templates/_layout/comments.twig index cfb8dbeb..30acf04b 100644 --- a/templates/_layout/comments.twig +++ b/templates/_layout/comments.twig @@ -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);'; - } - } }); - {% if perms.can_delete %} - - {% endif %} - {% if perms.can_comment %} {% endif %}