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 | import { SlashCommandDebugController } from './slash-commands/SlashCommandDebugController.js'; | 71 | import { SlashCommandDebugController } from './slash-commands/SlashCommandDebugController.js'; |
| 72 | import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js'; | 72 | import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js'; |
| 73 | import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js'; | 73 | import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js'; |
| 74 | import { slashCommandReturnHelper } from './slash-commands/SlashCommandReturnHelper.js'; | ||
| 74 | export { | 75 | export { |
| 75 | executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand, | 76 | executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand, |
| 76 | }; | 77 | }; |
| @@ -176,7 +177,7 @@ export function initDefaultSlashCommands() { | |||
| 176 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 177 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 177 | name: 'sendas', | 178 | name: 'sendas', |
| 178 | callback: sendMessageAs, | 179 | callback: sendMessageAs, |
| 179 | returns: 'The text of the sent message', | 180 | returns: 'Optionally the text of the sent message, if specified in the "return" argument', |
| 180 | namedArgumentList: [ | 181 | namedArgumentList: [ |
| 181 | SlashCommandNamedArgument.fromProps({ | 182 | SlashCommandNamedArgument.fromProps({ |
| 182 | name: 'name', | 183 | name: 'name', |
| @@ -195,6 +196,14 @@ export function initDefaultSlashCommands() { | |||
| 195 | typeList: [ARGUMENT_TYPE.NUMBER], | 196 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 196 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), | 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 | unnamedArgumentList: [ | 208 | unnamedArgumentList: [ |
| 200 | new SlashCommandArgument( | 209 | new SlashCommandArgument( |
| @@ -223,7 +232,7 @@ export function initDefaultSlashCommands() { | |||
| 223 | name: 'sys', | 232 | name: 'sys', |
| 224 | callback: sendNarratorMessage, | 233 | callback: sendNarratorMessage, |
| 225 | aliases: ['nar'], | 234 | aliases: ['nar'], |
| 226 | returns: 'The text of the sent message', | 235 | returns: 'Optionally the text of the sent message, if specified in the "return" argument', |
| 227 | namedArgumentList: [ | 236 | namedArgumentList: [ |
| 228 | new SlashCommandNamedArgument( | 237 | new SlashCommandNamedArgument( |
| 229 | 'compact', | 238 | 'compact', |
| @@ -239,6 +248,14 @@ export function initDefaultSlashCommands() { | |||
| 239 | typeList: [ARGUMENT_TYPE.NUMBER], | 248 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 240 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), | 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 | unnamedArgumentList: [ | 260 | unnamedArgumentList: [ |
| 244 | new SlashCommandArgument( | 261 | new SlashCommandArgument( |
| @@ -278,7 +295,7 @@ export function initDefaultSlashCommands() { | |||
| 278 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 295 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 279 | name: 'comment', | 296 | name: 'comment', |
| 280 | callback: sendCommentMessage, | 297 | callback: sendCommentMessage, |
| 281 | returns: 'The text of the sent message', | 298 | returns: 'Optionally the text of the sent message, if specified in the "return" argument', |
| 282 | namedArgumentList: [ | 299 | namedArgumentList: [ |
| 283 | new SlashCommandNamedArgument( | 300 | new SlashCommandNamedArgument( |
| 284 | 'compact', | 301 | 'compact', |
| @@ -294,6 +311,14 @@ export function initDefaultSlashCommands() { | |||
| 294 | typeList: [ARGUMENT_TYPE.NUMBER], | 311 | typeList: [ARGUMENT_TYPE.NUMBER], |
| 295 | enumProvider: commonEnumProviders.messages({ allowIdAfter: true }), | 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 | unnamedArgumentList: [ | 323 | unnamedArgumentList: [ |
| 299 | new SlashCommandArgument( | 324 | new SlashCommandArgument( |
| @@ -3210,7 +3235,7 @@ export async function sendMessageAs(args, text) { | |||
| 3210 | await saveChatConditional(); | 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 | export async function sendNarratorMessage(args, text) { | 3241 | export async function sendNarratorMessage(args, text) { |
| @@ -3264,7 +3289,7 @@ export async function sendNarratorMessage(args, text) { | |||
| 3264 | await saveChatConditional(); | 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 | export async function promptQuietForLoudResponse(who, text) { | 3295 | export async function promptQuietForLoudResponse(who, text) { |
| @@ -3353,7 +3378,7 @@ async function sendCommentMessage(args, text) { | |||
| 3353 | await saveChatConditional(); | 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 | message: '💬', | 36 | message: '💬', |
| 37 | voice: '🎤', | 37 | voice: '🎤', |
| 38 | server: '🖥️', | 38 | server: '🖥️', |
| 39 | popup: '🗔', | ||
| 39 | 40 | ||
| 40 | true: '✔️', | 41 | true: '✔️', |
| 41 | false: '❌', | 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 | }; | ||