Handle offline expressions for VN mode. Don't add blocks without sprites. Force empty block on chat change.

This commit is contained in:
Cohee
2023-06-04 00:42:16 +03:00
parent 8e2c20da3c
commit cccca22601
3 changed files with 44 additions and 7 deletions

View File

@ -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);
})(); })();

View File

@ -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;
} }

View File

@ -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 {