diff --git a/public/scripts/extensions/quick-reply/index.js b/public/scripts/extensions/quick-reply/index.js index fa82b88b1..08ff88949 100644 --- a/public/scripts/extensions/quick-reply/index.js +++ b/public/scripts/extensions/quick-reply/index.js @@ -102,7 +102,8 @@ const loadSettings = async () => { } try { settings = QuickReplySettings.from(extension_settings.quickReplyV2); - } catch { + } catch (ex) { + debugger; settings = QuickReplySettings.from(defaultSettings); } }; diff --git a/public/scripts/extensions/quick-reply/src/QuickReplyConfig.js b/public/scripts/extensions/quick-reply/src/QuickReplyConfig.js index 7afbe69b2..c7ca95c5a 100644 --- a/public/scripts/extensions/quick-reply/src/QuickReplyConfig.js +++ b/public/scripts/extensions/quick-reply/src/QuickReplyConfig.js @@ -16,7 +16,7 @@ export class QuickReplyConfig { static from(props) { - props.setList = props.setList?.map(it=>QuickReplySetLink.from(it)) ?? []; + props.setList = props.setList?.map(it=>QuickReplySetLink.from(it))?.filter(it=>it.set) ?? []; const instance = Object.assign(new this(), props); instance.init(); return instance; @@ -50,7 +50,7 @@ export class QuickReplyConfig { delay: getSortableDelay(), stop: ()=>this.onSetListSort(), }); - this.setList.forEach((qrl,idx)=>setList.append(qrl.renderSettings(idx))); + this.setList.filter(it=>!it.set.isDeleted).forEach((qrl,idx)=>setList.append(qrl.renderSettings(idx))); } diff --git a/public/scripts/extensions/quick-reply/src/QuickReplySet.js b/public/scripts/extensions/quick-reply/src/QuickReplySet.js index a66b3455b..61156750e 100644 --- a/public/scripts/extensions/quick-reply/src/QuickReplySet.js +++ b/public/scripts/extensions/quick-reply/src/QuickReplySet.js @@ -26,17 +26,16 @@ export class QuickReplySet { /**@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 {Boolean}*/ isDeleted = false; + /**@type {Function}*/ save; /**@type {HTMLElement}*/ dom; /**@type {HTMLElement}*/ settingsDom; @@ -201,6 +200,7 @@ export class QuickReplySet { this.unrender(); const idx = QuickReplySet.list.indexOf(this); QuickReplySet.list.splice(idx, 1); + this.isDeleted = true; } else { warn(`Failed to delete Quick Reply Set: ${this.name}`); } diff --git a/public/scripts/extensions/quick-reply/src/QuickReplySetLink.js b/public/scripts/extensions/quick-reply/src/QuickReplySetLink.js index fb32870ac..0c8ec2994 100644 --- a/public/scripts/extensions/quick-reply/src/QuickReplySetLink.js +++ b/public/scripts/extensions/quick-reply/src/QuickReplySetLink.js @@ -1,9 +1,14 @@ import { QuickReplySet } from './QuickReplySet.js'; + + + export class QuickReplySetLink { static from(props) { props.set = QuickReplySet.get(props.set); - return Object.assign(new this(), props); + /**@type {QuickReplySetLink}*/ + const instance = Object.assign(new this(), props); + return instance; } @@ -24,67 +29,65 @@ export class QuickReplySetLink { renderSettings(idx) { - if (!this.settingsDom || idx != this.index) { - this.index = idx; - const item = document.createElement('div'); { - this.settingsDom = item; - item.classList.add('qr--item'); - item.setAttribute('data-order', String(this.index)); - const drag = document.createElement('div'); { - drag.classList.add('drag-handle'); - drag.classList.add('ui-sortable-handle'); - drag.textContent = '☰'; - item.append(drag); - } - const set = document.createElement('select'); { - set.classList.add('qr--set'); - set.addEventListener('change', ()=>{ - this.set = QuickReplySet.get(set.value); + this.index = idx; + const item = document.createElement('div'); { + this.settingsDom = item; + item.classList.add('qr--item'); + item.setAttribute('data-order', String(this.index)); + const drag = document.createElement('div'); { + drag.classList.add('drag-handle'); + drag.classList.add('ui-sortable-handle'); + drag.textContent = '☰'; + item.append(drag); + } + const set = document.createElement('select'); { + set.classList.add('qr--set'); + set.addEventListener('change', ()=>{ + this.set = QuickReplySet.get(set.value); + this.update(); + }); + QuickReplySet.list.forEach(qrs=>{ + const opt = document.createElement('option'); { + opt.value = qrs.name; + opt.textContent = qrs.name; + opt.selected = qrs == this.set; + set.append(opt); + } + }); + item.append(set); + } + const visible = document.createElement('label'); { + visible.classList.add('qr--visible'); + const cb = document.createElement('input'); { + cb.type = 'checkbox'; + cb.checked = this.isVisible; + cb.addEventListener('click', ()=>{ + this.isVisible = cb.checked; this.update(); }); - QuickReplySet.list.forEach(qrs=>{ - const opt = document.createElement('option'); { - opt.value = qrs.name; - opt.textContent = qrs.name; - opt.selected = qrs == this.set; - set.append(opt); - } - }); - item.append(set); - } - const visible = document.createElement('label'); { - visible.classList.add('qr--visible'); - const cb = document.createElement('input'); { - cb.type = 'checkbox'; - cb.checked = this.isVisible; - cb.addEventListener('click', ()=>{ - this.isVisible = cb.checked; - this.update(); - }); - visible.append(cb); - } - visible.append('Show buttons'); - item.append(visible); - } - const edit = document.createElement('div'); { - edit.classList.add('menu_button'); - edit.classList.add('menu_button_icon'); - edit.classList.add('fa-solid'); - edit.classList.add('fa-pencil'); - edit.title = 'Edit quick reply set'; - edit.addEventListener('click', ()=>this.requestEditSet()); - item.append(edit); - } - const del = document.createElement('div'); { - del.classList.add('qr--del'); - del.classList.add('menu_button'); - del.classList.add('menu_button_icon'); - del.classList.add('fa-solid'); - del.classList.add('fa-trash-can'); - del.title = 'Remove quick reply set'; - del.addEventListener('click', ()=>this.delete()); - item.append(del); + visible.append(cb); } + visible.append('Show buttons'); + item.append(visible); + } + const edit = document.createElement('div'); { + edit.classList.add('menu_button'); + edit.classList.add('menu_button_icon'); + edit.classList.add('fa-solid'); + edit.classList.add('fa-pencil'); + edit.title = 'Edit quick reply set'; + edit.addEventListener('click', ()=>this.requestEditSet()); + item.append(edit); + } + const del = document.createElement('div'); { + del.classList.add('qr--del'); + del.classList.add('menu_button'); + del.classList.add('menu_button_icon'); + del.classList.add('fa-solid'); + del.classList.add('fa-trash-can'); + del.title = 'Remove quick reply set'; + del.addEventListener('click', ()=>this.delete()); + item.append(del); } } return this.settingsDom; diff --git a/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js b/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js index eb7b24b5c..1a31a6762 100644 --- a/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js +++ b/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js @@ -79,17 +79,26 @@ export class SettingsUi { } prepareGlobalSetList() { - this.settings.config.renderSettingsInto(this.dom.querySelector('#qr--global')); + const dom = this.template.querySelector('#qr--global'); + const clone = dom.cloneNode(true); + // @ts-ignore + this.settings.config.renderSettingsInto(clone); + this.dom.querySelector('#qr--global').replaceWith(clone); } prepareChatSetList() { + const dom = this.template.querySelector('#qr--chat'); + const clone = dom.cloneNode(true); if (this.settings.chatConfig) { - this.settings.chatConfig.renderSettingsInto(this.dom.querySelector('#qr--chat')); + // @ts-ignore + this.settings.chatConfig.renderSettingsInto(clone); } else { const info = document.createElement('div'); { info.textContent = 'No active chat.'; + // @ts-ignore + clone.append(info); } - this.dom.querySelector('#qr--chat').append(info); } + this.dom.querySelector('#qr--chat').replaceWith(clone); } prepareQrEditor() { @@ -201,19 +210,8 @@ export class SettingsUi { async deleteQrSet() { const confirmed = await callPopup(`Are you sure you want to delete the Quick Reply Set "${this.currentQrSet.name}"? This cannot be undone.`, 'confirm'); if (confirmed) { - const idx = QuickReplySet.list.indexOf(this.currentQrSet); await this.currentQrSet.delete(); - this.currentSet.children[idx].remove(); - [ - ...Array.from(this.globalSetList.querySelectorAll('.qr--item > .qr--set')), - ...Array.from(this.chatSetList.querySelectorAll('.qr--item > .qr--set')), - ] - // @ts-ignore - .filter(it=>it.value == this.currentQrSet.name) - // @ts-ignore - .forEach(it=>it.closest('.qr--item').querySelector('.qr--del').click()) - ; - this.onQrSetChange(); + this.rerender(); } } @@ -230,20 +228,32 @@ export class SettingsUi { QuickReplySet.list[QuickReplySet.list.indexOf(oldQrs)] = qrs; this.currentSet.value = name; this.onQrSetChange(); + this.prepareGlobalSetList(); + this.prepareChatSetList(); } } else { const qrs = new QuickReplySet(); qrs.name = name; qrs.addQuickReply(); const idx = QuickReplySet.list.findIndex(it=>it.name.localeCompare(name) == 1); - QuickReplySet.list.splice(idx, 0, qrs); + if (idx > -1) { + QuickReplySet.list.splice(idx, 0, qrs); + } else { + QuickReplySet.list.push(qrs); + } const opt = document.createElement('option'); { opt.value = qrs.name; opt.textContent = qrs.name; - this.currentSet.children[idx].insertAdjacentElement('beforebegin', opt); + if (idx > -1) { + this.currentSet.children[idx].insertAdjacentElement('beforebegin', opt); + } else { + this.currentSet.append(opt); + } } this.currentSet.value = name; this.onQrSetChange(); + this.prepareGlobalSetList(); + this.prepareChatSetList(); } } }