* feat(plugin): add gifMaker v2 * fix(gifMaker): address code review * fix(gifMaker): remove unused fps useEffect * fix(gifMaker): address code review p2 * fix(gifMaker): address code review - error boundary, blob release, fix imports and style * perf(gifMaker): use worker to offload gif creation task, import gifenc as esm module * [autofix.ci] apply automated fixes * fix(gifMaker): lint errors * fix(gifMaker): detect existing color palette * worker worker worker worker worker * api and some fixes * fix thororen fix * fix --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com>
68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
/*
|
|
* Vencord, a Discord client mod
|
|
* Copyright (c) 2025 Vendicated and contributors
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
import { Logger } from "@utils/Logger";
|
|
import { ContextMenuApi, FluxDispatcher, Menu, React } from "@webpack/common";
|
|
import type { ReactNode } from "react";
|
|
|
|
const logger = new Logger("GifPickerContextMenu");
|
|
|
|
export type GifPickerContextMenuItemFactory = (instance: any, e: React.MouseEvent) => ReactNode | void;
|
|
|
|
interface HandlerEntry {
|
|
render: GifPickerContextMenuItemFactory;
|
|
priority: number;
|
|
}
|
|
|
|
const handlers = new Map<string, HandlerEntry>();
|
|
|
|
/**
|
|
* Register a context menu item factory for GIF picker items.
|
|
* @param id Unique ID, typically the plugin name.
|
|
* @param render Function that receives the GIF item and returns ReactNode(s) to inject.
|
|
* @param priority Lower numbers appear first. Defaults to 0.
|
|
*/
|
|
export function addGifPickerContextMenuPatch(id: string, render: GifPickerContextMenuItemFactory, priority = 0) {
|
|
handlers.set(id, { render, priority });
|
|
}
|
|
|
|
/**
|
|
* Remove a previously registered context menu item factory.
|
|
* @param id Unique ID used when registering.
|
|
*/
|
|
export function removeGifPickerContextMenuPatch(id: string) {
|
|
handlers.delete(id);
|
|
}
|
|
|
|
/** @internal Called by ExtraContextMenusAPI to render the merged context menu. */
|
|
export function _openGifPickerContextMenu(e: React.MouseEvent, instance) {
|
|
if (!handlers.size) return;
|
|
|
|
const items: React.ReactNode[] = [];
|
|
for (const [id, { render }] of Array.from(handlers).sort(([, a], [, b]) => a.priority - b.priority)) {
|
|
try {
|
|
const node = render(instance, e);
|
|
if (node) items.push(node);
|
|
} catch (err) {
|
|
logger.error(`Failed to render context menu for ${id}`, err);
|
|
}
|
|
}
|
|
|
|
if (!items.length) return;
|
|
ContextMenuApi.openContextMenu(e, () => <GifPickerContextMenuRoot items={items} />);
|
|
}
|
|
|
|
function GifPickerContextMenuRoot({ items }: { items: React.ReactNode[]; }) {
|
|
return (
|
|
<Menu.Menu
|
|
navId="gif-picker-context"
|
|
onClose={() => FluxDispatcher.dispatch({ type: "CONTEXT_MENU_CLOSE" })}
|
|
aria-label="GIF Options"
|
|
>
|
|
{items}
|
|
</Menu.Menu>
|
|
);
|
|
}
|