From 89b645b33477d7f1a83813bf9478833f5fe93593 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 15:57:29 +0300 Subject: [PATCH 01/15] 24hour refactor to use new builtin base --- client/src/builtin/24Hour.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/client/src/builtin/24Hour.js b/client/src/builtin/24Hour.js index 1fc794c1..5d2ee577 100644 --- a/client/src/builtin/24Hour.js +++ b/client/src/builtin/24Hour.js @@ -15,23 +15,20 @@ const twelveHour = new RegExp(`([0-9]{1,2}):([0-9]{1,2})\\s(AM|PM)`); export default new class TwentyFourHour extends BuiltinModule { - get settingPath() { - return ['ui', 'default', '24-hour']; - } + get settingPath() { return ['ui', 'default', '24-hour'] } + get moduleName() { return 'TwentyFourHour' } - async enabled(e) { - if (Patcher.getPatchesByCaller('BD:TwentyFourHour').length) return; + applyPatches() { + if (this.patches.length) return; const { TimeFormatter } = Reflection.modules; - MonkeyPatch('BD:TwentyFourHour', TimeFormatter).after('calendarFormat', (thisObject, args, returnValue) => { - const matched = returnValue.match(twelveHour); - if (!matched || matched.length != 4) return; - if (matched[3] == 'AM') return returnValue.replace(matched[0], `${matched[1] == '12' ? '00' : matched[1].padStart(2, '0')}:${matched[2]}`) - return returnValue.replace(matched[0], `${parseInt(matched[1]) + 12}:${matched[2]}`) - }); + this.patch(TimeFormatter, 'calendarFormat', this.convertTimeStamps); } - disabled(e) { - Patcher.unpatchAll('BD:TwentyFourHour'); + convertTimeStamps(that, args, returnValue) { + const matched = returnValue.match(twelveHour); + if (!matched || matched.length !== 4) return; + if (matched[3] === 'AM') return returnValue.replace(matched[0], `${matched[1] === '12' ? '00' : matched[1].padStart(2, '0')}:${matched[2]}`) + return returnValue.replace(matched[0], `${parseInt(matched[1]) + 12}:${matched[2]}`) } - + } From 47af7a5da6ec8fe4e4ea6ef1992b5759b0e23637 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 16:02:42 +0300 Subject: [PATCH 02/15] Blocked messages refactor to use new builtin base --- client/src/builtin/BlockedMessages.js | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/client/src/builtin/BlockedMessages.js b/client/src/builtin/BlockedMessages.js index 4431119e..4b2205b5 100644 --- a/client/src/builtin/BlockedMessages.js +++ b/client/src/builtin/BlockedMessages.js @@ -9,12 +9,25 @@ */ import BuiltinModule from './BuiltinModule'; -import { Patcher, MonkeyPatch, Reflection, ReactComponents } from 'modules'; +import { Reflection } from 'modules'; export default new class BlockedMessages extends BuiltinModule { - get settingPath() { - return ['ui', 'default', 'blocked-messages']; + get settingPath() { return ['ui', 'default', 'blocked-messages'] } + get moduleName() { return 'BlockedMessages' } + + async enabled(e) { + const MessageListComponents = Reflection.module.byProps('BlockedMessageGroup'); + MessageListComponents.OriginalBlockedMessageGroup = MessageListComponents.BlockedMessageGroup; + MessageListComponents.BlockedMessageGroup = () => { return null; }; + this.cancelBlockedMessages = () => { + MessageListComponents.BlockedMessageGroup = MessageListComponents.OriginalBlockedMessageGroup; + delete MessageListComponents.OriginalBlockedMessageGroup; + } + } + + disabled(e) { + if (this.cancelBlockedMessages) this.cancelBlockedMessages(); } static isBlocked(id) { @@ -22,28 +35,15 @@ export default new class BlockedMessages extends BuiltinModule { return RelationshipStore.isBlocked(id); } - async enabled(e) { - if (Patcher.getPatchesByCaller('BD:BlockedMessages').length) return; + applyPatches() { + if (this.patches.length) return; const { MessageActions } = Reflection.modules; - MonkeyPatch('BD:BlockedMessages', MessageActions).instead('receiveMessage', this.processMessage); - - const MessageListComponents = Reflection.module.byProps('BlockedMessageGroup'); - MessageListComponents.OriginalBlockedMessageGroup = MessageListComponents.BlockedMessageGroup; - MessageListComponents.BlockedMessageGroup = () => {return null;}; - this.cancelBlockedMessages = () => { - MessageListComponents.BlockedMessageGroup = MessageListComponents.OriginalBlockedMessageGroup; - delete MessageListComponents.OriginalBlockedMessageGroup; - } + this.patch(MessageActions, 'receiveMessage', this.processMessage, 'instead'); } - processMessage(thisObject, args, originalFunction) { + processMessage(that, args, originalFunction) { if (args[1] && args[1].author && args[1].author.id && BlockedMessages.isBlocked(args[1].author.id)) return; return originalFunction(...args); } - disabled(e) { - Patcher.unpatchAll('BD:BlockedMessages'); - if (this.cancelBlockedMessages) this.cancelBlockedMessages(); - } - } From c11aa205a3ac4b5c8fbd4706e79426d66df4a5ec Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 16:03:13 +0300 Subject: [PATCH 03/15] Remove unused imports --- client/src/builtin/24Hour.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/builtin/24Hour.js b/client/src/builtin/24Hour.js index 5d2ee577..13126611 100644 --- a/client/src/builtin/24Hour.js +++ b/client/src/builtin/24Hour.js @@ -9,7 +9,7 @@ */ import BuiltinModule from './BuiltinModule'; -import { Patcher, MonkeyPatch, Reflection, ReactComponents } from 'modules'; +import { Reflection } from 'modules'; const twelveHour = new RegExp(`([0-9]{1,2}):([0-9]{1,2})\\s(AM|PM)`); From 62b7679408b6ec82275169ca2bfbd3bb7232e5d2 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 16:09:04 +0300 Subject: [PATCH 04/15] Coloured text refactor to use new builtin base --- client/src/builtin/ColoredText.js | 47 +++++++++++++------------------ 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/client/src/builtin/ColoredText.js b/client/src/builtin/ColoredText.js index 4c315cd3..7701642e 100644 --- a/client/src/builtin/ColoredText.js +++ b/client/src/builtin/ColoredText.js @@ -15,37 +15,40 @@ import { Settings, Patcher, MonkeyPatch, Reflection, ReactComponents, DiscordApi export default new class ColoredText extends BuiltinModule { + get moduleName() { return 'ColoredText' } + + get settingPath() { return ['ui', 'default', 'colored-text'] } + + get intensityPath() { return ['ui', 'advanced', 'colored-text-intensity'] } + + get intensitySetting() { return Settings.getSetting(...this.intensityPath) } + + get intensity() { return 100 - this.intensitySetting.value } + + get defaultColor() { return DiscordApi.UserSettings.theme == 'light' ? '#747f8d' : '#dcddde' } + constructor() { super(); this._intensityUpdated = this._intensityUpdated.bind(this); - this.injectColoredText = this.injectColoredText.bind(this); } - get settingPath() { - return ['ui', 'default', 'colored-text']; + async enabled(e) { + this.intensitySetting.off('setting-updated', this._intensityUpdated); + this.intensitySetting.on('setting-updated', this._intensityUpdated); } - get intensityPath() { - return ['ui', 'advanced', 'colored-text-intensity']; - } - - get intensitySetting() { - return Settings.getSetting(...this.intensityPath); - } - - get intensity() { - return 100 - this.intensitySetting.value; + disabled(e) { + this.intensitySetting.off('setting-updated', this._intensityUpdated); } _intensityUpdated() { this.MessageContent.forceUpdateAll(); } - async enabled(e) { - if (Patcher.getPatchesByCaller('BD:ColoredText').length) return; - this.intensitySetting.on('setting-updated', this._intensityUpdated); + async applyPatches() { + if (this.patches.length) return; this.MessageContent = await ReactComponents.getComponent('MessageContent', { selector: Reflection.resolve('container', 'containerCozy', 'containerCompact', 'edited').selector }); - MonkeyPatch('BD:ColoredText', this.MessageContent.component.prototype).after('render', this.injectColoredText); + this.patch(this.MessageContent.component.prototype, 'render', this.injectColoredText); this.MessageContent.forceUpdateAll(); } @@ -55,14 +58,4 @@ export default new class ColoredText extends BuiltinModule { const roleColor = thisObject.props.message.colorString; if (markup && roleColor) markup.props.style = {color: TinyColor.mix(roleColor, this.defaultColor, this.intensity)}; } - - get defaultColor() { - return DiscordApi.UserSettings.theme == 'light' ? '#747f8d' : '#dcddde'; - } - - disabled(e) { - Patcher.unpatchAll('BD:ColoredText'); - this.intensitySetting.off('setting-updated', this._intensityUpdated); - } - } From 6a5f185c80534424dfcf78245d8ebce74029786b Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 16:12:33 +0300 Subject: [PATCH 05/15] add some comments and consistent structure --- client/src/builtin/24Hour.js | 8 +++++++- client/src/builtin/BlockedMessages.js | 9 ++++++++- client/src/builtin/ColoredText.js | 6 ++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/client/src/builtin/24Hour.js b/client/src/builtin/24Hour.js index 13126611..56fd33fc 100644 --- a/client/src/builtin/24Hour.js +++ b/client/src/builtin/24Hour.js @@ -15,15 +15,21 @@ const twelveHour = new RegExp(`([0-9]{1,2}):([0-9]{1,2})\\s(AM|PM)`); export default new class TwentyFourHour extends BuiltinModule { - get settingPath() { return ['ui', 'default', '24-hour'] } + /* Getters */ get moduleName() { return 'TwentyFourHour' } + get settingPath() { return ['ui', 'default', '24-hour'] } + + /* Patches */ applyPatches() { if (this.patches.length) return; const { TimeFormatter } = Reflection.modules; this.patch(TimeFormatter, 'calendarFormat', this.convertTimeStamps); } + /** + * Convert 12 hours timestamps to 24 hour timestamps + */ convertTimeStamps(that, args, returnValue) { const matched = returnValue.match(twelveHour); if (!matched || matched.length !== 4) return; diff --git a/client/src/builtin/BlockedMessages.js b/client/src/builtin/BlockedMessages.js index 4b2205b5..c12ebd6f 100644 --- a/client/src/builtin/BlockedMessages.js +++ b/client/src/builtin/BlockedMessages.js @@ -13,9 +13,11 @@ import { Reflection } from 'modules'; export default new class BlockedMessages extends BuiltinModule { - get settingPath() { return ['ui', 'default', 'blocked-messages'] } + /* Getters */ get moduleName() { return 'BlockedMessages' } + get settingPath() { return ['ui', 'default', 'blocked-messages'] } + async enabled(e) { const MessageListComponents = Reflection.module.byProps('BlockedMessageGroup'); MessageListComponents.OriginalBlockedMessageGroup = MessageListComponents.BlockedMessageGroup; @@ -30,17 +32,22 @@ export default new class BlockedMessages extends BuiltinModule { if (this.cancelBlockedMessages) this.cancelBlockedMessages(); } + /* Methods */ static isBlocked(id) { const { RelationshipStore } = Reflection.modules; return RelationshipStore.isBlocked(id); } + /* Patches */ applyPatches() { if (this.patches.length) return; const { MessageActions } = Reflection.modules; this.patch(MessageActions, 'receiveMessage', this.processMessage, 'instead'); } + /** + * Ignore blocked messages completely + */ processMessage(that, args, originalFunction) { if (args[1] && args[1].author && args[1].author.id && BlockedMessages.isBlocked(args[1].author.id)) return; return originalFunction(...args); diff --git a/client/src/builtin/ColoredText.js b/client/src/builtin/ColoredText.js index 7701642e..c847a5ad 100644 --- a/client/src/builtin/ColoredText.js +++ b/client/src/builtin/ColoredText.js @@ -15,6 +15,7 @@ import { Settings, Patcher, MonkeyPatch, Reflection, ReactComponents, DiscordApi export default new class ColoredText extends BuiltinModule { + /* Getters */ get moduleName() { return 'ColoredText' } get settingPath() { return ['ui', 'default', 'colored-text'] } @@ -41,10 +42,12 @@ export default new class ColoredText extends BuiltinModule { this.intensitySetting.off('setting-updated', this._intensityUpdated); } + /* Methods */ _intensityUpdated() { this.MessageContent.forceUpdateAll(); } + /* Patches */ async applyPatches() { if (this.patches.length) return; this.MessageContent = await ReactComponents.getComponent('MessageContent', { selector: Reflection.resolve('container', 'containerCozy', 'containerCompact', 'edited').selector }); @@ -52,6 +55,9 @@ export default new class ColoredText extends BuiltinModule { this.MessageContent.forceUpdateAll(); } + /** + * Set markup text colour to match role colour + */ injectColoredText(thisObject, args, returnValue) { const { TinyColor } = Reflection.modules; const markup = Utils.findInReactTree(returnValue, m => m && m.props && m.props.className && m.props.className.includes('da-markup')); From 6d818f40d269699bbbbe87ea7f2d39e6ea25dce6 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 16:50:48 +0300 Subject: [PATCH 06/15] Get Message correctly --- client/src/builtin/E2EE.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/src/builtin/E2EE.js b/client/src/builtin/E2EE.js index 07f426c6..e667f706 100644 --- a/client/src/builtin/E2EE.js +++ b/client/src/builtin/E2EE.js @@ -137,7 +137,7 @@ export default new class E2EE extends BuiltinModule { const items = Settings.getSetting('security', 'e2eedb', 'e2ekvps').items; const index = items.findIndex(kvp => kvp.value.key === channelId); if (index > -1) { - items[index].value = {key: channelId, value: key}; + items[index].value = { key: channelId, value: key }; return; } Settings.getSetting('security', 'e2eedb', 'e2ekvps').addItem({ value: { key: channelId, value: key } }); @@ -223,7 +223,7 @@ export default new class E2EE extends BuiltinModule { const parsed = MessageParser.parse(currentChannel, decrypt).content; if (userMentionPattern.test(parsed)) - event.message.mentions = parsed.match(userMentionPattern).map(m => {return {id: m.replace(/[^0-9]/g, '')}}); + event.message.mentions = parsed.match(userMentionPattern).map(m => { return { id: m.replace(/[^0-9]/g, '') } }); if (roleMentionPattern.test(parsed)) event.message.mention_roles = parsed.match(roleMentionPattern).map(m => m.replace(/[^0-9]/g, '')); if (everyoneMentionPattern.test(parsed)) @@ -245,7 +245,8 @@ export default new class E2EE extends BuiltinModule { const key = this.getKey(component.props.message.channel_id); if (!key) return; // We don't have a key for this channel - const { Message, MessageParser, Permissions, DiscordConstants } = Reflection.modules; + const Message = Reflection.module.byPrototypes('isMentioned'); + const { MessageParser, Permissions, DiscordConstants } = Reflection.modules; const currentChannel = DiscordApi.Channel.fromId(component.props.message.channel_id).discordObject; if (typeof component.props.message.content !== 'string') return; // Ignore any non string content @@ -261,7 +262,7 @@ export default new class E2EE extends BuiltinModule { const message = MessageParser.createMessage(currentChannel.id, MessageParser.parse(currentChannel, decrypt).content); if (userMentionPattern.test(message.content)) - message.mentions = message.content.match(userMentionPattern).map(m => {return {id: m.replace(/[^0-9]/g, '')}}); + message.mentions = message.content.match(userMentionPattern).map(m => { return { id: m.replace(/[^0-9]/g, '') } }); if (roleMentionPattern.test(message.content)) message.mention_roles = message.content.match(roleMentionPattern).map(m => m.replace(/[^0-9]/g, '')); if (everyoneMentionPattern.test(message.content)) From f5b70d5a23ff1390a8c1bf37d98ec41c69f10299 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 16:51:45 +0300 Subject: [PATCH 07/15] Not much to change here --- client/src/builtin/EmoteAc.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/src/builtin/EmoteAc.js b/client/src/builtin/EmoteAc.js index b2cd4c0b..cacbfb5a 100644 --- a/client/src/builtin/EmoteAc.js +++ b/client/src/builtin/EmoteAc.js @@ -22,6 +22,8 @@ const EMOTE_SOURCES = [ export default new class EmoteAc extends BuiltinModule { + /* Getters */ + get moduleName() { return 'EmoteAC' } get settingPath() { return ['emotes', 'default', 'emoteac'] } async enabled(e) { From aa0882c449d7d8789ab477943c9c357c2c4774c8 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 16:55:58 +0300 Subject: [PATCH 08/15] Kill clyde refactor to use new builtin base --- client/src/builtin/KillClyde.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/client/src/builtin/KillClyde.js b/client/src/builtin/KillClyde.js index 734614ed..25395e22 100644 --- a/client/src/builtin/KillClyde.js +++ b/client/src/builtin/KillClyde.js @@ -13,18 +13,16 @@ import { Patcher, MonkeyPatch, Reflection } from 'modules'; export default new class KillClyde extends BuiltinModule { - get settingPath() { - return ['ui', 'default', 'kill-clyde']; - } + /* Getters */ + get moduleName() { return 'KillClyde' } - async enabled(e) { - if (Patcher.getPatchesByCaller('BD:KillClyde').length) return; + get settingPath() { return ['ui', 'default', 'kill-clyde'] } + + /* Patches */ + applyPatches() { + if (this.patches.length) return; const { MessageActions } = Reflection.modules; - MonkeyPatch('BD:KillClyde', MessageActions).instead('sendBotMessage', void 0); - } - - disabled(e) { - Patcher.unpatchAll('BD:KillClyde'); + this.patch(MessageActions, 'sendBotMessage', () => void 0, 'instead'); } } From 937ab55456c3e0759bd07ce38cf501dc1ffc1b63 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 16:58:27 +0300 Subject: [PATCH 09/15] Tracking protection refactor to use new builtin base --- client/src/builtin/TrackingProtection.js | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/client/src/builtin/TrackingProtection.js b/client/src/builtin/TrackingProtection.js index 9c4d1b76..802a358a 100644 --- a/client/src/builtin/TrackingProtection.js +++ b/client/src/builtin/TrackingProtection.js @@ -14,23 +14,23 @@ import { Patcher, MonkeyPatch, Reflection } from 'modules'; export default new class E2EE extends BuiltinModule { - get settingPath() { - return ['security', 'default', 'tracking-protection']; + /* Getters */ + get moduleName() { return 'TrackingProtection' } + + get settingPath() { return ['security', 'default', 'tracking-protection'] } + + /* Patches */ + applyPatches() { + if (this.patches.length) return; + const TrackingModule = Reflection.module.byProps('track'); + if (!TrackingModule) { + this.warn('Tracking module not found!'); + return; + } + this.patch(TrackingModule, 'track', this.track, 'instead'); } track(e) { - // console.log('Blocked Tracking'); + this.debug('Tracking blocked'); } - - enabled(e) { - if (Patcher.getPatchesByCaller('BD:TrackingProtection').length) return; - const trackingModule = Reflection.module.byProps('track'); - if (!trackingModule) return; // TODO Log it - MonkeyPatch('BD:TrackingProtection', trackingModule).instead('track', this.track); - } - - disabled(e) { - for (const patch of Patcher.getPatchesByCaller('BD:TrackingProtection')) patch.unpatch(); - } - } From e798e3d6e2bf1a4edcadb8ab68a702b099234adf Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 16:59:24 +0300 Subject: [PATCH 10/15] Voice Disconnect refactor to use new builtin base --- client/src/builtin/VoiceDisconnect.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/client/src/builtin/VoiceDisconnect.js b/client/src/builtin/VoiceDisconnect.js index 24a279d3..9457f35a 100644 --- a/client/src/builtin/VoiceDisconnect.js +++ b/client/src/builtin/VoiceDisconnect.js @@ -13,21 +13,23 @@ import { Reflection } from 'modules'; export default new class VoiceDisconnect extends BuiltinModule { - get settingPath() { - return ['core', 'default', 'voice-disconnect']; - } + /* Getters */ + get moduleName() { return 'VoiceDisconnect' } + + get settingPath() { return ['core', 'default', 'voice-disconnect'] } async enabled(e) { window.addEventListener('beforeunload', this.listener); } - listener() { - const { VoiceChannelActions } = Reflection.modules; - VoiceChannelActions.selectVoiceChannel(null, null); - } - disabled(e) { window.removeEventListener('beforeunload', this.listener); } + /* Methods */ + listener() { + const { VoiceChannelActions } = Reflection.modules; + VoiceChannelActions.selectVoiceChannel(null, null); + } + } From 5e0c5e39f61b36c6b9463f26d21cdb28d6d50778 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 17:01:37 +0300 Subject: [PATCH 11/15] Unused imports --- client/src/builtin/ColoredText.js | 2 +- client/src/builtin/KillClyde.js | 2 +- client/src/builtin/TrackingProtection.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/builtin/ColoredText.js b/client/src/builtin/ColoredText.js index c847a5ad..79cdee28 100644 --- a/client/src/builtin/ColoredText.js +++ b/client/src/builtin/ColoredText.js @@ -11,7 +11,7 @@ import BuiltinModule from './BuiltinModule'; import { Utils } from 'common'; -import { Settings, Patcher, MonkeyPatch, Reflection, ReactComponents, DiscordApi } from 'modules'; +import { Settings, Reflection, ReactComponents, DiscordApi } from 'modules'; export default new class ColoredText extends BuiltinModule { diff --git a/client/src/builtin/KillClyde.js b/client/src/builtin/KillClyde.js index 25395e22..9f9ee42c 100644 --- a/client/src/builtin/KillClyde.js +++ b/client/src/builtin/KillClyde.js @@ -9,7 +9,7 @@ */ import BuiltinModule from './BuiltinModule'; -import { Patcher, MonkeyPatch, Reflection } from 'modules'; +import { Reflection } from 'modules'; export default new class KillClyde extends BuiltinModule { diff --git a/client/src/builtin/TrackingProtection.js b/client/src/builtin/TrackingProtection.js index 802a358a..4f2eab6b 100644 --- a/client/src/builtin/TrackingProtection.js +++ b/client/src/builtin/TrackingProtection.js @@ -10,7 +10,7 @@ import BuiltinModule from './BuiltinModule'; -import { Patcher, MonkeyPatch, Reflection } from 'modules'; +import { Reflection } from 'modules'; export default new class E2EE extends BuiltinModule { From a4cbfd9235ac19ebd9deaeb6b3bc4b029ab0ea64 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 17:03:46 +0300 Subject: [PATCH 12/15] Devtools --- client/src/builtin/ReactDevtoolsModule.js | 9 +++++---- client/src/builtin/VueDevToolsModule.js | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/client/src/builtin/ReactDevtoolsModule.js b/client/src/builtin/ReactDevtoolsModule.js index d8205851..acfb6345 100644 --- a/client/src/builtin/ReactDevtoolsModule.js +++ b/client/src/builtin/ReactDevtoolsModule.js @@ -18,15 +18,16 @@ import { Toasts } from 'ui'; export default new class ReactDevtoolsModule extends BuiltinModule { + /* Getters */ + get moduleName() { return 'ReactDevTools' } + + get settingPath() { return ['core', 'advanced', 'react-devtools'] } + constructor() { super(); this.devToolsOpened = this.devToolsOpened.bind(this); } - get settingPath() { - return ['core', 'advanced', 'react-devtools']; - } - enabled(e) { electron.remote.getCurrentWindow().webContents.on('devtools-opened', this.devToolsOpened); if (electron.remote.getCurrentWindow().isDevToolsOpened) this.devToolsOpened(); diff --git a/client/src/builtin/VueDevToolsModule.js b/client/src/builtin/VueDevToolsModule.js index 8c976c9f..7632c03c 100644 --- a/client/src/builtin/VueDevToolsModule.js +++ b/client/src/builtin/VueDevToolsModule.js @@ -18,15 +18,16 @@ import { Toasts } from 'ui'; export default new class VueDevtoolsModule extends BuiltinModule { + /* Getters */ + get moduleName() { return 'VueDevTools' } + + get settingPath() { return ['core', 'advanced', 'vue-devtools'] } + constructor() { super(); this.devToolsOpened = this.devToolsOpened.bind(this); } - get settingPath() { - return ['core', 'advanced', 'vue-devtools']; - } - enabled(e) { electron.remote.getCurrentWindow().webContents.on('devtools-opened', this.devToolsOpened); if (electron.remote.getCurrentWindow().isDevToolsOpened) this.devToolsOpened(); From da8e912a95431b7e0a2032bda258434ed40d8055 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 17:43:29 +0300 Subject: [PATCH 13/15] Emotemodule refactor to use new builtin base --- client/src/builtin/EmoteModule.js | 177 ++++++++++++++++-------------- 1 file changed, 92 insertions(+), 85 deletions(-) diff --git a/client/src/builtin/EmoteModule.js b/client/src/builtin/EmoteModule.js index a24e7f11..d769426e 100644 --- a/client/src/builtin/EmoteModule.js +++ b/client/src/builtin/EmoteModule.js @@ -29,6 +29,10 @@ const EMOTE_SOURCES = [ export default new class EmoteModule extends BuiltinModule { + /* Getters */ + + get moduleName() { return 'EmoteModule' } + /** * @returns {String} Path to local emote database */ @@ -76,13 +80,14 @@ export default new class EmoteModule extends BuiltinModule { // Read favourites and most used from database await this.loadUserData(); - - this.patchMessageContent(); - this.patchSendAndEdit(); - const ImageWrapper = await ReactComponents.getComponent('ImageWrapper', { selector: Reflection.resolve('imageWrapper').selector }); - MonkeyPatch('BD:EMOTEMODULE', ImageWrapper.component.prototype).after('render', this.beforeRenderImageWrapper.bind(this)); } + async disabled() { + DiscordContextMenu.remove(this.favCm); + } + + /* Methods */ + /** * Adds an emote to favourites. * @param {Object|String} emote @@ -115,12 +120,6 @@ export default new class EmoteModule extends BuiltinModule { return !!this.favourites.find(e => e.name === emote || e.name === emote.name); } - async disabled() { - // Unpatch all patches - for (const patch of Patcher.getPatchesByCaller('BD:EMOTEMODULE')) patch.unpatch(); - DiscordContextMenu.remove(this.favCm); - } - /** * Load emotes from local database */ @@ -151,15 +150,96 @@ export default new class EmoteModule extends BuiltinModule { }); } + /** + * Add/update emote to most used + * @param {Object} emote emote to add/update + * @return {Promise} + */ + addToMostUsed(emote) { + const isMostUsed = this.mostUsed.find(mu => mu.key === emote.name); + if (isMostUsed) { + isMostUsed.useCount += 1; + } else { + this.mostUsed.push({ + key: emote.name, + id: emote.id, + type: emote.type, + useCount: 1 + }); + } + // Save most used to database + // TODO only save first n + return this.saveUserData(); + } + + /** + * Find an emote by name + * @param {String} name Emote name + * @param {Boolean} simple Simple object or Emote instance + * @returns {Object|Emote} + */ + findByName(name, simple = false) { + const emote = this.database.get(name); + if (!emote) return null; + return this.parseEmote(name, emote, simple); + } + + /** + * Parse emote object + * @param {String} name Emote name + * @param {Object} emote Emote object + * @param {Boolean} simple Simple object or Emote instance + * @returns {Object|Emote} + */ + parseEmote(name, emote, simple = false) { + const { type, id } = emote; + if (type < 0 || type > 2) return null; + return simple ? { type, id, name } : new Emote(type, id, name); + } + + /** + * Search for anything else + * @param {any} regex + * @param {any} limit + */ + search(regex, limit = 10) { + if (typeof regex === 'string') regex = new RegExp(regex, 'i'); + const matching = []; + + for (const [key, value] of this.database.entries()) { + if (matching.length >= limit) break; + if (regex.test(key)) matching.push({ key, value }) + } + + return matching; + } + + /* Patches */ + async applyPatches() { + this.patchMessageContent(); + this.patchSendAndEdit(); + const ImageWrapper = await ReactComponents.getComponent('ImageWrapper', { selector: Reflection.resolve('imageWrapper').selector }); + MonkeyPatch('BD:EMOTEMODULE', ImageWrapper.component.prototype).after('render', this.beforeRenderImageWrapper.bind(this)); + } + /** * Patches MessageContent render method */ async patchMessageContent() { const MessageContent = await ReactComponents.getComponent('MessageContent', { selector: Reflection.resolve('container', 'containerCozy', 'containerCompact', 'edited').selector }); - MonkeyPatch('BD:EMOTEMODULE', MessageContent.component.prototype).after('render', this.afterRenderMessageContent.bind(this)); + this.patch(MessageContent.component.prototype, 'render', this.afterRenderMessageContent); MessageContent.forceUpdateAll(); } + /** + * Patches MessageActions send and edit + */ + patchSendAndEdit() { + const { MessageActions } = Reflection.modules; + this.patch(MessageActions, 'sendMessage', this.handleSendMessage, 'instead'); + this.patch(MessageActions, 'editMessage', this.handleEditMessage, 'instead'); + } + /** * Handle message render */ @@ -173,15 +253,6 @@ export default new class EmoteModule extends BuiltinModule { markup.children[1] = this.processMarkup(markup.children[1]); } - /** - * Patches MessageActions send and edit - */ - patchSendAndEdit() { - const { MessageActions } = Reflection.modules; - MonkeyPatch('BD:EMOTEMODULE', MessageActions).instead('sendMessage', this.handleSendMessage.bind(this)); - MonkeyPatch('BD:EMOTEMODULE', MessageActions).instead('editMessage', this.handleEditMessage.bind(this)); - } - /** * Handle send message */ @@ -253,28 +324,6 @@ export default new class EmoteModule extends BuiltinModule { retVal.props.children = emote.render(); } - /** - * Add/update emote to most used - * @param {Object} emote emote to add/update - * @return {Promise} - */ - addToMostUsed(emote) { - const isMostUsed = this.mostUsed.find(mu => mu.key === emote.name); - if (isMostUsed) { - isMostUsed.useCount += 1; - } else { - this.mostUsed.push({ - key: emote.name, - id: emote.id, - type: emote.type, - useCount: 1 - }); - } - // Save most used to database - // TODO only save first n - return this.saveUserData(); - } - /** * Inject emotes into markup */ @@ -330,46 +379,4 @@ export default new class EmoteModule extends BuiltinModule { return newMarkup; } - /** - * Find an emote by name - * @param {String} name Emote name - * @param {Boolean} simple Simple object or Emote instance - * @returns {Object|Emote} - */ - findByName(name, simple = false) { - const emote = this.database.get(name); - if (!emote) return null; - return this.parseEmote(name, emote, simple); - } - - /** - * Parse emote object - * @param {String} name Emote name - * @param {Object} emote Emote object - * @param {Boolean} simple Simple object or Emote instance - * @returns {Object|Emote} - */ - parseEmote(name, emote, simple = false) { - const { type, id } = emote; - if (type < 0 || type > 2) return null; - return simple ? { type, id, name } : new Emote(type, id, name); - } - - /** - * Search for anything else - * @param {any} regex - * @param {any} limit - */ - search(regex, limit = 10) { - if (typeof regex === 'string') regex = new RegExp(regex, 'i'); - const matching = []; - - for (const [key, value] of this.database.entries()) { - if (matching.length >= limit) break; - if (regex.test(key)) matching.push({ key, value }) - } - - return matching; - } - } From 9b5464b9a545832f22f12e18ff0cac66293da485 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 17:45:52 +0300 Subject: [PATCH 14/15] Remove unused imports --- client/src/builtin/EmoteModule.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/builtin/EmoteModule.js b/client/src/builtin/EmoteModule.js index d769426e..2ee563c7 100644 --- a/client/src/builtin/EmoteModule.js +++ b/client/src/builtin/EmoteModule.js @@ -12,9 +12,9 @@ import BuiltinModule from './BuiltinModule'; import path from 'path'; import { request } from 'vendor'; -import { Utils, FileUtils, ClientLogger as Logger } from 'common'; -import { DiscordApi, Settings, Globals, Reflection, ReactComponents, MonkeyPatch, Cache, Patcher, Database } from 'modules'; -import { VueInjector, DiscordContextMenu } from 'ui'; +import { Utils, FileUtils } from 'common'; +import { DiscordApi, Settings, Globals, Reflection, ReactComponents, Database } from 'modules'; +import { DiscordContextMenu } from 'ui'; import Emote from './EmoteComponent.js'; import Autocomplete from '../ui/components/common/Autocomplete.vue'; @@ -219,7 +219,7 @@ export default new class EmoteModule extends BuiltinModule { this.patchMessageContent(); this.patchSendAndEdit(); const ImageWrapper = await ReactComponents.getComponent('ImageWrapper', { selector: Reflection.resolve('imageWrapper').selector }); - MonkeyPatch('BD:EMOTEMODULE', ImageWrapper.component.prototype).after('render', this.beforeRenderImageWrapper.bind(this)); + this.patch(ImageWrapper.component.prototype, 'render', this.beforeRenderImageWrapper, 'before'); } /** From 1afbcacec33d41283fa0683ee11062f4d1baab69 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sat, 25 Aug 2018 18:05:17 +0300 Subject: [PATCH 15/15] add favourite contextmenu to emote autocomplete --- client/src/builtin/EmoteAc.js | 37 ++++++++++++++++++- .../src/ui/components/common/Autocomplete.vue | 2 +- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/client/src/builtin/EmoteAc.js b/client/src/builtin/EmoteAc.js index cacbfb5a..a0e8ecbe 100644 --- a/client/src/builtin/EmoteAc.js +++ b/client/src/builtin/EmoteAc.js @@ -13,6 +13,7 @@ import { Settings } from 'modules'; import BuiltinModule from './BuiltinModule'; import EmoteModule from './EmoteModule'; import GlobalAc from '../ui/autocomplete'; +import { BdContextMenu } from 'ui'; const EMOTE_SOURCES = [ 'https://static-cdn.jtvnw.net/emoticons/v1/:id/1.0', @@ -28,10 +29,40 @@ export default new class EmoteAc extends BuiltinModule { async enabled(e) { GlobalAc.add(';', this); + window.removeEventListener('contextmenu', this.acCm); + window.addEventListener('contextmenu', this.acCm); } disabled(e) { GlobalAc.remove(';'); + window.removeEventListener('contextmenu', this.acCm); + } + + /* Methods */ + acCm(e) { + const row = e.target.closest('.bd-emotAc'); + if (!row) return; + const img = row.querySelector('img'); + if (!img || !img.alt) return; + + BdContextMenu.show(e, [ + { + text: 'Test', + items: [ + { + text: 'Favourite', + type: 'toggle', + checked: EmoteModule.isFavourite(img.alt.replace(/;/g, '')), + onChange: checked => { + if (!img || !img.alt) return; + const emote = img.alt.replace(/;/g, ''); + if (!checked) return EmoteModule.removeFavourite(emote), false; + return EmoteModule.addFavourite(emote), true; + } + } + ] + } + ]); } /** @@ -53,7 +84,8 @@ export default new class EmoteAc extends BuiltinModule { hint: mu.useCount ? `Used ${mu.useCount} times` : null } } - }) + }), + extraClasses: ['bd-emotAc'] } } @@ -65,7 +97,8 @@ export default new class EmoteAc extends BuiltinModule { result.value.src = EMOTE_SOURCES[result.value.type].replace(':id', result.value.id); result.value.replaceWith = `;${result.key};`; return result; - }) + }), + extraClasses: ['bd-emotAc'] } } diff --git a/client/src/ui/components/common/Autocomplete.vue b/client/src/ui/components/common/Autocomplete.vue index 86d6dfbf..4c705ab2 100644 --- a/client/src/ui/components/common/Autocomplete.vue +++ b/client/src/ui/components/common/Autocomplete.vue @@ -21,7 +21,7 @@
-
+