Merge pull request #1543 from valadaptive/bg-load-improvements

Set background client-side
This commit is contained in:
Cohee 2023-12-15 18:12:51 +02:00 committed by GitHub
commit 7e3c150524
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 69 additions and 58 deletions

View File

@ -31,10 +31,9 @@ RUN \
echo "*** Create symbolic links to config directory ***" && \ echo "*** Create symbolic links to config directory ***" && \
for R in $RESOURCES; do ln -s "../config/$R" "public/$R"; done || true && \ for R in $RESOURCES; do ln -s "../config/$R" "public/$R"; done || true && \
\ \
rm -f "config.yaml" "public/settings.json" "public/css/bg_load.css" || true && \ rm -f "config.yaml" "public/settings.json" || true && \
ln -s "./config/config.yaml" "config.yaml" || true && \ ln -s "./config/config.yaml" "config.yaml" || true && \
ln -s "../config/settings.json" "public/settings.json" || true && \ ln -s "../config/settings.json" "public/settings.json" || true && \
ln -s "../../config/bg_load.css" "public/css/bg_load.css" || true && \
mkdir "config" || true mkdir "config" || true
# Cleanup unnecessary files # Cleanup unnecessary files

View File

@ -1 +0,0 @@
#bg1 {background-image: url(../backgrounds/__transparent.png);}

View File

@ -19,11 +19,6 @@ if [ ! -e "config/settings.json" ]; then
cp -r "default/settings.json" "config/settings.json" cp -r "default/settings.json" "config/settings.json"
fi fi
if [ ! -e "config/bg_load.css" ]; then
echo "Resource not found, copying from defaults: bg_load.css"
cp -r "default/bg_load.css" "config/bg_load.css"
fi
CONFIG_FILE="config.yaml" CONFIG_FILE="config.yaml"
echo "Starting with the following config:" echo "Starting with the following config:"

View File

