feat(HeaderBarAPI): Add API to register header bar buttons (#530)
* feat(HeaderBarAPI): Add API to register header bar buttons * bleh * t * t * a * t --------- Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com>
This commit is contained in:
parent
4850a6401f
commit
0c0498e531
30 changed files with 204 additions and 400 deletions
62
src/api/HeaderBar.tsx
Normal file
62
src/api/HeaderBar.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { useEffect, useState } from "@webpack/common";
|
||||
import type { JSX } from "react";
|
||||
|
||||
export type HeaderBarButtonFactory = () => JSX.Element | null;
|
||||
|
||||
interface HeaderBarButton {
|
||||
render: HeaderBarButtonFactory;
|
||||
priority: number;
|
||||
}
|
||||
|
||||
export const buttons = new Map<string, HeaderBarButton>();
|
||||
|
||||
const listeners = new Set<() => void>();
|
||||
|
||||
/**
|
||||
* Add a button to the header bar.
|
||||
* @param id Unique identifier for the button.
|
||||
* @param render Function that renders the button component.
|
||||
* @param priority Higher priority = more to the right. Default is 0.
|
||||
*/
|
||||
export function addHeaderBarButton(id: string, render: HeaderBarButtonFactory, priority = 0) {
|
||||
buttons.set(id, { render, priority });
|
||||
listeners.forEach(l => l());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a button from the header bar.
|
||||
* @param id The identifier of the button to remove.
|
||||
*/
|
||||
export function removeHeaderBarButton(id: string) {
|
||||
buttons.delete(id);
|
||||
listeners.forEach(l => l());
|
||||
}
|
||||
|
||||
function HeaderBarButtons() {
|
||||
const [, forceUpdate] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = () => forceUpdate(n => n + 1);
|
||||
listeners.add(listener);
|
||||
return () => { listeners.delete(listener); };
|
||||
}, []);
|
||||
|
||||
const sorted = Array.from(buttons).sort(([, a], [, b]) => a.priority - b.priority);
|
||||
|
||||
return sorted.map(([id, { render: Button }]) => (
|
||||
<ErrorBoundary noop key={id}>
|
||||
<Button />
|
||||
</ErrorBoundary>
|
||||
));
|
||||
}
|
||||
|
||||
export function _addButtons() {
|
||||
return [<HeaderBarButtons key="vc-header-bar-buttons" />];
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ export { Plugins as plugins };
|
|||
|
||||
import { traceFunction } from "../debug/Tracer";
|
||||
import { addAudioProcessor, removeAudioProcessor } from "./AudioPlayer";
|
||||
import { addHeaderBarButton, removeHeaderBarButton } from "./HeaderBar";
|
||||
|
||||
const logger = new Logger("PluginManager", "#a6d189");
|
||||
|
||||
|
|
@ -190,7 +191,7 @@ export const startPlugin = traceFunction("startPlugin", function startPlugin(p:
|
|||
onBeforeMessageEdit, onBeforeMessageSend, onMessageClick,
|
||||
renderChatBarButton, chatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton, messagePopoverButton,
|
||||
// Custom
|
||||
renderNicknameIcon, audioProcessor
|
||||
renderNicknameIcon, renderHeaderBarButton, onAudioProcessor
|
||||
} = p;
|
||||
|
||||
if (p.start) {
|
||||
|
|
@ -252,7 +253,8 @@ export const startPlugin = traceFunction("startPlugin", function startPlugin(p:
|
|||
|
||||
// Custom
|
||||
if (renderNicknameIcon) addNicknameIcon(name, renderNicknameIcon);
|
||||
if (audioProcessor) addAudioProcessor(name, audioProcessor);
|
||||
if (renderHeaderBarButton) addHeaderBarButton(name, renderHeaderBarButton);
|
||||
if (onAudioProcessor) addAudioProcessor(name, onAudioProcessor);
|
||||
|
||||
return true;
|
||||
}, p => `startPlugin ${p.name}`);
|
||||
|
|
@ -263,7 +265,7 @@ export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plu
|
|||
onBeforeMessageEdit, onBeforeMessageSend, onMessageClick,
|
||||
renderChatBarButton, chatBarButton, renderMemberListDecorator, renderMessageAccessory, renderMessageDecoration, renderMessagePopoverButton, messagePopoverButton,
|
||||
// Custom
|
||||
renderNicknameIcon, audioProcessor
|
||||
renderNicknameIcon, renderHeaderBarButton, onAudioProcessor
|
||||
} = p;
|
||||
|
||||
if (p.stop) {
|
||||
|
|
@ -319,7 +321,8 @@ export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plu
|
|||
|
||||
// Custom
|
||||
if (renderNicknameIcon) removeNicknameIcon(name);
|
||||
if (audioProcessor) removeAudioProcessor(name);
|
||||
if (renderHeaderBarButton) removeHeaderBarButton(name);
|
||||
if (onAudioProcessor) removeAudioProcessor(name);
|
||||
|
||||
return true;
|
||||
}, p => `stopPlugin ${p.name}`);
|
||||
|
|
@ -330,7 +333,9 @@ export const initPluginManager = onlyOnce(function init() {
|
|||
|
||||
const pluginKeysToBind: Array<keyof PluginDef & `${"on" | "render"}${string}`> = [
|
||||
"onBeforeMessageEdit", "onBeforeMessageSend", "onMessageClick",
|
||||
"renderChatBarButton", "renderMemberListDecorator", "renderMessageAccessory", "renderMessageDecoration", "renderMessagePopoverButton", "renderNicknameIcon"
|
||||
"renderChatBarButton", "renderMemberListDecorator", "renderMessageAccessory", "renderMessageDecoration", "renderMessagePopoverButton",
|
||||
// Custom
|
||||
"renderNicknameIcon", "renderHeaderBarButton", "onAudioProcessor"
|
||||
];
|
||||
|
||||
const neededApiPlugins = new Set<string>();
|
||||
|
|
@ -369,7 +374,8 @@ export const initPluginManager = onlyOnce(function init() {
|
|||
|
||||
// Custom
|
||||
if (p.renderNicknameIcon) neededApiPlugins.add("NicknameIconsAPI");
|
||||
if (p.audioProcessor) neededApiPlugins.add("AudioPlayerAPI");
|
||||
if (p.renderHeaderBarButton) neededApiPlugins.add("HeaderBarAPI");
|
||||
if (p.onAudioProcessor) neededApiPlugins.add("AudioPlayerAPI");
|
||||
|
||||
for (const key of pluginKeysToBind) {
|
||||
p[key] &&= p[key].bind(p) as any;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import * as $ChatButtons from "./ChatButtons";
|
|||
import * as $Commands from "./Commands";
|
||||
import * as $ContextMenu from "./ContextMenu";
|
||||
import * as $DataStore from "./DataStore";
|
||||
import * as $HeaderBar from "./HeaderBar";
|
||||
import * as $MemberListDecorators from "./MemberListDecorators";
|
||||
import * as $MessageAccessories from "./MessageAccessories";
|
||||
import * as $MessageDecorations from "./MessageDecorations";
|
||||
|
|
@ -129,6 +130,11 @@ export const ContextMenu = $ContextMenu;
|
|||
*/
|
||||
export const ChatButtons = $ChatButtons;
|
||||
|
||||
/**
|
||||
* An API allowing you to add buttons to the header bar.
|
||||
*/
|
||||
export const HeaderBar = $HeaderBar;
|
||||
|
||||
/**
|
||||
* An API allowing you to update and re-render messages.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ export default definePlugin({
|
|||
name: "DecodeBase64",
|
||||
description: "Decode base64 content of any message and copy the decoded content.",
|
||||
authors: [EquicordDevs.ThePirateStoner],
|
||||
dependencies: ["MessagePopoverAPI"],
|
||||
settings,
|
||||
messagePopoverButton: {
|
||||
icon: DecodeIcon,
|
||||
|
|
|
|||
|
|
@ -394,12 +394,9 @@ export default definePlugin({
|
|||
name: "CustomSounds",
|
||||
description: "Customize Discord's sounds.",
|
||||
authors: [Devs.ScattrdBlade, Devs.TheKodeToad],
|
||||
dependencies: ["AudioPlayerAPI"],
|
||||
|
||||
settings,
|
||||
getCustomSoundURL,
|
||||
startAt: StartAt.Init,
|
||||
audioProcessor: getCustomSoundURL,
|
||||
onAudioProcessor: getCustomSoundURL,
|
||||
|
||||
async start() {
|
||||
console.log("[CustomSounds] Plugin starting...");
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { addMessagePreSendListener, removeMessagePreSendListener } from "@api/MessageEvents";
|
||||
import { Paragraph } from "@components/Paragraph";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
|
|
@ -35,36 +34,27 @@ function warningEmbedNotice(trigger) {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
const handleMessage = async (channelId, messageObj) => {
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
if (channel.isDM()) return { cancel: false };
|
||||
if (PermissionStore.can(PermissionsBits.ADMINISTRATOR, channel) || PermissionStore.can(PermissionsBits.MANAGE_GUILD, channel)) return { cancel: false };
|
||||
|
||||
const escapedStrings = filterList.map(escapeRegex);
|
||||
const regexString = escapedStrings.join("|");
|
||||
const regex = new RegExp(`(${regexString})`, "i");
|
||||
|
||||
const matches = regex.exec(messageObj.content);
|
||||
console.log(matches);
|
||||
if (matches) {
|
||||
if (!await warningEmbedNotice(matches[0])) {
|
||||
return { cancel: true };
|
||||
}
|
||||
}
|
||||
|
||||
return { cancel: false };
|
||||
};
|
||||
|
||||
export default definePlugin({
|
||||
name: "DontFilterMe",
|
||||
description: "Warns you if your message contains a term in the automod preset list",
|
||||
authors: [Devs.Samwich],
|
||||
dependencies: ["MessageEventsAPI"],
|
||||
start() {
|
||||
addMessagePreSendListener(handleMessage);
|
||||
},
|
||||
stop() {
|
||||
removeMessagePreSendListener(handleMessage);
|
||||
async onBeforeMessageSend(channelId, messageObj) {
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
if (channel.isDM()) return { cancel: false };
|
||||
if (PermissionStore.can(PermissionsBits.ADMINISTRATOR, channel) || PermissionStore.can(PermissionsBits.MANAGE_GUILD, channel)) return { cancel: false };
|
||||
|
||||
const escapedStrings = filterList.map(escapeRegex);
|
||||
const regexString = escapedStrings.join("|");
|
||||
const regex = new RegExp(`(${regexString})`, "i");
|
||||
|
||||
const matches = regex.exec(messageObj.content);
|
||||
console.log(matches);
|
||||
if (matches) {
|
||||
if (!await warningEmbedNotice(matches[0])) {
|
||||
return { cancel: true };
|
||||
}
|
||||
}
|
||||
|
||||
return { cancel: false };
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,13 +18,12 @@
|
|||
|
||||
import "./styles.css";
|
||||
|
||||
import { addHeaderBarButton, removeHeaderBarButton } from "@api/HeaderBar";
|
||||
import { definePluginSettings, migratePluginSettings } from "@api/Settings";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findComponentByCodeLazy } from "@webpack";
|
||||
import { Popout, useRef, useState } from "@webpack/common";
|
||||
import type { PropsWithChildren } from "react";
|
||||
|
||||
import { renderPopout } from "./menu";
|
||||
|
||||
|
|
@ -48,7 +47,7 @@ function Icon() {
|
|||
);
|
||||
}
|
||||
|
||||
function VencordPopoutButton({ buttonClass }: { buttonClass: string; }) {
|
||||
function VencordPopoutButton() {
|
||||
const buttonRef = useRef(null);
|
||||
const [show, setShow] = useState(false);
|
||||
|
||||
|
|
@ -66,10 +65,10 @@ function VencordPopoutButton({ buttonClass }: { buttonClass: string; }) {
|
|||
{(_, { isShown }) => (
|
||||
<HeaderBarIcon
|
||||
ref={buttonRef}
|
||||
className={`vc-toolbox-btn ${buttonClass}`}
|
||||
className="vc-toolbox-btn"
|
||||
onClick={() => setShow(v => !v)}
|
||||
tooltip={isShown ? null : "Equicord Toolbox"}
|
||||
icon={() => <Icon />}
|
||||
icon={Icon}
|
||||
selected={isShown}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -82,27 +81,15 @@ export default definePlugin({
|
|||
name: "EquicordToolbox",
|
||||
description: "Adds a button next to the inbox button in the channel header that houses Equicord quick actions",
|
||||
authors: [Devs.Ven, Devs.AutumnVN],
|
||||
dependencies: ["HeaderBarAPI"],
|
||||
|
||||
settings,
|
||||
|
||||
patches: [
|
||||
{
|
||||
find: '?"BACK_FORWARD_NAVIGATION":',
|
||||
replacement: {
|
||||
match: /(?<=trailing:.{0,50})\i\.Fragment,\{(?=.+?className:(\i))/,
|
||||
replace: "$self.TrailingWrapper,{className:$1,"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
TrailingWrapper({ children, className }: PropsWithChildren<{ className: string; }>) {
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
<ErrorBoundary noop>
|
||||
<VencordPopoutButton buttonClass={className} />
|
||||
</ErrorBoundary>
|
||||
</>
|
||||
);
|
||||
start() {
|
||||
addHeaderBarButton("EquicordToolbox", VencordPopoutButton, 1000);
|
||||
},
|
||||
|
||||
stop() {
|
||||
removeHeaderBarButton("EquicordToolbox");
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { removeMessagePopoverButton } from "@api/MessagePopover";
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { disableStyle, enableStyle } from "@api/Styles";
|
||||
import { Devs } from "@utils/constants";
|
||||
|
|
@ -154,7 +153,6 @@ export default definePlugin({
|
|||
enableStyle(styles);
|
||||
},
|
||||
stop() {
|
||||
removeMessagePopoverButton("vc-findreply");
|
||||
root && root.unmount();
|
||||
element?.remove();
|
||||
disableStyle(styles);
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ import "./style.css";
|
|||
|
||||
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||
import { DataStore } from "@api/index";
|
||||
import { removeMessagePopoverButton } from "@api/MessagePopover";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { EquicordDevs } from "@utils/constants";
|
||||
import { classes } from "@utils/misc";
|
||||
import { openModal } from "@utils/modal";
|
||||
|
|
@ -58,15 +56,13 @@ function ToolBarHeader() {
|
|||
const iconClasses = findByProps("iconWrapper", "clickable");
|
||||
|
||||
return (
|
||||
<ErrorBoundary noop={true}>
|
||||
<HeaderBarIcon
|
||||
tooltip="Holy Notes"
|
||||
position="bottom"
|
||||
className={classes("vc-note-button", iconClasses.iconWrapper, iconClasses.clickable)}
|
||||
icon={e => Popover(e)}
|
||||
onClick={() => openModal(props => <NoteModal {...props} />)}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
<HeaderBarIcon
|
||||
tooltip="Holy Notes"
|
||||
position="bottom"
|
||||
className={classes("vc-note-button", iconClasses.iconWrapper, iconClasses.clickable)}
|
||||
icon={Popover}
|
||||
onClick={() => openModal(props => <NoteModal {...props} />)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -75,17 +71,6 @@ export default definePlugin({
|
|||
name: "HolyNotes",
|
||||
description: "Holy Notes allows you to save messages",
|
||||
authors: [EquicordDevs.Wolfie],
|
||||
dependencies: ["MessagePopoverAPI", "ChatInputButtonAPI"],
|
||||
|
||||
patches: [
|
||||
{
|
||||
find: ".controlButtonWrapper,",
|
||||
replacement: {
|
||||
match: /(function \i\(\i\){)(.{1,200}toolbar.{1,100}mobileToolbar)/,
|
||||
replace: "$1$self.toolbarAction(arguments[0]);$2"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
toolboxActions: {
|
||||
async "Open Notes"() {
|
||||
|
|
@ -97,21 +82,8 @@ export default definePlugin({
|
|||
"message": messageContextMenuPatch
|
||||
},
|
||||
|
||||
toolbarAction(e) {
|
||||
if (Array.isArray(e.toolbar))
|
||||
return e.toolbar.unshift(
|
||||
<ErrorBoundary noop={true}>
|
||||
<ToolBarHeader />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
renderHeaderBarButton: ToolBarHeader,
|
||||
|
||||
e.toolbar = [
|
||||
<ErrorBoundary noop={true} key={"HolyNotes"}>
|
||||
<ToolBarHeader />
|
||||
</ErrorBoundary>,
|
||||
e.toolbar,
|
||||
];
|
||||
},
|
||||
messagePopoverButton: {
|
||||
icon: NoteButtonPopover,
|
||||
render(message) {
|
||||
|
|
@ -129,8 +101,4 @@ export default definePlugin({
|
|||
if (await DataStore.keys(HolyNoteStore).then(keys => !keys.includes("Main"))) return noteHandler.newNoteBook("Main");
|
||||
if (!noteHandlerCache.has("Main")) await DataStoreToCache();
|
||||
},
|
||||
|
||||
async stop() {
|
||||
removeMessagePopoverButton("HolyNotes");
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ export default definePlugin({
|
|||
name: "Husk",
|
||||
description: "Adds Husk button (check settings to change used emoji)",
|
||||
authors: [Devs.nin0dev],
|
||||
dependencies: ["MessagePopoverAPI"],
|
||||
settings,
|
||||
messagePopoverButton: {
|
||||
icon: Husk,
|
||||
|
|
|
|||
|
|
@ -21,28 +21,7 @@ import { findComponentByCodeLazy } from "@webpack";
|
|||
import { openLogModal } from "./LogsModal";
|
||||
|
||||
const HeaderBarIcon = findComponentByCodeLazy(".HEADER_BAR_BADGE_TOP:", '.iconBadge,"top"');
|
||||
|
||||
export function OpenLogsIcon() {
|
||||
return (
|
||||
<svg
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
strokeWidth="0"
|
||||
viewBox="0 0 15 15"
|
||||
height={24}
|
||||
width={24}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
fill="currentColor"
|
||||
d="M3 2.5C3 2.22386 3.22386 2 3.5 2H9.08579C9.21839 2 9.34557 2.05268 9.43934 2.14645L11.8536 4.56066C11.9473 4.65443 12 4.78161 12 4.91421V12.5C12 12.7761 11.7761 13 11.5 13H3.5C3.22386 13 3 12.7761 3 12.5V2.5ZM3.5 1C2.67157 1 2 1.67157 2 2.5V12.5C2 13.3284 2.67157 14 3.5 14H11.5C12.3284 14 13 13.3284 13 12.5V4.91421C13 4.51639 12.842 4.13486 12.5607 3.85355L10.1464 1.43934C9.86514 1.15804 9.48361 1 9.08579 1H3.5ZM4.5 4C4.22386 4 4 4.22386 4 4.5C4 4.77614 4.22386 5 4.5 5H7.5C7.77614 5 8 4.77614 8 4.5C8 4.22386 7.77614 4 7.5 4H4.5ZM4.5 7C4.22386 7 4 7.22386 4 7.5C4 7.77614 4.22386 8 4.5 8H10.5C10.7761 8 11 7.77614 11 7.5C11 7.22386 10.7761 7 10.5 7H4.5ZM4.5 10C4.22386 10 4 10.2239 4 10.5C4 10.7761 4.22386 11 4.5 11H10.5C10.7761 11 11 10.7761 11 10.5C11 10.2239 10.7761 10 10.5 10H4.5Z"
|
||||
>
|
||||
</path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
const Icon = findComponentByCodeLazy("0-1.27-.97l-2.5.7a3");
|
||||
|
||||
export function OpenLogsButton() {
|
||||
return (
|
||||
|
|
@ -50,7 +29,7 @@ export function OpenLogsButton() {
|
|||
className="vc-log-toolbox-btn"
|
||||
onClick={() => openLogModal()}
|
||||
tooltip={"Open Logs"}
|
||||
icon={OpenLogsIcon}
|
||||
icon={Icon}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,11 @@ export const Native = getNative();
|
|||
|
||||
import "./styles.css";
|
||||
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import definePlugin from "@utils/types";
|
||||
import { findByPropsLazy } from "@webpack";
|
||||
import { FluxDispatcher, MessageStore, React, UserStore } from "@webpack/common";
|
||||
import { FluxDispatcher, MessageStore, UserStore } from "@webpack/common";
|
||||
|
||||
import { OpenLogsButton } from "./components/LogsButton";
|
||||
import { openLogModal } from "./components/LogsModal";
|
||||
|
|
@ -256,15 +255,6 @@ export default definePlugin({
|
|||
replace: "deleted:$self.getDeleted(...arguments), editHistory:$self.getEdited(...arguments),"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: ".controlButtonWrapper,",
|
||||
predicate: () => settings.store.ShowLogsButton,
|
||||
replacement: {
|
||||
match: /(function \i\(\i\){)(.{1,200}toolbar.{1,100}mobileToolbar)/,
|
||||
replace: "$1$self.addIconToToolBar(arguments[0]);$2"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
find: "childrenMessageContent:null",
|
||||
replacement: {
|
||||
|
|
@ -310,21 +300,9 @@ export default definePlugin({
|
|||
openLogModal();
|
||||
}
|
||||
},
|
||||
|
||||
addIconToToolBar(e: { toolbar: React.ReactNode[] | React.ReactNode; }) {
|
||||
if (Array.isArray(e.toolbar))
|
||||
return e.toolbar.unshift(
|
||||
<ErrorBoundary noop={true}>
|
||||
<OpenLogsButton />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
e.toolbar = [
|
||||
<ErrorBoundary noop={true} key={"MessageLoggerEnhanced"} >
|
||||
<OpenLogsButton />
|
||||
</ErrorBoundary>,
|
||||
e.toolbar,
|
||||
];
|
||||
renderHeaderBarButton() {
|
||||
if (!settings.store.ShowLogsButton) return null;
|
||||
return OpenLogsButton();
|
||||
},
|
||||
|
||||
processMessageFetch,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ export default definePlugin({
|
|||
name: "MoreUserTags",
|
||||
description: "Adds tags for webhooks and moderative roles (owner, admin, etc.)",
|
||||
authors: [Devs.Cyn, Devs.TheSun, Devs.RyanCaoDev, Devs.LordElias, Devs.AutumnVN, EquicordDevs.Hen],
|
||||
dependencies: ["MemberListDecoratorsAPI", "NicknameIconsAPI", "MessageDecorationsAPI"],
|
||||
settings,
|
||||
patches: [
|
||||
// Make discord actually use our tags
|
||||
|
|
|
|||
|
|
@ -4,23 +4,14 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { addMessagePreSendListener, removeMessagePreSendListener } from "@api/MessageEvents";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
export default definePlugin({
|
||||
name: "NoBulletPoints",
|
||||
description: "Stops you from typing markdown bullet points (stinky)",
|
||||
authors: [Devs.Samwich],
|
||||
dependencies: ["MessageEventsAPI"],
|
||||
start() {
|
||||
this.preSend = addMessagePreSendListener((channelId, msg) => {
|
||||
msg.content = textProcessing(msg.content);
|
||||
});
|
||||
},
|
||||
stop() {
|
||||
this.preSend = removeMessagePreSendListener((channelId, msg) => {
|
||||
msg.content = textProcessing(msg.content);
|
||||
});
|
||||
onBeforeMessageSend(channelId, msg) {
|
||||
msg.content = textProcessing(msg.content);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
addMessagePreSendListener,
|
||||
MessageSendListener,
|
||||
removeMessagePreSendListener,
|
||||
} from "@api/MessageEvents";
|
||||
import {
|
||||
definePluginSettings,
|
||||
|
|
@ -67,9 +65,7 @@ export default definePlugin({
|
|||
name: "PolishWording",
|
||||
description: "Tweaks your messages to make them look nicer and have better grammar. See settings",
|
||||
authors: [Devs.Samwich, EquicordDevs.WKoA],
|
||||
dependencies: ["MessageEventsAPI"],
|
||||
start: () => addMessagePreSendListener(presendObject),
|
||||
stop: () => removeMessagePreSendListener(presendObject),
|
||||
onBeforeMessageSend: presendObject,
|
||||
settings,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,11 @@ import "./style.css";
|
|||
|
||||
import { showNotification } from "@api/Notifications";
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { ErrorBoundary } from "@components/index";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { getTheme, Theme } from "@utils/discord";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
||||
import { Button, ChannelStore, FluxDispatcher, GuildChannelStore, NavigationRouter, RestAPI, Tooltip, UserStore } from "@webpack/common";
|
||||
import { ChannelStore, FluxDispatcher, GuildChannelStore, NavigationRouter, RestAPI, UserStore } from "@webpack/common";
|
||||
|
||||
const QuestIcon = findComponentByCodeLazy("10.47a.76.76");
|
||||
const HeaderBarIcon = findComponentByCodeLazy(".HEADER_BAR_BADGE_TOP:", '.iconBadge,"top"');
|
||||
|
|
@ -37,16 +36,13 @@ let questIdCheck = 0;
|
|||
|
||||
function ToolBarHeader() {
|
||||
return (
|
||||
<ErrorBoundary noop={true}>
|
||||
<HeaderBarIcon
|
||||
tooltip="Complete Quest"
|
||||
position="bottom"
|
||||
className="vc-quest-completer"
|
||||
icon={QuestIcon}
|
||||
onClick={openCompleteQuestUI}
|
||||
>
|
||||
</HeaderBarIcon>
|
||||
</ErrorBoundary>
|
||||
<HeaderBarIcon
|
||||
tooltip="Complete Quest"
|
||||
position="bottom"
|
||||
className="vc-quest-completer"
|
||||
icon={QuestIcon}
|
||||
onClick={openCompleteQuestUI}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -212,11 +208,6 @@ async function openCompleteQuestUI() {
|
|||
}
|
||||
|
||||
const settings = definePluginSettings({
|
||||
useNavBar: {
|
||||
description: "Move quest button down to the server nav bar",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: false,
|
||||
},
|
||||
disableNotifications: {
|
||||
description: "Disable notifications when no quests are available or when a quest is completed",
|
||||
type: OptionType.BOOLEAN,
|
||||
|
|
@ -237,22 +228,6 @@ export default definePlugin({
|
|||
replace: "onClick:()=>$self.mobileQuestPatch($1)"
|
||||
},
|
||||
},
|
||||
{
|
||||
find: '?"BACK_FORWARD_NAVIGATION":',
|
||||
replacement: {
|
||||
match: /"HELP".{0,100}className:\i\}\)(?=\])/,
|
||||
replace: "$&,$self.renderTitleBar()"
|
||||
},
|
||||
predicate: () => !settings.store.useNavBar
|
||||
},
|
||||
{
|
||||
find: ".controlButtonWrapper,",
|
||||
replacement: {
|
||||
match: /(function \i\(\i\){)(.{1,200}toolbar.{1,200}mobileToolbar)/,
|
||||
replace: "$1$self.renderNavBar(arguments[0]);$2"
|
||||
},
|
||||
predicate: () => settings.store.useNavBar
|
||||
}
|
||||
],
|
||||
mobileQuestPatch(questId) {
|
||||
if (questId === questIdCheck) return;
|
||||
|
|
@ -264,37 +239,5 @@ export default definePlugin({
|
|||
}
|
||||
});
|
||||
},
|
||||
renderTitleBar() {
|
||||
return (
|
||||
<ErrorBoundary noop>
|
||||
<Tooltip text="Complete Quest">
|
||||
{tooltipProps => (
|
||||
<Button style={{ backgroundColor: "transparent", border: "none" }}
|
||||
{...tooltipProps}
|
||||
size={Button.Sizes.SMALL}
|
||||
className={"vc-quest-completer-icon"}
|
||||
onClick={openCompleteQuestUI}
|
||||
>
|
||||
<QuestIcon width={20} height={20} />
|
||||
</Button>
|
||||
)}
|
||||
</Tooltip>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
},
|
||||
renderNavBar(e) {
|
||||
if (Array.isArray(e.toolbar))
|
||||
return e.toolbar.unshift(
|
||||
<ErrorBoundary noop={true}>
|
||||
<ToolBarHeader />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
e.toolbar = [
|
||||
<ErrorBoundary noop={true} key={"QuestCompleter"}>
|
||||
<ToolBarHeader />
|
||||
</ErrorBoundary>,
|
||||
e.toolbar,
|
||||
];
|
||||
}
|
||||
renderHeaderBarButton: ToolBarHeader
|
||||
});
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ export default definePlugin({
|
|||
name: "SekaiStickers",
|
||||
description: "Sekai Stickers built in discord originally from github.com/TheOriginalAyaka",
|
||||
authors: [Devs.MaiKokain],
|
||||
dependencies: ["ChatInputButtonAPI"],
|
||||
settings,
|
||||
chatBarButton: {
|
||||
icon: kanadeSvg,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { addMessageDecoration, removeMessageDecoration } from "@api/MessageDecorations";
|
||||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import { isEquicordPluginDev, isPluginDev } from "@utils/misc";
|
||||
import definePlugin from "@utils/types";
|
||||
|
|
@ -142,12 +141,8 @@ export default definePlugin({
|
|||
name: "ShowBadgesInChat",
|
||||
authors: [Devs.Inbestigator, EquicordDevs.KrystalSkull],
|
||||
description: "Shows the message author's badges beside their name in chat.",
|
||||
dependencies: ["MessageDecorationsAPI"],
|
||||
settings,
|
||||
start: () => {
|
||||
addMessageDecoration("vc-show-badges-in-chat", props => props.message?.author ? <ChatBadges author={props.message.author} /> : null);
|
||||
},
|
||||
stop: () => {
|
||||
removeMessageDecoration("vc-show-badges-in-chat");
|
||||
renderMessageDecoration(props) {
|
||||
return props.message?.author ? <ChatBadges author={props.message.author} /> : null;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
import { ChatBarButton, ChatBarButtonFactory } from "@api/ChatButtons";
|
||||
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
|
||||
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||
import { addMessagePreSendListener, removeMessagePreSendListener } from "@api/MessageEvents";
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
|
|
@ -78,14 +77,6 @@ function SignatureIcon() {
|
|||
);
|
||||
}
|
||||
|
||||
const handleMessage = ((channelId, msg) => {
|
||||
if (!settings.store.isEnabled) {
|
||||
msg.content = msg.content;
|
||||
} else {
|
||||
msg.content = textProcessing(msg.content);
|
||||
}
|
||||
});
|
||||
|
||||
const ChatBarContextCheckbox: NavContextMenuPatchCallback = children => {
|
||||
const { isEnabled, contextMenu } = settings.use(["isEnabled", "contextMenu"]);
|
||||
if (!contextMenu) return;
|
||||
|
|
@ -110,16 +101,18 @@ export default definePlugin({
|
|||
name: "Signature",
|
||||
description: "Automated fingerprint/end text",
|
||||
authors: [Devs.Ven, Devs.Rini, Devs.ImBanana, EquicordDevs.KrystalSkull],
|
||||
dependencies: ["MessageEventsAPI", "ChatInputButtonAPI"],
|
||||
|
||||
onBeforeMessageSend(channelId, msg) {
|
||||
if (!settings.store.isEnabled) {
|
||||
msg.content = msg.content;
|
||||
} else {
|
||||
msg.content = textProcessing(msg.content);
|
||||
}
|
||||
},
|
||||
start: () => {
|
||||
if (settings.store.isEnabled) true;
|
||||
addMessagePreSendListener(handleMessage);
|
||||
},
|
||||
stop: () => {
|
||||
if (settings.store.isEnabled) false;
|
||||
removeMessagePreSendListener(handleMessage);
|
||||
|
||||
},
|
||||
|
||||
chatBarButton: {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
import { AudioPlayerInterface, createAudioPlayer } from "@api/AudioPlayer";
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { EquicordDevs } from "@utils/constants";
|
||||
import { ModalProps, ModalRoot, openModal } from "@utils/modal";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
|
|
@ -143,15 +142,7 @@ export default definePlugin({
|
|||
authors: [EquicordDevs.sliwka],
|
||||
settings,
|
||||
dependencies: ["AudioPlayerAPI"],
|
||||
patches: [
|
||||
{
|
||||
find: ".controlButtonWrapper,",
|
||||
replacement: {
|
||||
match: /(function \i\(\i\){)(.{1,200}toolbar.{1,450}mobileToolbar)/,
|
||||
replace: "$1$self.addIconToToolBar(arguments[0]);$2"
|
||||
}
|
||||
}
|
||||
],
|
||||
renderHeaderBarButton: SoggyButton,
|
||||
|
||||
start() {
|
||||
assignBoop(settings.store.boopLink, settings.store.boopVolume * 100);
|
||||
|
|
@ -162,21 +153,4 @@ export default definePlugin({
|
|||
boopSound?.delete();
|
||||
song?.delete();
|
||||
},
|
||||
|
||||
// taken from message logger lol
|
||||
addIconToToolBar(e: { toolbar: React.ReactNode[] | React.ReactNode; }) {
|
||||
if (Array.isArray(e.toolbar))
|
||||
return e.toolbar.unshift(
|
||||
<ErrorBoundary noop={true}>
|
||||
<SoggyButton />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
e.toolbar = [
|
||||
<ErrorBoundary noop={true} key={"MessageLoggerEnhanced"} >
|
||||
<SoggyButton />
|
||||
</ErrorBoundary>,
|
||||
e.toolbar,
|
||||
];
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,14 +4,11 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { addChatBarButton, removeChatBarButton } from "@api/ChatButtons";
|
||||
import { disableStyle, enableStyle } from "@api/Styles";
|
||||
import ErrorBoundary from "@components/ErrorBoundary";
|
||||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { FluxDispatcher } from "@webpack/common";
|
||||
|
||||
import { CharBarButton, ChatBarIcon } from "./components/Icons";
|
||||
import { OpenSBLogsButton } from "./components/SoundBoardLog";
|
||||
import settings from "./settings";
|
||||
import { updateLoggedSounds } from "./store";
|
||||
|
|
@ -22,33 +19,9 @@ export default definePlugin({
|
|||
name: "SoundBoardLogger",
|
||||
authors: [Devs.Moxxie, EquicordDevs.Fres, Devs.amy, Devs.thororen],
|
||||
description: "Logs all soundboards that are played in a voice chat and allows you to download them",
|
||||
dependencies: ["AudioPlayerAPI", "ChatInputButtonAPI"],
|
||||
patches: [
|
||||
{
|
||||
predicate: () => settings.store.IconLocation === "toolbar",
|
||||
find: ".controlButtonWrapper,",
|
||||
replacement: {
|
||||
match: /(function \i\(\i\){)(.{1,500}toolbar.{1,500}mobileToolbar)/,
|
||||
replace: "$1$self.addSBIconToToolBar(arguments[0]);$2"
|
||||
}
|
||||
}
|
||||
],
|
||||
dependencies: ["AudioPlayerAPI"],
|
||||
settings,
|
||||
addSBIconToToolBar(e: { toolbar: React.ReactNode[] | React.ReactNode; }) {
|
||||
if (Array.isArray(e.toolbar))
|
||||
return e.toolbar.unshift(
|
||||
<ErrorBoundary noop={true}>
|
||||
<OpenSBLogsButton />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
e.toolbar = [
|
||||
<ErrorBoundary noop={true} key={"SoundBoardLogger"} >
|
||||
<OpenSBLogsButton />
|
||||
</ErrorBoundary>,
|
||||
e.toolbar,
|
||||
];
|
||||
},
|
||||
renderHeaderBarButton: OpenSBLogsButton,
|
||||
start() {
|
||||
enableStyle(styles);
|
||||
FluxDispatcher.subscribe("VOICE_CHANNEL_EFFECT_SEND", async sound => {
|
||||
|
|
@ -56,10 +29,8 @@ export default definePlugin({
|
|||
await updateLoggedSounds(sound);
|
||||
getListeners().forEach(cb => cb());
|
||||
});
|
||||
if (settings.store.IconLocation === "chat") addChatBarButton("vc-soundlog-button", CharBarButton, ChatBarIcon);
|
||||
},
|
||||
stop() {
|
||||
disableStyle(styles);
|
||||
if (settings.store.IconLocation === "chat") removeChatBarButton("vc-soundlog-button");
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -85,15 +85,6 @@ const settings = definePluginSettings({
|
|||
default: 0.5,
|
||||
markers: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
|
||||
},
|
||||
IconLocation: {
|
||||
description: "choose where to show the SoundBoard Log icon (requires restart)",
|
||||
type: OptionType.SELECT,
|
||||
options: [
|
||||
{ label: "Toolbar", value: "toolbar", default: true },
|
||||
{ label: "Chat input", value: "chat" }
|
||||
],
|
||||
restartNeeded: true
|
||||
},
|
||||
});
|
||||
|
||||
export default settings;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { addMessagePreSendListener, MessageSendListener, removeMessagePreSendListener } from "@api/MessageEvents";
|
||||
import { MessageSendListener } from "@api/MessageEvents";
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { EquicordDevs } from "@utils/constants";
|
||||
import { getCurrentChannel, sendMessage } from "@utils/discord";
|
||||
|
|
@ -117,16 +117,11 @@ export default definePlugin({
|
|||
name: "SplitLargeMessages",
|
||||
description: "Splits large messages into multiple to fit Discord's message limit.",
|
||||
authors: [EquicordDevs.Reycko],
|
||||
dependencies: ["MessageEventsAPI"],
|
||||
settings,
|
||||
onBeforeMessageSend: listener,
|
||||
|
||||
start() {
|
||||
if (settings.store.maxLength === 0) maxLength = autoMaxLength();
|
||||
addMessagePreSendListener(listener);
|
||||
},
|
||||
|
||||
stop() {
|
||||
removeMessagePreSendListener(listener);
|
||||
},
|
||||
|
||||
patches: [
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ export default definePlugin({
|
|||
name: "TalkInReverse",
|
||||
authors: [EquicordDevs.Tolgchu],
|
||||
description: "Reverses the message content before sending it.",
|
||||
dependencies: ["MessageEventsAPI", "ChatInputButtonAPI"],
|
||||
dependencies: ["MessageEventsAPI"],
|
||||
chatBarButton: {
|
||||
icon: ReverseMessageIcon,
|
||||
render: ReverseMessageToggle
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ const messageCtxPatch: NavContextMenuPatchCallback = (children, { message }) =>
|
|||
export default definePlugin({
|
||||
name: "Translate+",
|
||||
description: "Vencord's translate plugin but with support for artistic languages!",
|
||||
dependencies: ["MessageAccessoriesAPI"],
|
||||
authors: [Devs.Ven, EquicordDevs.Prince527],
|
||||
settings,
|
||||
contextMenus: {
|
||||
|
|
|
|||
24
src/plugins/_api/headerBar.ts
Normal file
24
src/plugins/_api/headerBar.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { EquicordDevs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
|
||||
export default definePlugin({
|
||||
name: "HeaderBarAPI",
|
||||
description: "API to add buttons to the header bar.",
|
||||
authors: [EquicordDevs.Prism],
|
||||
|
||||
patches: [
|
||||
{
|
||||
find: '?"BACK_FORWARD_NAVIGATION":',
|
||||
replacement: {
|
||||
match: /(?<=\i\.Fragment,\{children:\[.{1,500}className:\i\}\))(?=\])/,
|
||||
replace: ",...Vencord.Api.HeaderBar._addButtons()"
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
import "./style.css";
|
||||
|
||||
import { addMemberListDecorator, removeMemberListDecorator } from "@api/MemberListDecorators";
|
||||
import { addMessageDecoration, removeMessageDecoration } from "@api/MessageDecorations";
|
||||
import { addNicknameIcon, removeNicknameIcon } from "@api/NicknameIcons";
|
||||
import { definePluginSettings, migratePluginSetting, Settings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import { classes } from "@utils/misc";
|
||||
|
|
@ -192,49 +189,22 @@ const PlatformIndicator = ({ user, isProfile, isMessage, isMemberList }: Platfor
|
|||
);
|
||||
};
|
||||
|
||||
function toggleMemberListDecorators(enabled: boolean) {
|
||||
if (enabled) {
|
||||
addMemberListDecorator("PlatformIndicators", props => <PlatformIndicator user={props.user} isMemberList />);
|
||||
} else {
|
||||
removeMemberListDecorator("PlatformIndicators");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleNicknameIcons(enabled: boolean) {
|
||||
if (enabled) {
|
||||
addNicknameIcon("PlatformIndicators", props => <PlatformIndicator user={UserStore.getUser(props.userId)} isProfile />, 1);
|
||||
} else {
|
||||
removeNicknameIcon("PlatformIndicators");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMessageDecorators(enabled: boolean) {
|
||||
if (enabled) {
|
||||
addMessageDecoration("PlatformIndicators", props => <PlatformIndicator user={props.message?.author} isMessage />);
|
||||
} else {
|
||||
removeMessageDecoration("PlatformIndicators");
|
||||
}
|
||||
}
|
||||
|
||||
migratePluginSetting("PlatformIndicators", "profiles", "badges");
|
||||
const settings = definePluginSettings({
|
||||
list: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show indicators in the member list",
|
||||
default: true,
|
||||
onChange: toggleMemberListDecorators
|
||||
},
|
||||
profiles: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show indicators in user profiles",
|
||||
default: true,
|
||||
onChange: toggleNicknameIcons
|
||||
},
|
||||
messages: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Show indicators inside messages",
|
||||
default: true,
|
||||
onChange: toggleMessageDecorators
|
||||
},
|
||||
colorMobileIndicator: {
|
||||
type: OptionType.BOOLEAN,
|
||||
|
|
@ -278,19 +248,21 @@ export default definePlugin({
|
|||
name: "PlatformIndicators",
|
||||
description: "Adds platform indicators (Desktop, Mobile, Web...) to users",
|
||||
authors: [Devs.kemo, Devs.TheSun, Devs.Nuckyz, Devs.Ven],
|
||||
dependencies: ["MemberListDecoratorsAPI", "NicknameIconsAPI", "MessageDecorationsAPI"],
|
||||
settings,
|
||||
|
||||
start() {
|
||||
if (settings.store.list) toggleMemberListDecorators(true);
|
||||
if (settings.store.profiles) toggleNicknameIcons(true);
|
||||
if (settings.store.messages) toggleMessageDecorators(true);
|
||||
renderNicknameIcon(props) {
|
||||
if (!settings.store.profiles) return null;
|
||||
return (
|
||||
<PlatformIndicator user={UserStore.getUser(props.userId)} isProfile />
|
||||
);
|
||||
},
|
||||
renderMemberListDecorator(props) {
|
||||
if (!settings.store.list) return null;
|
||||
return <PlatformIndicator user={props.user} isMemberList />;
|
||||
|
||||
stop() {
|
||||
if (settings.store.list) toggleMemberListDecorators(false);
|
||||
if (settings.store.profiles) toggleNicknameIcons;
|
||||
if (settings.store.messages) toggleMessageDecorators(false);
|
||||
},
|
||||
renderMessageDecoration(props) {
|
||||
if (!settings.store.messages) return null;
|
||||
return <PlatformIndicator user={props.message?.author} isMessage />;
|
||||
},
|
||||
|
||||
patches: [
|
||||
|
|
|
|||
|
|
@ -296,7 +296,6 @@ export default definePlugin({
|
|||
name: "SilentTyping",
|
||||
authors: [Devs.Ven, Devs.Rini, Devs.ImBanana, EquicordDevs.Etorix],
|
||||
description: "Hide your typing indicator from chat.",
|
||||
dependencies: ["ChatInputButtonAPI"],
|
||||
isModified: true,
|
||||
settings,
|
||||
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
import "./style.css";
|
||||
|
||||
import { addMemberListDecorator, removeMemberListDecorator } from "@api/MemberListDecorators";
|
||||
import { addMessageDecoration, removeMessageDecoration } from "@api/MessageDecorations";
|
||||
import { addNicknameIcon, removeNicknameIcon } from "@api/NicknameIcons";
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
|
|
@ -52,9 +49,22 @@ export default definePlugin({
|
|||
name: "UserVoiceShow",
|
||||
description: "Shows an indicator when a user is in a Voice Channel",
|
||||
authors: [Devs.Nuckyz, Devs.LordElias, EquicordDevs.omaw],
|
||||
dependencies: ["NicknameIconsAPI", "MemberListDecoratorsAPI", "MessageDecorationsAPI"],
|
||||
settings,
|
||||
renderNicknameIcon({ userId }) {
|
||||
if (!settings.store.showInUserProfileModal) return null;
|
||||
return (
|
||||
<VoiceChannelIndicator userId={userId} isProfile />
|
||||
);
|
||||
},
|
||||
renderMemberListDecorator({ user }) {
|
||||
if (!settings.store.showInMemberList) return null;
|
||||
return user == null ? null : <VoiceChannelIndicator userId={user.id} />;
|
||||
|
||||
},
|
||||
renderMessageDecoration({ message }) {
|
||||
if (!settings.store.showInMessages) return null;
|
||||
return message?.author == null ? null : <VoiceChannelIndicator userId={message.author.id} isMessageIndicator />;
|
||||
},
|
||||
patches: [
|
||||
// Friends List
|
||||
{
|
||||
|
|
@ -67,23 +77,5 @@ export default definePlugin({
|
|||
}
|
||||
],
|
||||
|
||||
start() {
|
||||
if (settings.store.showInUserProfileModal) {
|
||||
addNicknameIcon("UserVoiceShow", ({ userId }) => <VoiceChannelIndicator userId={userId} isProfile />);
|
||||
}
|
||||
if (settings.store.showInMemberList) {
|
||||
addMemberListDecorator("UserVoiceShow", ({ user }) => user == null ? null : <VoiceChannelIndicator userId={user.id} />);
|
||||
}
|
||||
if (settings.store.showInMessages) {
|
||||
addMessageDecoration("UserVoiceShow", ({ message }) => message?.author == null ? null : <VoiceChannelIndicator userId={message.author.id} isMessageIndicator />);
|
||||
}
|
||||
},
|
||||
|
||||
stop() {
|
||||
removeNicknameIcon("UserVoiceShow");
|
||||
removeMemberListDecorator("UserVoiceShow");
|
||||
removeMessageDecoration("UserVoiceShow");
|
||||
},
|
||||
|
||||
VoiceChannelIndicator
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import { AudioProcessor } from "@api/AudioPlayer";
|
|||
import type { ProfileBadge } from "@api/Badges";
|
||||
import type { ChatBarButtonData, ChatBarButtonFactory } from "@api/ChatButtons";
|
||||
import type { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||
import { HeaderBarButtonFactory } from "@api/HeaderBar";
|
||||
import type { MemberListDecoratorFactory } from "@api/MemberListDecorators";
|
||||
import type { MessageAccessoryFactory } from "@api/MessageAccessories";
|
||||
import type { MessageDecorationFactory } from "@api/MessageDecorations";
|
||||
|
|
@ -199,7 +200,8 @@ export interface PluginDef {
|
|||
|
||||
// Custom
|
||||
renderNicknameIcon?: NicknameIconFactory;
|
||||
audioProcessor?: AudioProcessor;
|
||||
renderHeaderBarButton?: HeaderBarButtonFactory;
|
||||
onAudioProcessor?: AudioProcessor;
|
||||
|
||||
// TODO: Remove eventually
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue