/* * Vencord, a Discord client mod * Copyright (c) 2026 Vendicated and contributors * SPDX-License-Identifier: GPL-3.0-or-later */ import { Heading } from "@components/Heading"; import type { IPluginOptionComponentProps } from "@utils/types"; import { findComponentByCodeLazy } from "@webpack"; import { TextInput, useState } from "@webpack/common"; import { settings } from "."; import "./styles.css"; type EmojiData = { id?: string | null; name: string; }; type EmojiSelectPayload = { id: string | null; name: string; animated?: boolean; }; const StatusEmojiPicker = findComponentByCodeLazy("setCustomStatusEmoji", "setIsEmojiPickerOpen", "selectedDefaultStatus"); export const MAX_ADDITIONAL_REACT_EMOJIS = 8; function getEmojiValue(emoji: EmojiData) { return emoji.id ? `${emoji.name}:${emoji.id}` : emoji.name; } function parseEmojiValue(value: string): EmojiSelectPayload | null { const trimmed = value.trim(); if (!trimmed) return null; const customEmoji = trimmed.match(/^:?([\w-]+):(\d+)$/); if (customEmoji) { return { id: customEmoji[2], name: customEmoji[1], animated: false }; } return { id: null, name: trimmed, animated: false }; } function parseEmojiList(value: string) { return Array.from(new Set( value .split(/[\n,]/g) .map(entry => entry.trim()) .filter(Boolean) )).slice(0, MAX_ADDITIONAL_REACT_EMOJIS); } export function ReactEmojiSetting({ setValue }: IPluginOptionComponentProps) { const [emoji, setEmoji] = useState(settings.store.reactEmoji ?? "💀"); const [isEmojiPickerOpen, setIsEmojiPickerOpen] = useState(false); return (
Select Emoji For Reactions
event.stopPropagation()} onMouseDown={event => event.stopPropagation()} > { if (!selectedEmoji) { setEmoji(""); setValue(""); setIsEmojiPickerOpen(false); return; } const value = getEmojiValue(selectedEmoji); setEmoji(value); setValue(value); setIsEmojiPickerOpen(false); }} selectedDefaultStatus={isEmojiPickerOpen ? null : "online"} setIsEmojiPickerOpen={setIsEmojiPickerOpen} defaultStatusVariant="small" />
); } export function AdditionalReactEmojisSetting({ setValue }: IPluginOptionComponentProps) { const { addAdditionalReacts } = settings.use(["addAdditionalReacts"]); const [emojiList, setEmojiList] = useState(settings.store.additionalReactEmojis ?? ""); const [isEmojiPickerOpen, setIsEmojiPickerOpen] = useState(false); const [pickerEmoji, setPickerEmoji] = useState(parseEmojiValue("😀")); if (!addAdditionalReacts) return null; return (
Select Additional Emojis
{ setEmojiList(newValue); setValue(newValue); const [first] = parseEmojiList(newValue); setPickerEmoji(parseEmojiValue(first ?? "😀")); }} onClick={event => event.stopPropagation()} onMouseDown={event => event.stopPropagation()} style={{ flex: 1 }} />
event.stopPropagation()} onMouseDown={event => event.stopPropagation()} style={{ display: "inline-flex", transform: "scale(1.2)", transformOrigin: "center" }} > { if (!selectedEmoji) { setIsEmojiPickerOpen(false); return; } const value = getEmojiValue(selectedEmoji); const parsed = parseEmojiList(emojiList); const merged = parsed.includes(value) ? parsed : [...parsed, value].slice(0, MAX_ADDITIONAL_REACT_EMOJIS); const nextValue = merged.join(", "); setEmojiList(nextValue); setValue(nextValue); setPickerEmoji(selectedEmoji); setIsEmojiPickerOpen(false); }} selectedDefaultStatus={isEmojiPickerOpen ? null : "online"} setIsEmojiPickerOpen={setIsEmojiPickerOpen} defaultStatusVariant="small" />
); }