${this.commentText}
/** * Author: Vera Konigin * Site: https://groundedwren.neocities.org * Contact: vera@groundedwren.com * * File Description: Comments Control */ registerNamespace("GW.Controls", function (ns) { ns.CommentForm = class CommentForm extends HTMLElement { //#region staticProperties static observedAttributes = []; static instanceCount = 0; static instanceMap = {}; //#endregion //#region instance properties instanceId; isInitialized; titleText; discordURL; //#region element properties formEl; titleEl; dispNameInpt; emailInpt; websiteInpt; respToInpt; commentInpt; resetBtn; submitBtn; //#endregion //#endregion constructor() { super(); this.instanceId = CommentForm.instanceCount++; CommentForm.instanceMap[this.instanceId] = this; } get idKey() { return `gw-comment-form-${this.instanceId}`; } //#region HTMLElement implementation connectedCallback() { if (this.isInitialized) { return; } this.titleText = this.getAttribute("titleText") || "Add a Comment"; this.discordURL = this.getAttribute("discordURL") this.renderContent(); this.registerHandlers(); this.isInitialized = true; } //#endregion renderContent() { //Markup this.innerHTML = `
`; //element properties this.formEl = document.getElementById(`${this.idKey}-form`); this.titleEl = document.getElementById(`${this.idKey}-title`); this.dispNameInpt = document.getElementById(`${this.idKey}-dispName`); this.emailInpt = document.getElementById(`${this.idKey}-email`); this.websiteInpt = document.getElementById(`${this.idKey}-website`); this.respToInpt = document.getElementById(`${this.idKey}-respTo`); this.commentInpt = document.getElementById(`${this.idKey}-comment`); this.resetBtn = document.getElementById(`${this.idKey}-reset`); this.submitBtn = document.getElementById(`${this.idKey}-submit`); //default values this.dispNameInpt.value = localStorage.getItem("comment-name") || ""; this.emailInpt.value = localStorage.getItem("comment-email") || ""; this.websiteInpt.value = localStorage.getItem("comment-website") || ""; } //#region Handlers registerHandlers() { this.formEl.onsubmit = this.onSubmit; } onSubmit = (event) => { event.preventDefault(); const contentObj = { name: this.dispNameInpt.value, email: this.emailInpt.value, website: this.websiteInpt.value, responseTo: this.respToInpt.value, comment: this.commentInpt.value, timestamp: new Date().toUTCString(), }; const contentAry = []; for (let contentKey in contentObj) { contentAry.push(`${contentKey}=${contentObj[contentKey]}`); } const request = new XMLHttpRequest(); request.open( "POST", this.discordURL, true ); request.setRequestHeader("Content-Type", "application/json"); request.onreadystatechange = function () { if (request.readyState == 4) { console.log(request.responseText); } }; request.send(JSON.stringify({ content: contentAry.join("; ") })); localStorage.setItem("comment-name", contentObj.name); localStorage.setItem("comment-email", contentObj.email); localStorage.setItem("comment-website", contentObj.website); this.formEl.reset(); this.dispNameInpt.value = contentObj.name; this.emailInpt.value = contentObj.email; this.websiteInpt.value = contentObj.website; alert("Your message has been submitted!"); }; //#endregion }; customElements.define("gw-comment-form", ns.CommentForm); ns.CommentList = class CommentList extends HTMLElement { //#region staticProperties static observedAttributes = []; static instanceCount = 0; static instanceMap = {}; //#endregion //#region instance properties instanceId; isInitialized; gSpreadsheetId; gSheetId; isNewestFirst; gwCommentFormId; //#region element properties //#endregion //#endregion constructor() { super(); this.instanceId = CommentList.instanceCount++; CommentList.instanceMap[this.instanceId] = this; } get idKey() { return `gw-comment-list-${this.instanceId}`; } //#region HTMLElement implementation connectedCallback() { if (this.isInitialized) { return; } this.gSpreadsheetId = this.getAttribute("gSpreadsheetId"); this.gSheetId = this.getAttribute("gSheetId"); this.isNewestFirst = this.getAttribute("isNewestFirst"); this.gwCommentFormId = this.getAttribute("gwCommentFormId"); this.loadAndRender(); this.isInitialized = true; } //#endregion async loadAndRender() { this.innerHTML = ` ` const sheetReader = new GW.Gizmos.GoogleSheetsReader(this.gSpreadsheetId, this.gSheetId); const sheetData = await sheetReader.loadData(); this.innerHTML = ""; const allComments = sheetReader.rowData; if (this.isNewestFirst) { allComments.reverse(); } this.renderContent(); this.registerHandlers(); const allCommentsIndex = {}; const topLevelCommentIdxs = []; const childCommentIdxs = []; for (let i = 0; i < allComments.length; i++) { const comment = allComments[i]; allCommentsIndex[comment.ID] = i; if (!comment.ResponseTo) { topLevelCommentIdxs.push(i); } else { childCommentIdxs.push(i); } } childCommentIdxs.forEach(childIdx => { const replyId = allComments[childIdx].ResponseTo; const respondeeComment = allComments[allCommentsIndex[replyId]]; respondeeComment.childrenIdxs = respondeeComment.childrenIdxs || []; respondeeComment.childrenIdxs.push(childIdx); }); let commentsToBuild = []; topLevelCommentIdxs.forEach( topCommentIdx => commentsToBuild.push( { parent: this.containerEl, parentId: null, comment: allComments[topCommentIdx] } ) ); while (commentsToBuild.length > 0) { let { parent, parentId, comment } = commentsToBuild.shift(); if (!comment.Timestamp) { continue; } parent.insertAdjacentHTML("beforeend", `${this.commentText}