Add default images to expressions plugin
@@ -30,8 +30,8 @@ async function moduleWorker() {
|
||||
: $('#send_picture').show(200);
|
||||
}
|
||||
|
||||
async function urlContentToDataUri(url) {
|
||||
const response = await fetch(url);
|
||||
async function urlContentToDataUri(url, params) {
|
||||
const response = await fetch(url, params);
|
||||
const blob = await response.blob();
|
||||
return await new Promise(callback => {
|
||||
let reader = new FileReader();
|
||||
@@ -45,7 +45,7 @@ async function setImageIcon() {
|
||||
const sendButton = document.getElementById('send_picture');
|
||||
const imgUrl = new URL(getApiUrl());
|
||||
imgUrl.pathname = `/api/asset/${MODULE_NAME}/image-solid.svg`;
|
||||
const dataUri = await urlContentToDataUri(imgUrl.toString());
|
||||
const dataUri = await urlContentToDataUri(imgUrl.toString(), { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': 'bypass' } });
|
||||
sendButton.style.backgroundImage = `url(${dataUri})`;
|
||||
sendButton.classList.remove('spin');
|
||||
}
|
||||
@@ -59,7 +59,7 @@ async function setSpinnerIcon() {
|
||||
const sendButton = document.getElementById('send_picture');
|
||||
const imgUrl = new URL(getApiUrl());
|
||||
imgUrl.pathname = `/api/asset/${MODULE_NAME}/spinner-solid.svg`;
|
||||
const dataUri = await urlContentToDataUri(imgUrl.toString());
|
||||
const dataUri = await urlContentToDataUri(imgUrl.toString(), { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': 'bypass' } });
|
||||
sendButton.style.backgroundImage = `url(${dataUri})`;
|
||||
sendButton.classList.add('spin');
|
||||
}
|
||||
|
||||
BIN
extensions/expressions/assets/admiration.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
extensions/expressions/assets/amusement.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
extensions/expressions/assets/anger.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
extensions/expressions/assets/annoyance.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
extensions/expressions/assets/approval.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
extensions/expressions/assets/caring.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
extensions/expressions/assets/confusion.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
extensions/expressions/assets/curiosity.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
extensions/expressions/assets/desire.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
extensions/expressions/assets/disappointment.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
extensions/expressions/assets/disapproval.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
extensions/expressions/assets/disgust.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
extensions/expressions/assets/embarrassment.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
extensions/expressions/assets/excitement.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
extensions/expressions/assets/fear.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
extensions/expressions/assets/gratitude.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
extensions/expressions/assets/grief.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
extensions/expressions/assets/joy.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
extensions/expressions/assets/love.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
extensions/expressions/assets/nervousness.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
extensions/expressions/assets/neutral.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
extensions/expressions/assets/optimism.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
extensions/expressions/assets/pride.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
extensions/expressions/assets/realization.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
extensions/expressions/assets/relief.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
extensions/expressions/assets/remorse.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
extensions/expressions/assets/sadness.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
extensions/expressions/assets/surprise.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
@@ -1,11 +1,46 @@
|
||||
const MODULE_NAME = 'expressions';
|
||||
const SETTINGS_KEY = 'extensions_memory_settings';
|
||||
const DEFAULT_KEY = 'extensions_expressions_showDefault';
|
||||
const UPDATE_INTERVAL = 1000;
|
||||
|
||||
let expressionsList = null;
|
||||
let lastCharacter = undefined;
|
||||
let lastMessage = null;
|
||||
let inApiCall = false;
|
||||
let showDefault = false;
|
||||
|
||||
async function urlContentToDataUri(url, params) {
|
||||
const response = await fetch(url, params);
|
||||
const blob = await response.blob();
|
||||
return await new Promise(callback => {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function () { callback(this.result); };
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
}
|
||||
|
||||
function loadSettings() {
|
||||
showDefault = localStorage.getItem(DEFAULT_KEY) == 'true';
|
||||
$('#expressions_show_default').prop('checked', showDefault).trigger('input');
|
||||
}
|
||||
|
||||
function saveSettings() {
|
||||
localStorage.setItem(DEFAULT_KEY, showDefault.toString());
|
||||
}
|
||||
|
||||
function onExpressionsShowDefaultInput() {
|
||||
const value = $(this).prop('checked');
|
||||
showDefault = value;
|
||||
saveSettings();
|
||||
|
||||
const existingImage = $('div.expression').css('background-image');
|
||||
if (!value && existingImage.includes('data:image/png')) {
|
||||
$('div.expression').css('background-image', 'unset');
|
||||
lastMessage = null;
|
||||
}
|
||||
if (value) {
|
||||
lastMessage = null;
|
||||
}
|
||||
}
|
||||
|
||||
const getContext = function () {
|
||||
return window['TavernAI'].getContext();
|
||||
@@ -87,6 +122,7 @@ async function moduleWorker() {
|
||||
}
|
||||
|
||||
function removeExpression() {
|
||||
lastMessage = null;
|
||||
$('div.expression').css('background-image', 'unset');
|
||||
$('.expression_settings').hide();
|
||||
}
|
||||
@@ -115,10 +151,10 @@ async function validateImages() {
|
||||
image.width = '0px';
|
||||
image.height = '0px';
|
||||
image.onload = function() {
|
||||
$('#image_list').append(`<li class="success">${item} - OK</li>`);
|
||||
$('#image_list').append(`<li id="${item}" class="success">${item} - OK</li>`);
|
||||
}
|
||||
image.onerror = function() {
|
||||
$('#image_list').append(`<li class="failure">${item} - Missing</li>`);
|
||||
$('#image_list').append(`<li id="${item}" class="failure">${item} - Missing</li>`);
|
||||
}
|
||||
$('#image_list').prepend(image);
|
||||
});
|
||||
@@ -151,9 +187,23 @@ async function getExpressionsList() {
|
||||
}
|
||||
}
|
||||
|
||||
function setExpression(character, expression) {
|
||||
const imgUrl = `url('/characters/${character}/${expression}.png')`;
|
||||
async function setExpression(character, expression) {
|
||||
const filename = `${expression}.png`;
|
||||
const imgUrl = `url('/characters/${character}/${filename}')`;
|
||||
$('div.expression').css('background-image', imgUrl);
|
||||
|
||||
const debugImageStatus = document.querySelector(`#image_list li[id="${filename}"]`);
|
||||
if (showDefault && debugImageStatus && debugImageStatus.classList.contains('failure')) {
|
||||
try {
|
||||
const imgUrl = new URL(getApiUrl());
|
||||
imgUrl.pathname = `/api/asset/${MODULE_NAME}/${filename}`;
|
||||
const dataUri = await urlContentToDataUri(imgUrl.toString(), { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': 'bypass' } });
|
||||
$('div.expression').css('background-image', `url(${dataUri})`);
|
||||
}
|
||||
catch {
|
||||
$('div.expression').css('background-image', 'unset');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
@@ -168,13 +218,16 @@ function setExpression(character, expression) {
|
||||
<ul id="image_list"></ul>
|
||||
<p><b>Hint:</b> <i>Put images into the <tt>public/characters/Name</tt>
|
||||
folder of TavernAI, where Name is the name of the character</i></p>
|
||||
<label for="expressions_show_default"><input id="expressions_show_default" type="checkbox">Show default images (emojis) if missing</label>
|
||||
</div>
|
||||
`;
|
||||
$('#extensions_settings').append(html);
|
||||
$('#expressions_show_default').on('input', onExpressionsShowDefaultInput);
|
||||
$('.expression_settings').hide();
|
||||
}
|
||||
|
||||
addExpressionImage();
|
||||
addSettings();
|
||||
loadSettings();
|
||||
setInterval(moduleWorker, UPDATE_INTERVAL);
|
||||
})();
|
||||
@@ -41,6 +41,21 @@ div.expression {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.expression_settings p {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.expression_settings label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.expression_settings label input {
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width:1200px) {
|
||||
div.expression {
|
||||
display: none;
|
||||
|
||||