Support joinmastodon.org#Emoji ns custom emojis

This commit is contained in:
Niko 2022-02-18 11:26:19 +01:00
parent 19567fadd9
commit e9feb6d912
6 changed files with 93 additions and 2 deletions

View File

@ -4,4 +4,5 @@ module.exports = {
feed: require('./api/feed.js'),
accounts: require('./api/accounts.js'),
me: require('./api/me.js'),
instance: require('./api/instance.js'),
}

36
api/src/api/instance.js Normal file
View File

@ -0,0 +1,36 @@
const auth = require('../auth.js')
const utils = require('../api-utils.js')
module.exports = {
emojis: {
get: [auth.enforceSession, async (req, res) => {
var result = {}
const masto_emojis = await db.table.objects().find(
{ type: 'http://joinmastodon.org/ns#Emoji' }).toArray()
for (var i = 0; i < masto_emojis.length; i++) {
const emoji = masto_emojis[i]
var name = utils.firstIfArray(emoji.name)
if (name === null) continue
name = name.replace(/^:/,'').replace(/:$/,'').trim()
if (result[name] !== undefined ||
!name.match(/^[a-zA-Z0-9\_]+$/))
continue
const icon = utils.firstIfArray(emoji.icon)
if (icon === null) continue
const url = utils.firstIfArray(icon.url)
if (url === null) continue
try { new URL(url).href.length > 0 }
catch (e) { continue }
result[name] = {
type: utils.firstIfArray(icon.mediaType),
url,
}
}
// TODO: support local emojis later
return res.json(result)
}],
},
}

View File

@ -70,6 +70,7 @@ app.on('apex-inbox', activity.federation.inbox)
/* GET */ app.route(api.v1('/me/pending_follows')).get(api.me.pending_follows.get)
/* POST */ app.route(api.v1('/accounts/follow')).post(api.accounts.follow.post)
/* POST */ app.route(api.v1('/accounts/unfollow')).post(api.accounts.unfollow.post)
/* GET */ app.route(api.v1('/instance/emojis')).get(api.instance.emojis.get)
// initialize
client.connect({ useNewUrlParser: true })

View File

@ -123,6 +123,12 @@ main {
background: linear-gradient(to right, #00000082, #00000063, #00000063, #00000082);
}
.status .user .emoji {
width: 1em;
height: 1em;
position: relative;
top: 3px;
}
.meet.item .status { color: #fff }
.meet.item .status-content {
padding: 1em;

View File

@ -108,6 +108,13 @@ app.storage = {
localStorage['fedilove'] = JSON.stringify(js);
return true;
},
del: function(key) {
app.storage._init();
const js = JSON.parse(localStorage['fedilove']);
delete js[key];
localStorage['fedilove'] = JSON.stringify(js);
return true;
},
}
app.post = {
@ -183,6 +190,31 @@ app.post = {
},
}
app.emoji = {
expand: function(value) {
const cemoji_str = value.match(/:[a-zA-Z0-9\_]+:/g);
if (cemoji_str === null) return value;
for (var i = 0; i < cemoji_str.length; i++) {
const name = cemoji_str[i].replace(/^:/,'').replace(/:$/,'');
const url = app.emoji.get(name);
if (url === null || url == undefined)
continue;
try { new URL(url).href.length > 0; }
catch (e) { continue; }
value = value.replaceAll(`:${name}:`,
'<img class="emoji" src="'+htmlescape(url)+'"/>');
}
return value;
},
get: function(name) {
var emojis = app.storage.get('emojis_cache');
if (emojis === undefined) return null;
emojis = JSON.parse(emojis);
if (emojis[name] === undefined) return null;
return emojis[name].url;
},
}
app.overlay = {
hideAll: function() {
document.querySelectorAll('.overlay')
@ -211,6 +243,18 @@ window.onload = function(e) {
scriptPageHandler('pages.crushes', { regex: /^crushes(\/you)?$/ });
scriptPageHandler('pages.chat', { exact: 'chat' });
}
const ts = new Date().getTime();
const ts2 = parseInt(app.storage.get('emojis_cache_ts'));
const diff = isNaN(ts2) ? -1 : ((ts - ts2) / 1000);
if (diff === -1 || diff >= (30 * 60)) {
app.storage.del('emojis_cache');
http.get('/api/v1/instance/emojis', {}, function(data) {
app.storage.set('emojis_cache', data);
app.storage.set('emojis_cache_ts', ts);
})
}
window.onhashchange();
}

View File

@ -12,7 +12,10 @@ app.pages.meet = {
http.get('/api/v1/feed/meet', {}, function(json) {
if (json === undefined) return;
app.pages.meet.data = json;
app.template.loadMany(['meet.item','meet.actions'], function(_) {
app.template.loadMany(['meet.item','meet.actions'], async function(_) {
await waitUntil(function() {
return app.storage.get('emojis_cache') !== undefined;
}, 3);
app.pages.meet.paint(json);
app.pages.meet.paintInterval();
});
@ -57,7 +60,7 @@ app.pages.meet = {
var tpl = app.template.fill(item, app.template.get('meet.item'),
function (k,v) {
if (k === 'text') return app.post.prepare4html(item.text, item.tags);
if (k === 'account.name') return capitalize(v);
if (k === 'account.name') return app.emoji.expand(capitalize(v));
if (k === 'date') return dayjs(v).fromNow(true);
});