import { getRequestHeaders } from '../../../../script.js'; import { executeSlashCommands } from '../../../slash-commands.js'; import { debounce } from '../../../utils.js'; import { warn } from '../index.js'; import { QuickReply } from './QuickReply.js'; export class QuickReplySet { /**@type {QuickReplySet[]}*/ static list = []; static from(props) { props.qrList = props.qrList?.map(it=>QuickReply.from(it)); const instance = Object.assign(new this(), props); instance.init(); return instance; } /** * @param {String} name - name of the QuickReplySet */ static get(name) { return this.list.find(it=>it.name == name); } /**@type {String}*/ name; /**@type {Boolean}*/ disableSend = false; /**@type {Boolean}*/ placeBeforeInput = false; /**@type {Boolean}*/ injectInput = false; /**@type {QuickReply[]}*/ qrList = []; /**@type {Number}*/ idIndex = 0; /**@type {Function}*/ save; /**@type {HTMLElement}*/ dom; /**@type {HTMLElement}*/ settingsDom; constructor() { this.save = debounce(()=>this.performSave(), 200); } init() { this.qrList.forEach(qr=>this.hookQuickReply(qr)); } unrender() { this.dom?.remove(); this.dom = null; } render() { this.unrender(); if (!this.dom) { const root = document.createElement('div'); { this.dom = root; root.classList.add('qr--buttons'); this.qrList.filter(qr=>!qr.isHidden).forEach(qr=>{ root.append(qr.render()); }); } } return this.dom; } rerender() { if (!this.dom) return; this.dom.innerHTML = ''; this.qrList.filter(qr=>!qr.isHidden).forEach(qr=>{ this.dom.append(qr.render()); }); } renderSettings() { if (!this.settingsDom) { this.settingsDom = document.createElement('div'); { this.settingsDom.classList.add('qr--set-qrListContents'); this.qrList.forEach((qr,idx)=>{ this.renderSettingsItem(qr, idx); }); } } return this.settingsDom; } renderSettingsItem(qr, idx) { this.settingsDom.append(qr.renderSettings(idx)); } /** * @param {QuickReply} qr */ async execute(qr) { /**@type {HTMLTextAreaElement}*/ const ta = document.querySelector('#send_textarea'); let input = ta.value; if (this.injectInput && input.length > 0) { if (this.placeBeforeInput) { input = `${qr.message} ${input}`; } else { input = `${input} ${qr.message}`; } } else { input = `${qr.message} `; } if (input[0] == '/' && !this.disableSend) { const result = await executeSlashCommands(input); return typeof result === 'object' ? result?.pipe : ''; } ta.value = input; ta.focus(); if (!this.disableSend) { // @ts-ignore document.querySelector('#send_but').click(); } } addQuickReply() { const id = Math.max(this.idIndex, this.qrList.reduce((max,qr)=>Math.max(max,qr.id),0)) + 1; this.idIndex = id + 1; const qr = QuickReply.from({ id }); this.qrList.push(qr); this.hookQuickReply(qr); if (this.settingsDom) { this.renderSettingsItem(qr, this.qrList.length - 1); } if (this.dom) { this.dom.append(qr.render()); } this.save(); return qr; } hookQuickReply(qr) { qr.onExecute = ()=>this.execute(qr); qr.onDelete = ()=>this.removeQuickReply(qr); qr.onUpdate = ()=>this.save(); } removeQuickReply(qr) { this.qrList.splice(this.qrList.indexOf(qr), 1); this.save(); } toJSON() { return { version: 2, name: this.name, disableSend: this.disableSend, placeBeforeInput: this.placeBeforeInput, injectInput: this.injectInput, qrList: this.qrList, idIndex: this.idIndex, }; } async performSave() { const response = await fetch('/savequickreply', { method: 'POST', headers: getRequestHeaders(), body: JSON.stringify(this), }); if (response.ok) { this.rerender(); } else { warn(`Failed to save Quick Reply Set: ${this.name}`); } } }