Merge pull request #2798 from SillyTavern/popup-command-styles Expand `/popup` command and refactor a bit

01b6ddbf8af179a3210082c8b0b7f3050bf28d92

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
2 files changed, +67 -20Showing whitespace changes
public/scripts/popup.js+2 -2
@@ -92,7 +92,7 @@ const showPopupHelper = {
92 * @param {string?} header - The header text for the popup.92 * @param {string?} header - The header text for the popup.
93 * @param {string?} text - The main text for the popup.93 * @param {string?} text - The main text for the popup.
94 * @param {PopupOptions} [popupOptions={}] - Options for the popup.94 * @param {PopupOptions} [popupOptions={}] - Options for the popup.
95 * @return {Promise<POPUP_RESULT>} A Promise that resolves with the result of the user's interaction.95 * @return {Promise<POPUP_RESULT?>} A Promise that resolves with the result of the user's interaction.
96 */96 */
97 confirm: async (header, text, popupOptions = {}) => {97 confirm: async (header, text, popupOptions = {}) => {
98 const content = PopupUtils.BuildTextWithHeader(header, text);98 const content = PopupUtils.BuildTextWithHeader(header, text);
@@ -107,7 +107,7 @@ const showPopupHelper = {
107 * @param {string?} header - The header text for the popup.107 * @param {string?} header - The header text for the popup.
108 * @param {string?} text - The main text for the popup.108 * @param {string?} text - The main text for the popup.
109 * @param {PopupOptions} [popupOptions={}] - Options for the popup.109 * @param {PopupOptions} [popupOptions={}] - Options for the popup.
110 * @return {Promise<POPUP_RESULT>} A Promise that resolves with the result of the user's interaction.110 * @return {Promise<POPUP_RESULT?>} A Promise that resolves with the result of the user's interaction.
111 */111 */
112 text: async (header, text, popupOptions = {}) => {112 text: async (header, text, popupOptions = {}) => {
113 const content = PopupUtils.BuildTextWithHeader(header, text);113 const content = PopupUtils.BuildTextWithHeader(header, text);
public/scripts/slash-commands.js+65 -18
@@ -1267,20 +1267,59 @@ export function initDefaultSlashCommands() {
1267 callback: popupCallback,1267 callback: popupCallback,
1268 returns: 'popup text',1268 returns: 'popup text',
1269 namedArgumentList: [1269 namedArgumentList: [
1270 new SlashCommandNamedArgument(1270 SlashCommandNamedArgument.fromProps({
1271 'large', 'show large popup', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(),1271 name: 'large',
1272 ),1272 description: 'show large popup',
1273 new SlashCommandNamedArgument(1273 typeList: [ARGUMENT_TYPE.BOOLEAN],
1274 'wide', 'show wide popup', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(),1274 enumList: commonEnumProviders.boolean('trueFalse')(),
1275 ),1275 defaultValue: 'false',
1276 new SlashCommandNamedArgument(1276 }),
1277 'okButton', 'text for the OK button', [ARGUMENT_TYPE.STRING], false,1277 SlashCommandNamedArgument.fromProps({
1278 ),1278 name: 'wide',
1279 description: 'show wide popup',
1280 typeList: [ARGUMENT_TYPE.BOOLEAN],
1281 enumList: commonEnumProviders.boolean('trueFalse')(),
1282 defaultValue: 'false',
1283 }),
1284 SlashCommandNamedArgument.fromProps({
1285 name: 'wider',
1286 description: 'show wider popup',
1287 typeList: [ARGUMENT_TYPE.BOOLEAN],
1288 enumList: commonEnumProviders.boolean('trueFalse')(),
1289 defaultValue: 'false',
1290 }),
1291 SlashCommandNamedArgument.fromProps({
1292 name: 'transparent',
1293 description: 'show transparent popup',
1294 typeList: [ARGUMENT_TYPE.BOOLEAN],
1295 enumList: commonEnumProviders.boolean('trueFalse')(),
1296 defaultValue: 'false',
1297 }),
1298 SlashCommandNamedArgument.fromProps({
1299 name: 'okButton',
1300 description: 'text for the OK button',
1301 typeList: [ARGUMENT_TYPE.STRING],
1302 defaultValue: 'OK',
1303 }),
1304 SlashCommandNamedArgument.fromProps({
1305 name: 'cancelButton',
1306 description: 'text for the Cancel button',
1307 typeList: [ARGUMENT_TYPE.STRING],
1308 }),
1309 SlashCommandNamedArgument.fromProps({
1310 name: 'result',
1311 description: 'if enabled, returns the popup result (as an integer) instead of the popup text. Resolves to 1 for OK and 0 cancel button, empty string for exiting out.',
1312 typeList: [ARGUMENT_TYPE.BOOLEAN],
1313 enumList: commonEnumProviders.boolean('trueFalse')(),
1314 defaultValue: 'false',
1315 }),
1279 ],1316 ],
1280 unnamedArgumentList: [1317 unnamedArgumentList: [
1281 new SlashCommandArgument(1318 SlashCommandArgument.fromProps({
1282 'text', [ARGUMENT_TYPE.STRING], true,1319 description: 'popup text',
1283 ),1320 typeList: [ARGUMENT_TYPE.STRING],
1321 isRequired: true,
1322 }),
1284 ],1323 ],
1285 helpString: `1324 helpString: `
1286 <div>1325 <div>
@@ -1291,7 +1330,10 @@ export function initDefaultSlashCommands() {
1291 <strong>Example:</strong>1330 <strong>Example:</strong>
1292 <ul>1331 <ul>
1293 <li>1332 <li>
1294 <pre><code>/popup large=on wide=on okButton="Submit" Enter some text:</code></pre>1333 <pre><code>/popup large=on wide=on okButton="Confirm" Please confirm this action.</code></pre>
1334 </li>
1335 <li>
1336 <pre><code>/popup okButton="Left" cancelButton="Right" result=true Do you want to go left or right? | /echo 0 means right, 1 means left. Choice: {{pipe}}</code></pre>
1295 </li>1337 </li>
1296 </ul>1338 </ul>
1297 </div>1339 </div>
@@ -1882,16 +1924,21 @@ async function buttonsCallback(args, text) {
1882}1924}
18831925
1884async function popupCallback(args, value) {1926async function popupCallback(args, value) {
1885 const safeValue = DOMPurify.sanitize(value || '');1927 const safeBody = DOMPurify.sanitize(value || '');
1928 const safeHeader = args?.header && typeof args?.header === 'string' ? DOMPurify.sanitize(args.header) : null;
1929 const requestedResult = isTrueBoolean(args?.result);
1930
1931 /** @type {import('./popup.js').PopupOptions} */
1886 const popupOptions = {1932 const popupOptions = {
1887 large: isTrueBoolean(args?.large),1933 large: isTrueBoolean(args?.large),
1888 wide: isTrueBoolean(args?.wide),1934 wide: isTrueBoolean(args?.wide),
1935 wider: isTrueBoolean(args?.wider),
1936 transparent: isTrueBoolean(args?.transparent),
1889 okButton: args?.okButton !== undefined && typeof args?.okButton === 'string' ? args.okButton : 'Ok',1937 okButton: args?.okButton !== undefined && typeof args?.okButton === 'string' ? args.okButton : 'Ok',
1938 cancelButton: args?.cancelButton !== undefined && typeof args?.cancelButton === 'string' ? args.cancelButton : null,
1890 };1939 };
1891 await delay(1);1940 const result = await Popup.show.text(safeHeader, safeBody, popupOptions);
1892 await callGenericPopup(safeValue, POPUP_TYPE.TEXT, '', popupOptions);1941 return String(requestedResult ? result ?? '' : value);
1893 await delay(1);
1894 return String(value);
1895}1942}
18961943
1897async function getMessagesCallback(args, value) {1944async function getMessagesCallback(args, value) {