Spaces:
Build error
Build error
import { generateQuietPrompt } from "../../../script.js"; | |
import { getContext, saveMetadataDebounced } from "../../extensions.js"; | |
import { registerSlashCommand } from "../../slash-commands.js"; | |
import { stringFormat } from "../../utils.js"; | |
export { MODULE_NAME }; | |
const MODULE_NAME = 'backgrounds'; | |
const METADATA_KEY = 'custom_background'; | |
const UPDATE_INTERVAL = 1000; | |
async function moduleWorker() { | |
if (hasCustomBackground()) { | |
$('#unlock_background').show(); | |
$('#lock_background').hide(); | |
setCustomBackground(); | |
} | |
else { | |
$('#unlock_background').hide(); | |
$('#lock_background').show(); | |
unsetCustomBackground(); | |
} | |
} | |
function onLockBackgroundClick() { | |
const bgImage = window.getComputedStyle(document.getElementById('bg1')).backgroundImage; | |
// Extract the URL from the CSS string | |
const urlRegex = /url\((['"])?(.*?)\1\)/; | |
const matches = bgImage.match(urlRegex); | |
const url = matches[2]; | |
// Remove the protocol and host, leaving the relative URL | |
const relativeUrl = new URL(url).pathname; | |
const relativeBgImage = `url("${relativeUrl}")` | |
saveBackgroundMetadata(relativeBgImage); | |
setCustomBackground(); | |
$('#unlock_background').show(); | |
$('#lock_background').hide(); | |
} | |
function onUnlockBackgroundClick() { | |
removeBackgroundMetadata(); | |
unsetCustomBackground(); | |
$('#unlock_background').hide(); | |
$('#lock_background').show(); | |
} | |
function hasCustomBackground() { | |
const context = getContext(); | |
return !!context.chatMetadata[METADATA_KEY]; | |
} | |
function saveBackgroundMetadata(file) { | |
const context = getContext(); | |
context.chatMetadata[METADATA_KEY] = file; | |
saveMetadataDebounced(); | |
} | |
function removeBackgroundMetadata() { | |
const context = getContext(); | |
delete context.chatMetadata[METADATA_KEY]; | |
saveMetadataDebounced(); | |
} | |
function setCustomBackground() { | |
const context = getContext(); | |
const file = context.chatMetadata[METADATA_KEY]; | |
// bg already set | |
if (document.getElementById("bg_custom").style.backgroundImage == file) { | |
return; | |
} | |
$("#bg_custom").css("background-image", file); | |
$("#custom_bg_preview").css("background-image", file); | |
} | |
function unsetCustomBackground() { | |
$("#bg_custom").css("background-image", 'none'); | |
$("#custom_bg_preview").css("background-image", 'none'); | |
} | |
function onSelectBackgroundClick() { | |
const bgfile = $(this).attr("bgfile"); | |
if (hasCustomBackground()) { | |
saveBackgroundMetadata(`url("backgrounds/${bgfile}")`); | |
setCustomBackground(); | |
} | |
} | |
const autoBgPrompt = `Pause your roleplay and choose a location ONLY from the provided list that is the most suitable for the current scene. Do not output any other text:\n{0}`; | |
async function autoBackgroundCommand() { | |
const options = Array.from(document.querySelectorAll('.BGSampleTitle')).map(x => ({ element: x, text: x.innerText.trim() })).filter(x => x.text.length > 0); | |
if (options.length == 0) { | |
toastr.warning('No backgrounds to choose from. Please upload some images to the "backgrounds" folder.'); | |
return; | |
} | |
const list = options.map(option => `- ${option.text}`).join('\n'); | |
const prompt = stringFormat(autoBgPrompt, list); | |
const reply = await generateQuietPrompt(prompt); | |
const fuse = new Fuse(options, { keys: ['text'] }); | |
const bestMatch = fuse.search(reply, { limit: 1 }); | |
if (bestMatch.length == 0) { | |
toastr.warning('No match found. Please try again.'); | |
return; | |
} | |
console.debug('Automatically choosing background:', bestMatch); | |
bestMatch[0].item.element.click(); | |
} | |
$(document).ready(function () { | |
function addSettings() { | |
const html = ` | |
<div class="background_settings"> | |
<div class="inline-drawer"> | |
<div class="inline-drawer-toggle inline-drawer-header"> | |
<b>Chat Backgrounds</b> | |
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div> | |
</div> | |
<div class="inline-drawer-content"> | |
<div class="background_controls"> | |
<div id="lock_background" class="menu_button"> | |
<i class="fa-solid fa-lock"></i> | |
Lock | |
</div> | |
<div id="unlock_background" class="menu_button"> | |
<i class="fa-solid fa-unlock"></i> | |
Unlock | |
</div> | |
<small> | |
Press "Lock" to assign a currently selected background to a character or group chat.<br> | |
Any background image selected while lock is engaged will be saved automatically. | |
</small> | |
</div> | |
<div class="background_controls"> | |
<div id="auto_background" class="menu_button"> | |
<i class="fa-solid fa-wand-magic"></i> | |
Auto | |
</div> | |
<small> | |
Automatically select a background based on the chat context.<br> | |
Respects the "Lock" setting state. | |
</small> | |
</div> | |
<div>Preview</div> | |
<div id="custom_bg_preview"> | |
</div> | |
</div> | |
</div> | |
</div> | |
`; | |
$('#extensions_settings').append(html); | |
$('#lock_background').on('click', onLockBackgroundClick); | |
$('#unlock_background').on('click', onUnlockBackgroundClick); | |
$(document).on("click", ".bg_example", onSelectBackgroundClick); | |
$('#auto_background').on("click", autoBackgroundCommand); | |
} | |
addSettings(); | |
setInterval(moduleWorker, UPDATE_INTERVAL); | |
registerSlashCommand('lockbg', onLockBackgroundClick, ['bglock'], " β locks a background for the currently selected chat", true, true); | |
registerSlashCommand('unlockbg', onUnlockBackgroundClick, ['bgunlock'], ' β unlocks a background for the currently selected chat', true, true); | |
registerSlashCommand('autobg', autoBackgroundCommand, ['bgauto'], ' β automatically changes the background based on the chat context using the AI request prompt', true, true); | |
}); | |