95 lines
4.3 KiB
JavaScript
95 lines
4.3 KiB
JavaScript
import Builtin from "../../structs/builtin";
|
|
import {Utilities, WebpackModules, React} from "modules";
|
|
import EmoteModule from "./emotes";
|
|
import EmoteMenuCard from "../../ui/emotemenucard";
|
|
import EmoteIcon from "../../ui/emoteicon";
|
|
import Category from "./category";
|
|
import Favorite from "../../ui/icons/favorite";
|
|
import Twitch from "../../ui/icons/twitch";
|
|
|
|
const EmojiPicker = WebpackModules.find(m => m.type && m.type.displayName == "ExpressionPicker");
|
|
const {useExpressionPickerStore} = WebpackModules.getByProps("useExpressionPickerStore") ?? {};
|
|
|
|
export default new class EmoteMenu extends Builtin {
|
|
get name() {return "EmoteMenu";}
|
|
get collection() {return "emotes";}
|
|
get category() {return "general";}
|
|
get id() {return "emoteMenu";}
|
|
get hideEmojisID() {return "hideEmojiMenu";}
|
|
get hideEmojis() {return this.get(this.hideEmojisID);}
|
|
|
|
enabled() {
|
|
this.after(EmojiPicker, "type", (_, __, returnValue) => {
|
|
const originalChildren = returnValue?.props?.children?.props?.children;
|
|
if (!originalChildren || originalChildren.__patched) return;
|
|
|
|
const activePicker = useExpressionPickerStore((state) => state.activeView);
|
|
|
|
returnValue.props.children.props.children = (props) => {
|
|
const childrenReturn = Reflect.apply(originalChildren, null, [props]);
|
|
|
|
// Attach a try {} catch {} because this might crash the user.
|
|
try {
|
|
const head = Utilities.findInTree(childrenReturn, (e) => e?.role === "tablist", {walkable: ["props", "children", "return", "stateNode"]})?.children;
|
|
const body = Utilities.findInTree(childrenReturn, (e) => e?.[0]?.type === "nav", {walkable: ["props", "children", "return", "stateNode"]});
|
|
if (!head || !body) return childrenReturn;
|
|
|
|
const isActive = activePicker == "bd-emotes";
|
|
const TabItem = head[0]?.type ?? (() => null);
|
|
|
|
if (!isActive && activePicker == "emoji" && this.hideEmojis) {
|
|
useExpressionPickerStore.setState({activeView: "bd-emotes"});
|
|
}
|
|
|
|
if (this.hideEmojis) {
|
|
const emojiTabIndex = head.findIndex((e) => e?.props?.id == "emoji-picker-tab");
|
|
if (emojiTabIndex > -1) head.splice(emojiTabIndex, 1);
|
|
}
|
|
|
|
head.push(
|
|
React.createElement(TabItem, {
|
|
"aria-controls": "bd-emotes",
|
|
"id": "bd-emotes",
|
|
"aria-selected": isActive,
|
|
"isActive": isActive,
|
|
"viewType": "bd-emotes"
|
|
}, "Twitch")
|
|
);
|
|
if (isActive) {
|
|
body.push(
|
|
React.createElement(EmoteMenuCard, {
|
|
type: "twitch",
|
|
}, [
|
|
React.createElement(Category, {
|
|
label: "Favorites",
|
|
icon: React.createElement(Favorite, {}),
|
|
}, Object.entries(EmoteModule.favorites).map(([emote, url]) => {
|
|
return React.createElement(EmoteIcon, {emote, url});
|
|
})),
|
|
React.createElement(Category, {
|
|
label: "Twitch Emotes",
|
|
icon: React.createElement(Twitch, {})
|
|
}, Object.keys(EmoteModule.getCategory("TwitchGlobal")).map((emote) => {
|
|
const url = EmoteModule.getUrl("TwitchGlobal", emote);
|
|
return React.createElement(EmoteIcon, {emote, url});
|
|
}))
|
|
])
|
|
);
|
|
}
|
|
}
|
|
catch (error) {
|
|
this.error("Error in EmojiPicker patch:\n", error);
|
|
}
|
|
|
|
return childrenReturn;
|
|
};
|
|
|
|
returnValue.props.children.props.children.__patched = true;
|
|
});
|
|
}
|
|
|
|
disabled() {
|
|
this.unpatchAll();
|
|
}
|
|
|
|
}; |