252 lines
No EOL
12 KiB
JavaScript
252 lines
No EOL
12 KiB
JavaScript
// Reimplement PopupManager.open
|
|
(() => {
|
|
const pv = window.PvInternals;
|
|
|
|
pv.popupMap = {
|
|
[pv.Modal.BAN]: pv.components_popups_pv_ban_pv_ban,
|
|
[pv.Modal.PROFILE]: pv.components_popups_pv_profile_pv_profile,
|
|
[pv.Modal.SETTINGS]: pv.components_popups_pv_settings_pv_settings,
|
|
[pv.Modal.MESSAGE]: pv.components_popups_pv_message_pv_message,
|
|
[pv.Modal.NEW_ROOM]: pv.components_popups_pv_new_room_pv_new_room,
|
|
[pv.Dialog.ROOMS]: pv.components_popups_pv_rooms_pv_rooms,
|
|
[pv.Dialog.ACTIONS]: pv.components_popups_pv_actions_pv_actions,
|
|
[pv.Dialog.DEVICES]: pv.components_popups_pv_devices_pv_devices,
|
|
[pv.Dialog.SOUNDS]: pv.components_popups_pv_sounds_pv_sounds,
|
|
[pv.Dialog.TRANSPOSE]: pv.components_popups_pv_transpose_pv_transpose,
|
|
[pv.Dialog.VELOCITY]: pv.components_popups_pv_velocity_pv_velocity,
|
|
};
|
|
|
|
pv.PopupManager.open = (popupName, ...args) => {
|
|
let dialogElement = document.querySelector(popupName)
|
|
if (dialogElement && !dialogElement.querySelector("dialog").hasAttribute("closing")) {
|
|
dialogElement.close();
|
|
return dialogElement;
|
|
}
|
|
|
|
const popupClass = pv.popupMap[popupName];
|
|
|
|
if (!popupClass) {
|
|
throw new Error(`Popup ${popupName} not found`);
|
|
}
|
|
|
|
dialogElement = new popupClass();
|
|
document.body.append(dialogElement);
|
|
dialogElement.open(...args);
|
|
|
|
return dialogElement;
|
|
}
|
|
})();
|
|
|
|
|
|
// custom rules
|
|
(() => {
|
|
const pv = window.PvInternals;
|
|
class PvmeRulesModal extends pv.components_pv_popup_pv_popup {
|
|
constructor() {
|
|
super();
|
|
this.innerHTML = `<dialog blocking class=popup modal><div class=header><div class=title style=margin-right:20px><i class="fas fa-info-circle"></i> Rules</div><div class=x><i class="fas fa-xmark"></i></div></div><div class=content><div class=message><b>pianoverse.me rules are very simple.</b><ul><li>Don't be annoying<li>Don't be racist<li>Do not argue punishments</ul>That's it! :)</div></div></dialog>`;
|
|
}
|
|
}
|
|
|
|
customElements.define("pvme-rules-modal", PvmeRulesModal);
|
|
pv.Modal.RULES = "pvme-rules-modal";
|
|
pv.popupMap[pv.Modal.RULES] = PvmeRulesModal
|
|
|
|
class PvmeRules extends HTMLElement {}
|
|
customElements.define("pvme-rules", PvmeRules);
|
|
|
|
let g = document.querySelector("body > pv-header > div.left");
|
|
{ let a = document.createElement("div"); a.className = "divider"; a.style.marginLeft = "20px"; g.appendChild(a); }
|
|
{
|
|
let a = document.createElement("pvme-rules");
|
|
a.innerHTML = `<div class="icon" aria-label="Rules" data-tooltip="Rules"><i class="fas fa-scale-balanced"></i></div>`;
|
|
a.addEventListener("click", () => {
|
|
pv.PopupManager.open(pv.Modal.RULES, null);
|
|
})
|
|
g.appendChild(a);
|
|
}
|
|
})();
|
|
|
|
// change title
|
|
(() => {
|
|
const pv = window.PvInternals;
|
|
|
|
document.querySelector("pv-room").updateBrowserTab = function () {
|
|
if(pv.services_client.room.id) {
|
|
if(pv.services_client.isConnected()) {
|
|
document.title = `pv.me - ${pv.services_client.room.id} (${1 + pv.services_client.users.length})`
|
|
} else {
|
|
document.title = `pv.me - ${pv.services_client.room.id}`
|
|
}
|
|
} else {
|
|
document.title = "pv.me"
|
|
}
|
|
}
|
|
|
|
document.querySelector("body > pv-header > div.left > div.pianoverse > span").innerText = "pv.me"
|
|
})();
|
|
(async () => {
|
|
|
|
const style = document.createElement("style");
|
|
style.innerHTML = `pv-chat>div button:nth-child(3){position:absolute;right:40px;z-index:26;cursor:url(88b4a467a18e813218f8.cur),auto;font-size:1em;border:none;height:46px;aspect-ratio:1;padding:0;border-radius:0;box-shadow:none;margin:0;flex:0;color:var(--color-text)}pv-chat>div button:nth-child(3)>img:hover{transform-origin:50% 50%;transform:scale(1.4);transition:.1s}pv-chat>div input[type=text]{padding:0 90px 0 14px}.emoji-container{display:grid;grid-template-columns:auto auto auto auto auto auto}.emoji-container>*{text-align:center;margin:2px}`
|
|
document.head.appendChild(style);
|
|
|
|
let shiftHeldDown = false; // ShiftLeft/Right or False
|
|
|
|
document.addEventListener("keydown", (e) => {
|
|
if(!shiftHeldDown) shiftHeldDown = e.code;
|
|
})
|
|
|
|
document.addEventListener("keyup", (e) => {
|
|
if(e.code == shiftHeldDown) shiftHeldDown = false;
|
|
})
|
|
|
|
const pv = window.PvInternals;
|
|
const emojiRequest = await fetch("emojis.json");
|
|
let emojis = await emojiRequest.json()
|
|
|
|
const discordEmojis = ["<:silly:1287108299057266850>", '<:bratkanye:1271842184798273668>', '<a:aniblobsweat:586029851870363660>', '<:blobpensive:978314885337346089>', '<:blobsip:978314935077597231>', '<:blobheart:856700296302428170>', '<:blobsaluteban:463464097137295392>', '<:blobthinkban:812905997034061834>', '<:blobreach:474817265339203584>', '<a:blobReachAustralia:1247812442239795282>', '<:nixos:1252753664397934646>', '<:archlinux:1252754080640667658>', '<:rust:1263598244588425388>', '<:perfect:1243013970764370061>', '<:True:811294080662896640>', '<:froglove:1228043131430240407>', '<a:frogpop:1228043129811374081>', '<a:frogwave:1228043128871845979>', '<:pianoverse:1218346119705133116>', '<:restart:1257118826106064899>', '<:tape:1274061265714811054>', '<:what:1279839007714316392>', '<:boof:1261047926088663161>', '<:CHECK_CHECK_1:1075442774649872384>', '<:CHECK_CROSS_1:1075442781708898414>', '<a:pogg:947236908256362496>', '<a:peeposhy:1052873747561971732>', '<a:catfbi:1292722712212672582>', '<:cat:1184105614994063410>', '<:MBDTF:1263773146972946442>', '<a:SpeedL:906979227939778580>', '<a:SpeedR:906979227876864051>', '<a:newports:1005206666792419458>', '<a:myman:829624853845245953>', '<a:skyperock:937848388685279262>', '<:shut:714946339850420324>', '<a:sponge:854419399871561800>', '<a:weedwalker:855115903426625578>', '<a:furret:791595456147750943>', '<a:weewoo_red:706925335228317868>'];
|
|
const discordEmojiRegex = /<(a?):(.*?):(\d+)>/g;
|
|
const discordEmojiRegexWeb = /<(a?):(.*?):(\d+)>/g;
|
|
|
|
function renderEmoji(emoji, size = "64") {
|
|
const id = emoji.replace(discordEmojiRegex, "$3");
|
|
const isAnimated = !!emoji.replace(discordEmojiRegex, "$1")
|
|
const img = document.createElement("img");
|
|
img.src = `https://cdn.discordapp.com/emojis/${id}.${isAnimated ? "gif" : "png"}?size=${size}`;
|
|
img.alt = "emoji";
|
|
img.width = size;
|
|
img.height = size;
|
|
return img;
|
|
}
|
|
|
|
//#region Modal
|
|
class PvmeEmojiPicker extends pv.components_pv_popup_pv_popup {
|
|
|
|
constructor() {
|
|
super();
|
|
|
|
const dialog = document.createElement("dialog");
|
|
dialog.className = "popup"
|
|
dialog.setAttribute("modal", "")
|
|
dialog.setAttribute("blocking", "")
|
|
|
|
const header = document.createElement("div");
|
|
header.className = "header";
|
|
header.innerHTML = `<div class="title"><i class="fas fa-info-circle" aria-hidden="true"></i>Emoji picker</div><div class="x"><i class="fas fa-xmark" aria-hidden="true"></i></div>`
|
|
dialog.appendChild(header)
|
|
|
|
|
|
const content = document.createElement("div")
|
|
content.className = "content"
|
|
|
|
// #region Modal search input
|
|
const input = document.createElement("input")
|
|
input.type = "text"
|
|
input.value = pv.settingsmanager.get("latestEmojiLookup") || ""
|
|
input.addEventListener("keyup", () => {
|
|
pv.settingsmanager.set("latestEmojiLookup", input.value);
|
|
|
|
this.renderContainer(document.querySelector(".emoji-container"), input.value)
|
|
});
|
|
content.appendChild(input)
|
|
// #endregion
|
|
|
|
// #region Modal info
|
|
const info = document.createElement("p")
|
|
info.innerText = "Write 'discord' for discord emoijs, anything else for normal ones.\nHold shift before opening emoji picker to spam emojis."
|
|
content.appendChild(info);
|
|
//#endregion
|
|
|
|
const container = document.createElement("div")
|
|
container.className = "emoji-container"
|
|
this.renderContainer(container, pv.settingsmanager.get("latestEmojiLookup") || "discord")
|
|
content.append(container);
|
|
dialog.appendChild(content)
|
|
|
|
this.appendChild(dialog)
|
|
}
|
|
|
|
renderContainer(container, value) {
|
|
container.innerHTML = ""
|
|
if(value !== "discord") {
|
|
emojis.filter(z => z[0].replace("_", " ").includes(value.toLowerCase()) || value.toLowerCase().includes(z[0].replace("_", " "))).slice(0, 30).forEach(z => {
|
|
|
|
const div = document.createElement("div")
|
|
div.innerText = z[1];
|
|
div.style.fontSize = "30px"
|
|
|
|
div.addEventListener("click", () => {
|
|
const chat = document.querySelector("pv-chat");
|
|
chat.input.value += z[1] + " ";
|
|
console.log(shiftHeldDown)
|
|
if(!shiftHeldDown) pv.PopupManager.closeModals();
|
|
setTimeout(() => {
|
|
document.querySelector("pv-chat").input.scrollLeft = document.querySelector("pv-chat").input.scrollWidth;
|
|
}, 50)
|
|
})
|
|
container.appendChild(div);
|
|
})
|
|
} else {
|
|
discordEmojis.forEach((z) => {
|
|
const img = renderEmoji(z, "64")
|
|
img.addEventListener("click", () => {
|
|
const chat = document.querySelector("pv-chat");
|
|
chat.input.value += z + " ";
|
|
console.log(shiftHeldDown)
|
|
if(!shiftHeldDown) pv.PopupManager.closeModals();
|
|
setTimeout(() => {
|
|
document.querySelector("pv-chat").input.scrollLeft = document.querySelector("pv-chat").input.scrollWidth;
|
|
}, 50)
|
|
})
|
|
container.appendChild(img);
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
customElements.define("pvme-emoji-picker", PvmeEmojiPicker);
|
|
pv.Modal.EMOJIS = "pvme-emoji-picker";
|
|
pv.popupMap[pv.Modal.EMOJIS] = PvmeEmojiPicker
|
|
//#endregion
|
|
|
|
//#region Button
|
|
const button = document.createElement("button");
|
|
button.className = "send";
|
|
button.type = "button"
|
|
button.ariaLabel = "Pick a emoji!"
|
|
|
|
function changeEmoji(emoji) {
|
|
button.firstElementChild?.remove()
|
|
button.appendChild(renderEmoji(emoji, "32"));
|
|
}
|
|
|
|
changeEmoji(discordEmojis[Math.floor(Math.random() * discordEmojis.length)]);
|
|
|
|
button.addEventListener("click", () => {
|
|
pv.PopupManager.open(pv.Modal.EMOJIS);
|
|
changeEmoji(discordEmojis[Math.floor(Math.random() * discordEmojis.length)]);
|
|
})
|
|
|
|
document.querySelector("body > div > div.chat > pv-chat > div").appendChild(button)
|
|
//#endregion
|
|
|
|
let chatComponent = document.querySelector("pv-chat");
|
|
const proxied = new Proxy(chatComponent.sendChatMessage, {
|
|
apply: async function (target, thisArg, argumentsList) {
|
|
let result = chatComponent.input.value
|
|
const normalEmojiMatches = result.matchAll(/(?<!<)(?<!<):([a-z0-9A-Z]*):/gm);
|
|
|
|
for (const normalEmojiMatch of normalEmojiMatches) {
|
|
let emoji = emojis.find(z => z[0] == normalEmojiMatch[1]);
|
|
|
|
if(emoji) {
|
|
result = result.replaceAll(":"+emoji[0]+":", emoji[1])
|
|
}
|
|
}
|
|
chatComponent.input.value = result;
|
|
return target();
|
|
}
|
|
});
|
|
chatComponent.sendChatMessage = proxied;
|
|
})(); |