Add keybind setting

This commit is contained in:
Samuel Elliott 2018-03-08 02:38:12 +00:00
parent e78089a509
commit 0229482be8
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
12 changed files with 215 additions and 28 deletions

View File

@ -17,27 +17,29 @@ import DropdownSetting from './types/dropdown';
import RadioSetting from './types/radio';
import SliderSetting from './types/slider';
import ColourSetting from './types/colour';
import KeybindSetting from './types/keybind';
import FileSetting from './types/file';
import ArraySetting from './types/array';
import CustomSetting from './types/custom';
export default class Setting {
constructor(args) {
constructor(args, ...merge) {
args = args.args || args;
if (args.type === 'color') args.type = 'colour';
if (args.type === 'bool') return new BoolSetting(args);
else if (args.type === 'text') return new StringSetting(args);
else if (args.type === 'number') return new NumberSetting(args);
else if (args.type === 'dropdown') return new DropdownSetting(args);
else if (args.type === 'radio') return new RadioSetting(args);
else if (args.type === 'slider') return new SliderSetting(args);
else if (args.type === 'colour') return new ColourSetting(args);
else if (args.type === 'file') return new FileSetting(args);
else if (args.type === 'array') return new ArraySetting(args);
else if (args.type === 'custom') return new CustomSetting(args);
if (args.type === 'bool') return new BoolSetting(args, ...merge);
else if (args.type === 'text') return new StringSetting(args, ...merge);
else if (args.type === 'number') return new NumberSetting(args, ...merge);
else if (args.type === 'dropdown') return new DropdownSetting(args, ...merge);
else if (args.type === 'radio') return new RadioSetting(args, ...merge);
else if (args.type === 'slider') return new SliderSetting(args, ...merge);
else if (args.type === 'colour') return new ColourSetting(args, ...merge);
else if (args.type === 'keybind') return new KeybindSetting(args, ...merge);
else if (args.type === 'file') return new FileSetting(args, ...merge);
else if (args.type === 'array') return new ArraySetting(args, ...merge);
else if (args.type === 'custom') return new CustomSetting(args, ...merge);
else throw {message: `Setting type ${args.type} unknown`};
}

View File

@ -0,0 +1,28 @@
/**
* BetterDiscord Keybind Setting Struct
* 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 Setting from './basesetting';
import Combokeys from 'combokeys';
export default class KeybindSetting extends Setting {
constructor(args, ...merge) {
super(args, ...merge);
this.combokeys = new Combokeys(document);
this.combokeys.bind(this.value, event => this.emit('keybind-activated', event));
}
setValueHook() {
this.combokeys.reset();
this.combokeys.bind(this.value, event => this.emit('keybind-activated', event));
}
}

View File

@ -1,9 +1,10 @@
@import './main.scss';
@import './switches.scss';
@import './text.scss';
@import './files.scss';
@import './dropdowns.scss';
@import './radios.scss';
@import './sliders.scss';
@import './switches.scss';
@import './colourpickers.scss';
@import './keybinds.scss';
@import './arrays.scss';
@import './colourpicker.scss';

View File

@ -0,0 +1,52 @@
.bd-keybind {
padding: 10px;
display: flex;
// width: 180px;
margin-top: 10px;
background-color: rgba(0,0,0,.1);
border: 1px solid rgba(0,0,0,.3);
transition: border .15s ease;
border-radius: 3px;
box-sizing: border-box;
min-height: 40px;
.bd-keybind-selected {
flex: 1 1 auto;
color: #f6f6f7;
font-size: 14px;
}
&.bd-keybind-unset {
.bd-keybind-selected {
color: hsla(240,6%,97%,.3);
font-weight: 600;
}
}
.bd-button {
border-radius: 2px;
margin: -4px -4px -4px 10px;
padding: 2px 20px;
transition: background-color .2s ease-in-out, color .2s ease-in-out;
font-size: 14px;
font-weight: 500;
flex: 0 0 auto;
cursor: pointer;
}
&.bd-active {
border-color: $colerr;
animation: bd-keybind-pulse 1s infinite;
.bd-button {
color: $colerr;
background-color: rgba($colerr, .3);
}
}
}
@keyframes bd-keybind-pulse {
0% { box-shadow: 0 0 6px rgba(240,71,71,.3) }
50% { box-shadow: 0 0 10px rgba(240,71,71,.6) }
100% { box-shadow: 0 0 6px rgba(240,71,71,.3) }
}

View File

@ -1,12 +1,13 @@
.bd-setting-switch,
.bd-form-textinput,
.bd-form-textarea,
.bd-form-fileinput,
.bd-form-numberinput,
.bd-form-dropdown,
.bd-form-radio,
.bd-form-numberinput,
.bd-form-slider,
.bd-form-colourpicker,
.bd-setting-switch,
.bd-form-keybind,
.bd-form-fileinput,
.bd-form-settingsarray {
.bd-title {
display: flex;

View File

@ -0,0 +1,78 @@
/**
* BetterDiscord Setting Keybind 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-form-keybind">
<div class="bd-form-keybind-details">
<div class="bd-title">
<h3>{{ setting.text }}</h3>
</div>
<div class="bd-hint">{{ setting.hint }}</div>
</div>
<div class="bd-keybind" :class="{'bd-active': active, 'bd-disabled': setting.disabled, 'bd-keybind-unset': !setting.value}">
<div class="bd-keybind-selected">{{ selected || 'No Keybind Set' }}</div>
<button class="bd-button" v-tooltip="`Click to record a new keybind sequence${setting.value ? ' (shift + click to delete the sequence)' : ''}`" @click="$event.shiftKey ? deleteKeybind() : toggleActive(); $event.target.blur()">{{ active ? 'Stop Recording' : setting.value ? 'Edit Keybind' : 'Record Keybind' }}</button>
</div>
</div>
</template>
<script>
import { shell } from 'electron';
import { ClientIPC } from 'common';
import Combokeys from 'combokeys';
import CombokeysRecord from 'combokeys/plugins/record';
const combokeys = new Combokeys(document);
CombokeysRecord(combokeys);
const process = window.require('process');
const modifierKey = process.platform === 'darwin' ? 'meta' : 'ctrl';
export default {
props: ['setting'],
data() {
return {
active: false
};
},
computed: {
selected() {
return this.getDisplayString(this.setting.value);
}
},
watch: {
active(active) {
if (active) combokeys.record(this.recorded);
}
},
methods: {
toggleActive() {
if (this.setting.disabled) return;
this.active = !this.active;
},
deleteKeybind() {
this.setting.value = '';
},
recorded(sequence) {
if (!this.active) return;
this.active = false;
this.recordingValue = undefined;
this.setting.value = sequence.join(' ');
console.log('keypress', sequence);
},
getDisplayString(value) {
if (!value) return;
return value.split(' ').map(pattern => {
return pattern.toUpperCase().replace(/\+/g, ' + ').replace(/mod/gi, modifierKey).replace(/meta/gi, 'Cmd').replace(/ctrl/gi, 'Ctrl').replace(/alt/gi, 'Alt').replace(/shift/gi, 'Shift');
}).join(', ');
}
}
}
</script>

View File

@ -10,17 +10,18 @@
<template>
<div class="bd-form-item" :class="{'bd-form-item-changed': setting.changed, 'bd-disabled': disabled, 'bd-form-item-noheader': !setting.text, 'bd-form-item-fullwidth': setting.fullwidth}">
<BoolSetting v-if="setting.type === 'bool'" :setting="setting" :change="change"/>
<DropdownSetting v-if="setting.type === 'dropdown'" :setting="setting" :change="change"/>
<NumberSetting v-if="setting.type === 'number'" :setting="setting" :change="change"/>
<RadioSetting v-if="setting.type === 'radio'" :setting="setting" :change="change"/>
<StringSetting v-if="setting.type === 'text' && !setting.multiline" :setting="setting" :change="change"/>
<MultilineTextSetting v-if="setting.type === 'text' && setting.multiline" :setting="setting" :change="change"/>
<SliderSetting v-if="setting.type === 'slider'" :setting="setting" :change="change"/>
<FileSetting v-if="setting.type === 'file'" :setting="setting" :change="change"/>
<BoolSetting v-if="setting.type === 'bool'" :setting="setting" :change="change" />
<DropdownSetting v-if="setting.type === 'dropdown'" :setting="setting" :change="change" />
<NumberSetting v-if="setting.type === 'number'" :setting="setting" :change="change" />
<RadioSetting v-if="setting.type === 'radio'" :setting="setting" :change="change" />
<StringSetting v-if="setting.type === 'text' && !setting.multiline" :setting="setting" :change="change" />
<MultilineTextSetting v-if="setting.type === 'text' && setting.multiline" :setting="setting" />
<SliderSetting v-if="setting.type === 'slider'" :setting="setting" :change="change" />
<ColourSetting v-if="setting.type === 'colour'" :setting="setting" :change="change" />
<KeybindSetting v-if="setting.type === 'keybind'" :setting="setting" />
<FileSetting v-if="setting.type === 'file'" :setting="setting" :change="change" />
<ArraySetting v-if="setting.type === 'array'" :setting="setting" :change="change" />
<CustomSetting v-if="setting.type === 'custom'" :setting="setting" :change="change" />
<ColourSetting v-if="setting.type === 'colour'" :setting="setting" :change="change"/>
<div class="bd-form-divider"></div>
</div>
</template>
@ -33,10 +34,11 @@
import StringSetting from './String.vue';
import MultilineTextSetting from './Multiline.vue';
import SliderSetting from './Slider.vue';
import ColourSetting from './Colour.vue';
import KeybindSetting from './Keybind.vue';
import FileSetting from './File.vue';
import ArraySetting from './Array.vue';
import CustomSetting from './Custom.vue';
import ColourSetting from './Colour.vue';
export default {
props: [
@ -50,10 +52,11 @@
StringSetting,
MultilineTextSetting,
SliderSetting,
ColourSetting,
KeybindSetting,
FileSetting,
ArraySetting,
CustomSetting,
ColourSetting
CustomSetting
},
computed: {
changed() {

6
package-lock.json generated
View File

@ -2032,6 +2032,12 @@
"delayed-stream": "1.0.0"
}
},
"combokeys": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/combokeys/-/combokeys-3.0.0.tgz",
"integrity": "sha1-lVxZo5Wa9A0mhGq2/DxoJEjnVy4=",
"dev": true
},
"commander": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",

View File

@ -22,6 +22,7 @@
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"codemirror": "^5.23.0",
"combokeys": "^3.0.0",
"css-loader": "^0.28.9",
"electron": "^1.6.15",
"electron-rebuild": "^1.7.3",

View File

@ -77,6 +77,13 @@
]
}
]
},
{
"id": "keybind-1",
"type": "keybind",
"value": "mod+.",
"text": "Test Keybind Setting 1",
"hint": "Test Keybind Setting Hint 1"
}
]
}

View File

@ -7,6 +7,14 @@ module.exports = (Plugin, { Logger, Settings, BdMenu: { BdMenuItems }, Api }) =>
arraySetting.on('item-updated', event => Logger.log('Item', event.item, 'of the array setting was updated', event));
arraySetting.on('item-removed', event => Logger.log('Item', event.item, 'removed from the array setting'));
// Keybind setting examples
const keybindSetting = this.settings.getSetting('default', 'keybind-1');
Logger.log('Keybind setting', keybindSetting);
keybindSetting.on('keybind-activated', event => {
Logger.log('Keybind pressed', event);
Modals.basic('Example Plugin 4', 'Test keybind activated.');
});
// Create a new settings set and add it to the menu
const set = Settings.createSet({
text: this.name