Add command for switching profiles
| @@ -2,9 +2,15 @@ import { main_api, saveSettingsDebounced } from '../../../script.js'; | ||
| 2 | 2 | import { extension_settings, renderExtensionTemplateAsync } from '../../extensions.js'; |
| 3 | 3 | import { callGenericPopup, Popup, POPUP_TYPE } from '../../popup.js'; |
| 4 | 4 | import { executeSlashCommandsWithOptions } from '../../slash-commands.js'; |
| 5 | +import { SlashCommand } from '../../slash-commands/SlashCommand.js'; | |
| 6 | +import { SlashCommandArgument } from '../../slash-commands/SlashCommandArgument.js'; | |
| 7 | +import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; | |
| 8 | +import { enumTypes, SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js'; | |
| 9 | +import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; | |
| 5 | 10 | import { uuidv4 } from '../../utils.js'; |
| 6 | 11 | |
| 7 | 12 | const MODULE_NAME = 'connection-manager'; |
| 13 | +const NONE = '<None>'; | |
| 8 | 14 | |
| 9 | 15 | const DEFAULT_SETTINGS = { |
| 10 | 16 | profiles: [], |
| @@ -43,6 +49,12 @@ const FANCY_NAMES = { | ||
| 43 | 49 | 'tokenizer': 'Tokenizer', |
| 44 | 50 | }; |
| 45 | 51 | |
| 52 | +/** @type {() => SlashCommandEnumValue[]} */ | |
| 53 | +const 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 | 59 | * @typedef {Object} ConnectionProfile |
| 48 | 60 | * @property {string} id Unique identifier |
| @@ -209,7 +221,7 @@ function renderConnectionProfiles(profiles) { | ||
| 209 | 221 | const noneOption = document.createElement('option'); |
| 210 | 222 | |
| 211 | 223 | noneOption.value = ''; |
| 212 | 224 | noneOption.textContent = '<None>'NONE; |
| 213 | 225 | noneOption.selected = !extension_settings.connectionManager.selectedProfile; |
| 214 | 226 | profiles.appendChild(noneOption); |
| 215 | 227 | |
| @@ -333,4 +345,54 @@ async function renderDetailsContent(details, detailsContent) { | ||
| 333 | 345 | const details = document.getElementById('connection_profile_details'); |
| 334 | 346 | const detailsContent = document.getElementById('connection_profile_details_content'); |
| 335 | 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><None></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 | })(); |
| @@ -33,6 +33,7 @@ export const enumIcons = { | ||
| 33 | 33 | file: '📄', |
| 34 | 34 | message: '💬', |
| 35 | 35 | voice: '🎤', |
| 36 | + server: '🖥️', | |
| 36 | 37 | |
| 37 | 38 | true: '✔️', |
| 38 | 39 | false: '❌', |