From 0229482be847ba4b09164bc36970a0f940cf10fe Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Thu, 8 Mar 2018 02:38:12 +0000 Subject: [PATCH] Add keybind setting --- client/src/structs/settings/setting.js | 24 +++--- client/src/structs/settings/types/keybind.js | 28 +++++++ .../{colourpicker.scss => colourpickers.scss} | 0 .../styles/partials/generic/forms/index.scss | 5 +- .../partials/generic/forms/keybinds.scss | 52 +++++++++++++ .../styles/partials/generic/forms/main.scss | 7 +- .../src/ui/components/bd/setting/Keybind.vue | 78 +++++++++++++++++++ .../src/ui/components/bd/setting/Setting.vue | 27 ++++--- package-lock.json | 6 ++ package.json | 1 + tests/plugins/Example 4/config.json | 7 ++ tests/plugins/Example 4/index.js | 8 ++ 12 files changed, 215 insertions(+), 28 deletions(-) create mode 100644 client/src/structs/settings/types/keybind.js rename client/src/styles/partials/generic/forms/{colourpicker.scss => colourpickers.scss} (100%) create mode 100644 client/src/styles/partials/generic/forms/keybinds.scss create mode 100644 client/src/ui/components/bd/setting/Keybind.vue diff --git a/client/src/structs/settings/setting.js b/client/src/structs/settings/setting.js index 2927b342..7785e03b 100644 --- a/client/src/structs/settings/setting.js +++ b/client/src/structs/settings/setting.js @@ -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`}; } diff --git a/client/src/structs/settings/types/keybind.js b/client/src/structs/settings/types/keybind.js new file mode 100644 index 00000000..efbe3f90 --- /dev/null +++ b/client/src/structs/settings/types/keybind.js @@ -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)); + } + +} diff --git a/client/src/styles/partials/generic/forms/colourpicker.scss b/client/src/styles/partials/generic/forms/colourpickers.scss similarity index 100% rename from client/src/styles/partials/generic/forms/colourpicker.scss rename to client/src/styles/partials/generic/forms/colourpickers.scss diff --git a/client/src/styles/partials/generic/forms/index.scss b/client/src/styles/partials/generic/forms/index.scss index e1154656..e6cef62f 100644 --- a/client/src/styles/partials/generic/forms/index.scss +++ b/client/src/styles/partials/generic/forms/index.scss @@ -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'; diff --git a/client/src/styles/partials/generic/forms/keybinds.scss b/client/src/styles/partials/generic/forms/keybinds.scss new file mode 100644 index 00000000..49bea00c --- /dev/null +++ b/client/src/styles/partials/generic/forms/keybinds.scss @@ -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) } +} diff --git a/client/src/styles/partials/generic/forms/main.scss b/client/src/styles/partials/generic/forms/main.scss index 9ac4e8ce..470e6379 100644 --- a/client/src/styles/partials/generic/forms/main.scss +++ b/client/src/styles/partials/generic/forms/main.scss @@ -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; diff --git a/client/src/ui/components/bd/setting/Keybind.vue b/client/src/ui/components/bd/setting/Keybind.vue new file mode 100644 index 00000000..e59b3b35 --- /dev/null +++ b/client/src/ui/components/bd/setting/Keybind.vue @@ -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. +*/ + + + + diff --git a/client/src/ui/components/bd/setting/Setting.vue b/client/src/ui/components/bd/setting/Setting.vue index 4132f44d..147060c0 100644 --- a/client/src/ui/components/bd/setting/Setting.vue +++ b/client/src/ui/components/bd/setting/Setting.vue @@ -10,17 +10,18 @@ @@ -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() { diff --git a/package-lock.json b/package-lock.json index 75b7dd91..15334a32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 55e0f401..d31ba623 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/tests/plugins/Example 4/config.json b/tests/plugins/Example 4/config.json index c38da573..1c06afe2 100644 --- a/tests/plugins/Example 4/config.json +++ b/tests/plugins/Example 4/config.json @@ -77,6 +77,13 @@ ] } ] + }, + { + "id": "keybind-1", + "type": "keybind", + "value": "mod+.", + "text": "Test Keybind Setting 1", + "hint": "Test Keybind Setting Hint 1" } ] } diff --git a/tests/plugins/Example 4/index.js b/tests/plugins/Example 4/index.js index 35b6968d..38cdb3dc 100644 --- a/tests/plugins/Example 4/index.js +++ b/tests/plugins/Example 4/index.js @@ -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