|
3 | 3 | * @author programmer2514 |
4 | 4 | * @authorId 563652755814875146 |
5 | 5 | * @description A feature-rich BetterDiscord plugin that reworks the Discord UI to be significantly more modular |
6 | | - * @version 12.3.4 |
| 6 | + * @version 12.3.5 |
7 | 7 | * @donate https://ko-fi.com/benjaminpryor |
8 | 8 | * @patreon https://www.patreon.com/BenjaminPryor |
9 | 9 | * @website https://github.com/programmer2514/BetterDiscord-CollapsibleUI |
@@ -1126,34 +1126,62 @@ const constants = { |
1126 | 1126 | I_TOOLBAR_FULL: 3, |
1127 | 1127 | }; |
1128 | 1128 |
|
1129 | | -// Abstract webpack modules |
1130 | | -const modules = { |
1131 | | - get members() { return this._members ?? (this._members = runtime.api.Webpack.getByKeys('membersWrap', 'hiddenMembers', 'roleIcon')); }, |
1132 | | - get icons() { return this._icons ?? (this._icons = runtime.api.Webpack.getByKeys('selected', 'iconWrapper', 'clickable', 'icon')); }, |
1133 | | - get social() { return this._social ?? (this._social = runtime.api.Webpack.getByKeys('inviteToolbar', 'peopleColumn', 'addFriend')); }, |
1134 | | - get toolbar() { return this._toolbar ?? (this._toolbar = runtime.api.Webpack.getByKeys('updateIconForeground', 'search', 'downloadArrow')); }, |
1135 | | - get panel() { return this._panel ?? (this._panel = runtime.api.Webpack.getByKeys('outer', 'inner', 'overlay')); }, |
1136 | | - get guilds() { return this._guilds ?? (this._guilds = runtime.api.Webpack.getByKeys('chatContent', 'noChat', 'parentChannelName', 'linkedLobby')); }, |
1137 | | - get frame() { return this._frame ?? (this._frame = runtime.api.Webpack.getByKeys('bar', 'title', 'winButtons')); }, |
1138 | | - get calls() { return this._calls ?? (this._calls = runtime.api.Webpack.getByKeys('wrapper', 'fullScreen', 'callContainer')); }, |
1139 | | - get threads() { return this._threads ?? (this._threads = runtime.api.Webpack.getByKeys('uploadArea', 'newMemberBanner', 'mainCard', 'newPostsButton')); }, |
1140 | | - get user() { return this._user ?? (this._user = runtime.api.Webpack.getByKeys('avatar', 'nameTag', 'customStatus', 'emoji', 'buttons')); }, |
1141 | | - get input() { return this._input ?? (this._input = runtime.api.Webpack.getByKeys('channelTextArea', 'attachButton', 'emojiButton')); }, |
1142 | | - get popout() { return this._popout ?? (this._popout = runtime.api.Webpack.getByKeys('chatLayerWrapper', 'container', 'chatTarget')); }, |
1143 | | - get sidebar() { return this._sidebar ?? (this._sidebar = runtime.api.Webpack.getByKeys('sidebar', 'activityPanel', 'sidebarListRounded')); }, |
1144 | | - get effects() { return this._effects ?? (this._effects = runtime.api.Webpack.getByKeys('profileEffects', 'hovered', 'effect')); }, |
1145 | | - get search() { return this._search ?? (this._search = runtime.api.Webpack.getByKeys('searchResultsWrap', 'stillIndexing', 'noResults')); }, |
1146 | | - get tooltip() { return this._tooltip ?? (this._tooltip = runtime.api.Webpack.getByKeys('menu', 'label', 'caret')); }, |
1147 | | - get preview() { return this._preview ?? (this._preview = runtime.api.Webpack.getByKeys('popout', 'more', 'title', 'timestamp', 'name')); }, |
1148 | | - get channels() { return this._channels ?? (this._channels = runtime.api.Webpack.getByKeys('channel', 'closeIcon', 'dm')); }, |
1149 | | - get activity() { return this._activity ?? (this._activity = runtime.api.Webpack.getByKeys('itemCard', 'emptyCard', 'emptyText')); }, |
1150 | | - get game() { return this._game ?? (this._game = runtime.api.Webpack.getByKeys('openOnHover', 'userSection', 'thumbnail')); }, |
1151 | | - get callButtons() { return this._callButtons ?? (this._callButtons = runtime.api.Webpack.getByKeys('controlButton', 'wrapper', 'buttonContainer')); }, |
1152 | | - get userAreaButtons() { return this._userAreaButtons ?? (this._userAreaButtons = runtime.api.Webpack.getByKeys('krispLogo', 'actionButtons', 'buttonIcon')); }, |
1153 | | - get scroller() { return this._scroller ?? (this._scroller = runtime.api.Webpack.getByKeys('wrapper', 'scroller', 'discoveryIcon')); }, |
1154 | | - get profileWrappers() { return this._profileWrappers ?? (this._profileWrappers = runtime.api.Webpack.getByKeys('header', 'footerButton', 'backdrop', 'wishlistBreadcrumb')); }, |
| 1129 | +// Key sets for all required webpack modules |
| 1130 | +const MODULE_KEY_SETS = { |
| 1131 | + members: ['membersWrap', 'hiddenMembers', 'roleIcon'], |
| 1132 | + icons: ['selected', 'iconWrapper', 'clickable', 'icon'], |
| 1133 | + social: ['inviteToolbar', 'peopleColumn', 'addFriend'], |
| 1134 | + toolbar: ['updateIconForeground', 'search', 'downloadArrow'], |
| 1135 | + panel: ['outer', 'inner', 'overlay'], |
| 1136 | + guilds: ['chatContent', 'noChat', 'parentChannelName', 'linkedLobby'], |
| 1137 | + frame: ['bar', 'title', 'winButtons'], |
| 1138 | + calls: ['wrapper', 'fullScreen', 'callContainer'], |
| 1139 | + threads: ['uploadArea', 'newMemberBanner', 'mainCard', 'newPostsButton'], |
| 1140 | + user: ['avatar', 'nameTag', 'customStatus', 'emoji', 'buttons'], |
| 1141 | + input: ['channelTextArea', 'attachButton', 'emojiButton'], |
| 1142 | + popout: ['chatLayerWrapper', 'container', 'chatTarget'], |
| 1143 | + sidebar: ['sidebar', 'activityPanel', 'sidebarListRounded'], |
| 1144 | + effects: ['profileEffects', 'hovered', 'effect'], |
| 1145 | + search: ['searchResultsWrap', 'stillIndexing', 'noResults'], |
| 1146 | + tooltip: ['menu', 'label', 'caret'], |
| 1147 | + preview: ['popout', 'more', 'title', 'timestamp', 'name'], |
| 1148 | + channels: ['channel', 'closeIcon', 'dm'], |
| 1149 | + activity: ['itemCard', 'emptyCard', 'emptyText'], |
| 1150 | + game: ['openOnHover', 'userSection', 'thumbnail'], |
| 1151 | + callButtons: ['controlButton', 'wrapper', 'buttonContainer'], |
| 1152 | + userAreaButtons: ['krispLogo', 'actionButtons', 'buttonIcon'], |
| 1153 | + scroller: ['wrapper', 'scroller', 'discoveryIcon'], |
| 1154 | + profileWrappers: ['header', 'footerButton', 'backdrop', 'wishlistBreadcrumb'], |
1155 | 1155 | }; |
1156 | 1156 |
|
| 1157 | +// getBulk walks the webpack module cache once for all queries together. |
| 1158 | +function bulkResolveModules() { |
| 1159 | + const names = Object.keys(MODULE_KEY_SETS); |
| 1160 | + const queries = names.map(name => ({ |
| 1161 | + filter: runtime.api.Webpack.Filters.byKeys(...MODULE_KEY_SETS[name]), |
| 1162 | + })); |
| 1163 | + const resolved = runtime.api.Webpack.getBulk(...queries); |
| 1164 | + return Object.fromEntries(names.map((name, i) => [name, resolved[i]])); |
| 1165 | +} |
| 1166 | + |
| 1167 | +// Abstract webpack modules |
| 1168 | +const _moduleCache = { _resolved: false, _data: {} }; |
| 1169 | +const modules = new Proxy(_moduleCache, { |
| 1170 | + get(target, prop) { |
| 1171 | + if (prop.startsWith('_')) return target[prop]; |
| 1172 | + if (!target._resolved) { |
| 1173 | + target._data = bulkResolveModules(); |
| 1174 | + target._resolved = true; |
| 1175 | + } |
| 1176 | + return target._data[prop]; |
| 1177 | + }, |
| 1178 | + set(target, prop, value) { |
| 1179 | + if (prop.startsWith('_')) { target[prop] = value; return true; } |
| 1180 | + target._data[prop] = value; |
| 1181 | + return true; |
| 1182 | + }, |
| 1183 | +}); |
| 1184 | + |
1157 | 1185 | const elements = { |
1158 | 1186 | get inviteToolbar() { return document.querySelector(`.${modules.social?.inviteToolbar}`); }, |
1159 | 1187 | get searchBar() { return document.querySelector(`.${modules.toolbar?.search}`); }, |
@@ -1204,7 +1232,7 @@ const runtime = { |
1204 | 1232 | toolbar: null, |
1205 | 1233 | dragging: null, |
1206 | 1234 | interval: null, |
1207 | | - loaded: Object.fromEntries(Object.keys(modules).filter(key => !key.startsWith('_')).map(key => [key, false])), |
| 1235 | + loaded: Object.fromEntries(Object.keys(MODULE_KEY_SETS).map(key => [key, false])), |
1208 | 1236 | allModulesLoaded: false, |
1209 | 1237 | collapsed: [false, false, false, false, false, false, false, false, false, false, false], |
1210 | 1238 | keys: new Set(), |
@@ -3225,18 +3253,16 @@ module.exports = class CollapsibleUI { |
3225 | 3253 |
|
3226 | 3254 | // Check if the cursor is within the given distance of an element |
3227 | 3255 | isNear = (element, distance, x, y) => { |
3228 | | - let box = element?.getBoundingClientRect(); |
3229 | | - if (!box) return false; |
3230 | | - |
3231 | | - let top = box.top - distance; |
3232 | | - let left = box.left - distance; |
3233 | | - let right = box.right + distance; |
3234 | | - let bottom = box.bottom + distance; |
3235 | | - |
3236 | | - if (element.classList.contains(`${modules.frame?.bar}`)) |
3237 | | - right = window.innerWidth + distance; |
3238 | | - |
3239 | | - return (x > left && x < right && y > top && y < bottom); |
| 3256 | + if (!element) return false; |
| 3257 | + |
| 3258 | + const rect = element.getBoundingClientRect(); |
| 3259 | + const frameBar = modules.frame?.bar; |
| 3260 | + const top = rect.top - distance; |
| 3261 | + const left = rect.left - distance; |
| 3262 | + const right = (frameBar && element.classList.contains(frameBar) ? window.innerWidth : rect.right) + distance; |
| 3263 | + const bottom = rect.bottom + distance; |
| 3264 | + |
| 3265 | + return x >= left && x <= right && y >= top && y <= bottom; |
3240 | 3266 | }; |
3241 | 3267 |
|
3242 | 3268 | // Update the dynamic collapsed state of an element |
|
0 commit comments