Update return types as optional via named arg - Update the modified slash commands for chat sending to use the named arg - Add `slashCommandReturnHelper` for shared funcitonality on return type usage
| @@ -71,6 +71,7 @@ import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCom | ||
| 71 | 71 | import { SlashCommandDebugController } from './slash-commands/SlashCommandDebugController.js'; |
| 72 | 72 | import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js'; |
| 73 | 73 | import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js'; |
| 74 | +import { slashCommandReturnHelper } from './slash-commands/SlashCommandReturnHelper.js'; | |
| 74 | 75 | export { |
| 75 | 76 | executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand, |
| 76 | 77 | }; |
| @@ -176,7 +177,7 @@ export function initDefaultSlashCommands() { | ||
| 176 | 177 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 177 | 178 | name: 'sendas', |
| 178 | 179 | callback: sendMessageAs, |
| 179 | 180 | returns: 'TheOptionally the text of the sent message, if specified in the "return" argument', |
| 180 | 181 | namedArgumentList: [ |
| 181 | 182 | SlashCommandNamedArgument.fromProps({ |
| 182 | 183 | name: 'name', |
| @@ -195,6 +196,14 @@ export function initDefaultSlashCommands() { | ||
| 195 | 196 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 196 | 197 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), |
| 197 | 198 | }), |
| 199 | + SlashCommandNamedArgument.fromProps({ | |
| 200 | + name: 'return', | |
| 201 | + description: 'The way how you want the return value to be provided', | |
| 202 | + typeList: [ARGUMENT_TYPE.STRING], | |
| 203 | + defaultValue: 'none', | |
| 204 | + enumList: slashCommandReturnHelper.enumList({ allowObject: true }), | |
| 205 | + forceEnum: true, | |
| 206 | + }), | |
| 198 | 207 | ], |
| 199 | 208 | unnamedArgumentList: [ |
| 200 | 209 | new SlashCommandArgument( |
| @@ -223,7 +232,7 @@ export function initDefaultSlashCommands() { | ||
| 223 | 232 | name: 'sys', |
| 224 | 233 | callback: sendNarratorMessage, |
| 225 | 234 | aliases: ['nar'], |
| 226 | 235 | returns: 'TheOptionally the text of the sent message, if specified in the "return" argument', |
| 227 | 236 | namedArgumentList: [ |
| 228 | 237 | new SlashCommandNamedArgument( |
| 229 | 238 | 'compact', |
| @@ -239,6 +248,14 @@ export function initDefaultSlashCommands() { | ||
| 239 | 248 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 240 | 249 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), |
| 241 | 250 | }), |
| 251 | + SlashCommandNamedArgument.fromProps({ | |
| 252 | + name: 'return', | |
| 253 | + description: 'The way how you want the return value to be provided', | |
| 254 | + typeList: [ARGUMENT_TYPE.STRING], | |
| 255 | + defaultValue: 'none', | |
| 256 | + enumList: slashCommandReturnHelper.enumList({ allowObject: true }), | |
| 257 | + forceEnum: true, | |
| 258 | + }), | |
| 242 | 259 | ], |
| 243 | 260 | unnamedArgumentList: [ |
| 244 | 261 | new SlashCommandArgument( |
| @@ -278,7 +295,7 @@ export function initDefaultSlashCommands() { | ||
| 278 | 295 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 279 | 296 | name: 'comment', |
| 280 | 297 | callback: sendCommentMessage, |
| 281 | 298 | returns: 'TheOptionally the text of the sent message, if specified in the "return" argument', |
| 282 | 299 | namedArgumentList: [ |
| 283 | 300 | new SlashCommandNamedArgument( |
| 284 | 301 | 'compact', |
| @@ -294,6 +311,14 @@ export function initDefaultSlashCommands() { | ||
| 294 | 311 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 295 | 312 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), |
| 296 | 313 | }), |
| 314 | + SlashCommandNamedArgument.fromProps({ | |
| 315 | + name: 'return', | |
| 316 | + description: 'The way how you want the return value to be provided', | |
| 317 | + typeList: [ARGUMENT_TYPE.STRING], | |
| 318 | + defaultValue: 'none', | |
| 319 | + enumList: slashCommandReturnHelper.enumList({ allowObject: true }), | |
| 320 | + forceEnum: true, | |
| 321 | + }), | |
| 297 | 322 | ], |
| 298 | 323 | unnamedArgumentList: [ |
| 299 | 324 | new SlashCommandArgument( |
| @@ -3210,7 +3235,7 @@ export async function sendMessageAs(args, text) { | ||
| 3210 | 3235 | await saveChatConditional(); |
| 3211 | 3236 | } |
| 3212 | 3237 | |
| 3213 | - return message.mes; | |
| 3238 | + return await slashCommandReturnHelper.doReturn(args.return ?? 'none', message, { objectToStringFunc: x => x.mes }); | |
| 3214 | 3239 | } |
| 3215 | 3240 | |
| 3216 | 3241 | export async function sendNarratorMessage(args, text) { |
| @@ -3264,7 +3289,7 @@ export async function sendNarratorMessage(args, text) { | ||
| 3264 | 3289 | await saveChatConditional(); |
| 3265 | 3290 | } |
| 3266 | 3291 | |
| 3267 | - return message.mes; | |
| 3292 | + return await slashCommandReturnHelper.doReturn(args.return ?? 'none', message, { objectToStringFunc: x => x.mes }); | |
| 3268 | 3293 | } |
| 3269 | 3294 | |
| 3270 | 3295 | export async function promptQuietForLoudResponse(who, text) { |
| @@ -3353,7 +3378,7 @@ async function sendCommentMessage(args, text) { | ||
| 3353 | 3378 | await saveChatConditional(); |
| 3354 | 3379 | } |
| 3355 | 3380 | |
| 3356 | - return message.mes; | |
| 3381 | + return await slashCommandReturnHelper.doReturn(args.return ?? 'none', message, { objectToStringFunc: x => x.mes }); | |
| 3357 | 3382 | } |
| 3358 | 3383 | |
| 3359 | 3384 | /** |
| @@ -36,6 +36,7 @@ export const enumIcons = { | ||
| 36 | 36 | message: '💬', |
| 37 | 37 | voice: '🎤', |
| 38 | 38 | server: '🖥️', |
| 39 | + popup: '🗔', | |
| 39 | 40 | |
| 40 | 41 | true: '✔️', |
| 41 | 42 | false: '❌', |
| @@ -0,0 +1,74 @@ | ||
| 1 | +import { sendSystemMessage, system_message_types } from '../../script.js'; | |
| 2 | +import { callGenericPopup, POPUP_TYPE } from '../popup.js'; | |
| 3 | +import { escapeHtml } from '../utils.js'; | |
| 4 | +import { enumIcons } from './SlashCommandCommonEnumsProvider.js'; | |
| 5 | +import { enumTypes, SlashCommandEnumValue } from './SlashCommandEnumValue.js'; | |
| 6 | + | |
| 7 | +/** @typedef {'pipe'|'object'|'chat-html'|'chat-text'|'popup-html'|'popup-text'|'toast-html'|'toast-text'|'console'|'none'} SlashCommandReturnType */ | |
| 8 | + | |
| 9 | +export const slashCommandReturnHelper = { | |
| 10 | + /** | |
| 11 | + * Gets/creates the enum list of types of return relevant for a slash command | |
| 12 | + * | |
| 13 | + * @param {object} [options={}] Options | |
| 14 | + * @param {boolean} [options.allowPipe=true] Allow option to pipe the return value | |
| 15 | + * @param {boolean} [options.allowObject=false] Allow option to return the value as an object | |
| 16 | + * @param {boolean} [options.allowChat=false] Allow option to return the value as a chat message | |
| 17 | + * @param {boolean} [options.allowPopup=false] Allow option to return the value as a popup | |
| 18 | + * @returns {SlashCommandEnumValue[]} The enum list | |
| 19 | + */ | |
| 20 | + enumList: ({ allowPipe = true, allowObject = false, allowChat = false, allowPopup = false } = {}) => [ | |
| 21 | + allowPipe && new SlashCommandEnumValue('pipe', 'Return to the pipe for the next command', enumTypes.name, '|'), | |
| 22 | + allowObject && new SlashCommandEnumValue('object', 'Return as an object to the pipe for the next command', enumTypes.variable, enumIcons.dictionary), | |
| 23 | + allowChat && new SlashCommandEnumValue('chat-html', 'Sending a chat message with the return value - Can display HTML', enumTypes.command, enumIcons.message), | |
| 24 | + allowChat && new SlashCommandEnumValue('chat-text', 'Sending a chat message with the return value - Will only display as text', enumTypes.qr, enumIcons.message), | |
| 25 | + new SlashCommandEnumValue('popup-html', 'Showing as a popup with the return value - Can display HTML', enumTypes.command, enumIcons.popup), | |
| 26 | + new SlashCommandEnumValue('popup-text', 'Showing as a popup with the return value - Will only display as text', enumTypes.qr, enumIcons.popup), | |
| 27 | + new SlashCommandEnumValue('toast-html', 'Show the return value as a toast notification - Can display HTML', enumTypes.command, 'ℹ️'), | |
| 28 | + new SlashCommandEnumValue('toast-text', 'Show the return value as a toast notification - Will only display as text', enumTypes.qr, 'ℹ️'), | |
| 29 | + new SlashCommandEnumValue('console', 'Log the return value to the console', enumTypes.enum, '>'), | |
| 30 | + new SlashCommandEnumValue('none', 'No return value'), | |
| 31 | + ].filter(x => !!x), | |
| 32 | + | |
| 33 | + /** | |
| 34 | + * Handles the return value based on the specified type | |
| 35 | + * | |
| 36 | + * @param {SlashCommandReturnType} type The type of return | |
| 37 | + * @param {object|number|string} value The value to return | |
| 38 | + * @param {object} [options={}] Options | |
| 39 | + * @param {(o: object) => string} [options.objectToStringFunc=null] Function to convert the object to a string, if object was provided and 'object' was not the chosen return type | |
| 40 | + * @returns {Promise<*>} The processed return value | |
| 41 | + */ | |
| 42 | + async doReturn(type, value, { objectToStringFunc = o => o?.toString() } = {}) { | |
| 43 | + const stringValue = typeof value !== 'string' ? objectToStringFunc(value) : value; | |
| 44 | + | |
| 45 | + switch (type) { | |
| 46 | + case 'popup-html': | |
| 47 | + case 'popup-text': | |
| 48 | + case 'chat-text': | |
| 49 | + case 'chat-html': | |
| 50 | + case 'toast-text': | |
| 51 | + case 'toast-html': { | |
| 52 | + const shouldHtml = type.endsWith('html'); | |
| 53 | + const makeHtml = (str) => (new showdown.Converter()).makeHtml(str); | |
| 54 | + | |
| 55 | + if (type.startsWith('popup')) await callGenericPopup(shouldHtml ? makeHtml(stringValue) : escapeHtml(stringValue), POPUP_TYPE.TEXT); | |
| 56 | + if (type.startsWith('chat')) sendSystemMessage(system_message_types.GENERIC, shouldHtml ? makeHtml(stringValue) : escapeHtml(stringValue)); | |
| 57 | + if (type.startsWith('toast')) toastr.info(stringValue, null, { escapeHtml: !shouldHtml }); // Toastr handles HTML conversion internally already | |
| 58 | + | |
| 59 | + return ''; | |
| 60 | + } | |
| 61 | + case 'pipe': | |
| 62 | + return stringValue ?? ''; | |
| 63 | + case 'object': | |
| 64 | + return JSON.stringify(value); | |
| 65 | + case 'console': | |
| 66 | + console.info(value); | |
| 67 | + return ''; | |
| 68 | + case 'none': | |
| 69 | + return ''; | |
| 70 | + default: | |
| 71 | + throw new Error(`Unknown return type: ${type}`); | |
| 72 | + } | |
| 73 | + }, | |
| 74 | +}; | |