FavouriteAnything: Message components V2 support (#1175)
* FavouriteAnything: Add support for file message components * FavouriteAnything: Further components v2 support * FavouriteAnything: Improve CV2 handling
This commit is contained in:
parent
4bb2a24977
commit
a75c31773e
4 changed files with 53 additions and 9 deletions
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -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 | Embed>(null));
|
||||
export const EmbedMosaicContext = proxyLazyWebpack(() => React.createContext<null | number>(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 ? <FilePicker onSelectItem={onSelectGIF} /> : null;
|
||||
},
|
||||
renderAttachment(children: ReactNode, props: { item: AttachmentItem; }) {
|
||||
return <AttachmentContext.Provider value={props.item}>{children}</AttachmentContext.Provider>;
|
||||
renderAttachment(children: ReactNode, props: { item: AttachmentItem<MessageAttachment | { media: CV2Attachment; }>; }) {
|
||||
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 <AttachmentContext.Provider value={{ originalItem: raw, ...rest }}>{children}</AttachmentContext.Provider>;
|
||||
},
|
||||
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 <AttachmentContext.Provider value={transformAttachment(raw)} key={key}>{children}</AttachmentContext.Provider>;
|
||||
},
|
||||
renderEmbed(this: EmbedComponent) {
|
||||
return <EmbedContext.Provider value={this.props.embed}>{this.__render()}</EmbedContext.Provider>;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export interface EmbedComponent extends Component<{ embed: Embed; }> {
|
|||
__render: () => ReactNode;
|
||||
}
|
||||
|
||||
export interface AttachmentItem {
|
||||
export interface AttachmentItem<TOriginal = MessageAttachment> {
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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<typeof import("./native")>;
|
||||
|
||||
|
|
@ -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 = <const A, const B extends JsonValue>(item: CustomItemDef<A, B>) => item;
|
||||
function defineItems<T extends Record<CustomItemFormat, CustomItemDef>>(def: ItemsDef<T>) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue