Add autocomplete to the plugin API

This commit is contained in:
Samuel Elliott 2018-08-22 19:07:06 +01:00
parent 73192f5762
commit a0bee1846e
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
3 changed files with 77 additions and 9 deletions

View File

@ -23,6 +23,7 @@ import { WebpackModules } from './webpackmodules';
import DiscordApi from './discordapi';
import { ReactComponents, ReactHelpers } from './reactcomponents';
import { Patcher, MonkeyPatch } from './patcher';
import GlobalAc from '../ui/autocomplete';
export default class PluginApi {
@ -349,6 +350,43 @@ export default class PluginApi {
};
}
/**
* Autocomplete
*/
get autocompleteSets() {
return this._autocompleteSets || (this._autocompleteSets = new Map());
}
addAutocompleteController(prefix, controller) {
if (!controller) controller = this.plugin;
if (GlobalAc.validPrefix(prefix)) return;
GlobalAc.add(prefix, controller);
this.autocompleteSets.set(prefix, controller);
}
removeAutocompleteController(prefix) {
if (this.autocompleteSets.get(prefix) !== GlobalAc.sets.get(prefix)) return;
GlobalAc.remove(prefix);
this.autocompleteSets.delete(prefix);
}
removeAllAutocompleteControllers() {
for (let [prefix] of this.autocompleteSets) {
this.removeAutocompleteController(prefix);
}
}
validAutocompletePrefix(prefix) {
return GlobalAc.validPrefix(prefix);
}
get Autocomplete() {
return Object.defineProperty({
add: this.addAutocompleteController.bind(this),
remove: this.removeAutocompleteController.bind(this),
removeAll: this.removeAllAutocompleteControllers.bind(this),
validPrefix: this.validAutocompletePrefix.bind(this)
}, 'sets', {
get: () => this.autocompleteSets
});
}
/**
* Emotes
*/

View File

@ -4,15 +4,15 @@ import { VueInjector } from 'ui';
import AutocompleteComponent from './components/common/Autocomplete.vue';
import { Utils } from 'common';
export default new class AutoComplete {
export default new class Autocomplete {
get sets() {
return this._sets || (this._sets = {});
return this._sets || (this._sets = new Map());
}
async init() {
this.cta = await ReactComponents.getComponent('ChannelTextArea', { selector: WebpackModules.getSelector('channelTextArea', 'emojiButton') });
MonkeyPatch('BD:EMOTEMODULE', this.cta.component.prototype).after('render', this.channelTextAreaAfterRender.bind(this));
MonkeyPatch('BD:Autocomplete', this.cta.component.prototype).after('render', this.channelTextAreaAfterRender.bind(this));
this.initialized = true;
}
@ -32,21 +32,21 @@ export default new class AutoComplete {
add(prefix, controller) {
if (!this.initialized) this.init();
if (this.sets.hasOwnProperty(prefix)) return;
this.sets[prefix] = controller;
if (this.validPrefix(prefix)) return;
this.sets.set(prefix, controller);
}
remove(prefix) {
if (this.sets.hasOwnProperty(prefix)) delete this.sets[prefix];
this.sets.delete(prefix);
}
validPrefix(prefix) {
return this.sets.hasOwnProperty(prefix);
return this.sets.has(prefix);
}
items(prefix, sterm) {
if (!this.validPrefix(prefix)) return [];
return this.sets[prefix].acsearch(sterm);
return this.sets.get(prefix).acsearch(sterm);
}
}

View File

@ -1,4 +1,4 @@
exports.main = (Plugin, { Logger, Settings, Modals, BdMenu: { BdMenuItems }, CommonComponents, DiscordContextMenu, Api }) => class extends Plugin {
exports.main = (Plugin, { Logger, Settings, Modals, BdMenu: { BdMenuItems }, CommonComponents, DiscordContextMenu, Autocomplete, Api }) => class extends Plugin {
async onstart() {
this.keybindEvent = this.keybindEvent.bind(this);
@ -89,6 +89,13 @@ exports.main = (Plugin, { Logger, Settings, Modals, BdMenu: { BdMenuItems }, Com
onClick: () => Modals.basic('Test', 'Hello from Plugin 4')
}
]);
/**
* Autocomplete.
* This calls `acsearch` on the controller (the plugin object). You can add multiple autocomplete sets by passing another controller.
*/
Autocomplete.add('|');
}
onstop() {
@ -97,10 +104,33 @@ exports.main = (Plugin, { Logger, Settings, Modals, BdMenu: { BdMenuItems }, Com
BdMenuItems.removeAll();
DiscordContextMenu.removeAll();
Autocomplete.removeAll();
}
keybindEvent(event) {
Logger.log('Keybind pressed', event);
Modals.basic('Example Plugin 4', 'Test keybind activated.');
}
acsearch(sterm) {
// sterm is the text after the prefix
Logger.log('Searching for', sterm);
return {
title: ['Plugin 4 autocomplete'],
items: [
{key: 'Item 1', value: {replaceWith: 'Something to insert when selected'}},
{key: 'Item 2', value: {replaceWith: 'Something to insert when selected'}},
{key: 'Item 3', value: {replaceWith: 'Something to insert when selected'}},
{key: 'Item 4', value: {replaceWith: 'Something to insert when selected'}}
]
// `title` can also be an array - the second item will be white
// You can also add `type: 'imagetext'` here and add an `src` property to each item's value to show an image
};
}
get api() {
return Api;
}
};