2024-09-30 23:32:24 +02:00
import { sendSystemMessage , system _message _types } from '../../script.js' ;
import { callGenericPopup , POPUP _TYPE } from '../popup.js' ;
import { escapeHtml } from '../utils.js' ;
import { enumIcons } from './SlashCommandCommonEnumsProvider.js' ;
import { enumTypes , SlashCommandEnumValue } from './SlashCommandEnumValue.js' ;
/** @typedef {'pipe'|'object'|'chat-html'|'chat-text'|'popup-html'|'popup-text'|'toast-html'|'toast-text'|'console'|'none'} SlashCommandReturnType */
export const slashCommandReturnHelper = {
2024-10-01 00:06:18 +02:00
// Without this, VSCode formatter fucks up JS docs. Don't ask me why.
_ : false ,
2024-09-30 23:32:24 +02:00
/ * *
* Gets / creates the enum list of types of return relevant for a slash command
*
* @ param { object } [ options = { } ] Options
* @ param { boolean } [ options . allowPipe = true ] Allow option to pipe the return value
* @ param { boolean } [ options . allowObject = false ] Allow option to return the value as an object
* @ param { boolean } [ options . allowChat = false ] Allow option to return the value as a chat message
* @ param { boolean } [ options . allowPopup = false ] Allow option to return the value as a popup
2024-10-01 00:06:18 +02:00
* @ param { boolean } [ options . allowTextVersion = true ] Used in combination with chat / popup / toast , some of them do not make sense for text versions , e . g . if you are building a HTML string anyway
2024-09-30 23:32:24 +02:00
* @ returns { SlashCommandEnumValue [ ] } The enum list
* /
2024-10-01 00:06:18 +02:00
enumList : ( { allowPipe = true , allowObject = false , allowChat = false , allowPopup = false , allowTextVersion = true } = { } ) => [
2024-09-30 23:32:24 +02:00
allowPipe && new SlashCommandEnumValue ( 'pipe' , 'Return to the pipe for the next command' , enumTypes . name , '|' ) ,
2024-10-01 00:37:21 +02:00
allowObject && new SlashCommandEnumValue ( 'object' , 'Return as an object (or array) to the pipe for the next command' , enumTypes . variable , enumIcons . dictionary ) ,
2024-09-30 23:32:24 +02:00
allowChat && new SlashCommandEnumValue ( 'chat-html' , 'Sending a chat message with the return value - Can display HTML' , enumTypes . command , enumIcons . message ) ,
2024-10-01 00:06:18 +02:00
allowChat && allowTextVersion && new SlashCommandEnumValue ( 'chat-text' , 'Sending a chat message with the return value - Will only display as text' , enumTypes . qr , enumIcons . message ) ,
allowPopup && new SlashCommandEnumValue ( 'popup-html' , 'Showing as a popup with the return value - Can display HTML' , enumTypes . command , enumIcons . popup ) ,
allowPopup && allowTextVersion && new SlashCommandEnumValue ( 'popup-text' , 'Showing as a popup with the return value - Will only display as text' , enumTypes . qr , enumIcons . popup ) ,
2024-09-30 23:32:24 +02:00
new SlashCommandEnumValue ( 'toast-html' , 'Show the return value as a toast notification - Can display HTML' , enumTypes . command , 'ℹ ️ ' ) ,
2024-10-01 00:06:18 +02:00
allowTextVersion && new SlashCommandEnumValue ( 'toast-text' , 'Show the return value as a toast notification - Will only display as text' , enumTypes . qr , 'ℹ ️ ' ) ,
new SlashCommandEnumValue ( 'console' , 'Log the return value (object, if it can be one) to the console' , enumTypes . enum , '>' ) ,
2024-09-30 23:32:24 +02:00
new SlashCommandEnumValue ( 'none' , 'No return value' ) ,
] . filter ( x => ! ! x ) ,
/ * *
* Handles the return value based on the specified type
*
* @ param { SlashCommandReturnType } type The type of return
* @ param { object | number | string } value The value to return
* @ param { object } [ options = { } ] Options
* @ 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
2024-10-01 00:53:19 +02:00
* @ param { ( o : object ) => string } [ options . objectToHtmlFunc = null ] Analog to 'objectToStringFunc' , which will be used here if not provided - but can do a different string layout if HTML is requested
2024-09-30 23:32:24 +02:00
* @ returns { Promise < * > } The processed return value
* /
2024-10-01 00:53:19 +02:00
async doReturn ( type , value , { objectToStringFunc = o => o ? . toString ( ) , objectToHtmlFunc = null } = { } ) {
const shouldHtml = type . endsWith ( 'html' ) ;
const actualConverterFunc = shouldHtml && objectToHtmlFunc ? objectToHtmlFunc : objectToStringFunc ;
const stringValue = typeof value !== 'string' ? actualConverterFunc ( value ) : value ;
2024-09-30 23:32:24 +02:00
switch ( type ) {
case 'popup-html' :
case 'popup-text' :
case 'chat-text' :
case 'chat-html' :
case 'toast-text' :
case 'toast-html' : {
2024-10-01 01:23:34 +02:00
const htmlOrNotHtml = shouldHtml ? DOMPurify . sanitize ( ( new showdown . Converter ( ) ) . makeHtml ( stringValue ) ) : escapeHtml ( stringValue ) ;
2024-09-30 23:32:24 +02:00
2024-10-01 00:53:19 +02:00
if ( type . startsWith ( 'popup' ) ) await callGenericPopup ( htmlOrNotHtml , POPUP _TYPE . TEXT ) ;
if ( type . startsWith ( 'chat' ) ) sendSystemMessage ( system _message _types . GENERIC , htmlOrNotHtml ) ;
if ( type . startsWith ( 'toast' ) ) toastr . info ( htmlOrNotHtml , null , { escapeHtml : ! shouldHtml } ) ;
2024-09-30 23:32:24 +02:00
return '' ;
}
case 'pipe' :
return stringValue ? ? '' ;
case 'object' :
return JSON . stringify ( value ) ;
case 'console' :
console . info ( value ) ;
return '' ;
case 'none' :
return '' ;
default :
throw new Error ( ` Unknown return type: ${ type } ` ) ;
}
} ,
} ;