// half finished comments bullshit
This commit is contained in:
parent
418ab0fcb2
commit
b4abea015a
6 changed files with 337 additions and 251 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
/// <reference path="FormUtilities.ts" />
|
||||||
|
|
||||||
|
|
||||||
let globalCommentLock = false;
|
let globalCommentLock = false;
|
||||||
|
|
||||||
function commentsLocked(): boolean
|
function commentsLocked(): boolean
|
||||||
|
@ -18,13 +21,31 @@ function commentsFreeLock(): void
|
||||||
globalCommentLock = false;
|
globalCommentLock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommentDeletionInfo {
|
interface CommentNotice {
|
||||||
comment_id: number;
|
|
||||||
error: string;
|
error: string;
|
||||||
message: string;
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function commentDelete(ev: Event)
|
interface CommentDeletionInfo extends CommentNotice {
|
||||||
|
comment_id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CommentPostInfo extends CommentNotice {
|
||||||
|
comment_id: number;
|
||||||
|
category_id: number;
|
||||||
|
comment_text: string;
|
||||||
|
comment_html: string;
|
||||||
|
comment_created: Date;
|
||||||
|
comment_edited: Date | null;
|
||||||
|
comment_deleted: Date | null;
|
||||||
|
comment_reply_to: number;
|
||||||
|
comment_pinned: Date | null;
|
||||||
|
user_id: number;
|
||||||
|
username: string;
|
||||||
|
user_colour: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentDelete(ev: Event): void
|
||||||
{
|
{
|
||||||
if (!checkUserPerm('comments', CommentPermission.Delete) || !commentsRequestLock())
|
if (!checkUserPerm('comments', CommentPermission.Delete) || !commentsRequestLock())
|
||||||
return;
|
return;
|
||||||
|
@ -37,13 +58,13 @@ function commentDelete(ev: Event)
|
||||||
return;
|
return;
|
||||||
commentsFreeLock();
|
commentsFreeLock();
|
||||||
|
|
||||||
var json: CommentDeletionInfo = JSON.parse(xhr.responseText) as CommentDeletionInfo,
|
let json: CommentDeletionInfo = JSON.parse(xhr.responseText) as CommentDeletionInfo,
|
||||||
message = json.error || json.message;
|
message = json.error || json.message;
|
||||||
|
|
||||||
if (message)
|
if (message)
|
||||||
alert(message);
|
alert(message);
|
||||||
else {
|
else {
|
||||||
var elem = document.getElementById('comment-' + json.comment_id);
|
let elem = document.getElementById('comment-' + json.comment_id);
|
||||||
|
|
||||||
if (elem)
|
if (elem)
|
||||||
elem.parentNode.removeChild(elem);
|
elem.parentNode.removeChild(elem);
|
||||||
|
@ -54,12 +75,265 @@ function commentDelete(ev: Event)
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
function commentsInit() {
|
function commentPostEventHandler(ev: Event): void
|
||||||
|
{
|
||||||
|
const form: HTMLFormElement = ev.target as HTMLFormElement,
|
||||||
|
formData: FormData = ExtractFormData(form, true);
|
||||||
|
|
||||||
|
commentPost(
|
||||||
|
formData,
|
||||||
|
info => commentPostSuccess(form, info),
|
||||||
|
message => commentPostFail
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentPost(formData: FormData, onSuccess: (comment: CommentPostInfo) => void = null, onFail: (message: string) => void = null): void
|
||||||
|
{
|
||||||
|
if (!commentsRequestLock())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
|
xhr.addEventListener('readystatechange', () => {
|
||||||
|
if (xhr.readyState !== 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
commentsFreeLock();
|
||||||
|
|
||||||
|
const json: CommentPostInfo = JSON.parse(xhr.responseText) as CommentPostInfo,
|
||||||
|
message: string = json.error || json.message;
|
||||||
|
|
||||||
|
if (message && onFail)
|
||||||
|
onFail(message);
|
||||||
|
else if (!message && onSuccess)
|
||||||
|
onSuccess(json);
|
||||||
|
});
|
||||||
|
|
||||||
|
xhr.open('POST', '/comments.php?m=create');
|
||||||
|
xhr.setRequestHeader('X-Misuzu-XHR', 'comments');
|
||||||
|
xhr.send(formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentPostSuccess(form: HTMLFormElement, comment: CommentPostInfo): void {
|
||||||
|
if (form.classList.contains('comment--reply'))
|
||||||
|
(form.parentNode.parentNode.querySelector('label.comment__action') as HTMLLabelElement).click();
|
||||||
|
|
||||||
|
//commentInsert(info, form);
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentPostFail(message: string): void {
|
||||||
|
alert(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentsInit(): void {
|
||||||
const commentDeletes: HTMLCollectionOf<HTMLAnchorElement> = document.getElementsByClassName('comment__action--delete') as HTMLCollectionOf<HTMLAnchorElement>;
|
const commentDeletes: HTMLCollectionOf<HTMLAnchorElement> = document.getElementsByClassName('comment__action--delete') as HTMLCollectionOf<HTMLAnchorElement>;
|
||||||
|
|
||||||
for (var i = 0; i < commentDeletes.length; i++) {
|
for (let i = 0; i < commentDeletes.length; i++) {
|
||||||
commentDeletes[i].onclick = commentDelete;
|
commentDeletes[i].addEventListener('click', commentDelete);
|
||||||
commentDeletes[i].dataset.href = commentDeletes[i].href;
|
commentDeletes[i].dataset.href = commentDeletes[i].href;
|
||||||
commentDeletes[i].href = 'javascript:void(0);';
|
commentDeletes[i].href = 'javascript:void(0);';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const commentInputs: HTMLCollectionOf<HTMLTextAreaElement> = document.getElementsByClassName('comment__text--input') as HTMLCollectionOf<HTMLTextAreaElement>;
|
||||||
|
|
||||||
|
for (let i = 0; i < commentInputs.length; i++) {
|
||||||
|
commentInputs[i].addEventListener('keydown', ev => {
|
||||||
|
if (ev.keyCode === 13 && ev.ctrlKey && !ev.altKey && !ev.shiftKey) {
|
||||||
|
let form = commentInputs[i].form;
|
||||||
|
commentPost(
|
||||||
|
ExtractFormData(form, true),
|
||||||
|
info => commentPostSuccess(form, info),
|
||||||
|
message => commentPostFail
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentConstruct(comment: CommentPostInfo, layer: number = 0): HTMLElement {
|
||||||
|
const isReply = comment.comment_reply_to > 0;
|
||||||
|
|
||||||
|
const commentElement: HTMLDivElement = document.createElement('div');
|
||||||
|
commentElement.className = 'comment';
|
||||||
|
commentElement.id = 'comment-' + comment.comment_id;
|
||||||
|
|
||||||
|
// layer 2
|
||||||
|
const commentContainer: HTMLDivElement = commentElement.appendChild(document.createElement('div'));
|
||||||
|
commentContainer.className = 'comment__container';
|
||||||
|
|
||||||
|
const commentReplies: HTMLDivElement = commentElement.appendChild(document.createElement('div'));
|
||||||
|
commentReplies.className = 'comment__replies comment__replies--indent-' + layer;
|
||||||
|
commentReplies.id = commentElement.id + '-replies';
|
||||||
|
|
||||||
|
// container
|
||||||
|
const commentAvatar: HTMLAnchorElement = commentContainer.appendChild(document.createElement('a'));
|
||||||
|
commentAvatar.className = 'avatar comment__avatar';
|
||||||
|
commentAvatar.href = '/profile.php?u=' + comment.user_id;
|
||||||
|
commentAvatar.style.backgroundImage = `url('/profile.php?m=avatar&u=${comment.user_id}')`;
|
||||||
|
|
||||||
|
const commentContent: HTMLDivElement = commentContainer.appendChild(document.createElement('div'));
|
||||||
|
commentContent.className = 'comment__content';
|
||||||
|
|
||||||
|
// content
|
||||||
|
const commentInfo = commentContent.appendChild(document.createElement('div'));
|
||||||
|
commentInfo.className = 'comment__info';
|
||||||
|
|
||||||
|
const commentText = commentContent.appendChild(document.createElement('div'));
|
||||||
|
commentText.className = 'comment__text';
|
||||||
|
|
||||||
|
if (comment.comment_html)
|
||||||
|
commentText.innerHTML = comment.comment_html;
|
||||||
|
else
|
||||||
|
commentText.textContent = comment.comment_text;
|
||||||
|
|
||||||
|
const commentActions = commentContent.appendChild(document.createElement('div'));
|
||||||
|
commentActions.className = 'comment__actions';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentInsert(comment, form): void
|
||||||
|
{
|
||||||
|
var isReply = form.classList.contains('comment--reply'),
|
||||||
|
parent = isReply
|
||||||
|
? form.parentNode
|
||||||
|
: form.parentNode.parentNode.getElementsByClassName('comments__listing')[0],
|
||||||
|
repliesIndent = isReply
|
||||||
|
? (parseInt(parent.classList[1].substr(25)) + 1)
|
||||||
|
: 1;
|
||||||
|
|
||||||
|
// info
|
||||||
|
var commentUser = document.createElement('a');
|
||||||
|
commentUser.className = 'comment__user comment__user--link';
|
||||||
|
commentUser.textContent = comment.username;
|
||||||
|
commentUser.href = '/profile?u=' + comment.user_id;
|
||||||
|
commentUser.style.color = comment.user_colour == null || (comment.user_colour & 0x40000000) > 0
|
||||||
|
? 'inherit'
|
||||||
|
: '#' + (comment.user_colour & 0xFFFFFF).toString(16);
|
||||||
|
commentInfo.appendChild(commentUser);
|
||||||
|
|
||||||
|
var commentLink = document.createElement('a');
|
||||||
|
commentLink.className = 'comment__link';
|
||||||
|
commentLink.href = '#' + commentElement.id;
|
||||||
|
commentInfo.appendChild(commentLink);
|
||||||
|
|
||||||
|
var commentTime = document.createElement('time'),
|
||||||
|
commentDate = new Date(comment.comment_created + 'Z');
|
||||||
|
commentTime.className = 'comment__date';
|
||||||
|
commentTime.title = commentDate.toLocaleString();
|
||||||
|
commentTime.dateTime = commentDate.toISOString();
|
||||||
|
commentTime.textContent = timeago().format(commentDate);
|
||||||
|
commentLink.appendChild(commentTime);
|
||||||
|
|
||||||
|
// actions
|
||||||
|
if (typeof commentVote === 'function') {
|
||||||
|
var commentLike = document.createElement('a');
|
||||||
|
commentLike.className = 'comment__action comment__action--link comment__action--like';
|
||||||
|
commentLike.href = 'javascript:void(0);';
|
||||||
|
commentLike.textContent = 'Like';
|
||||||
|
commentLike.onclick = commentVote;
|
||||||
|
commentActions.appendChild(commentLike);
|
||||||
|
|
||||||
|
var commentDislike = document.createElement('a');
|
||||||
|
commentDislike.className = 'comment__action comment__action--link comment__action--dislike';
|
||||||
|
commentDislike.href = 'javascript:void(0);';
|
||||||
|
commentDislike.textContent = 'Dislike';
|
||||||
|
commentDislike.onclick = commentVote;
|
||||||
|
commentActions.appendChild(commentDislike);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we're executing this it's fairly obvious that we can reply,
|
||||||
|
// so no need to have a permission check on it here
|
||||||
|
var commentReply = document.createElement('label');
|
||||||
|
commentReply.className = 'comment__action comment__action--link';
|
||||||
|
commentReply.htmlFor = 'comment-reply-toggle-' + comment.comment_id;
|
||||||
|
commentReply.textContent = 'Reply';
|
||||||
|
commentActions.appendChild(commentReply);
|
||||||
|
|
||||||
|
// reply section
|
||||||
|
var commentReplyState = document.createElement('input');
|
||||||
|
commentReplyState.id = commentReply.htmlFor;
|
||||||
|
commentReplyState.type = 'checkbox';
|
||||||
|
commentReplyState.className = 'comment__reply-toggle';
|
||||||
|
commentReplies.appendChild(commentReplyState);
|
||||||
|
|
||||||
|
var commentReplyInput = document.createElement('form');
|
||||||
|
commentReplyInput.id = 'comment-reply-' + comment.comment_id;
|
||||||
|
commentReplyInput.className = 'comment comment--input comment--reply';
|
||||||
|
commentReplyInput.method = 'post';
|
||||||
|
commentReplyInput.action = 'javascript:void(0);';
|
||||||
|
commentReplyInput.onsubmit = commentPostEventHandler;
|
||||||
|
commentReplies.appendChild(commentReplyInput);
|
||||||
|
|
||||||
|
// reply attributes
|
||||||
|
var replyCategory = document.createElement('input');
|
||||||
|
replyCategory.name = 'comment[category]';
|
||||||
|
replyCategory.value = comment.category_id;
|
||||||
|
replyCategory.type = 'hidden';
|
||||||
|
commentReplyInput.appendChild(replyCategory);
|
||||||
|
|
||||||
|
var replyCsrf = document.createElement('input');
|
||||||
|
replyCsrf.name = 'csrf';
|
||||||
|
replyCsrf.value = '{{ csrf_token("comments") }}';
|
||||||
|
replyCsrf.type = 'hidden';
|
||||||
|
commentReplyInput.appendChild(replyCsrf);
|
||||||
|
|
||||||
|
var replyId = document.createElement('input');
|
||||||
|
replyId.name = 'comment[reply]';
|
||||||
|
replyId.value = comment.comment_id;
|
||||||
|
replyId.type = 'hidden';
|
||||||
|
commentReplyInput.appendChild(replyId);
|
||||||
|
|
||||||
|
var replyContainer = document.createElement('div');
|
||||||
|
replyContainer.className = 'comment__container';
|
||||||
|
commentReplyInput.appendChild(replyContainer);
|
||||||
|
|
||||||
|
// reply container
|
||||||
|
var replyAvatar = document.createElement('div');
|
||||||
|
replyAvatar.className = 'avatar comment__avatar';
|
||||||
|
replyAvatar.style.backgroundImage = 'url(\'/profile.php?m=avatar&u={0}\')'.replace('{0}', comment.user_id);
|
||||||
|
replyContainer.appendChild(replyAvatar);
|
||||||
|
|
||||||
|
var replyContent = document.createElement('div');
|
||||||
|
replyContent.className = 'comment__content';
|
||||||
|
replyContainer.appendChild(replyContent);
|
||||||
|
|
||||||
|
// reply content
|
||||||
|
var replyInfo = document.createElement('div');
|
||||||
|
replyInfo.className = 'comment__info';
|
||||||
|
replyContent.appendChild(replyInfo);
|
||||||
|
|
||||||
|
var replyUser = document.createElement('div');
|
||||||
|
replyUser.className = 'comment__user';
|
||||||
|
replyUser.textContent = comment.username;
|
||||||
|
replyUser.style.color = comment.user_colour == null || (comment.user_colour & 0x40000000) > 0
|
||||||
|
? 'inherit'
|
||||||
|
: '#' + (comment.user_colour & 0xFFFFFF).toString(16);
|
||||||
|
replyInfo.appendChild(replyUser);
|
||||||
|
|
||||||
|
var replyText = document.createElement('textarea');
|
||||||
|
replyText.className = 'comment__text input__textarea comment__text--input';
|
||||||
|
replyText.name = 'comment[text]';
|
||||||
|
replyText.placeholder = 'Share your extensive insights...';
|
||||||
|
replyContent.appendChild(replyText);
|
||||||
|
|
||||||
|
var replyActions = document.createElement('div');
|
||||||
|
replyActions.className = 'comment__actions';
|
||||||
|
replyContent.appendChild(replyActions);
|
||||||
|
|
||||||
|
var replyButton = document.createElement('button');
|
||||||
|
replyButton.className = 'input__button comment__action comment__action--button comment__action--post';
|
||||||
|
replyButton.textContent = 'Reply';
|
||||||
|
replyActions.appendChild(replyButton);
|
||||||
|
|
||||||
|
if (isReply)
|
||||||
|
parent.appendChild(commentElement);
|
||||||
|
else
|
||||||
|
parent.insertBefore(commentElement, parent.firstElementChild);
|
||||||
|
|
||||||
|
timeago().render(commentTime);
|
||||||
|
|
||||||
|
var placeholder = document.getElementById('_no_comments_notice_' + comment.category_id);
|
||||||
|
|
||||||
|
if (placeholder)
|
||||||
|
placeholder.parentNode.removeChild(placeholder);
|
||||||
}
|
}
|
||||||
|
|
3
assets/typescript/Common.ts
Normal file
3
assets/typescript/Common.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
interface Array<T> {
|
||||||
|
find(predicate: (search: T) => boolean) : T;
|
||||||
|
}
|
48
assets/typescript/FormUtilities.ts
Normal file
48
assets/typescript/FormUtilities.ts
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
function ExtractFormData(form: HTMLFormElement, resetSource: boolean = false): FormData
|
||||||
|
{
|
||||||
|
const formData: FormData = new FormData;
|
||||||
|
|
||||||
|
for (let i = 0; i < form.length; i++) {
|
||||||
|
let input: HTMLInputElement = form[i] as HTMLInputElement,
|
||||||
|
type = input.type.toLowerCase(),
|
||||||
|
isCheckbox = type === 'checkbox';
|
||||||
|
|
||||||
|
if (isCheckbox && !input.checked)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
formData.append(input.name, input.value || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resetSource)
|
||||||
|
ResetForm(form);
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FormHiddenDefault {
|
||||||
|
Name: string;
|
||||||
|
Value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ResetForm(form: HTMLFormElement, defaults: FormHiddenDefault[] = []): void
|
||||||
|
{
|
||||||
|
for (let i = 0; i < form.length; i++) {
|
||||||
|
let input: HTMLInputElement = form[i] as HTMLInputElement;
|
||||||
|
|
||||||
|
switch (input.type.toLowerCase()) {
|
||||||
|
case 'checkbox':
|
||||||
|
input.checked = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'hidden':
|
||||||
|
let hiddenDefault: FormHiddenDefault = defaults.find(fhd => fhd.Name.toLowerCase() === input.name.toLowerCase());
|
||||||
|
|
||||||
|
if (hiddenDefault)
|
||||||
|
input.value = hiddenDefault.Value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
input.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
/// <reference path="Support.ts" />
|
/// <reference path="Support.ts" />
|
||||||
/// <reference path="Permissions.ts" />
|
/// <reference path="Permissions.ts" />
|
||||||
/// <reference path="Comments.ts" />
|
/// <reference path="Comments.ts" />
|
||||||
|
/// <reference path="Common.ts" />
|
||||||
|
|
||||||
declare const timeago: any;
|
declare const timeago: any;
|
||||||
declare const hljs: any;
|
declare const hljs: any;
|
||||||
|
|
|
@ -195,257 +195,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof commentPost === 'function') { // can comment
|
if (typeof commentPostEventHandler === 'function') { // can comment
|
||||||
var commentForms = document.getElementsByClassName('comment--input');
|
var commentForms = document.getElementsByClassName('comment--input');
|
||||||
|
|
||||||
for (var i = 0; i < commentForms.length; i++) {
|
for (var i = 0; i < commentForms.length; i++) {
|
||||||
commentForms[i].action = 'javascript:void(0);';
|
commentForms[i].action = 'javascript:void(0);';
|
||||||
commentForms[i].onsubmit = commentPost;
|
commentForms[i].onsubmit = commentPostEventHandler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% if perms.can_comment %}
|
|
||||||
<script>
|
|
||||||
function commentPost(ev)
|
|
||||||
{
|
|
||||||
// the moment we find the id we engage vote lock
|
|
||||||
if (!commentsRequestLock())
|
|
||||||
return;
|
|
||||||
|
|
||||||
var form = ev.target,
|
|
||||||
formData = new FormData;
|
|
||||||
|
|
||||||
for (var i = 0; i < form.length; i++) {
|
|
||||||
var isCheckbox = form[i].type === 'checkbox';
|
|
||||||
if (isCheckbox && !form[i].checked)
|
|
||||||
continue;
|
|
||||||
formData.append(form[i].name, form[i].value || '');
|
|
||||||
|
|
||||||
if (isCheckbox)
|
|
||||||
form[i].checked = false;
|
|
||||||
else if (form[i].type !== 'hidden')
|
|
||||||
form[i].value = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.onreadystatechange = function () {
|
|
||||||
if (this.readyState !== 4)
|
|
||||||
return;
|
|
||||||
|
|
||||||
commentsFreeLock();
|
|
||||||
|
|
||||||
var json = JSON.parse(this.responseText),
|
|
||||||
message = json.error || json.message;
|
|
||||||
|
|
||||||
if (message)
|
|
||||||
alert(message);
|
|
||||||
else {
|
|
||||||
if (form.classList.contains('comment--reply'))
|
|
||||||
form.parentNode.parentNode.querySelector('label.comment__action').click();
|
|
||||||
commentInsert(json, form);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
xhr.open('POST', '/comments.php?m=create');
|
|
||||||
xhr.setRequestHeader('X-Misuzu-XHR', 'comments');
|
|
||||||
xhr.send(formData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is the biggest doozy of them all, this should create an element identical to comments_entry
|
|
||||||
function commentInsert(comment, form)
|
|
||||||
{
|
|
||||||
var isReply = form.classList.contains('comment--reply'),
|
|
||||||
parent = isReply
|
|
||||||
? form.parentNode
|
|
||||||
: form.parentNode.parentNode.getElementsByClassName('comments__listing')[0],
|
|
||||||
repliesIndent = isReply
|
|
||||||
? (parseInt(parent.classList[1].substr(25)) + 1)
|
|
||||||
: 1;
|
|
||||||
|
|
||||||
// layer 1
|
|
||||||
var commentElement = document.createElement('div');
|
|
||||||
commentElement.className = 'comment';
|
|
||||||
commentElement.id = 'comment-' + comment.comment_id;
|
|
||||||
|
|
||||||
// layer 2
|
|
||||||
var commentContainer = document.createElement('div');
|
|
||||||
commentContainer.className = 'comment__container';
|
|
||||||
commentElement.appendChild(commentContainer);
|
|
||||||
|
|
||||||
var commentReplies = document.createElement('div');
|
|
||||||
commentReplies.className = 'comment__replies comment__replies--indent-' + repliesIndent;
|
|
||||||
commentReplies.id = commentElement.id + '-replies';
|
|
||||||
commentElement.appendChild(commentReplies);
|
|
||||||
|
|
||||||
// container
|
|
||||||
var commentAvatar = document.createElement('a');
|
|
||||||
commentAvatar.className = 'avatar comment__avatar';
|
|
||||||
commentAvatar.href = '/profile.php?u=' + comment.user_id;
|
|
||||||
commentAvatar.style.backgroundImage = 'url(\'/profile.php?m=avatar&u={0}\')'.replace('{0}', comment.user_id);
|
|
||||||
commentContainer.appendChild(commentAvatar);
|
|
||||||
|
|
||||||
var commentContent = document.createElement('div');
|
|
||||||
commentContent.className = 'comment__content';
|
|
||||||
commentContainer.appendChild(commentContent);
|
|
||||||
|
|
||||||
// content
|
|
||||||
var commentInfo = document.createElement('div');
|
|
||||||
commentInfo.className = 'comment__info';
|
|
||||||
commentContent.appendChild(commentInfo);
|
|
||||||
|
|
||||||
var commentText = document.createElement('div');
|
|
||||||
commentText.className = 'comment__text';
|
|
||||||
|
|
||||||
if (comment.comment_html)
|
|
||||||
commentText.innerHTML = comment.comment_html;
|
|
||||||
else
|
|
||||||
commentText.textContent = comment.comment_text;
|
|
||||||
|
|
||||||
commentContent.appendChild(commentText);
|
|
||||||
|
|
||||||
var commentActions = document.createElement('div');
|
|
||||||
commentActions.className = 'comment__actions';
|
|
||||||
commentContent.appendChild(commentActions);
|
|
||||||
|
|
||||||
// info
|
|
||||||
var commentUser = document.createElement('a');
|
|
||||||
commentUser.className = 'comment__user comment__user--link';
|
|
||||||
commentUser.textContent = comment.username;
|
|
||||||
commentUser.href = '/profile?u=' + comment.user_id;
|
|
||||||
commentUser.style.color = comment.user_colour == null || (comment.user_colour & 0x40000000) > 0
|
|
||||||
? 'inherit'
|
|
||||||
: '#' + (comment.user_colour & 0xFFFFFF).toString(16);
|
|
||||||
commentInfo.appendChild(commentUser);
|
|
||||||
|
|
||||||
var commentLink = document.createElement('a');
|
|
||||||
commentLink.className = 'comment__link';
|
|
||||||
commentLink.href = '#' + commentElement.id;
|
|
||||||
commentInfo.appendChild(commentLink);
|
|
||||||
|
|
||||||
var commentTime = document.createElement('time'),
|
|
||||||
commentDate = new Date(comment.comment_created + 'Z');
|
|
||||||
commentTime.className = 'comment__date';
|
|
||||||
commentTime.title = commentDate.toLocaleString();
|
|
||||||
commentTime.dateTime = commentDate.toISOString();
|
|
||||||
commentTime.textContent = timeago().format(commentDate);
|
|
||||||
commentLink.appendChild(commentTime);
|
|
||||||
|
|
||||||
// actions
|
|
||||||
if (typeof commentVote === 'function') {
|
|
||||||
var commentLike = document.createElement('a');
|
|
||||||
commentLike.className = 'comment__action comment__action--link comment__action--like';
|
|
||||||
commentLike.href = 'javascript:void(0);';
|
|
||||||
commentLike.textContent = 'Like';
|
|
||||||
commentLike.onclick = commentVote;
|
|
||||||
commentActions.appendChild(commentLike);
|
|
||||||
|
|
||||||
var commentDislike = document.createElement('a');
|
|
||||||
commentDislike.className = 'comment__action comment__action--link comment__action--dislike';
|
|
||||||
commentDislike.href = 'javascript:void(0);';
|
|
||||||
commentDislike.textContent = 'Dislike';
|
|
||||||
commentDislike.onclick = commentVote;
|
|
||||||
commentActions.appendChild(commentDislike);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we're executing this it's fairly obvious that we can reply,
|
|
||||||
// so no need to have a permission check on it here
|
|
||||||
var commentReply = document.createElement('label');
|
|
||||||
commentReply.className = 'comment__action comment__action--link';
|
|
||||||
commentReply.htmlFor = 'comment-reply-toggle-' + comment.comment_id;
|
|
||||||
commentReply.textContent = 'Reply';
|
|
||||||
commentActions.appendChild(commentReply);
|
|
||||||
|
|
||||||
// reply section
|
|
||||||
var commentReplyState = document.createElement('input');
|
|
||||||
commentReplyState.id = commentReply.htmlFor;
|
|
||||||
commentReplyState.type = 'checkbox';
|
|
||||||
commentReplyState.className = 'comment__reply-toggle';
|
|
||||||
commentReplies.appendChild(commentReplyState);
|
|
||||||
|
|
||||||
var commentReplyInput = document.createElement('form');
|
|
||||||
commentReplyInput.id = 'comment-reply-' + comment.comment_id;
|
|
||||||
commentReplyInput.className = 'comment comment--input comment--reply';
|
|
||||||
commentReplyInput.method = 'post';
|
|
||||||
commentReplyInput.action = 'javascript:void(0);';
|
|
||||||
commentReplyInput.onsubmit = commentPost;
|
|
||||||
commentReplies.appendChild(commentReplyInput);
|
|
||||||
|
|
||||||
// reply attributes
|
|
||||||
var replyCategory = document.createElement('input');
|
|
||||||
replyCategory.name = 'comment[category]';
|
|
||||||
replyCategory.value = comment.category_id;
|
|
||||||
replyCategory.type = 'hidden';
|
|
||||||
commentReplyInput.appendChild(replyCategory);
|
|
||||||
|
|
||||||
var replyCsrf = document.createElement('input');
|
|
||||||
replyCsrf.name = 'csrf';
|
|
||||||
replyCsrf.value = '{{ csrf_token("comments") }}';
|
|
||||||
replyCsrf.type = 'hidden';
|
|
||||||
commentReplyInput.appendChild(replyCsrf);
|
|
||||||
|
|
||||||
var replyId = document.createElement('input');
|
|
||||||
replyId.name = 'comment[reply]';
|
|
||||||
replyId.value = comment.comment_id;
|
|
||||||
replyId.type = 'hidden';
|
|
||||||
commentReplyInput.appendChild(replyId);
|
|
||||||
|
|
||||||
var replyContainer = document.createElement('div');
|
|
||||||
replyContainer.className = 'comment__container';
|
|
||||||
commentReplyInput.appendChild(replyContainer);
|
|
||||||
|
|
||||||
// reply container
|
|
||||||
var replyAvatar = document.createElement('div');
|
|
||||||
replyAvatar.className = 'avatar comment__avatar';
|
|
||||||
replyAvatar.style.backgroundImage = 'url(\'/profile.php?m=avatar&u={0}\')'.replace('{0}', comment.user_id);
|
|
||||||
replyContainer.appendChild(replyAvatar);
|
|
||||||
|
|
||||||
var replyContent = document.createElement('div');
|
|
||||||
replyContent.className = 'comment__content';
|
|
||||||
replyContainer.appendChild(replyContent);
|
|
||||||
|
|
||||||
// reply content
|
|
||||||
var replyInfo = document.createElement('div');
|
|
||||||
replyInfo.className = 'comment__info';
|
|
||||||
replyContent.appendChild(replyInfo);
|
|
||||||
|
|
||||||
var replyUser = document.createElement('div');
|
|
||||||
replyUser.className = 'comment__user';
|
|
||||||
replyUser.textContent = comment.username;
|
|
||||||
replyUser.style.color = comment.user_colour == null || (comment.user_colour & 0x40000000) > 0
|
|
||||||
? 'inherit'
|
|
||||||
: '#' + (comment.user_colour & 0xFFFFFF).toString(16);
|
|
||||||
replyInfo.appendChild(replyUser);
|
|
||||||
|
|
||||||
var replyText = document.createElement('textarea');
|
|
||||||
replyText.className = 'comment__text input__textarea comment__text--input';
|
|
||||||
replyText.name = 'comment[text]';
|
|
||||||
replyText.placeholder = 'Share your extensive insights...';
|
|
||||||
replyContent.appendChild(replyText);
|
|
||||||
|
|
||||||
var replyActions = document.createElement('div');
|
|
||||||
replyActions.className = 'comment__actions';
|
|
||||||
replyContent.appendChild(replyActions);
|
|
||||||
|
|
||||||
var replyButton = document.createElement('button');
|
|
||||||
replyButton.className = 'input__button comment__action comment__action--button comment__action--post';
|
|
||||||
replyButton.textContent = 'Reply';
|
|
||||||
replyActions.appendChild(replyButton);
|
|
||||||
|
|
||||||
if (isReply)
|
|
||||||
parent.appendChild(commentElement);
|
|
||||||
else
|
|
||||||
parent.insertBefore(commentElement, parent.firstElementChild);
|
|
||||||
|
|
||||||
timeago().render(commentTime);
|
|
||||||
|
|
||||||
var placeholder = document.getElementById('_no_comments_notice_' + comment.category_id);
|
|
||||||
placeholder.parentNode.removeChild(placeholder);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if perms.can_vote %}
|
{% if perms.can_vote %}
|
||||||
<script>
|
<script>
|
||||||
var commentVoteLock = false,
|
var commentVoteLock = false,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es6",
|
||||||
"module": "es6",
|
"module": "es6",
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"preserveConstEnums": true,
|
"preserveConstEnums": true,
|
||||||
|
|
Loading…
Add table
Reference in a new issue