add api's for easy generic components

This commit is contained in:
Jiiks 2018-08-26 17:34:54 +03:00
parent 8146e0e7f2
commit 6d8ef35bd6
5 changed files with 118 additions and 1 deletions

View File

@ -12,6 +12,7 @@ import { EmoteModule } from 'builtin';
import { SettingsSet, SettingsCategory, Setting, SettingsScheme } from 'structs';
import { BdMenu, Modals, DOM, DOMObserver, VueInjector, Toasts, Notifications, BdContextMenu, DiscordContextMenu } from 'ui';
import * as CommonComponents from 'commoncomponents';
import { default as Components } from '../ui/components/generic';
import { Utils, Filters, ClientLogger as Logger, ClientIPC, AsyncEventEmitter } from 'common';
import Settings from './settings';
import ExtModuleManager from './extmodulemanager';
@ -64,6 +65,7 @@ export default class PluginApi {
get EventsWrapper() { return EventsWrapper }
get CommonComponents() { return CommonComponents }
get Components() { return Components }
get Filters() { return Filters }
get Discord() { return DiscordApi }
get DiscordApi() { return DiscordApi }

View File

@ -0,0 +1,21 @@
/**
* BetterDiscord Generic Button 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.
*/
<template>
<div class="bd-button" :class="classes" @click="onClick">
{{text}}
</div>
</template>
<script>
export default {
props: ['classes', 'text', 'onClick']
}
</script>

View File

@ -0,0 +1,23 @@
/**
* BetterDiscord Generic Button Group 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.
*/
<template>
<div class="bd-buttonGroup" :class="classes">
<Button v-for="(button, index) in buttons" :text="button.text" :classes="button.classes" :onClick="button.onClick" :key="index"/>
</div>
</template>
<script>
import Button from './Button.vue';
export default {
props: ['buttons', 'classes'],
components: { Button }
}
</script>

View File

@ -0,0 +1,29 @@
import VrWrapper from '../../vrwrapper';
import ButtonGroupComponent from './ButtonGroup.vue';
class ButtonGroupWrapper extends VrWrapper {
get component() { return ButtonGroupComponent }
constructor(props) {
super();
this.props = props;
}
}
import ButtonComponent from './Button.vue';
class ButtonWrapper extends VrWrapper {
get component() { return ButtonComponent }
constructor(props) {
super();
this.props = props;
}
}
export default class {
static Button(props) {
return new ButtonWrapper(props);
}
static ButtonGroup(props) {
return new ButtonGroupWrapper(props);
}
}

View File

@ -19,6 +19,7 @@ module.exports = (Plugin, Api, Vendor) => {
Logger.log('Custom Elements Example Started');
this.injectStyle();
this.patchGuildTextChannel();
this.patchMessages();
return true;
}
@ -31,6 +32,8 @@ module.exports = (Plugin, Api, Vendor) => {
// Force update elements to remove our changes
const GuildTextChannel = await ReactComponents.getComponent('GuildTextChannel');
GuildTextChannel.forceUpdateAll();
const MessageContent = await ReactComponents.getComponent('MessageContent', { selector: Reflection.resolve('container', 'containerCozy', 'containerCompact', 'edited').selector });
MessageContent.forceUpdateAll();
return true;
}
@ -47,7 +50,14 @@ module.exports = (Plugin, Api, Vendor) => {
&:hover {
opacity: 1;
}
}`;
}
.exampleBtnGroup {
.bd-button {
font-size: 14px;
padding: 5px;
}
}
`;
await CssUtils.injectSass(css);
}
@ -59,6 +69,14 @@ module.exports = (Plugin, Api, Vendor) => {
GuildTextChannel.forceUpdateAll();
}
async patchMessages() {
// Get Message component and patch it's render function
const MessageContent = await ReactComponents.getComponent('MessageContent', { selector: Reflection.resolve('container', 'containerCozy', 'containerCompact', 'edited').selector });
monkeyPatch(MessageContent.component.prototype).after('render', this.injectGenericComponents.bind(this));
// Force update to see our changes immediatly
MessageContent.forceUpdateAll();
}
/*
* Injecting a custom React element using React.createElement
* https://reactjs.org/docs/react-api.html#createelement
@ -77,6 +95,30 @@ module.exports = (Plugin, Api, Vendor) => {
child.children.push(customVueComponent(Vuewrap, { onClick: e => this.handleClick(e, child.channel) }));
}
/**
* Inject generic components provided by BD
*/
injectGenericComponents(that, args, returnValue) {
// If children is not an array make it into one
if (!returnValue.props.children instanceof Array) returnValue.props.children = [returnValue.props.children];
// Add a generic Button component provided by BD
returnValue.props.children.push(Api.Components.ButtonGroup({
classes: [ 'exampleBtnGroup' ], // Additional classes for button group
buttons: [
{
classes: ['exampleBtn'], // Additional classes for button
text: 'Hello World!', // Text for button
onClick: e => Logger.log('Hello World!') // Button click handler
},
{
classes: ['exampleBtn'],
text: 'Button',
onClick: e => Logger.log('Button!')
}
]
}).render()); // Render will return the wrapped component that can then be displayed
}
/**
* Will log the channel object
*/