diff --git a/src/equicordplugins/favouriteAnything/components.tsx b/src/equicordplugins/favouriteAnything/components.tsx index 0f6db374f..64b2ed030 100644 --- a/src/equicordplugins/favouriteAnything/components.tsx +++ b/src/equicordplugins/favouriteAnything/components.tsx @@ -279,7 +279,8 @@ export function AttachmentAccessory() { const props: FavoriteButtonProps | null = useMemo(() => { if (!attachment?.downloadUrl) return null; - const { originalItem, type, downloadUrl, width = 600, height = 400, srcIsAnimated } = attachment; + const { originalItem, type, downloadUrl, srcIsAnimated } = attachment; + const width = attachment.width || 600, height = attachment.height || 400; // Do not render the custom accessory if the original attachment component already has a gif accessory const isAnimated = ImageUtils.isAnimated({ diff --git a/src/equicordplugins/favouriteAnything/index.tsx b/src/equicordplugins/favouriteAnything/index.tsx index 9aaa3c214..1bbe94482 100644 --- a/src/equicordplugins/favouriteAnything/index.tsx +++ b/src/equicordplugins/favouriteAnything/index.tsx @@ -7,7 +7,7 @@ import { Devs, EquicordDevs } from "@utils/constants"; import { getIntlMessage } from "@utils/discord"; import definePlugin from "@utils/types"; -import { Embed } from "@vencord/discord-types"; +import { Embed, MessageAttachment } from "@vencord/discord-types"; import { proxyLazyWebpack } from "@webpack"; import { React } from "@webpack/common"; import { ComponentType, ReactNode } from "react"; @@ -15,8 +15,8 @@ import { ComponentType, ReactNode } from "react"; import { AttachmentAccessory, EmbedAccessory, FilePicker } from "./components"; import { SignedUrlsStore } from "./stores"; import managedStyle from "./style.css?managed"; -import { AttachmentItem, EmbedComponent, ExpressionPickerTabProps, ExpressionPickerView, FavouriteItem, FavouriteItemFormat } from "./types"; -import { getThumbnailUrl } from "./utils"; +import { AttachmentItem, CV2Attachment, EmbedComponent, ExpressionPickerTabProps, ExpressionPickerView, FavouriteItem, FavouriteItemFormat } from "./types"; +import { getThumbnailUrl, transformAttachment } from "./utils"; export const EmbedContext = proxyLazyWebpack(() => React.createContext(null)); export const EmbedMosaicContext = proxyLazyWebpack(() => React.createContext(null)); @@ -70,6 +70,14 @@ export default definePlugin({ } ] }, + // COMPONENTS V2 + { + find: "#{intl::ATTACHMENT_FILENAME_UNKNOWN}", + replacement: { + match: /(?<=case \i\.\i\.FILE:)return(\(0,\i\.jsx\)\(\i,\{\.\.\.(\i)\},(\i)\))/, + replace: "return $self.renderCV2File($1,$3,$2)" + } + }, // EXPRESSION PICKER { find: "#{intl::EXPRESSION_PICKER_CATEGORIES_A11Y_LABEL}", @@ -133,8 +141,30 @@ export default definePlugin({ renderFilePicker(activeView: ExpressionPickerView, onSelectGIF: (item: { url: string; }) => void) { return activeView === ExpressionPickerView.FILES ? : null; }, - renderAttachment(children: ReactNode, props: { item: AttachmentItem; }) { - return {children}; + renderAttachment(children: ReactNode, props: { item: AttachmentItem; }) { + const { item: { originalItem, ...rest } } = props; + + // Regular media attachments and cv2 media attachments are structured differently + const raw: MessageAttachment = + "media" in originalItem + ? { + ...originalItem.media, + id: rest.uniqueId, + size: 0, + spoiler: rest.spoiler, + filename: (rest.spoiler ? "SPOILER_" : "") + rest.uniqueId, + content_type: originalItem.media.contentType, + proxy_url: originalItem.media.proxyUrl, + } + : originalItem; + + return {children}; + }, + renderCV2File(children: ReactNode, key: React.Key, props: { id: string; size: number; name: string; spoiler: boolean; file: CV2Attachment; }) { + const { id, size, name, spoiler, file } = props; + const raw = { ...file, size, filename: name, id, spoiler, content_type: file.contentType, proxy_url: file.proxyUrl }; + + return {children}; }, renderEmbed(this: EmbedComponent) { return {this.__render()}; diff --git a/src/equicordplugins/favouriteAnything/types.ts b/src/equicordplugins/favouriteAnything/types.ts index 583ac409c..505af2051 100644 --- a/src/equicordplugins/favouriteAnything/types.ts +++ b/src/equicordplugins/favouriteAnything/types.ts @@ -76,7 +76,7 @@ export interface EmbedComponent extends Component<{ embed: Embed; }> { __render: () => ReactNode; } -export interface AttachmentItem { +export interface AttachmentItem { contentType: string; type: "IMAGE" | "VIDEO" | "CLIP" | "AUDIO" | "VISUAL_PLACEHOLDER" | "PLAINTEXT_PREVIEW" | "OTHER" | "INVALID"; width?: number; @@ -85,7 +85,17 @@ export interface AttachmentItem { spoiler: boolean; srcIsAnimated: boolean; uniqueId: string; - originalItem: MessageAttachment; + originalItem: TOriginal; +} + +export interface CV2Attachment { + url: string; + proxyUrl: string; + width: number; + height: number; + placeholder?: string; + contentType: string; + flags: number; } export enum FavouriteItemFormat { @@ -138,3 +148,5 @@ export type ResizeObserverHook = ( export interface ImageUtils { isAnimated(image: { src: string; original?: string; animated: boolean; srcIsAnimated?: boolean; }): boolean; } + +export type AttachmentTransformer = (attachment: MessageAttachment, inlineAttachmentMedia?: boolean) => AttachmentItem; diff --git a/src/equicordplugins/favouriteAnything/utils.ts b/src/equicordplugins/favouriteAnything/utils.ts index b03aa347c..cb471dfa1 100644 --- a/src/equicordplugins/favouriteAnything/utils.ts +++ b/src/equicordplugins/favouriteAnything/utils.ts @@ -18,7 +18,7 @@ import { Key } from "react"; import { JsonValue } from "type-fest"; import { base64ToUint8Array, uint8ArrayToBase64 } from "./polyfills"; -import { CustomItemDef, CustomItemFormat, FavouriteItem, FavouriteItemFormat, ImageUtils as ImageUtils_, ItemsDef, ResizeObserverHook, UnfurledEmbedsResponse } from "./types"; +import { AttachmentTransformer, CustomItemDef, CustomItemFormat, FavouriteItem, FavouriteItemFormat, ImageUtils as ImageUtils_, ItemsDef, ResizeObserverHook, UnfurledEmbedsResponse } from "./types"; const Native = VencordNative.pluginHelpers.FavouriteAnything as PluginNative; @@ -26,6 +26,7 @@ export const cl = classNameFactory("vc-favouriteAnything-"); export const useResizeObserver: ResizeObserverHook = findByCodeLazy("borderBoxSize", "blockSize", "inlineSize"); export const ImageUtils: ImageUtils_ = findByPropsLazy("isAnimated", "getFormatQuality"); +export const transformAttachment: AttachmentTransformer = findByCodeLazy("return{uniqueId", ".IS_ANIMATED"); const defineItem = (item: CustomItemDef) => item; function defineItems>(def: ItemsDef) {