diff --git a/public/scripts/extensions/expressions/index.js b/public/scripts/extensions/expressions/index.js index 41b81d0c8..823692a05 100644 --- a/public/scripts/extensions/expressions/index.js +++ b/public/scripts/extensions/expressions/index.js @@ -7,6 +7,7 @@ export { MODULE_NAME }; const MODULE_NAME = 'expressions'; const UPDATE_INTERVAL = 2000; +const FALLBACK_EXPRESSION = 'joy'; const DEFAULT_EXPRESSIONS = [ "admiration", "amusement", @@ -128,7 +129,8 @@ async function visualNovelSetCharacterSprites(container, name, expression) { const sprites = spriteCache[character.name]; 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 (name == character.name) { @@ -138,10 +140,12 @@ async function visualNovelSetCharacterSprites(container, name, expression) { const img = expressionImage.find('img'); setImage(img, path); } + expressionImage.toggleClass('hidden', noSprites); } else { const template = $('#expression-holder').clone(); template.attr('data-avatar', avatar); $('#visual-novel-wrapper').append(template); + template.toggleClass('hidden', noSprites); setImage(template.find('img'), defaultSpritePath || ''); const fadeInPromise = new Promise(resolve => { template.fadeIn(250, () => resolve()); @@ -304,6 +308,7 @@ async function moduleWorker() { if (context.groupId) { await validateImages(currentLastMessage.name, true); + await forceUpdateVisualNovelMode(); } return; @@ -340,8 +345,8 @@ async function moduleWorker() { const force = !!context.groupId; // Character won't be angry on you for swiping - if (currentLastMessage.mes == '...' && expressionsList.includes('joy')) { - expression = 'joy'; + if (currentLastMessage.mes == '...' && expressionsList.includes(FALLBACK_EXPRESSION)) { + expression = FALLBACK_EXPRESSION; } if (vnMode) { @@ -362,6 +367,10 @@ async function moduleWorker() { } async function getExpressionLabel(text) { + if (!modules.includes('classify')) { + return FALLBACK_EXPRESSION; + } + const url = new URL(getApiUrl()); url.pathname = '/api/classify'; @@ -516,6 +525,25 @@ async function setExpression(character, expression, force) { console.debug('checking for expression images to show..'); if (sprite) { 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.removeClass('default'); img.off('error'); @@ -729,6 +757,10 @@ async function onClickExpressionDelete(event) { const updateFunction = wrapper.update.bind(wrapper); setInterval(updateFunction, UPDATE_INTERVAL); 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); })(); diff --git a/public/scripts/extensions/expressions/style.css b/public/scripts/extensions/expressions/style.css index decdc3066..e29b1f20f 100644 --- a/public/scripts/extensions/expressions/style.css +++ b/public/scripts/extensions/expressions/style.css @@ -21,6 +21,11 @@ width: max-content; } +#visual-novel-wrapper .hidden { + display: none !important; + visibility: hidden !important; +} + #visual-novel-wrapper img.expression { object-fit: cover; } diff --git a/public/style.css b/public/style.css index 2b88f2304..5a7f85363 100644 --- a/public/style.css +++ b/public/style.css @@ -340,7 +340,7 @@ code { margin: 0 auto; left: 0; right: 0; - z-index: 3; + z-index: 30; min-height: 100px; min-width: 100px; width: var(--sheldWidth); @@ -405,14 +405,14 @@ code { text-shadow: 0px 0px calc(var(--shadowWidth) * 1px) var(--SmartThemeShadowColor); scrollbar-width: thin; flex-direction: column; - z-index: 3; + z-index: 30; } #form_sheld { white-space: nowrap; width: 100%; margin: 1px auto 0 auto; - z-index: 3; + z-index: 30; } #send_form {