forked from andyburke/autonomous.contact
feature: reactions
This commit is contained in:
parent
6500d9a9be
commit
b8467ec870
16 changed files with 2603 additions and 383 deletions
|
|
@ -13,6 +13,7 @@
|
||||||
"test": {
|
"test": {
|
||||||
"exclude": ["tests/data/"]
|
"exclude": ["tests/data/"]
|
||||||
},
|
},
|
||||||
|
"compilerOptions": {},
|
||||||
"fmt": {
|
"fmt": {
|
||||||
"include": ["**/*.ts"],
|
"include": ["**/*.ts"],
|
||||||
"options": {
|
"options": {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import { by_character, by_lurid } from '@andyburke/fsdb/organizers';
|
import { by_character, by_lurid } from '@andyburke/fsdb/organizers';
|
||||||
import { FSDB_COLLECTION } from '@andyburke/fsdb';
|
import { FSDB_COLLECTION } from '@andyburke/fsdb';
|
||||||
import { FSDB_INDEXER_SYMLINKS } from '@andyburke/fsdb/indexers';
|
import { FSDB_INDEXER_SYMLINKS } from '@andyburke/fsdb/indexers';
|
||||||
import { EMOJI_MAP as JS_EMOJI_MAP } from '../public/js/emojis/en.js';
|
import { EMOJIS } from '../public/js/emojis/en.ts';
|
||||||
|
|
||||||
const EMOJI_MAP: Record<string, string[]> = JS_EMOJI_MAP;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {object} TIMESTAMPS
|
* @typedef {object} TIMESTAMPS
|
||||||
|
|
@ -124,7 +122,7 @@ export function VALIDATE_EVENT(event: EVENT) {
|
||||||
cause: 'reaction_must_be_an_emoji',
|
cause: 'reaction_must_be_an_emoji',
|
||||||
message: 'A reaction event must have a `data.reaction` that is an emoji.'
|
message: 'A reaction event must have a `data.reaction` that is an emoji.'
|
||||||
});
|
});
|
||||||
} else if (typeof EMOJI_MAP[event.data.reaction] === 'undefined') {
|
} else if (typeof EMOJIS.MAP[event.data?.reaction] === 'undefined') {
|
||||||
errors.push({
|
errors.push({
|
||||||
cause: 'reaction_must_be_an_emoji',
|
cause: 'reaction_must_be_an_emoji',
|
||||||
message: 'A reaction event must have a `data.reaction` that is an emoji.'
|
message: 'A reaction event must have a `data.reaction` that is an emoji.'
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ export async function GET(request: Request, meta: Record<string, any>): Promise<
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta.query.type && event_type !== meta.query.type) {
|
if (meta.query.type && !meta.query.type.split(',').includes(event_type)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,12 @@
|
||||||
|
|
||||||
<link rel="stylesheet" href="./base.css"></link>
|
<link rel="stylesheet" href="./base.css"></link>
|
||||||
|
|
||||||
|
<script src="./js/api.js" type="text/javascript"></script>
|
||||||
|
|
||||||
<script src="./js/audioplayer.js" type="text/javascript"></script>
|
<script src="./js/audioplayer.js" type="text/javascript"></script>
|
||||||
<script src="./js/datetimeutils.js" type="text/javascript"></script>
|
<script src="./js/datetimeutils.js" type="text/javascript"></script>
|
||||||
|
<script src="./js/debounce.js" type="text/javascript"></script>
|
||||||
|
<script src="./js/external/md_to_html.js" type="text/javascript"></script>
|
||||||
<script src="./js/embeds/audio.js" type="text/javascript"></script>
|
<script src="./js/embeds/audio.js" type="text/javascript"></script>
|
||||||
<script src="./js/embeds/gif.js" type="text/javascript"></script>
|
<script src="./js/embeds/gif.js" type="text/javascript"></script>
|
||||||
<script src="./js/embeds/image.js" type="text/javascript"></script>
|
<script src="./js/embeds/image.js" type="text/javascript"></script>
|
||||||
|
|
@ -25,18 +28,16 @@
|
||||||
<script src="./js/embeds/tidal.js" type="text/javascript"></script>
|
<script src="./js/embeds/tidal.js" type="text/javascript"></script>
|
||||||
<script src="./js/embeds/vimeo.js" type="text/javascript"></script>
|
<script src="./js/embeds/vimeo.js" type="text/javascript"></script>
|
||||||
<script src="./js/embeds/youtube.js" type="text/javascript"></script>
|
<script src="./js/embeds/youtube.js" type="text/javascript"></script>
|
||||||
|
<script src="./js/emojis/en.js" type="text/javascript"></script>
|
||||||
<script src="./js/external/md_to_html.js" type="text/javascript"></script>
|
|
||||||
|
|
||||||
<script src="./js/htmlify.js" type="text/javascript"></script>
|
<script src="./js/htmlify.js" type="text/javascript"></script>
|
||||||
|
|
||||||
<script src="./js/locationchange.js" type="text/javascript"></script>
|
<script src="./js/locationchange.js" type="text/javascript"></script>
|
||||||
<script src="./js/notifications.js" type="text/javascript"></script>
|
<script src="./js/notifications.js" type="text/javascript"></script>
|
||||||
<script src="./js/totp.js" type="text/javascript"></script>
|
<script src="./js/reactions.js" type="text/javascript"></script>
|
||||||
<script src="./js/api.js" type="text/javascript"></script>
|
|
||||||
<script src="./js/smartfeeds.js" type="text/javascript"></script>
|
<script src="./js/smartfeeds.js" type="text/javascript"></script>
|
||||||
<script src="./js/smartforms.js" type="text/javascript"></script>
|
<script src="./js/smartforms.js" type="text/javascript"></script>
|
||||||
<script src="./js/textareaenhancements.js" type="text/javascript"></script>
|
<script src="./js/textareaenhancements.js" type="text/javascript"></script>
|
||||||
|
<script src="./js/totp.js" type="text/javascript"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- #include file="./signup_login_wall.html" -->
|
<!-- #include file="./signup_login_wall.html" -->
|
||||||
|
|
|
||||||
7
public/js/debounce.js
Normal file
7
public/js/debounce.js
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
function debounce(fn, delay = 1_000) {
|
||||||
|
let timer = null;
|
||||||
|
return (...args) => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = setTimeout(() => fn(...args), delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export const EMOJI_MAP = {
|
const EMOJI_MAP = {
|
||||||
"☔": ["umbrella with rain drops"],
|
"☔": ["umbrella with rain drops"],
|
||||||
"☕": ["coffee"],
|
"☕": ["coffee"],
|
||||||
"♈": ["aries"],
|
"♈": ["aries"],
|
||||||
|
|
@ -38,264 +38,264 @@ export const EMOJI_MAP = {
|
||||||
"🆘": ["sos"],
|
"🆘": ["sos"],
|
||||||
"🆙": ["up"],
|
"🆙": ["up"],
|
||||||
"🆚": ["vs"],
|
"🆚": ["vs"],
|
||||||
"🇦🇨": ["flag: ac"],
|
"🇦🇨": ["flag ac"],
|
||||||
"🇦🇩": ["flag: ad"],
|
"🇦🇩": ["flag ad"],
|
||||||
"🇦🇪": ["flag: ae"],
|
"🇦🇪": ["flag ae"],
|
||||||
"🇦🇫": ["flag: af"],
|
"🇦🇫": ["flag af"],
|
||||||
"🇦🇬": ["flag: ag"],
|
"🇦🇬": ["flag ag"],
|
||||||
"🇦🇮": ["flag: ai"],
|
"🇦🇮": ["flag ai"],
|
||||||
"🇦🇱": ["flag: al"],
|
"🇦🇱": ["flag al"],
|
||||||
"🇦🇲": ["flag: am"],
|
"🇦🇲": ["flag am"],
|
||||||
"🇦🇴": ["flag: ao"],
|
"🇦🇴": ["flag ao"],
|
||||||
"🇦🇶": ["flag: aq"],
|
"🇦🇶": ["flag aq"],
|
||||||
"🇦🇷": ["flag: ar"],
|
"🇦🇷": ["flag ar"],
|
||||||
"🇦🇸": ["flag: as"],
|
"🇦🇸": ["flag as"],
|
||||||
"🇦🇹": ["flag: at"],
|
"🇦🇹": ["flag at"],
|
||||||
"🇦🇺": ["flag: au"],
|
"🇦🇺": ["flag au"],
|
||||||
"🇦🇼": ["flag: aw"],
|
"🇦🇼": ["flag aw"],
|
||||||
"🇦🇽": ["flag: ax"],
|
"🇦🇽": ["flag ax"],
|
||||||
"🇦🇿": ["flag: az"],
|
"🇦🇿": ["flag az"],
|
||||||
"🇧🇦": ["flag: ba"],
|
"🇧🇦": ["flag ba"],
|
||||||
"🇧🇧": ["flag: bb"],
|
"🇧🇧": ["flag bb"],
|
||||||
"🇧🇩": ["flag: bd"],
|
"🇧🇩": ["flag bd"],
|
||||||
"🇧🇪": ["flag: be"],
|
"🇧🇪": ["flag be"],
|
||||||
"🇧🇫": ["flag: bf"],
|
"🇧🇫": ["flag bf"],
|
||||||
"🇧🇬": ["flag: bg"],
|
"🇧🇬": ["flag bg"],
|
||||||
"🇧🇭": ["flag: bh"],
|
"🇧🇭": ["flag bh"],
|
||||||
"🇧🇮": ["flag: bi"],
|
"🇧🇮": ["flag bi"],
|
||||||
"🇧🇯": ["flag: bj"],
|
"🇧🇯": ["flag bj"],
|
||||||
"🇧🇱": ["flag: bl"],
|
"🇧🇱": ["flag bl"],
|
||||||
"🇧🇲": ["flag: bm"],
|
"🇧🇲": ["flag bm"],
|
||||||
"🇧🇳": ["flag: bn"],
|
"🇧🇳": ["flag bn"],
|
||||||
"🇧🇴": ["flag: bo"],
|
"🇧🇴": ["flag bo"],
|
||||||
"🇧🇶": ["flag: bq"],
|
"🇧🇶": ["flag bq"],
|
||||||
"🇧🇷": ["flag: br"],
|
"🇧🇷": ["flag br"],
|
||||||
"🇧🇸": ["flag: bs"],
|
"🇧🇸": ["flag bs"],
|
||||||
"🇧🇹": ["flag: bt"],
|
"🇧🇹": ["flag bt"],
|
||||||
"🇧🇻": ["flag: bv"],
|
"🇧🇻": ["flag bv"],
|
||||||
"🇧🇼": ["flag: bw"],
|
"🇧🇼": ["flag bw"],
|
||||||
"🇧🇾": ["flag: by"],
|
"🇧🇾": ["flag by"],
|
||||||
"🇧🇿": ["flag: bz"],
|
"🇧🇿": ["flag bz"],
|
||||||
"🇨🇦": ["flag: ca"],
|
"🇨🇦": ["flag ca"],
|
||||||
"🇨🇨": ["flag: cc"],
|
"🇨🇨": ["flag cc"],
|
||||||
"🇨🇩": ["flag: cd"],
|
"🇨🇩": ["flag cd"],
|
||||||
"🇨🇫": ["flag: cf"],
|
"🇨🇫": ["flag cf"],
|
||||||
"🇨🇬": ["flag: cg"],
|
"🇨🇬": ["flag cg"],
|
||||||
"🇨🇭": ["flag: ch"],
|
"🇨🇭": ["flag ch"],
|
||||||
"🇨🇮": ["flag: ci"],
|
"🇨🇮": ["flag ci"],
|
||||||
"🇨🇰": ["flag: ck"],
|
"🇨🇰": ["flag ck"],
|
||||||
"🇨🇱": ["flag: cl"],
|
"🇨🇱": ["flag cl"],
|
||||||
"🇨🇲": ["flag: cm"],
|
"🇨🇲": ["flag cm"],
|
||||||
"🇨🇳": ["flag: cn"],
|
"🇨🇳": ["flag cn"],
|
||||||
"🇨🇴": ["flag: co"],
|
"🇨🇴": ["flag co"],
|
||||||
"🇨🇵": ["flag: cp"],
|
"🇨🇵": ["flag cp"],
|
||||||
"🇨🇷": ["flag: cr"],
|
"🇨🇷": ["flag cr"],
|
||||||
"🇨🇺": ["flag: cu"],
|
"🇨🇺": ["flag cu"],
|
||||||
"🇨🇻": ["flag: cv"],
|
"🇨🇻": ["flag cv"],
|
||||||
"🇨🇼": ["flag: cw"],
|
"🇨🇼": ["flag cw"],
|
||||||
"🇨🇽": ["flag: cx"],
|
"🇨🇽": ["flag cx"],
|
||||||
"🇨🇾": ["flag: cy"],
|
"🇨🇾": ["flag cy"],
|
||||||
"🇨🇿": ["flag: cz"],
|
"🇨🇿": ["flag cz"],
|
||||||
"🇩🇪": ["flag: de"],
|
"🇩🇪": ["flag de"],
|
||||||
"🇩🇬": ["flag: dg"],
|
"🇩🇬": ["flag dg"],
|
||||||
"🇩🇯": ["flag: dj"],
|
"🇩🇯": ["flag dj"],
|
||||||
"🇩🇰": ["flag: dk"],
|
"🇩🇰": ["flag dk"],
|
||||||
"🇩🇲": ["flag: dm"],
|
"🇩🇲": ["flag dm"],
|
||||||
"🇩🇴": ["flag: do"],
|
"🇩🇴": ["flag do"],
|
||||||
"🇩🇿": ["flag: dz"],
|
"🇩🇿": ["flag dz"],
|
||||||
"🇪🇦": ["flag: ea"],
|
"🇪🇦": ["flag ea"],
|
||||||
"🇪🇨": ["flag: ec"],
|
"🇪🇨": ["flag ec"],
|
||||||
"🇪🇪": ["flag: ee"],
|
"🇪🇪": ["flag ee"],
|
||||||
"🇪🇬": ["flag: eg"],
|
"🇪🇬": ["flag eg"],
|
||||||
"🇪🇭": ["flag: eh"],
|
"🇪🇭": ["flag eh"],
|
||||||
"🇪🇷": ["flag: er"],
|
"🇪🇷": ["flag er"],
|
||||||
"🇪🇸": ["flag: es"],
|
"🇪🇸": ["flag es"],
|
||||||
"🇪🇹": ["flag: et"],
|
"🇪🇹": ["flag et"],
|
||||||
"🇪🇺": ["flag: eu"],
|
"🇪🇺": ["flag eu"],
|
||||||
"🇫🇮": ["flag: fi"],
|
"🇫🇮": ["flag fi"],
|
||||||
"🇫🇯": ["flag: fj"],
|
"🇫🇯": ["flag fj"],
|
||||||
"🇫🇰": ["flag: fk"],
|
"🇫🇰": ["flag fk"],
|
||||||
"🇫🇲": ["flag: fm"],
|
"🇫🇲": ["flag fm"],
|
||||||
"🇫🇴": ["flag: fo"],
|
"🇫🇴": ["flag fo"],
|
||||||
"🇫🇷": ["flag: fr"],
|
"🇫🇷": ["flag fr"],
|
||||||
"🇬🇦": ["flag: ga"],
|
"🇬🇦": ["flag ga"],
|
||||||
"🇬🇧": ["flag: gb", "flag: uk"],
|
"🇬🇧": ["flag gb", "flag uk"],
|
||||||
"🇬🇩": ["flag: gd"],
|
"🇬🇩": ["flag gd"],
|
||||||
"🇬🇪": ["flag: ge"],
|
"🇬🇪": ["flag ge"],
|
||||||
"🇬🇫": ["flag: gf"],
|
"🇬🇫": ["flag gf"],
|
||||||
"🇬🇬": ["flag: gg"],
|
"🇬🇬": ["flag gg"],
|
||||||
"🇬🇭": ["flag: gh"],
|
"🇬🇭": ["flag gh"],
|
||||||
"🇬🇮": ["flag: gi"],
|
"🇬🇮": ["flag gi"],
|
||||||
"🇬🇱": ["flag: gl"],
|
"🇬🇱": ["flag gl"],
|
||||||
"🇬🇲": ["flag: gm"],
|
"🇬🇲": ["flag gm"],
|
||||||
"🇬🇳": ["flag: gn"],
|
"🇬🇳": ["flag gn"],
|
||||||
"🇬🇵": ["flag: gp"],
|
"🇬🇵": ["flag gp"],
|
||||||
"🇬🇶": ["flag: gq"],
|
"🇬🇶": ["flag gq"],
|
||||||
"🇬🇷": ["flag: gr"],
|
"🇬🇷": ["flag gr"],
|
||||||
"🇬🇸": ["flag: gs"],
|
"🇬🇸": ["flag gs"],
|
||||||
"🇬🇹": ["flag: gt"],
|
"🇬🇹": ["flag gt"],
|
||||||
"🇬🇺": ["flag: gu"],
|
"🇬🇺": ["flag gu"],
|
||||||
"🇬🇼": ["flag: gw"],
|
"🇬🇼": ["flag gw"],
|
||||||
"🇬🇾": ["flag: gy"],
|
"🇬🇾": ["flag gy"],
|
||||||
"🇭🇰": ["flag: hk"],
|
"🇭🇰": ["flag hk"],
|
||||||
"🇭🇲": ["flag: hm"],
|
"🇭🇲": ["flag hm"],
|
||||||
"🇭🇳": ["flag: hn"],
|
"🇭🇳": ["flag hn"],
|
||||||
"🇭🇷": ["flag: hr"],
|
"🇭🇷": ["flag hr"],
|
||||||
"🇭🇹": ["flag: ht"],
|
"🇭🇹": ["flag ht"],
|
||||||
"🇭🇺": ["flag: hu"],
|
"🇭🇺": ["flag hu"],
|
||||||
"🇮🇨": ["flag: ic"],
|
"🇮🇨": ["flag ic"],
|
||||||
"🇮🇩": ["flag: id"],
|
"🇮🇩": ["flag id"],
|
||||||
"🇮🇪": ["flag: ie"],
|
"🇮🇪": ["flag ie"],
|
||||||
"🇮🇱": ["flag: il"],
|
"🇮🇱": ["flag il"],
|
||||||
"🇮🇲": ["flag: im"],
|
"🇮🇲": ["flag im"],
|
||||||
"🇮🇳": ["flag: in"],
|
"🇮🇳": ["flag in"],
|
||||||
"🇮🇴": ["flag: io"],
|
"🇮🇴": ["flag io"],
|
||||||
"🇮🇶": ["flag: iq"],
|
"🇮🇶": ["flag iq"],
|
||||||
"🇮🇷": ["flag: ir"],
|
"🇮🇷": ["flag ir"],
|
||||||
"🇮🇸": ["flag: is"],
|
"🇮🇸": ["flag is"],
|
||||||
"🇮🇹": ["flag: it"],
|
"🇮🇹": ["flag it"],
|
||||||
"🇯🇪": ["flag: je"],
|
"🇯🇪": ["flag je"],
|
||||||
"🇯🇲": ["flag: jm"],
|
"🇯🇲": ["flag jm"],
|
||||||
"🇯🇴": ["flag: jo"],
|
"🇯🇴": ["flag jo"],
|
||||||
"🇯🇵": ["flag: jp"],
|
"🇯🇵": ["flag jp"],
|
||||||
"🇰🇪": ["flag: ke"],
|
"🇰🇪": ["flag ke"],
|
||||||
"🇰🇬": ["flag: kg"],
|
"🇰🇬": ["flag kg"],
|
||||||
"🇰🇭": ["flag: kh"],
|
"🇰🇭": ["flag kh"],
|
||||||
"🇰🇮": ["flag: ki"],
|
"🇰🇮": ["flag ki"],
|
||||||
"🇰🇲": ["flag: km"],
|
"🇰🇲": ["flag km"],
|
||||||
"🇰🇳": ["flag: kn"],
|
"🇰🇳": ["flag kn"],
|
||||||
"🇰🇵": ["flag: kp"],
|
"🇰🇵": ["flag kp"],
|
||||||
"🇰🇷": ["flag: kr"],
|
"🇰🇷": ["flag kr"],
|
||||||
"🇰🇼": ["flag: kw"],
|
"🇰🇼": ["flag kw"],
|
||||||
"🇰🇾": ["flag: ky"],
|
"🇰🇾": ["flag ky"],
|
||||||
"🇰🇿": ["flag: kz"],
|
"🇰🇿": ["flag kz"],
|
||||||
"🇱🇦": ["flag: la"],
|
"🇱🇦": ["flag la"],
|
||||||
"🇱🇧": ["flag: lb"],
|
"🇱🇧": ["flag lb"],
|
||||||
"🇱🇨": ["flag: lc"],
|
"🇱🇨": ["flag lc"],
|
||||||
"🇱🇮": ["flag: li"],
|
"🇱🇮": ["flag li"],
|
||||||
"🇱🇰": ["flag: lk"],
|
"🇱🇰": ["flag lk"],
|
||||||
"🇱🇷": ["flag: lr"],
|
"🇱🇷": ["flag lr"],
|
||||||
"🇱🇸": ["flag: ls"],
|
"🇱🇸": ["flag ls"],
|
||||||
"🇱🇹": ["flag: lt"],
|
"🇱🇹": ["flag lt"],
|
||||||
"🇱🇺": ["flag: lu"],
|
"🇱🇺": ["flag lu"],
|
||||||
"🇱🇻": ["flag: lv"],
|
"🇱🇻": ["flag lv"],
|
||||||
"🇱🇾": ["flag: ly"],
|
"🇱🇾": ["flag ly"],
|
||||||
"🇲🇦": ["flag: ma"],
|
"🇲🇦": ["flag ma"],
|
||||||
"🇲🇨": ["flag: mc"],
|
"🇲🇨": ["flag mc"],
|
||||||
"🇲🇩": ["flag: md"],
|
"🇲🇩": ["flag md"],
|
||||||
"🇲🇪": ["flag: me"],
|
"🇲🇪": ["flag me"],
|
||||||
"🇲🇫": ["flag: mf"],
|
"🇲🇫": ["flag mf"],
|
||||||
"🇲🇬": ["flag: mg"],
|
"🇲🇬": ["flag mg"],
|
||||||
"🇲🇭": ["flag: mh"],
|
"🇲🇭": ["flag mh"],
|
||||||
"🇲🇰": ["flag: mk"],
|
"🇲🇰": ["flag mk"],
|
||||||
"🇲🇱": ["flag: ml"],
|
"🇲🇱": ["flag ml"],
|
||||||
"🇲🇲": ["flag: mm"],
|
"🇲🇲": ["flag mm"],
|
||||||
"🇲🇳": ["flag: mn"],
|
"🇲🇳": ["flag mn"],
|
||||||
"🇲🇴": ["flag: mo"],
|
"🇲🇴": ["flag mo"],
|
||||||
"🇲🇵": ["flag: mp"],
|
"🇲🇵": ["flag mp"],
|
||||||
"🇲🇶": ["flag: mq"],
|
"🇲🇶": ["flag mq"],
|
||||||
"🇲🇷": ["flag: mr"],
|
"🇲🇷": ["flag mr"],
|
||||||
"🇲🇸": ["flag: ms"],
|
"🇲🇸": ["flag ms"],
|
||||||
"🇲🇹": ["flag: mt"],
|
"🇲🇹": ["flag mt"],
|
||||||
"🇲🇺": ["flag: mu"],
|
"🇲🇺": ["flag mu"],
|
||||||
"🇲🇻": ["flag: mv"],
|
"🇲🇻": ["flag mv"],
|
||||||
"🇲🇼": ["flag: mw"],
|
"🇲🇼": ["flag mw"],
|
||||||
"🇲🇽": ["flag: mx"],
|
"🇲🇽": ["flag mx"],
|
||||||
"🇲🇾": ["flag: my"],
|
"🇲🇾": ["flag my"],
|
||||||
"🇲🇿": ["flag: mz"],
|
"🇲🇿": ["flag mz"],
|
||||||
"🇳🇦": ["flag: na"],
|
"🇳🇦": ["flag na"],
|
||||||
"🇳🇨": ["flag: nc"],
|
"🇳🇨": ["flag nc"],
|
||||||
"🇳🇪": ["flag: ne"],
|
"🇳🇪": ["flag ne"],
|
||||||
"🇳🇫": ["flag: nf"],
|
"🇳🇫": ["flag nf"],
|
||||||
"🇳🇬": ["flag: ng"],
|
"🇳🇬": ["flag ng"],
|
||||||
"🇳🇮": ["flag: ni"],
|
"🇳🇮": ["flag ni"],
|
||||||
"🇳🇱": ["flag: nl"],
|
"🇳🇱": ["flag nl"],
|
||||||
"🇳🇴": ["flag: no"],
|
"🇳🇴": ["flag no"],
|
||||||
"🇳🇵": ["flag: np"],
|
"🇳🇵": ["flag np"],
|
||||||
"🇳🇷": ["flag: nr"],
|
"🇳🇷": ["flag nr"],
|
||||||
"🇳🇺": ["flag: nu"],
|
"🇳🇺": ["flag nu"],
|
||||||
"🇳🇿": ["flag: nz"],
|
"🇳🇿": ["flag nz"],
|
||||||
"🇴🇲": ["flag: om"],
|
"🇴🇲": ["flag om"],
|
||||||
"🇵🇦": ["flag: pa"],
|
"🇵🇦": ["flag pa"],
|
||||||
"🇵🇪": ["flag: pe"],
|
"🇵🇪": ["flag pe"],
|
||||||
"🇵🇫": ["flag: pf"],
|
"🇵🇫": ["flag pf"],
|
||||||
"🇵🇬": ["flag: pg"],
|
"🇵🇬": ["flag pg"],
|
||||||
"🇵🇭": ["flag: ph"],
|
"🇵🇭": ["flag ph"],
|
||||||
"🇵🇰": ["flag: pk"],
|
"🇵🇰": ["flag pk"],
|
||||||
"🇵🇱": ["flag: pl"],
|
"🇵🇱": ["flag pl"],
|
||||||
"🇵🇲": ["flag: pm"],
|
"🇵🇲": ["flag pm"],
|
||||||
"🇵🇳": ["flag: pn"],
|
"🇵🇳": ["flag pn"],
|
||||||
"🇵🇷": ["flag: pr"],
|
"🇵🇷": ["flag pr"],
|
||||||
"🇵🇸": ["flag: ps"],
|
"🇵🇸": ["flag ps"],
|
||||||
"🇵🇹": ["flag: pt"],
|
"🇵🇹": ["flag pt"],
|
||||||
"🇵🇼": ["flag: pw"],
|
"🇵🇼": ["flag pw"],
|
||||||
"🇵🇾": ["flag: py"],
|
"🇵🇾": ["flag py"],
|
||||||
"🇶🇦": ["flag: qa"],
|
"🇶🇦": ["flag qa"],
|
||||||
"🇷🇪": ["flag: re"],
|
"🇷🇪": ["flag re"],
|
||||||
"🇷🇴": ["flag: ro"],
|
"🇷🇴": ["flag ro"],
|
||||||
"🇷🇸": ["flag: rs"],
|
"🇷🇸": ["flag rs"],
|
||||||
"🇷🇺": ["flag: ru"],
|
"🇷🇺": ["flag ru"],
|
||||||
"🇷🇼": ["flag: rw"],
|
"🇷🇼": ["flag rw"],
|
||||||
"🇸🇦": ["flag: sa"],
|
"🇸🇦": ["flag sa"],
|
||||||
"🇸🇧": ["flag: sb"],
|
"🇸🇧": ["flag sb"],
|
||||||
"🇸🇨": ["flag: sc"],
|
"🇸🇨": ["flag sc"],
|
||||||
"🇸🇩": ["flag: sd"],
|
"🇸🇩": ["flag sd"],
|
||||||
"🇸🇪": ["flag: se"],
|
"🇸🇪": ["flag se"],
|
||||||
"🇸🇬": ["flag: sg"],
|
"🇸🇬": ["flag sg"],
|
||||||
"🇸🇭": ["flag: sh"],
|
"🇸🇭": ["flag sh"],
|
||||||
"🇸🇮": ["flag: si"],
|
"🇸🇮": ["flag si"],
|
||||||
"🇸🇯": ["flag: sj"],
|
"🇸🇯": ["flag sj"],
|
||||||
"🇸🇰": ["flag: sk"],
|
"🇸🇰": ["flag sk"],
|
||||||
"🇸🇱": ["flag: sl"],
|
"🇸🇱": ["flag sl"],
|
||||||
"🇸🇲": ["flag: sm"],
|
"🇸🇲": ["flag sm"],
|
||||||
"🇸🇳": ["flag: sn"],
|
"🇸🇳": ["flag sn"],
|
||||||
"🇸🇴": ["flag: so"],
|
"🇸🇴": ["flag so"],
|
||||||
"🇸🇷": ["flag: sr"],
|
"🇸🇷": ["flag sr"],
|
||||||
"🇸🇸": ["flag: ss"],
|
"🇸🇸": ["flag ss"],
|
||||||
"🇸🇹": ["flag: st"],
|
"🇸🇹": ["flag st"],
|
||||||
"🇸🇻": ["flag: sv"],
|
"🇸🇻": ["flag sv"],
|
||||||
"🇸🇽": ["flag: sx"],
|
"🇸🇽": ["flag sx"],
|
||||||
"🇸🇾": ["flag: sy"],
|
"🇸🇾": ["flag sy"],
|
||||||
"🇸🇿": ["flag: sz"],
|
"🇸🇿": ["flag sz"],
|
||||||
"🇹🇦": ["flag: ta"],
|
"🇹🇦": ["flag ta"],
|
||||||
"🇹🇨": ["flag: tc"],
|
"🇹🇨": ["flag tc"],
|
||||||
"🇹🇩": ["flag: td"],
|
"🇹🇩": ["flag td"],
|
||||||
"🇹🇫": ["flag: tf"],
|
"🇹🇫": ["flag tf"],
|
||||||
"🇹🇬": ["flag: tg"],
|
"🇹🇬": ["flag tg"],
|
||||||
"🇹🇭": ["flag: th"],
|
"🇹🇭": ["flag th"],
|
||||||
"🇹🇯": ["flag: tj"],
|
"🇹🇯": ["flag tj"],
|
||||||
"🇹🇰": ["flag: tk"],
|
"🇹🇰": ["flag tk"],
|
||||||
"🇹🇱": ["flag: tl"],
|
"🇹🇱": ["flag tl"],
|
||||||
"🇹🇲": ["flag: tm"],
|
"🇹🇲": ["flag tm"],
|
||||||
"🇹🇳": ["flag: tn"],
|
"🇹🇳": ["flag tn"],
|
||||||
"🇹🇴": ["flag: to"],
|
"🇹🇴": ["flag to"],
|
||||||
"🇹🇷": ["flag: tr"],
|
"🇹🇷": ["flag tr"],
|
||||||
"🇹🇹": ["flag: tt"],
|
"🇹🇹": ["flag tt"],
|
||||||
"🇹🇻": ["flag: tv"],
|
"🇹🇻": ["flag tv"],
|
||||||
"🇹🇼": ["flag: tw"],
|
"🇹🇼": ["flag tw"],
|
||||||
"🇹🇿": ["flag: tz"],
|
"🇹🇿": ["flag tz"],
|
||||||
"🇺🇦": ["flag: ua"],
|
"🇺🇦": ["flag ua"],
|
||||||
"🇺🇬": ["flag: ug"],
|
"🇺🇬": ["flag ug"],
|
||||||
"🇺🇲": ["flag: um"],
|
"🇺🇲": ["flag um"],
|
||||||
"🇺🇳": ["flag: un"],
|
"🇺🇳": ["flag un"],
|
||||||
"🇺🇸": ["flag: us", "flag: usa"],
|
"🇺🇸": ["flag us", "flag usa"],
|
||||||
"🇺🇾": ["flag: uy"],
|
"🇺🇾": ["flag uy"],
|
||||||
"🇺🇿": ["flag: uz"],
|
"🇺🇿": ["flag uz"],
|
||||||
"🇻🇦": ["flag: va"],
|
"🇻🇦": ["flag va"],
|
||||||
"🇻🇨": ["flag: vc"],
|
"🇻🇨": ["flag vc"],
|
||||||
"🇻🇪": ["flag: ve"],
|
"🇻🇪": ["flag ve"],
|
||||||
"🇻🇬": ["flag: vg"],
|
"🇻🇬": ["flag vg"],
|
||||||
"🇻🇮": ["flag: vi"],
|
"🇻🇮": ["flag vi"],
|
||||||
"🇻🇳": ["flag: vn"],
|
"🇻🇳": ["flag vn"],
|
||||||
"🇻🇺": ["flag: vu"],
|
"🇻🇺": ["flag vu"],
|
||||||
"🇼🇫": ["flag: wf"],
|
"🇼🇫": ["flag wf"],
|
||||||
"🇼🇸": ["flag: ws"],
|
"🇼🇸": ["flag ws"],
|
||||||
"🇽🇰": ["flag: xk"],
|
"🇽🇰": ["flag xk"],
|
||||||
"🇾🇪": ["flag: ye"],
|
"🇾🇪": ["flag ye"],
|
||||||
"🇾🇹": ["flag: yt"],
|
"🇾🇹": ["flag yt"],
|
||||||
"🇿🇦": ["flag: za"],
|
"🇿🇦": ["flag za"],
|
||||||
"🇿🇲": ["flag: zm"],
|
"🇿🇲": ["flag zm"],
|
||||||
"🇿🇼": ["flag: zw"],
|
"🇿🇼": ["flag zw"],
|
||||||
"🌀": ["cyclone"],
|
"🌀": ["cyclone"],
|
||||||
"🌁": ["foggy"],
|
"🌁": ["foggy"],
|
||||||
"🌂": ["closed umbrella"],
|
"🌂": ["closed umbrella"],
|
||||||
|
|
@ -482,7 +482,7 @@ export const EMOJI_MAP = {
|
||||||
"🎾": ["tennis"],
|
"🎾": ["tennis"],
|
||||||
"🎿": ["ski"],
|
"🎿": ["ski"],
|
||||||
"🏀": ["basketball"],
|
"🏀": ["basketball"],
|
||||||
"🏁": ["flag: checkered", "checkered flag"],
|
"🏁": ["flag checkered", "checkered flag"],
|
||||||
"🏂": ["snowboarder"],
|
"🏂": ["snowboarder"],
|
||||||
"🏃♀️": ["running"],
|
"🏃♀️": ["running"],
|
||||||
"🏃♂️": ["running"],
|
"🏃♂️": ["running"],
|
||||||
|
|
@ -535,14 +535,14 @@ export const EMOJI_MAP = {
|
||||||
"🏮": ["izakaya lantern", "lantern"],
|
"🏮": ["izakaya lantern", "lantern"],
|
||||||
"🏯": ["japanese castle"],
|
"🏯": ["japanese castle"],
|
||||||
"🏰": ["european castle"],
|
"🏰": ["european castle"],
|
||||||
"🏳️🌈": ["flag: rainbow"],
|
"🏳️🌈": ["flag rainbow"],
|
||||||
"🏳️⚧️": ["flag: transgender"],
|
"🏳️⚧️": ["flag transgender"],
|
||||||
"🏳️": ["flag: white", "waving white flag"],
|
"🏳️": ["flag white", "waving white flag"],
|
||||||
"🏴☠️": ["flag: pirate", "pirate flag"],
|
"🏴☠️": ["flag pirate", "pirate flag"],
|
||||||
"🏴": ["flag: england"],
|
"🏴": ["flag england"],
|
||||||
"🏴": ["flag: scotland"],
|
"🏴": ["flag scotland"],
|
||||||
"🏴": ["flag: wales"],
|
"🏴": ["flag wales"],
|
||||||
"🏴": ["flag: black", "waving black flag"],
|
"🏴": ["flag black", "waving black flag"],
|
||||||
"🏵️": ["rosette"],
|
"🏵️": ["rosette"],
|
||||||
"🏷️": ["label"],
|
"🏷️": ["label"],
|
||||||
"🏸": ["badminton racquet and shuttlecock"],
|
"🏸": ["badminton racquet and shuttlecock"],
|
||||||
|
|
@ -959,30 +959,30 @@ export const EMOJI_MAP = {
|
||||||
"🕌": ["mosque"],
|
"🕌": ["mosque"],
|
||||||
"🕍": ["synagogue"],
|
"🕍": ["synagogue"],
|
||||||
"🕎": ["menorah with nine branches"],
|
"🕎": ["menorah with nine branches"],
|
||||||
"🕐": ["clock 01:00", "clock 13:00", "clock1"],
|
"🕐": ["clock 0100", "clock 1300", "clock1"],
|
||||||
"🕑": ["clock 02:00", "clock 14:00", "clock2"],
|
"🕑": ["clock 0200", "clock 1400", "clock2"],
|
||||||
"🕒": ["clock 03:00", "clock 15:00", "clock3"],
|
"🕒": ["clock 0300", "clock 1500", "clock3"],
|
||||||
"🕓": ["clock 04:00", "clock 16:00", "clock4"],
|
"🕓": ["clock 0400", "clock 1600", "clock4"],
|
||||||
"🕔": ["clock 05:00", "clock 17:00", "clock5"],
|
"🕔": ["clock 0500", "clock 1700", "clock5"],
|
||||||
"🕕": ["clock 06:00", "clock 18:00", "clock6"],
|
"🕕": ["clock 0600", "clock 1800", "clock6"],
|
||||||
"🕖": ["clock 07:00", "clock 19:00", "clock7"],
|
"🕖": ["clock 0700", "clock 1900", "clock7"],
|
||||||
"🕗": ["clock 08:00", "clock 20:00", "clock8"],
|
"🕗": ["clock 0800", "clock 2000", "clock8"],
|
||||||
"🕘": ["clock 09:00", "clock 21:00", "clock9"],
|
"🕘": ["clock 0900", "clock 2100", "clock9"],
|
||||||
"🕙": ["clock 10:00", "clock 22:00", "clock10"],
|
"🕙": ["clock 1000", "clock 2200", "clock10"],
|
||||||
"🕚": ["clock 11:00", "clock 23:00", "clock11"],
|
"🕚": ["clock 1100", "clock 2300", "clock11"],
|
||||||
"🕛": ["clock 12:00", "clock 24:00", "clock12"],
|
"🕛": ["clock 1200", "clock 2400", "clock12"],
|
||||||
"🕜": ["clock 01:30", "clock 13:30", "clock130"],
|
"🕜": ["clock 0130", "clock 1330", "clock130"],
|
||||||
"🕝": ["clock 02:30", "clock 14:30", "clock230"],
|
"🕝": ["clock 0230", "clock 1430", "clock230"],
|
||||||
"🕞": ["clock 03:30", "clock 15:30", "clock330"],
|
"🕞": ["clock 0330", "clock 1530", "clock330"],
|
||||||
"🕟": ["clock 04:30", "clock 16:30", "clock430"],
|
"🕟": ["clock 0430", "clock 1630", "clock430"],
|
||||||
"🕠": ["clock 05:30", "clock 17:30", "clock530"],
|
"🕠": ["clock 0530", "clock 1730", "clock530"],
|
||||||
"🕡": ["clock 06:30", "clock 18:30", "clock630"],
|
"🕡": ["clock 0630", "clock 1830", "clock630"],
|
||||||
"🕢": ["clock 07:30", "clock 19:30", "clock730"],
|
"🕢": ["clock 0730", "clock 1930", "clock730"],
|
||||||
"🕣": ["clock 08:30", "clock 20:30", "clock830"],
|
"🕣": ["clock 0830", "clock 2030", "clock830"],
|
||||||
"🕤": ["clock 09:30", "clock 21:30", "clock930"],
|
"🕤": ["clock 0930", "clock 2130", "clock930"],
|
||||||
"🕥": ["clock 10:30", "clock 22:30", "clock1030"],
|
"🕥": ["clock 1030", "clock 2230", "clock1030"],
|
||||||
"🕦": ["clock 11:30", "clock 23:30", "clock1130"],
|
"🕦": ["clock 1130", "clock 2330", "clock1130"],
|
||||||
"🕧": ["clock 00:30", "clock 12:30", "clock1230"],
|
"🕧": ["clock 0030", "clock 1230", "clock1230"],
|
||||||
"🕯️": ["candle"],
|
"🕯️": ["candle"],
|
||||||
"🕰️": ["mantelpiece clock"],
|
"🕰️": ["mantelpiece clock"],
|
||||||
"🕳️": ["hole"],
|
"🕳️": ["hole"],
|
||||||
|
|
@ -1807,53 +1807,52 @@ export const EMOJI_MAP = {
|
||||||
"㊙️": ["secret"],
|
"㊙️": ["secret"],
|
||||||
};
|
};
|
||||||
|
|
||||||
EMOJI_MAP.filter = function (filter) {
|
let _EMOJI_WORDS;
|
||||||
const result = {};
|
const EMOJIS = {
|
||||||
if (typeof filter === "function") {
|
MAP: EMOJI_MAP,
|
||||||
for (const entry of Object.entries(this)) {
|
|
||||||
if (filter(entry)) {
|
filter: function (filter) {
|
||||||
result[entry[0]] = entry[1];
|
const result = {};
|
||||||
|
if (typeof filter === "function") {
|
||||||
|
for (const entry of Object.entries(this.MAP)) {
|
||||||
|
if (filter(entry)) {
|
||||||
|
result[entry[0]] = entry[1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (Array.isArray(filter)) {
|
||||||
|
const matchers = [];
|
||||||
|
for (const f of filter) {
|
||||||
|
matchers.push(
|
||||||
|
new RegExp(
|
||||||
|
`[\\u{${parseInt(f[0]).toString(16)}}-\\u{${parseInt(f[1]).toString(16)}}]`,
|
||||||
|
"u",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const entry of Object.entries(this.MAP)) {
|
||||||
|
const matches = matchers.some((matcher) => matcher.test(entry[0]));
|
||||||
|
if (matches) {
|
||||||
|
result[entry[0]] = entry[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error("unknown filter type");
|
||||||
}
|
}
|
||||||
} else if (Array.isArray(filter)) {
|
|
||||||
const matchers = [];
|
return result;
|
||||||
for (const f of filter) {
|
},
|
||||||
matchers.push(
|
|
||||||
new RegExp(
|
autocomplete: function (prompt) {
|
||||||
`[\\u{${parseInt(f[0]).toString(16)}}-\\u{${parseInt(f[1]).toString(16)}}]`,
|
const results = Object.entries(this.MAP).filter((entry) => {
|
||||||
"u",
|
return entry[1].some(
|
||||||
),
|
(name) =>
|
||||||
|
name.toLowerCase().indexOf(prompt) >= 0 ||
|
||||||
|
prompt.toLowerCase().indexOf(name) >= 0,
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
return results;
|
||||||
for (const entry of Object.entries(this)) {
|
},
|
||||||
const matches = matchers.some((matcher) => matcher.test(entry[0]));
|
|
||||||
if (matches) {
|
|
||||||
result[entry[0]] = entry[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error("unknown filter type");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
let EMOJI_WORDS;
|
|
||||||
EMOJI_MAP.autocomplete = function (prompt) {
|
|
||||||
EMOJI_WORDS =
|
|
||||||
EMOJI_WORDS ??
|
|
||||||
Object.values(this).reduce((_EMOJI_WORDS, words) => {
|
|
||||||
if (Array.isArray(words)) {
|
|
||||||
_EMOJI_WORDS.push(...words);
|
|
||||||
}
|
|
||||||
return _EMOJI_WORDS;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const results = EMOJI_WORDS.filter((word) => {
|
|
||||||
return word.toLowerCase().indexOf(prompt) >= 0 || prompt.toLowerCase().indexOf(word) >= 0;
|
|
||||||
});
|
|
||||||
return results;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* VERY limited testing:
|
/* VERY limited testing:
|
||||||
|
|
|
||||||
1867
public/js/emojis/en.ts
Normal file
1867
public/js/emojis/en.ts
Normal file
File diff suppressed because it is too large
Load diff
256
public/js/reactions.js
Normal file
256
public/js/reactions.js
Normal file
|
|
@ -0,0 +1,256 @@
|
||||||
|
const reactions_popup_width = 280;
|
||||||
|
const reactions_popup_height = 280;
|
||||||
|
|
||||||
|
const reactions_popup_styling = `
|
||||||
|
#reactionspopup {
|
||||||
|
position: fixed;
|
||||||
|
width: ${reactions_popup_width}px;
|
||||||
|
height: ${reactions_popup_height}px;
|
||||||
|
z-index: 100;
|
||||||
|
background: inherit;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--border-normal);
|
||||||
|
padding: 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#reactionspopup .icon.close {
|
||||||
|
float: right;
|
||||||
|
margin: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#reactionspopup input[name="search"] {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#reactionspopup ul {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
text-align: left;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
#reactionspopup ul li {
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#reactionspopup ul[data-filtered] li {
|
||||||
|
display: none;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#reactionspopup ul[data-filtered] li[data-filtered] {
|
||||||
|
display: inline-block;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
#reactionspopup #reactions-names-display {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 2rem;
|
||||||
|
background: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
function get_best_coords_for_popup(target, offset = { x: 10, y: 10 }) {
|
||||||
|
const target_x = target?.getBoundingClientRect().left ?? 0;
|
||||||
|
const target_y = target?.getBoundingClientRect().top ?? 0;
|
||||||
|
|
||||||
|
const viewport_width = document.body.getBoundingClientRect().width;
|
||||||
|
const viewport_height = document.body.getBoundingClientRect().height;
|
||||||
|
|
||||||
|
const best_coords = {
|
||||||
|
x: target_x + offset.x,
|
||||||
|
y: target_y + offset.y,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (target_x + offset.x + reactions_popup_width + offset.x > viewport_width) {
|
||||||
|
best_coords.x = Math.max(0, target_x - reactions_popup_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_y + offset.y + reactions_popup_height + offset.y > viewport_height) {
|
||||||
|
best_coords.y = Math.max(0, target_y - reactions_popup_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return best_coords;
|
||||||
|
}
|
||||||
|
|
||||||
|
let reactions_popup;
|
||||||
|
let reactions_popup_form;
|
||||||
|
let reactions_popup_parent_id_input;
|
||||||
|
let reactions_popup_emojis_list;
|
||||||
|
let reactions_popup_reaction_input;
|
||||||
|
|
||||||
|
function open_reactions_popup(event) {
|
||||||
|
const parent_event_id = event.target?.closest("[data-event_id]")?.dataset?.event_id;
|
||||||
|
reactions_popup_parent_id_input.value = parent_event_id ?? "";
|
||||||
|
|
||||||
|
const position = get_best_coords_for_popup(event.target.closest("[data-reactions]"), {
|
||||||
|
x: 25,
|
||||||
|
y: 25,
|
||||||
|
});
|
||||||
|
|
||||||
|
reactions_popup.style.left = position.x + "px";
|
||||||
|
reactions_popup.style.top = position.y + "px";
|
||||||
|
|
||||||
|
reactions_popup.style.visibility = "visible";
|
||||||
|
reactions_popup.style.opacity = "1";
|
||||||
|
reactions_popup.style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear_reactions_popup() {
|
||||||
|
if (!reactions_popup) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reactions_popup.style.visibility = "hidden";
|
||||||
|
reactions_popup.style.opacity = "0";
|
||||||
|
reactions_popup.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
if (!document.getElementById("reactions-styling")) {
|
||||||
|
const style = document.createElement("style");
|
||||||
|
style.id = "reactions-styling";
|
||||||
|
style.innerHTML = reactions_popup_styling;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
reactions_popup = document.createElement("div");
|
||||||
|
|
||||||
|
reactions_popup.id = "reactionspopup";
|
||||||
|
reactions_popup.innerHTML = `
|
||||||
|
<div class="icon close" onclick="clear_reactions_popup()"></div>
|
||||||
|
<form
|
||||||
|
id="reactions-selection-form"
|
||||||
|
data-smart="true"
|
||||||
|
method="POST"
|
||||||
|
on_reply="async (event) => { await document.querySelectorAll( '[data-feed]' ).forEach((feed) => feed.__render(event)); }"
|
||||||
|
on_parsed="async (event) => { await document.querySelectorAll( '[data-feed]' ).forEach((feed) => feed.__render(event)); }"
|
||||||
|
>
|
||||||
|
<input id="reactions-search-input" name="search" type="text" placeholder="Search..." data-skip="true" />
|
||||||
|
|
||||||
|
<input type="hidden" name="type" value="reaction" />
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="id"
|
||||||
|
generator="(_input, form) => 'TEMP-' + form.__submitted_at.toISOString()"
|
||||||
|
reset-on-submit
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="meta.temp_id"
|
||||||
|
generator="(_input, form) => 'TEMP-' + form.__submitted_at.toISOString()"
|
||||||
|
reset-on-submit
|
||||||
|
/>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="creator_id"
|
||||||
|
generator="() => { return JSON.parse( document.body.dataset.user ?? '{}' ).id; }"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="timestamps.created"
|
||||||
|
generator="(_input, form) => form.__submitted_at.toISOString()"
|
||||||
|
reset-on-submit
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name="timestamps.updated"
|
||||||
|
generator="(_input, form) => form.__submitted_at.toISOString()"
|
||||||
|
reset-on-submit
|
||||||
|
/>
|
||||||
|
|
||||||
|
<input type="hidden" name="parent_id" reset-on-submit />
|
||||||
|
|
||||||
|
<input type="hidden" name="data.reaction" reset-on-submit />
|
||||||
|
<ul id="reactions-emojis-list">
|
||||||
|
${Object.keys(EMOJIS.MAP)
|
||||||
|
.map(
|
||||||
|
(emoji) =>
|
||||||
|
`<li data-emoji="${emoji}" data-names="${EMOJIS.MAP[emoji].map((name) => `:${name}:`).join(" ")}">${emoji}</li>`,
|
||||||
|
)
|
||||||
|
.join("\n")}
|
||||||
|
</ul>
|
||||||
|
</form>
|
||||||
|
<div id="reactions-names-display"></div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(reactions_popup);
|
||||||
|
|
||||||
|
reactions_popup_form = document.getElementById("reactions-selection-form");
|
||||||
|
document.addEventListener("topic_changed", ({ detail: { topic_id } }) => {
|
||||||
|
const reaction_topic_id = topic_id ?? document.body.dataset.topic;
|
||||||
|
reactions_popup_form.action = reaction_topic_id
|
||||||
|
? `/api/topics/${reaction_topic_id}/events`
|
||||||
|
: "";
|
||||||
|
});
|
||||||
|
|
||||||
|
reactions_popup_parent_id_input = reactions_popup_form.querySelector('[name="parent_id"]');
|
||||||
|
reactions_popup_emojis_list = document.getElementById("reactions-emojis-list");
|
||||||
|
reactions_popup_reaction_input = reactions_popup_form.querySelector('[name="data.reaction"]');
|
||||||
|
reactions_popup_names_display = document.getElementById("reactions-names-display");
|
||||||
|
|
||||||
|
reactions_popup_emojis_list.querySelectorAll("li[data-emoji]").forEach((emoji_selector) => {
|
||||||
|
emoji_selector.addEventListener("click", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const selector = event.target;
|
||||||
|
const emoji = selector.dataset.emoji;
|
||||||
|
|
||||||
|
reactions_popup_reaction_input.value = emoji;
|
||||||
|
reactions_popup_form.requestSubmit();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
reactions_popup_form.addEventListener("mouseover", (event) => {
|
||||||
|
reactions_popup_names_display.textContent = event.target.matches("li[data-names]")
|
||||||
|
? event.target.dataset.names
|
||||||
|
: "";
|
||||||
|
});
|
||||||
|
|
||||||
|
const reactions_popup_search = debounce((event) => {
|
||||||
|
const prompt = event.target?.value;
|
||||||
|
const filtered = EMOJIS.autocomplete(prompt);
|
||||||
|
|
||||||
|
delete emojis_list.dataset.filtered;
|
||||||
|
if (filtered.length) {
|
||||||
|
emojis_list.dataset.filtered = true;
|
||||||
|
emojis_list.querySelectorAll("li").forEach((li) => {
|
||||||
|
if (filtered.some((entry) => entry[0] === li.dataset.emoji)) {
|
||||||
|
li.dataset.filtered = true;
|
||||||
|
} else {
|
||||||
|
delete li.dataset.filtered;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
document
|
||||||
|
.getElementById("reactions-search-input")
|
||||||
|
.addEventListener("input", reactions_popup_search);
|
||||||
|
document
|
||||||
|
.getElementById("reactions-search-input")
|
||||||
|
.addEventListener("paste", reactions_popup_search);
|
||||||
|
document
|
||||||
|
.getElementById("reactions-search-input")
|
||||||
|
.addEventListener("change", reactions_popup_search);
|
||||||
|
|
||||||
|
document.querySelector("body").addEventListener("click", (event) => {
|
||||||
|
const is_a_data_reactions_child = event?.target?.closest("[data-reactions]");
|
||||||
|
if (!is_a_data_reactions_child) {
|
||||||
|
clear_reactions_popup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
open_reactions_popup(event);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -14,11 +14,13 @@ function smarten_feeds() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const feed_item_template = feed.querySelector("template");
|
feed.__templates = feed
|
||||||
if (!feed_item_template) {
|
.querySelectorAll("template[data-for_type]")
|
||||||
console.warn("No template for smart feed: " + feed);
|
.values()
|
||||||
continue;
|
.reduce((_templates, template) => {
|
||||||
}
|
_templates[template.dataset.for_type] = template;
|
||||||
|
return _templates;
|
||||||
|
}, {});
|
||||||
|
|
||||||
feed.__start = () => {
|
feed.__start = () => {
|
||||||
feed.__started = true;
|
feed.__started = true;
|
||||||
|
|
@ -65,17 +67,26 @@ function smarten_feeds() {
|
||||||
};
|
};
|
||||||
|
|
||||||
feed.__target = (item) => {
|
feed.__target = (item) => {
|
||||||
return feed.__target_element?.(item) ?? feed;
|
if (!feed.__target_element) {
|
||||||
|
return feed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return feed.__target_element(item);
|
||||||
};
|
};
|
||||||
|
|
||||||
feed.__autoscroll_debounce_timeout = undefined;
|
feed.__autoscroll_debounce_timeout = undefined;
|
||||||
feed.__render = async (item) => {
|
feed.__render = async (item) => {
|
||||||
|
const template = feed.__templates[item.type];
|
||||||
|
if (!template) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
feed.__context =
|
feed.__context =
|
||||||
feed.__context ??
|
feed.__context ??
|
||||||
(feed.dataset.context ? new Function(feed.dataset.context) : undefined);
|
(feed.dataset.context ? new Function(feed.dataset.context) : undefined);
|
||||||
const context = feed.__context ? await feed.__context(item, feed) : {};
|
const context = feed.__context ? await feed.__context(item, feed) : {};
|
||||||
|
|
||||||
const rendered_html = eval("`" + feed_item_template.innerHTML.trim() + "`");
|
const rendered_html = eval("`" + template.innerHTML.trim() + "`");
|
||||||
|
|
||||||
const existing_element =
|
const existing_element =
|
||||||
feed.querySelector("#" + item.id?.replace(/([:\.])/g, "\\$1")) ??
|
feed.querySelector("#" + item.id?.replace(/([:\.])/g, "\\$1")) ??
|
||||||
|
|
@ -106,6 +117,10 @@ function smarten_feeds() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const target = feed.__target(item);
|
const target = feed.__target(item);
|
||||||
|
if (!target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (feed.dataset.insert ?? "append") {
|
switch (feed.dataset.insert ?? "append") {
|
||||||
case "prepend":
|
case "prepend":
|
||||||
target.insertAdjacentHTML("afterbegin", rendered_html);
|
target.insertAdjacentHTML("afterbegin", rendered_html);
|
||||||
|
|
@ -120,7 +135,7 @@ function smarten_feeds() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (feed.dataset.autoscroll) {
|
if (target === feed && feed.dataset.autoscroll) {
|
||||||
if (feed.__autoscroll_debounce_timeout) {
|
if (feed.__autoscroll_debounce_timeout) {
|
||||||
clearTimeout(feed.__autoscroll_debounce_timeout);
|
clearTimeout(feed.__autoscroll_debounce_timeout);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ function smarten_forms() {
|
||||||
for (const [key, value] of form_data.entries()) {
|
for (const [key, value] of form_data.entries()) {
|
||||||
const input = form.querySelector(`[name="${key}"]`);
|
const input = form.querySelector(`[name="${key}"]`);
|
||||||
|
|
||||||
|
if (input.dataset.skip) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (input.type === "file") {
|
if (input.type === "file") {
|
||||||
if (input.dataset["smartformsSaveToHome"]) {
|
if (input.dataset["smartformsSaveToHome"]) {
|
||||||
form.uploaded = [];
|
form.uploaded = [];
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,36 @@
|
||||||
|
let enhance_textareas_debounce_timeout;
|
||||||
function enhance_textareas() {
|
function enhance_textareas() {
|
||||||
const textareas = document.body.querySelectorAll("textarea:not([data-enhanced])");
|
if (enhance_textareas_debounce_timeout) {
|
||||||
for (const textarea of textareas) {
|
clearTimeout(enhance_textareas_debounce_timeout);
|
||||||
const max_length_attr = textarea.getAttribute("maxlength");
|
}
|
||||||
if (/^\d+$/.test(max_length_attr)) {
|
|
||||||
const max_length = parseInt(max_length_attr, 10);
|
|
||||||
|
|
||||||
function on_updated() {
|
enhance_textareas_debounce_timeout = setTimeout(() => {
|
||||||
const counters = this.parentElement.querySelectorAll(
|
enhance_textareas_debounce_timeout = undefined;
|
||||||
`[data-limit-counter-for="${this.name}"]`,
|
|
||||||
);
|
const textareas = document.body.querySelectorAll("textarea:not([data-enhanced])");
|
||||||
for (const counter of counters) {
|
for (const textarea of textareas) {
|
||||||
counter.innerHTML = `${this.value.length} / ${max_length}`;
|
const max_length_attr = textarea.getAttribute("maxlength");
|
||||||
|
if (/^\d+$/.test(max_length_attr)) {
|
||||||
|
const max_length = parseInt(max_length_attr, 10);
|
||||||
|
|
||||||
|
function on_updated() {
|
||||||
|
const counters = this.parentElement.querySelectorAll(
|
||||||
|
`[data-limit-counter-for="${this.name}"]`,
|
||||||
|
);
|
||||||
|
for (const counter of counters) {
|
||||||
|
counter.innerHTML = `${this.value.length} / ${max_length}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textarea.addEventListener("keyup", on_updated);
|
||||||
|
textarea.addEventListener("paste", on_updated);
|
||||||
|
textarea.addEventListener("blur", on_updated);
|
||||||
|
on_updated.call(textarea);
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea.addEventListener("keyup", on_updated);
|
textarea.dataset.enhanced = true;
|
||||||
textarea.addEventListener("paste", on_updated);
|
|
||||||
textarea.addEventListener("blur", on_updated);
|
|
||||||
on_updated.call(textarea);
|
|
||||||
}
|
}
|
||||||
|
}, 10);
|
||||||
textarea.dataset.enhanced = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const textarea_enhancement_observer = new MutationObserver(enhance_textareas);
|
const textarea_enhancement_observer = new MutationObserver(enhance_textareas);
|
||||||
|
|
|
||||||
|
|
@ -174,8 +174,14 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template data-for_type="blurb">
|
||||||
<div id="${ context.blurb.id }" class="blurb-container" data-creator_id="${context.creator.id}" data-blurb_id="${context.blurb.id}" data-temp_id="${context.blurb.meta?.temp_id ?? ""}">
|
<div
|
||||||
|
id="${ context.blurb.id }"
|
||||||
|
class="blurb-container"
|
||||||
|
data-event_id="${context.blurb.id}"
|
||||||
|
data-creator_id="${context.creator.id}"
|
||||||
|
data-blurb_id="${context.blurb.id}"
|
||||||
|
data-temp_id="${context.blurb.meta?.temp_id ?? ""}">
|
||||||
<div class="media-preview-container">
|
<div class="media-preview-container">
|
||||||
${context.blurb.data?.media?.length ? context.blurb.data.media.map(function(url) { return `<img src='${url}' />`; }).join('\n') : ''}
|
${context.blurb.data?.media?.length ? context.blurb.data.media.map(function(url) { return `<img src='${url}' />`; }).join('\n') : ''}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -234,10 +234,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .message-container .message-content-container,
|
#chat .message-container .message-content-container,
|
||||||
#chat .message-container .message-media-container {
|
#chat .message-container .message-media-container,
|
||||||
|
#chat .message-container .reactions-container {
|
||||||
padding-left: 8rem;
|
padding-left: 8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chat .message-container .reactions-container:has(> .reaction-container) {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat .message-container .reactions-container .reaction-container {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid var(--border-subtle);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
font-size: large;
|
||||||
|
}
|
||||||
|
|
||||||
#chat .embed-container {
|
#chat .embed-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -327,7 +342,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .message-container .message-content-container,
|
#chat .message-container .message-content-container,
|
||||||
#chat .message-container .message-media-container {
|
#chat .message-container .message-media-container,
|
||||||
|
#chat .message-container .reactions-container {
|
||||||
padding-left: 4rem;
|
padding-left: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
id="chat-content"
|
id="chat-content"
|
||||||
data-feed
|
data-feed
|
||||||
data-precheck="!!document.body.dataset.user && document.body.dataset.user.indexOf( 'topics.chat.read' ) !== -1"
|
data-precheck="!!document.body.dataset.user && document.body.dataset.user.indexOf( 'topics.chat.read' ) !== -1"
|
||||||
data-source="/api/topics/${ document.body.dataset.topic }/events?type=chat&limit=100&sort=newest&wait=true&after_id=${ feed.__newest_id ?? 'chat:able-able-able-able-able-able-able-able-able-able' }"
|
data-source="/api/topics/${ document.body.dataset.topic }/events?type=chat,reaction&limit=100&sort=newest&wait=true&after_id=${ feed.__newest_id ?? 'chat:able-able-able-able-able-able-able-able-able-able' }"
|
||||||
data-longpolling="true"
|
data-longpolling="true"
|
||||||
data-reverse="true"
|
data-reverse="true"
|
||||||
data-insert="append"
|
data-insert="append"
|
||||||
|
|
@ -77,12 +77,33 @@
|
||||||
user_tick_tock_class,
|
user_tick_tock_class,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
feed.__target_element = (item) => {
|
||||||
|
let target = feed;
|
||||||
|
switch (item.type) {
|
||||||
|
case "reaction":
|
||||||
|
target = document.querySelector(
|
||||||
|
`.message-container[data-event_id='${item.parent_id}'] > .reactions-container`,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "chat":
|
||||||
|
default:
|
||||||
|
target =
|
||||||
|
document.querySelector(
|
||||||
|
`.message-container[data-event_id='${item.parent_id}'] > .replies-container`,
|
||||||
|
) ?? feed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template data-for_type="chat">
|
||||||
<div
|
<div
|
||||||
id="${context.event.id}"
|
id="${context.event.id}"
|
||||||
class="message-container ${context.user_tick_tock_class} ${context.time_tick_tock_class}"
|
class="message-container ${context.user_tick_tock_class} ${context.time_tick_tock_class}"
|
||||||
|
data-event_id="${context.event.id}"
|
||||||
data-creator_id="${context.creator.id}"
|
data-creator_id="${context.creator.id}"
|
||||||
data-temp_id="${context.event.meta?.temp_id ?? ''}"
|
data-temp_id="${context.event.meta?.temp_id ?? ''}"
|
||||||
>
|
>
|
||||||
|
|
@ -99,7 +120,12 @@
|
||||||
<div class="icon more-borderless"></div>
|
<div class="icon more-borderless"></div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<button class="message-action mockup" data-action="react">
|
<button
|
||||||
|
class="message-action"
|
||||||
|
data-action="react"
|
||||||
|
data-reactions
|
||||||
|
data-smart
|
||||||
|
>
|
||||||
<i class="icon circle"></i><span class="action-name">React</span>
|
<i class="icon circle"></i><span class="action-name">React</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|
@ -140,6 +166,19 @@
|
||||||
<div class="message-media-container">
|
<div class="message-media-container">
|
||||||
${htmlify(context.event.data.media?.join("\n") ?? "")}
|
${htmlify(context.event.data.media?.join("\n") ?? "")}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="reactions-container"></div>
|
||||||
|
<div class="replies-container"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template data-for_type="reaction">
|
||||||
|
<div
|
||||||
|
id="${context.event.id}"
|
||||||
|
class="reaction-container"
|
||||||
|
data-event_id="${context.event.id}"
|
||||||
|
data-creator_id="${context.creator.id}"
|
||||||
|
data-temp_id="${context.event.meta?.temp_id ?? ''}"
|
||||||
|
>
|
||||||
|
<span class="reaction">${ context.event.data.reaction }</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -145,10 +145,11 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template data-for_type="essay">
|
||||||
<div
|
<div
|
||||||
id="${context.essay.id}"
|
id="${context.essay.id}"
|
||||||
class="essay-container"
|
class="essay-container"
|
||||||
|
data-event_id="${context.essay.id}"
|
||||||
data-creator_id="${context.creator.id}"
|
data-creator_id="${context.creator.id}"
|
||||||
data-essay_id="${context.essay.id}"
|
data-essay_id="${context.essay.id}"
|
||||||
data-temp_id="${context.essay.meta?.temp_id ?? ''}"
|
data-temp_id="${context.essay.meta?.temp_id ?? ''}"
|
||||||
|
|
|
||||||
|
|
@ -175,10 +175,11 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template data-for_type="post">
|
||||||
<div
|
<div
|
||||||
id="${context.post.id}"
|
id="${context.post.id}"
|
||||||
class="post-container"
|
class="post-container"
|
||||||
|
data-event_id="${context.post.id}"
|
||||||
data-creator_id="${context.creator.id}"
|
data-creator_id="${context.creator.id}"
|
||||||
data-post_id="${context.post.id}"
|
data-post_id="${context.post.id}"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue