rDrama/files/assets/js/comments_v.js
TLSM fdc6fa4181 fix: username popover listener on comment reply
Fixes #612. Ports in an existing working fix from upstream with
the change to bs_trigger. Also a stylistic improvement on the
preceding line I noticed while porting it.

bs_trigger is what attaches the event listeners for the Boostrap
popovers. It wasn't being called on the new elements, so they get no
user card. It is now, so it does. Calling it on the comment form
element doesn't work here because, unlike in an earlier stage of the
codebase (which I think the fork occured during the transition of)
put replies into a dedicated element rather than replacing the reply
form.
2023-07-09 13:38:29 -05:00

421 lines
15 KiB
JavaScript

function post_toast3(t, url, button1, button2) {
t.disabled=true;
t.classList.add("disabled");
const xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader('xhr', 'xhr');
var form = new FormData()
form.append("formkey", formkey());
if(typeof data === 'object' && data !== null) {
for(let k of Object.keys(data)) {
form.append(k, data[k]);
}
}
xhr.onload = function() {
let data
try {data = JSON.parse(xhr.response)}
catch(e) {console.log(e)}
if (xhr.status >= 200 && xhr.status < 300 && data && data["message"]) {
document.getElementById('toast-post-success-text').innerText = data["message"];
bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success')).show();
document.getElementById(button1).classList.toggle("d-md-inline-block");
document.getElementById(button2).classList.toggle("d-md-inline-block");
} else {
document.getElementById('toast-post-error-text').innerText = "Error, please try again later."
if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"];
bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show();
}
setTimeout(() => {
t.disabled = false;
t.classList.remove("disabled");
}, 2000);
};
xhr.send(form);
}
function report_commentModal(id, author) {
document.getElementById("comment-author").textContent = author;
const wholeFormBefore = document.getElementById('reportCommentFormBefore');
const wholeFormAfter = document.getElementById('reportCommentFormAfter');
const submitButton = document.getElementById("reportCommentButton")
const reasonField = document.getElementById("reason-field")
//The HTML is reused if the user makes multiple reports without a reload, so clean up
//from any previous openings
wholeFormBefore.classList.remove('d-none');
wholeFormAfter.classList.add('d-none');
submitButton.disabled = true;
submitButton.classList.add('disabled');
submitButton.innerHTML = 'Report comment';
reasonField.value = ""
reasonField.disabled = true;
for (const radioButton of document.querySelectorAll('input[name="report-reason"]')) {
radioButton.checked = false;
}
const otherButton = document.querySelector('input#other');
function handleRadioButtonChange() {
submitButton.disabled = false;
submitButton.classList.remove('disabled');
reasonField.disabled = !otherButton.checked;
if (!otherButton.checked) {
reasonField.value = "";
}
};
wholeFormBefore.addEventListener('change', handleRadioButtonChange);
submitButton.onclick = function() {
this.innerHTML = 'Reporting comment';
this.disabled = true;
this.classList.add('disabled');
const xhr = new XMLHttpRequest();
xhr.open("POST", '/report/comment/'+id);
xhr.setRequestHeader('xhr', 'xhr');
var form = new FormData()
form.append("formkey", formkey());
let reasonValue;
if (otherButton.checked) {
reasonValue = reasonField.value;
} else {
reasonValue = document.querySelector('input[name="report-reason"]:checked').value;
}
form.append("reason", reasonValue);
xhr.onload=function() {
wholeFormBefore.classList.add('d-none');
wholeFormAfter.classList.remove('d-none');
wholeFormBefore.removeEventListener('change', handleRadioButtonChange);
};
xhr.onerror=function(){alert(errortext)};
xhr.send(form);
}
};
function openReplyBox(id) {
const element = document.getElementById(id);
const textarea = element.getElementsByTagName('textarea')[0]
let text = getSelection().toString()
if (text)
{
textarea.value = '>' + text
textarea.value = textarea.value.replace(/\n\n([^$])/g,"\n\n>$1")
if (!textarea.value.endsWith('\n\n')) textarea.value += '\n\n'
}
element.classList.remove('d-none')
textarea.focus()
}
function toggleEdit(id){
comment=document.getElementById("comment-text-"+id);
form=document.getElementById("comment-edit-"+id);
box=document.getElementById('comment-edit-body-'+id);
actions = document.getElementById('comment-' + id +'-actions');
comment.classList.toggle("d-none");
form.classList.toggle("d-none");
actions.classList.toggle("d-none");
autoExpand(box);
};
function delete_commentModal(id) {
document.getElementById("deleteCommentButton").onclick = function() {
const xhr = new XMLHttpRequest();
xhr.open("POST", `/delete/comment/${id}`);
xhr.setRequestHeader('xhr', 'xhr');
var form = new FormData()
form.append("formkey", formkey());
xhr.onload = function() {
let data
try {data = JSON.parse(xhr.response)}
catch(e) {console.log(e)}
if (xhr.status >= 200 && xhr.status < 300 && data && data['message']) {
document.getElementsByClassName(`comment-${id}-only`)[0].classList.add('deleted');
document.getElementById(`delete-${id}`).classList.add('d-none');
document.getElementById(`undelete-${id}`).classList.remove('d-none');
document.getElementById(`delete2-${id}`).classList.add('d-none');
document.getElementById(`undelete2-${id}`).classList.remove('d-none');
document.getElementById('toast-post-success-text').innerText = data["message"];
bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success')).show();
} else {
document.getElementById('toast-post-error-text').innerText = "Error, please try again later."
if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"];
bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show();
}
};
xhr.send(form);
};
}
function post_reply(id){
const btn = document.getElementById(`save-reply-to-${id}`)
btn.disabled = true;
btn.classList.add('disabled');
var form = new FormData();
form.append('formkey', formkey());
form.append('parent_id', id);
form.append('body', document.getElementById('reply-form-body-'+id).value);
try {
for (const e of document.getElementById('file-upload').files)
form.append('file', e);
}
catch(e) {}
const xhr = new XMLHttpRequest();
xhr.open("post", "/reply");
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload=function(){
let data
try {data = JSON.parse(xhr.response)}
catch(e) {console.log(e)}
if (data && data["comment"]) {
commentForm=document.getElementById('comment-form-space-'+id);
commentForm.innerHTML = data["comment"].replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '').replace('comment-collapse-desktop d-none d-md-block','d-none').replace('border-left: 2px solid','padding-left:0;border-left: 0px solid');
bs_trigger(commentForm);
}
else {
if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"];
else document.getElementById('toast-post-error-text').innerText = "Error, please try again later."
bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show();
}
setTimeout(() => {
btn.disabled = false;
btn.classList.remove('disabled');
}, 2000);
}
xhr.send(form)
}
function comment_edit(id){
const btn = document.getElementById(`edit-btn-${id}`)
btn.disabled = true
btn.classList.add('disabled');
var form = new FormData();
form.append('formkey', formkey());
form.append('body', document.getElementById('comment-edit-body-'+id).value);
try {
for (const e of document.getElementById('file-edit-reply-'+id).files)
form.append('file', e);
}
catch(e) {}
const xhr = new XMLHttpRequest();
xhr.open("post", "/edit_comment/"+id);
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload=function(){
let data
try {data = JSON.parse(xhr.response)}
catch(e) {console.log(e)}
if (data && data["comment"]) {
commentForm=document.getElementById('comment-text-'+id);
commentForm.innerHTML = data["comment"].replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '')
document.getElementById('cancel-edit-'+id).click()
bs_trigger(commentForm);
}
else {
if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"];
else document.getElementById('toast-post-error-text').innerText = "Error, please try again later."
bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show();
}
setTimeout(() => {
btn.disabled = false;
btn.classList.remove('disabled');
}, 2000);
}
xhr.send(form)
}
function post_comment(fullname,id,level = 1){
const previewPlaceholderHTML= '<p class="preview-msg">Comment preview</p>';
function reset_preview(element_id) {
const element = document.getElementById(element_id);
if (element) {
element.innerHTML = previewPlaceholderHTML;
return true;
}
return false;
}
const btn = document.getElementById('save-reply-to-'+fullname)
btn.disabled = true
btn.classList.add('disabled');
var form = new FormData();
let submissionEl = document.getElementById('reply-form-submission-'+fullname);
let bodyEl = document.getElementById('reply-form-body-'+fullname);
form.append('formkey', formkey());
form.append('parent_fullname', fullname);
form.append('parent_level', level);
form.append('submission', submissionEl.value);
form.append('body', bodyEl.value);
try {
for (const e of document.getElementById('file-upload-reply-'+fullname).files)
form.append('file', e);
}
catch(e) {}
const xhr = new XMLHttpRequest();
xhr.open("post", "/comment");
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload=function(){
let data
try {data = JSON.parse(xhr.response)}
catch(e) {console.log(e)}
if (data && data["comment"]) {
let id = fullname.split('_')[1];
let name = 'comment-form-space-' + fullname;
commentForm = document.getElementById(name);
// dynamically insert comment into the comments section of the current comment/post
let comments = document.getElementById('replies-of-' + id);
let comment = data["comment"].replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '');
comments.insertAdjacentHTML('afterbegin', comment);
bs_trigger(comments);
// remove the placeholder if it exists
let placeholder = document.getElementById("placeholder-comment");
if(placeholder){
// clear out the text-center classes etc.
comments.classList.remove('text-center');
comments.classList.remove('py-7');
placeholder.parentNode.removeChild(placeholder);
}
// clear comment textarea, and preview.
bodyEl.value = '';
// when called from top-level comment, clear top-level preview
reset_preview('form-preview-'+id);
// when called from comment reply, clear comment reply preview
if(reset_preview('reply-edit-'+id)) {
// We are in a comment reply, need to find and hide the comment section
const replyArea = document.getElementById(`reply-to-${id}`);
if (replyArea) {
replyArea.classList.add('d-none');
}
}
if (data["message"]) {
document.getElementById("toast-post-success-text").innerText = data["message"];
bootstrap.Toast.getOrCreateInstance(document.getElementById("toast-post-success")).show();
}
} else {
if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"];
else document.getElementById('toast-post-error-text').innerText = "Error, please try again later."
bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show();
}
setTimeout(() => {
btn.disabled = false;
btn.classList.remove('disabled');
}, 2000);
}
xhr.send(form)
}
document.onpaste = function(event) {
var focused = document.activeElement;
if (focused.id.includes('reply-form-body-')) {
var fullname = focused.dataset.fullname;
f=document.getElementById('file-upload-reply-' + fullname);
files = event.clipboardData.files
try {
filename = files[0].name.toLowerCase()
if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".png") || filename.endsWith(".webp") || filename.endsWith(".gif"))
{
f.files = files;
document.getElementById('filename-show-reply-' + fullname).textContent = filename;
}
}
catch(e) {console.log(e)}
}
else if (focused.id.includes('comment-edit-body-')) {
var id = focused.dataset.id;
f=document.getElementById('file-edit-reply-' + id);
files = event.clipboardData.files
filename = files[0].name.toLowerCase()
if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".png") || filename.endsWith(".webp") || filename.endsWith(".gif"))
{
f.files = files;
document.getElementById('filename-edit-reply-' + id).textContent = filename;
}
}
else if (focused.id.includes('post-edit-box-')) {
var id = focused.dataset.id;
f=document.getElementById('file-upload-edit-' + id);
files = event.clipboardData.files
filename = files[0].name.toLowerCase()
if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".png") || filename.endsWith(".webp") || filename.endsWith(".gif"))
{
f.files = files;
document.getElementById('filename-show-edit-' + id).textContent = filename;
}
}
}
function handle_action(type, cid, thing) {
const btns = document.getElementsByClassName(`action-${cid}`)
for (const btn of btns)
{
btn.disabled = true;
btn.classList.add('disabled');
}
const form = new FormData();
form.append('formkey', formkey());
form.append('comment_id', cid);
form.append('thing', thing);
const xhr = new XMLHttpRequest();
xhr.open("post", `/${type}/${cid}`);
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload=function(){
let data
try {data = JSON.parse(xhr.response)}
catch(e) {console.log(e)}
if (data && data["response"]) {
const element = document.getElementById(`${type}-${cid}`);
element.innerHTML = data["response"]
}
else {
if (data && data["error"]) document.getElementById('toast-post-error-text').innerText = data["error"];
if (data && data["details"]) document.getElementById('toast-post-error-text').innerText = data["details"];
else document.getElementById('toast-post-error-text').innerText = "Error, please try again later."
bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show();
}
setTimeout(() => {
for (const btn of btns)
{
btn.disabled = false;
btn.classList.remove('disabled');
}
}, 2000);
}
xhr.send(form)
}