diff --git a/client/src/index.js b/client/src/index.js index 060eb804..3939e608 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -8,7 +8,7 @@ * LICENSE file in the root directory of this source tree. */ -import { DOM, BdUI } from 'ui'; +import { DOM, BdUI, ProfileBadges } from 'ui'; import BdCss from './styles/index.scss'; import { Events, CssEditor, Globals, PluginManager, ThemeManager } from 'modules'; import { ClientLogger as Logger } from 'common'; @@ -16,6 +16,7 @@ import { ClientLogger as Logger } from 'common'; class BetterDiscord { constructor() { + ProfileBadges.init(); // Not final way to do it DOM.injectStyle(BdCss, 'bdmain'); Events.on('global-ready', this.globalReady.bind(this)); } @@ -27,6 +28,7 @@ class BetterDiscord { } globalReady() { + BdUI.initUiEvents(); this.vueInstance = BdUI.injectUi(); (async () => { this.init(); diff --git a/client/src/modules/modules.js b/client/src/modules/modules.js index 1e5537cb..28626124 100644 --- a/client/src/modules/modules.js +++ b/client/src/modules/modules.js @@ -4,4 +4,5 @@ export { default as CssEditor } from './csseditor'; export { default as PluginManager } from './pluginmanager'; export { default as ThemeManager } from './thememanager'; export { default as Globals } from './globals'; -export { default as Vendor } from './vendor'; \ No newline at end of file +export { default as Vendor } from './vendor'; +export { default as WebpackModules } from './webpackmodules'; diff --git a/client/src/styles/partials/index.scss b/client/src/styles/partials/index.scss index d40d30a0..b2d7157c 100644 --- a/client/src/styles/partials/index.scss +++ b/client/src/styles/partials/index.scss @@ -5,5 +5,6 @@ @import './sidebarview/index.scss'; @import './bdsettings/index.scss'; @import './generic/index.scss'; +@import './profilebadges.scss'; @import './discordoverrides.scss'; diff --git a/client/src/styles/partials/profilebadges.scss b/client/src/styles/partials/profilebadges.scss new file mode 100644 index 00000000..9af642ed --- /dev/null +++ b/client/src/styles/partials/profilebadges.scss @@ -0,0 +1,30 @@ +.bd-profile-badges-wrap { + display: flex; + margin-top: 8px; + flex: 1 1 auto; +} + +.bd-profile-badges { + display: flex; +} + +.bd-profile-badge { + background-position: 50%; + background-repeat: no-repeat; + background-size: cover; + cursor: pointer; + height: 16px; + margin-right: 6px; +} + +.bd-profile-badge-developer, +.bd-profile-badge-contributor { + background-image: $logoSmallBw; + width: 16px; + filter: brightness(10); + + .theme-light [class*="topSectionNormal-"] & { + background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FscXVlXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjAwMCAyMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyMDAwIDIwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwYXRoIGZpbGw9IiMzRTgyRTUiIGQ9Ik0xNDAyLjIsNjMxLjdjLTkuNy0zNTMuNC0yODYuMi00OTYtNjQyLjYtNDk2SDY4LjR2NzE0LjFsNDQyLDM5OFY0OTAuN2gyNTdjMjc0LjUsMCwyNzQuNSwzNDQuOSwwLDM0NC45SDU5Ny42djMyOS41aDE2OS44YzI3NC41LDAsMjc0LjUsMzQ0LjgsMCwzNDQuOGgtNjk5djM1NC45aDY5MS4yYzM1Ni4zLDAsNjMyLjgtMTQyLjYsNjQyLjYtNDk2YzAtMTYyLjYtNDQuNS0yODQuMS0xMjIuOS0zNjguNkMxMzU3LjcsOTE1LjgsMTQwMi4yLDc5NC4zLDE0MDIuMiw2MzEuN3oiLz48cGF0aCBmaWxsPSIjYmJiYmJiIiBkPSJNMTI2Mi41LDEzNS4yTDEyNjIuNSwxMzUuMmwtNzYuOCwwYzI2LjYsMTMuMyw1MS43LDI4LjEsNzUsNDQuM2M3MC43LDQ5LjEsMTI2LjEsMTExLjUsMTY0LjYsMTg1LjNjMzkuOSw3Ni42LDYxLjUsMTY1LjYsNjQuMywyNjQuNmwwLDEuMnYxLjJjMCwxNDEuMSwwLDU5Ni4xLDAsNzM3LjF2MS4ybDAsMS4yYy0yLjcsOTktMjQuMywxODgtNjQuMywyNjQuNmMtMzguNSw3My44LTkzLjgsMTM2LjItMTY0LjYsMTg1LjNjLTIyLjYsMTUuNy00Ni45LDMwLjEtNzIuNiw0My4xaDcyLjVjMzQ2LjIsMS45LDY3MS0xNzEuMiw2NzEtNTY3LjlWNzE2LjdDMTkzMy41LDMxMi4yLDE2MDguNywxMzUuMiwxMjYyLjUsMTM1LjJ6Ii8+PC9nPjwvc3ZnPg=='); + filter: none; + } +} diff --git a/client/src/ui/bdui.js b/client/src/ui/bdui.js index 48d5a690..dd6646dd 100644 --- a/client/src/ui/bdui.js +++ b/client/src/ui/bdui.js @@ -8,23 +8,36 @@ * LICENSE file in the root directory of this source tree. */ -import Dom from './dom'; -import Vue from 'vue'; -import VTooltip from 'v-tooltip'; +import DOM from './dom'; +import Vue from './vue'; import { BdSettingsWrapper } from './components'; +import { Events, WebpackModules } from 'modules'; +import { Utils } from 'common'; export default class { + + static initUiEvents() { + //this.profilePopupModule.open + const defer = setInterval(() => { + if (!this.profilePopupModule) return; + clearInterval(defer); + this.profilePopupModule.open = Utils.overload(this.profilePopupModule.open, userid => { + Events.emit('ui-event', { + event: 'profile-popup-open', + data: { userid } + }); + }); + }, 100); + + } + + static get profilePopupModule() { + return WebpackModules.getModuleByProps(['fetchMutualFriends', 'setSection']); + } + static injectUi() { - Vue.use(VTooltip, { - defaultContainer: 'bdtooltips', - defaultClass: 'bd-tooltip', - defaultTargetClass: 'bd-has-tooltip', - defaultInnerSelector: '.bd-tooltip-inner', - defaultTemplate: '
' - }); - - Dom.createElement('div', null, 'bd-settings').appendTo(Dom.bdBody); - + DOM.createElement('bdtooltips').appendTo(DOM.bdBody); + DOM.createElement('div', null, 'bd-settings').appendTo(DOM.bdBody); const vueInstance = new Vue({ el: '#bd-settings', components: { BdSettingsWrapper }, diff --git a/client/src/ui/components/bd/BdBadge.vue b/client/src/ui/components/bd/BdBadge.vue new file mode 100644 index 00000000..c151627d --- /dev/null +++ b/client/src/ui/components/bd/BdBadge.vue @@ -0,0 +1,34 @@ +/** + * BetterDiscord BD Badge Component + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * https://betterdiscord.net + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. +*/ + + + diff --git a/client/src/ui/components/bd/index.js b/client/src/ui/components/bd/index.js index dfa19573..a0019f2f 100644 --- a/client/src/ui/components/bd/index.js +++ b/client/src/ui/components/bd/index.js @@ -3,4 +3,5 @@ export { default as CoreSettings } from './CoreSettings.vue'; export { default as UISettings } from './UISettings.vue'; export { default as EmoteSettings } from './EmoteSettings.vue'; export { default as CssEditorView } from './CssEditor.vue'; -export { default as PluginsView } from './PluginsView.vue'; \ No newline at end of file +export { default as PluginsView } from './PluginsView.vue'; +export { default as BdBadge } from './BdBadge.vue'; diff --git a/client/src/ui/profilebadges.js b/client/src/ui/profilebadges.js new file mode 100644 index 00000000..948fe15a --- /dev/null +++ b/client/src/ui/profilebadges.js @@ -0,0 +1,71 @@ +/** + * BetterDiscord Developer/Contributor Profile Badges + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * https://betterdiscord.net + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import DOM from './dom'; +import { BdBadge } from './components/bd'; +import VueInjector from './vueinjector'; +import { Events } from 'modules'; + +export default class { + + static init() { + Events.on('ui-event', this.uiEvent.bind(this)); + } + + static uiEvent(e) { + const { event, data } = e; + if (event !== 'profile-popup-open') return; + const { userid } = data; + if (!userid) return; + + this.inject(userid); + } + + static inject(userid) { + const contributor = this.contributors.find(c => c.id == userid); + if (!contributor) return; + + setTimeout(() => { + let hasBadges = false; + let root = document.querySelector('[class*=profileBadges]'); + if (root) { + hasBadges = true; + } else { + root = document.querySelector('[class*="headerInfo"]'); + } + + VueInjector.inject( + root, + DOM.createElement('div', null, 'bdprofilebadges'), + { BdBadge }, + `` + ); + }, 200); + } + + static filter(mutation) { + return mutation.target.firstChild && mutation.target.className.includes('modal'); + } + + static get contributors() { + return [ + { 'id': 81388395867156480, 'webdev': true, 'developer': true, 'contributor': true }, // Jiiks + { 'id': 98003542823944192, 'webdev': false, 'developer': true, 'contributor': true }, // Pohky + { 'id': 138850472541814784, 'webdev': true, 'developer': false, 'contributor': true }, // Hammock + { 'id': 249746236008169473, 'webdev': false, 'developer': true, 'contributor': true }, // Zerebos + { 'id': 125367412370440192, 'webdev': false, 'developer': true, 'contributor': true }, // Pierce + { 'id': 284056145272766465, 'webdev': false, 'developer': false, 'contributor': true }, // Samuel Elliott + { 'id': 184021060562321419, 'webdev': false, 'developer': false, 'contributor': true }, // Lilian Tedone + { 'id': 76052829285916672, 'webdev': false, 'developer': false, 'contributor': true }, // samfun123 + { 'id': 171005991272316937, 'webdev': false, 'developer': false, 'contributor': true }, // samogot + ]; + } + +} diff --git a/client/src/ui/ui.js b/client/src/ui/ui.js index 3f794fff..e17a542e 100644 --- a/client/src/ui/ui.js +++ b/client/src/ui/ui.js @@ -1,2 +1,4 @@ export { default as DOM } from './dom'; export { default as BdUI } from './bdui'; +export { default as VueInjector } from './vueinjector'; +export { default as ProfileBadges } from './profilebadges'; diff --git a/client/src/ui/vue.js b/client/src/ui/vue.js new file mode 100644 index 00000000..a3ec554b --- /dev/null +++ b/client/src/ui/vue.js @@ -0,0 +1,22 @@ +/** + * BetterDiscord Client UI Module + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * https://betterdiscord.net + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import Vue from 'vue'; +import VTooltip from 'v-tooltip'; + +Vue.use(VTooltip, { + defaultContainer: 'bdtooltips', + defaultClass: 'bd-tooltip', + defaultTargetClass: 'bd-has-tooltip', + defaultInnerSelector: '.bd-tooltip-inner', + defaultTemplate: '
' +}); + +export default Vue; diff --git a/client/src/ui/vueinjector.js b/client/src/ui/vueinjector.js new file mode 100644 index 00000000..0dfc0d93 --- /dev/null +++ b/client/src/ui/vueinjector.js @@ -0,0 +1,25 @@ +/** + * BetterDiscord VUE Injector Module + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * https://betterdiscord.net + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. +*/ + +import Vue from './vue'; + +export default class { + + static inject(root, bdnode, components, template) { + bdnode.appendTo(root); + + return new Vue({ + el: bdnode.element, + components, + template + }); + } + +} diff --git a/package.json b/package.json index c9adbf2f..855c6af4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "betterdiscord", "description": "BetterDiscord", "author": "Jiiks", - "version": "0.4.0", + "version": "2.0.0a", "homepage": "https://betterdiscord.net", "license": "MIT", "main": "./core/index.js",