mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Autocomplete for WI automation IDs
This commit is contained in:
@@ -6,6 +6,7 @@ import { QuickReplySet } from '../src/QuickReplySet.js';
|
|||||||
import { QuickReplySettings } from '../src/QuickReplySettings.js';
|
import { QuickReplySettings } from '../src/QuickReplySettings.js';
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
import { SettingsUi } from '../src/ui/SettingsUi.js';
|
import { SettingsUi } from '../src/ui/SettingsUi.js';
|
||||||
|
import { onlyUnique } from '../../../utils.js';
|
||||||
|
|
||||||
export class QuickReplyApi {
|
export class QuickReplyApi {
|
||||||
/**@type {QuickReplySettings}*/ settings;
|
/**@type {QuickReplySettings}*/ settings;
|
||||||
@@ -460,4 +461,20 @@ export class QuickReplyApi {
|
|||||||
}
|
}
|
||||||
return set.qrList.map(it=>it.label);
|
return set.qrList.map(it=>it.label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of all Automation IDs used by quick replies.
|
||||||
|
*
|
||||||
|
* @returns {String[]} array with all automation IDs used by quick replies
|
||||||
|
*/
|
||||||
|
listAutomationIds() {
|
||||||
|
return this
|
||||||
|
.listSets()
|
||||||
|
.flatMap(it => ({ set: it, qrs: this.listQuickReplies(it) }))
|
||||||
|
.map(it => it.qrs?.map(qr => this.getQrByLabel(it.set, qr)?.automationId))
|
||||||
|
.flat()
|
||||||
|
.filter(Boolean)
|
||||||
|
.filter(onlyUnique)
|
||||||
|
.map(String);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -200,6 +200,8 @@ const init = async () => {
|
|||||||
autoExec = new AutoExecuteHandler(settings);
|
autoExec = new AutoExecuteHandler(settings);
|
||||||
|
|
||||||
eventSource.on(event_types.APP_READY, async()=>await finalizeInit());
|
eventSource.on(event_types.APP_READY, async()=>await finalizeInit());
|
||||||
|
|
||||||
|
window['quickReplyApi'] = quickReplyApi;
|
||||||
};
|
};
|
||||||
const finalizeInit = async () => {
|
const finalizeInit = async () => {
|
||||||
log('executing startup');
|
log('executing startup');
|
||||||
|
@@ -1286,7 +1286,7 @@ function getWorldEntry(name, data, entry) {
|
|||||||
saveWorldInfo(name, data);
|
saveWorldInfo(name, data);
|
||||||
});
|
});
|
||||||
groupInput.val(entry.group ?? '').trigger('input');
|
groupInput.val(entry.group ?? '').trigger('input');
|
||||||
setTimeout(() => createInclusionGroupAutocomplete(groupInput, data), 1);
|
setTimeout(() => createEntryInputAutocomplete(groupInput, getInclusionGroupCallback(data)), 1);
|
||||||
|
|
||||||
// probability
|
// probability
|
||||||
if (entry.probability === undefined) {
|
if (entry.probability === undefined) {
|
||||||
@@ -1586,6 +1586,7 @@ function getWorldEntry(name, data, entry) {
|
|||||||
saveWorldInfo(name, data);
|
saveWorldInfo(name, data);
|
||||||
});
|
});
|
||||||
automationIdInput.val(entry.automationId ?? '').trigger('input');
|
automationIdInput.val(entry.automationId ?? '').trigger('input');
|
||||||
|
setTimeout(() => createEntryInputAutocomplete(automationIdInput, getAutomationIdCallback(data)), 1);
|
||||||
|
|
||||||
template.find('.inline-drawer-content').css('display', 'none'); //entries start collapsed
|
template.find('.inline-drawer-content').css('display', 'none'); //entries start collapsed
|
||||||
|
|
||||||
@@ -1617,12 +1618,12 @@ function getWorldEntry(name, data, entry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an autocomplete for the inclusion group.
|
* Get the inclusion groups for the autocomplete.
|
||||||
* @param {JQuery<HTMLElement>} input Input element to attach the autocomplete to
|
|
||||||
* @param {any} data WI data
|
* @param {any} data WI data
|
||||||
|
* @returns {(input: any, output: any) => any} Callback function for the autocomplete
|
||||||
*/
|
*/
|
||||||
function createInclusionGroupAutocomplete(input, data) {
|
function getInclusionGroupCallback(data) {
|
||||||
function getGroups(input, output) {
|
return function(input, output) {
|
||||||
const groups = new Set();
|
const groups = new Set();
|
||||||
for (const entry of Object.values(data.entries)) {
|
for (const entry of Object.values(data.entries)) {
|
||||||
if (entry.group) {
|
if (entry.group) {
|
||||||
@@ -1641,17 +1642,54 @@ function createInclusionGroupAutocomplete(input, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
output(result);
|
output(result);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAutomationIdCallback(data) {
|
||||||
|
return function(input, output) {
|
||||||
|
const ids = new Set();
|
||||||
|
for (const entry of Object.values(data.entries)) {
|
||||||
|
if (entry.automationId) {
|
||||||
|
ids.add(String(entry.automationId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('quickReplyApi' in window) {
|
||||||
|
// @ts-ignore
|
||||||
|
for (const automationId of window['quickReplyApi'].listAutomationIds()) {
|
||||||
|
ids.add(String(automationId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const haystack = Array.from(ids);
|
||||||
|
haystack.sort((a, b) => a.localeCompare(b));
|
||||||
|
const needle = input.term.toLowerCase();
|
||||||
|
const hasExactMatch = haystack.findIndex(x => x.toLowerCase() == needle) !== -1;
|
||||||
|
const result = haystack.filter(x => x.toLowerCase().includes(needle));
|
||||||
|
|
||||||
|
if (input.term && !hasExactMatch) {
|
||||||
|
result.unshift(input.term);
|
||||||
|
}
|
||||||
|
|
||||||
|
output(result);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an autocomplete for the inclusion group.
|
||||||
|
* @param {JQuery<HTMLElement>} input Input element to attach the autocomplete to
|
||||||
|
* @param {(input: any, output: any) => any} callback Source data callbacks
|
||||||
|
*/
|
||||||
|
function createEntryInputAutocomplete(input, callback) {
|
||||||
$(input).autocomplete({
|
$(input).autocomplete({
|
||||||
minLength: 0,
|
minLength: 0,
|
||||||
source: getGroups,
|
source: callback,
|
||||||
select: function (event, ui) {
|
select: function (event, ui) {
|
||||||
$(input).val(ui.item.value).trigger('input').trigger('blur');
|
$(input).val(ui.item.value).trigger('input').trigger('blur');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
$(input).on('focus', function () {
|
$(input).on('focus click', function () {
|
||||||
$(input).autocomplete('search', String($(input).val()));
|
$(input).autocomplete('search', String($(input).val()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2886,7 +2924,7 @@ jQuery(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$('#WorldInfo').on('scroll', () => {
|
$('#WorldInfo').on('scroll', () => {
|
||||||
$('.world_entry input[name="group"]').each((_, el) => {
|
$('.world_entry input[name="group"], .world_entry input[name="automationId"]').each((_, el) => {
|
||||||
const instance = $(el).autocomplete('instance');
|
const instance = $(el).autocomplete('instance');
|
||||||
|
|
||||||
if (instance !== undefined) {
|
if (instance !== undefined) {
|
||||||
|
Reference in New Issue
Block a user