Replaced emoticon loading code with newer API library.

This commit is contained in:
flash 2025-04-12 21:01:25 +00:00
parent d084b838f5
commit f38aee7e4d
Signed by: flash
GPG key ID: 2C9C2C574D47FE3E
5 changed files with 159 additions and 21 deletions

View file

@ -16,14 +16,6 @@ const FutamiCommon = function(vars) {
const { body } = await $xhr.get(get(name), options); const { body } = await $xhr.get(get(name), options);
return body; return body;
}, },
getApiJson: async (path, noCache) => {
const options = { type: 'json' };
if(noCache)
options.headers = { 'Cache-Control': 'no-cache' };
const { body } = await $xhr.get(get('api') + path, options);
return body;
},
}; };
}; };

View file

@ -1,4 +1,5 @@
#include events.js #include events.js
#include flashii.js
const MamiContext = function(globalEventTarget, eventTarget) { const MamiContext = function(globalEventTarget, eventTarget) {
if(typeof globalEventTarget !== 'object' && globalEventTarget === null) if(typeof globalEventTarget !== 'object' && globalEventTarget === null)
@ -12,6 +13,8 @@ const MamiContext = function(globalEventTarget, eventTarget) {
if(typeof eventTarget === 'string') if(typeof eventTarget === 'string')
eventTarget = globalEventTarget.scopeTo(eventTarget); eventTarget = globalEventTarget.scopeTo(eventTarget);
const flashii = new Flashii;
let isUnloading = false; let isUnloading = false;
let settings; let settings;
@ -25,6 +28,7 @@ const MamiContext = function(globalEventTarget, eventTarget) {
return { return {
get globalEvents() { return globalEventTarget; }, get globalEvents() { return globalEventTarget; },
get events() { return eventTarget; }, get events() { return eventTarget; },
get flashii() { return flashii; },
get isUnloading() { return isUnloading; }, get isUnloading() { return isUnloading; },
set isUnloading(state) { set isUnloading(state) {

View file

@ -18,15 +18,10 @@ const MamiEmotes = (function() {
clear, clear,
add, add,
load, load,
async loadUrl(url=null) { async loadApi(flashii, fresh=false) {
const { status, body } = await $xhr.get( const emotes = await flashii.v1.emotes({ fields: ['url', 'strings', 'min_rank'], fresh });
url ?? `${FII_API}/v1/emotes?fields=url,strings,min_rank`, clear();
{ type: 'json' } load(emotes);
);
if(status !== 200)
throw 'Could not load emoticons';
load(body);
}, },
forEach(minRank, callback) { forEach(minRank, callback) {
for(const emote of emotes) for(const emote of emotes)

149
src/mami.js/flashii.js Normal file
View file

@ -0,0 +1,149 @@
#include xhr.js
const Flashii = function(baseUrl=null) {
baseUrl ??= window.FII_API;
if(baseUrl.startsWith('//'))
baseUrl = window.location.protocol + baseUrl;
const sortArray = typeof Array.prototype.toSorted === 'function'
? array => array.toSorted()
: array => {
array = array.slice();
array.sort();
return array;
};
const convertFields = fields => {
if(fields === true)
return '*';
if(Array.isArray(fields))
return sortArray(fields).join(',');
if(typeof fields === 'string')
return fields;
return null;
};
const createUrl = (path, fields=null) => {
const url = new URL(baseUrl + path);
if(fields)
url.searchParams.set('fields', convertFields(fields));
return url;
};
const send = async ({
method,
path,
fresh=false,
params=null,
fields=null,
body=null,
headers=null,
type='json',
}) => {
const url = createUrl(path, fields);
if(params)
for(const name in params) {
if(name === 'fields')
continue;
url.searchParams.set(name, params[name]);
}
headers ??= {};
if(fresh) headers['Cache-Control'] = 'no-cache';
const options = { type, headers };
return await $xhr.send(method, url, options, body);
};
const fii = {};
fii.v1 = {};
const verifyColourPresetName = name => {
if(/^([^A-Za-z0-9\-_]+)$/gu.test(name))
throw new Error('name argument is not an acceptable colour preset name.');
return name;
};
fii.v1.colours = {};
fii.v1.colours.presets = async function({ fields=null, fresh=false }) {
const { status, body } = await send({ method: 'GET', path: '/v1/colours/presets', fields, fresh });
if(status === 400)
throw new Error('Fields argument contains unsupported value.');
if(status > 299)
throw new Error(`Failed to fetch colour presets with error code ${status}.`);
return body;
};
fii.v1.colours.presets.preset = async function({ name, fields=null, fresh=false }) {
name = verifyColourPresetName(name);
const { status, body } = await send({ method: 'GET', path: `/v1/colours/presets/${name}`, fields, fresh });
if(status === 400)
throw new Error('Fields argument contains unsupported value.');
if(status === 404)
throw new Error('Requested colour preset does not exist.');
if(status > 299)
throw new Error(`Failed to fetch colour preset "${name}" with error code ${status}.`);
return body;
};
const verifyEmoticonId = id => {
if(typeof id === 'number')
id = id.toString();
if(/^([^0-9]+)$/gu.test(id))
throw new Error('id argument is not an acceptable emoticon id.');
return id;
};
fii.v1.emotes = async function({ fields=null, fresh=false }) {
const { status, body } = await send({ method: 'GET', path: '/v1/emotes', fields, fresh });
if(status === 400)
throw new Error('Fields argument contains unsupported value.');
if(status > 299)
throw new Error(`Failed to fetch emoticons with error code ${status}.`);
return body;
};
fii.v1.emotes.emote = async function({ id, fields=null, fresh=false }) {
id = verifyEmoticonId(id);
const { status, body } = await send({ method: 'GET', path: `/v1/emotes/${id}`, fields, fresh });
if(status === 400)
throw new Error('Fields argument contains unsupported value.');
if(status === 404)
throw new Error('Requested emoticon does not exist.');
if(status > 299)
throw new Error(`Failed to fetch emoticon "${id}" with error code ${status}.`);
return body;
};
fii.v1.emotes.emote.strings = async function({ id, fields=null, fresh=false }) {
id = verifyEmoticonId(id);
const { status, body } = await send({ method: 'GET', path: `/v1/emotes/${id}/strings`, fields, fresh });
if(status === 400)
throw new Error('Fields argument contains unsupported value.');
if(status === 404)
throw new Error('Requested emoticon does not exist.');
if(status > 299)
throw new Error(`Failed to fetch emoticon "${id}" with error code ${status}.`);
return body;
};
return fii;
};

View file

@ -222,7 +222,7 @@ const MamiInit = async args => {
// loading these asynchronously makes them not show up in the backlog // loading these asynchronously makes them not show up in the backlog
// revisit when emote reparsing is implemented // revisit when emote reparsing is implemented
try { try {
MamiEmotes.loadUrl(); await MamiEmotes.loadApi(ctx.flashii);
} catch(ex) { } catch(ex) {
console.error('Failed to load emoticons.', ex); console.error('Failed to load emoticons.', ex);
} }
@ -562,9 +562,7 @@ const MamiInit = async args => {
button.disabled = true; button.disabled = true;
button.textContent = 'Reloading emoticons...'; button.textContent = 'Reloading emoticons...';
try { try {
const emotes = await futami.getApiJson('/v1/emotes', true); await MamiEmotes.loadApi(ctx.flashii, true);
MamiEmotes.clear();
MamiEmotes.load(emotes);
} finally { } finally {
button.textContent = textOrig; button.textContent = textOrig;
button.disabled = false; button.disabled = false;