diff --git a/package.json b/package.json index 147194f6..467ade17 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "frankerfacez", "author": "Dan Salvato LLC", - "version": "4.20.60", + "version": "4.20.61", "description": "FrankerFaceZ is a Twitch enhancement suite.", "license": "Apache-2.0", "scripts": { diff --git a/src/bridge.js b/src/bridge.js index 02a9fd6a..3e6e036d 100644 --- a/src/bridge.js +++ b/src/bridge.js @@ -6,6 +6,7 @@ import Logger from 'utilities/logging'; import Module from 'utilities/module'; import {DEBUG} from 'utilities/constants'; +import {serializeBlob, deserializeBlob} from 'utilities/blobs'; import SettingsManager from './settings/index'; @@ -28,6 +29,7 @@ class FFZBridge extends Module { this.inject('raven', RavenLogger); this.log = new Logger(null, null, null, this.raven); + this.log.label = 'FFZBridge'; this.log.init = true; this.core_log = this.log.get('core'); @@ -60,15 +62,21 @@ class FFZBridge extends Module { return FFZBridge.instance; } - onEnable() { + async onEnable() { window.addEventListener('message', this.onMessage.bind(this)); this.settings.provider.on('changed', this.onProviderChange, this); + this.settings.provider.on('changed-blob', this.onProviderBlobChange, this); + this.settings.provider.on('clear-blobs', this.onProviderClearBlobs, this); + + await this.settings.awaitProvider(); + await this.settings.provider.awaitReady(); + this.send({ ffz_type: 'ready' }); } - onMessage(event) { + async onMessage(event) { const msg = event.data; if ( ! msg || ! msg.ffz_type ) return; @@ -83,13 +91,86 @@ class FFZBridge extends Module { data: out }); - } else if ( msg.ffz_type === 'change' ) + return; + + } else if ( msg.ffz_type === 'change' ) { this.onChange(msg); + return; + } + + if ( ! msg.id ) + return this.log.warn('Received command with no reply ID'); + + let reply, transfer; + + try { + if ( msg.ffz_type === 'init-load' ) { + reply = { + blobs: this.settings.provider.supportsBlobs, + values: {} + }; + + for(const [key,value] of this.settings.provider.entries()) + reply.values[key] = value; + + } else if ( msg.ffz_type === 'set' ) + this.settings.provider.set(msg.key, msg.value); + + else if ( msg.ffz_type === 'delete' ) + this.settings.provider.delete(msg.key); + + else if ( msg.ffz_type === 'clear' ) + this.settings.provider.clear(); + + else if ( msg.ffz_type === 'get-blob' ) { + reply = await serializeBlob(await this.settings.provider.getBlob(msg.key)); + if ( reply ) + transfer = reply.buffer; + + } else if ( msg.ffz_type === 'set-blob' ) { + const blob = deserializeBlob(msg.value); + await this.settings.provider.setBlob(msg.key, blob); + + } else if ( msg.ffz_type === 'delete-blob' ) + await this.settings.provider.deleteBlob(msg.key); + + else if ( msg.ffz_type === 'has-blob' ) + reply = await this.settings.provider.hasBlob(msg.key); + + else if ( msg.ffz_type === 'clear-blobs' ) + await this.settings.provider.clearBlobs(); + + else if ( msg.ffz_type === 'blob-keys' ) + reply = await this.settings.provider.blobKeys(); + + else if ( msg.ffz_type === 'flush' ) + await this.settings.provider.flush(); + + else + return this.send({ + ffz_type: 'reply-error', + id: msg.id, + error: 'bad-command' + }); + + this.send({ + ffz_type: 'reply', + id: msg.id, + reply + }, transfer); + + } catch(err) { + this.log.error('Error handling command.', err); + this.send({ + ffz_type: 'reply-error', + id: msg.id + }); + } } - send(msg) { // eslint-disable-line class-methods-use-this + send(msg, blob) { // eslint-disable-line class-methods-use-this try { - window.parent.postMessage(msg, '*') + window.parent.postMessage(msg, '*', blob ? [blob] : undefined) } catch(err) { this.log.error('send error', err); /* no-op */ } } @@ -112,6 +193,20 @@ class FFZBridge extends Module { deleted }); } + + onProviderBlobChange(key, deleted) { + this.send({ + ffz_type: 'change-blob', + key, + deleted + }); + } + + onProviderClearBlobs() { + this.send({ + ffz_type: 'clear-blobs' + }); + } } FFZBridge.Logger = Logger; diff --git a/src/main.js b/src/main.js index 75be9dcb..d50cebc5 100644 --- a/src/main.js +++ b/src/main.js @@ -68,17 +68,17 @@ class FrankerFaceZ extends Module { // Startup // ======================================================================== - this.discoverModules(); + this.discoverModules() + .then(() => this.enable()) + .then(() => this.enableInitialModules()).then(() => { + const duration = performance.now() - start_time; + this.core_log.info(`Initialization complete in ${duration.toFixed(5)}ms.`); + this.log.init = false; - this.enable().then(() => this.enableInitialModules()).then(() => { - const duration = performance.now() - start_time; - this.core_log.info(`Initialization complete in ${duration.toFixed(5)}ms.`); - this.log.init = false; - - }).catch(err => { - this.core_log.error('An error occurred during initialization.', err); - this.log.init = false; - }); + }).catch(err => { + this.core_log.error('An error occurred during initialization.', err); + this.log.init = false; + }); } static get() { @@ -132,9 +132,10 @@ ${typeof x[1] === 'string' ? x[1] : JSON.stringify(x[1], null, 4)}`).join('\n\n' // Modules // ======================================================================== - discoverModules() { - const ctx = require.context('src/modules', true, /(?:^(?:\.\/)?[^/]+|index)\.jsx?$/), - modules = this.populate(ctx, this.core_log); + async discoverModules() { + // TODO: Actually do async modules. + const ctx = await require.context('src/modules', true, /(?:^(?:\.\/)?[^/]+|index)\.jsx?$/ /*, 'lazy-once' */); + const modules = this.populate(ctx, this.core_log); this.core_log.info(`Loaded descriptions of ${Object.keys(modules).length} modules.`); } diff --git a/src/modules/chat/actions/components/edit-ban.vue b/src/modules/chat/actions/components/edit-ban.vue index c37ec6ca..e92aeceb 100644 --- a/src/modules/chat/actions/components/edit-ban.vue +++ b/src/modules/chat/actions/components/edit-ban.vue @@ -8,7 +8,7 @@ diff --git a/src/modules/chat/actions/components/edit-chat.vue b/src/modules/chat/actions/components/edit-chat.vue index b5ed980a..b14f7c64 100644 --- a/src/modules/chat/actions/components/edit-chat.vue +++ b/src/modules/chat/actions/components/edit-chat.vue @@ -9,7 +9,7 @@ :id="'edit_chat$' + id" v-model="value.command" :placeholder="defaults.command" - class="tw-border-radius-medium tw-font-size-6 tw-full-width tw-input tw-pd-x-1 tw-pd-y-05 tw-mg-y-05" + class="tw-border-radius-medium tw-font-size-6 tw-full-width ffz-input tw-pd-x-1 tw-pd-y-05 tw-mg-y-05" @input="$emit('input', value)" > @@ -17,16 +17,16 @@ {{ t('setting.actions.variables', 'Available Variables: {vars}', {vars}) }} -
+
-
diff --git a/src/modules/chat/actions/components/edit-image.vue b/src/modules/chat/actions/components/edit-image.vue index 4b313b4b..65807322 100644 --- a/src/modules/chat/actions/components/edit-image.vue +++ b/src/modules/chat/actions/components/edit-image.vue @@ -7,7 +7,7 @@
diff --git a/src/modules/chat/actions/components/edit-text.vue b/src/modules/chat/actions/components/edit-text.vue index 5a15d2ba..d60aec3c 100644 --- a/src/modules/chat/actions/components/edit-text.vue +++ b/src/modules/chat/actions/components/edit-text.vue @@ -7,7 +7,7 @@ diff --git a/src/modules/chat/actions/components/edit-timeout.vue b/src/modules/chat/actions/components/edit-timeout.vue index 34454809..c39e9ca8 100644 --- a/src/modules/chat/actions/components/edit-timeout.vue +++ b/src/modules/chat/actions/components/edit-timeout.vue @@ -9,7 +9,7 @@ id="edit_duration" v-model="value.duration_rich" :placeholder="defaults.duration" - class="tw-border-radius-medium tw-font-size-6 tw-full-width tw-input tw-pd-x-1 tw-pd-y-05 tw-mg-y-05" + class="tw-border-radius-medium tw-font-size-6 tw-full-width ffz-input tw-pd-x-1 tw-pd-y-05 tw-mg-y-05" type="text" @input="update()" > @@ -23,7 +23,7 @@ diff --git a/src/modules/chat/actions/components/edit-url.vue b/src/modules/chat/actions/components/edit-url.vue index 0618ea62..289f637c 100644 --- a/src/modules/chat/actions/components/edit-url.vue +++ b/src/modules/chat/actions/components/edit-url.vue @@ -9,7 +9,7 @@ id="edit_url" v-model="value.url" :placeholder="defaults.url" - class="tw-border-radius-medium tw-font-size-6 tw-full-width tw-input tw-pd-x-1 tw-pd-y-05 tw-mg-y-05" + class="tw-border-radius-medium tw-font-size-6 tw-full-width ffz-input tw-pd-x-1 tw-pd-y-05 tw-mg-y-05" @input="$emit('input', value)" > diff --git a/src/modules/chat/actions/index.jsx b/src/modules/chat/actions/index.jsx index b12cea47..dae3a951 100644 --- a/src/modules/chat/actions/index.jsx +++ b/src/modules/chat/actions/index.jsx @@ -263,7 +263,7 @@ export default class Actions extends Module { reason_elements.push(
  • {text} @@ -280,7 +280,7 @@ export default class Actions extends Module { reason_elements.push(
  • {rule} @@ -350,9 +350,9 @@ export default class Actions extends Module { hover_events: true, no_update: true, - tooltipClass: 'ffz-action-balloon tw-balloon tw-block tw-border tw-elevation-1 tw-border-radius-small tw-c-background-base', - arrowClass: 'tw-balloon__tail tw-overflow-hidden tw-absolute', - arrowInner: 'tw-balloon__tail-symbol tw-border-t tw-border-r tw-border-b tw-border-l tw-border-radius-small tw-c-background-base tw-absolute', + tooltipClass: 'ffz-action-balloon ffz-balloon tw-block tw-border tw-elevation-1 tw-border-radius-small tw-c-background-base', + arrowClass: 'ffz-balloon__tail tw-overflow-hidden tw-absolute', + arrowInner: 'ffz-balloon__tail-symbol tw-border-t tw-border-r tw-border-b tw-border-l tw-border-radius-small tw-c-background-base tw-absolute', innerClass: '', popper: { diff --git a/src/modules/chat/components/chat-rich.vue b/src/modules/chat/components/chat-rich.vue index 350cf9b0..852003c6 100644 --- a/src/modules/chat/components/chat-rich.vue +++ b/src/modules/chat/components/chat-rich.vue @@ -281,8 +281,8 @@ export default { class: [ tooltip && 'ffz-tooltip', this.accent && 'ffz-accent-card', - !this.error && 'tw-interactable--hover-enabled', - 'tw-block tw-border-radius-medium tw-full-width tw-interactable tw-interactable--default tw-interactive' + !this.error && 'ffz-interactable--hover-enabled', + 'tw-block tw-border-radius-medium tw-full-width ffz-interactable ffz-interactable--default tw-interactive' ], attrs: { 'data-tooltip-type': 'link', diff --git a/src/modules/chat/override-editor.vue b/src/modules/chat/override-editor.vue index b0ab37c5..75ef1bc8 100644 --- a/src/modules/chat/override-editor.vue +++ b/src/modules/chat/override-editor.vue @@ -20,7 +20,7 @@ diff --git a/src/modules/chat/overrides.js b/src/modules/chat/overrides.js index a7354323..6fe42973 100644 --- a/src/modules/chat/overrides.js +++ b/src/modules/chat/overrides.js @@ -67,9 +67,9 @@ export default class Overrides extends Module { no_update: true, no_auto_remove: true, - tooltipClass: 'ffz-action-balloon tw-balloon tw-block tw-border tw-elevation-1 tw-border-radius-small tw-c-background-base', - arrowClass: '', //tw-balloon__tail tw-overflow-hidden tw-absolute', - arrowInner: '', //tw-balloon__tail-symbol tw-border-t tw-border-r tw-border-b tw-border-l tw-border-radius-small tw-c-background-base tw-absolute', + tooltipClass: 'ffz-action-balloon ffz-balloon tw-block tw-border tw-elevation-1 tw-border-radius-small tw-c-background-base', + arrowClass: '', //ffz-balloon__tail tw-overflow-hidden tw-absolute', + arrowInner: '', //ffz-balloon__tail-symbol tw-border-t tw-border-r tw-border-b tw-border-l tw-border-radius-small tw-c-background-base tw-absolute', innerClass: '', popper: { diff --git a/src/modules/main_menu/components/action-editor.vue b/src/modules/main_menu/components/action-editor.vue index a3fa7f04..0c611fbd 100644 --- a/src/modules/main_menu/components/action-editor.vue +++ b/src/modules/main_menu/components/action-editor.vue @@ -19,7 +19,7 @@ ref="json" v-model="json" readonly - class="tw-full-width tw-full-height tw-border-radius-medium tw-font-size-6 tw-pd-x-1 tw-pd-y-05 tw-input" + class="tw-full-width tw-full-height tw-border-radius-medium tw-font-size-6 tw-pd-x-1 tw-pd-y-05 ffz-input" @focus="$event.target.select()" /> @@ -34,7 +34,7 @@ @@ -47,7 +47,7 @@ id="renderer_type" ref="renderer_type" v-model="edit_data.appearance.type" - class="tw-border-radius-medium tw-font-size-6 tw-full-width tw-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05 tw-mg-y-05" + class="tw-border-radius-medium tw-font-size-6 tw-full-width ffz-select tw-pd-l-1 tw-pd-r-3 tw-pd-y-05 tw-mg-y-05" >
    +
    -
    -
    +
    -
    -
    +
    -
    -
    +
    -
    -
    +
    -