From dc1822035798bf2e11f4ffe29379e11063f4c9f6 Mon Sep 17 00:00:00 2001 From: everestmcarthur Date: Sat, 1 Aug 2026 19:29:11 +0000 Subject: [PATCH] deploy: 0ccfd1b2765be78b8b9c1e82532da132e0a84892 --- plugins-data.json | 4 ++-- rose-utils/install/index.js | 4 ++-- rose-utils/install/manifest.json | 2 +- server-drawer/install/index.js | 2 +- server-drawer/install/manifest.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins-data.json b/plugins-data.json index 2c08da5..bdacb1a 100644 --- a/plugins-data.json +++ b/plugins-data.json @@ -144,7 +144,7 @@ "status": "revived", "accent": "#F97316", "tagline": "An expandable server grid with DMs, smarter folders, and mark-all-read built in.", - "note": "Fork of kmmiio99o's ServerDrawer. One lookup (useMobileQuestDock) was missing an optional-chaining guard - if that lookup came back empty, the whole onLoad threw and every patch after it in the sequence never got applied, not just that one surface. Fixed, plus every patch call is now wrapped so a single bad lookup only skips its own surface. Folder options (auto-collapse, hide preview icons) are adapted from fres621's BetterFolders - its icon-hiding half patched a \"GuildContainer\" component that no longer exists anywhere in current Discord builds (confirmed against decompiled source), and only applied to the native server rail anyway, which this plugin already replaces - so it's been rebuilt as a feature of the drawer's own folders instead. Two more bugs fixed after real device testing: guild icons that never loaded (GuildStore lookups weren't reactive to guild data streaming in after connect, so most servers just showed a bare unread dot with no icon) and taps in the drawer not navigating anywhere (several lookups - transitionToGuild, the create/join action, the root nav ref - were resolved once at plugin-load time, before Discord had necessarily required those modules yet, same class of bug as YouBar+'s startup race). Both fixed; DMs also moved from a leftover sidebar icon into the drawer itself, and a mark-all-servers-as-read button was added. Two more rounds after that: the Quest Dock hijack (10 separate internal lookups just to force it to render) used to be attempted once at onLoad, so if any single one of them wasn't registered in Metro yet the drawer could just silently not show up for the whole session - it now retries whatever hasn't landed on a fast 200ms interval until everything's applied. And mark-all-read was rebuilt to match Discord's own markGuildsAsRead action exactly (getSelectableChannelIds + getVocalChannelIds per guild, confirmed against decompiled source) instead of a less certain guild-enumeration method.", + "note": "Fork of kmmiio99o's ServerDrawer. One lookup (useMobileQuestDock) was missing an optional-chaining guard - if that lookup came back empty, the whole onLoad threw and every patch after it in the sequence never got applied, not just that one surface. Fixed, plus every patch call is now wrapped so a single bad lookup only skips its own surface. Folder options (auto-collapse, hide preview icons) are adapted from fres621's BetterFolders - its icon-hiding half patched a \"GuildContainer\" component that no longer exists anywhere in current Discord builds (confirmed against decompiled source), and only applied to the native server rail anyway, which this plugin already replaces - so it's been rebuilt as a feature of the drawer's own folders instead. Two more bugs fixed after real device testing: guild icons that never loaded (GuildStore lookups weren't reactive to guild data streaming in after connect, so most servers just showed a bare unread dot with no icon) and taps in the drawer not navigating anywhere (several lookups - transitionToGuild, the create/join action, the root nav ref - were resolved once at plugin-load time, before Discord had necessarily required those modules yet, same class of bug as YouBar+'s startup race). Both fixed; DMs also moved from a leftover sidebar icon into the drawer itself, and a mark-all-servers-as-read button was added. Two more rounds after that: the Quest Dock hijack (10 separate internal lookups just to force it to render) used to be attempted once at onLoad, so if any single one of them wasn't registered in Metro yet the drawer could just silently not show up for the whole session - it now retries whatever hasn't landed on a fast 200ms interval until everything's applied. And mark-all-read was rebuilt to match Discord's own markGuildsAsRead action exactly (getSelectableChannelIds + getVocalChannelIds per guild, confirmed against decompiled source) instead of a less certain guild-enumeration method. The left server rail hiding was also fixed properly this round: the rail's root component has no discoverable name at runtime at all (confirmed against decompiled source - it's a bare default export, and unlike memo-wrapped components with an explicit displayName, a plain function's own .name doesn't survive production minification), so every name-based lookup for it was guaranteed to fail. Now intercepted by its outermost View's literal nativeID (\"guilds-bar-view\", confirmed unique in the bundle) instead. The long-press context menu on a server icon had the exact same problem (getGuildsBarGuildMenuItems is also a bare default export) - replaced with a small menu of actions built from APIs this repo has already confirmed work (mark this server as read, copy server ID) instead of a lookup that could never succeed.", "howItWorks": "Hijacks the Quest Dock - the strip Discord normally uses for daily quests, right above the tab bar - and puts a grid of your servers there instead. Tap it to expand, tap a server to jump to it, long-press for the usual context menu (mark as read, notification settings, leave, etc). A + button opens Discord's own create/join-server modal. Optionally hides the left server rail down to a single DMs icon, since your servers now live in the drawer instead.", "features": [ "Tap-to-expand server grid with folders, unread badges, and mention counts", @@ -390,7 +390,7 @@ "status": "revived", "accent": "#F0637E", "tagline": "Spotify listen-along, a Tenor fix, colorful channels, and more - now actually working.", - "note": "Fork of nexpid's NexxUtils. Fixed the reported \"render is not a function in SpotifyPlayButton\" crash - Discord converted it from a class component to a function component, confirmed against decompiled current-build source, so patching .prototype.render no longer worked. Also fixed six other lookups across the plugin that had the same unguarded pattern that crashed FPTE's whole bundle at load time - any one of them failing would have taken the entire plugin down, not just one module. A more serious bug was found and fixed after real device testing: opening RoseUtils' own settings screen crashed outright with \"Cannot convert undefined value to object\". Root cause, confirmed by reading the compiled bundle directly: this repo's SWC build config lowers class syntax to plain functions for compatibility, but doesn't also handle the separate class-fields transform, so every field initializer on the internal Module class (errors, patches, started, listeners) was silently dropped from the compiled output - every module was missing all four. Fixed by assigning them in the constructor body instead, which every build target handles the same way. Also added a new module: Enforce Developer Mode, which keeps Discord's Developer Mode switched on since it tends to reset itself on Revenge.", + "note": "Fork of nexpid's NexxUtils. Fixed the reported \"render is not a function in SpotifyPlayButton\" crash - Discord converted it from a class component to a function component, confirmed against decompiled current-build source, so patching .prototype.render no longer worked. Also fixed six other lookups across the plugin that had the same unguarded pattern that crashed FPTE's whole bundle at load time - any one of them failing would have taken the entire plugin down, not just one module. A more serious bug was found and fixed after real device testing: opening RoseUtils' own settings screen crashed outright with \"Cannot convert undefined value to object\". Root cause, confirmed by reading the compiled bundle directly: this repo's SWC build config lowers class syntax to plain functions for compatibility, but doesn't also handle the separate class-fields transform, so every field initializer on the internal Module class (errors, patches, started, listeners) was silently dropped from the compiled output - every module was missing all four. Fixed by assigning them in the constructor body instead, which every build target handles the same way. Also added a new module: Enforce Developer Mode, which keeps Discord's Developer Mode switched on since it tends to reset itself on Revenge. Minimod's timeout indicator was fixed too: GuildMemberStore.getCommunicationDisabledUserMap doesn't exist anymore (confirmed against decompiled source) - it now reads getMember(guildId, userId).communicationDisabledUntil per member instead, which does. Enforce Developer Mode also gained a 5-second poll as a backup to the settings-change listener, so it can't stay off for long no matter what actually reset it.", "howItWorks": "Each utility is its own independently toggleable module: Spotify listen-along buttons on activities, a fix for Tenor GIFs downloading as videos, an invite-to-listen-along button in the chat attachment menu, a fun \"minimod\" that shows member timeouts in chat, and colorful/NSFW-tagged channel icons. Every module tracks its own errors and shows a one-tap \"copy report\" row if something goes wrong, so a problem in one module is easy to report without digging through logs. The original's Material-Design component reskin (Switch/Toast/Alert) wasn't ported - it depends on react-native-reanimated, which isn't part of this build, and it was already disabled by default upstream due to known issues.", "features": [ "Spotify listen-along buttons on activities (fixed)", diff --git a/rose-utils/install/index.js b/rose-utils/install/index.js index 2e6ad17..2eabca4 100644 --- a/rose-utils/install/index.js +++ b/rose-utils/install/index.js @@ -1,4 +1,4 @@ -(function(S,g,o,a,u,H,h,R,b,w){"use strict";function C(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function N(e,t){for(var n=0;nn&&(r.message.communicationDisabled=!0)}))},onStop(){}}});const he=o.findByStoreName("ThemeStore"),be=o.find(function(e){return e?.default?.internal?.resolveSemanticColor})?.default?.internal?.resolveSemanticColor??o.find(function(e){return e?.meta?.resolveSemanticColor})?.meta?.resolveSemanticColor??function(){};function O(e,t=he?.theme){if(e)try{return be(t,e)}catch{return}}const{View:ye,Text:pe}=a.ReactNative,V={destructive:{bg:"#F23F42",fg:"#FFFFFF"},default:{bg:"#4E5058",fg:"#FFFFFF"}};function ve({variant:e="default",children:t}){const n=V[e]??V.default;return a.React.createElement(ye,{style:{backgroundColor:n.bg,borderRadius:4,paddingHorizontal:4,paddingVertical:1,marginLeft:4,alignSelf:"center"}},a.React.createElement(pe,{style:{color:n.fg,fontSize:10,fontWeight:"700",textTransform:"uppercase"}},t))}var Se="f47fd463dcaac61e.png",Re="f944dbd033a60207.png",we="88eacd3588829ded.png",Ee="4d1aef97fe869aaf.png",ke="3a73d84a21043a5e.png",me="8b628d7e3fc05957.png",$e="cb7a2c9b3fb9561c.png",Fe="11d89273b5bd6cc6.png",Te="ea31146eb15fdde7.png",Ae="b0d124bd12658047.png",Ce="cb8b45023e70bb61.png",Ne="a738efc867a225ee.png",Ie="cba17334eeaf3198.png",Be="fead9e69933db668.png",Le="fead9e69933db668.png",De="d6a4e512cdcf1078.png",xe="9901722947705011.png",Pe=function(e){return e.Lock="Lock",e.Warning="Warning",e.Controller="Controller",e}(Pe||{});function Me(e,t){if(e==="Lock")return t?Te:Fe;if(e==="Warning")return t?xe:De;if(e==="Controller")return we}const Ue={Lock:["#f0b232","STATUS_WARNING"],Warning:["#f23f43","STATUS_DANGER"],Controller:["#23a55a","STATUS_POSITIVE"]},_e=[{name:"Announcements",kind:"Lock",base:Se},{name:"Announcements",kind:"Warning",base:Re},{name:"Text",kind:"Lock",base:Ne},{name:"Text",kind:"Warning",base:Ie},{name:"Text",kind:"Controller",base:Ce},{name:"Voice",kind:"Lock",base:Be},{name:"Voice",kind:"Warning",base:Le},{name:"Forum",kind:"Lock",base:Ee},{name:"Forum",kind:"Warning",base:ke},{name:"Stage",kind:"Lock",bottom:!0,base:Ae},{name:"Stage",kind:"Warning",bottom:!0,base:0},{name:"Image",kind:"Lock",bottom:!0,base:me},{name:"Image",kind:"Warning",bottom:!0,base:$e}],W=o.findByName("ChannelInfo",!1),j=o.findByProps("BaseChannelIcon");var Oe=new d({id:"colorful-channels",label:"Colorful Channels",meta:{sublabel:"Gives channel icons with symbols colors to make them more aesthetically pleasing",category:c.Useful},settings:{nsfwTag:{label:"NSFW tag",subLabel:"Adds a red NSFW tag next to channel names",type:"toggle",default:!0},colorIcons:{label:"Colored icon symbols",subLabel:"Turns locked channel symbols yellow, NSFW channel symbols red",type:"toggle",default:!0},colorIconsFallback:{label:"Fallback colors for colored icon symbols",subLabel:"Uses yellow, red and green colors regardless of theme",type:"toggle",default:!1}},handlers:{onStart(){var e=this;this.storage.options.nsfwTag&&W&&this.patches.add(u.after("default",W,function([{channel:t}],n){return a.React.createElement(a.React.Fragment,{},t?.nsfw_&&a.React.createElement(ve,{variant:"destructive"},"nsfw"),n)})),this.storage.options.colorIcons&&j?.BaseChannelIcon&&this.patches.add(u.after("BaseChannelIcon",j,function([{source:t,style:n}],r){try{const i=typeof t?.original=="number"?b.getAssetByID(t.original)?.name:typeof t=="number"?b.getAssetByID(t)?.name:null;if(!i)return;const s=_e.find(function(G){return i===`${G.name}${G.kind}Icon`});if(!s)return;const[l,T]=Ue[s.kind],A=Me(s.kind,s.bottom),f=r?.props?.color?.replace(/-/g,"_")?.toUpperCase(),nt=f&&w.semanticColors?.[f]?O(w.semanticColors[f]):void 0,z=a.ReactNative.StyleSheet.flatten([n,r?.props?.style,{width:18,height:18,tintColor:nt}]),at=e.storage.options.colorIconsFallback?l:O(w.semanticColors?.[T])??l;return a.React.createElement(a.ReactNative.View,{},a.React.createElement(a.ReactNative.Image,{style:z,source:s.base}),a.React.createElement(a.ReactNative.View,{style:{position:"absolute",right:0,bottom:0}},a.React.createElement(a.ReactNative.Image,{style:{...z,tintColor:at},source:A})))}catch{return}}))},onStop(){}}});const Ve=o.findByProps("DeveloperMode","DarkSidebar");var We=new d({id:"enforce-developer-mode",label:"Enforce Developer Mode",meta:{sublabel:"Keeps Developer Mode switched on - it tends to reset itself on Revenge-based clients",category:c.Fixes},handlers:{onStart(){const e=Ve?.DeveloperMode;if(!e?.getSetting||!e?.updateSetting)return;const t=function(){try{e.getSetting()||e.updateSetting(!0)}catch{}};t(),this.patches.add(p("USER_SETTINGS_PROTO_UPDATE",t))},onStop(){}}}),$=[ne,ae,de,ge,Oe,We];const{ScrollView:je,View:Ye}=a.ReactNative;function ze({children:e}){return a.React.createElement(je,{style:{flex:1}},e,a.React.createElement(Ye,{style:{height:24}}))}const{View:Ge,Text:He}=a.ReactNative;function Ke({children:e,style:t}){return a.React.createElement(Ge,{style:[{marginHorizontal:16,marginVertical:8,padding:10,borderRadius:8,borderWidth:1,borderColor:"rgba(128,128,128,0.25)"},t]},a.React.createElement(He,{style:{fontSize:12.5,lineHeight:18,opacity:.75}},e))}const{FormSection:Je,FormSwitchRow:Y,FormRow:F}=R.Forms;function qe(e,t){return typeof e.subLabel=="function"?e.subLabel(t):e.subLabel}function Qe({module:e,settingKey:t}){const n=e.settings[t];if(n.predicate&&!n.predicate.call(e))return null;const r=e.storage.options[t],i=qe(n,r),s=!e.storage.enabled;return n.type==="toggle"?a.React.createElement(Y,{label:n.label,subLabel:i,value:!!r,disabled:s,onValueChange:function(l){e.storage.options[t]=l,e.restart()}}):n.type==="button"?a.React.createElement(F,{label:n.label,subLabel:i,disabled:s,onPress:function(){return n.action.call(e)}}):a.React.createElement(F,{label:n.label,subLabel:[i,r].filter(Boolean).join(" - "),disabled:s,onPress:function(){const l=n.choices.indexOf(r);e.storage.options[t]=n.choices[(l+1)%n.choices.length],e.restart()}})}function Xe({module:e}){e.useRefresh();const t=Object.entries(e.errors);return a.React.createElement(Je,{title:e.label},a.React.createElement(Y,{label:"Enabled",subLabel:e.meta.sublabel,value:!!e.storage.enabled,onValueChange:function(){return e.toggle()}}),e.storage.enabled&&Object.keys(e.settings).map(function(n){return a.React.createElement(Qe,{key:n,module:e,settingKey:n})}),t.length>0&&a.React.createElement(F,{label:`${t.length} error${t.length===1?"":"s"} - tap to copy`,onPress:function(){const n=t.map(function([r,i]){return`[${e.label}] ${r} +(function(S,g,o,a,u,H,h,R,b,w){"use strict";function I(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function N(e,t){for(var n=0;nt&&(n.message.communicationDisabled=!0)}}))},onStop(){}}});const he=o.findByStoreName("ThemeStore"),be=o.find(function(e){return e?.default?.internal?.resolveSemanticColor})?.default?.internal?.resolveSemanticColor??o.find(function(e){return e?.meta?.resolveSemanticColor})?.meta?.resolveSemanticColor??function(){};function O(e,t=he?.theme){if(e)try{return be(t,e)}catch{return}}const{View:ye,Text:pe}=a.ReactNative,V={destructive:{bg:"#F23F42",fg:"#FFFFFF"},default:{bg:"#4E5058",fg:"#FFFFFF"}};function ve({variant:e="default",children:t}){const n=V[e]??V.default;return a.React.createElement(ye,{style:{backgroundColor:n.bg,borderRadius:4,paddingHorizontal:4,paddingVertical:1,marginLeft:4,alignSelf:"center"}},a.React.createElement(pe,{style:{color:n.fg,fontSize:10,fontWeight:"700",textTransform:"uppercase"}},t))}var Se="f47fd463dcaac61e.png",Re="f944dbd033a60207.png",we="88eacd3588829ded.png",Ee="4d1aef97fe869aaf.png",ke="3a73d84a21043a5e.png",me="8b628d7e3fc05957.png",Fe="cb7a2c9b3fb9561c.png",$e="11d89273b5bd6cc6.png",Te="ea31146eb15fdde7.png",Ae="b0d124bd12658047.png",Ie="cb8b45023e70bb61.png",Ne="a738efc867a225ee.png",Ce="cba17334eeaf3198.png",Be="fead9e69933db668.png",Le="fead9e69933db668.png",xe="d6a4e512cdcf1078.png",De="9901722947705011.png",Pe=function(e){return e.Lock="Lock",e.Warning="Warning",e.Controller="Controller",e}(Pe||{});function Me(e,t){if(e==="Lock")return t?Te:$e;if(e==="Warning")return t?De:xe;if(e==="Controller")return we}const Ue={Lock:["#f0b232","STATUS_WARNING"],Warning:["#f23f43","STATUS_DANGER"],Controller:["#23a55a","STATUS_POSITIVE"]},_e=[{name:"Announcements",kind:"Lock",base:Se},{name:"Announcements",kind:"Warning",base:Re},{name:"Text",kind:"Lock",base:Ne},{name:"Text",kind:"Warning",base:Ce},{name:"Text",kind:"Controller",base:Ie},{name:"Voice",kind:"Lock",base:Be},{name:"Voice",kind:"Warning",base:Le},{name:"Forum",kind:"Lock",base:Ee},{name:"Forum",kind:"Warning",base:ke},{name:"Stage",kind:"Lock",bottom:!0,base:Ae},{name:"Stage",kind:"Warning",bottom:!0,base:0},{name:"Image",kind:"Lock",bottom:!0,base:me},{name:"Image",kind:"Warning",bottom:!0,base:Fe}],W=o.findByName("ChannelInfo",!1),j=o.findByProps("BaseChannelIcon");var Oe=new d({id:"colorful-channels",label:"Colorful Channels",meta:{sublabel:"Gives channel icons with symbols colors to make them more aesthetically pleasing",category:c.Useful},settings:{nsfwTag:{label:"NSFW tag",subLabel:"Adds a red NSFW tag next to channel names",type:"toggle",default:!0},colorIcons:{label:"Colored icon symbols",subLabel:"Turns locked channel symbols yellow, NSFW channel symbols red",type:"toggle",default:!0},colorIconsFallback:{label:"Fallback colors for colored icon symbols",subLabel:"Uses yellow, red and green colors regardless of theme",type:"toggle",default:!1}},handlers:{onStart(){var e=this;this.storage.options.nsfwTag&&W&&this.patches.add(u.after("default",W,function([{channel:t}],n){return a.React.createElement(a.React.Fragment,{},t?.nsfw_&&a.React.createElement(ve,{variant:"destructive"},"nsfw"),n)})),this.storage.options.colorIcons&&j?.BaseChannelIcon&&this.patches.add(u.after("BaseChannelIcon",j,function([{source:t,style:n}],r){try{const i=typeof t?.original=="number"?b.getAssetByID(t.original)?.name:typeof t=="number"?b.getAssetByID(t)?.name:null;if(!i)return;const s=_e.find(function(G){return i===`${G.name}${G.kind}Icon`});if(!s)return;const[l,T]=Ue[s.kind],A=Me(s.kind,s.bottom),f=r?.props?.color?.replace(/-/g,"_")?.toUpperCase(),nt=f&&w.semanticColors?.[f]?O(w.semanticColors[f]):void 0,z=a.ReactNative.StyleSheet.flatten([n,r?.props?.style,{width:18,height:18,tintColor:nt}]),at=e.storage.options.colorIconsFallback?l:O(w.semanticColors?.[T])??l;return a.React.createElement(a.ReactNative.View,{},a.React.createElement(a.ReactNative.Image,{style:z,source:s.base}),a.React.createElement(a.ReactNative.View,{style:{position:"absolute",right:0,bottom:0}},a.React.createElement(a.ReactNative.Image,{style:{...z,tintColor:at},source:A})))}catch{return}}))},onStop(){}}});const Ve=o.findByProps("DeveloperMode","DarkSidebar");var We=new d({id:"enforce-developer-mode",label:"Enforce Developer Mode",meta:{sublabel:"Keeps Developer Mode switched on - it tends to reset itself on Revenge-based clients",category:c.Fixes},handlers:{onStart(){const e=Ve?.DeveloperMode;if(!e?.getSetting||!e?.updateSetting)return;const t=function(){try{e.getSetting()||e.updateSetting(!0)}catch{}};t(),this.patches.add(p("USER_SETTINGS_PROTO_UPDATE",t));const n=setInterval(t,5e3);this.patches.add(function(){return clearInterval(n)})},onStop(){}}}),F=[ne,ae,de,ge,Oe,We];const{ScrollView:je,View:Ye}=a.ReactNative;function ze({children:e}){return a.React.createElement(je,{style:{flex:1}},e,a.React.createElement(Ye,{style:{height:24}}))}const{View:Ge,Text:He}=a.ReactNative;function Ke({children:e,style:t}){return a.React.createElement(Ge,{style:[{marginHorizontal:16,marginVertical:8,padding:10,borderRadius:8,borderWidth:1,borderColor:"rgba(128,128,128,0.25)"},t]},a.React.createElement(He,{style:{fontSize:12.5,lineHeight:18,opacity:.75}},e))}const{FormSection:Je,FormSwitchRow:Y,FormRow:$}=R.Forms;function qe(e,t){return typeof e.subLabel=="function"?e.subLabel(t):e.subLabel}function Qe({module:e,settingKey:t}){const n=e.settings[t];if(n.predicate&&!n.predicate.call(e))return null;const r=e.storage.options[t],i=qe(n,r),s=!e.storage.enabled;return n.type==="toggle"?a.React.createElement(Y,{label:n.label,subLabel:i,value:!!r,disabled:s,onValueChange:function(l){e.storage.options[t]=l,e.restart()}}):n.type==="button"?a.React.createElement($,{label:n.label,subLabel:i,disabled:s,onPress:function(){return n.action.call(e)}}):a.React.createElement($,{label:n.label,subLabel:[i,r].filter(Boolean).join(" - "),disabled:s,onPress:function(){const l=n.choices.indexOf(r);e.storage.options[t]=n.choices[(l+1)%n.choices.length],e.restart()}})}function Xe({module:e}){e.useRefresh();const t=Object.entries(e.errors);return a.React.createElement(Je,{title:e.label},a.React.createElement(Y,{label:"Enabled",subLabel:e.meta.sublabel,value:!!e.storage.enabled,onValueChange:function(){return e.toggle()}}),e.storage.enabled&&Object.keys(e.settings).map(function(n){return a.React.createElement(Qe,{key:n,module:e,settingKey:n})}),t.length>0&&a.React.createElement($,{label:`${t.length} error${t.length===1?"":"s"} - tap to copy`,onPress:function(){const n=t.map(function([r,i]){return`[${e.label}] ${r} ${i}`}).join(` -`);a.clipboard.setString(n),h.showToast("Copied - paste this when reporting the issue",void 0)}}))}const Ze=[c.Useful,c.Fixes,c.Fun];function et(){return a.React.createElement(ze,null,a.React.createElement(Ke,null,"RoseUtils is a collection of small, independent utilities - toggle whichever ones you want. Fork of nexpid's NexxUtils, with fixes for lookups that broke on newer Discord versions. If a module shows an error below, tap it to copy the details for a bug report."),Ze.flatMap(function(e){return $.filter(function(t){return t.meta.category===e}).map(function(t){return a.React.createElement(Xe,{key:t.id,module:t})})}))}var tt={onLoad(){y.modules??={};for(const e of $)try{e.storage.enabled&&e.start()}catch(t){g.logger.error(`[RoseUtils] Failed to start "${e.label}" on load: ${t}`)}},onUnload(){for(const e of $)try{e.stop()}catch(t){g.logger.error(`[RoseUtils] Failed to stop "${e.label}" cleanly: ${t}`)}},settings:et};return S.default=tt,Object.defineProperty(S,"__esModule",{value:!0}),S})({},vendetta,vendetta.metro,vendetta.metro.common,vendetta.patcher,vendetta.plugin,vendetta.ui.toasts,vendetta.ui.components,vendetta.ui.assets,vendetta.ui); +`);a.clipboard.setString(n),h.showToast("Copied - paste this when reporting the issue",void 0)}}))}const Ze=[c.Useful,c.Fixes,c.Fun];function et(){return a.React.createElement(ze,null,a.React.createElement(Ke,null,"RoseUtils is a collection of small, independent utilities - toggle whichever ones you want. Fork of nexpid's NexxUtils, with fixes for lookups that broke on newer Discord versions. If a module shows an error below, tap it to copy the details for a bug report."),Ze.flatMap(function(e){return F.filter(function(t){return t.meta.category===e}).map(function(t){return a.React.createElement(Xe,{key:t.id,module:t})})}))}var tt={onLoad(){y.modules??={};for(const e of F)try{e.storage.enabled&&e.start()}catch(t){g.logger.error(`[RoseUtils] Failed to start "${e.label}" on load: ${t}`)}},onUnload(){for(const e of F)try{e.stop()}catch(t){g.logger.error(`[RoseUtils] Failed to stop "${e.label}" cleanly: ${t}`)}},settings:et};return S.default=tt,Object.defineProperty(S,"__esModule",{value:!0}),S})({},vendetta,vendetta.metro,vendetta.metro.common,vendetta.patcher,vendetta.plugin,vendetta.ui.toasts,vendetta.ui.components,vendetta.ui.assets,vendetta.ui); diff --git a/rose-utils/install/manifest.json b/rose-utils/install/manifest.json index d7aa4a7..8757ed1 100644 --- a/rose-utils/install/manifest.json +++ b/rose-utils/install/manifest.json @@ -1 +1 @@ -{"name":"RoseUtils","description":"A small collection of independent utilities - Spotify listen-along, a Tenor download fix, colorful channel icons, and more. Fork of nexpid's NexxUtils.","authors":[{"name":"everestmcarthur"},{"name":"nexpid"}],"main":"index.js","hash":"54b0f23d30bed6575a7bf8fac7d58655e055c31a05225b49d6e2ee06b545d8f0"} \ No newline at end of file +{"name":"RoseUtils","description":"A small collection of independent utilities - Spotify listen-along, a Tenor download fix, colorful channel icons, and more. Fork of nexpid's NexxUtils.","authors":[{"name":"everestmcarthur"},{"name":"nexpid"}],"main":"index.js","hash":"fa54bc3e77dd332fd3e3d859268a4a79b26bae320c19a26e0c6eb148c57398e0"} \ No newline at end of file diff --git a/server-drawer/install/index.js b/server-drawer/install/index.js index 8998e85..a266e79 100644 --- a/server-drawer/install/index.js +++ b/server-drawer/install/index.js @@ -1 +1 @@ -(function(Q,Z,f,i,a,n,o,$,M,N,v,Xe){"use strict";function Je(e){const t=i.findByProps("useIsMobileQuestDockRendered");if(!t?.useIsMobileQuestDockRendered)return!1;const r=t.useIsMobileQuestDockRendered;return t.useIsMobileQuestDockRendered=function(...s){return r.apply(this,s),!0},e.push(function(){t.useIsMobileQuestDockRendered=r}),!0}function Ke(e){const t=i.findByProps("useIsMobileQuestDockRenderedBase");if(!t?.useIsMobileQuestDockRenderedBase)return!1;const r=t.useIsMobileQuestDockRenderedBase;return t.useIsMobileQuestDockRenderedBase=function(...s){return r.apply(this,s),!0},e.push(function(){t.useIsMobileQuestDockRenderedBase=r}),!0}function Ye(e){const t=i.findByProps("useMobileQuestDock");if(!t?.useMobileQuestDock)return!1;const r=t.useMobileQuestDock;return t.useMobileQuestDock=function(...s){return r.apply(this,s)||{id:"server-drawer",config:{quest_content_type:0,assets:{questBarHeroVideo:null,questBarHero:null},features:[]},userStatus:{enrolledAt:"2099-01-01",claimedAt:null},benefits:{rewards:[]},guildId:"0",tasks:[]}},e.push(function(){t.useMobileQuestDock=r}),!0}const Ze="[ServerDrawer]";function $e(e){const t=i.findByProps("getQuestAsset");if(!t?.getQuestAsset)return console.log(Ze,"WARN: getQuestAsset not found"),!1;const r=t.getQuestAsset;return t.getQuestAsset=function(...s){try{return r.apply(this,s)}catch{return{url:null,isAnimated:!1}}},e.push(function(){t.getQuestAsset=r}),!0}function E(e){let t,r=!1;return function(){if(r)return t;const s=e();return s!=null&&(t=s,r=!0),s??void 0}}const he=i.findByStoreName("GuildStore"),Ne=i.findByProps("useStateFromStores"),et=i.findByProps("colors","unsafe_rawColors")?.colors;function ge({id:e,size:t=48}){const r=Ne?.useStateFromStores?.([he],function(){return he?.getGuild?.(e)},[e])??null;if(!r)return null;const s=t>=40?16:8;return r.icon?n.createElement(o.Image,{source:{uri:`https://cdn.discordapp.com/icons/${r.id}/${r.icon}.png?size=${t*2}`},style:{width:t,height:t,borderRadius:s}}):n.createElement(o.View,{style:[pe.fallback,{width:t,height:t,borderRadius:s,backgroundColor:et?.BG_ACCENT??"#5865f2"}]},n.createElement(o.Text,{style:[pe.letter,{fontSize:Math.max(10,t*.4)}]},r.name?.split(" ").map(function(l){return l[0]}).join("").slice(0,2).toUpperCase()||"?"))}const pe=o.StyleSheet.create({fallback:{alignItems:"center",justifyContent:"center"},letter:{color:"#fff",fontWeight:"700"}}),tt=i.findByStoreName("ThemeStore"),nt=i.find(function(e){return e?.default?.internal?.resolveSemanticColor})?.default?.internal?.resolveSemanticColor??i.find(function(e){return e?.meta?.resolveSemanticColor})?.meta?.resolveSemanticColor??function(){};function rt(e,t=tt?.theme){if(e)try{return nt(t,e)}catch{return}}const ye=i.findByProps("TextStyleSheet")?.TextStyleSheet,me=i.findByProps("triggerHapticFeedback","HapticFeedbackTypes");function L(e,t){return rt(e)??t}const I=12,ee=12,be=42,te=220,Se=4,A=16,O=20,Ce={tension:200,friction:20};function ot({visible:e,items:t,title:r,anchorX:s,anchorY:l,onClose:u}){const{width:d,height:R}=o.Dimensions.get("window"),B=(r?ee+20+Se:0)+t.length*be;let b=s,p=l+48+10;b+te>d-I&&(b=d-te-I),bR-I&&(p=l-B-10),p0?n.createElement(o.View,{style:T.outline},n.createElement(o.View,{style:T.badge},n.createElement(o.Text,{style:T.text},t>99?"99+":String(t)))):r?n.createElement(o.View,{style:T.dotOutline},n.createElement(o.View,{style:T.dot})):null:null}function we({node:e,onPick:t}){const r=n.useRef(null),s=n.useRef(new o.Animated.Value(1)).current,l=function(){return o.Animated.spring(s,{toValue:.85,useNativeDriver:!0}).start()},u=function(){return o.Animated.spring(s,{toValue:1,useNativeDriver:!0}).start()},[d,R]=n.useState({visible:!1,items:[],title:"",x:0,y:0}),B=n.useCallback(function(){const D=e.id,c=st?.getGuild?.(D),g=i.find(function(y){return y?.default?.name==="getGuildsBarGuildMenuItems"})?.default??i.find(function(y){return typeof y?.default=="function"&&y.default.length<=2&&/guild/i.test(y.default.name??"")})?.default;if(!c||!g)return;const x=it?.getGuildsTree?.()?.version,P=g(D,x);if(!P?.length)return;const F=r.current;F?.measure&&F.measure(function(y,ue,ce,V,H,S){R({visible:!0,items:P.map(function(C){return{label:C.label??C.title??"Unknown",action:C.action,danger:C.variant==="destructive",iconSource:C.iconSource,IconComponent:C.IconComponent}}),title:c.name,x:H,y:S})})},[e.id]),b=n.useCallback(function(){ke?.triggerHapticFeedback?.(ke.HapticFeedbackTypes.IMPACT_MEDIUM),B()},[B]),p=e.id;return n.createElement(n.Fragment,null,n.createElement(o.Pressable,{onPressIn:l,onPressOut:u,onPress:function(){return t(p)},onLongPress:b,delayLongPress:500},n.createElement(o.View,{ref:r,style:Re.outer,collapsable:!1},n.createElement(o.Animated.View,{style:[Re.icon,{transform:[{scale:s}]}]},n.createElement(ge,{id:p})),n.createElement(lt,{guildId:p}))),n.createElement(ot,{visible:d.visible,items:d.items,title:d.title,anchorX:d.x,anchorY:d.y,onClose:function(){return R(function(D){return{...D,visible:!1}})}}))}const Re=o.StyleSheet.create({outer:{width:j,height:j},icon:{width:j,height:j,borderRadius:16,overflow:"hidden"}}),T=o.StyleSheet.create({outline:{position:"absolute",bottom:-3,right:-3,minWidth:23,minHeight:23,borderRadius:12,backgroundColor:"#1a1a2e",alignItems:"center",justifyContent:"center"},badge:{minWidth:19,height:19,borderRadius:9,backgroundColor:"#ed4245",alignItems:"center",justifyContent:"center",paddingHorizontal:5},text:{color:"#fff",fontSize:10,fontWeight:"700",lineHeight:19},dotOutline:{position:"absolute",bottom:-2,right:-2,width:14,height:14,borderRadius:7,backgroundColor:"#1a1a2e",alignItems:"center",justifyContent:"center"},dot:{width:10,height:10,borderRadius:5,backgroundColor:"#ed4245"}}),at=i.findByProps("useStateFromStores");i.findByProps("colors","unsafe_rawColors")?.colors;const Be=i.findByStoreName("ExpandedGuildFolderStore");function ut(e){return at?.useStateFromStores?.([Be],function(){const t=Be?.getExpandedFolders?.();return t instanceof Set?t.has(e):!1},[e])??!1}const ct=i.findByProps("toggleGuildFolderExpand"),dt=i.findByProps("useStateFromStores"),De=i.findByStoreName("GuildReadStateStore"),k=48,re=16,ft=[{top:6,left:6},{top:6,right:6},{bottom:6,left:6},{bottom:6,right:6}],Ie=N.getAssetIDByName("FolderIcon");function Pe(e){return e==null?"#5865f2":`#${e.toString(16).padStart(6,"0")}`}function ht({node:e}){const t=dt?.useStateFromStores?.([De],function(){let r=0;for(const s of e.children)r+=De?.getMentionCount?.(s.id)??0;return r},[e.children])??0;return t>0?n.createElement(o.View,{style:se.outline},n.createElement(o.View,{style:se.badge},n.createElement(o.Text,{style:se.text},t>99?"99+":String(t)))):null}function gt({node:e}){$.useProxy(f.storage);const t=Pe(e.color);return n.createElement(o.View,{style:z.outer},n.createElement(o.View,{style:[z.icon,{backgroundColor:t}]},f.storage.hideFolderIcons?n.createElement(o.View,{style:z.plainIcon},n.createElement(o.Image,{source:Ie,style:oe.folderImg,tintColor:"#fff"})):e.children.slice(0,4).map(function(r,s){return n.createElement(o.View,{key:r.id,style:[z.cell,ft[s]]},n.createElement(ge,{id:r.id,size:re}))})),n.createElement(ht,{node:e}))}const z=o.StyleSheet.create({outer:{width:k,height:k},icon:{width:k,height:k,borderRadius:16,overflow:"hidden"},cell:{position:"absolute",width:re,height:re,borderRadius:8,overflow:"hidden"},plainIcon:{width:k,height:k,alignItems:"center",justifyContent:"center"}});function pt({children:e}){const t=n.useRef(new o.Animated.Value(0)).current;return n.useEffect(function(){o.Animated.timing(t,{toValue:1,duration:180,useNativeDriver:!0}).start()},[]),n.createElement(o.Animated.View,{style:{opacity:t}},e)}function yt({node:e,onPick:t}){const r=ut(e.id),s=function(){ct?.toggleGuildFolderExpand?.(e.id)};return r?n.createElement(n.Fragment,null,n.createElement(o.Pressable,{onPress:s},n.createElement(o.View,{style:[oe.openIcon,{backgroundColor:Pe(e.color)}]},n.createElement(o.Image,{source:Ie,style:oe.folderImg,tintColor:"#fff"}))),e.children.map(function(l){return n.createElement(pt,{key:l.id},n.createElement(we,{node:l,onPick:t}))})):n.createElement(o.Pressable,{onPress:s},n.createElement(gt,{node:e}))}const oe=o.StyleSheet.create({openIcon:{width:k,height:k,borderRadius:16,alignItems:"center",justifyContent:"center"},folderImg:{width:24,height:24}}),se=o.StyleSheet.create({outline:{position:"absolute",bottom:-3,right:-3,minWidth:23,minHeight:23,borderRadius:12,backgroundColor:"#1a1a2e",alignItems:"center",justifyContent:"center"},badge:{minWidth:19,height:19,borderRadius:9,backgroundColor:"#ed4245",alignItems:"center",justifyContent:"center",paddingHorizontal:5},text:{color:"#fff",fontSize:10,fontWeight:"700",lineHeight:19}}),W=48,mt=N.getAssetIDByName("ChatIcon"),Fe=i.findByProps("triggerHapticFeedback","HapticFeedbackTypes"),xe=i.findByProps("selectPrivateChannel"),bt=i.findByName("SelectedChannelStore"),St=i.findByProps("useStateFromStores"),Ae=i.findByProps("getGuildId"),Ct=i.findByProps("colors","unsafe_rawColors")?.colors;function Et(){if(Fe?.triggerHapticFeedback(Fe.HapticFeedbackTypes.SOFT),xe?.selectPrivateChannel){const e=bt?.getLastSelectedChannelId?.();xe.selectPrivateChannel(e)}}function kt(){const e=St?.useStateFromStores?.([Ae],function(){return Ae?.getGuildId?.()==null})??!1;return n.createElement(o.Pressable,{onPress:Et,style:Te.outer},n.createElement(o.View,{style:[Te.icon,{backgroundColor:e?Ct?.BG_ACCENT??"#5865f2":"rgba(128,128,128,0.24)"}]},n.createElement(o.Image,{source:mt,style:{width:24,height:24,tintColor:"#fff"}})))}const Te=o.StyleSheet.create({outer:{width:W,height:W},icon:{width:W,height:W,borderRadius:16,alignItems:"center",justifyContent:"center"}}),Ge=48,wt=N.getAssetIDByName("CheckmarkLargeIcon"),Rt=i.findByStoreName("SortedGuildStore"),U=i.findByStoreName("GuildChannelStore"),Bt=i.findByStoreName("ChannelStore"),Dt=E(function(){return i.findByProps("triggerHapticFeedback","HapticFeedbackTypes")}),It=E(function(){return i.findByProps("bulkAck","ackChannel")}),Pt=E(function(){return i.findByProps("ReadStateTypes","UnreadSetting")?.ReadStateTypes});function Ft(){const e=(Rt?.getGuildsTree?.()?.root?.children??[]).filter(function(s){return s?.type!=="root"}),t=[],r=function(s){for(const l of s)l.type==="folder"?r(l.children??[]):l.id!=null&&t.push(String(l.id))};return r(e),t}function xt(){const e=It(),t=Pt();if(!e?.bulkAck||t?.CHANNEL==null||!U?.getSelectableChannelIds||!U?.getVocalChannelIds){v.showToast("Couldn't find Discord's read-state action - this may be unavailable on your version.",void 0);return}const r=Ft();if(r.length===0){v.showToast("Nothing to mark as read.",void 0);return}const s=[];for(const l of r){const u=[...U.getSelectableChannelIds(l)??[],...U.getVocalChannelIds(l)??[]];for(const d of u)s.push({channelId:d,readStateType:t.CHANNEL,messageId:Bt?.getChannel?.(d)?.lastMessageId??null})}if(s.length===0){v.showToast("Nothing to mark as read.",void 0);return}e.bulkAck(s),v.showToast(`Marked ${s.length} channel${s.length===1?"":"s"} as read`,void 0)}function At(){const e=n.useCallback(function(){const t=Dt();t?.triggerHapticFeedback?.(t.HapticFeedbackTypes.SOFT),xt()},[]);return n.createElement(o.Pressable,{onPress:e,style:Tt.outer},n.createElement(o.Image,{source:wt,style:{width:24,height:24,tintColor:"#80848e"}}))}const Tt=o.StyleSheet.create({outer:{width:Ge,height:Ge,alignItems:"center",justifyContent:"center"}}),Gt=i.findByProps("useStateFromStores"),Ve=i.findByStoreName("SortedGuildStore"),Vt=E(function(){return i.findByProps("getRootNavigationRef")}),He=E(function(){return i.findByProps("triggerHapticFeedback","HapticFeedbackTypes")}),Ht=E(function(){return i.findByProps("transitionToGuild")}),Qt=E(function(){return i.find(function(e){return typeof e?.handleCreateJoinGuildPress=="function"})}),Mt=E(function(){return i.find(function(e){return e?.CirclePlusIcon})?.CirclePlusIcon}),vt=E(function(){return i.findByProps("colors","unsafe_rawColors")?.unsafe_rawColors}),Lt=i.find(function(e){return e?.QuestDockExternalCoordinationContext}),Qe=Lt?.QuestDockExternalCoordinationContext,Me=i.find(function(e){return e?.QuestDockMode?.COLLAPSED!=null})?.QuestDockMode,q=48,X=6,Ot=12;function jt(){const e=n.useRef(new o.Animated.Value(1)).current,t=n.useCallback(function(){o.Animated.spring(e,{toValue:.9,useNativeDriver:!0}).start()},[e]),r=n.useCallback(function(){o.Animated.spring(e,{toValue:1,useNativeDriver:!0}).start()},[e]),s=n.useCallback(function(){const d=He();d?.triggerHapticFeedback?.(d.HapticFeedbackTypes.SOFT),Qt()?.handleCreateJoinGuildPress?.()},[]),l=Mt(),u=vt();return n.createElement(o.Pressable,{onPress:s,onPressIn:t,onPressOut:r},n.createElement(o.Animated.View,{style:[J.createJoin,{backgroundColor:u?.GREEN_360,transform:[{scale:e}]}]},l?n.createElement(l,{size:"md",color:u?.WHITE}):n.createElement(o.Text,{style:[J.createJoinFallback,{color:u?.WHITE}]},"+")))}function ve({gestureContext:e}){const t=n.useCallback(function(c){const g=He();g?.triggerHapticFeedback?.(g.HapticFeedbackTypes.SOFT);const x=Ht();x?.transitionToGuild?x.transitionToGuild(c):Vt()?.getRootNavigationRef?.()?.navigate("guilds",{guildId:c})},[]),r=Gt?.useStateFromStores?.([Ve],function(){return(Ve?.getGuildsTree()?.root?.children||[]).filter(function(c){return c.type!=="root"})})??[],s=e?n.useContext(e):null,l=s?.minExpandedContentHeight,u=n.useCallback(function(c){if(!l)return;const g=c.nativeEvent.layout.height;l.get()!==g&&l.set(g)},[l]),d=(Qe?n.useContext(Qe):null)?.setRestingQuestDockMode,R=s?.questDockWrapperSpecs;n.useEffect(function(){if(!d||!Me||!R)return;const c=o.BackHandler.addEventListener("hardwareBackPress",function(){return(R.get()?.height??56)>80?(d(Me.COLLAPSED),!0):!1});return function(){return c.remove()}},[d,R]);const{width:B}=o.Dimensions.get("window"),b=Math.max(3,Math.floor((B-Ot*2+X)/(q+X))),p=b*q+(b-1)*X,D=Math.max(0,(B-p)/2);return n.createElement(o.View,{style:J.alignTop},n.createElement(o.View,{style:[J.grid,{paddingHorizontal:D,gap:X}],onLayout:u},n.createElement(kt,null),r.map(function(c){return c.type==="folder"?n.createElement(yt,{key:c.id,node:c,onPick:t}):n.createElement(we,{key:c.id,node:c,onPick:t})}),n.createElement(jt,null),n.createElement(At,null)))}const J=o.StyleSheet.create({alignTop:{flex:1,justifyContent:"flex-start",alignItems:"flex-start"},grid:{flexDirection:"row",flexWrap:"wrap",paddingTop:4,paddingBottom:16},createJoin:{width:q,height:q,borderRadius:16,alignItems:"center",justifyContent:"center"},createJoinFallback:{fontSize:28,fontWeight:"700",lineHeight:30}}),ie=new Map;let w=null,K=!1;function Le(e,t,r){ie.set(e,{replacement:t,extraProps:r})}function _t(e){if(K)return;if(w=a.React.createElement,!w){console.warn("[ServerDrawer] React.createElement is null, skipping patch");return}const t=function(r,s,...l){if(!w)return a.React.createElement(r,s,...l);const u=ie.get(r);if(u){const d=u.extraProps?{...s,...u.extraProps}:s;return w.call(a.React,u.replacement,d,...l)}return w.call(a.React,r,s,...l)};Object.assign(t,w),a.React.createElement=t,K=!0,e.push(function(){K&&w&&(a.React.createElement=w,K=!1),ie.clear()})}const le="[ServerDrawer]";let ae=null;function Oe(){return ae||(ae=i.find(function(e){return e?.QuestDockGestureContext})?.QuestDockGestureContext??null),ae}function zt(e){const t=i.find(function(s){return s?.type?.displayName==="QuestDockContentExpanded"||s?.type?.name==="QuestDockContentExpanded"});if(!t?.type)return console.log(le,"WARN: QuestDockContentExpanded not found (will retry)"),!1;const r=t.type;return Le(r,ve,{gestureContext:Oe()}),t.type=function(){return a.React.createElement(ve,{gestureContext:Oe()})},e.push(function(){t.type=r}),console.log(le,"PATCH: QuestDockContentExpanded replaced"),!0}function G(e,t){const r=i.find(function(u){return u?.type?.displayName===e||u?.type?.name===e});if(!r?.type)return console.log(le,`WARN: ${e} not found`),!1;const s=r.type,l=s;return r.type=function(){return null},l&&(Object.defineProperties(r.type,Object.getOwnPropertyDescriptors(l)),r.type.displayName=e),t.push(function(){r.type=s}),!0}const Wt="[ServerDrawer]";function je(){return null}function Ut(){const e=i.findByName("GuildsBar");if(e)return{default:e};let t=i.find(function(r){try{return r?.default?.type?.name==="GuildsBar"}catch{return!1}});return t?.default||(t=i.find(function(r){try{return r?.default?.displayName==="GuildsBar"}catch{return!1}}),t?.default)?t:null}function qt(e){const t=Ut();if(!t?.default)return console.log(Wt,"WARN: GuildsBar not found"),!1;const r=t.default;return Le(r,je),t.default=function(){return n.createElement(je)},t.default.displayName="GuildsBar",e.push(function(){t.default=r}),!0}function Xt(e){const t=i.findByStoreName("ExpandedGuildFolderStore");if(!t?.getExpandedFolders)return!1;const r=function({folderId:s}){if(!f.storage.autoCollapseFolders||s==null)return;const l=t.getExpandedFolders();if(!(!(l instanceof Set)||!l.has(s)))for(const u of l)u!==s&&a.FluxDispatcher.dispatch({type:"TOGGLE_GUILD_FOLDER_EXPAND",folderId:u})};return a.FluxDispatcher.subscribe("TOGGLE_GUILD_FOLDER_EXPAND",r),e.push(function(){return a.FluxDispatcher.unsubscribe("TOGGLE_GUILD_FOLDER_EXPAND",r)}),!0}const{ScrollView:Jt,View:Kt}=a.ReactNative;function Yt({children:e}){return a.React.createElement(Jt,{style:{flex:1}},e,a.React.createElement(Kt,{style:{height:24}}))}const{View:Zt,Text:$t}=a.ReactNative;function _e({children:e,style:t}){return a.React.createElement(Zt,{style:[{marginHorizontal:16,marginVertical:8,padding:10,borderRadius:8,borderWidth:1,borderColor:"rgba(128,128,128,0.25)"},t]},a.React.createElement($t,{style:{fontSize:12.5,lineHeight:18,opacity:.75}},e))}const{FormSection:ze,FormSwitchRow:Y}=Xe.Forms;function Nt(){return $.useProxy(f.storage),a.React.createElement(Yt,null,a.React.createElement(_e,null,"Server Drawer takes over the Quest Dock (the strip above the tab bar) to show your servers as a grid instead - tap to expand, long-press a server for its usual context menu, the chat bubble jumps to DMs, the + button creates or joins a server through Discord's own modal, and the check button marks every channel in every server as read."),a.React.createElement(ze,{title:"Layout"},a.React.createElement(Y,{label:"Hide the left server rail",subLabel:"Your servers and DMs already live in the drawer, so the rail is redundant",value:f.storage.hideGuildsBar!==!1,onValueChange:function(e){f.storage.hideGuildsBar=e,qe()}}),a.React.createElement(Y,{label:"Unread badges",subLabel:"Show mention counts and unread dots on server icons in the drawer",value:f.storage.showUnreadBadges!==!1,onValueChange:function(e){f.storage.showUnreadBadges=e}})),a.React.createElement(ze,{title:"Folders"},a.React.createElement(Y,{label:"Auto-collapse other folders",subLabel:"Opening a folder collapses any other folder that was already open",value:!!f.storage.autoCollapseFolders,onValueChange:function(e){f.storage.autoCollapseFolders=e}}),a.React.createElement(Y,{label:"Hide icons in collapsed folders",subLabel:"Show a plain folder icon instead of a 4-server preview",value:!!f.storage.hideFolderIcons,onValueChange:function(e){f.storage.hideFolderIcons=e}})),a.React.createElement(_e,null,"The folder options above are ported from fres621's BetterFolders - its other half (hiding icons in the native left server rail) patched a component that no longer exists in current Discord builds, so it's been rebuilt here instead, where it actually applies to what you see."))}let h=[],m;function en(e,t){try{return t()}catch(r){return Z.logger.error(`[ServerDrawer] "${e}" patch threw, skipping: ${r}`),!1}}function We(){const e={questDockRender:function(){return Je(h)},questDockBase:function(){return Ke(h)},mobileQuestDock:function(){return Ye(h)},getQuestAsset:function(){return $e(h)},expanded:function(){return zt(h)},collapsed:function(){return G("QuestDockContentCollapsed",h)},enrolledHeader:function(){return G("QuestDockEnrolledHeader",h)},unenrolledHeader:function(){return G("QuestDockUnenrolledHeader",h)},enrolledBody:function(){return G("QuestDockEnrolledBody",h)},unenrolledBody:function(){return G("QuestDockUnenrolledBody",h)},autoCollapseFolders:function(){return Xt(h)},...f.storage.hideGuildsBar?{hideGuildsBar:function(){return qt(h)}}:{}};_t(h);const t=new Set(Object.keys(e)),r=new Set,s=function(){for(const l of t)en(l,e[l])&&(r.add(l),t.delete(l));t.size===0&&m&&(clearInterval(m),m=void 0)};if(s(),t.size>0){let l=0;m=setInterval(function(){s(),++l>=50&&m&&(clearInterval(m),m=void 0,t.size>0&&Z.logger.error(`[ServerDrawer] Gave up waiting on: ${[...t].join(", ")}`))},200)}Z.logger.log(`[ServerDrawer] onLoad: applied immediately - ${[...r].join(", ")||"none"}${t.size?`, still waiting on ${[...t].join(", ")}`:""}`)}function Ue(){m&&(clearInterval(m),m=void 0);for(const e of h)try{e()}catch{}h=[]}function qe(){Ue(),We()}var tn={onLoad:function(){f.storage.hideGuildsBar??=!0,f.storage.showUnreadBadges??=!0,f.storage.autoCollapseFolders??=!1,f.storage.hideFolderIcons??=!1,We()},onUnload:function(){return Ue()},settings:Nt};return Q.default=tn,Q.restart=qe,Object.defineProperty(Q,"__esModule",{value:!0}),Q})({},vendetta,vendetta.plugin,vendetta.metro,vendetta.metro.common,window.React,vendetta.metro.common.ReactNative,vendetta.storage,vendetta.ui,vendetta.ui.assets,vendetta.ui.toasts,vendetta.ui.components); +(function(G,K,f,i,a,n,r,Z,k,Q,$,Je){"use strict";function Xe(e){const t=i.findByProps("useIsMobileQuestDockRendered");if(!t?.useIsMobileQuestDockRendered)return!1;const o=t.useIsMobileQuestDockRendered;return t.useIsMobileQuestDockRendered=function(...s){return o.apply(this,s),!0},e.push(function(){t.useIsMobileQuestDockRendered=o}),!0}function Ye(e){const t=i.findByProps("useIsMobileQuestDockRenderedBase");if(!t?.useIsMobileQuestDockRenderedBase)return!1;const o=t.useIsMobileQuestDockRenderedBase;return t.useIsMobileQuestDockRenderedBase=function(...s){return o.apply(this,s),!0},e.push(function(){t.useIsMobileQuestDockRenderedBase=o}),!0}function Ke(e){const t=i.findByProps("useMobileQuestDock");if(!t?.useMobileQuestDock)return!1;const o=t.useMobileQuestDock;return t.useMobileQuestDock=function(...s){return o.apply(this,s)||{id:"server-drawer",config:{quest_content_type:0,assets:{questBarHeroVideo:null,questBarHero:null},features:[]},userStatus:{enrolledAt:"2099-01-01",claimedAt:null},benefits:{rewards:[]},guildId:"0",tasks:[]}},e.push(function(){t.useMobileQuestDock=o}),!0}const Ze="[ServerDrawer]";function $e(e){const t=i.findByProps("getQuestAsset");if(!t?.getQuestAsset)return console.log(Ze,"WARN: getQuestAsset not found"),!1;const o=t.getQuestAsset;return t.getQuestAsset=function(...s){try{return o.apply(this,s)}catch{return{url:null,isAnimated:!1}}},e.push(function(){t.getQuestAsset=o}),!0}function p(e){let t,o=!1;return function(){if(o)return t;const s=e();return s!=null&&(t=s,o=!0),s??void 0}}const pe=i.findByStoreName("GuildStore"),Ne=i.findByProps("useStateFromStores"),et=i.findByProps("colors","unsafe_rawColors")?.colors;function ye({id:e,size:t=48}){const o=Ne?.useStateFromStores?.([pe],function(){return pe?.getGuild?.(e)},[e])??null;if(!o)return null;const s=t>=40?16:8;return o.icon?n.createElement(r.Image,{source:{uri:`https://cdn.discordapp.com/icons/${o.id}/${o.icon}.png?size=${t*2}`},style:{width:t,height:t,borderRadius:s}}):n.createElement(r.View,{style:[be.fallback,{width:t,height:t,borderRadius:s,backgroundColor:et?.BG_ACCENT??"#5865f2"}]},n.createElement(r.Text,{style:[be.letter,{fontSize:Math.max(10,t*.4)}]},o.name?.split(" ").map(function(l){return l[0]}).join("").slice(0,2).toUpperCase()||"?"))}const be=r.StyleSheet.create({fallback:{alignItems:"center",justifyContent:"center"},letter:{color:"#fff",fontWeight:"700"}}),tt=i.findByStoreName("ThemeStore"),nt=i.find(function(e){return e?.default?.internal?.resolveSemanticColor})?.default?.internal?.resolveSemanticColor??i.find(function(e){return e?.meta?.resolveSemanticColor})?.meta?.resolveSemanticColor??function(){};function rt(e,t=tt?.theme){if(e)try{return nt(t,e)}catch{return}}const me=i.findByProps("TextStyleSheet")?.TextStyleSheet,Se=i.findByProps("triggerHapticFeedback","HapticFeedbackTypes");function M(e,t){return rt(e)??t}const D=12,N=12,Ce=42,ee=220,Ee=4,F=16,v=20,ke={tension:200,friction:20};function ot({visible:e,items:t,title:o,anchorX:s,anchorY:l,onClose:u}){const{width:c,height:y}=r.Dimensions.get("window"),I=(o?N+20+Ee:0)+t.length*Ce;let S=s,b=l+48+10;S+ee>c-D&&(S=c-ee-D),Sy-D&&(b=l-I-10),b0?n.createElement(r.View,{style:T.outline},n.createElement(r.View,{style:T.badge},n.createElement(r.Text,{style:T.text},t>99?"99+":String(t)))):o?n.createElement(r.View,{style:T.dotOutline},n.createElement(r.View,{style:T.dot})):null:null}function Re({node:e,onPick:t}){const o=n.useRef(null),s=n.useRef(new r.Animated.Value(1)).current,l=function(){return r.Animated.spring(s,{toValue:.85,useNativeDriver:!0}).start()},u=function(){return r.Animated.spring(s,{toValue:1,useNativeDriver:!0}).start()},[c,y]=n.useState({visible:!1,items:[],title:"",x:0,y:0}),I=n.useCallback(function(){const E=e.id,d=st?.getGuild?.(E);if(!d)return;const g=o.current;if(!g?.measure)return;const B=[{label:"Mark as Read",action:function(){return ut(E)}},{label:"Copy Server ID",action:function(){a.clipboard.setString(E),k.showToast("Copied server ID",void 0)}}];g.measure(function(x,H,V,ce,Y,P){y({visible:!0,items:B,title:d.name,x:Y,y:P})})},[e.id]),S=n.useCallback(function(){Ie?.triggerHapticFeedback?.(Ie.HapticFeedbackTypes.IMPACT_MEDIUM),I()},[I]),b=e.id;return n.createElement(n.Fragment,null,n.createElement(r.Pressable,{onPressIn:l,onPressOut:u,onPress:function(){return t(b)},onLongPress:S,delayLongPress:500},n.createElement(r.View,{ref:o,style:De.outer,collapsable:!1},n.createElement(r.Animated.View,{style:[De.icon,{transform:[{scale:s}]}]},n.createElement(ye,{id:b})),n.createElement(ct,{guildId:b}))),n.createElement(ot,{visible:c.visible,items:c.items,title:c.title,anchorX:c.x,anchorY:c.y,onClose:function(){return y(function(E){return{...E,visible:!1}})}}))}const De=r.StyleSheet.create({outer:{width:L,height:L},icon:{width:L,height:L,borderRadius:16,overflow:"hidden"}}),T=r.StyleSheet.create({outline:{position:"absolute",bottom:-3,right:-3,minWidth:23,minHeight:23,borderRadius:12,backgroundColor:"#1a1a2e",alignItems:"center",justifyContent:"center"},badge:{minWidth:19,height:19,borderRadius:9,backgroundColor:"#ed4245",alignItems:"center",justifyContent:"center",paddingHorizontal:5},text:{color:"#fff",fontSize:10,fontWeight:"700",lineHeight:19},dotOutline:{position:"absolute",bottom:-2,right:-2,width:14,height:14,borderRadius:7,backgroundColor:"#1a1a2e",alignItems:"center",justifyContent:"center"},dot:{width:10,height:10,borderRadius:5,backgroundColor:"#ed4245"}}),dt=i.findByProps("useStateFromStores");i.findByProps("colors","unsafe_rawColors")?.colors;const Be=i.findByStoreName("ExpandedGuildFolderStore");function ft(e){return dt?.useStateFromStores?.([Be],function(){const t=Be?.getExpandedFolders?.();return t instanceof Set?t.has(e):!1},[e])??!1}const ht=i.findByProps("toggleGuildFolderExpand"),gt=i.findByProps("useStateFromStores"),Pe=i.findByStoreName("GuildReadStateStore"),w=48,re=16,pt=[{top:6,left:6},{top:6,right:6},{bottom:6,left:6},{bottom:6,right:6}],Fe=$.getAssetIDByName("FolderIcon");function Te(e){return e==null?"#5865f2":`#${e.toString(16).padStart(6,"0")}`}function yt({node:e}){const t=gt?.useStateFromStores?.([Pe],function(){let o=0;for(const s of e.children)o+=Pe?.getMentionCount?.(s.id)??0;return o},[e.children])??0;return t>0?n.createElement(r.View,{style:se.outline},n.createElement(r.View,{style:se.badge},n.createElement(r.Text,{style:se.text},t>99?"99+":String(t)))):null}function bt({node:e}){Z.useProxy(f.storage);const t=Te(e.color);return n.createElement(r.View,{style:j.outer},n.createElement(r.View,{style:[j.icon,{backgroundColor:t}]},f.storage.hideFolderIcons?n.createElement(r.View,{style:j.plainIcon},n.createElement(r.Image,{source:Fe,style:oe.folderImg,tintColor:"#fff"})):e.children.slice(0,4).map(function(o,s){return n.createElement(r.View,{key:o.id,style:[j.cell,pt[s]]},n.createElement(ye,{id:o.id,size:re}))})),n.createElement(yt,{node:e}))}const j=r.StyleSheet.create({outer:{width:w,height:w},icon:{width:w,height:w,borderRadius:16,overflow:"hidden"},cell:{position:"absolute",width:re,height:re,borderRadius:8,overflow:"hidden"},plainIcon:{width:w,height:w,alignItems:"center",justifyContent:"center"}});function mt({children:e}){const t=n.useRef(new r.Animated.Value(0)).current;return n.useEffect(function(){r.Animated.timing(t,{toValue:1,duration:180,useNativeDriver:!0}).start()},[]),n.createElement(r.Animated.View,{style:{opacity:t}},e)}function St({node:e,onPick:t}){const o=ft(e.id),s=function(){ht?.toggleGuildFolderExpand?.(e.id)};return o?n.createElement(n.Fragment,null,n.createElement(r.Pressable,{onPress:s},n.createElement(r.View,{style:[oe.openIcon,{backgroundColor:Te(e.color)}]},n.createElement(r.Image,{source:Fe,style:oe.folderImg,tintColor:"#fff"}))),e.children.map(function(l){return n.createElement(mt,{key:l.id},n.createElement(Re,{node:l,onPick:t}))})):n.createElement(r.Pressable,{onPress:s},n.createElement(bt,{node:e}))}const oe=r.StyleSheet.create({openIcon:{width:w,height:w,borderRadius:16,alignItems:"center",justifyContent:"center"},folderImg:{width:24,height:24}}),se=r.StyleSheet.create({outline:{position:"absolute",bottom:-3,right:-3,minWidth:23,minHeight:23,borderRadius:12,backgroundColor:"#1a1a2e",alignItems:"center",justifyContent:"center"},badge:{minWidth:19,height:19,borderRadius:9,backgroundColor:"#ed4245",alignItems:"center",justifyContent:"center",paddingHorizontal:5},text:{color:"#fff",fontSize:10,fontWeight:"700",lineHeight:19}}),_=48,Ct=$.getAssetIDByName("ChatIcon"),Ae=i.findByProps("triggerHapticFeedback","HapticFeedbackTypes"),xe=i.findByProps("selectPrivateChannel"),Et=i.findByName("SelectedChannelStore"),kt=i.findByProps("useStateFromStores"),He=i.findByProps("getGuildId"),wt=i.findByProps("colors","unsafe_rawColors")?.colors;function It(){if(Ae?.triggerHapticFeedback(Ae.HapticFeedbackTypes.SOFT),xe?.selectPrivateChannel){const e=Et?.getLastSelectedChannelId?.();xe.selectPrivateChannel(e)}}function Rt(){const e=kt?.useStateFromStores?.([He],function(){return He?.getGuildId?.()==null})??!1;return n.createElement(r.Pressable,{onPress:It,style:Ve.outer},n.createElement(r.View,{style:[Ve.icon,{backgroundColor:e?wt?.BG_ACCENT??"#5865f2":"rgba(128,128,128,0.24)"}]},n.createElement(r.Image,{source:Ct,style:{width:24,height:24,tintColor:"#fff"}})))}const Ve=r.StyleSheet.create({outer:{width:_,height:_},icon:{width:_,height:_,borderRadius:16,alignItems:"center",justifyContent:"center"}}),Ge=48,Dt=$.getAssetIDByName("CheckmarkLargeIcon"),Bt=i.findByStoreName("SortedGuildStore"),z=i.findByStoreName("GuildChannelStore"),Pt=i.findByStoreName("ChannelStore"),Ft=p(function(){return i.findByProps("triggerHapticFeedback","HapticFeedbackTypes")}),Tt=p(function(){return i.findByProps("bulkAck","ackChannel")}),At=p(function(){return i.findByProps("ReadStateTypes","UnreadSetting")?.ReadStateTypes});function xt(){const e=(Bt?.getGuildsTree?.()?.root?.children??[]).filter(function(s){return s?.type!=="root"}),t=[],o=function(s){for(const l of s)l.type==="folder"?o(l.children??[]):l.id!=null&&t.push(String(l.id))};return o(e),t}function Ht(){const e=Tt(),t=At();if(!e?.bulkAck||t?.CHANNEL==null||!z?.getSelectableChannelIds||!z?.getVocalChannelIds){k.showToast("Couldn't find Discord's read-state action - this may be unavailable on your version.",void 0);return}const o=xt();if(o.length===0){k.showToast("Nothing to mark as read.",void 0);return}const s=[];for(const l of o){const u=[...z.getSelectableChannelIds(l)??[],...z.getVocalChannelIds(l)??[]];for(const c of u)s.push({channelId:c,readStateType:t.CHANNEL,messageId:Pt?.getChannel?.(c)?.lastMessageId??null})}if(s.length===0){k.showToast("Nothing to mark as read.",void 0);return}e.bulkAck(s),k.showToast(`Marked ${s.length} channel${s.length===1?"":"s"} as read`,void 0)}function Vt(){const e=n.useCallback(function(){const t=Ft();t?.triggerHapticFeedback?.(t.HapticFeedbackTypes.SOFT),Ht()},[]);return n.createElement(r.Pressable,{onPress:e,style:Gt.outer},n.createElement(r.Image,{source:Dt,style:{width:24,height:24,tintColor:"#80848e"}}))}const Gt=r.StyleSheet.create({outer:{width:Ge,height:Ge,alignItems:"center",justifyContent:"center"}}),Qt=i.findByProps("useStateFromStores"),Qe=i.findByStoreName("SortedGuildStore"),Mt=p(function(){return i.findByProps("getRootNavigationRef")}),Me=p(function(){return i.findByProps("triggerHapticFeedback","HapticFeedbackTypes")}),vt=p(function(){return i.findByProps("transitionToGuild")}),Lt=p(function(){return i.find(function(e){return typeof e?.handleCreateJoinGuildPress=="function"})}),Ot=p(function(){return i.find(function(e){return e?.CirclePlusIcon})?.CirclePlusIcon}),jt=p(function(){return i.findByProps("colors","unsafe_rawColors")?.unsafe_rawColors}),_t=i.find(function(e){return e?.QuestDockExternalCoordinationContext}),ve=_t?.QuestDockExternalCoordinationContext,Le=i.find(function(e){return e?.QuestDockMode?.COLLAPSED!=null})?.QuestDockMode,W=48,U=6,zt=12;function Wt(){const e=n.useRef(new r.Animated.Value(1)).current,t=n.useCallback(function(){r.Animated.spring(e,{toValue:.9,useNativeDriver:!0}).start()},[e]),o=n.useCallback(function(){r.Animated.spring(e,{toValue:1,useNativeDriver:!0}).start()},[e]),s=n.useCallback(function(){const c=Me();c?.triggerHapticFeedback?.(c.HapticFeedbackTypes.SOFT),Lt()?.handleCreateJoinGuildPress?.()},[]),l=Ot(),u=jt();return n.createElement(r.Pressable,{onPress:s,onPressIn:t,onPressOut:o},n.createElement(r.Animated.View,{style:[q.createJoin,{backgroundColor:u?.GREEN_360,transform:[{scale:e}]}]},l?n.createElement(l,{size:"md",color:u?.WHITE}):n.createElement(r.Text,{style:[q.createJoinFallback,{color:u?.WHITE}]},"+")))}function Oe({gestureContext:e}){const t=n.useCallback(function(d){const g=Me();g?.triggerHapticFeedback?.(g.HapticFeedbackTypes.SOFT);const B=vt();B?.transitionToGuild?B.transitionToGuild(d):Mt()?.getRootNavigationRef?.()?.navigate("guilds",{guildId:d})},[]),o=Qt?.useStateFromStores?.([Qe],function(){return(Qe?.getGuildsTree()?.root?.children||[]).filter(function(d){return d.type!=="root"})})??[],s=e?n.useContext(e):null,l=s?.minExpandedContentHeight,u=n.useCallback(function(d){if(!l)return;const g=d.nativeEvent.layout.height;l.get()!==g&&l.set(g)},[l]),c=(ve?n.useContext(ve):null)?.setRestingQuestDockMode,y=s?.questDockWrapperSpecs;n.useEffect(function(){if(!c||!Le||!y)return;const d=r.BackHandler.addEventListener("hardwareBackPress",function(){return(y.get()?.height??56)>80?(c(Le.COLLAPSED),!0):!1});return function(){return d.remove()}},[c,y]);const{width:I}=r.Dimensions.get("window"),S=Math.max(3,Math.floor((I-zt*2+U)/(W+U))),b=S*W+(S-1)*U,E=Math.max(0,(I-b)/2);return n.createElement(r.View,{style:q.alignTop},n.createElement(r.View,{style:[q.grid,{paddingHorizontal:E,gap:U}],onLayout:u},n.createElement(Rt,null),o.map(function(d){return d.type==="folder"?n.createElement(St,{key:d.id,node:d,onPick:t}):n.createElement(Re,{key:d.id,node:d,onPick:t})}),n.createElement(Wt,null),n.createElement(Vt,null)))}const q=r.StyleSheet.create({alignTop:{flex:1,justifyContent:"flex-start",alignItems:"flex-start"},grid:{flexDirection:"row",flexWrap:"wrap",paddingTop:4,paddingBottom:16},createJoin:{width:W,height:W,borderRadius:16,alignItems:"center",justifyContent:"center"},createJoinFallback:{fontSize:28,fontWeight:"700",lineHeight:30}}),ie=new Map,le=[];let C=null,J=!1;function Ut(e,t,o){ie.set(e,{replacement:t,extraProps:o})}function qt(e,t){le.push({predicate:e,replacement:t})}function Jt(e){if(J)return;if(C=a.React.createElement,!C){console.warn("[ServerDrawer] React.createElement is null, skipping patch");return}const t=function(o,s,...l){if(!C)return a.React.createElement(o,s,...l);if(s)for(const{predicate:c,replacement:y}of le)try{if(c(s))return y?C.call(a.React,y,s,...l):null}catch{}const u=ie.get(o);if(u){const c=u.extraProps?{...s,...u.extraProps}:s;return C.call(a.React,u.replacement,c,...l)}return C.call(a.React,o,s,...l)};Object.assign(t,C),a.React.createElement=t,J=!0,e.push(function(){J&&C&&(a.React.createElement=C,J=!1),ie.clear(),le.length=0})}const ae="[ServerDrawer]";let ue=null;function je(){return ue||(ue=i.find(function(e){return e?.QuestDockGestureContext})?.QuestDockGestureContext??null),ue}function Xt(e){const t=i.find(function(s){return s?.type?.displayName==="QuestDockContentExpanded"||s?.type?.name==="QuestDockContentExpanded"});if(!t?.type)return console.log(ae,"WARN: QuestDockContentExpanded not found (will retry)"),!1;const o=t.type;return Ut(o,Oe,{gestureContext:je()}),t.type=function(){return a.React.createElement(Oe,{gestureContext:je()})},e.push(function(){t.type=o}),console.log(ae,"PATCH: QuestDockContentExpanded replaced"),!0}function A(e,t){const o=i.find(function(u){return u?.type?.displayName===e||u?.type?.name===e});if(!o?.type)return console.log(ae,`WARN: ${e} not found`),!1;const s=o.type,l=s;return o.type=function(){return null},l&&(Object.defineProperties(o.type,Object.getOwnPropertyDescriptors(l)),o.type.displayName=e),t.push(function(){o.type=s}),!0}const Yt="[ServerDrawer]";function Kt(e){return qt(function(t){return t?.nativeID==="guilds-bar-view"},null),e.push(function(){}),console.log(Yt,"PATCH: guilds-bar-view createElement calls now render nothing"),!0}function Zt(e){const t=i.findByStoreName("ExpandedGuildFolderStore");if(!t?.getExpandedFolders)return!1;const o=function({folderId:s}){if(!f.storage.autoCollapseFolders||s==null)return;const l=t.getExpandedFolders();if(!(!(l instanceof Set)||!l.has(s)))for(const u of l)u!==s&&a.FluxDispatcher.dispatch({type:"TOGGLE_GUILD_FOLDER_EXPAND",folderId:u})};return a.FluxDispatcher.subscribe("TOGGLE_GUILD_FOLDER_EXPAND",o),e.push(function(){return a.FluxDispatcher.unsubscribe("TOGGLE_GUILD_FOLDER_EXPAND",o)}),!0}const{ScrollView:$t,View:Nt}=a.ReactNative;function en({children:e}){return a.React.createElement($t,{style:{flex:1}},e,a.React.createElement(Nt,{style:{height:24}}))}const{View:tn,Text:nn}=a.ReactNative;function _e({children:e,style:t}){return a.React.createElement(tn,{style:[{marginHorizontal:16,marginVertical:8,padding:10,borderRadius:8,borderWidth:1,borderColor:"rgba(128,128,128,0.25)"},t]},a.React.createElement(nn,{style:{fontSize:12.5,lineHeight:18,opacity:.75}},e))}const{FormSection:ze,FormSwitchRow:X}=Je.Forms;function rn(){return Z.useProxy(f.storage),a.React.createElement(en,null,a.React.createElement(_e,null,"Server Drawer takes over the Quest Dock (the strip above the tab bar) to show your servers as a grid instead - tap to expand, long-press a server for its usual context menu, the chat bubble jumps to DMs, the + button creates or joins a server through Discord's own modal, and the check button marks every channel in every server as read."),a.React.createElement(ze,{title:"Layout"},a.React.createElement(X,{label:"Hide the left server rail",subLabel:"Your servers and DMs already live in the drawer, so the rail is redundant",value:f.storage.hideGuildsBar!==!1,onValueChange:function(e){f.storage.hideGuildsBar=e,qe()}}),a.React.createElement(X,{label:"Unread badges",subLabel:"Show mention counts and unread dots on server icons in the drawer",value:f.storage.showUnreadBadges!==!1,onValueChange:function(e){f.storage.showUnreadBadges=e}})),a.React.createElement(ze,{title:"Folders"},a.React.createElement(X,{label:"Auto-collapse other folders",subLabel:"Opening a folder collapses any other folder that was already open",value:!!f.storage.autoCollapseFolders,onValueChange:function(e){f.storage.autoCollapseFolders=e}}),a.React.createElement(X,{label:"Hide icons in collapsed folders",subLabel:"Show a plain folder icon instead of a 4-server preview",value:!!f.storage.hideFolderIcons,onValueChange:function(e){f.storage.hideFolderIcons=e}})),a.React.createElement(_e,null,"The folder options above are ported from fres621's BetterFolders - its other half (hiding icons in the native left server rail) patched a component that no longer exists in current Discord builds, so it's been rebuilt here instead, where it actually applies to what you see."))}let h=[],m;function on(e,t){try{return t()}catch(o){return K.logger.error(`[ServerDrawer] "${e}" patch threw, skipping: ${o}`),!1}}function We(){const e={questDockRender:function(){return Xe(h)},questDockBase:function(){return Ye(h)},mobileQuestDock:function(){return Ke(h)},getQuestAsset:function(){return $e(h)},expanded:function(){return Xt(h)},collapsed:function(){return A("QuestDockContentCollapsed",h)},enrolledHeader:function(){return A("QuestDockEnrolledHeader",h)},unenrolledHeader:function(){return A("QuestDockUnenrolledHeader",h)},enrolledBody:function(){return A("QuestDockEnrolledBody",h)},unenrolledBody:function(){return A("QuestDockUnenrolledBody",h)},autoCollapseFolders:function(){return Zt(h)},...f.storage.hideGuildsBar?{hideGuildsBar:function(){return Kt(h)}}:{}};Jt(h);const t=new Set(Object.keys(e)),o=new Set,s=function(){for(const l of t)on(l,e[l])&&(o.add(l),t.delete(l));t.size===0&&m&&(clearInterval(m),m=void 0)};if(s(),t.size>0){let l=0;m=setInterval(function(){s(),++l>=50&&m&&(clearInterval(m),m=void 0,t.size>0&&K.logger.error(`[ServerDrawer] Gave up waiting on: ${[...t].join(", ")}`))},200)}K.logger.log(`[ServerDrawer] onLoad: applied immediately - ${[...o].join(", ")||"none"}${t.size?`, still waiting on ${[...t].join(", ")}`:""}`)}function Ue(){m&&(clearInterval(m),m=void 0);for(const e of h)try{e()}catch{}h=[]}function qe(){Ue(),We()}var sn={onLoad:function(){f.storage.hideGuildsBar??=!0,f.storage.showUnreadBadges??=!0,f.storage.autoCollapseFolders??=!1,f.storage.hideFolderIcons??=!1,We()},onUnload:function(){return Ue()},settings:rn};return G.default=sn,G.restart=qe,Object.defineProperty(G,"__esModule",{value:!0}),G})({},vendetta,vendetta.plugin,vendetta.metro,vendetta.metro.common,window.React,vendetta.metro.common.ReactNative,vendetta.storage,vendetta.ui.toasts,vendetta.ui,vendetta.ui.assets,vendetta.ui.components); diff --git a/server-drawer/install/manifest.json b/server-drawer/install/manifest.json index c6d99f8..fa0c7a3 100644 --- a/server-drawer/install/manifest.json +++ b/server-drawer/install/manifest.json @@ -1 +1 @@ -{"name":"ServerDrawer","description":"Replaces the Quest Dock with a server grid drawer above the YouBar - tap to expand, long-press a server for its context menu, plus a one-tap create/join button.","authors":[{"name":"everestmcarthur"},{"name":"kmmiio99o"},{"name":"fres"}],"main":"index.js","vendetta":{"icon":"ServerIcon"},"hash":"25b67abaaf23f7755deb448176f5f2d2fb41f87c355daaed375df15e73df82fd"} \ No newline at end of file +{"name":"ServerDrawer","description":"Replaces the Quest Dock with a server grid drawer above the YouBar - tap to expand, long-press a server for its context menu, plus a one-tap create/join button.","authors":[{"name":"everestmcarthur"},{"name":"kmmiio99o"},{"name":"fres"}],"main":"index.js","vendetta":{"icon":"ServerIcon"},"hash":"9d4e6347d8cf731d4c9bd16b5e9b12dd6114cf4fb509b75bd613966c29bd7a1b"} \ No newline at end of file