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) { | export function ImageVisible(props: IconProps) { | ||||||
|     return ( |     return ( | ||||||
|         <Icon |         <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 { definePluginSettings } from "@api/Settings"; | ||||||
| import { ImageIcon } from "@components/Icons"; | import { ImageIcon } from "@components/Icons"; | ||||||
| import { Devs } from "@utils/constants"; | import { Devs } from "@utils/constants"; | ||||||
| import { ModalRoot, ModalSize, openModal } from "@utils/modal"; | import { openImageModal } from "@utils/discord"; | ||||||
| import { LazyComponent } from "@utils/react"; |  | ||||||
| import definePlugin, { OptionType } from "@utils/types"; | import definePlugin, { OptionType } from "@utils/types"; | ||||||
| import { find, findByCode, findByPropsLazy } from "@webpack"; | import { findByPropsLazy } from "@webpack"; | ||||||
| import { GuildMemberStore, Menu } from "@webpack/common"; | import { GuildMemberStore, Menu } from "@webpack/common"; | ||||||
| import type { Channel, Guild, User } from "discord-types/general"; | 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"); | const BannerStore = findByPropsLazy("getGuildBannerURL"); | ||||||
| 
 | 
 | ||||||
| interface UserContextProps { | interface UserContextProps { | ||||||
|  | @ -60,26 +57,29 @@ const settings = definePluginSettings({ | ||||||
|                 value: "jpg", |                 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) { | function openImage(url: string) { | ||||||
|     const format = url.startsWith("/") ? "png" : settings.store.format; |     const format = url.startsWith("/") ? "png" : settings.store.format; | ||||||
|  | 
 | ||||||
|     const u = new URL(url, window.location.href); |     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}`); |     u.pathname = u.pathname.replace(/\.(png|jpe?g|webp)$/, `.${format}`); | ||||||
|     url = u.toString(); |     url = u.toString(); | ||||||
| 
 | 
 | ||||||
|     openModal(modalProps => ( |     u.searchParams.set("size", "4096"); | ||||||
|         <ModalRoot size={ModalSize.DYNAMIC} {...modalProps}> |     const originalUrl = u.toString(); | ||||||
|             <ImageModal | 
 | ||||||
|                 shouldAnimate={true} |     openImageModal(url, { | ||||||
|                 original={url} |         original: originalUrl, | ||||||
|                 src={url} |         height: 256 | ||||||
|                 renderLinkComponent={MaskedLink} |     }); | ||||||
|             /> |  | ||||||
|         </ModalRoot> |  | ||||||
|     )); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const UserContext: NavContextMenuPatchCallback = (children, { user, guildId }: UserContextProps) => () => { | const UserContext: NavContextMenuPatchCallback = (children, { user, guildId }: UserContextProps) => () => { | ||||||
|  | @ -90,7 +90,7 @@ const UserContext: NavContextMenuPatchCallback = (children, { user, guildId }: U | ||||||
|             <Menu.MenuItem |             <Menu.MenuItem | ||||||
|                 id="view-avatar" |                 id="view-avatar" | ||||||
|                 label="View Avatar" |                 label="View Avatar" | ||||||
|                 action={() => openImage(BannerStore.getUserAvatarURL(user, true, 512))} |                 action={() => openImage(BannerStore.getUserAvatarURL(user, true))} | ||||||
|                 icon={ImageIcon} |                 icon={ImageIcon} | ||||||
|             /> |             /> | ||||||
|             {memberAvatar && ( |             {memberAvatar && ( | ||||||
|  | @ -122,7 +122,6 @@ const GuildContext: NavContextMenuPatchCallback = (children, { guild: { id, icon | ||||||
|                         openImage(BannerStore.getGuildIconURL({ |                         openImage(BannerStore.getGuildIconURL({ | ||||||
|                             id, |                             id, | ||||||
|                             icon, |                             icon, | ||||||
|                             size: 512, |  | ||||||
|                             canAnimate: true |                             canAnimate: true | ||||||
|                         })) |                         })) | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|  | @ -319,6 +319,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({ | ||||||
|         name: "amia", |         name: "amia", | ||||||
|         id: 142007603549962240n |         id: 142007603549962240n | ||||||
|     }, |     }, | ||||||
|  |     phil: { | ||||||
|  |         name: "phil", | ||||||
|  |         id: 305288513941667851n | ||||||
|  |     }, | ||||||
|     ImLvna: { |     ImLvna: { | ||||||
|         name: "Luna <3", |         name: "Luna <3", | ||||||
|         id: 174200708818665472n |         id: 174200708818665472n | ||||||
|  |  | ||||||
|  | @ -18,9 +18,11 @@ | ||||||
| 
 | 
 | ||||||
| import { MessageObject } from "@api/MessageEvents"; | import { MessageObject } from "@api/MessageEvents"; | ||||||
| import { findByPropsLazy, findLazy } from "@webpack"; | 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 { Guild, Message } from "discord-types/general"; | ||||||
| 
 | 
 | ||||||
|  | import { ImageModal, ModalRoot, ModalSize, openModal } from "./modal"; | ||||||
|  | 
 | ||||||
| const PreloadedUserSettings = findLazy(m => m.ProtoClass?.typeName.endsWith("PreloadedUserSettings")); | const PreloadedUserSettings = findLazy(m => m.ProtoClass?.typeName.endsWith("PreloadedUserSettings")); | ||||||
| const MessageActions = findByPropsLazy("editMessage", "sendMessage"); | const MessageActions = findByPropsLazy("editMessage", "sendMessage"); | ||||||
| 
 | 
 | ||||||
|  | @ -77,3 +79,23 @@ export function sendMessage( | ||||||
| 
 | 
 | ||||||
|     return MessageActions.sendMessage(channelId, messageData, waitForChannelReady, extra); |     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/>.
 |  * 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 type { ComponentType, PropsWithChildren, ReactNode, Ref } from "react"; | ||||||
| 
 | 
 | ||||||
| import { LazyComponent } 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 ModalRoot = LazyComponent(() => Modals.ModalRoot); | ||||||
| export const ModalHeader = LazyComponent(() => Modals.ModalHeader); | export const ModalHeader = LazyComponent(() => Modals.ModalHeader); | ||||||
| export const ModalContent = LazyComponent(() => Modals.ModalContent); | 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
 | // eslint-disable-next-line path-alias/no-relative
 | ||||||
| import { filters, findByPropsLazy, waitFor } from "@webpack"; | import { filters, waitFor } from "@webpack"; | ||||||
| 
 | 
 | ||||||
| import { waitForComponent } from "./internal"; | import { waitForComponent } from "./internal"; | ||||||
| import * as t from "./types/components"; | 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 */ | /** css colour resolver stuff, no clue what exactly this does, just copied usage from Discord */ | ||||||
| export let useToken: t.useToken; | 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 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 Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]); | ||||||
| 
 | 
 | ||||||
| export const ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent") as Record<string, string>; |  | ||||||
| 
 |  | ||||||
| waitFor("FormItem", m => { | waitFor("FormItem", m => { | ||||||
|     ({ useToken, Card, Button, FormSwitch: Switch, Tooltip, TextInput, TextArea, Text, Select, SearchableSelect, Slider, ButtonLooks, TabBar, Popout, Dialog, Paginator, ScrollerThin, Clickable, Avatar } = m); |     ({ useToken, Card, Button, FormSwitch: Switch, Tooltip, TextInput, TextArea, Text, Select, SearchableSelect, Slider, ButtonLooks, TabBar, Popout, Dialog, Paginator, ScrollerThin, Clickable, Avatar } = m); | ||||||
|     Forms = m; |     Forms = m; | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 |  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
|  | export * from "./classes"; | ||||||
| export * from "./components"; | export * from "./components"; | ||||||
| export * from "./menu"; | export * from "./menu"; | ||||||
| export * from "./react"; | export * from "./react"; | ||||||
|  | @ -24,4 +25,3 @@ export * as ComponentTypes from "./types/components.d"; | ||||||
| export * as MenuTypes from "./types/menu.d"; | export * as MenuTypes from "./types/menu.d"; | ||||||
| export * as UtilTypes from "./types/utils.d"; | export * as UtilTypes from "./types/utils.d"; | ||||||
| export * from "./utils"; | 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; |     hideMaxPage?: boolean; | ||||||
| }>; | }>; | ||||||
| 
 | 
 | ||||||
|  | export type MaskedLink = ComponentType<{ | ||||||
|  |     onClick(): void; | ||||||
|  |     trusted: boolean; | ||||||
|  |     title: string, | ||||||
|  |     href: string; | ||||||
|  | }>; | ||||||
|  | 
 | ||||||
| export type ScrollerThin = ComponentType<PropsWithChildren<{ | export type ScrollerThin = ComponentType<PropsWithChildren<{ | ||||||
|     className?: string; |     className?: string; | ||||||
|     style?: CSSProperties; |     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; |         onChildrenScroll?: Function; | ||||||
|         childRowHeight?: number; |         childRowHeight?: number; | ||||||
|         listClassName?: string; |         listClassName?: string; | ||||||
|  |         disabled?: boolean; | ||||||
|     }>; |     }>; | ||||||
|     MenuCheckboxItem: RC<{ |     MenuCheckboxItem: RC<{ | ||||||
|         id: string; |         id: string; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue