ExpressionCloner: improve FakeNitro emoji handling (#4526)
Co-authored-by: Vendicated <vendicated@riseup.net>
This commit is contained in:
parent
a581197a27
commit
4e4cdedae4
2 changed files with 26 additions and 9 deletions
|
|
@ -26,7 +26,7 @@ import { Devs } from "@utils/constants";
|
||||||
import { getGuildAcronym, hasGuildFeature } from "@utils/discord";
|
import { getGuildAcronym, hasGuildFeature } from "@utils/discord";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { Guild, GuildSticker } from "@vencord/discord-types";
|
import { Guild, GuildSticker, Message } from "@vencord/discord-types";
|
||||||
import { StickerFormatType } from "@vencord/discord-types/enums";
|
import { StickerFormatType } from "@vencord/discord-types/enums";
|
||||||
import { findByCodeLazy } from "@webpack";
|
import { findByCodeLazy } from "@webpack";
|
||||||
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, IconUtils, Menu, Modal, openModalLazy, PermissionsBits, PermissionStore, React, RestAPI, StickersStore, Toasts, Tooltip, UserStore } from "@webpack/common";
|
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, IconUtils, Menu, Modal, openModalLazy, PermissionsBits, PermissionStore, React, RestAPI, StickersStore, Toasts, Tooltip, UserStore } from "@webpack/common";
|
||||||
|
|
@ -366,18 +366,31 @@ function isGifUrl(url: string) {
|
||||||
return u.pathname.endsWith(".gif") || u.searchParams.get("animated") === "true";
|
return u.pathname.endsWith(".gif") || u.searchParams.get("animated") === "true";
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => {
|
function resolveEmojiName(favoriteableId: string, message: Message) {
|
||||||
const { favoriteableId, itemHref, itemSrc, favoriteableType } = props ?? {};
|
const emoji = EmojiStore.getCustomEmojiById(favoriteableId);
|
||||||
|
if (emoji) return emoji.name;
|
||||||
|
|
||||||
|
const reaction = message.reactions.find(reaction => reaction.emoji.id === favoriteableId);
|
||||||
|
if (reaction) return reaction.emoji.name;
|
||||||
|
|
||||||
|
const match = message.content.match(RegExp(`<a?:(\\w+)(?:~\\d+)?:${favoriteableId}>|https://cdn\\.discordapp\\.com/emojis/${favoriteableId}\\.[\\w?&=%]*`));
|
||||||
|
if (!match) return null;
|
||||||
|
|
||||||
|
return match[1]
|
||||||
|
?? URL.parse(match[0])?.searchParams.get("name")
|
||||||
|
?? "FakeNitroEmoji";
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props: Record<"favoriteableId" | "itemHref" | "itemSrc" | "favoriteableType", string> & { message: Message; }) => {
|
||||||
|
const { favoriteableId, itemHref, itemSrc, favoriteableType, message } = props ?? {};
|
||||||
|
|
||||||
if (!favoriteableId) return;
|
if (!favoriteableId) return;
|
||||||
|
|
||||||
const menuItem = (() => {
|
const menuItem = (() => {
|
||||||
switch (favoriteableType) {
|
switch (favoriteableType) {
|
||||||
case "emoji":
|
case "emoji":
|
||||||
const match = props.message.content.match(RegExp(`<a?:(\\w+)(?:~\\d+)?:${favoriteableId}>|https://cdn\\.discordapp\\.com/emojis/${favoriteableId}\\.`));
|
const name = resolveEmojiName(favoriteableId, message);
|
||||||
const reaction = props.message.reactions.find(reaction => reaction.emoji.id === favoriteableId);
|
if (!name) return;
|
||||||
if (!match && !reaction) return;
|
|
||||||
const name = (match && match[1]) ?? reaction?.emoji.name ?? "FakeNitroEmoji";
|
|
||||||
|
|
||||||
return buildMenuItem("Emoji", () => ({
|
return buildMenuItem("Emoji", () => ({
|
||||||
id: favoriteableId,
|
id: favoriteableId,
|
||||||
|
|
@ -385,7 +398,7 @@ const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) =
|
||||||
isAnimated: isGifUrl(itemHref ?? itemSrc)
|
isAnimated: isGifUrl(itemHref ?? itemSrc)
|
||||||
}));
|
}));
|
||||||
case "sticker":
|
case "sticker":
|
||||||
const sticker = props.message.stickerItems.find(s => s.id === favoriteableId);
|
const sticker = message.stickerItems.find(s => s.id === favoriteableId);
|
||||||
if (sticker?.format_type === 3 /* LOTTIE */) return;
|
if (sticker?.format_type === 3 /* LOTTIE */) return;
|
||||||
|
|
||||||
return buildMenuItem("Sticker", () => fetchSticker(favoriteableId));
|
return buildMenuItem("Sticker", () => fetchSticker(favoriteableId));
|
||||||
|
|
@ -419,7 +432,7 @@ export default definePlugin({
|
||||||
description: "Allows you to clone Emotes & Stickers to your own server (right click them)",
|
description: "Allows you to clone Emotes & Stickers to your own server (right click them)",
|
||||||
tags: ["Emotes", "Servers"],
|
tags: ["Emotes", "Servers"],
|
||||||
searchTerms: ["StickerCloner", "EmoteCloner", "EmojiCloner"],
|
searchTerms: ["StickerCloner", "EmoteCloner", "EmojiCloner"],
|
||||||
authors: [Devs.Ven, Devs.Nuckyz],
|
authors: [Devs.Ven, Devs.Nuckyz, Devs.scattagain],
|
||||||
contextMenus: {
|
contextMenus: {
|
||||||
"message": messageContextMenuPatch,
|
"message": messageContextMenuPatch,
|
||||||
"expression-picker": expressionPickerPatch
|
"expression-picker": expressionPickerPatch
|
||||||
|
|
|
||||||
|
|
@ -666,6 +666,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
name: "yuna0x0",
|
name: "yuna0x0",
|
||||||
id: 213656926414831616n
|
id: 213656926414831616n
|
||||||
},
|
},
|
||||||
|
scattagain: {
|
||||||
|
name: "Amelia",
|
||||||
|
id: 1098234477626544180n
|
||||||
|
},
|
||||||
Davri: {
|
Davri: {
|
||||||
name: "Davri",
|
name: "Davri",
|
||||||
id: 457579346282938368n
|
id: 457579346282938368n
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue