mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'staging' into char-cache-limit
This commit is contained in:
@@ -419,30 +419,35 @@ export class SlashCommandHandler {
|
||||
namedArgumentList: [
|
||||
SlashCommandNamedArgument.fromProps({
|
||||
name: 'set',
|
||||
description: 'QR set name',
|
||||
description: 'Name of QR set to add the context menu to',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
isRequired: true,
|
||||
enumProvider: localEnumProviders.qrSets,
|
||||
}),
|
||||
SlashCommandNamedArgument.fromProps({
|
||||
name: 'label',
|
||||
description: 'Quick Reply label',
|
||||
description: 'Label of Quick Reply to add the context menu to',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
enumProvider: localEnumProviders.qrEntries,
|
||||
}),
|
||||
SlashCommandNamedArgument.fromProps({
|
||||
name: 'id',
|
||||
description: 'numeric ID of the QR, e.g., id=42',
|
||||
description: 'Numeric ID of Quick Reply to add the context menu to, e.g. id=42',
|
||||
typeList: [ARGUMENT_TYPE.NUMBER],
|
||||
enumProvider: localEnumProviders.qrIds,
|
||||
}),
|
||||
new SlashCommandNamedArgument(
|
||||
'chain', 'boolean', [ARGUMENT_TYPE.BOOLEAN], false, false, 'false',
|
||||
'chain',
|
||||
'If true, button QR is sent together with (before) the clicked QR from the context menu',
|
||||
[ARGUMENT_TYPE.BOOLEAN],
|
||||
false,
|
||||
false,
|
||||
'false',
|
||||
),
|
||||
],
|
||||
unnamedArgumentList: [
|
||||
SlashCommandArgument.fromProps({
|
||||
description: 'QR set name',
|
||||
description: 'Name of QR set to add as a context menu',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
isRequired: true,
|
||||
enumProvider: localEnumProviders.qrSets,
|
||||
@@ -450,13 +455,16 @@ export class SlashCommandHandler {
|
||||
],
|
||||
helpString: `
|
||||
<div>
|
||||
Add context menu preset to a QR.
|
||||
Add a context menu preset to a QR.
|
||||
</div>
|
||||
<div>
|
||||
If <code>id</code> and <code>label</code> are both provided, <code>id</code> will be used.
|
||||
</div>
|
||||
<div>
|
||||
<strong>Example:</strong>
|
||||
<ul>
|
||||
<li>
|
||||
<pre><code>/qr-contextadd set=MyPreset label=MyButton chain=true MyOtherPreset</code></pre>
|
||||
<pre><code>/qr-contextadd set=MyQRSetWithTheButton label=MyButton chain=true MyQRSetWithContextItems</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -470,27 +478,27 @@ export class SlashCommandHandler {
|
||||
namedArgumentList: [
|
||||
SlashCommandNamedArgument.fromProps({
|
||||
name: 'set',
|
||||
description: 'QR set name',
|
||||
description: 'Name of QR set to remove the context menu from',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
isRequired: true,
|
||||
enumProvider: localEnumProviders.qrSets,
|
||||
}),
|
||||
SlashCommandNamedArgument.fromProps({
|
||||
name: 'label',
|
||||
description: 'Quick Reply label',
|
||||
description: 'Label of Quick Reply to remove the context menu from',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
enumProvider: localEnumProviders.qrEntries,
|
||||
}),
|
||||
SlashCommandNamedArgument.fromProps({
|
||||
name: 'id',
|
||||
description: 'numeric ID of the QR, e.g., id=42',
|
||||
description: 'Numeric ID of Quick Reply to remove the context menu from, e.g. id=42',
|
||||
typeList: [ARGUMENT_TYPE.NUMBER],
|
||||
enumProvider: localEnumProviders.qrIds,
|
||||
}),
|
||||
],
|
||||
unnamedArgumentList: [
|
||||
SlashCommandArgument.fromProps({
|
||||
description: 'QR set name',
|
||||
description: 'Name of QR set to remove',
|
||||
typeList: [ARGUMENT_TYPE.STRING],
|
||||
isRequired: true,
|
||||
enumProvider: localEnumProviders.qrSets,
|
||||
@@ -500,6 +508,9 @@ export class SlashCommandHandler {
|
||||
<div>
|
||||
Remove context menu preset from a QR.
|
||||
</div>
|
||||
<div>
|
||||
If <code>id</code> and <code>label</code> are both provided, <code>id</code> will be used.
|
||||
</div>
|
||||
<div>
|
||||
<strong>Example:</strong>
|
||||
<ul>
|
||||
@@ -541,6 +552,9 @@ export class SlashCommandHandler {
|
||||
<div>
|
||||
Remove all context menu presets from a QR.
|
||||
</div>
|
||||
<div>
|
||||
If <code>id</code> and a label are both provided, <code>id</code> will be used.
|
||||
</div>
|
||||
<div>
|
||||
<strong>Example:</strong>
|
||||
<ul>
|
||||
@@ -908,12 +922,11 @@ export class SlashCommandHandler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
createContextItem(args, name) {
|
||||
try {
|
||||
this.api.createContextItem(
|
||||
args.set,
|
||||
args.label,
|
||||
args.id !== undefined ? Number(args.id) : args.label,
|
||||
name,
|
||||
isTrueBoolean(args.chain),
|
||||
);
|
||||
@@ -923,14 +936,14 @@ export class SlashCommandHandler {
|
||||
}
|
||||
deleteContextItem(args, name) {
|
||||
try {
|
||||
this.api.deleteContextItem(args.set, args.label, name);
|
||||
this.api.deleteContextItem(args.set, args.id !== undefined ? Number(args.id) : args.label, name);
|
||||
} catch (ex) {
|
||||
toastr.error(ex.message);
|
||||
}
|
||||
}
|
||||
clearContextMenu(args, label) {
|
||||
try {
|
||||
this.api.clearContextMenu(args.set, args.label ?? label);
|
||||
this.api.clearContextMenu(args.set, args.id !== undefined ? Number(args.id) : args.label ?? label);
|
||||
} catch (ex) {
|
||||
toastr.error(ex.message);
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ export class ContextMenu {
|
||||
this.itemList = this.build(qr).children;
|
||||
this.itemList.forEach(item => {
|
||||
item.onExpand = () => {
|
||||
this.itemList.filter(it => it != item)
|
||||
this.itemList.filter(it => it !== item)
|
||||
.forEach(it => it.collapse());
|
||||
};
|
||||
});
|
||||
@@ -36,7 +36,9 @@ export class ContextMenu {
|
||||
icon: qr.icon,
|
||||
showLabel: qr.showLabel,
|
||||
label: qr.label,
|
||||
title: qr.title,
|
||||
message: (chainedMessage && qr.message ? `${chainedMessage} | ` : '') + qr.message,
|
||||
isHidden: qr.isHidden,
|
||||
children: [],
|
||||
};
|
||||
qr.contextList.forEach((cl) => {
|
||||
@@ -51,7 +53,9 @@ export class ContextMenu {
|
||||
subTree.icon,
|
||||
subTree.showLabel,
|
||||
subTree.label,
|
||||
subTree.title,
|
||||
subTree.message,
|
||||
subTree.isHidden,
|
||||
(evt) => {
|
||||
evt.stopPropagation();
|
||||
const finalQr = Object.assign(new QuickReply(), subQr);
|
||||
|
@@ -2,7 +2,7 @@ import { MenuItem } from './MenuItem.js';
|
||||
|
||||
export class MenuHeader extends MenuItem {
|
||||
constructor(/**@type {String}*/label) {
|
||||
super(null, null, label, null, null);
|
||||
super(null, null, label, null, null, false, null, []);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -4,11 +4,12 @@ export class MenuItem {
|
||||
/**@type {string}*/ icon;
|
||||
/**@type {boolean}*/ showLabel;
|
||||
/**@type {string}*/ label;
|
||||
/**@type {string}*/ title;
|
||||
/**@type {object}*/ value;
|
||||
/**@type {boolean}*/ isHidden = false;
|
||||
/**@type {function}*/ callback;
|
||||
/**@type {MenuItem[]}*/ childList = [];
|
||||
/**@type {SubMenu}*/ subMenu;
|
||||
/**@type {boolean}*/ isForceExpanded = false;
|
||||
|
||||
/**@type {HTMLElement}*/ root;
|
||||
|
||||
@@ -19,35 +20,67 @@ export class MenuItem {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} icon
|
||||
* @param {boolean} showLabel
|
||||
* @param {?string} icon
|
||||
* @param {?boolean} showLabel
|
||||
* @param {string} label
|
||||
* @param {?string} title Tooltip
|
||||
* @param {object} value
|
||||
* @param {boolean} isHidden QR is Invisible (auto-execute only)
|
||||
* @param {function} callback
|
||||
* @param {MenuItem[]} children
|
||||
*/
|
||||
constructor(icon, showLabel, label, value, callback, children = []) {
|
||||
constructor(icon, showLabel, label, title, value, isHidden, callback, children = []) {
|
||||
this.icon = icon;
|
||||
this.showLabel = showLabel;
|
||||
this.label = label;
|
||||
this.title = title;
|
||||
this.value = value;
|
||||
this.isHidden = isHidden;
|
||||
this.callback = callback;
|
||||
this.childList = children;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders the MenuItem
|
||||
*
|
||||
* A .qr--hidden class is added to:
|
||||
* - the item if it is "Invisible (auto-execute only)"
|
||||
* - the icon if no icon is set
|
||||
* - the label if an icon is set and showLabel is false
|
||||
*
|
||||
* There is no .qr--hidden class defined in default CSS, since having items
|
||||
* that are invisible on the QR bar but visible in the context menu,
|
||||
* or icon-only on the QR bar but labelled in the context menu, is a valid use case.
|
||||
*
|
||||
* To hide optional labels when icons are present, add this user CSS:
|
||||
* .ctx-menu .ctx-item .qr--button-label.qr--hidden {display: none;}
|
||||
* To hide icons when no icon is present (removes unwanted padding):
|
||||
* .ctx-menu .ctx-item .qr--button-icon.qr--hidden {display: none;}
|
||||
* To hide items that are set "invisible":
|
||||
* .ctx-menu .ctx-item.qr--hidden {display: none;}
|
||||
* To target submenus only, use .ctx-menu .ctx-sub-menu .qr--hidden {display: none;}
|
||||
*
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
render() {
|
||||
if (!this.root) {
|
||||
const item = document.createElement('li'); {
|
||||
this.root = item;
|
||||
item.classList.add('list-group-item');
|
||||
item.classList.add('ctx-item');
|
||||
item.title = this.value;
|
||||
|
||||
// if this item is Invisible, add the hidden class
|
||||
if (this.isHidden) item.classList.add('qr--hidden');
|
||||
|
||||
// if a title/tooltip is set, add it, otherwise use the QR content
|
||||
// same as for the main QR list
|
||||
item.title = this.title || this.value;
|
||||
|
||||
if (this.callback) {
|
||||
item.addEventListener('click', (evt) => this.callback(evt, this));
|
||||
}
|
||||
const icon = document.createElement('div'); {
|
||||
this.domIcon = icon;
|
||||
icon.classList.add('qr--button-icon');
|
||||
icon.classList.add('fa-solid');
|
||||
if (!this.icon) icon.classList.add('qr--hidden');
|
||||
@@ -55,7 +88,6 @@ export class MenuItem {
|
||||
item.append(icon);
|
||||
}
|
||||
const lbl = document.createElement('div'); {
|
||||
this.domLabel = lbl;
|
||||
lbl.classList.add('qr--button-label');
|
||||
if (this.icon && !this.showLabel) lbl.classList.add('qr--hidden');
|
||||
lbl.textContent = this.label;
|
||||
|
Reference in New Issue
Block a user