mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-07 21:53:04 -04:00
feat(plugin): CopyStickerLinks (#240)
Some checks are pending
Test / Test (push) Waiting to run
Some checks are pending
Test / Test (push) Waiting to run
* add awesome swag plugin * Update README.md * Update pnpm-lock.yaml --------- Co-authored-by: thororen <78185467+thororen1234@users.noreply.github.com>
This commit is contained in:
parent
d01ea8aaff
commit
ccbe5c16f1
3 changed files with 154 additions and 2 deletions
|
@ -11,7 +11,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch
|
||||||
### Extra included plugins
|
### Extra included plugins
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>166 additional plugins</summary>
|
<summary>167 additional plugins</summary>
|
||||||
|
|
||||||
### All Platforms
|
### All Platforms
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch
|
||||||
- CleanChannelName by AutumnVN
|
- CleanChannelName by AutumnVN
|
||||||
- ClientSideBlock by Samwich
|
- ClientSideBlock by Samwich
|
||||||
- CommandPalette by Ethan
|
- CommandPalette by Ethan
|
||||||
|
- CopyStickerLinks by Byeoon
|
||||||
- CopyUserMention by Cortex & castdrian
|
- CopyUserMention by Cortex & castdrian
|
||||||
- CustomSounds by TheKodeToad & SpikeHD
|
- CustomSounds by TheKodeToad & SpikeHD
|
||||||
- CustomTimestamps by Rini & nvhrr
|
- CustomTimestamps by Rini & nvhrr
|
||||||
|
|
147
src/plugins/copyStickerLinks/index.tsx
Normal file
147
src/plugins/copyStickerLinks/index.tsx
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a modification for Discord's desktop app
|
||||||
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||||
|
import { Devs } from "@utils/constants";
|
||||||
|
import { copyWithToast } from "@utils/misc";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
import { findStoreLazy } from "@webpack";
|
||||||
|
import { Menu, React } from "@webpack/common";
|
||||||
|
import { Promisable } from "type-fest";
|
||||||
|
|
||||||
|
const StickersStore = findStoreLazy("StickersStore");
|
||||||
|
|
||||||
|
interface Sticker {
|
||||||
|
t: "Sticker";
|
||||||
|
format_type: number;
|
||||||
|
id: string;
|
||||||
|
type: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StickerExt = [, "png", "png", "json", "gif"] as const;
|
||||||
|
|
||||||
|
function getUrl(data: Sticker) {
|
||||||
|
if (data.format_type === 4)
|
||||||
|
return `https:${window.GLOBAL_ENV.MEDIA_PROXY_ENDPOINT}/stickers/${data.id}.gif?size=4096&lossless=true`;
|
||||||
|
|
||||||
|
return `https://${window.GLOBAL_ENV.CDN_HOST}/stickers/${data.id}.${StickerExt[data.format_type]}?size=4096&lossless=true`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildMenuItem(Sticker, fetchData: () => Promisable<Omit<Sticker, "t">>) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Menu.MenuSeparator></Menu.MenuSeparator>
|
||||||
|
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="copystickerurl"
|
||||||
|
key="copystickerurl"
|
||||||
|
label={"Copy URL"}
|
||||||
|
action={async () => {
|
||||||
|
const res = await fetchData();
|
||||||
|
const data = { t: Sticker, ...res } as Sticker;
|
||||||
|
const url = getUrl(data[0]);
|
||||||
|
copyWithToast(url, "Link copied!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="openstickerlink"
|
||||||
|
key="openstickerlink"
|
||||||
|
label={"Open URL"}
|
||||||
|
action={async () => {
|
||||||
|
const res = await fetchData();
|
||||||
|
const data = { t: Sticker, ...res } as Sticker;
|
||||||
|
const url = getUrl(data[0]);
|
||||||
|
VencordNative.native.openExternal(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildMenuExpression(Sticker, fetchData: () => Promisable<Omit<Sticker, "t">>) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Menu.MenuSeparator></Menu.MenuSeparator>
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="copystickerurl"
|
||||||
|
key="copystickerurl"
|
||||||
|
label={"Copy URL"}
|
||||||
|
action={async () => {
|
||||||
|
const res = await fetchData();
|
||||||
|
const data = { t: Sticker, ...res } as Sticker;
|
||||||
|
const url = getUrl(data);
|
||||||
|
copyWithToast(url, "Link copied!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="openstickerlink"
|
||||||
|
key="openstickerlink"
|
||||||
|
label={"Open URL"}
|
||||||
|
action={async () => {
|
||||||
|
const res = await fetchData();
|
||||||
|
const data = { t: Sticker, ...res } as Sticker;
|
||||||
|
const url = getUrl(data);
|
||||||
|
VencordNative.native.openExternal(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => {
|
||||||
|
const { favoriteableId, favoriteableType } = props ?? {};
|
||||||
|
if (!favoriteableId) return;
|
||||||
|
const menuItem = (() => {
|
||||||
|
const sticker = props.message.stickerItems.find(s => s.id === favoriteableId);
|
||||||
|
if (sticker?.format_type === 3) return;
|
||||||
|
switch (favoriteableType) {
|
||||||
|
case "sticker":
|
||||||
|
return buildMenuItem("Sticker", () => props.message.stickerItems);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (menuItem)
|
||||||
|
findGroupChildrenByChildId("devmode-copy-id", children, true)?.push(menuItem);
|
||||||
|
};
|
||||||
|
|
||||||
|
const expressionPickerPatch: NavContextMenuPatchCallback = (children, props: { target: HTMLElement; }) => {
|
||||||
|
const { id } = props?.target?.dataset ?? {};
|
||||||
|
if (!id) return;
|
||||||
|
|
||||||
|
if (!props.target.className?.includes("lottieCanvas")) {
|
||||||
|
const stickerCache = StickersStore.getStickerById(id);
|
||||||
|
if (stickerCache) {
|
||||||
|
children.push(buildMenuExpression("Sticker", () => stickerCache));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "CopyStickerLinks",
|
||||||
|
description: "Adds the ability to copy and open sticker links to your browser",
|
||||||
|
authors: [Devs.Byeoon],
|
||||||
|
contextMenus: {
|
||||||
|
"message": messageContextMenuPatch,
|
||||||
|
"expression-picker": expressionPickerPatch
|
||||||
|
}
|
||||||
|
});
|
|
@ -494,7 +494,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({
|
||||||
name: "Sqaaakoi",
|
name: "Sqaaakoi",
|
||||||
id: 259558259491340288n
|
id: 259558259491340288n
|
||||||
},
|
},
|
||||||
Byron: {
|
Byeoon: {
|
||||||
name: "byeoon",
|
name: "byeoon",
|
||||||
id: 1167275288036655133n
|
id: 1167275288036655133n
|
||||||
},
|
},
|
||||||
|
@ -1046,6 +1046,10 @@ export const EquicordDevs = Object.freeze({
|
||||||
name: "ItsAlex",
|
name: "ItsAlex",
|
||||||
id: 551023598203043840n
|
id: 551023598203043840n
|
||||||
},
|
},
|
||||||
|
Byeoon: {
|
||||||
|
name: "byeoon",
|
||||||
|
id: 1167275288036655133n
|
||||||
|
},
|
||||||
} satisfies Record<string, Dev>);
|
} satisfies Record<string, Dev>);
|
||||||
|
|
||||||
// iife so #__PURE__ works correctly
|
// iife so #__PURE__ works correctly
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue