From 946f68e4ef2bd16638363da59f4f7052803b6a86 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sun, 25 Mar 2018 18:31:17 +0100 Subject: [PATCH 01/42] Fix theme edit button --- client/src/ui/components/bd/ThemeCard.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/ui/components/bd/ThemeCard.vue b/client/src/ui/components/bd/ThemeCard.vue index 83c67d1a..6d6f2c64 100644 --- a/client/src/ui/components/bd/ThemeCard.vue +++ b/client/src/ui/components/bd/ThemeCard.vue @@ -33,7 +33,7 @@ methods: { editTheme() { try { - shell.openItem(this.theme.themePath); + shell.openItem(this.theme.contentPath); } catch (err) { Logger.err('ThemeCard', [`Error opening theme directory ${this.theme.contentPath}:`, err]); } From 10fd25607d085c6120a04550a4271b7efc498d3b Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Thu, 29 Mar 2018 20:04:01 +0100 Subject: [PATCH 02/42] Remove installer from release build script --- client/src/modules/pluginapi.js | 5 +++-- package.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/src/modules/pluginapi.js b/client/src/modules/pluginapi.js index dbdc74ce..eb0499e8 100644 --- a/client/src/modules/pluginapi.js +++ b/client/src/modules/pluginapi.js @@ -416,12 +416,13 @@ export default class PluginApi { instead: this.patchInstead.bind(this), pushChildPatch: this.pushChildPatch.bind(this), unpatchAll: this.unpatchAll.bind(this), + monkeyPatch: this.monkeyPatch.bind(this) }, 'patches', { get: () => this.patches }); } - get monkeyPatch() { - return module => MonkeyPatch(this.plugin.id, module); + monkeyPatch(module) { + return MonkeyPatch(this.plugin.id, module); } } diff --git a/package.json b/package.json index 7d86c9fd..62a2312d 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "lint": "eslint -f unix client/src core/src csseditor/src", "test": "npm run build && npm run lint", "build_node-sass": "node scripts/build-node-sass.js", - "build_release": "npm run release --prefix client && npm run build --prefix core && npm run release --prefix csseditor && npm run build --prefix installer", + "build_release": "npm run release --prefix client && npm run build --prefix core && npm run release --prefix csseditor", "release": "npm run lint && npm run build_release && gulp release" } } From 4634266e1451c44f7424c9cd9d93091ac5c03942 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Thu, 29 Mar 2018 20:16:06 +0100 Subject: [PATCH 03/42] Make the button look more built in --- client/src/styles/partials/bdsettings/button.scss | 2 -- client/src/styles/partials/bdsettings/sidebarview.scss | 6 +++--- client/src/styles/partials/discordoverrides.scss | 5 +++++ client/src/styles/partials/generic/forms/colourpickers.scss | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/client/src/styles/partials/bdsettings/button.scss b/client/src/styles/partials/bdsettings/button.scss index 635b17da..0069c3a4 100644 --- a/client/src/styles/partials/bdsettings/button.scss +++ b/client/src/styles/partials/bdsettings/button.scss @@ -5,7 +5,6 @@ width: 70px; height: 48px; left: 0; - background: #202225; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 2px 0 rgba(0, 0, 0, 0.06); opacity: 1; @@ -24,7 +23,6 @@ background-position: center; width: 100%; height: 100%; - z-index: 3001; cursor: pointer; filter: grayscale(100%); opacity: 0.5; diff --git a/client/src/styles/partials/bdsettings/sidebarview.scss b/client/src/styles/partials/bdsettings/sidebarview.scss index 0e7f175c..fd0155db 100644 --- a/client/src/styles/partials/bdsettings/sidebarview.scss +++ b/client/src/styles/partials/bdsettings/sidebarview.scss @@ -60,7 +60,7 @@ background-color: hsla(218,5%,47%,.3); .bd-material-design-icon { - fill: #FFF; + fill: #fff; } } } @@ -94,7 +94,7 @@ &:hover { .bd-material-design-icon { - fill: #FFF; + fill: #fff; } } } @@ -103,7 +103,7 @@ fill: #414245; &:hover { - fill: #FFF; + fill: #fff; } } } diff --git a/client/src/styles/partials/discordoverrides.scss b/client/src/styles/partials/discordoverrides.scss index 61950dd1..43c0f3b2 100644 --- a/client/src/styles/partials/discordoverrides.scss +++ b/client/src/styles/partials/discordoverrides.scss @@ -17,3 +17,8 @@ top: 50px; } } + +// Any layers need to be above the main layer (where the BD button is placed) +.layer-kosS71 + .layer-kosS71 { + z-index: 900; +} diff --git a/client/src/styles/partials/generic/forms/colourpickers.scss b/client/src/styles/partials/generic/forms/colourpickers.scss index 968b6461..100ba885 100644 --- a/client/src/styles/partials/generic/forms/colourpickers.scss +++ b/client/src/styles/partials/generic/forms/colourpickers.scss @@ -21,7 +21,7 @@ .vc-chrome-fields-wrap { .vc-input__input { background: #1e2124; - color: #FFF; + color: #fff; box-shadow: inset 0 0 0 1px #000; } @@ -30,7 +30,7 @@ } .vc-chrome-toggle-btn svg path { - fill: #FFF; + fill: #fff; } } } From 441e80e0e8b21be14585ea808f2ac8faa0190502 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Thu, 29 Mar 2018 21:23:15 +0100 Subject: [PATCH 04/42] Tweak colour picker and add animation --- .../partials/generic/forms/colourpickers.scss | 16 ++++- .../src/ui/components/bd/setting/Colour.vue | 59 +++++++++---------- .../src/ui/components/bd/setting/Setting.vue | 2 +- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/client/src/styles/partials/generic/forms/colourpickers.scss b/client/src/styles/partials/generic/forms/colourpickers.scss index 100ba885..7ae9837c 100644 --- a/client/src/styles/partials/generic/forms/colourpickers.scss +++ b/client/src/styles/partials/generic/forms/colourpickers.scss @@ -10,7 +10,7 @@ .vc-chrome { position: absolute; - right: 60px; + right: 0; top: 35px; border-radius: 3px; z-index: 9001; @@ -34,5 +34,19 @@ } } } + + &:not(.bd-hide) { + animation: bd-colourpicker-slidein 0.1s ease-in; + } + } +} + +@keyframes bd-colourpicker-slidein { + 0% { + right: 20px; + } + + 100% { + right: 0; } } diff --git a/client/src/ui/components/bd/setting/Colour.vue b/client/src/ui/components/bd/setting/Colour.vue index 698ebe2c..99718f29 100644 --- a/client/src/ui/components/bd/setting/Colour.vue +++ b/client/src/ui/components/bd/setting/Colour.vue @@ -9,74 +9,67 @@ */ - diff --git a/client/src/ui/components/bd/setting/Setting.vue b/client/src/ui/components/bd/setting/Setting.vue index cc1250c5..eec9c892 100644 --- a/client/src/ui/components/bd/setting/Setting.vue +++ b/client/src/ui/components/bd/setting/Setting.vue @@ -17,7 +17,7 @@ - + From 9b1dd771ad980582a411b41a19701cf5da2d00c6 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Thu, 29 Mar 2018 21:46:33 +0100 Subject: [PATCH 05/42] Use v-model/events instead of a change function Custom settings still work the same --- client/src/styles/partials/generic/forms.scss | 2 -- client/src/ui/components/BdSettings.vue | 1 + .../src/ui/components/BdSettingsWrapper.vue | 1 + client/src/ui/components/bd/PluginCard.vue | 2 +- client/src/ui/components/bd/ThemeCard.vue | 2 +- client/src/ui/components/bd/setting/Array.vue | 2 +- client/src/ui/components/bd/setting/Bool.vue | 5 ++-- .../src/ui/components/bd/setting/Colour.vue | 1 + .../src/ui/components/bd/setting/Custom.vue | 9 ++++++- .../src/ui/components/bd/setting/Dropdown.vue | 7 +++--- client/src/ui/components/bd/setting/File.vue | 11 ++++---- .../src/ui/components/bd/setting/Keybind.vue | 2 +- .../ui/components/bd/setting/Multiline.vue | 1 + .../src/ui/components/bd/setting/Number.vue | 17 +++++++------ client/src/ui/components/bd/setting/Radio.vue | 5 ++-- .../src/ui/components/bd/setting/Setting.vue | 25 ++++++++----------- .../src/ui/components/bd/setting/Slider.vue | 17 +++++-------- .../src/ui/components/bd/setting/String.vue | 10 +++----- client/src/ui/components/common/Dropdown.vue | 10 +++++--- .../src/ui/components/common/RadioGroup.vue | 11 +++++--- .../ui/components/common/SettingSwitch.vue | 7 +++--- 21 files changed, 78 insertions(+), 70 deletions(-) diff --git a/client/src/styles/partials/generic/forms.scss b/client/src/styles/partials/generic/forms.scss index a417627c..747acb7c 100644 --- a/client/src/styles/partials/generic/forms.scss +++ b/client/src/styles/partials/generic/forms.scss @@ -43,8 +43,6 @@ font-size: 12px; } - - .bd-form-divider { height: 1px; margin: 15px 0; diff --git a/client/src/ui/components/BdSettings.vue b/client/src/ui/components/BdSettings.vue index f2bc4afc..38522ed8 100644 --- a/client/src/ui/components/BdSettings.vue +++ b/client/src/ui/components/BdSettings.vue @@ -55,6 +55,7 @@ + diff --git a/client/src/ui/components/bd/setting/Slider.vue b/client/src/ui/components/bd/setting/Slider.vue index 9609cb87..97171b5c 100644 --- a/client/src/ui/components/bd/setting/Slider.vue +++ b/client/src/ui/components/bd/setting/Slider.vue @@ -9,7 +9,7 @@ */ + diff --git a/client/src/ui/components/common/Dropdown.vue b/client/src/ui/components/common/Dropdown.vue index c0cb984d..5f14d3b1 100644 --- a/client/src/ui/components/common/Dropdown.vue +++ b/client/src/ui/components/common/Dropdown.vue @@ -17,13 +17,13 @@
-
{{ option.text }}
+
{{ option.text }}
diff --git a/client/src/ui/components/common/SettingSwitch.vue b/client/src/ui/components/common/SettingSwitch.vue index 5fe1ddf1..69b0e32d 100644 --- a/client/src/ui/components/common/SettingSwitch.vue +++ b/client/src/ui/components/common/SettingSwitch.vue @@ -9,13 +9,14 @@ */ + From fd3b0a92ce601fac30a7b27fb7b32646776afd9e Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Fri, 30 Mar 2018 00:57:01 +0100 Subject: [PATCH 06/42] Use events on modal close button click --- .../ui/components/bd/modals/BasicModal.vue | 2 +- .../ui/components/bd/modals/ConfirmModal.vue | 2 +- .../ui/components/bd/modals/ErrorModal.vue | 2 +- .../components/bd/modals/PermissionModal.vue | 2 +- .../ui/components/bd/modals/SettingsModal.vue | 9 +++--- .../src/ui/components/common/ErrorModal.vue | 30 ------------------- client/src/ui/components/common/Modal.vue | 11 ++++--- 7 files changed, 13 insertions(+), 45 deletions(-) delete mode 100644 client/src/ui/components/common/ErrorModal.vue diff --git a/client/src/ui/components/bd/modals/BasicModal.vue b/client/src/ui/components/bd/modals/BasicModal.vue index 850d7dda..2660c353 100644 --- a/client/src/ui/components/bd/modals/BasicModal.vue +++ b/client/src/ui/components/bd/modals/BasicModal.vue @@ -9,7 +9,7 @@ */ + diff --git a/client/src/ui/components/sidebar/Header.vue b/client/src/ui/components/sidebar/Header.vue index fbc31834..624cd62b 100644 --- a/client/src/ui/components/sidebar/Header.vue +++ b/client/src/ui/components/sidebar/Header.vue @@ -13,6 +13,7 @@ {{item.text}} + diff --git a/client/src/ui/components/sidebar/View.vue b/client/src/ui/components/sidebar/View.vue index e2653b2f..51851b6d 100644 --- a/client/src/ui/components/sidebar/View.vue +++ b/client/src/ui/components/sidebar/View.vue @@ -23,6 +23,7 @@ + diff --git a/client/src/builtin/EmoteComponent.vue b/client/src/builtin/EmoteComponent.vue index 98cd63a1..60b4d6bf 100644 --- a/client/src/builtin/EmoteComponent.vue +++ b/client/src/builtin/EmoteComponent.vue @@ -1,6 +1,6 @@ diff --git a/client/src/ui/components/BdSettings.vue b/client/src/ui/components/BdSettings.vue index b4f6aafe..c1e297fd 100644 --- a/client/src/ui/components/BdSettings.vue +++ b/client/src/ui/components/BdSettings.vue @@ -9,10 +9,10 @@ */ From 1bde3b4ec973e484921b652d05ce92e2ce0eef2a Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sat, 31 Mar 2018 03:26:42 +0100 Subject: [PATCH 24/42] Add setting to enable/disable emotes --- client/src/builtin/EmoteModule.js | 14 ++++++++++- client/src/data/user.settings.default.json | 28 +++++++++++++++------- client/src/index.js | 2 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/client/src/builtin/EmoteModule.js b/client/src/builtin/EmoteModule.js index 95b43241..d193ea30 100644 --- a/client/src/builtin/EmoteModule.js +++ b/client/src/builtin/EmoteModule.js @@ -24,6 +24,18 @@ export default new class EmoteModule { this.favourite_emotes = []; } + init() { + this.enabledSetting = Settings.getSetting('emotes', 'default', 'enable'); + this.enabledSetting.on('setting-updated', event => { + // Rerender all messages (or if we're disabling emotes, those that have emotes) + for (const message of document.querySelectorAll(event.value ? '.message' : '.bd-emote-outer')) { + Reflection(event.value ? message : message.closest('.message')).forceUpdate(); + } + }); + + return this.observe(); + } + /** * Sets an emote as favourite. * @param {String} emote The name of the emote @@ -66,7 +78,7 @@ export default new class EmoteModule { } processMarkup(markup, timestamp) { - if (!emotesEnabled) return markup; // TODO Get it from setttings + if (!this.enabledSetting.value) return markup; timestamp = timestamp.valueOf(); const allowNoWrapper = timestamp < enforceWrapperFrom; diff --git a/client/src/data/user.settings.default.json b/client/src/data/user.settings.default.json index 3cf0ddda..7038d652 100644 --- a/client/src/data/user.settings.default.json +++ b/client/src/data/user.settings.default.json @@ -5,7 +5,7 @@ "headertext": "Core Settings", "settings": [ { - "category": "default", + "id": "default", "settings": [ { "id": "test-setting", @@ -40,8 +40,8 @@ ] }, { - "category": "advanced", - "category_name": "Advanced", + "id": "advanced", + "name": "Advanced", "type": "drawer", "settings": [ { @@ -74,7 +74,7 @@ "headertext": "UI Settings", "settings": [ { - "category": "default", + "id": "default", "settings": [ { "id": "hide-button", @@ -92,14 +92,26 @@ "id": "emotes", "text": "Emotes", "headertext": "Emote Settings", - "settings": [] + "settings": [ + { + "id": "default", + "settings": [ + { + "id": "enable", + "type": "bool", + "text": "Enable emotes", + "value": true + } + ] + } + ] }, { "id": "css", "text": "CSS Editor", "settings": [ { - "category": "default", + "id": "default", "settings": [ { "id": "live-update", @@ -123,8 +135,6 @@ "id": "security", "text": "Security", "headertext": "Security Settings", - "settings": [ - - ] + "settings": [] } ] diff --git a/client/src/index.js b/client/src/index.js index e5867217..77ad5d24 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -76,7 +76,7 @@ class BetterDiscord { Events.emit('ready'); Events.emit('discord-ready'); - EmoteModule.observe(); + EmoteModule.init(); } catch (err) { Logger.err('main', ['FAILED TO LOAD!', err]); } From b3442ee1085870d4948b18fa6bfab755264ca34b Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sat, 31 Mar 2018 04:37:26 +0100 Subject: [PATCH 25/42] Store emote database in a map --- client/src/builtin/EmoteModule.js | 135 +++++++++--------- .../styles/partials/generic/autocomplete.scss | 10 +- 2 files changed, 72 insertions(+), 73 deletions(-) diff --git a/client/src/builtin/EmoteModule.js b/client/src/builtin/EmoteModule.js index d193ea30..4b80d718 100644 --- a/client/src/builtin/EmoteModule.js +++ b/client/src/builtin/EmoteModule.js @@ -14,17 +14,16 @@ import { Utils, FileUtils, ClientLogger as Logger } from 'common'; import path from 'path'; import EmoteComponent from './EmoteComponent.vue'; -let emotes = null; -const emotesEnabled = true; const enforceWrapperFrom = (new Date('2018-05-01')).valueOf(); export default new class EmoteModule { constructor() { + this.emotes = new Map(); this.favourite_emotes = []; } - init() { + async init() { this.enabledSetting = Settings.getSetting('emotes', 'default', 'enable'); this.enabledSetting.on('setting-updated', event => { // Rerender all messages (or if we're disabling emotes, those that have emotes) @@ -33,7 +32,25 @@ export default new class EmoteModule { } }); - return this.observe(); + const dataPath = Globals.getPath('data'); + try { + const emotes = await FileUtils.readJsonFromFile(path.join(dataPath, 'emotes.json')); + for (let emote of emotes) { + const uri = emote.type === 2 ? 'https://cdn.betterttv.net/emote/:id/1x' : emote.type === 1 ? 'https://cdn.frankerfacez.com/emoticon/:id/1' : 'https://static-cdn.jtvnw.net/emoticons/v1/:id/1.0'; + emote.name = emote.id; + emote.src = uri.replace(':id', emote.value.id || emote.value); + this.emotes.set(emote.id, emote); + } + } catch (err) { + Logger.err('EmoteModule', [`Failed to load emote data. Make sure you've downloaded the emote data and placed it in ${dataPath}:`, err]); + return; + } + + try { + await this.observe(); + } catch (err) { + Logger.err('EmoteModule', ['Error patching Message', err]); + } } /** @@ -65,10 +82,6 @@ export default new class EmoteModule { return this._searchCache || (this._searchCache = {}); } - get emoteDb() { - return emotes; - } - get React() { return WebpackModules.getModuleByName('React'); } @@ -97,16 +110,16 @@ export default new class EmoteModule { if (!words) continue; let text = null; for (const [wordIndex, word] of words.entries()) { - const isEmote = this.isEmote(word); - if (isEmote) { + const emote = this.getEmote(word); + if (emote) { if (text !== null) { newMarkup.push(text); text = null; } newMarkup.push(this.React.createElement('span', { className: 'bd-emote-outer', - 'data-bdemote-name': isEmote.name, - 'data-bdemote-src': isEmote.src, + 'data-bdemote-name': emote.name, + 'data-bdemote-src': emote.src, 'data-has-wrapper': /;[\w]+;/gmi.test(word) })); continue; @@ -129,7 +142,8 @@ export default new class EmoteModule { } injectAll() { - if (!emotesEnabled) return; + if (!this.enabledSetting.value) return; + const all = document.getElementsByClassName('bd-emote-outer'); for (const ec of all) { if (ec.children.length) continue; @@ -150,48 +164,36 @@ export default new class EmoteModule { } async observe() { - const dataPath = Globals.getPath('data'); - try { - emotes = await FileUtils.readJsonFromFile(path.join(dataPath, 'emotes.json')); - } catch (err) { - Logger.err('EmoteModule', [`Failed to load emote data. Make sure you've downloaded the emote data and placed it in ${dataPath}:`, err]); - return; - } - - try { - const Message = await ReactComponents.getComponent('Message'); - this.unpatchRender = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('render', (component, args, retVal) => { - try { - // First child has all the actual text content, second is the edited timestamp - const markup = this.findByProp(retVal, 'className', 'markup'); - if (!markup) return; - Logger.log('EmoteModule', ['Message :', retVal, component]); - markup.children[0] = this.processMarkup(markup.children[0], component.props.message.editedTimestamp || component.props.message.timestamp); - } catch (err) { - Logger.err('EmoteModule', err); - } - }); - for (const message of document.querySelectorAll('.message')) { - Reflection(message).forceUpdate(); + const Message = await ReactComponents.getComponent('Message'); + this.unpatchRender = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('render', (component, args, retVal) => { + try { + // First child has all the actual text content, second is the edited timestamp + const markup = this.findByProp(retVal, 'className', 'markup'); + if (!markup) return; + markup.children[0] = this.processMarkup(markup.children[0], component.props.message.editedTimestamp || component.props.message.timestamp); + } catch (err) { + Logger.err('EmoteModule', err); } - this.injectAll(); - this.unpatchMount = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('componentDidMount', component => { - const element = this.ReactDOM.findDOMNode(component); - if (!element) return; - this.injectEmotes(element); - }); - this.unpatchUpdate = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('componentDidUpdate', component => { - const element = this.ReactDOM.findDOMNode(component); - if (!element) return; - this.injectEmotes(element); - }); - } catch (err) { - Logger.err('EmoteModule', err); + }); + for (const message of document.querySelectorAll('.message')) { + Reflection(message).forceUpdate(); } + this.injectAll(); + this.unpatchMount = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('componentDidMount', component => { + const element = this.ReactDOM.findDOMNode(component); + if (!element) return; + this.injectEmotes(element); + }); + this.unpatchUpdate = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('componentDidUpdate', component => { + const element = this.ReactDOM.findDOMNode(component); + if (!element) return; + this.injectEmotes(element); + }); } injectEmote(root) { - if (!emotesEnabled) return; + if (!this.enabledSetting.value) return; + while (root.firstChild) { root.removeChild(root.firstChild); } @@ -206,25 +208,14 @@ export default new class EmoteModule { } injectEmotes(element) { - if (!emotesEnabled || !element) return; + if (!this.enabledSetting.value || !element) return; + for (const beo of element.getElementsByClassName('bd-emote-outer')) this.injectEmote(beo); } - isEmote(word) { - if (!emotes) return null; + getEmote(word) { const name = word.replace(/;/g, ''); - const emote = emotes.find(emote => emote.id === name); - if (!emote) return null; - let { id, value } = emote; - if (value.id) value = value.id; - const uri = emote.type === 2 ? 'https://cdn.betterttv.net/emote/:id/1x' : emote.type === 1 ? 'https://cdn.frankerfacez.com/emoticon/:id/1' : 'https://static-cdn.jtvnw.net/emoticons/v1/:id/1.0'; - return { name, src: uri.replace(':id', value) }; - } - - filterTest() { - const re = new RegExp('Kappa', 'i'); - const filtered = emotes.filter(emote => re.test(emote.id)); - return filtered.slice(0, 10); + return this.emotes.get(name); } filter(regex, limit, start = 0) { @@ -232,17 +223,21 @@ export default new class EmoteModule { if (this.searchCache.hasOwnProperty(key)) return this.searchCache[key]; let index = 0; let startIndex = 0; - return this.searchCache[key] = emotes.filter(emote => { - if (index >= limit) return false; + + const matching = this.searchCache[key] = []; + for (let emote of this.emotes.values()) { + if (index >= limit) break; if (regex.test(emote.id)) { if (startIndex < start) { startIndex++; - return false; + continue; } index++; - return true; + matching.push(emote); } - }); + } + + return matching; } } diff --git a/client/src/styles/partials/generic/autocomplete.scss b/client/src/styles/partials/generic/autocomplete.scss index bfc8ebd5..75312e1e 100644 --- a/client/src/styles/partials/generic/autocomplete.scss +++ b/client/src/styles/partials/generic/autocomplete.scss @@ -25,10 +25,14 @@ &.bd-selectable { cursor: pointer; - } - &.bd-selected { - background-color: #36393f; + &:hover { + background-color: darken(#36393f, 5%); + } + + &.bd-selected { + background-color: #36393f; + } } .bd-autocomplete-title { From c701a2b5f959aa1041b6f29957b7fc1573a2c42f Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sat, 31 Mar 2018 16:51:14 +0100 Subject: [PATCH 26/42] Add emotes to the plugin API --- client/src/modules/pluginapi.js | 51 +++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/client/src/modules/pluginapi.js b/client/src/modules/pluginapi.js index d01288ad..f76dbfd2 100644 --- a/client/src/modules/pluginapi.js +++ b/client/src/modules/pluginapi.js @@ -8,6 +8,9 @@ * LICENSE file in the root directory of this source tree. */ +import { EmoteModule } from 'builtin'; +import { SettingsSet, SettingsCategory, Setting, SettingsScheme } from 'structs'; +import { BdMenu, Modals, DOM, Reflection } from 'ui'; import { Utils, ClientLogger as Logger, ClientIPC, AsyncEventEmitter } from 'common'; import Settings from './settings'; import ExtModuleManager from './extmodulemanager'; @@ -16,8 +19,6 @@ import ThemeManager from './thememanager'; import Events from './events'; import EventsWrapper from './eventswrapper'; import { WebpackModules } from './webpackmodules'; -import { SettingsSet, SettingsCategory, Setting, SettingsScheme } from 'structs'; -import { BdMenu, Modals, DOM, Reflection } from 'ui'; import DiscordApi from './discordapi'; import { ReactComponents } from './reactcomponents'; import { Patcher, MonkeyPatch } from './patcher'; @@ -290,6 +291,52 @@ export default class PluginApi { }); } + /** + * Emotes + */ + + get emotes() { + return EmoteModule.emotes; + } + get favourite_emotes() { + return EmoteModule.favourite_emotes; + } + setFavouriteEmote(emote, favourite) { + return EmoteModule.setFavourite(emote, favourite); + } + addFavouriteEmote(emote) { + return EmoteModule.addFavourite(emote); + } + removeFavouriteEmote(emote) { + return EmoteModule.addFavourite(emote); + } + isFavouriteEmote(emote) { + return EmoteModule.isFavourite(emote); + } + getEmote(emote) { + return EmoteModule.getEmote(emote); + } + filterEmotes(regex, limit, start = 0) { + return EmoteModule.filterEmotes(regex, limit, start); + } + get Emotes() { + return Object.defineProperties({ + setFavourite: this.setFavouriteEmote.bind(this), + addFavourite: this.addFavouriteEmote.bind(this), + removeFavourite: this.removeFavouriteEmote.bind(this), + isFavourite: this.isFavouriteEmote.bind(this), + getEmote: this.getEmote.bind(this), + filter: this.filterEmotes.bind(this) + }, { + emotes: { + get: () => this.emotes + }, + favourite_emotes: { + get: () => this.favourite_emotes + } + }); + } + /** * Plugins */ From 0e14d167dcc14534a67096b77a669dfa120e1994 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sat, 31 Mar 2018 17:38:11 +0100 Subject: [PATCH 27/42] Fix event callbacks not being passed any arguments --- client/src/modules/eventswrapper.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/modules/eventswrapper.js b/client/src/modules/eventswrapper.js index 8196e561..bd8ece2b 100644 --- a/client/src/modules/eventswrapper.js +++ b/client/src/modules/eventswrapper.js @@ -23,14 +23,14 @@ export default class EventsWrapper { get on() { return this.subscribe } subscribe(event, callback) { if (this.eventSubs.find(e => e.event === event && e.callback === callback)) return; - const boundCallback = () => callback.apply(this.bind, arguments); + const boundCallback = (...args) => callback.apply(this.bind, args); this.eventSubs.push({ event, callback, boundCallback }); eventemitters.get(this).on(event, boundCallback); } once(event, callback) { if (this.eventSubs.find(e => e.event === event && e.callback === callback)) return; - const boundCallback = () => this.off(event, callback) && callback.apply(this.bind, arguments); + const boundCallback = (...args) => this.off(event, callback) && callback.apply(this.bind, args); this.eventSubs.push({ event, callback, boundCallback }); eventemitters.get(this).on(event, boundCallback); } @@ -50,4 +50,5 @@ export default class EventsWrapper { } this.eventSubs.splice(0, this.eventSubs.length); } + } From 3eb1782a645eea90ca7048b15f66741e46d9b059 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sat, 31 Mar 2018 22:44:24 +0100 Subject: [PATCH 28/42] Fix for Discord Canary --- core/src/main.js | 24 ++++++++++++-- core/src/patch-browser-window.js | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 core/src/patch-browser-window.js diff --git a/core/src/main.js b/core/src/main.js index d66c5465..f721eb73 100644 --- a/core/src/main.js +++ b/core/src/main.js @@ -52,8 +52,19 @@ const globals = { paths }; -class Comms { +class PatchedBrowserWindow extends BrowserWindow { + constructor(originalOptions) { + const options = Object.assign({}, originalOptions); + options.webPreferences = Object.assign({}, options.webPreferences); + options.webPreferences.nodeIntegration = true; + + console.log('Creating new BrowserWindow with options', options, originalOptions); + return new BrowserWindow(options); + } +} + +class Comms { constructor(bd) { this.bd = bd; this.initListeners(); @@ -101,7 +112,6 @@ class Comms { async sendToCssEditor(channel, message) { return this.bd.csseditor.send(channel, message); } - } class BetterDiscord { @@ -201,8 +211,18 @@ class BetterDiscord { return this.windowUtils.injectScript(this.config.getPath('cs')); } + static patchBrowserWindow() { + const electron_path = require.resolve('electron'); + const browser_window_path = require.resolve(path.resolve(electron_path, '..', '..', 'browser-window.js')); + const browser_window_module = require.cache[browser_window_path]; + + browser_window_module.exports = PatchedBrowserWindow; + } + } +BetterDiscord.patchBrowserWindow(); + module.exports = { BetterDiscord }; diff --git a/core/src/patch-browser-window.js b/core/src/patch-browser-window.js new file mode 100644 index 00000000..b8378daf --- /dev/null +++ b/core/src/patch-browser-window.js @@ -0,0 +1,57 @@ + + +const electron = require('electron'); +const path = require('path'); + +const _BrowserWindow = electron.BrowserWindow; + +console.log('Open windows:', _BrowserWindow.getAllWindows()); +console.log('Open window URLs:', _BrowserWindow.getAllWindows().map(w => w.getURL())); + +console.log('Patching BrowserWindow'); + +class PatchedBrowserWindow extends _BrowserWindow { + constructor(originalOptions) { + const options = Object.assign({}, originalOptions); + options.webPreferences = Object.assign({}, options.webPreferences); + + options.webPreferences.nodeIntegration = true; + + console.log('Creating new BrowserWindow with options', options, originalOptions); + return new _BrowserWindow(options); + } +}; + +// Can't just do this because electron.BrowserWindow is a getter +// electron.BrowserWindow = PatchedBrowserWindow; + +// Can't do this either because it's not configurable because ^^ +// Object.defineProperty(electron, 'BrowserWindow', { +// get: () => PatchedBrowserWindow +// }); + +console.log('Electron:', electron); + +console.log('Electron BrowserWindow getter:', electron.__lookupGetter__('BrowserWindow')); +console.log('Electron BrowserWindow setter:', electron.__lookupSetter__('BrowserWindow')); + +const electron_path = require.resolve('electron'); +const electron_module = require.cache[electron_path]; +console.log('Electron module path:', electron_path); +console.log('Electron module:', electron_module); + +const browser_window_path = require.resolve(path.resolve(electron_path, '..', '..', 'browser-window.js')); +const browser_window_module = require.cache[browser_window_path]; +console.log('BrowserWindow module path:', browser_window_path); +console.log('BrowserWindow module:', browser_window_module); + +browser_window_module.exports = PatchedBrowserWindow; + +try { + new (require("../../../../BetterDiscord")).BetterDiscord(); +} catch (err) { + console.err('Error loading BetterDiscord:', err); +} + +// Main window is created here +module.exports = require('./core'); From 858fdcec59adf33f64a4b37cd61d055cad789b30 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sat, 31 Mar 2018 22:49:00 +0100 Subject: [PATCH 29/42] Clean up and comment --- core/src/main.js | 7 +++- core/src/patch-browser-window.js | 57 -------------------------------- 2 files changed, 6 insertions(+), 58 deletions(-) delete mode 100644 core/src/patch-browser-window.js diff --git a/core/src/main.js b/core/src/main.js index f721eb73..ecc6eea6 100644 --- a/core/src/main.js +++ b/core/src/main.js @@ -57,9 +57,9 @@ class PatchedBrowserWindow extends BrowserWindow { const options = Object.assign({}, originalOptions); options.webPreferences = Object.assign({}, options.webPreferences); + // Make sure Node integration is enabled options.webPreferences.nodeIntegration = true; - console.log('Creating new BrowserWindow with options', options, originalOptions); return new BrowserWindow(options); } } @@ -211,6 +211,11 @@ class BetterDiscord { return this.windowUtils.injectScript(this.config.getPath('cs')); } + /** + * Patches Electron's BrowserWindow so all windows have Node integration enabled. + * This needs to be called only once before the main window is created (or BrowserWindow is put in a variable). + * Basically BetterDiscord needs to load before discord_desktop_core. + */ static patchBrowserWindow() { const electron_path = require.resolve('electron'); const browser_window_path = require.resolve(path.resolve(electron_path, '..', '..', 'browser-window.js')); diff --git a/core/src/patch-browser-window.js b/core/src/patch-browser-window.js deleted file mode 100644 index b8378daf..00000000 --- a/core/src/patch-browser-window.js +++ /dev/null @@ -1,57 +0,0 @@ - - -const electron = require('electron'); -const path = require('path'); - -const _BrowserWindow = electron.BrowserWindow; - -console.log('Open windows:', _BrowserWindow.getAllWindows()); -console.log('Open window URLs:', _BrowserWindow.getAllWindows().map(w => w.getURL())); - -console.log('Patching BrowserWindow'); - -class PatchedBrowserWindow extends _BrowserWindow { - constructor(originalOptions) { - const options = Object.assign({}, originalOptions); - options.webPreferences = Object.assign({}, options.webPreferences); - - options.webPreferences.nodeIntegration = true; - - console.log('Creating new BrowserWindow with options', options, originalOptions); - return new _BrowserWindow(options); - } -}; - -// Can't just do this because electron.BrowserWindow is a getter -// electron.BrowserWindow = PatchedBrowserWindow; - -// Can't do this either because it's not configurable because ^^ -// Object.defineProperty(electron, 'BrowserWindow', { -// get: () => PatchedBrowserWindow -// }); - -console.log('Electron:', electron); - -console.log('Electron BrowserWindow getter:', electron.__lookupGetter__('BrowserWindow')); -console.log('Electron BrowserWindow setter:', electron.__lookupSetter__('BrowserWindow')); - -const electron_path = require.resolve('electron'); -const electron_module = require.cache[electron_path]; -console.log('Electron module path:', electron_path); -console.log('Electron module:', electron_module); - -const browser_window_path = require.resolve(path.resolve(electron_path, '..', '..', 'browser-window.js')); -const browser_window_module = require.cache[browser_window_path]; -console.log('BrowserWindow module path:', browser_window_path); -console.log('BrowserWindow module:', browser_window_module); - -browser_window_module.exports = PatchedBrowserWindow; - -try { - new (require("../../../../BetterDiscord")).BetterDiscord(); -} catch (err) { - console.err('Error loading BetterDiscord:', err); -} - -// Main window is created here -module.exports = require('./core'); From 2f9af2e2d012e2c3746a768bee6a0092785e6125 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sat, 31 Mar 2018 23:06:24 +0100 Subject: [PATCH 30/42] Use correct Electron version --- package-lock.json | 24 ++++++++++++------------ package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 429ea27f..2d6c521a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@types/node": { - "version": "8.9.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.9.4.tgz", - "integrity": "sha1-39MnWCoGwRTrbgRB+j1vqzXtrUg=", + "version": "7.0.58", + "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.58.tgz", + "integrity": "sha512-4LwjraUddrN+sJ2cL7v64w9fEWQ0zUlDdB8yqmFrWlavHkXxjxBSnZ4ofeW5SbHLpUE0Ve3XvijT/eQmylzasg==", "dev": true }, "abbrev": { @@ -2820,12 +2820,12 @@ } }, "electron": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/electron/-/electron-1.8.2.tgz", - "integrity": "sha1-qBfNczwpcrPHzE93fK9uQkuIAU0=", + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/electron/-/electron-1.6.15.tgz", + "integrity": "sha1-w07FRIa39Jpm21jG8koJKEFPrqc=", "dev": true, "requires": { - "@types/node": "8.9.4", + "@types/node": "7.0.58", "electron-download": "3.3.0", "extract-zip": "1.6.6" } @@ -2842,7 +2842,7 @@ "minimist": "1.2.0", "nugget": "2.0.1", "path-exists": "2.1.0", - "rc": "1.2.5", + "rc": "1.2.6", "semver": "5.5.0", "sumchecker": "1.3.1" }, @@ -3048,7 +3048,7 @@ "es6-promise": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha1-3EIhwrFlGHYL2MOaUtjzVvwA7Sk=", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", "dev": true }, "es6-set": { @@ -9671,9 +9671,9 @@ } }, "rc": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.5.tgz", - "integrity": "sha1-J1zWh/bjs2zHVrqibf7oCnkDAf0=", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz", + "integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=", "dev": true, "requires": { "deep-extend": "0.4.2", diff --git a/package.json b/package.json index 62a2312d..13f0ccec 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "combokeys": "^3.0.0", "css-loader": "^0.28.9", "del": "^3.0.0", - "electron": "^1.6.15", + "electron": "1.6.15", "electron-rebuild": "^1.7.3", "eslint": "^4.16.0", "eslint-plugin-vue": "^4.3.0", From 60a82a3ad9d0ef5c2fdf80dd5dd23fdf006c03dc Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sun, 1 Apr 2018 00:18:05 +0100 Subject: [PATCH 31/42] =?UTF-8?q?Add=20package=20script=20and=20fix=20rele?= =?UTF-8?q?ase=20script=20not=20working=20when=20the=20release=20directory?= =?UTF-8?q?=20doesn=E2=80=99t=20already=20exist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpfile.js | 2 + package-lock.json | 428 ++++++++++++++++++++++++++++++++++++- package.json | 5 +- scripts/package-release.js | 65 ++++++ 4 files changed, 498 insertions(+), 2 deletions(-) create mode 100644 scripts/package-release.js diff --git a/gulpfile.js b/gulpfile.js index a6d5a2d2..42b2e812 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,5 +1,6 @@ const fs = require('fs'), + mkdirp = require('mkdirp'), gulp = require('gulp'), del = require('del'), pump = require('pump'), @@ -18,6 +19,7 @@ const releasepkg = function() { delete mainpkg.main; delete mainpkg.devDependencies; delete mainpkg.scripts; + mkdirp.sync('./release'); return fs.writeFileSync('./release/package.json', JSON.stringify(mainpkg, null, 2)); }; diff --git a/package-lock.json b/package-lock.json index 2d6c521a..1ce9b485 100644 --- a/package-lock.json +++ b/package-lock.json @@ -269,6 +269,112 @@ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=" }, + "archiver": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz", + "integrity": "sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=", + "dev": true, + "requires": { + "archiver-utils": "1.3.0", + "async": "2.6.0", + "buffer-crc32": "0.2.13", + "glob": "7.1.2", + "lodash": "4.17.5", + "readable-stream": "2.3.5", + "tar-stream": "1.5.5", + "zip-stream": "1.2.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "dev": true, + "requires": { + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "lazystream": "1.0.0", + "lodash": "4.17.5", + "normalize-path": "2.1.1", + "readable-stream": "2.3.5" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -1311,6 +1417,54 @@ "underscore": "1.4.4" } }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dev": true, + "requires": { + "readable-stream": "2.3.5", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -1479,6 +1633,12 @@ } } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -2092,6 +2252,56 @@ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "dev": true, + "requires": { + "buffer-crc32": "0.2.13", + "crc32-stream": "2.0.0", + "normalize-path": "2.1.1", + "readable-stream": "2.3.5" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2235,6 +2445,60 @@ } } }, + "crc": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.5.0.tgz", + "integrity": "sha1-mLi6fUiWZbo5efWbITgTdBAaGWQ=", + "dev": true + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "dev": true, + "requires": { + "crc": "3.5.0", + "readable-stream": "2.3.5" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "create-ecdh": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", @@ -3048,7 +3312,7 @@ "es6-promise": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "integrity": "sha1-3EIhwrFlGHYL2MOaUtjzVvwA7Sk=", "dev": true }, "es6-set": { @@ -6898,6 +7162,53 @@ "set-getter": "0.1.0" } }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "2.3.5" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", @@ -11164,6 +11475,71 @@ "inherits": "2.0.3" } }, + "tar-stream": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", + "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", + "dev": true, + "requires": { + "bl": "1.2.2", + "end-of-stream": "1.4.1", + "readable-stream": "2.3.5", + "xtend": "4.0.1" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + } + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -12592,6 +12968,56 @@ "requires": { "fd-slicer": "1.0.1" } + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "dev": true, + "requires": { + "archiver-utils": "1.3.0", + "compress-commons": "1.2.2", + "lodash": "4.17.5", + "readable-stream": "2.3.5" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } } } } diff --git a/package.json b/package.json index 13f0ccec..df59798e 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "nedb": "^1.8.0" }, "devDependencies": { + "archiver": "^2.1.1", "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-env": "^1.6.1", @@ -47,6 +48,7 @@ "html-webpack-plugin": "^3.0.6", "jquery": "^3.2.1", "lodash": "^4.17.4", + "mkdirp": "^0.5.1", "node-gyp": "^3.6.2", "pump": "^2.0.0", "sass-loader": "^6.0.6", @@ -74,6 +76,7 @@ "test": "npm run build && npm run lint", "build_node-sass": "node scripts/build-node-sass.js", "build_release": "npm run release --prefix client && npm run build --prefix core && npm run release --prefix csseditor", - "release": "npm run lint && npm run build_release && gulp release" + "package_release": "node scripts/package-release.js", + "release": "npm run lint && npm run build_release && gulp release && npm run package_release" } } diff --git a/scripts/package-release.js b/scripts/package-release.js new file mode 100644 index 00000000..443e3b2e --- /dev/null +++ b/scripts/package-release.js @@ -0,0 +1,65 @@ +const fs = require('fs'); +const path = require('path'); +const archiver = require('archiver'); + +const releasepkg = require('../release/package.json'); +const mainpkg = require('../package.json'); +const corepkg = require('../core/package.json'); +const clientpkg = require('../client/package.json'); +const editorpkg = require('../csseditor/package.json'); + +// core.zip +const core = new Promise((resolve, reject) => { + const core_zip = archiver('zip'); + core_zip.file('./release/package.json', {name: 'package.json'}); + core_zip.file('./release/index.js', {name: 'index.js'}); + core_zip.file(`./release/core.${corepkg.version}.js`, {name: `core.${corepkg.version}.js`}); + core_zip.file('./release/sparkplug.js', {name: 'sparkplug.js'}); + core_zip.directory('./release/modules', 'modules'); + core_zip.directory('./release/node_modules', 'node_modules'); + + const core_zip_stream = fs.createWriteStream('./release/core.zip'); + core_zip.pipe(core_zip_stream); + + core_zip.on('end', resolve); + core_zip.on('error', reject); + core_zip.finalize(); +}); + +// client.zip +const client = new Promise((resolve, reject) => { + const client_zip = archiver('zip'); + client_zip.file(`./release/client.${clientpkg.version}.js`, {name: `client.${clientpkg.version}.js`}); + + const client_zip_stream = fs.createWriteStream('./release/client.zip'); + client_zip.pipe(client_zip_stream); + + client_zip.on('end', resolve); + client_zip.on('error', reject); + client_zip.finalize(); +}); + +// csseditor.zip +const csseditor = new Promise((resolve, reject) => { + const csseditor_zip = archiver('zip'); + csseditor_zip.directory('./release/csseditor', 'csseditor'); + + const csseditor_zip_stream = fs.createWriteStream('./release/csseditor.zip'); + csseditor_zip.pipe(csseditor_zip_stream); + + csseditor_zip.on('end', resolve); + csseditor_zip.on('error', reject); + csseditor_zip.finalize(); +}); + +// full.zip +Promise.all([core, client, csseditor]).then(() => { + const full_zip = archiver('zip'); + full_zip.file('./release/core.zip', {name: 'core.zip'}); + full_zip.file('./release/client.zip', {name: 'client.zip'}); + full_zip.file('./release/csseditor.zip', {name: 'csseditor.zip'}); + + const full_zip_stream = fs.createWriteStream('./release/full.zip'); + full_zip.pipe(full_zip_stream); + full_zip.finalize(); +}); From c95d60ab0f456853cb50909c80f56dc20cab4500 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Sun, 1 Apr 2018 02:39:58 +0100 Subject: [PATCH 32/42] =?UTF-8?q?Don=E2=80=99t=20toggle=20favourite=20when?= =?UTF-8?q?=20the=20emote=20itself=20is=20clicked?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/builtin/EmoteComponent.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/builtin/EmoteComponent.vue b/client/src/builtin/EmoteComponent.vue index 24f73792..0eda75d6 100644 --- a/client/src/builtin/EmoteComponent.vue +++ b/client/src/builtin/EmoteComponent.vue @@ -1,6 +1,6 @@