mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
#1090 Save Kobold/ooba servers history
This commit is contained in:
@@ -31,7 +31,7 @@ import {
|
||||
SECRET_KEYS,
|
||||
secret_state,
|
||||
} from "./secrets.js";
|
||||
import { debounce, delay, getStringHash, waitUntilCondition } from "./utils.js";
|
||||
import { debounce, delay, getStringHash, isUrlOrAPIKey, waitUntilCondition } from "./utils.js";
|
||||
import { chat_completion_sources, oai_settings } from "./openai.js";
|
||||
import { getTokenCount } from "./tokenizers.js";
|
||||
|
||||
@@ -403,15 +403,6 @@ function RA_autoconnect(PrevApi) {
|
||||
}
|
||||
}
|
||||
|
||||
function isUrlOrAPIKey(string) {
|
||||
try {
|
||||
new URL(string);
|
||||
return true;
|
||||
} catch (_) {
|
||||
// return pattern.test(string);
|
||||
}
|
||||
}
|
||||
|
||||
function OpenNavPanels() {
|
||||
const deviceInfo = getDeviceInfo();
|
||||
if (deviceInfo && deviceInfo.device.type === 'desktop') {
|
||||
|
@@ -201,6 +201,7 @@ let power_user = {
|
||||
fuzzy_search: false,
|
||||
encode_tags: false,
|
||||
lazy_load: 0,
|
||||
servers: [],
|
||||
};
|
||||
|
||||
let themes = [];
|
||||
|
86
public/scripts/server-history.js
Normal file
86
public/scripts/server-history.js
Normal file
@@ -0,0 +1,86 @@
|
||||
import { saveSettingsDebounced } from "../script.js";
|
||||
import { power_user } from "./power-user.js";
|
||||
import { isUrlOrAPIKey } from "./utils.js";
|
||||
|
||||
/**
|
||||
* @param {{ term: string; }} request
|
||||
* @param {function} resolve
|
||||
* @param {string} serverLabel
|
||||
*/
|
||||
function findServers(request, resolve, serverLabel) {
|
||||
if (!power_user.servers) {
|
||||
power_user.servers = [];
|
||||
}
|
||||
|
||||
const needle = request.term.toLowerCase();
|
||||
const result = power_user.servers.filter(x => x.label == serverLabel).sort((a, b) => b.lastConnection - a.lastConnection).map(x => x.url).slice(0, 5);
|
||||
const hasExactMatch = result.findIndex(x => x.toLowerCase() == needle) !== -1;
|
||||
|
||||
if (request.term && !hasExactMatch) {
|
||||
result.unshift(request.term);
|
||||
}
|
||||
|
||||
resolve(result);
|
||||
}
|
||||
|
||||
function selectServer(event, ui, serverLabel) {
|
||||
// unfocus the input
|
||||
$(event.target).val(ui.item.value).trigger('blur');
|
||||
|
||||
$('[data-server-connect]').each(function () {
|
||||
const serverLabels = String($(this).data('server-connect')).split(',');
|
||||
|
||||
if (serverLabels.includes(serverLabel)) {
|
||||
$(this).trigger('click');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createServerAutocomplete() {
|
||||
const inputElement = $(this);
|
||||
const serverLabel = inputElement.data('server-history');
|
||||
|
||||
inputElement
|
||||
.autocomplete({
|
||||
source: (i, o) => findServers(i, o, serverLabel),
|
||||
select: (e, u) => selectServer(e, u, serverLabel),
|
||||
minLength: 0,
|
||||
})
|
||||
.focus(onInputFocus); // <== show tag list on click
|
||||
}
|
||||
|
||||
function onInputFocus() {
|
||||
$(this).autocomplete('search', $(this).val());
|
||||
}
|
||||
|
||||
function onServerConnectClick() {
|
||||
const serverLabels = String($(this).data('server-connect')).split(',');
|
||||
|
||||
serverLabels.forEach(serverLabel => {
|
||||
if (!power_user.servers) {
|
||||
power_user.servers = [];
|
||||
}
|
||||
|
||||
const value = String($(`[data-server-history="${serverLabel}"]`).val()).toLowerCase().trim();
|
||||
|
||||
// Don't save empty values or invalid URLs
|
||||
if (!value || !isUrlOrAPIKey(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const server = power_user.servers.find(x => x.url === value && x.label === serverLabel);
|
||||
|
||||
if (!server) {
|
||||
power_user.servers.push({ label: serverLabel, url: value, lastConnection: Date.now() });
|
||||
} else {
|
||||
server.lastConnection = Date.now();
|
||||
}
|
||||
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
}
|
||||
|
||||
jQuery(function () {
|
||||
$('[data-server-history]').each(createServerAutocomplete);
|
||||
$(document).on('click', '[data-server-connect]', onServerConnectClick);
|
||||
});
|
@@ -18,6 +18,15 @@ export function escapeHtml(str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
||||
export function isUrlOrAPIKey(value) {
|
||||
try {
|
||||
new URL(value);
|
||||
return true;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a value is unique in an array.
|
||||
* @param {any} value Current value.
|
||||
@@ -850,7 +859,7 @@ export async function saveBase64AsFile(base64Data, characterName, filename = "",
|
||||
|
||||
/**
|
||||
* Loads either a CSS or JS file and appends it to the appropriate document section.
|
||||
*
|
||||
*
|
||||
* @param {string} url - The URL of the file to be loaded.
|
||||
* @param {string} type - The type of file to load: "css" or "js".
|
||||
* @returns {Promise} - Resolves when the file has loaded, rejects if there's an error or invalid type.
|
||||
|
Reference in New Issue
Block a user