Refactor findChar to utils
- Refactor and move finChar to utils, instead of slashcommands function - Refactor scrapers to use actual init functionality
This commit is contained in:
parent
edcf52e3a8
commit
d7bad6335c
|
@ -230,7 +230,7 @@ import { MacrosParser, evaluateMacros, getLastMessageId } from './scripts/macros
|
||||||
import { currentUser, setUserControls } from './scripts/user.js';
|
import { currentUser, setUserControls } from './scripts/user.js';
|
||||||
import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';
|
import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup, fixToastrForDialogs } from './scripts/popup.js';
|
||||||
import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';
|
import { renderTemplate, renderTemplateAsync } from './scripts/templates.js';
|
||||||
import { ScraperManager } from './scripts/scrapers.js';
|
import { initScrapers, ScraperManager } from './scripts/scrapers.js';
|
||||||
import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';
|
import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';
|
||||||
import { SlashCommand } from './scripts/slash-commands/SlashCommand.js';
|
import { SlashCommand } from './scripts/slash-commands/SlashCommand.js';
|
||||||
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './scripts/slash-commands/SlashCommandArgument.js';
|
import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './scripts/slash-commands/SlashCommandArgument.js';
|
||||||
|
@ -959,6 +959,7 @@ async function firstLoadInit() {
|
||||||
initCfg();
|
initCfg();
|
||||||
initLogprobs();
|
initLogprobs();
|
||||||
initInputMarkdown();
|
initInputMarkdown();
|
||||||
|
initScrapers();
|
||||||
doDailyExtensionUpdatesCheck();
|
doDailyExtensionUpdatesCheck();
|
||||||
await hideLoader();
|
await hideLoader();
|
||||||
await fixViewport();
|
await fixViewport();
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { callPopup, eventSource, event_types, generateRaw, getRequestHeaders, ma
|
||||||
import { dragElement, isMobile } from '../../RossAscends-mods.js';
|
import { dragElement, isMobile } from '../../RossAscends-mods.js';
|
||||||
import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch, renderExtensionTemplateAsync } from '../../extensions.js';
|
import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch, renderExtensionTemplateAsync } from '../../extensions.js';
|
||||||
import { loadMovingUIState, power_user } from '../../power-user.js';
|
import { loadMovingUIState, power_user } from '../../power-user.js';
|
||||||
import { onlyUnique, debounce, getCharaFilename, trimToEndSentence, trimToStartSentence, waitUntilCondition } from '../../utils.js';
|
import { onlyUnique, debounce, getCharaFilename, trimToEndSentence, trimToStartSentence, waitUntilCondition, findChar } from '../../utils.js';
|
||||||
import { hideMutedSprites } from '../../group-chats.js';
|
import { hideMutedSprites } from '../../group-chats.js';
|
||||||
import { isJsonSchemaSupported } from '../../textgen-settings.js';
|
import { isJsonSchemaSupported } from '../../textgen-settings.js';
|
||||||
import { debounce_timeout } from '../../constants.js';
|
import { debounce_timeout } from '../../constants.js';
|
||||||
|
@ -12,7 +12,6 @@ import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '
|
||||||
import { isFunctionCallingSupported } from '../../openai.js';
|
import { isFunctionCallingSupported } from '../../openai.js';
|
||||||
import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js';
|
||||||
import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
|
import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
import { findChar } from '../../slash-commands.js';
|
|
||||||
export { MODULE_NAME };
|
export { MODULE_NAME };
|
||||||
|
|
||||||
const MODULE_NAME = 'expressions';
|
const MODULE_NAME = 'expressions';
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { isValidUrl } from './utils.js';
|
||||||
* @property {string} description
|
* @property {string} description
|
||||||
* @property {string} iconClass
|
* @property {string} iconClass
|
||||||
* @property {boolean} iconAvailable
|
* @property {boolean} iconAvailable
|
||||||
|
* @property {() => Promise<void>} [init=null]
|
||||||
* @property {() => Promise<boolean>} isAvailable
|
* @property {() => Promise<boolean>} isAvailable
|
||||||
* @property {() => Promise<File[]>} scrape
|
* @property {() => Promise<File[]>} scrape
|
||||||
*/
|
*/
|
||||||
|
@ -42,6 +43,10 @@ export class ScraperManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scraper.init) {
|
||||||
|
scraper.init();
|
||||||
|
}
|
||||||
|
|
||||||
ScraperManager.#scrapers.push(scraper);
|
ScraperManager.#scrapers.push(scraper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,7 +467,9 @@ class YouTubeScraper {
|
||||||
this.description = 'Download a transcript from a YouTube video.';
|
this.description = 'Download a transcript from a YouTube video.';
|
||||||
this.iconClass = 'fa-brands fa-youtube';
|
this.iconClass = 'fa-brands fa-youtube';
|
||||||
this.iconAvailable = true;
|
this.iconAvailable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||||
name: 'yt-script',
|
name: 'yt-script',
|
||||||
callback: async (args, url) => {
|
callback: async (args, url) => {
|
||||||
|
@ -564,9 +571,11 @@ class YouTubeScraper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScraperManager.registerDataBankScraper(new FileScraper());
|
export function initScrapers() {
|
||||||
ScraperManager.registerDataBankScraper(new Notepad());
|
ScraperManager.registerDataBankScraper(new FileScraper());
|
||||||
ScraperManager.registerDataBankScraper(new WebScraper());
|
ScraperManager.registerDataBankScraper(new Notepad());
|
||||||
ScraperManager.registerDataBankScraper(new MediaWikiScraper());
|
ScraperManager.registerDataBankScraper(new WebScraper());
|
||||||
ScraperManager.registerDataBankScraper(new FandomScraper());
|
ScraperManager.registerDataBankScraper(new MediaWikiScraper());
|
||||||
ScraperManager.registerDataBankScraper(new YouTubeScraper());
|
ScraperManager.registerDataBankScraper(new FandomScraper());
|
||||||
|
ScraperManager.registerDataBankScraper(new YouTubeScraper());
|
||||||
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockStat
|
||||||
import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';
|
import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';
|
||||||
import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js';
|
import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js';
|
||||||
import { decodeTextTokens, getAvailableTokenizers, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync, selectTokenizer } from './tokenizers.js';
|
import { decodeTextTokens, getAvailableTokenizers, getFriendlyTokenizerName, getTextTokens, getTokenCountAsync, selectTokenizer } from './tokenizers.js';
|
||||||
import { debounce, delay, equalsIgnoreCaseAndAccents, isFalseBoolean, isTrueBoolean, showFontAwesomePicker, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js';
|
import { debounce, delay, equalsIgnoreCaseAndAccents, findChar, isFalseBoolean, isTrueBoolean, showFontAwesomePicker, stringToRange, trimToEndSentence, trimToStartSentence, waitUntilCondition } from './utils.js';
|
||||||
import { registerVariableCommands, resolveVariable } from './variables.js';
|
import { registerVariableCommands, resolveVariable } from './variables.js';
|
||||||
import { background_settings } from './backgrounds.js';
|
import { background_settings } from './backgrounds.js';
|
||||||
import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js';
|
import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js';
|
||||||
|
@ -68,10 +68,8 @@ import { SlashCommandNamedArgumentAssignment } from './slash-commands/SlashComma
|
||||||
import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js';
|
import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandEnumValue.js';
|
||||||
import { POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
|
import { POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
|
||||||
import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
import { SlashCommandDebugController } from './slash-commands/SlashCommandDebugController.js';
|
|
||||||
import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js';
|
import { SlashCommandBreakController } from './slash-commands/SlashCommandBreakController.js';
|
||||||
import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js';
|
import { SlashCommandExecutionError } from './slash-commands/SlashCommandExecutionError.js';
|
||||||
import { getTagsList } from './tags.js';
|
|
||||||
export {
|
export {
|
||||||
executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand,
|
executeSlashCommands, executeSlashCommandsWithOptions, getSlashCommandsHelp, registerSlashCommand,
|
||||||
};
|
};
|
||||||
|
@ -2969,29 +2967,6 @@ async function deleteMessagesByNameCallback(_, name) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function findCharacterIndex(name) {
|
|
||||||
const matchTypes = [
|
|
||||||
(a, b) => a === b,
|
|
||||||
(a, b) => a.startsWith(b),
|
|
||||||
(a, b) => a.includes(b),
|
|
||||||
];
|
|
||||||
|
|
||||||
const exactAvatarMatch = characters.findIndex(x => x.avatar === name);
|
|
||||||
|
|
||||||
if (exactAvatarMatch !== -1) {
|
|
||||||
return exactAvatarMatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const matchType of matchTypes) {
|
|
||||||
const index = characters.findIndex(x => matchType(x.name.toLowerCase(), name.toLowerCase()));
|
|
||||||
if (index !== -1) {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function goToCharacterCallback(_, name) {
|
async function goToCharacterCallback(_, name) {
|
||||||
if (!name) {
|
if (!name) {
|
||||||
console.warn('WARN: No character name provided for /go command');
|
console.warn('WARN: No character name provided for /go command');
|
||||||
|
@ -3238,77 +3213,6 @@ export function getNameAndAvatarForMessage(character, name = null) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds a character by name, with optional filtering and precedence for avatars
|
|
||||||
* @param {object} [options={}] - The options for the search
|
|
||||||
* @param {string?} [options.name=null] - The name to search for
|
|
||||||
* @param {boolean} [options.allowAvatar=true] - Whether to allow searching by avatar
|
|
||||||
* @param {boolean} [options.insensitive=true] - Whether the search should be case insensitive
|
|
||||||
* @param {string[]?} [options.filteredByTags=null] - Tags to filter characters by
|
|
||||||
* @param {boolean} [options.preferCurrentChar=true] - Whether to prefer the current character(s)
|
|
||||||
* @param {boolean} [options.quiet=false] - Whether to suppress warnings
|
|
||||||
* @returns {any?} - The found character or null if not found
|
|
||||||
*/
|
|
||||||
export function findChar({ name = null, allowAvatar = true, insensitive = true, filteredByTags = null, preferCurrentChar = true, quiet = false } = {}) {
|
|
||||||
const matches = (char) => (allowAvatar && char.avatar === name) || (insensitive ? equalsIgnoreCaseAndAccents(char.name, name) : char.name === name);
|
|
||||||
|
|
||||||
// Filter characters by tags if provided
|
|
||||||
let filteredCharacters = characters;
|
|
||||||
if (filteredByTags) {
|
|
||||||
filteredCharacters = characters.filter(char => {
|
|
||||||
const charTags = getTagsList(char.avatar, false);
|
|
||||||
return filteredByTags.every(tagName => charTags.some(x => x.name == tagName));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the current character(s)
|
|
||||||
/** @type {any[]} */
|
|
||||||
const currentChars = selected_group ? groups.find(group => group.id === selected_group)?.members.map(member => filteredCharacters.find(char => char.avatar === member))
|
|
||||||
: [filteredCharacters.find(char => characters[this_chid]?.avatar === char.avatar)];
|
|
||||||
|
|
||||||
// If we have a current char and prefer it, return that if it matches
|
|
||||||
if (preferCurrentChar) {
|
|
||||||
const preferredCharSearch = currentChars.filter(matches);
|
|
||||||
if (preferredCharSearch.length > 1) {
|
|
||||||
if (!quiet) toastr.warning(`Multiple characters found for name "${name}" and given conditions.`);
|
|
||||||
else console.warn(`Multiple characters found for name "${name}". Returning the first match.`);
|
|
||||||
}
|
|
||||||
if (preferredCharSearch.length) {
|
|
||||||
return preferredCharSearch[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If allowAvatar is true, search by avatar first
|
|
||||||
if (allowAvatar && name) {
|
|
||||||
const characterByAvatar = filteredCharacters.find(char => char.avatar === name);
|
|
||||||
if (characterByAvatar) {
|
|
||||||
return characterByAvatar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for matching characters by name
|
|
||||||
const matchingCharacters = name ? filteredCharacters.filter(matches) : filteredCharacters;
|
|
||||||
if (matchingCharacters.length > 1) {
|
|
||||||
if (!quiet) toastr.warning(`Multiple characters found for name "${name}" and given conditions.`);
|
|
||||||
else console.warn(`Multiple characters found for name "${name}". Returning the first match.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchingCharacters[0] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the index of a character based on the character object
|
|
||||||
* @param {object} char - The character object to find the index for
|
|
||||||
* @throws {Error} If the character is not found
|
|
||||||
* @returns {number} The index of the character in the characters array
|
|
||||||
*/
|
|
||||||
export function getCharIndex(char) {
|
|
||||||
if (!char) throw new Error('Character is undefined');
|
|
||||||
const index = characters.findIndex(c => c.avatar === char.avatar);
|
|
||||||
if (index === -1) throw new Error(`Character not found: ${char.avatar}`);
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function sendMessageAs(args, text) {
|
export async function sendMessageAs(args, text) {
|
||||||
if (!text) {
|
if (!text) {
|
||||||
return '';
|
return '';
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
import { FILTER_TYPES, FILTER_STATES, DEFAULT_FILTER_STATE, isFilterState, FilterHelper } from './filters.js';
|
import { FILTER_TYPES, FILTER_STATES, DEFAULT_FILTER_STATE, isFilterState, FilterHelper } from './filters.js';
|
||||||
|
|
||||||
import { groupCandidatesFilter, groups, selected_group } from './group-chats.js';
|
import { groupCandidatesFilter, groups, selected_group } from './group-chats.js';
|
||||||
import { download, onlyUnique, parseJsonFile, uuidv4, getSortableDelay, flashHighlight, equalsIgnoreCaseAndAccents, includesIgnoreCaseAndAccents, removeFromArray, getFreeName, debounce } from './utils.js';
|
import { download, onlyUnique, parseJsonFile, uuidv4, getSortableDelay, flashHighlight, equalsIgnoreCaseAndAccents, includesIgnoreCaseAndAccents, removeFromArray, getFreeName, debounce, findChar } from './utils.js';
|
||||||
import { power_user } from './power-user.js';
|
import { power_user } from './power-user.js';
|
||||||
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
|
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
|
||||||
import { SlashCommand } from './slash-commands/SlashCommand.js';
|
import { SlashCommand } from './slash-commands/SlashCommand.js';
|
||||||
|
@ -26,7 +26,6 @@ import { debounce_timeout } from './constants.js';
|
||||||
import { INTERACTABLE_CONTROL_CLASS } from './keyboard.js';
|
import { INTERACTABLE_CONTROL_CLASS } from './keyboard.js';
|
||||||
import { commonEnumProviders } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
import { commonEnumProviders } from './slash-commands/SlashCommandCommonEnumsProvider.js';
|
||||||
import { renderTemplateAsync } from './templates.js';
|
import { renderTemplateAsync } from './templates.js';
|
||||||
import { findChar } from './slash-commands.js';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
TAG_FOLDER_TYPES,
|
TAG_FOLDER_TYPES,
|
||||||
|
@ -51,7 +50,6 @@ export {
|
||||||
removeTagFromMap,
|
removeTagFromMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @typedef {import('../scripts/popup.js').Popup} Popup */
|
|
||||||
/** @typedef {import('../script.js').Character} Character */
|
/** @typedef {import('../script.js').Character} Character */
|
||||||
|
|
||||||
const CHARACTER_FILTER_SELECTOR = '#rm_characters_block .rm_tag_filter';
|
const CHARACTER_FILTER_SELECTOR = '#rm_characters_block .rm_tag_filter';
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import { getContext } from './extensions.js';
|
import { getContext } from './extensions.js';
|
||||||
import { getRequestHeaders } from '../script.js';
|
import { characters, getRequestHeaders, this_chid } from '../script.js';
|
||||||
import { isMobile } from './RossAscends-mods.js';
|
import { isMobile } from './RossAscends-mods.js';
|
||||||
import { collapseNewlines } from './power-user.js';
|
import { collapseNewlines } from './power-user.js';
|
||||||
import { debounce_timeout } from './constants.js';
|
import { debounce_timeout } from './constants.js';
|
||||||
import { Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js';
|
import { Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js';
|
||||||
import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js';
|
import { SlashCommandClosure } from './slash-commands/SlashCommandClosure.js';
|
||||||
|
import { getTagsList } from './tags.js';
|
||||||
|
import { groups, selected_group } from './group-chats.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pagination status string template.
|
* Pagination status string template.
|
||||||
|
@ -2110,3 +2112,74 @@ export async function showFontAwesomePicker(customList = null) {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a character by name, with optional filtering and precedence for avatars
|
||||||
|
* @param {object} [options={}] - The options for the search
|
||||||
|
* @param {string?} [options.name=null] - The name to search for
|
||||||
|
* @param {boolean} [options.allowAvatar=true] - Whether to allow searching by avatar
|
||||||
|
* @param {boolean} [options.insensitive=true] - Whether the search should be case insensitive
|
||||||
|
* @param {string[]?} [options.filteredByTags=null] - Tags to filter characters by
|
||||||
|
* @param {boolean} [options.preferCurrentChar=true] - Whether to prefer the current character(s)
|
||||||
|
* @param {boolean} [options.quiet=false] - Whether to suppress warnings
|
||||||
|
* @returns {any?} - The found character or null if not found
|
||||||
|
*/
|
||||||
|
export function findChar({ name = null, allowAvatar = true, insensitive = true, filteredByTags = null, preferCurrentChar = true, quiet = false } = {}) {
|
||||||
|
const matches = (char) => (allowAvatar && char.avatar === name) || (insensitive ? equalsIgnoreCaseAndAccents(char.name, name) : char.name === name);
|
||||||
|
|
||||||
|
// Filter characters by tags if provided
|
||||||
|
let filteredCharacters = characters;
|
||||||
|
if (filteredByTags) {
|
||||||
|
filteredCharacters = characters.filter(char => {
|
||||||
|
const charTags = getTagsList(char.avatar, false);
|
||||||
|
return filteredByTags.every(tagName => charTags.some(x => x.name == tagName));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current character(s)
|
||||||
|
/** @type {any[]} */
|
||||||
|
const currentChars = selected_group ? groups.find(group => group.id === selected_group)?.members.map(member => filteredCharacters.find(char => char.avatar === member))
|
||||||
|
: [filteredCharacters.find(char => characters[this_chid]?.avatar === char.avatar)];
|
||||||
|
|
||||||
|
// If we have a current char and prefer it, return that if it matches
|
||||||
|
if (preferCurrentChar) {
|
||||||
|
const preferredCharSearch = currentChars.filter(matches);
|
||||||
|
if (preferredCharSearch.length > 1) {
|
||||||
|
if (!quiet) toastr.warning(`Multiple characters found for name "${name}" and given conditions.`);
|
||||||
|
else console.warn(`Multiple characters found for name "${name}". Returning the first match.`);
|
||||||
|
}
|
||||||
|
if (preferredCharSearch.length) {
|
||||||
|
return preferredCharSearch[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If allowAvatar is true, search by avatar first
|
||||||
|
if (allowAvatar && name) {
|
||||||
|
const characterByAvatar = filteredCharacters.find(char => char.avatar === name);
|
||||||
|
if (characterByAvatar) {
|
||||||
|
return characterByAvatar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for matching characters by name
|
||||||
|
const matchingCharacters = name ? filteredCharacters.filter(matches) : filteredCharacters;
|
||||||
|
if (matchingCharacters.length > 1) {
|
||||||
|
if (!quiet) toastr.warning(`Multiple characters found for name "${name}" and given conditions.`);
|
||||||
|
else console.warn(`Multiple characters found for name "${name}". Returning the first match.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchingCharacters[0] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index of a character based on the character object
|
||||||
|
* @param {object} char - The character object to find the index for
|
||||||
|
* @throws {Error} If the character is not found
|
||||||
|
* @returns {number} The index of the character in the characters array
|
||||||
|
*/
|
||||||
|
export function getCharIndex(char) {
|
||||||
|
if (!char) throw new Error('Character is undefined');
|
||||||
|
const index = characters.findIndex(c => c.avatar === char.avatar);
|
||||||
|
if (index === -1) throw new Error(`Character not found: ${char.avatar}`);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue