diff --git a/public/scripts/extensions/quick-reply/html/settings.html b/public/scripts/extensions/quick-reply/html/settings.html
index a9a810fd8..210ad4f32 100644
--- a/public/scripts/extensions/quick-reply/html/settings.html
+++ b/public/scripts/extensions/quick-reply/html/settings.html
@@ -46,10 +46,12 @@
Edit Quick Replies
+
+
diff --git a/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js b/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js
index 920c2cd30..df6bb081f 100644
--- a/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js
+++ b/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js
@@ -1,4 +1,4 @@
-import { callPopup } from '../../../../../script.js';
+import { Popup } from '../../../../popup.js';
import { getSortableDelay } from '../../../../utils.js';
import { log, warn } from '../../index.js';
import { QuickReply } from '../QuickReply.js';
@@ -111,6 +111,7 @@ export class SettingsUi {
prepareQrEditor() {
// qr editor
+ this.dom.querySelector('#qr--set-rename').addEventListener('click', async () => this.renameQrSet());
this.dom.querySelector('#qr--set-new').addEventListener('click', async()=>this.addQrSet());
/**@type {HTMLInputElement}*/
const importFile = this.dom.querySelector('#qr--set-importFile');
@@ -119,7 +120,8 @@ export class SettingsUi {
importFile.value = null;
});
this.dom.querySelector('#qr--set-import').addEventListener('click', ()=>importFile.click());
- this.dom.querySelector('#qr--set-export').addEventListener('click', async()=>this.exportQrSet());
+ this.dom.querySelector('#qr--set-export').addEventListener('click', async () => this.exportQrSet());
+ this.dom.querySelector('#qr--set-duplicate').addEventListener('click', async () => this.duplicateQrSet());
this.dom.querySelector('#qr--set-delete').addEventListener('click', async()=>this.deleteQrSet());
this.dom.querySelector('#qr--set-add').addEventListener('click', async()=>{
this.currentQrSet.addQuickReply();
@@ -279,7 +281,7 @@ 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');
+ const confirmed = await Popup.show.confirm('Delete Quick Reply Set', `Are you sure you want to delete the Quick Reply Set "${this.currentQrSet.name}"?
This cannot be undone.`);
if (confirmed) {
await this.doDeleteQrSet(this.currentQrSet);
this.rerender();
@@ -303,12 +305,52 @@ export class SettingsUi {
this.settings.save();
}
+ async renameQrSet() {
+ const newName = await Popup.show.input('Rename Quick Reply Set', 'Enter a new name:', this.currentQrSet.name);
+ if (newName && newName.length > 0) {
+ const existingSet = QuickReplySet.get(newName);
+ if (existingSet) {
+ toastr.error(`A Quick Reply Set named "${newName}" already exists.`);
+ return;
+ }
+ const oldName = this.currentQrSet.name;
+ this.currentQrSet.name = newName;
+ await this.currentQrSet.save();
+
+ // Update it in both set lists
+ this.settings.config.setList.forEach(set => {
+ if (set.set.name === oldName) {
+ set.set.name = newName;
+ }
+ });
+ this.settings.chatConfig?.setList.forEach(set => {
+ if (set.set.name === oldName) {
+ set.set.name = newName;
+ }
+ });
+ this.settings.save();
+
+ // Update the option in the current selected QR dropdown. All others will be refreshed via the prepare calls below.
+ /** @type {HTMLOptionElement} */
+ const option = this.currentSet.querySelector(`#qr--set option[value="${oldName}"]`);
+ option.value = newName;
+ option.textContent = newName;
+
+ this.currentSet.value = newName;
+ this.onQrSetChange();
+ this.prepareGlobalSetList();
+ this.prepareChatSetList();
+
+ console.info(`Quick Reply Set renamed from ""${oldName}" to "${newName}".`);
+ }
+ }
+
async addQrSet() {
- const name = await callPopup('Quick Reply Set Name:', 'input');
+ const name = await Popup.show.input('Create a new World Info', 'Enter a name for the new Quick Reply Set:');
if (name && name.length > 0) {
const oldQrs = QuickReplySet.get(name);
if (oldQrs) {
- const replace = await callPopup(`A Quick Reply Set named "${name}" already exists.
Do you want to overwrite the existing Quick Reply Set?
The existing set will be deleted. This cannot be undone.`, 'confirm');
+ const replace = Popup.show.confirm('Replace existing World Info', `A Quick Reply Set named "${name}" already exists.
Do you want to overwrite the existing Quick Reply Set?
The existing set will be deleted. This cannot be undone.`);
if (replace) {
const idx = QuickReplySet.list.indexOf(oldQrs);
await this.doDeleteQrSet(oldQrs);
@@ -369,7 +411,7 @@ export class SettingsUi {
qrs.init();
const oldQrs = QuickReplySet.get(props.name);
if (oldQrs) {
- const replace = await callPopup(`A Quick Reply Set named "${qrs.name}" already exists.
Do you want to overwrite the existing Quick Reply Set?
The existing set will be deleted. This cannot be undone.`, 'confirm');
+ const replace = Popup.show.confirm('Replace existing World Info', `A Quick Reply Set named "${name}" already exists.
Do you want to overwrite the existing Quick Reply Set?
The existing set will be deleted. This cannot be undone.`);
if (replace) {
const idx = QuickReplySet.list.indexOf(oldQrs);
await this.doDeleteQrSet(oldQrs);
@@ -421,6 +463,40 @@ export class SettingsUi {
URL.revokeObjectURL(url);
}
+ async duplicateQrSet() {
+ const newName = await Popup.show.input('Duplicate Quick Reply Set', 'Enter a name for the new Quick Reply Set:', `${this.currentQrSet.name} (Copy)`);
+ if (newName && newName.length > 0) {
+ const existingSet = QuickReplySet.get(newName);
+ if (existingSet) {
+ toastr.error(`A Quick Reply Set named "${newName}" already exists.`);
+ return;
+ }
+ const newQrSet = QuickReplySet.from(JSON.parse(JSON.stringify(this.currentQrSet)));
+ newQrSet.name = newName;
+ newQrSet.qrList = this.currentQrSet.qrList.map(qr => QuickReply.from(JSON.parse(JSON.stringify(qr))));
+ newQrSet.addQuickReply();
+ const idx = QuickReplySet.list.findIndex(it => it.name.toLowerCase().localeCompare(newName.toLowerCase()) == 1);
+ if (idx > -1) {
+ QuickReplySet.list.splice(idx, 0, newQrSet);
+ } else {
+ QuickReplySet.list.push(newQrSet);
+ }
+ const opt = document.createElement('option'); {
+ opt.value = newQrSet.name;
+ opt.textContent = newQrSet.name;
+ if (idx > -1) {
+ this.currentSet.children[idx].insertAdjacentElement('beforebegin', opt);
+ } else {
+ this.currentSet.append(opt);
+ }
+ }
+ this.currentSet.value = newName;
+ this.onQrSetChange();
+ this.prepareGlobalSetList();
+ this.prepareChatSetList();
+ }
+ }
+
selectQrSet(qrs) {
this.currentSet.value = qrs.name;
this.onQrSetChange();