diff --git a/renderer/src/builtins/emotes/emotemenu.js b/renderer/src/builtins/emotes/emotemenu.js index 85f7da75..9ae4e679 100644 --- a/renderer/src/builtins/emotes/emotemenu.js +++ b/renderer/src/builtins/emotes/emotemenu.js @@ -6,7 +6,9 @@ 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";} @@ -16,60 +18,69 @@ export default new class EmoteMenu extends Builtin { get hideEmojisID() {return "hideEmojiMenu";} get hideEmojis() {return this.get(this.hideEmojisID);} - getSelected(body) { - if (body[1]) return {id: "stickers", index: 1}; - else if (body[2]) return {id: "gif", index: 2}; - else if (body[3]) return {id: "emoji", index: 3}; - return {id: "bd-emotes", index: 3}; - } - enabled() { this.after(EmojiPicker, "type", (_, __, returnValue) => { const originalChildren = Utilities.getNestedProp(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]); - const head = Utilities.getNestedProp(childrenReturn, "props.children.props.children.1.props.children.0.props.children.props.children"); - const body = Utilities.getNestedProp(childrenReturn, "props.children.props.children.1.props.children"); - if (!head || !body) return childrenReturn; - let activePicker = this.getSelected(body); - let isActive = activePicker.id == "bd-emotes"; - const tabProps = head[0].props; - if (!isActive && activePicker.id == "emoji" && this.hideEmojis) { - activePicker = {id: "bd-emotes", index: 3}; - isActive = true; + // Attach a try {} catch {} because this might crash the user. + try { + const head = Utilities.findInReactTree(childrenReturn, (e) => e?.role === "tablist")?.children; + const body = Utilities.findInReactTree(childrenReturn, (e) => e?.[0]?.type === "nav"); + if (!head || !body) return childrenReturn; + + const isActive = activePicker == "bd-emotes"; + const tabProps = head[0].props; + + 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("div", { + "id": "bd-emotes-tab", + "role": "tab", + "aria-selected": isActive, + "className": tabProps.className, + }, React.createElement(tabProps.children.type, { + viewType: "bd-emotes", + isActive: isActive, + }, "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}); + })) + ]) + ); + } } - if (this.hideEmojis) head.splice(head.findIndex(e => e && e.props && e.props.id == "emoji-picker-tab"), 1); - head.push( - React.createElement("div", { - "id": "bd-emotes-tab", - "role": "tab", - "aria-selected": isActive, - "className": tabProps.className, - }, React.createElement(tabProps.children.type, { - viewType: "bd-emotes", - isActive: isActive, - }, "Twitch") - )); - if (isActive) { - body[activePicker.index] = 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;