lmlfc-bttv/src/main.ts

88 lines
2.6 KiB
TypeScript
Raw Normal View History

2023-12-30 14:51:19 +00:00
import { bttv_get_url } from "./bttv_api";
2023-12-30 15:46:06 +00:00
import { map_concurrent } from "./helpers";
2023-12-28 15:37:38 +00:00
2023-12-30 14:51:19 +00:00
const emote_regex = /bttv:([^\s]+)/gi;
2023-12-28 13:55:42 +00:00
2023-12-30 15:46:06 +00:00
/**
* Process "bttv:*" emotes in a string
*
* @param text the input string
* @returns new string with existing "bttv:*" emotes replaced by "[not]" BBCodes
*/
2023-12-28 13:55:42 +00:00
async function process_text(text: string): Promise<string> {
2023-12-30 15:46:06 +00:00
// find "bttv:*" emotes
2023-12-28 15:37:38 +00:00
const matches = [...text.matchAll(emote_regex)];
2023-12-30 15:46:06 +00:00
// unique emote codes (the "*" parts)
2023-12-30 14:51:19 +00:00
const codes = new Set(matches.map(([_, code]) => code));
2023-12-30 15:46:06 +00:00
// find emote pics using BTTV API
2023-12-30 14:51:19 +00:00
console.log("[lmlfc-bttv]", `searching ${[...codes].length} emotes`);
2023-12-30 15:46:06 +00:00
const emotes = await map_concurrent(codes, bttv_get_url);
2023-12-28 15:37:38 +00:00
2023-12-30 15:46:06 +00:00
// replace emotes with BBCodes
2023-12-28 15:37:38 +00:00
for (const emote of matches.reverse()) {
const [match, code] = emote;
2023-12-30 14:51:19 +00:00
2023-12-30 16:01:23 +00:00
// ensure emote exists
2023-12-30 14:51:19 +00:00
const url = emotes.get(code);
2023-12-30 16:01:23 +00:00
if (url == null) continue;
2023-12-28 13:55:42 +00:00
2023-12-30 16:01:23 +00:00
// ensure position in input string is known
2023-12-30 15:46:06 +00:00
const index = emote.index;
2023-12-30 16:01:23 +00:00
if (index == undefined) continue;
2023-12-30 15:46:06 +00:00
2023-12-28 15:37:38 +00:00
text =
text.substring(0, index) +
2023-12-30 14:51:19 +00:00
`[not]${url}[/not]` +
2023-12-28 15:37:38 +00:00
text.substring(index + match.length);
}
2023-12-30 15:46:06 +00:00
// remove space between adjacent emotes
// (maybe do this in emote_regex instead?)
2023-12-30 14:51:19 +00:00
return text.replace(/\[\/not\]\s+\[not\]/g, "[/not][not]");
2023-12-28 13:55:42 +00:00
}
(() => {
2023-12-30 15:46:06 +00:00
// find chatbox elements
2023-12-28 13:55:42 +00:00
const cb_form = document.querySelector("#mgc_cb_evo_form");
2023-12-28 21:40:08 +00:00
const cb_send = document.querySelector(
"#mgc_cb_evo_form > input[type=image]:nth-child(2)",
);
2023-12-30 14:51:19 +00:00
const cb_input = document.querySelector("#mgc_cb_evo_input");
2023-12-30 15:46:06 +00:00
// check chatbox elements
if (!(cb_form instanceof HTMLFormElement)) return;
if (!(cb_send instanceof HTMLInputElement)) return;
2023-12-30 14:51:19 +00:00
if (!(cb_input instanceof HTMLInputElement)) return;
2023-12-30 15:46:06 +00:00
// create "bttv" button
2023-12-28 13:55:42 +00:00
const bttv_btn = (() => {
const btn = document.createElement("a");
btn.style.setProperty("cursor", "pointer");
btn.style.setProperty("margin-right", "4px");
const img = document.createElement("img");
2023-12-28 21:28:02 +00:00
img.setAttribute("src", chrome.runtime.getURL("img/sb_button.png"));
2023-12-28 21:40:08 +00:00
img.setAttribute("alt", "bttv emotes ersetzen und absenden");
img.setAttribute("title", "bttv:* emotes ersetzen und absenden");
2023-12-28 13:55:42 +00:00
img.style.setProperty("vertical-align", "middle");
2023-12-30 15:46:06 +00:00
// ******************
// * business logic *
// ******************
2023-12-28 21:40:08 +00:00
btn.addEventListener("click", async () => {
2023-12-28 16:16:15 +00:00
cb_input.value = await process_text(cb_input.value);
cb_input.focus();
2023-12-28 21:40:08 +00:00
cb_send.click();
2023-12-28 13:55:42 +00:00
});
btn.appendChild(img);
return btn;
})();
2023-12-28 21:40:08 +00:00
cb_form.insertBefore(bttv_btn, cb_send);
2023-12-28 13:55:42 +00:00
2023-12-30 14:51:19 +00:00
console.log("[lmlfc-bttv]", `loaded`);
2023-12-28 13:55:42 +00:00
})();