mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-03-02 19:07:40 +01:00
Add /extension-toggle
This commit is contained in:
parent
eda7493a33
commit
a6445aee1b
@ -8,7 +8,7 @@ import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCom
|
|||||||
import { enumTypes, SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
|
import { enumTypes, SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
|
||||||
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
|
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
|
||||||
import { renderTemplate, renderTemplateAsync } from './templates.js';
|
import { renderTemplate, renderTemplateAsync } from './templates.js';
|
||||||
import { equalsIgnoreCaseAndAccents, isSubsetOf, isTrueBoolean, setValueByPath } from './utils.js';
|
import { equalsIgnoreCaseAndAccents, isFalseBoolean, isSubsetOf, isTrueBoolean, setValueByPath } from './utils.js';
|
||||||
export {
|
export {
|
||||||
getContext,
|
getContext,
|
||||||
getApiUrl,
|
getApiUrl,
|
||||||
@ -1050,33 +1050,50 @@ export async function openThirdPartyExtensionMenu(suggestUrl = '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} enable - Whether to enable or disable the extension
|
* @param {'enable' | 'disable' | 'toggle'} action - The action to perform on the extension
|
||||||
* @returns {(args: {[key: string]: string | SlashCommandClosure}, extensionName: string | SlashCommandClosure) => Promise<string>}
|
* @returns {(args: {[key: string]: string | SlashCommandClosure}, extensionName: string | SlashCommandClosure) => Promise<string>}
|
||||||
*/
|
*/
|
||||||
function getExtensionToggleCallback(enable) {
|
function getExtensionActionCallback(action) {
|
||||||
return async (args, extensionName) => {
|
return async (args, extensionName) => {
|
||||||
if (args?.reload instanceof SlashCommandClosure) throw new Error('\'reload\' argument cannot be a closure.');
|
if (args?.reload instanceof SlashCommandClosure) throw new Error('\'reload\' argument cannot be a closure.');
|
||||||
if (typeof extensionName !== 'string') throw new Error('Extension name does only support string. Closures or arrays are not allowed.');
|
if (typeof extensionName !== 'string') throw new Error('Extension name does only support string. Closures or arrays are not allowed.');
|
||||||
if (!extensionName) {
|
if (!extensionName) {
|
||||||
toastr.warning(`Extension name must be provided as an argument to ${enable ? 'enable' : 'disable'} this extension.`);
|
toastr.warning(`Extension name must be provided as an argument to ${action} this extension.`);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const reload = isTrueBoolean(args?.reload);
|
const reload = isTrueBoolean(args?.reload);
|
||||||
|
|
||||||
const internalExtensionName = extensionNames.find(x => equalsIgnoreCaseAndAccents(x, extensionName));
|
const internalExtensionName = extensionNames.find(x => equalsIgnoreCaseAndAccents(x, extensionName));
|
||||||
if (!internalExtensionName) {
|
if (!internalExtensionName) {
|
||||||
toastr.warning(`Extension ${extensionName} does not exist.`);
|
toastr.warning(`Extension ${extensionName} does not exist.`);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (enable === !extension_settings.disabledExtensions.includes(internalExtensionName)) {
|
|
||||||
toastr.info(`Extension ${extensionName} is already ${enable ? 'enabled' : 'disabled'}.`);
|
const isEnabled = !extension_settings.disabledExtensions.includes(internalExtensionName);
|
||||||
|
|
||||||
|
if (action === 'enable' && isEnabled) {
|
||||||
|
toastr.info(`Extension ${extensionName} is already enabled.`);
|
||||||
return internalExtensionName;
|
return internalExtensionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
reload && toastr.info(`${enable ? 'Enabling' : 'Disabling'} extension ${extensionName} and reloading...`);
|
if (action === 'disable' && !isEnabled) {
|
||||||
|
toastr.info(`Extension ${extensionName} is already disabled.`);
|
||||||
|
return internalExtensionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === 'toggle') {
|
||||||
|
action = isEnabled ? 'disable' : 'enable';
|
||||||
|
}
|
||||||
|
|
||||||
|
reload && toastr.info(`${action.charAt(0).toUpperCase() + action.slice(1)}ing extension ${extensionName} and reloading...`);
|
||||||
|
|
||||||
|
if (action === 'enable') {
|
||||||
await enableExtension(internalExtensionName, reload);
|
await enableExtension(internalExtensionName, reload);
|
||||||
toastr.success(`Extension ${extensionName} ${enable ? 'enabled' : 'disabled'}.`);
|
} else {
|
||||||
|
await disableExtension(internalExtensionName, reload);
|
||||||
|
}
|
||||||
|
|
||||||
|
toastr.success(`Extension ${extensionName} ${action}d.`);
|
||||||
|
|
||||||
return internalExtensionName;
|
return internalExtensionName;
|
||||||
};
|
};
|
||||||
@ -1085,7 +1102,7 @@ function getExtensionToggleCallback(enable) {
|
|||||||
function registerExtensionSlashCommands() {
|
function registerExtensionSlashCommands() {
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: 'extension-enable',
|
name: 'extension-enable',
|
||||||
callback: getExtensionToggleCallback(true),
|
callback: getExtensionActionCallback('enable'),
|
||||||
namedArgumentList: [
|
namedArgumentList: [
|
||||||
SlashCommandNamedArgument.fromProps({
|
SlashCommandNamedArgument.fromProps({
|
||||||
name: 'reload',
|
name: 'reload',
|
||||||
@ -1125,7 +1142,7 @@ function registerExtensionSlashCommands() {
|
|||||||
}));
|
}));
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: 'extension-disable',
|
name: 'extension-disable',
|
||||||
callback: getExtensionToggleCallback(false),
|
callback: getExtensionActionCallback('enable'),
|
||||||
namedArgumentList: [
|
namedArgumentList: [
|
||||||
SlashCommandNamedArgument.fromProps({
|
SlashCommandNamedArgument.fromProps({
|
||||||
name: 'reload',
|
name: 'reload',
|
||||||
@ -1163,6 +1180,64 @@ function registerExtensionSlashCommands() {
|
|||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
}));
|
}));
|
||||||
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
|
name: 'extension-toggle',
|
||||||
|
callback: async (args, extensionName) => {
|
||||||
|
if (args?.state instanceof SlashCommandClosure) throw new Error('\'state\' argument cannot be a closure.');
|
||||||
|
if (typeof extensionName !== 'string') throw new Error('Extension name does only support string. Closures or arrays are not allowed.');
|
||||||
|
|
||||||
|
const action = isTrueBoolean(args?.state) ? 'enable' :
|
||||||
|
isFalseBoolean(args?.state) ? 'disable' :
|
||||||
|
'toggle';
|
||||||
|
|
||||||
|
return await getExtensionActionCallback(action)(args, extensionName);
|
||||||
|
},
|
||||||
|
namedArgumentList: [
|
||||||
|
SlashCommandNamedArgument.fromProps({
|
||||||
|
name: 'reload',
|
||||||
|
description: 'Whether to reload the page after toggling the extension',
|
||||||
|
typeList: [ARGUMENT_TYPE.BOOLEAN],
|
||||||
|
defaultValue: 'true',
|
||||||
|
enumList: commonEnumProviders.boolean('trueFalse')(),
|
||||||
|
}),
|
||||||
|
SlashCommandNamedArgument.fromProps({
|
||||||
|
name: 'state',
|
||||||
|
description: 'Explicitly set the state of the extension (true to enable, false to disable). If not provided, the state will be toggled to the opposite of the current state.',
|
||||||
|
typeList: [ARGUMENT_TYPE.BOOLEAN],
|
||||||
|
enumList: commonEnumProviders.boolean('trueFalse')(),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
unnamedArgumentList: [
|
||||||
|
SlashCommandArgument.fromProps({
|
||||||
|
description: 'Extension name',
|
||||||
|
typeList: [ARGUMENT_TYPE.STRING],
|
||||||
|
isRequired: true,
|
||||||
|
enumProvider: () => extensionNames.map(name => new SlashCommandEnumValue(name)),
|
||||||
|
forceEnum: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
helpString: `
|
||||||
|
<div>
|
||||||
|
Toggles the state of a specified extension.
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
By default, the page will be reloaded automatically, stopping any further commands.<br />
|
||||||
|
If <code>reload=false</code> named argument is passed, the page will not be reloaded, and the extension will stay in its current state until refreshed.
|
||||||
|
The page either needs to be refreshed, or <code>/reload-page</code> has to be called.
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Example:</strong>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<pre><code class="language-stscript">/extension-toggle Summarize</code></pre>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<pre><code class="language-stscript">/extension-toggle Summarize state=true</code></pre>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
}));
|
||||||
|
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: 'reload-page',
|
name: 'reload-page',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user