Equicord/src/equicordplugins/philsPluginLibrary/patches/userPanel.tsx
thororen1234 3c4d217312 Stuff
2024-07-18 00:53:55 -04:00

107 lines
3.8 KiB
TypeScript

/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { React } from "@webpack/common";
import { SettingsPanel } from "../components";
import { IconComponent, SettingsPanelButton } from "../components/settingsPanel/SettingsPanelButton";
import { SettingsPanelRow } from "../components/settingsPanel/SettingsPanelRow";
import { SettingsPanelTooltipButton } from "../components/settingsPanel/SettingsPanelTooltipButton";
export interface PanelButton {
name: string,
tooltipText?: string,
icon?: IconComponent;
onClick?: () => void;
}
const settingsPanelButtonsSubscriptions = new Set<React.DispatchWithoutAction>();
export const settingsPanelButtons: PanelButton[] = new Proxy<PanelButton[]>([], {
set: (target, p, newValue) => {
target[p] = newValue;
settingsPanelButtonsSubscriptions.forEach(fn => fn());
return true;
},
});
export const useButtons = () => {
const [, forceUpdate] = React.useReducer(() => ({}), {});
React.useEffect(() => {
settingsPanelButtonsSubscriptions.add(forceUpdate);
return () => void settingsPanelButtonsSubscriptions.delete(() => forceUpdate);
}, []);
return settingsPanelButtons;
};
export const ButtonsSettingsPanel = () => {
const rawPanelButtons = useButtons();
const convertRawPanelButtons = (buttons: PanelButton[]) => {
const settingsPanelButtonsClone = [...buttons].sort();
const groupedButtons: JSX.Element[][] = [];
while (settingsPanelButtonsClone.length) {
const splicedButtons =
settingsPanelButtonsClone
.splice(0, 3)
.map(({ icon, tooltipText, onClick }) =>
tooltipText
? <SettingsPanelTooltipButton tooltipProps={{ text: tooltipText }} icon={icon} onClick={onClick} />
: <SettingsPanelButton icon={icon} onClick={onClick} />
);
groupedButtons.push(splicedButtons);
}
return groupedButtons;
};
return rawPanelButtons.length > 0
? <SettingsPanel>
{...convertRawPanelButtons(rawPanelButtons).map(value => <SettingsPanelRow children={value} />)}
</SettingsPanel>
: <>
</>;
};
export function replacedUserPanelComponent(oldComponent: (...args: any[]) => any, thisContext: any, functionArguments: any) {
const componentResult: JSX.Element = Reflect.apply(oldComponent, thisContext, functionArguments);
if (!componentResult?.props) return componentResult;
const { children } = componentResult.props;
const userPanel = children.at(-2);
const userPanelChildren = userPanel.props.children;
userPanelChildren.splice(userPanelChildren.length - 1, 0,
<ButtonsSettingsPanel />
);
return componentResult;
}
export function addSettingsPanelButton(settings: PanelButton) {
settingsPanelButtons.push(settings);
}
export function removeSettingsPanelButton(name: string) {
settingsPanelButtons.splice(0, settingsPanelButtons.length, ...settingsPanelButtons.filter(value => value.name !== name));
}