Update backend returned sprites list

a072951102f40be153a019ccb4443305654387da

Wolfsblvt <wolfsblvt@gmail.com>

1 files changed, +34 -5Showing whitespace changes
public/scripts/extensions/expressions/index.js+34 -5
@@ -20,7 +20,7 @@ export { MODULE_NAME };
20/**20/**
21* @typedef {object} Expression Expression definition with label and file path21* @typedef {object} Expression Expression definition with label and file path
22* @property {string} label The label of the expression22* @property {string} label The label of the expression
23 * @property {string} path The path to the expression image23* @property {ExpressionImage[]} files One or more images to represent this expression
24*/24*/
2525
26/**26/**
@@ -86,6 +86,7 @@ let lastCharacter = undefined;
86let lastMessage = null;86let lastMessage = null;
87let lastTalkingState = false;87let lastTalkingState = false;
88let lastTalkingStateMessage = null; // last message as seen by `updateTalkingState` (tracked separately, different timer)88let lastTalkingStateMessage = null; // last message as seen by `updateTalkingState` (tracked separately, different timer)
89/** @type {{[characterKey: string]: Expression[]}} */
89let spriteCache = {};90let spriteCache = {};
90let inApiCall = false;91let inApiCall = false;
91let lastServerResponseTime = 0;92let lastServerResponseTime = 0;
@@ -1307,6 +1308,11 @@ function removeExpression() {
1307 $('#no_chat_expressions').show();1308 $('#no_chat_expressions').show();
1308}1309}
13091310
1311/**
1312 * Validate a character's sprites, and redraw the sprites list if not done before or forced to redraw.
1313 * @param {string} character - The character to validate
1314 * @param {boolean} forceRedrawCached - Whether to force redrawing the sprites list even if it's already been drawn before
1315 */
1310async function validateImages(character, forceRedrawCached) {1316async function validateImages(character, forceRedrawCached) {
1311 if (!character) {1317 if (!character) {
1312 return;1318 return;
@@ -1330,7 +1336,7 @@ async function validateImages(character, forceRedrawCached) {
13301336
1331/**1337/**
1332 * Takes a given sprite as returned from the server, and enriches it with additional data for display/sorting1338 * Takes a given sprite as returned from the server, and enriches it with additional data for display/sorting
1333 * @param {Expression} sprite1339 * @param {{ path: string, label: string }} sprite
1334 * @returns {ExpressionImage}1340 * @returns {ExpressionImage}
1335 */1341 */
1336function getExpressionImageData(sprite) {1342function getExpressionImageData(sprite) {
@@ -1371,7 +1377,8 @@ async function drawSpritesList(character, labels, sprites) {
1371 const isCustom = extension_settings.expressions.custom?.includes(expression);1377 const isCustom = extension_settings.expressions.custom?.includes(expression);
1372 const images = sprites1378 const images = sprites
1373 .filter(s => s.label === expression)1379 .filter(s => s.label === expression)
1374 .map(getExpressionImageData)1380 .map(s => s.files)
1381 .flat()
1375 .sort((a, b) => a.title.localeCompare(b.title));1382 .sort((a, b) => a.title.localeCompare(b.title));
13761383
1377 if (images.length === 0) {1384 if (images.length === 0) {
@@ -1384,7 +1391,7 @@ async function drawSpritesList(character, labels, sprites) {
1384 }1391 }
13851392
1386 // TODO: Fix valid expression lists/caching and group them correctly1393 // TODO: Fix valid expression lists/caching and group them correctly
1387 validExpressions.push({ label: expression, paths: images });1394 validExpressions.push({ label: expression, files: images });
13881395
1389 // Render main = first file, additional = rest1396 // Render main = first file, additional = rest
1390 let listItem = await getListItem(expression, {1397 let listItem = await getListItem(expression, {
@@ -1408,13 +1415,35 @@ async function getListItem(expression, { images, isCustom = false } = {}) {
1408 return renderExtensionTemplateAsync(MODULE_NAME, 'list-item', { expression, images, isCustom: isCustom ?? false });1415 return renderExtensionTemplateAsync(MODULE_NAME, 'list-item', { expression, images, isCustom: isCustom ?? false });
1409}1416}
14101417
1418/**
1419 * Fetches and processes the list of sprites for a given character name.
1420 * Retrieves sprite data from the server and organizes it into labeled groups.
1421 *
1422 * @param {string} name - The character name to fetch sprites for
1423 * @returns {Promise<Expression[]>} A promise that resolves to an array of grouped expression objects, each containing a label and associated image data
1424 */
1425
1411async function getSpritesList(name) {1426async function getSpritesList(name) {
1412 console.debug('getting sprites list');1427 console.debug('getting sprites list');
14131428
1414 try {1429 try {
1415 const result = await fetch(`/api/sprites/get?name=${encodeURIComponent(name)}`);1430 const result = await fetch(`/api/sprites/get?name=${encodeURIComponent(name)}`);
1431 /** @type {{ label: string, path: string }[]} */
1416 let sprites = result.ok ? (await result.json()) : [];1432 let sprites = result.ok ? (await result.json()) : [];
1417 return sprites;1433
1434 /** @type {Expression[]} */
1435 const grouped = sprites.reduce((acc, sprite) => {
1436 const imageData = getExpressionImageData(sprite);
1437 let existingExpression = acc.find(exp => exp.label === sprite.label);
1438 if (existingExpression) {
1439 existingExpression.files.push(imageData);
1440 } else {
1441 acc.push({ label: sprite.label, files: [imageData] });
1442 }
1443
1444 return acc;
1445 }, []);
1446 return grouped;
1418 }1447 }
1419 catch (err) {1448 catch (err) {
1420 console.log(err);1449 console.log(err);