Profilebadges. Implements #55

This commit is contained in:
Jiiks 2018-01-31 17:45:25 +02:00
parent 92634a2f98
commit 14de558305
11 changed files with 191 additions and 15 deletions

View File

@ -8,14 +8,17 @@
* 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';
import { default as WebpackModules } from './modules/webpackmodules';
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 +30,7 @@ class BetterDiscord {
}
globalReady() {
BdUI.initUiEvents();
this.vueInstance = BdUI.injectUi();
(async () => {
this.init();

View File

@ -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';
export { default as Vendor } from './vendor';
export { default as WebpackModules } from './webpackmodules';

View File

@ -5,5 +5,6 @@
@import './sidebarview/index.scss';
@import './bdsettings/index.scss';
@import './generic/index.scss';
@import './profilebadges.scss';
@import './discordoverrides.scss';

View File

@ -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;
}
}

View File

@ -9,19 +9,35 @@
*/
import Dom from './dom';
import Vue from 'vue';
import Vue from './vue';
import VTooltip from 'v-tooltip';
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: '<div class="bd-tooltip"><span class="bd-tooltip-inner"></span></div>'
});
Dom.createElement('bdtooltips').appendTo(Dom.bdBody);
Dom.createElement('div', null, 'bd-settings').appendTo(Dom.bdBody);

View File

@ -9,10 +9,11 @@
*/
<template>
<div class="bd-profile-badges-wrap">
<div :class="{'bd-profile-badges-wrap': !hasBadges}">
<div class="bd-profile-badges">
<div v-if="developer" class="bd-profile-badge bd-profile-badge-developer"></div>
<div v-id="contributor" class="bd-profile-badge bd-profile-badge-contributor"></div>
<div v-if="developer" v-tooltip="'BetterDiscord Developer'" class="bd-profile-badge bd-profile-badge-developer" @click="onClick"></div>
<div v-else-if="webdev" v-tooltip="'BetterDiscord Web Developer'" class="bd-profile-badge bd-profile-badge-developer" @click="onClick"></div>
<div v-else-if="contributor" v-tooltip="'BetterDiscord Contributor'" class="bd-profile-badge bd-profile-badge-contributor" @click="onClick"></div>
</div>
</div>
</template>
@ -21,10 +22,11 @@
import { shell } from 'electron';
export default {
props: ['developer', 'contributor'],
props: ['webdev', 'developer', 'contributor', 'hasBadges'],
methods: {
onClick() {
if (this.developer) return shell.openExternal('https://github.com/JsSucks/BetterDiscordApp');
if (this.webdev) return shell.openExternal('http://betterdiscord.net');
if (this.contributor) return shell.openExternal('https://github.com/JsSucks/BetterDiscordApp/graphs/contributors');
}
}

View File

@ -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';
export { default as PluginsView } from './PluginsView.vue';
export { default as BdBadge } from './BdBadge.vue';

View File

@ -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 },
`<BdBadge developer="${contributor.developer}" contributor="${contributor.contributor}" webdev="${contributor.webdev}" hasBadges="${hasBadges}" />`
);
}, 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
];
}
}

View File

@ -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';

22
client/src/ui/vue.js Normal file
View File

@ -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: '<div class="bd-tooltip"><span class="bd-tooltip-inner"></span></div>'
});
export default Vue;

View File

@ -0,0 +1,26 @@
/**
* 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 Dom from './dom';
import Vue from './vue';
export default class {
static inject(root, bdnode, components, template) {
bdnode.appendTo(root);
return new Vue({
el: bdnode.element,
components,
template
});
}
}