New plugin CopyStickerLinks: adds Copy/Open Link option to stickers (#3191)
Co-authored-by: V <vendicated@riseup.net>
This commit is contained in:
parent
7e028267f1
commit
4403aee3c1
13 changed files with 188 additions and 69 deletions
|
|
@ -1 +1,2 @@
|
||||||
export * from "./commands";
|
export * from "./commands";
|
||||||
|
export * from "./messages";
|
||||||
|
|
|
||||||
13
packages/discord-types/enums/messages.ts
Normal file
13
packages/discord-types/enums/messages.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
export const enum StickerType {
|
||||||
|
/** an official sticker in a pack */
|
||||||
|
STANDARD = 1,
|
||||||
|
/** a sticker uploaded to a guild for the guild's members */
|
||||||
|
GUILD = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enum StickerFormatType {
|
||||||
|
PNG = 1,
|
||||||
|
APNG = 2,
|
||||||
|
LOTTIE = 3,
|
||||||
|
GIF = 4
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ import { CommandOption } from './Commands';
|
||||||
import { User, UserJSON } from '../User';
|
import { User, UserJSON } from '../User';
|
||||||
import { Embed, EmbedJSON } from './Embed';
|
import { Embed, EmbedJSON } from './Embed';
|
||||||
import { DiscordRecord } from "../Record";
|
import { DiscordRecord } from "../Record";
|
||||||
|
import { StickerFormatType } from "../../../enums";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: looks like discord has moved over to Date instead of Moment;
|
* TODO: looks like discord has moved over to Date instead of Moment;
|
||||||
|
|
@ -92,7 +93,7 @@ export class Message extends DiscordRecord {
|
||||||
reactions: MessageReaction[];
|
reactions: MessageReaction[];
|
||||||
state: string;
|
state: string;
|
||||||
stickerItems: {
|
stickerItems: {
|
||||||
format_type: number;
|
format_type: StickerFormatType;
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
}[];
|
}[];
|
||||||
|
|
|
||||||
35
packages/discord-types/src/common/messages/Sticker.d.ts
vendored
Normal file
35
packages/discord-types/src/common/messages/Sticker.d.ts
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { StickerFormatType, StickerType } from "../../../enums";
|
||||||
|
|
||||||
|
interface BaseSticker {
|
||||||
|
asset: string;
|
||||||
|
available: boolean;
|
||||||
|
description: string;
|
||||||
|
format_type: StickerFormatType;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
sort_value?: number;
|
||||||
|
/** a comma separated string */
|
||||||
|
tags: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PackSticker extends BaseSticker {
|
||||||
|
pack_id: string;
|
||||||
|
type: StickerType.STANDARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GuildSticker extends BaseSticker {
|
||||||
|
guild_id: string;
|
||||||
|
type: StickerType.GUILD;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Sticker = PackSticker | GuildSticker;
|
||||||
|
|
||||||
|
export interface PremiumStickerPack {
|
||||||
|
banner_asset_id?: string;
|
||||||
|
cover_sticker_id?: string;
|
||||||
|
description: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
sku_id: string;
|
||||||
|
stickers: PackSticker[];
|
||||||
|
}
|
||||||
|
|
@ -2,3 +2,4 @@ export * from "./Commands";
|
||||||
export * from "./Message";
|
export * from "./Message";
|
||||||
export * from "./Embed";
|
export * from "./Embed";
|
||||||
export * from "./Emoji";
|
export * from "./Emoji";
|
||||||
|
export * from "./Sticker";
|
||||||
|
|
|
||||||
15
packages/discord-types/src/stores/StickersStore.d.ts
vendored
Normal file
15
packages/discord-types/src/stores/StickersStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { FluxStore, GuildSticker, PremiumStickerPack, Sticker } from "..";
|
||||||
|
|
||||||
|
export type StickerGuildMap = Map<string, GuildSticker[]>;
|
||||||
|
|
||||||
|
export class StickersStore extends FluxStore {
|
||||||
|
getAllGuildStickers(): StickerGuildMap;
|
||||||
|
getRawStickersByGuild(): StickerGuildMap;
|
||||||
|
getPremiumPacks(): PremiumStickerPack[];
|
||||||
|
|
||||||
|
getStickerById(id: string): Sticker | undefined;
|
||||||
|
getStickerPack(id: string): PremiumStickerPack | undefined;
|
||||||
|
getStickersByGuildId(guildId: string): Sticker[] | undefined;
|
||||||
|
|
||||||
|
isPremiumPack(id: string): boolean;
|
||||||
|
}
|
||||||
1
packages/discord-types/src/stores/index.d.ts
vendored
1
packages/discord-types/src/stores/index.d.ts
vendored
|
|
@ -11,6 +11,7 @@ export * from "./MessageStore";
|
||||||
export * from "./RelationshipStore";
|
export * from "./RelationshipStore";
|
||||||
export * from "./SelectedChannelStore";
|
export * from "./SelectedChannelStore";
|
||||||
export * from "./SelectedGuildStore";
|
export * from "./SelectedGuildStore";
|
||||||
|
export * from "./StickersStore";
|
||||||
export * from "./ThemeStore";
|
export * from "./ThemeStore";
|
||||||
export * from "./TypingStore";
|
export * from "./TypingStore";
|
||||||
export * from "./UserProfileStore";
|
export * from "./UserProfileStore";
|
||||||
|
|
|
||||||
5
src/plugins/copyStickerLinks/README.MD
Normal file
5
src/plugins/copyStickerLinks/README.MD
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# CopyStickerLinks
|
||||||
|
|
||||||
|
Adds "Copy Link" and "Open Link" options to the context menu of stickers!
|
||||||
|
|
||||||
|

|
||||||
94
src/plugins/copyStickerLinks/index.tsx
Normal file
94
src/plugins/copyStickerLinks/index.tsx
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* 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 { Message, Sticker } from "@vencord/discord-types";
|
||||||
|
import { Menu, React, StickersStore } from "@webpack/common";
|
||||||
|
import ExpressionClonerPlugin from "plugins/expressionCloner";
|
||||||
|
|
||||||
|
const StickerExt = [, "png", "png", "json", "gif"] as const;
|
||||||
|
|
||||||
|
type PartialSticker = Pick<Sticker, "id" | "format_type">;
|
||||||
|
|
||||||
|
function getUrl(data: PartialSticker): string {
|
||||||
|
if (data.format_type === 4)
|
||||||
|
return `https:${window.GLOBAL_ENV.MEDIA_PROXY_ENDPOINT}/stickers/${data.id}.gif?size=512&lossless=true`;
|
||||||
|
|
||||||
|
return `https://${window.GLOBAL_ENV.CDN_HOST}/stickers/${data.id}.${StickerExt[data.format_type]}?size=512&lossless=true`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildMenuItem(sticker: PartialSticker, addBottomSeparator: boolean) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Menu.MenuGroup>
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="vc-copy-sticker-link"
|
||||||
|
key="vc-copy-sticker-link"
|
||||||
|
label="Copy Link"
|
||||||
|
action={() => copyWithToast(getUrl(sticker), "Link copied!")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="vc-open-sticker-link"
|
||||||
|
key="vc-open-sticker-link"
|
||||||
|
label="Open Link"
|
||||||
|
action={() => VencordNative.native.openExternal(getUrl(sticker))}
|
||||||
|
/>
|
||||||
|
</Menu.MenuGroup>
|
||||||
|
{addBottomSeparator && <Menu.MenuSeparator />}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageContextMenuPatch: NavContextMenuPatchCallback = (
|
||||||
|
children,
|
||||||
|
{ favoriteableId, favoriteableType, message }: { favoriteableId: string; favoriteableType: string; message: Message; }
|
||||||
|
) => {
|
||||||
|
if (!favoriteableId || favoriteableType !== "sticker") return;
|
||||||
|
|
||||||
|
const sticker = message.stickerItems.find(s => s.id === favoriteableId);
|
||||||
|
if (!sticker?.format_type) return;
|
||||||
|
|
||||||
|
const idx = children.findIndex(c => Array.isArray(c) && findGroupChildrenByChildId("vc-copy-sticker-url", c) != null);
|
||||||
|
|
||||||
|
children.splice(idx, 0, buildMenuItem(sticker, idx !== -1));
|
||||||
|
};
|
||||||
|
|
||||||
|
const expressionPickerPatch: NavContextMenuPatchCallback = (children, props: { target: HTMLElement; }) => {
|
||||||
|
const id = props?.target?.dataset?.id;
|
||||||
|
if (!id) return;
|
||||||
|
if (props.target.className?.includes("lottieCanvas")) return;
|
||||||
|
|
||||||
|
const sticker = StickersStore.getStickerById(id);
|
||||||
|
if (sticker) {
|
||||||
|
children.push(buildMenuItem(sticker, Vencord.Plugins.isPluginEnabled(ExpressionClonerPlugin.name)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "CopyStickerLinks",
|
||||||
|
description: "Adds the ability to copy & open Sticker links",
|
||||||
|
authors: [Devs.Ven, Devs.Byeoon],
|
||||||
|
contextMenus: {
|
||||||
|
"message": messageContextMenuPatch,
|
||||||
|
"expression-picker": expressionPickerPatch
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -25,25 +25,17 @@ import { Logger } from "@utils/Logger";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
|
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { Guild } from "@vencord/discord-types";
|
import { Guild, GuildSticker } from "@vencord/discord-types";
|
||||||
import { findByCodeLazy, findStoreLazy } from "@webpack";
|
import { findByCodeLazy } from "@webpack";
|
||||||
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, IconUtils, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
|
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, IconUtils, Menu, PermissionsBits, PermissionStore, React, RestAPI, StickersStore, Toasts, Tooltip, UserStore } from "@webpack/common";
|
||||||
import { Promisable } from "type-fest";
|
import { Promisable } from "type-fest";
|
||||||
|
|
||||||
const StickersStore = findStoreLazy("StickersStore");
|
|
||||||
const uploadEmoji = findByCodeLazy(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START");
|
const uploadEmoji = findByCodeLazy(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START");
|
||||||
|
|
||||||
const getGuildMaxEmojiSlots = findByCodeLazy(".additionalEmojiSlots") as (guild: Guild) => number;
|
const getGuildMaxEmojiSlots = findByCodeLazy(".additionalEmojiSlots") as (guild: Guild) => number;
|
||||||
|
|
||||||
interface Sticker {
|
interface Sticker extends GuildSticker {
|
||||||
t: "Sticker";
|
t: "Sticker";
|
||||||
description: string;
|
|
||||||
format_type: number;
|
|
||||||
guild_id: string;
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
tags: string;
|
|
||||||
type: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Emoji {
|
interface Emoji {
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,12 @@ import { getCurrentGuild, getEmojiURL } from "@utils/discord";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType, Patch } from "@utils/types";
|
import definePlugin, { OptionType, Patch } from "@utils/types";
|
||||||
import type { Emoji, Message } from "@vencord/discord-types";
|
import type { Emoji, Message } from "@vencord/discord-types";
|
||||||
|
import { StickerFormatType } from "@vencord/discord-types/enums";
|
||||||
import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
|
import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
|
||||||
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
|
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, lodash, Parser, PermissionsBits, PermissionStore, StickersStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
|
||||||
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
||||||
import type { ReactElement, ReactNode } from "react";
|
import type { ReactElement, ReactNode } from "react";
|
||||||
|
|
||||||
const StickerStore = findStoreLazy("StickersStore") as {
|
|
||||||
getPremiumPacks(): StickerPack[];
|
|
||||||
getAllGuildStickers(): Map<string, Sticker[]>;
|
|
||||||
getStickerById(id: string): Sticker | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const UserSettingsProtoStore = findStoreLazy("UserSettingsProtoStore");
|
const UserSettingsProtoStore = findStoreLazy("UserSettingsProtoStore");
|
||||||
|
|
||||||
const BINARY_READ_OPTIONS = findByPropsLazy("readerFactory");
|
const BINARY_READ_OPTIONS = findByPropsLazy("readerFactory");
|
||||||
|
|
@ -70,41 +65,6 @@ const enum EmojiIntentions {
|
||||||
|
|
||||||
const IS_BYPASSEABLE_INTENTION = `[${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)`;
|
const IS_BYPASSEABLE_INTENTION = `[${EmojiIntentions.CHAT},${EmojiIntentions.GUILD_STICKER_RELATED_EMOJI}].includes(fakeNitroIntention)`;
|
||||||
|
|
||||||
const enum StickerType {
|
|
||||||
PNG = 1,
|
|
||||||
APNG = 2,
|
|
||||||
LOTTIE = 3,
|
|
||||||
// don't think you can even have gif stickers but the docs have it
|
|
||||||
GIF = 4
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BaseSticker {
|
|
||||||
available: boolean;
|
|
||||||
description: string;
|
|
||||||
format_type: number;
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
tags: string;
|
|
||||||
type: number;
|
|
||||||
}
|
|
||||||
interface GuildSticker extends BaseSticker {
|
|
||||||
guild_id: string;
|
|
||||||
}
|
|
||||||
interface DiscordSticker extends BaseSticker {
|
|
||||||
pack_id: string;
|
|
||||||
}
|
|
||||||
type Sticker = GuildSticker | DiscordSticker;
|
|
||||||
|
|
||||||
interface StickerPack {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
sku_id: string;
|
|
||||||
description: string;
|
|
||||||
cover_sticker_id: string;
|
|
||||||
banner_asset_id: string;
|
|
||||||
stickers: Sticker[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const enum FakeNoticeType {
|
const enum FakeNoticeType {
|
||||||
Sticker,
|
Sticker,
|
||||||
Emoji
|
Emoji
|
||||||
|
|
@ -549,8 +509,8 @@ export default definePlugin({
|
||||||
|
|
||||||
const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);
|
const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);
|
||||||
if (gifMatch) {
|
if (gifMatch) {
|
||||||
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker
|
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
|
||||||
if (StickerStore.getStickerById(gifMatch[1])) return null;
|
if (StickersStore.getStickerById(gifMatch[1])) return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -638,7 +598,7 @@ export default definePlugin({
|
||||||
url = new URL(item);
|
url = new URL(item);
|
||||||
} catch { }
|
} catch { }
|
||||||
|
|
||||||
const stickerName = StickerStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker";
|
const stickerName = StickersStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker";
|
||||||
stickers.push({
|
stickers.push({
|
||||||
format_type: 1,
|
format_type: 1,
|
||||||
id: imgMatch[1],
|
id: imgMatch[1],
|
||||||
|
|
@ -651,9 +611,9 @@ export default definePlugin({
|
||||||
|
|
||||||
const gifMatch = item.match(fakeNitroGifStickerRegex);
|
const gifMatch = item.match(fakeNitroGifStickerRegex);
|
||||||
if (gifMatch) {
|
if (gifMatch) {
|
||||||
if (!StickerStore.getStickerById(gifMatch[1])) continue;
|
if (!StickersStore.getStickerById(gifMatch[1])) continue;
|
||||||
|
|
||||||
const stickerName = StickerStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker";
|
const stickerName = StickersStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker";
|
||||||
stickers.push({
|
stickers.push({
|
||||||
format_type: 2,
|
format_type: 2,
|
||||||
id: gifMatch[1],
|
id: gifMatch[1],
|
||||||
|
|
@ -689,8 +649,8 @@ export default definePlugin({
|
||||||
|
|
||||||
const gifMatch = url.match(fakeNitroGifStickerRegex);
|
const gifMatch = url.match(fakeNitroGifStickerRegex);
|
||||||
if (gifMatch) {
|
if (gifMatch) {
|
||||||
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker
|
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
|
||||||
if (StickerStore.getStickerById(gifMatch[1])) return true;
|
if (StickersStore.getStickerById(gifMatch[1])) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -710,8 +670,8 @@ export default definePlugin({
|
||||||
|
|
||||||
const match = attachment.url.match(fakeNitroGifStickerRegex);
|
const match = attachment.url.match(fakeNitroGifStickerRegex);
|
||||||
if (match) {
|
if (match) {
|
||||||
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker
|
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
|
||||||
if (StickerStore.getStickerById(match[1])) return false;
|
if (StickersStore.getStickerById(match[1])) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -866,7 +826,7 @@ export default definePlugin({
|
||||||
if (!s.enableStickerBypass)
|
if (!s.enableStickerBypass)
|
||||||
break stickerBypass;
|
break stickerBypass;
|
||||||
|
|
||||||
const sticker = StickerStore.getStickerById(extra.stickers?.[0]!);
|
const sticker = StickersStore.getStickerById(extra.stickers?.[0]!);
|
||||||
if (!sticker)
|
if (!sticker)
|
||||||
break stickerBypass;
|
break stickerBypass;
|
||||||
|
|
||||||
|
|
@ -883,11 +843,11 @@ export default definePlugin({
|
||||||
// but will give us a normal non animated png for no reason
|
// but will give us a normal non animated png for no reason
|
||||||
// TODO: Remove this workaround when it's not needed anymore
|
// TODO: Remove this workaround when it's not needed anymore
|
||||||
let link = this.getStickerLink(sticker.id);
|
let link = this.getStickerLink(sticker.id);
|
||||||
if (sticker.format_type === StickerType.GIF && link.includes(".png")) {
|
if (sticker.format_type === StickerFormatType.GIF && link.includes(".png")) {
|
||||||
link = link.replace(".png", ".gif");
|
link = link.replace(".png", ".gif");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sticker.format_type === StickerType.APNG) {
|
if (sticker.format_type === StickerFormatType.APNG) {
|
||||||
if (!hasAttachmentPerms(channelId)) {
|
if (!hasAttachmentPerms(channelId)) {
|
||||||
Alerts.show({
|
Alerts.show({
|
||||||
title: "Hold on!",
|
title: "Hold on!",
|
||||||
|
|
|
||||||
|
|
@ -482,7 +482,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
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,11 @@ export let TypingStore: t.TypingStore;
|
||||||
export let RelationshipStore: t.RelationshipStore;
|
export let RelationshipStore: t.RelationshipStore;
|
||||||
|
|
||||||
export let EmojiStore: t.EmojiStore;
|
export let EmojiStore: t.EmojiStore;
|
||||||
|
export let StickersStore: t.StickersStore;
|
||||||
export let ThemeStore: t.ThemeStore;
|
export let ThemeStore: t.ThemeStore;
|
||||||
export let WindowStore: t.WindowStore;
|
export let WindowStore: t.WindowStore;
|
||||||
export let DraftStore: t.DraftStore;
|
export let DraftStore: t.DraftStore;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see jsdoc of {@link t.useStateFromStores}
|
* @see jsdoc of {@link t.useStateFromStores}
|
||||||
*/
|
*/
|
||||||
|
|
@ -77,6 +77,7 @@ waitForStore("GuildRoleStore", m => GuildRoleStore = m);
|
||||||
waitForStore("MessageStore", m => MessageStore = m);
|
waitForStore("MessageStore", m => MessageStore = m);
|
||||||
waitForStore("WindowStore", m => WindowStore = m);
|
waitForStore("WindowStore", m => WindowStore = m);
|
||||||
waitForStore("EmojiStore", m => EmojiStore = m);
|
waitForStore("EmojiStore", m => EmojiStore = m);
|
||||||
|
waitForStore("StickersStore", m => StickersStore = m);
|
||||||
waitForStore("TypingStore", m => TypingStore = m);
|
waitForStore("TypingStore", m => TypingStore = m);
|
||||||
waitForStore("ThemeStore", m => {
|
waitForStore("ThemeStore", m => {
|
||||||
ThemeStore = m;
|
ThemeStore = m;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue