feat(plugin): BiggerStreamPreview (#1222)
Co-authored-by: V <vendicated@riseup.net>
This commit is contained in:
		
							parent
							
								
									55af40ee74
								
							
						
					
					
						commit
						e8d90d2b45
					
				
					 14 changed files with 362 additions and 24 deletions
				
			
		|  | @ -147,6 +147,26 @@ export function OwnerCrownIcon(props: IconProps) { | |||
|     ); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Discord's screenshare icon, as seen in the connection panel | ||||
|  */ | ||||
| export function ScreenshareIcon(props: IconProps) { | ||||
|     return ( | ||||
|         <Icon | ||||
|             {...props} | ||||
|             className={classes(props.className, "vc-screenshare-icon")} | ||||
|             viewBox="0 0 24 24" | ||||
|         > | ||||
|             <path | ||||
|                 fill="currentColor" | ||||
|                 fill-rule="evenodd" | ||||
|                 clip-rule="evenodd" | ||||
|                 d="M2 4.5C2 3.397 2.897 2.5 4 2.5H20C21.103 2.5 22 3.397 22 4.5V15.5C22 16.604 21.103 17.5 20 17.5H13V19.5H17V21.5H7V19.5H11V17.5H4C2.897 17.5 2 16.604 2 15.5V4.5ZM13.2 14.3375V11.6C9.864 11.6 7.668 12.6625 6 15C6.672 11.6625 8.532 8.3375 13.2 7.6625V5L18 9.6625L13.2 14.3375Z" | ||||
|             /> | ||||
|         </Icon> | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| export function ImageVisible(props: IconProps) { | ||||
|     return ( | ||||
|         <Icon | ||||
|  |  | |||
							
								
								
									
										101
									
								
								src/plugins/biggerStreamPreview/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/plugins/biggerStreamPreview/index.tsx
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,101 @@ | |||
| /* | ||||
|  * Vencord, a modification for Discord's desktop app | ||||
|  * Copyright (c) 2023 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 { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu"; | ||||
| import { ScreenshareIcon } from "@components/Icons"; | ||||
| import { Devs } from "@utils/constants"; | ||||
| import { openImageModal } from "@utils/discord"; | ||||
| import definePlugin from "@utils/types"; | ||||
| import { Menu } from "@webpack/common"; | ||||
| import { Channel, User } from "discord-types/general"; | ||||
| 
 | ||||
| import { ApplicationStreamingStore, ApplicationStreamPreviewStore } from "./webpack/stores"; | ||||
| import { ApplicationStream, Stream } from "./webpack/types/stores"; | ||||
| 
 | ||||
| export interface UserContextProps { | ||||
|     channel: Channel, | ||||
|     channelSelected: boolean, | ||||
|     className: string, | ||||
|     config: { context: string; }; | ||||
|     context: string, | ||||
|     onHeightUpdate: Function, | ||||
|     position: string, | ||||
|     target: HTMLElement, | ||||
|     theme: string, | ||||
|     user: User; | ||||
| } | ||||
| 
 | ||||
| export interface StreamContextProps { | ||||
|     appContext: string, | ||||
|     className: string, | ||||
|     config: { context: string; }; | ||||
|     context: string, | ||||
|     exitFullscreen: Function, | ||||
|     onHeightUpdate: Function, | ||||
|     position: string, | ||||
|     target: HTMLElement, | ||||
|     stream: Stream, | ||||
|     theme: string, | ||||
| } | ||||
| 
 | ||||
| export const handleViewPreview = async ({ guildId, channelId, ownerId }: ApplicationStream | Stream) => { | ||||
|     const previewUrl = await ApplicationStreamPreviewStore.getPreviewURL(guildId, channelId, ownerId); | ||||
|     if (!previewUrl) return; | ||||
| 
 | ||||
|     openImageModal(previewUrl); | ||||
| }; | ||||
| 
 | ||||
| export const addViewStreamContext: NavContextMenuPatchCallback = (children, { userId }: { userId: string | bigint; }) => () => { | ||||
|     const streamPreviewItemIdentifier = "view-stream-preview"; | ||||
| 
 | ||||
|     const stream = ApplicationStreamingStore.getAnyStreamForUser(userId); | ||||
| 
 | ||||
|     const streamPreviewItem = ( | ||||
|         <Menu.MenuItem | ||||
|             label="View Stream Preview" | ||||
|             id={streamPreviewItemIdentifier} | ||||
|             icon={ScreenshareIcon} | ||||
|             action={() => stream && handleViewPreview(stream)} | ||||
|             disabled={!stream} | ||||
|         /> | ||||
|     ); | ||||
| 
 | ||||
|     children.push(<Menu.MenuSeparator />, streamPreviewItem); | ||||
| }; | ||||
| 
 | ||||
| export const streamContextPatch: NavContextMenuPatchCallback = (children, { stream }: StreamContextProps) => { | ||||
|     return addViewStreamContext(children, { userId: stream.ownerId }); | ||||
| }; | ||||
| 
 | ||||
| export const userContextPatch: NavContextMenuPatchCallback = (children, { user }: UserContextProps) => { | ||||
|     return addViewStreamContext(children, { userId: user.id }); | ||||
| }; | ||||
| 
 | ||||
| export default definePlugin({ | ||||
|     name: "BiggerStreamPreview", | ||||
|     description: "This plugin allows you to enlarge stream previews", | ||||
|     authors: [Devs.phil], | ||||
|     start: () => { | ||||
|         addContextMenuPatch("user-context", userContextPatch); | ||||
|         addContextMenuPatch("stream-context", streamContextPatch); | ||||
|     }, | ||||
|     stop: () => { | ||||
|         removeContextMenuPatch("user-context", userContextPatch); | ||||
|         removeContextMenuPatch("stream-context", streamContextPatch); | ||||
|     } | ||||
| }); | ||||
							
								
								
									
										25
									
								
								src/plugins/biggerStreamPreview/webpack/stores.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/plugins/biggerStreamPreview/webpack/stores.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| /* | ||||
|  * Vencord, a modification for Discord's desktop app | ||||
|  * Copyright (c) 2023 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 { findStoreLazy } from "@webpack"; | ||||
| 
 | ||||
| import * as t from "./types/stores"; | ||||
| 
 | ||||
| export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStoreLazy("ApplicationStreamPreviewStore"); | ||||
| export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStoreLazy("ApplicationStreamingStore"); | ||||
							
								
								
									
										77
									
								
								src/plugins/biggerStreamPreview/webpack/types/stores.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/plugins/biggerStreamPreview/webpack/types/stores.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | |||
| /* | ||||
|  * Vencord, a modification for Discord's desktop app | ||||
|  * Copyright (c) 2023 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 { FluxStore } from "@webpack/types"; | ||||
| 
 | ||||
| export interface ApplicationStreamPreviewStore extends FluxStore { | ||||
|     getIsPreviewLoading: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => boolean; | ||||
|     getPreviewURL: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => Promise<string | null>; | ||||
|     getPreviewURLForStreamKey: (streamKey: string) => ReturnType<ApplicationStreamPreviewStore["getPreviewURL"]>; | ||||
| } | ||||
| 
 | ||||
| export interface ApplicationStream { | ||||
|     streamType: string; | ||||
|     guildId: string | null; | ||||
|     channelId: string; | ||||
|     ownerId: string; | ||||
| } | ||||
| 
 | ||||
| export interface Stream extends ApplicationStream { | ||||
|     state: string; | ||||
| } | ||||
| 
 | ||||
| export interface RTCStream { | ||||
|     region: string, | ||||
|     streamKey: string, | ||||
|     viewerIds: string[]; | ||||
| } | ||||
| 
 | ||||
| export interface StreamMetadata { | ||||
|     id: string | null, | ||||
|     pid: number | null, | ||||
|     sourceName: string | null; | ||||
| } | ||||
| 
 | ||||
| export interface StreamingStoreState { | ||||
|     activeStreams: [string, Stream][]; | ||||
|     rtcStreams: { [key: string]: RTCStream; }; | ||||
|     streamerActiveStreamMetadatas: { [key: string]: StreamMetadata | null; }; | ||||
|     streamsByUserAndGuild: { [key: string]: { [key: string]: ApplicationStream; }; }; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * example how a stream key could look like: `call(type of connection):1116549917987192913(channelId):305238513941667851(ownerId)` | ||||
|  */ | ||||
| export interface ApplicationStreamingStore extends FluxStore { | ||||
|     getActiveStreamForApplicationStream: (stream: ApplicationStream) => Stream | null; | ||||
|     getActiveStreamForStreamKey: (streamKey: string) => Stream | null; | ||||
|     getActiveStreamForUser: (userId: string | bigint, guildId?: string | bigint | null) => Stream | null; | ||||
|     getAllActiveStreams: () => Stream[]; | ||||
|     getAllApplicationStreams: () => ApplicationStream[]; | ||||
|     getAllApplicationStreamsForChannel: (channelId: string | bigint) => ApplicationStream[]; | ||||
|     getAllActiveStreamsForChannel: (channelId: string | bigint) => Stream[]; | ||||
|     getAnyStreamForUser: (userId: string | bigint) => Stream | ApplicationStream | null; | ||||
|     getStreamForUser: (userId: string | bigint, guildId?: string | bigint | null) => Stream | null; | ||||
|     getCurrentUserActiveStream: () => Stream | null; | ||||
|     getLastActiveStream: () => Stream | null; | ||||
|     getState: () => StreamingStoreState; | ||||
|     getRTCStream: (streamKey: string) => RTCStream | null; | ||||
|     getStreamerActiveStreamMetadata: () => StreamMetadata; | ||||
|     getViewerIds: (stream: ApplicationStream) => string[]; | ||||
|     isSelfStreamHidden: (channelId: string | bigint | null) => boolean; | ||||
| } | ||||
|  | @ -20,15 +20,12 @@ import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatc | |||
| import { definePluginSettings } from "@api/Settings"; | ||||
| import { ImageIcon } from "@components/Icons"; | ||||
| import { Devs } from "@utils/constants"; | ||||
| import { ModalRoot, ModalSize, openModal } from "@utils/modal"; | ||||
| import { LazyComponent } from "@utils/react"; | ||||
| import { openImageModal } from "@utils/discord"; | ||||
| import definePlugin, { OptionType } from "@utils/types"; | ||||
| import { find, findByCode, findByPropsLazy } from "@webpack"; | ||||
| import { findByPropsLazy } from "@webpack"; | ||||
| import { GuildMemberStore, Menu } from "@webpack/common"; | ||||
| import type { Channel, Guild, User } from "discord-types/general"; | ||||
| 
 | ||||
| const ImageModal = LazyComponent(() => findByCode(".MEDIA_MODAL_CLOSE,")); | ||||
| const MaskedLink = LazyComponent(() => find(m => m.type?.toString().includes("MASKED_LINK)"))); | ||||
| const BannerStore = findByPropsLazy("getGuildBannerURL"); | ||||
| 
 | ||||
| interface UserContextProps { | ||||
|  | @ -60,26 +57,29 @@ const settings = definePluginSettings({ | |||
|                 value: "jpg", | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     imgSize: { | ||||
|         type: OptionType.SELECT, | ||||
|         description: "The image size to use", | ||||
|         options: ["128", "256", "512", "1024", "2048", "4096"].map(n => ({ label: n, value: n, default: n === "1024" })) | ||||
|     } | ||||
| }); | ||||
| 
 | ||||
| function openImage(url: string) { | ||||
|     const format = url.startsWith("/") ? "png" : settings.store.format; | ||||
| 
 | ||||
|     const u = new URL(url, window.location.href); | ||||
|     u.searchParams.set("size", "512"); | ||||
|     u.searchParams.set("size", settings.store.imgSize); | ||||
|     u.pathname = u.pathname.replace(/\.(png|jpe?g|webp)$/, `.${format}`); | ||||
|     url = u.toString(); | ||||
| 
 | ||||
|     openModal(modalProps => ( | ||||
|         <ModalRoot size={ModalSize.DYNAMIC} {...modalProps}> | ||||
|             <ImageModal | ||||
|                 shouldAnimate={true} | ||||
|                 original={url} | ||||
|                 src={url} | ||||
|                 renderLinkComponent={MaskedLink} | ||||
|             /> | ||||
|         </ModalRoot> | ||||
|     )); | ||||
|     u.searchParams.set("size", "4096"); | ||||
|     const originalUrl = u.toString(); | ||||
| 
 | ||||
|     openImageModal(url, { | ||||
|         original: originalUrl, | ||||
|         height: 256 | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| const UserContext: NavContextMenuPatchCallback = (children, { user, guildId }: UserContextProps) => () => { | ||||
|  | @ -90,7 +90,7 @@ const UserContext: NavContextMenuPatchCallback = (children, { user, guildId }: U | |||
|             <Menu.MenuItem | ||||
|                 id="view-avatar" | ||||
|                 label="View Avatar" | ||||
|                 action={() => openImage(BannerStore.getUserAvatarURL(user, true, 512))} | ||||
|                 action={() => openImage(BannerStore.getUserAvatarURL(user, true))} | ||||
|                 icon={ImageIcon} | ||||
|             /> | ||||
|             {memberAvatar && ( | ||||
|  | @ -122,7 +122,6 @@ const GuildContext: NavContextMenuPatchCallback = (children, { guild: { id, icon | |||
|                         openImage(BannerStore.getGuildIconURL({ | ||||
|                             id, | ||||
|                             icon, | ||||
|                             size: 512, | ||||
|                             canAnimate: true | ||||
|                         })) | ||||
|                     } | ||||
|  |  | |||
|  | @ -319,6 +319,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({ | |||
|         name: "amia", | ||||
|         id: 142007603549962240n | ||||
|     }, | ||||
|     phil: { | ||||
|         name: "phil", | ||||
|         id: 305288513941667851n | ||||
|     }, | ||||
|     ImLvna: { | ||||
|         name: "Luna <3", | ||||
|         id: 174200708818665472n | ||||
|  |  | |||
|  | @ -18,9 +18,11 @@ | |||
| 
 | ||||
| import { MessageObject } from "@api/MessageEvents"; | ||||
| import { findByPropsLazy, findLazy } from "@webpack"; | ||||
| import { ChannelStore, ComponentDispatch, GuildStore, PrivateChannelsStore, SelectedChannelStore } from "@webpack/common"; | ||||
| import { ChannelStore, ComponentDispatch, GuildStore, MaskedLink, ModalImageClasses, PrivateChannelsStore, SelectedChannelStore } from "@webpack/common"; | ||||
| import { Guild, Message } from "discord-types/general"; | ||||
| 
 | ||||
| import { ImageModal, ModalRoot, ModalSize, openModal } from "./modal"; | ||||
| 
 | ||||
| const PreloadedUserSettings = findLazy(m => m.ProtoClass?.typeName.endsWith("PreloadedUserSettings")); | ||||
| const MessageActions = findByPropsLazy("editMessage", "sendMessage"); | ||||
| 
 | ||||
|  | @ -77,3 +79,23 @@ export function sendMessage( | |||
| 
 | ||||
|     return MessageActions.sendMessage(channelId, messageData, waitForChannelReady, extra); | ||||
| } | ||||
| 
 | ||||
| export function openImageModal(url: string, props?: Partial<React.ComponentProps<ImageModal>>): string { | ||||
|     return openModal(modalProps => ( | ||||
|         <ModalRoot | ||||
|             {...modalProps} | ||||
|             className={ModalImageClasses.modal} | ||||
|             size={ModalSize.DYNAMIC}> | ||||
|             <ImageModal | ||||
|                 className={ModalImageClasses.image} | ||||
|                 original={url} | ||||
|                 placeholder={url} | ||||
|                 src={url} | ||||
|                 renderLinkComponent={props => <MaskedLink {...props} />} | ||||
|                 shouldHideMediaOptions={false} | ||||
|                 shouldAnimate | ||||
|                 {...props} | ||||
|             /> | ||||
|         </ModalRoot> | ||||
|     )); | ||||
| } | ||||
|  | @ -16,7 +16,7 @@ | |||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| 
 | ||||
| import { filters, mapMangledModuleLazy } from "@webpack"; | ||||
| import { filters, findByCode, mapMangledModuleLazy } from "@webpack"; | ||||
| import type { ComponentType, PropsWithChildren, ReactNode, Ref } from "react"; | ||||
| 
 | ||||
| import { LazyComponent } from "./react"; | ||||
|  | @ -107,6 +107,25 @@ export const Modals = mapMangledModuleLazy(".closeWithCircleBackground", { | |||
|     }>; | ||||
| }; | ||||
| 
 | ||||
| export type ImageModal = ComponentType<{ | ||||
|     className?: string; | ||||
|     src: string; | ||||
|     placeholder: string; | ||||
|     original: string; | ||||
|     width?: number; | ||||
|     height?: number; | ||||
|     animated?: boolean; | ||||
|     responsive?: boolean; | ||||
|     renderLinkComponent(props: any): ReactNode; | ||||
|     maxWidth?: number; | ||||
|     maxHeight?: number; | ||||
|     shouldAnimate?: boolean; | ||||
|     onClose?(): void; | ||||
|     shouldHideMediaOptions?: boolean; | ||||
| }>; | ||||
| 
 | ||||
| export const ImageModal = LazyComponent(() => findByCode(".renderLinkComponent", ".responsive") as ImageModal); | ||||
| 
 | ||||
| export const ModalRoot = LazyComponent(() => Modals.ModalRoot); | ||||
| export const ModalHeader = LazyComponent(() => Modals.ModalHeader); | ||||
| export const ModalContent = LazyComponent(() => Modals.ModalContent); | ||||
|  |  | |||
							
								
								
									
										24
									
								
								src/webpack/common/classes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/webpack/common/classes.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| /* | ||||
|  * Vencord, a modification for Discord's desktop app | ||||
|  * Copyright (c) 2023 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 { findByPropsLazy } from "@webpack"; | ||||
| 
 | ||||
| import * as t from "./types/classes"; | ||||
| 
 | ||||
| export const ModalImageClasses: t.ImageModalClasses = findByPropsLazy("image", "modal"); | ||||
| export const ButtonWrapperClasses: t.ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent"); | ||||
|  | @ -17,7 +17,7 @@ | |||
| */ | ||||
| 
 | ||||
| // eslint-disable-next-line path-alias/no-relative
 | ||||
| import { filters, findByPropsLazy, waitFor } from "@webpack"; | ||||
| import { filters, waitFor } from "@webpack"; | ||||
| 
 | ||||
| import { waitForComponent } from "./internal"; | ||||
| import * as t from "./types/components"; | ||||
|  | @ -51,11 +51,10 @@ export let Avatar: t.Avatar; | |||
| /** css colour resolver stuff, no clue what exactly this does, just copied usage from Discord */ | ||||
| export let useToken: t.useToken; | ||||
| 
 | ||||
| export const MaskedLink = waitForComponent<t.MaskedLink>("MaskedLink", m => m?.type?.toString().includes("MASKED_LINK)")); | ||||
| export const Timestamp = waitForComponent<t.Timestamp>("Timestamp", filters.byCode(".Messages.MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL.format")); | ||||
| export const Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]); | ||||
| 
 | ||||
| export const ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent") as Record<string, string>; | ||||
| 
 | ||||
| waitFor("FormItem", m => { | ||||
|     ({ useToken, Card, Button, FormSwitch: Switch, Tooltip, TextInput, TextArea, Text, Select, SearchableSelect, Slider, ButtonLooks, TabBar, Popout, Dialog, Paginator, ScrollerThin, Clickable, Avatar } = m); | ||||
|     Forms = m; | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ | |||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| 
 | ||||
| export * from "./classes"; | ||||
| export * from "./components"; | ||||
| export * from "./menu"; | ||||
| export * from "./react"; | ||||
|  | @ -24,4 +25,3 @@ export * as ComponentTypes from "./types/components.d"; | |||
| export * as MenuTypes from "./types/menu.d"; | ||||
| export * as UtilTypes from "./types/utils.d"; | ||||
| export * from "./utils"; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										40
									
								
								src/webpack/common/types/classes.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/webpack/common/types/classes.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| /* | ||||
|  * Vencord, a modification for Discord's desktop app | ||||
|  * Copyright (c) 2023 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/>.
 | ||||
| */ | ||||
| 
 | ||||
| export interface ImageModalClasses { | ||||
|     image: string, | ||||
|     modal: string, | ||||
|     responsiveWidthMobile: string; | ||||
| } | ||||
| 
 | ||||
| export interface ButtonWrapperClasses { | ||||
|     hoverScale: string; | ||||
|     buttonWrapper: string; | ||||
|     button: string; | ||||
|     iconMask: string; | ||||
|     buttonContent: string; | ||||
|     icon: string; | ||||
|     pulseIcon: string; | ||||
|     pulseButton: string; | ||||
|     notificationDot: string; | ||||
|     sparkleContainer: string; | ||||
|     sparkleStar: string; | ||||
|     sparklePlus: string; | ||||
|     sparkle: string; | ||||
|     active: string; | ||||
| } | ||||
							
								
								
									
										7
									
								
								src/webpack/common/types/components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								src/webpack/common/types/components.d.ts
									
									
									
									
										vendored
									
									
								
							|  | @ -398,6 +398,13 @@ export type Paginator = ComponentType<{ | |||
|     hideMaxPage?: boolean; | ||||
| }>; | ||||
| 
 | ||||
| export type MaskedLink = ComponentType<{ | ||||
|     onClick(): void; | ||||
|     trusted: boolean; | ||||
|     title: string, | ||||
|     href: string; | ||||
| }>; | ||||
| 
 | ||||
| export type ScrollerThin = ComponentType<PropsWithChildren<{ | ||||
|     className?: string; | ||||
|     style?: CSSProperties; | ||||
|  |  | |||
							
								
								
									
										1
									
								
								src/webpack/common/types/menu.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/webpack/common/types/menu.d.ts
									
									
									
									
										vendored
									
									
								
							|  | @ -44,6 +44,7 @@ export interface Menu { | |||
|         onChildrenScroll?: Function; | ||||
|         childRowHeight?: number; | ||||
|         listClassName?: string; | ||||
|         disabled?: boolean; | ||||
|     }>; | ||||
|     MenuCheckboxItem: RC<{ | ||||
|         id: string; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue