Add command for switching profiles

bcac8c065b044028937d0482c7255989d00b8b45

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

2 files changed, +64 -1Showing whitespace changes
public/scripts/extensions/connection-manager/index.js+63 -1
@@ -2,9 +2,15 @@ import { main_api, saveSettingsDebounced } from '../../../script.js';
2import { extension_settings, renderExtensionTemplateAsync } from '../../extensions.js';2import { extension_settings, renderExtensionTemplateAsync } from '../../extensions.js';
3import { callGenericPopup, Popup, POPUP_TYPE } from '../../popup.js';3import { callGenericPopup, Popup, POPUP_TYPE } from '../../popup.js';
4import { executeSlashCommandsWithOptions } from '../../slash-commands.js';4import { executeSlashCommandsWithOptions } from '../../slash-commands.js';
5import { SlashCommand } from '../../slash-commands/SlashCommand.js';
6import { SlashCommandArgument } from '../../slash-commands/SlashCommandArgument.js';
7import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
8import { enumTypes, SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js';
9import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
5import { uuidv4 } from '../../utils.js';10import { uuidv4 } from '../../utils.js';
611
7const MODULE_NAME = 'connection-manager';12const MODULE_NAME = 'connection-manager';
13const NONE = '<None>';
814
9const DEFAULT_SETTINGS = {15const DEFAULT_SETTINGS = {
10 profiles: [],16 profiles: [],
@@ -43,6 +49,12 @@ const FANCY_NAMES = {
43 'tokenizer': 'Tokenizer',49 'tokenizer': 'Tokenizer',
44};50};
4551
52/** @type {() => SlashCommandEnumValue[]} */
53const profilesProvider = () => [
54 new SlashCommandEnumValue(NONE, NONE),
55 ...extension_settings.connectionManager.profiles.map(p => new SlashCommandEnumValue(p.name, p.name, enumTypes.name, enumIcons.server)),
56];
57
46/**58/**
47 * @typedef {Object} ConnectionProfile59 * @typedef {Object} ConnectionProfile
48 * @property {string} id Unique identifier60 * @property {string} id Unique identifier
@@ -209,7 +221,7 @@ function renderConnectionProfiles(profiles) {
209 const noneOption = document.createElement('option');221 const noneOption = document.createElement('option');
210222
211 noneOption.value = '';223 noneOption.value = '';
212 noneOption.textContent = '<None>';224 noneOption.textContent = NONE;
213 noneOption.selected = !extension_settings.connectionManager.selectedProfile;225 noneOption.selected = !extension_settings.connectionManager.selectedProfile;
214 profiles.appendChild(noneOption);226 profiles.appendChild(noneOption);
215227
@@ -333,4 +345,54 @@ async function renderDetailsContent(details, detailsContent) {
333 const details = document.getElementById('connection_profile_details');345 const details = document.getElementById('connection_profile_details');
334 const detailsContent = document.getElementById('connection_profile_details_content');346 const detailsContent = document.getElementById('connection_profile_details_content');
335 details.addEventListener('toggle', () => renderDetailsContent(details, detailsContent));347 details.addEventListener('toggle', () => renderDetailsContent(details, detailsContent));
348
349 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
350 name: 'profile',
351 helpString: 'Switch to a connection profile or return the name of the current profile in no argument is provided. Use <code>&lt;None&gt;</code> to switch to no profile.',
352 unnamedArgumentList: [
353 SlashCommandArgument.fromProps({
354 description: 'Name of the connection profile',
355 enumProvider: profilesProvider,
356 isRequired: false,
357 }),
358 ],
359 callback: async (_args, value) => {
360 if (!value || typeof value !== 'string') {
361 const selectedProfile = extension_settings.connectionManager.selectedProfile;
362 const profile = extension_settings.connectionManager.profiles.find(p => p.id === selectedProfile);
363 if (!profile) {
364 return NONE;
365 }
366 return profile.name;
367 }
368
369 if (value === NONE) {
370 profiles.selectedIndex = 0;
371 profiles.dispatchEvent(new Event('change'));
372 return NONE;
373 }
374
375 // Try to find exact match
376 const profile = extension_settings.connectionManager.profiles.find(p => p.name === value);
377
378 if (profile) {
379 profiles.selectedIndex = Array.from(profiles.options).findIndex(o => o.value === profile.id);
380 profiles.dispatchEvent(new Event('change'));
381 return profile.name;
382 }
383
384 // Try to find fuzzy match
385 const fuse = new Fuse(extension_settings.connectionManager.profiles, { keys: ['name'] });
386 const results = fuse.search(value);
387
388 if (results.length === 0) {
389 return '';
390 }
391
392 const bestMatch = results[0];
393 profiles.value = bestMatch.item.id;
394 profiles.dispatchEvent(new Event('change'));
395 return bestMatch.item.name;
396 },
397 }));
336})();398})();
public/scripts/slash-commands/SlashCommandCommonEnumsProvider.js+1 -0
@@ -33,6 +33,7 @@ export const enumIcons = {
33 file: 'πŸ“„',33 file: 'πŸ“„',
34 message: 'πŸ’¬',34 message: 'πŸ’¬',
35 voice: '🎀',35 voice: '🎀',
36 server: 'πŸ–₯️',
3637
37 true: 'βœ”οΈ',38 true: 'βœ”οΈ',
38 false: '❌',39 false: '❌',