Add BetterTV smilies to editor autocomplete
// ==UserScript==
// @name LZT BetterTV AC
// @namespace lzt-bettertv-ac
// @description Add BetterTV smilies to editor autocomplete
// @version 1.0.0
// @author Toil
// @homepageURL https://t.me/lzt_upgrade
// @icon https://cdn.lztup.net/brand/logo-mini.png
// @license MIT
// @match *://lolz.guru/*
// @match *://lolz.live/*
// @match *://zelenka.guru/*
// @match *://zelenka.market/*
// @match *://lzt.market/*
// @match *://lolz.market/*
// @supportURL https://t.me/lzt_upgrade
// ==/UserScript==
// Generated by LZT Upgrade extension bundler. Telegram: https://t.me/lzt_upgrade Github: https://github.com/lzt-upgrade
var __legacyDecorateClassTS = function(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
r = Reflect.decorate(decorators, target, key, desc);
else
for (var i = decorators.length - 1;i >= 0; i--)
if (d = decorators[i])
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
// __style_helper__
function injectStyle(text, hash) {
if (typeof document === "undefined") {
return;
}
const style = document.createElement("style");
style.id = `lztup_${hash}`;
style.innerText = text;
document.head.appendChild(style);
}
// lzt-bettertv-ac/style.css
injectStyle(".fe-ac-BetterTV{flex-direction:row;display:flex}.fe-ac-smilie-image.lztup-smilie{margin:0!important}", "fa4e12cb0f2f32d4");
// lzt-bettertv-ac/index.js
function registerBetterTVAC(froala) {
new CustomEditorAutoCompleter(froala.$el, { insertMode: "html" }, froala);
}
if (typeof Lolzteam.ACProvider !== "function") {
console.log("[BetterTVAC] FroalaEditor isn't loaded");
return;
}
class BetterTVACProvider extends Lolzteam.ACProvider {
constructor(froala) {
super(froala, "BetterTV");
this.froala = froala;
this.apiUrl = "https://api.betterttv.net/3/";
this.cdnUrl = "https://cdn.betterttv.net/";
this.limit = 5;
this.debounceTime = 300;
}
debounceShow(text) {
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
}
this.debounceTimer = setTimeout(async () => {
let results = await this.searchSmilies(text[0] === ":" ? text.slice(1) : text);
if (!results?.length) {
return false;
}
this.state = {
text,
textNode: this.froala.selection.get().anchorNode
};
this.popup.html("");
const prioritySmilies = $(".fe-ac-smilie > .fe-ac-smilie-result").toArray();
for (const prioritySmilie of prioritySmilies) {
$(prioritySmilie).appendTo(this.popup);
}
for (const result of results) {
if (this.popup.find(".fe-ac-smilie-result").length >= this.limit) {
continue;
}
$('<div class="fe-ac-smilie-result fe-ac-result"/>').append($("<img/>", {
class: "fe-ac-smilie-image fr-draggable lztup-smilie",
alt: result.name,
title: result.name,
src: result.image
})).appendTo(this.popup);
}
this.debounceTimeout = null;
this.showPopup();
}, this.debounceTime);
}
async searchSmilies(text) {
if (text.length < 3) {
return [];
}
try {
const res = await fetch(`${this.apiUrl}emotes/shared/search?query=${text}&offset=0&limit=${this.limit}`);
const data = await res.json();
return data.map((smilie) => ({
aliases: [],
image: `${this.cdnUrl}emote/${smilie.id}/1x.webp`,
name: smilie.code,
value: `:${smilie.code}:`
}));
} catch (err) {
console.error(`[BetterTVAC] Failed to search BetterTV smilies by text: ${err.message}`);
}
}
async trigger() {
let text = this.getSelectedText(", ");
let selectedNode = this.froala.selection.get().anchorNode;
let previousSibling = selectedNode.previousSibling || selectedNode.parentNode.previousSibling;
selectedNode = selectedNode?.cloneNode(true);
previousSibling = previousSibling?.cloneNode(true);
if (!text || text.indexOf("@") !== -1 || selectedNode.textContent.startsWith(text) && previousSibling && previousSibling?.textContent.length !== 0 && !previousSibling?.textContent.endsWith(" ")) {
return false;
}
text = text?.trim();
this.hide();
this.debounceShow(text);
return true;
}
insertResult() {
if (!this.popup.find(".active").length) {
this.hide();
return false;
}
this.froala.selection.save();
this.state.textNode.textContent = this.state.textNode.textContent.trimEnd().slice(0, -this.state.text.length);
this.froala.selection.restore();
this.froala.html.insert(this.popup.find(".active").html());
$("#lzt-fe-eb-smilie").trigger("ac-picked-smilie");
this.hide();
return true;
}
}
class CustomEditorAutoCompleter extends Lolzteam.EditorAutoCompleter {
constructor(el, n, froala) {
super(el, n, froala);
this.froala = froala;
this.providers = [new BetterTVACProvider(froala)];
froala.events.on("keydown", this.onKeydown.bind(this), true);
froala.events.on("keyup", this.onKeyup.bind(this), true);
froala.events.on("focus", this.onFocus.bind(this), true);
}
}
FroalaEditor.MODULES.smilieBetterTVAC = function(e) {
return {
_init: registerBetterTVAC(e)
};
};