@ -107,7 +107,6 @@ function addMissingConfigValues() {
function createDefaultFiles() { function createDefaultFiles() {
const files = { const files = {
settings: './public/settings.json', settings: './public/settings.json',
bg_load: './public/css/bg_load.css',
config: './config.yaml', config: './config.yaml',
user: './public/css/user.css', user: './public/css/user.css',
}; };
@ -168,6 +167,29 @@ function copyWasmFiles() {
} }
} }
/**
* Moves the custom background into settings.json.
*/
function migrateBackground() {
if (!fs.existsSync('./public/css/bg_load.css')) return;
const bgCSS = fs.readFileSync('./public/css/bg_load.css', 'utf-8');
const bgMatch = /url\('([^']*)'\)/.exec(bgCSS);
if (!bgMatch) return;
const bgFilename = bgMatch[1].replace('../backgrounds/', '');
const settings = fs.readFileSync('./public/settings.json', 'utf-8');
const settingsJSON = JSON.parse(settings);
if (Object.hasOwn(settingsJSON, 'background')) {
console.log(color.yellow('Both bg_load.css and the "background" setting exist. Please delete bg_load.css manually.'));
return;
}
settingsJSON.background = { name: bgFilename, url: `url('backgrounds/${bgFilename}')` };
fs.writeFileSync('./public/settings.json', JSON.stringify(settingsJSON, null, 4));
fs.rmSync('./public/css/bg_load.css');
}
try { try {
// 0. Convert config.conf to config.yaml // 0. Convert config.conf to config.yaml
convertConfig(); convertConfig();
@ -177,6 +199,8 @@ try {
copyWasmFiles(); copyWasmFiles();
// 3. Add missing config values // 3. Add missing config values
addMissingConfigValues(); addMissingConfigValues();
// 4. Migrate bg_load.css to settings.json
migrateBackground();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} }

View File

@ -1,4 +1,4 @@
#loader { #loader, #preloader {
position: fixed; position: fixed;
margin: 0; margin: 0;
padding: 0; padding: 0;

View File

@ -61,7 +61,6 @@
<link rel="stylesheet" type="text/css" href="css/extensions-panel.css"> <link rel="stylesheet" type="text/css" href="css/extensions-panel.css">
<link rel="stylesheet" type="text/css" href="css/select2-overrides.css"> <link rel="stylesheet" type="text/css" href="css/select2-overrides.css">
<link rel="stylesheet" type="text/css" href="css/mobile-styles.css"> <link rel="stylesheet" type="text/css" href="css/mobile-styles.css">
<link rel="stylesheet" href="css/bg_load.css">
<link rel="stylesheet" type="text/css" href="css/user.css"> <link rel="stylesheet" type="text/css" href="css/user.css">
<link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="icon" type="image/x-icon" href="favicon.ico">
<script type="module" src="scripts/i18n.js"></script> <script type="module" src="scripts/i18n.js"></script>
@ -91,6 +90,7 @@
</head> </head>
<body class="no-blur"> <body class="no-blur">
<div id="preloader"></div>
<div id="bg_custom"></div> <div id="bg_custom"></div>
<div id="bg1"></div> <div id="bg1"></div>
<div id="character_context_menu" class="hidden"> <div id="character_context_menu" class="hidden">

View File

@ -186,7 +186,7 @@ import {
import { applyLocale, initLocales } from './scripts/i18n.js'; import { applyLocale, initLocales } from './scripts/i18n.js';
import { getFriendlyTokenizerName, getTokenCount, getTokenizerModel, initTokenizers, saveTokenCache } from './scripts/tokenizers.js'; import { getFriendlyTokenizerName, getTokenCount, getTokenizerModel, initTokenizers, saveTokenCache } from './scripts/tokenizers.js';
import { createPersona, initPersonas, selectCurrentPersona, setPersonaDescription } from './scripts/personas.js'; import { createPersona, initPersonas, selectCurrentPersona, setPersonaDescription } from './scripts/personas.js';
import { getBackgrounds, initBackgrounds } from './scripts/backgrounds.js'; import { getBackgrounds, initBackgrounds, loadBackgroundSettings, background_settings } from './scripts/backgrounds.js';
import { hideLoader, showLoader } from './scripts/loader.js'; import { hideLoader, showLoader } from './scripts/loader.js';
import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay.js'; import { BulkEditOverlay, CharacterContextMenu } from './scripts/BulkEditOverlay.js';
import { loadMancerModels } from './scripts/mancer-settings.js'; import { loadMancerModels } from './scripts/mancer-settings.js';
@ -265,8 +265,9 @@ export {
countOccurrences, countOccurrences,
}; };
// Cohee: Uncomment when we decide to use loader
showLoader(); showLoader();
// Yoink preloader entirely; it only exists to cover up unstyled content while loading JS
document.getElementById('preloader').remove();
// Allow target="_blank" in links // Allow target="_blank" in links
DOMPurify.addHook('afterSanitizeAttributes', function (node) { DOMPurify.addHook('afterSanitizeAttributes', function (node) {
@ -5672,6 +5673,9 @@ async function getSettings() {
// Load character tags // Load character tags
loadTagsSettings(settings); loadTagsSettings(settings);
// Load background
loadBackgroundSettings(settings);
// Allow subscribers to mutate settings // Allow subscribers to mutate settings
eventSource.emit(event_types.SETTINGS_LOADED_AFTER, settings); eventSource.emit(event_types.SETTINGS_LOADED_AFTER, settings);
@ -5754,6 +5758,9 @@ async function saveSettings(type) {
console.warn('Settings not ready, aborting save'); console.warn('Settings not ready, aborting save');
return; return;
} }
console.log(background_settings);
//console.log('Entering settings with name1 = '+name1); //console.log('Entering settings with name1 = '+name1);
return jQuery.ajax({ return jQuery.ajax({
@ -5783,6 +5790,7 @@ async function saveSettings(type) {
nai_settings: nai_settings, nai_settings: nai_settings,
kai_settings: kai_settings, kai_settings: kai_settings,
oai_settings: oai_settings, oai_settings: oai_settings,
background: background_settings,
}, null, 4), }, null, 4),
beforeSend: function () { }, beforeSend: function () { },
cache: false, cache: false,

View File

@ -1,4 +1,4 @@
import { callPopup, chat_metadata, eventSource, event_types, generateQuietPrompt, getCurrentChatId, getRequestHeaders, getThumbnailUrl } from '../script.js'; import { callPopup, chat_metadata, eventSource, event_types, generateQuietPrompt, getCurrentChatId, getRequestHeaders, getThumbnailUrl, saveSettingsDebounced } from '../script.js';
import { saveMetadataDebounced } from './extensions.js'; import { saveMetadataDebounced } from './extensions.js';
import { registerSlashCommand } from './slash-commands.js'; import { registerSlashCommand } from './slash-commands.js';
import { stringFormat } from './utils.js'; import { stringFormat } from './utils.js';
@ -6,6 +6,19 @@ import { stringFormat } from './utils.js';
const BG_METADATA_KEY = 'custom_background'; const BG_METADATA_KEY = 'custom_background';
const LIST_METADATA_KEY = 'chat_backgrounds'; const LIST_METADATA_KEY = 'chat_backgrounds';
export let background_settings = {
name: '__transparent.png',
url: generateUrlParameter('__transparent.png', false),
};
export function loadBackgroundSettings(settings) {
let backgroundSettings = settings.background;
if (!backgroundSettings || !backgroundSettings.name || !backgroundSettings.url) {
backgroundSettings = background_settings;
}
setBackground(backgroundSettings.name, backgroundSettings.url);
}
/** /**
* Sets the background for the current chat and adds it to the list of custom backgrounds. * Sets the background for the current chat and adds it to the list of custom backgrounds.
* @param {{url: string, path:string}} backgroundInfo * @param {{url: string, path:string}} backgroundInfo
@ -141,9 +154,8 @@ function onSelectBackgroundClick() {
saveBackgroundMetadata(relativeBgImage); saveBackgroundMetadata(relativeBgImage);
setCustomBackground(); setCustomBackground();
highlightLockedBackground(); highlightLockedBackground();
} else {
highlightLockedBackground();
} }
highlightLockedBackground();
const customBg = window.getComputedStyle(document.getElementById('bg_custom')).backgroundImage; const customBg = window.getComputedStyle(document.getElementById('bg_custom')).backgroundImage;
@ -157,8 +169,7 @@ function onSelectBackgroundClick() {
// Fetching to browser memory to reduce flicker // Fetching to browser memory to reduce flicker
fetch(backgroundUrl).then(() => { fetch(backgroundUrl).then(() => {
$('#bg1').css('background-image', relativeBgImage); setBackground(bgFile, relativeBgImage);
setBackground(bgFile);
}).catch(() => { }).catch(() => {
console.log('Background could not be set: ' + backgroundUrl); console.log('Background could not be set: ' + backgroundUrl);
}); });
@ -333,7 +344,7 @@ export async function getBackgrounds() {
'': '', '': '',
}), }),
}); });
if (response.ok === true) { if (response.ok) {
const getData = await response.json(); const getData = await response.json();
//background = getData; //background = getData;
//console.log(getData.length); //console.log(getData.length);
@ -346,7 +357,7 @@ export async function getBackgrounds() {
} }
/** /**
* Gets the URL of the background * Gets the CSS URL of the background
* @param {Element} block * @param {Element} block
* @returns {string} URL of the background * @returns {string} URL of the background
*/ */
@ -354,6 +365,10 @@ function getUrlParameter(block) {
return $(block).closest('.bg_example').data('url'); return $(block).closest('.bg_example').data('url');
} }
function generateUrlParameter(bg, isCustom) {
return isCustom ? `url("${encodeURI(bg)}")` : `url("${getBackgroundPath(bg)}")`;
}
/** /**
* Instantiates a background template * Instantiates a background template
* @param {string} bg Path to background * @param {string} bg Path to background
@ -363,7 +378,7 @@ function getUrlParameter(block) {
function getBackgroundFromTemplate(bg, isCustom) { function getBackgroundFromTemplate(bg, isCustom) {
const template = $('#background_template .bg_example').clone(); const template = $('#background_template .bg_example').clone();
const thumbPath = isCustom ? bg : getThumbnailUrl('bg', bg); const thumbPath = isCustom ? bg : getThumbnailUrl('bg', bg);
const url = isCustom ? `url("${encodeURI(bg)}")` : `url("${getBackgroundPath(bg)}")`; const url = generateUrlParameter(bg, isCustom);
const title = isCustom ? bg.split('/').pop() : bg; const title = isCustom ? bg.split('/').pop() : bg;
const friendlyTitle = title.slice(0, title.lastIndexOf('.')); const friendlyTitle = title.slice(0, title.lastIndexOf('.'));
template.attr('title', title); template.attr('title', title);
@ -375,26 +390,11 @@ function getBackgroundFromTemplate(bg, isCustom) {
return template; return template;
} }
async function setBackground(bg) { async function setBackground(bg, url) {
jQuery.ajax({ $('#bg1').css('background-image', url);
type: 'POST', // background_settings.name = bg;
url: '/api/backgrounds/set', // background_settings.url = url;
data: JSON.stringify({ saveSettingsDebounced();
bg: bg,
}),
beforeSend: function () {
},
cache: false,
dataType: 'json',
contentType: 'application/json',
//processData: false,
success: function (html) { },
error: function (jqXHR, exception) {
console.log(exception);
console.log(jqXHR);
},
});
} }
async function delBackground(bg) { async function delBackground(bg) {
@ -435,8 +435,7 @@ function uploadBackground(formData) {
contentType: false, contentType: false,
processData: false, processData: false,
success: async function (bg) { success: async function (bg) {
setBackground(bg); setBackground(bg, generateUrlParameter(bg, false));
$('#bg1').css('background-image', `url("${getBackgroundPath(bg)}"`);
await getBackgrounds(); await getBackgrounds();
highlightNewBackground(bg); highlightNewBackground(bg);
}, },

View File

@ -41,7 +41,7 @@ const getRequestArgs = () => ({
}, },
}); });
async function getWorkers() { async function getWorkers(workerType) {
const response = await fetch('https://horde.koboldai.net/api/v2/workers?type=text', getRequestArgs()); const response = await fetch('https://horde.koboldai.net/api/v2/workers?type=text', getRequestArgs());
const data = await response.json(); const data = await response.json();
return data; return data;

View File

@ -537,7 +537,6 @@ redirect('/updatestats', '/api/stats/update');
// Redirect deprecated backgrounds API endpoints // Redirect deprecated backgrounds API endpoints
redirect('/getbackgrounds', '/api/backgrounds/all'); redirect('/getbackgrounds', '/api/backgrounds/all');
redirect('/setbackground', '/api/backgrounds/set');
redirect('/delbackground', '/api/backgrounds/delete'); redirect('/delbackground', '/api/backgrounds/delete');
redirect('/renamebackground', '/api/backgrounds/rename'); redirect('/renamebackground', '/api/backgrounds/rename');
redirect('/downloadbackground', '/api/backgrounds/upload'); // yes, the downloadbackground endpoint actually uploads one redirect('/downloadbackground', '/api/backgrounds/upload'); // yes, the downloadbackground endpoint actually uploads one

View File

@ -2,7 +2,6 @@ const fs = require('fs');
const path = require('path'); const path = require('path');
const express = require('express'); const express = require('express');
const sanitize = require('sanitize-filename'); const sanitize = require('sanitize-filename');
const writeFileAtomicSync = require('write-file-atomic').sync;
const { jsonParser, urlencodedParser } = require('../express-common'); const { jsonParser, urlencodedParser } = require('../express-common');
const { DIRECTORIES, UPLOADS_PATH } = require('../constants'); const { DIRECTORIES, UPLOADS_PATH } = require('../constants');
@ -17,17 +16,6 @@ router.post('/all', jsonParser, function (request, response) {
}); });
router.post('/set', jsonParser, function (request, response) {
try {
const bg = `#bg1 {background-image: url('../backgrounds/${request.body.bg}');}`;
writeFileAtomicSync('public/css/bg_load.css', bg, 'utf8');
response.send({ result: 'ok' });
} catch (err) {
console.log(err);
response.send(err);
}
});
router.post('/delete', jsonParser, function (request, response) { router.post('/delete', jsonParser, function (request, response) {
if (!request.body) return response.sendStatus(400); if (!request.body) return response.sendStatus(400);