#include msgbox.jsx #include comments/api.js #include comments/form.jsx const MszCommentsEntryVoteButton = function(args) { const { name, title, icon, vote } = args ?? {}; let element, counter; const isCast = () => element?.classList.contains('comments-entry-action-vote-cast') === true; element = ; return { get element() { return element; }, get disabled() { return element.disabled; }, set disabled(state) { element.disabled = state; }, get cast() { return isCast(); }, set cast(state) { element.classList.toggle('comments-entry-action-vote-cast', state); }, get count() { return counter ? parseInt(counter.textContent) : 0; }, set count(count) { if(count > 0) { if(!counter) element.appendChild(counter = ); const formatted = count.toLocaleString(); counter.textContent = formatted; element.title = title.replace('$0', formatted).replace('$s', count === 1 ? '' : 's'); } else { if(counter) { element.removeChild(counter); counter = undefined; } element.title = title.replace('$0', 'No').replace('$s', 's'); } }, }; }; const MszCommentsEntryVoteActions = function(args) { const { vote } = args ?? {}; const like = new MszCommentsEntryVoteButton({ name: 'like', title: '$0 like$s', icon: , vote: cast => { vote(cast ? 0 : 1); } }); const dislike = new MszCommentsEntryVoteButton({ name: 'dislike', title: '$0 dislike$s', icon: , vote: cast => { vote(cast ? 0 : -1); } }); const element =
{like} {dislike}
; return { get element() { return element; }, get disabled() { return element.classList.contains('comments-entry-actions-group-disabled'); }, set disabled(state) { element.classList.toggle('comments-entry-actions-group-disabled', state); like.disabled = dislike.disabled = state; }, updateVotes(votes) { like.count = votes?.positive ?? 0; like.cast = votes?.vote > 0; dislike.count = Math.abs(votes?.negative ?? 0); dislike.cast = votes?.vote < 0; }, }; }; const MszCommentsEntryReplyToggleButton = function(args) { const { replies, toggle } = args ?? {}; let icon, counter; const element = ; const setVisible = state => { element.classList.toggle('hidden', !state); }; const setOpen = state => { icon.classList.toggle('fa-plus', !state); icon.classList.toggle('fa-minus', state); }; const setCount = count => { const formatted = count.toLocaleString(); counter.textContent = formatted; element.title = `${count} ${count === 1 ? 'reply' : 'replies'}`; setVisible(count > 0); }; setCount(Array.isArray(replies) ? replies.length : (replies ?? 0)); return { get element() { return element; }, get visible() { return !element.classList.contains('hidden'); }, set visible(state) { setVisible(state); }, get count() { return parseInt(counter.textContent); }, set count(count) { setCount(count); }, get open() { return element.classList.contains('fa-plus'); }, set open(state) { setOpen(state); }, }; }; const MszCommentsEntryReplyCreateButton = function(args) { const { toggle } = args ?? {}; const element = ; return { get element() { return element; }, get visible() { return !element.classList.contains('hidden'); }, set visible(state) { element.classList.toggle('hidden', !state); }, get active() { return element.classList.contains('comments-entry-action-reply-active'); }, set active(state) { element.classList.toggle('comments-entry-action-reply-active', state); }, click() { element.click(); }, }; }; const MszCommentsEntryReplyActions = function(args) { const { replies, toggleReplies, toggleForm } = args ?? {}; const toggle = new MszCommentsEntryReplyToggleButton({ replies, toggle: toggleReplies }); const button = toggleForm ? new MszCommentsEntryReplyCreateButton({ toggle: toggleForm }) : undefined; const element =
{toggle} {button}
; const setVisible = state => { element.classList.toggle('hidden', !state); }; return { get element() { return element; }, get visible() { return !element.classList.contains('hidden'); }, set visible(state) { setVisible(state); }, get toggle() { return toggle; }, get button() { return button; }, updateVisible() { setVisible(toggle.visible || button?.visible === true); }, }; }; const MszCommentsEntryGeneralButton = function(args) { const { icon, title, action } = args ?? {}; const element = ; return { get element() { return element; }, get visible() { return !element.classList.contains('hidden'); }, set visible(state) { element.classList.toggle('hidden', !state); }, get disabled() { return element.disabled; }, set disabled(state) { element.disabled = state; }, }; }; const MszCommentsEntryGeneralActions = function(args) { let deleteButton, restoreButton, nukeButton, pinButton, unpinButton; const element =
{deleteButton = args.delete ? new MszCommentsEntryGeneralButton({ icon: , title: 'Delete', action: args.delete }) : null} {restoreButton = args.restore ? new MszCommentsEntryGeneralButton({ icon: , title: 'Restore', action: args.restore }) : null} {nukeButton = args.nuke ? new MszCommentsEntryGeneralButton({ icon: , title: 'Permanently delete', action: args.nuke }) : null} {pinButton = args.pin ? new MszCommentsEntryGeneralButton({ icon: , title: 'Pin', action: args.pin }) : null} {unpinButton = args.unpin ? new MszCommentsEntryGeneralButton({ icon: , title: 'Unpin', action: args.unpin }) : null}
; return { get element() { return element; }, get visible() { return !element.classList.contains('hidden'); }, set visible(state) { element.classList.toggle('hidden', !state); }, get disabled() { return element.classList.contains('comments-entry-actions-group-disabled'); }, set disabled(state) { element.classList.toggle('comments-entry-actions-group-disabled', state); if(deleteButton) deleteButton.disabled = state; if(restoreButton) restoreButton.disabled = state; if(nukeButton) nukeButton.disabled = state; if(pinButton) pinButton.disabled = state; if(unpinButton) unpinButton.disabled = state; }, get deleteButton() { return deleteButton; }, get restoreButton() { return restoreButton; }, get nukeButton() { return nukeButton; }, get deleteVisible() { return deleteButton?.visible === true; }, set deleteVisible(state) { if(deleteButton) deleteButton.visible = state; if(restoreButton) restoreButton.visible = !state; if(nukeButton) nukeButton.visible = !state; }, get pinButton() { return pinButton; }, get unpinButton() { return unpinButton; }, get pinVisible() { return pinButton?.visible === true; }, set pinVisible(state) { if(pinButton) pinButton.visible = state; if(unpinButton) unpinButton.visible = !state; }, }; }; const MszCommentsEntryActions = function() { const element =