Add command for switching profiles
| @@ -2,9 +2,15 @@ import { main_api, saveSettingsDebounced } from '../../../script.js'; | |||
| 2 | import { extension_settings, renderExtensionTemplateAsync } from '../../extensions.js'; | 2 | import { extension_settings, renderExtensionTemplateAsync } from '../../extensions.js'; |
| 3 | import { callGenericPopup, Popup, POPUP_TYPE } from '../../popup.js'; | 3 | import { callGenericPopup, Popup, POPUP_TYPE } from '../../popup.js'; |
| 4 | import { executeSlashCommandsWithOptions } from '../../slash-commands.js'; | 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 | import { uuidv4 } from '../../utils.js'; | 10 | import { uuidv4 } from '../../utils.js'; |
| 6 | 11 | ||
| 7 | const MODULE_NAME = 'connection-manager'; | 12 | const MODULE_NAME = 'connection-manager'; |
| 13 | const NONE = '<None>'; | ||
| 8 | 14 | ||
| 9 | const DEFAULT_SETTINGS = { | 15 | const DEFAULT_SETTINGS = { |
| 10 | profiles: [], | 16 | profiles: [], |
| @@ -43,6 +49,12 @@ const FANCY_NAMES = { | |||
| 43 | 'tokenizer': 'Tokenizer', | 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 | * @typedef {Object} ConnectionProfile | 59 | * @typedef {Object} ConnectionProfile |
| 48 | * @property {string} id Unique identifier | 60 | * @property {string} id Unique identifier |
| @@ -209,7 +221,7 @@ function renderConnectionProfiles(profiles) { | |||
| 209 | const noneOption = document.createElement('option'); | 221 | const noneOption = document.createElement('option'); |
| 210 | 222 | ||
| 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); |
| 215 | 227 | ||
| @@ -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><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 | file: 'π', | 33 | file: 'π', |
| 34 | message: 'π¬', | 34 | message: 'π¬', |
| 35 | voice: 'π€', | 35 | voice: 'π€', |
| 36 | server: 'π₯οΈ', | ||
| 36 | 37 | ||
| 37 | true: 'βοΈ', | 38 | true: 'βοΈ', |
| 38 | false: 'β', | 39 | false: 'β', |