mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Handle offline expressions for VN mode. Don't add blocks without sprites. Force empty block on chat change.
This commit is contained in:
@ -7,6 +7,7 @@ export { MODULE_NAME };
|
|||||||
|
|
||||||
const MODULE_NAME = 'expressions';
|
const MODULE_NAME = 'expressions';
|
||||||
const UPDATE_INTERVAL = 2000;
|
const UPDATE_INTERVAL = 2000;
|
||||||
|
const FALLBACK_EXPRESSION = 'joy';
|
||||||
const DEFAULT_EXPRESSIONS = [
|
const DEFAULT_EXPRESSIONS = [
|
||||||
"admiration",
|
"admiration",
|
||||||
"amusement",
|
"amusement",
|
||||||
@ -128,7 +129,8 @@ async function visualNovelSetCharacterSprites(container, name, expression) {
|
|||||||
|
|
||||||
const sprites = spriteCache[character.name];
|
const sprites = spriteCache[character.name];
|
||||||
const expressionImage = container.find(`.expression-holder[data-avatar="${avatar}"]`);
|
const expressionImage = container.find(`.expression-holder[data-avatar="${avatar}"]`);
|
||||||
const defaultSpritePath = sprites.find(x => x.label === 'joy')?.path;
|
const defaultSpritePath = sprites.find(x => x.label === FALLBACK_EXPRESSION)?.path;
|
||||||
|
const noSprites = sprites.length === 0;
|
||||||
|
|
||||||
if (expressionImage.length > 0) {
|
if (expressionImage.length > 0) {
|
||||||
if (name == character.name) {
|
if (name == character.name) {
|
||||||
@ -138,10 +140,12 @@ async function visualNovelSetCharacterSprites(container, name, expression) {
|
|||||||
const img = expressionImage.find('img');
|
const img = expressionImage.find('img');
|
||||||
setImage(img, path);
|
setImage(img, path);
|
||||||
}
|
}
|
||||||
|
expressionImage.toggleClass('hidden', noSprites);
|
||||||
} else {
|
} else {
|
||||||
const template = $('#expression-holder').clone();
|
const template = $('#expression-holder').clone();
|
||||||
template.attr('data-avatar', avatar);
|
template.attr('data-avatar', avatar);
|
||||||
$('#visual-novel-wrapper').append(template);
|
$('#visual-novel-wrapper').append(template);
|
||||||
|
template.toggleClass('hidden', noSprites);
|
||||||
setImage(template.find('img'), defaultSpritePath || '');
|
setImage(template.find('img'), defaultSpritePath || '');
|
||||||
const fadeInPromise = new Promise(resolve => {
|
const fadeInPromise = new Promise(resolve => {
|
||||||
template.fadeIn(250, () => resolve());
|
template.fadeIn(250, () => resolve());
|
||||||
@ -304,6 +308,7 @@ async function moduleWorker() {
|
|||||||
|
|
||||||
if (context.groupId) {
|
if (context.groupId) {
|
||||||
await validateImages(currentLastMessage.name, true);
|
await validateImages(currentLastMessage.name, true);
|
||||||
|
await forceUpdateVisualNovelMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -340,8 +345,8 @@ async function moduleWorker() {
|
|||||||
const force = !!context.groupId;
|
const force = !!context.groupId;
|
||||||
|
|
||||||
// Character won't be angry on you for swiping
|
// Character won't be angry on you for swiping
|
||||||
if (currentLastMessage.mes == '...' && expressionsList.includes('joy')) {
|
if (currentLastMessage.mes == '...' && expressionsList.includes(FALLBACK_EXPRESSION)) {
|
||||||
expression = 'joy';
|
expression = FALLBACK_EXPRESSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vnMode) {
|
if (vnMode) {
|
||||||
@ -362,6 +367,10 @@ async function moduleWorker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getExpressionLabel(text) {
|
async function getExpressionLabel(text) {
|
||||||
|
if (!modules.includes('classify')) {
|
||||||
|
return FALLBACK_EXPRESSION;
|
||||||
|
}
|
||||||
|
|
||||||
const url = new URL(getApiUrl());
|
const url = new URL(getApiUrl());
|
||||||
url.pathname = '/api/classify';
|
url.pathname = '/api/classify';
|
||||||
|
|
||||||
@ -516,6 +525,25 @@ async function setExpression(character, expression, force) {
|
|||||||
console.debug('checking for expression images to show..');
|
console.debug('checking for expression images to show..');
|
||||||
if (sprite) {
|
if (sprite) {
|
||||||
console.debug('setting expression from character images folder');
|
console.debug('setting expression from character images folder');
|
||||||
|
|
||||||
|
if (force && isVisualNovelMode()) {
|
||||||
|
const context = getContext();
|
||||||
|
const group = context.groups.find(x => x.id === context.groupId);
|
||||||
|
|
||||||
|
for (const member of group.members) {
|
||||||
|
const groupMember = context.characters.find(x => x.avatar === member);
|
||||||
|
|
||||||
|
if (!groupMember) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupMember.name == character) {
|
||||||
|
setImage($(`.expression-holder[data-avatar="${member}"] img`), sprite.path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
img.attr('src', sprite.path);
|
img.attr('src', sprite.path);
|
||||||
img.removeClass('default');
|
img.removeClass('default');
|
||||||
img.off('error');
|
img.off('error');
|
||||||
@ -729,6 +757,10 @@ async function onClickExpressionDelete(event) {
|
|||||||
const updateFunction = wrapper.update.bind(wrapper);
|
const updateFunction = wrapper.update.bind(wrapper);
|
||||||
setInterval(updateFunction, UPDATE_INTERVAL);
|
setInterval(updateFunction, UPDATE_INTERVAL);
|
||||||
moduleWorker();
|
moduleWorker();
|
||||||
eventSource.on(event_types.CHAT_CHANGED, updateFunction);
|
eventSource.on(event_types.CHAT_CHANGED, () => {
|
||||||
|
if (isVisualNovelMode()) {
|
||||||
|
$('#visual-novel-wrapper').empty();
|
||||||
|
}
|
||||||
|
});
|
||||||
eventSource.on(event_types.GROUP_UPDATED, updateVisualNovelModeDebounced);
|
eventSource.on(event_types.GROUP_UPDATED, updateVisualNovelModeDebounced);
|
||||||
})();
|
})();
|
||||||
|
@ -21,6 +21,11 @@
|
|||||||
width: max-content;
|
width: max-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#visual-novel-wrapper .hidden {
|
||||||
|
display: none !important;
|
||||||
|
visibility: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
#visual-novel-wrapper img.expression {
|
#visual-novel-wrapper img.expression {
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
@ -340,7 +340,7 @@ code {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 3;
|
z-index: 30;
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
width: var(--sheldWidth);
|
width: var(--sheldWidth);
|
||||||
@ -405,14 +405,14 @@ code {
|
|||||||
text-shadow: 0px 0px calc(var(--shadowWidth) * 1px) var(--SmartThemeShadowColor);
|
text-shadow: 0px 0px calc(var(--shadowWidth) * 1px) var(--SmartThemeShadowColor);
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
z-index: 3;
|
z-index: 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
#form_sheld {
|
#form_sheld {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 1px auto 0 auto;
|
margin: 1px auto 0 auto;
|
||||||
z-index: 3;
|
z-index: 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
#send_form {
|
#send_form {
|
||||||
|
Reference in New Issue
Block a user