From 838a90831f0b0405150cc69e9ee0ca11d96f5c59 Mon Sep 17 00:00:00 2001 From: sadan4 <117494111+sadan4@users.noreply.github.com> Date: Fri, 2 May 2025 20:40:07 -0400 Subject: [PATCH] Fix BetterFolders, ReviewDB and minor ShowHiddenChannels patch (#3396) Co-authored-by: Nuckyz <61953774+Nuckyz@users.noreply.github.com> --- src/plugins/betterFolders/index.tsx | 101 ++++++++++++++--------- src/plugins/reviewDB/index.tsx | 12 +-- src/plugins/showHiddenChannels/index.tsx | 17 ++-- 3 files changed, 80 insertions(+), 50 deletions(-) diff --git a/src/plugins/betterFolders/index.tsx b/src/plugins/betterFolders/index.tsx index 3bcf0335..2b1defd8 100644 --- a/src/plugins/betterFolders/index.tsx +++ b/src/plugins/betterFolders/index.tsx @@ -50,6 +50,35 @@ function closeFolders() { FolderUtils.toggleGuildFolderExpand(id); } +// Nuckyz: Unsure if this should be a general utility or not +function filterTreeWithTargetNode(children: any, predicate: (node: any) => boolean) { + if (children == null) { + return false; + } + + if (!Array.isArray(children)) { + if (predicate(children)) { + return true; + } + + return filterTreeWithTargetNode(children.props.children, predicate); + } + + + let childIsTargetChild = false; + for (let i = 0; i < children.length; i++) { + const shouldKeep = filterTreeWithTargetNode(children[i], predicate); + if (shouldKeep) { + childIsTargetChild = true; + continue; + } + + children.splice(i--, 1); + } + + return childIsTargetChild; +} + export const settings = definePluginSettings({ sidebar: { type: OptionType.BOOLEAN, @@ -114,29 +143,35 @@ export default definePlugin({ predicate: () => settings.store.sidebar, replacement: [ // Create the isBetterFolders variable in the GuildsBar component + // Needed because we access this from a non-arrow closure so we can't use arguments[0] { match: /let{disableAppDownload:\i=\i\.isPlatformEmbedded,isOverlay:.+?(?=}=\i,)/, replace: "$&,isBetterFolders" }, + // Export the isBetterFolders and betterFoldersExpandedIds variable to the Guild List component + { + match: /0,\i\.jsxs?[^0}]{0,100}guildDiscoveryButton:\i,/g, + replace: "$&isBetterFolders:arguments[0]?.isBetterFolders,betterFoldersExpandedIds:arguments[0]?.betterFoldersExpandedIds," + }, + // Export the isBetterFolders variable to the folders component + { + match: /switch\(\i\.type\){case \i\.\i\.FOLDER:.+?folderNode:\i,/, + replace: '$&isBetterFolders:typeof isBetterFolders!=="undefined"?isBetterFolders:false,' + }, // If we are rendering the Better Folders sidebar, we filter out guilds that are not in folders and unexpanded folders { match: /\[(\i)\]=(\(0,\i\.\i\).{0,40}getGuildsTree\(\).+?}\))(?=,)/, replace: (_, originalTreeVar, rest) => `[betterFoldersOriginalTree]=${rest},${originalTreeVar}=$self.getGuildTree(!!arguments[0]?.isBetterFolders,betterFoldersOriginalTree,arguments[0]?.betterFoldersExpandedIds)` }, - // If we are rendering the Better Folders sidebar, we filter out everything but the servers and folders from the GuildsBar Guild List children + // If we are rendering the Better Folders sidebar, we filter out everything but the servers and folders from the Guild List children { match: /lastTargetNode:\i\[\i\.length-1\].+?}\)(?::null)?\](?=}\))/, replace: "$&.filter($self.makeGuildsBarGuildListFilter(!!arguments[0]?.isBetterFolders))" }, - // If we are rendering the Better Folders sidebar, we filter out everything but the scroller for the guild list from the GuildsBar Tree children + // If we are rendering the Better Folders sidebar, we filter out everything but the Guild List from the Sidebar children { - match: /unreadMentionsIndicatorBottom,.+?}\)\]/, - replace: "$&.filter($self.makeGuildsBarTreeFilter(!!arguments[0]?.isBetterFolders))" - }, - // Export the isBetterFolders variable to the folders component - { - match: /switch\(\i\.type\){case \i\.\i\.FOLDER:.+?folderNode:\i,/, - replace: '$&isBetterFolders:typeof isBetterFolders!=="undefined"?isBetterFolders:false,' + match: /unreadMentionsFixedFooter\].+?\]/, + replace: "$&.filter($self.makeGuildsBarSidebarFilter(!!arguments[0]?.isBetterFolders))" } ] }, @@ -161,7 +196,7 @@ export default definePlugin({ ] }, { - find: ".expandedFolderBackground,", + find: ".FOLDER_ITEM_ANIMATION_DURATION),", predicate: () => settings.store.sidebar, replacement: [ // We use arguments[0] to access the isBetterFolders variable in this nested folder component (the parent exports all the props so we don't have to patch it) @@ -181,27 +216,20 @@ export default definePlugin({ // If we are rendering the normal GuildsBar sidebar, we avoid rendering guilds from folders that are expanded { predicate: () => !settings.store.keepIcons, - match: /expandedFolderBackground,.+?,(?=\i\(\(\i,\i,\i\)=>{let{key.{0,45}ul)(?<=selected:\i,expanded:(\i),.+?)/, + match: /folderGroupBackground.+?,(?=\i\(\(\i,\i,\i\)=>{let{key:.{0,70}"ul")(?<=selected:\i,expanded:(\i),.+?)/, replace: (m, isExpanded) => `${m}$self.shouldRenderContents(arguments[0],${isExpanded})?null:` }, + // Decide if we should render the expanded folder background if we are rendering the Better Folders sidebar { - // Decide if we should render the expanded folder background if we are rendering the Better Folders sidebar predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always, - match: /\.isExpanded\),.{0,30}children:\[/, + match: /\.isExpanded\].{0,110}children:\[/, replace: "$&$self.shouldShowFolderIconAndBackground(!!arguments[0]?.isBetterFolders,arguments[0]?.betterFoldersExpandedIds)&&" }, + // Decide if we should render the expanded folder icon if we are rendering the Better Folders sidebar { - // Decide if we should render the expanded folder icon if we are rendering the Better Folders sidebar predicate: () => settings.store.showFolderIcon !== FolderIconDisplay.Always, - match: /(?<=\.expandedFolderBackground.+?}\),)(?=\i,)/, + match: /(?<=\.folderGroupBackground.*?}\),)(?=\i,)/, replace: "!$self.shouldShowFolderIconAndBackground(!!arguments[0]?.isBetterFolders,arguments[0]?.betterFoldersExpandedIds)?null:" - }, - { - // Discord adds a slight bottom margin of 4px when it's expanded - // Which looks off when there's nothing open in the folder - predicate: () => !settings.store.keepIcons, - match: /(?=className:.{0,50}folderIcon)/, - replace: "style:arguments[0]?.isBetterFolders?{}:{marginBottom:0}," } ] }, @@ -278,6 +306,9 @@ export default definePlugin({ } }, + FolderSideBar, + closeFolders, + gridStyle: "vc-betterFolders-sidebar-grid", getGuildTree(isBetterFolders: boolean, originalTree: any, expandedFolderIds?: Set) { @@ -299,34 +330,33 @@ export default definePlugin({ makeGuildsBarGuildListFilter(isBetterFolders: boolean) { return child => { - if (!isBetterFolders) return true; + if (!isBetterFolders) { + return true; + } try { return child?.props?.["aria-label"] === getIntlMessage("SERVERS"); } catch (e) { console.error(e); + return true; } - - return true; }; }, - makeGuildsBarTreeFilter(isBetterFolders: boolean) { + makeGuildsBarSidebarFilter(isBetterFolders: boolean) { return child => { - if (!isBetterFolders) return true; - - if (child?.props?.className?.includes("itemsContainer") && child.props.children != null) { - // Filter out everything but the scroller for the guild list - child.props.children = child.props.children.filter(child => child?.props?.onScroll != null); + if (!isBetterFolders) { return true; } - return false; + return filterTreeWithTargetNode(child, child => child?.props?.renderTreeNode != null); }; }, shouldShowFolderIconAndBackground(isBetterFolders: boolean, expandedFolderIds?: Set) { - if (!isBetterFolders) return true; + if (!isBetterFolders) { + return true; + } switch (settings.store.showFolderIcon) { case FolderIconDisplay.Never: @@ -352,8 +382,5 @@ export default definePlugin({ if (props?.folderNode?.id === 1) return false; return !props?.isBetterFolders && isExpanded; - }, - - FolderSideBar, - closeFolders, + } }); diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx index 822ebde6..32546b9b 100644 --- a/src/plugins/reviewDB/index.tsx +++ b/src/plugins/reviewDB/index.tsx @@ -77,23 +77,23 @@ export default definePlugin({ patches: [ { - find: ".BITE_SIZE,user:", + find: ".POPOUT,user:", replacement: { - match: /{profileType:\i\.\i\.BITE_SIZE,children:\[/, + match: /children:\[(?=[^[]+?shouldShowTooltip:)/, replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user})," } }, { - find: ".FULL_SIZE,user:", + find: ".MODAL,user:", replacement: { - match: /{profileType:\i\.\i\.FULL_SIZE,children:\[/, + match: /children:\[(?=[^[]+?shouldShowTooltip:)/, replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user})," } }, { - find: 'location:"UserProfilePanel"', + find: ".SIDEBAR,shouldShowTooltip:", replacement: { - match: /{profileType:\i\.\i\.PANEL,children:\[/, + match: /children:\[(?=[^[]+?shouldShowTooltip:)/, replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user})," } } diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx index 7a38bb12..7a3dd9fb 100644 --- a/src/plugins/showHiddenChannels/index.tsx +++ b/src/plugins/showHiddenChannels/index.tsx @@ -325,7 +325,7 @@ export default definePlugin({ ] }, { - find: '})},"overflow"))', + find: '="interactive-normal",overflowCountClassName:', replacement: [ { // Create a variable for the channel prop @@ -334,18 +334,21 @@ export default definePlugin({ }, { // Make Discord always render the plus button if the component is used inside the HiddenChannelLockScreen - match: /\i>0(?=&&.{0,60}renderPopout)/, + match: /\i>0(?=&&.{0,30}Math.min)/, replace: m => `($self.isHiddenChannel(typeof shcChannel!=="undefined"?shcChannel:void 0,true)?true:${m})` }, { - // Prevent Discord from overwriting the last children with the plus button if the overflow amount is <= 0 and the component is used inside the HiddenChannelLockScreen - match: /(?<=\.value\(\),(\i)=.+?length-)1(?=\]=.{0,60}renderPopout)/, + // Prevent Discord from overwriting the last children with the plus button + // if the overflow amount is <= 0 and the component is used inside the HiddenChannelLockScreen + match: /(?<=\i\.length-)1(?=\]=.{0,60}renderPopout)(?<=(\i)=\i\.length-\i.+?)/, replace: (_, amount) => `($self.isHiddenChannel(typeof shcChannel!=="undefined"?shcChannel:void 0,true)&&${amount}<=0?0:1)` }, { - // Show only the plus text without overflowed children amount if the overflow amount is <= 0 and the component is used inside the HiddenChannelLockScreen - match: /(?<="\+",)(\i)\+1/, - replace: (m, amount) => `$self.isHiddenChannel(typeof shcChannel!=="undefined"?shcChannel:void 0,true)&&${amount}<=0?"":${m}` + // Show only the plus text without overflowed children amount + // if the overflow amount is <= 0 and the component is used inside the HiddenChannelLockScreen + match: /(?<="\+"\.concat\()\i/, + replace: overflowTextAmount => "" + + `$self.isHiddenChannel(typeof shcChannel!=="undefined"?shcChannel:void 0,true)&&(${overflowTextAmount}-1)<=0?"":${overflowTextAmount}` } ] },