diff --git a/src/Client.js b/src/Client.js index 73a808e12..c64f510cc 100644 --- a/src/Client.js +++ b/src/Client.js @@ -10,6 +10,7 @@ import type {App} from './App.js'; import type Logger from './fb-stubs/Logger.js'; import type {Store} from './reducers/index.js'; +import {setPluginState} from './reducers/pluginStates.js'; import {clientPlugins} from './plugins/index.js'; import {ReactiveSocket, PartialResponder} from 'rsocket-core'; @@ -169,17 +170,17 @@ export default class Client extends EventEmitter { if (persistingPlugin) { const pluginKey = `${this.id}#${params.api}`; const persistedState = this.store.getState().pluginStates[pluginKey]; - this.store.dispatch({ - type: 'SET_PLUGIN_STATE', - payload: { + // $FlowFixMe: We checked persistedStateReducer exists + const newPluginState = persistingPlugin.persistedStateReducer( + persistedState, + params.params, + ); + this.store.dispatch( + setPluginState({ pluginKey, - // $FlowFixMe: We checked persistedStateReducer exists - state: persistingPlugin.persistedStateReducer( - persistedState, - params.params, - ), - }, - }); + state: newPluginState, + }), + ); } else { const apiCallbacks = this.broadcastCallbacks.get(params.api); if (!apiCallbacks) { diff --git a/src/PluginContainer.js b/src/PluginContainer.js index bbebedbdd..672489b2e 100644 --- a/src/PluginContainer.js +++ b/src/PluginContainer.js @@ -6,12 +6,11 @@ */ import type {FlipperPlugin, FlipperBasePlugin} from './plugin.js'; import type LogManager from './fb-stubs/Logger'; -import type Client from './Client.js'; import type BaseDevice from './devices/BaseDevice.js'; import type {Props as PluginProps} from './plugin'; import {FlipperDevicePlugin} from './plugin.js'; -import type {Notification} from './plugin.js'; +import Client from './Client.js'; import { ErrorBoundary, Component, @@ -23,7 +22,6 @@ import { import React from 'react'; import {connect} from 'react-redux'; import {setPluginState} from './reducers/pluginStates.js'; -import {setActiveNotifications} from './reducers/notifications.js'; import {devicePlugins, clientPlugins} from './plugins/index.js'; import NotificationsHub from './NotificationsHub'; import {activateMenuItems} from './MenuBar.js'; @@ -54,10 +52,6 @@ type Props = { pluginKey: string, state: Object, }) => void, - setActiveNotifications: ({ - pluginId: string, - notifications: Array, - }) => void, deepLinkPayload: ?string, }; @@ -131,7 +125,7 @@ class PluginContainer extends Component { }; render() { - const {pluginStates, setPluginState, setActiveNotifications} = this.props; + const {pluginStates, setPluginState} = this.props; const {activePlugin, pluginKey, target} = this.state; if (!activePlugin || !target) { @@ -142,18 +136,7 @@ class PluginContainer extends Component { key: pluginKey, logger: this.props.logger, persistedState: pluginStates[pluginKey] || {}, - setPersistedState: state => { - // We are using setTimout here to wait for previous state updated to - // finish before triggering a new state update. Otherwise this can - // cause race conditions, with multiple state updates happening at the - // same time. - setTimeout(() => setPluginState({pluginKey, state}), 0); - }, - setActiveNotifications: (notifications: Array) => - setActiveNotifications({ - pluginId: pluginKey, - notifications: notifications, - }), + setPersistedState: state => setPluginState({pluginKey, state}), target, deepLinkPayload: this.props.deepLinkPayload, ref: this.refChanged, @@ -197,6 +180,5 @@ export default connect( }), { setPluginState, - setActiveNotifications, }, )(PluginContainer); diff --git a/src/dispatcher/notifications.js b/src/dispatcher/notifications.js index f953d76c8..d1d4f01bf 100644 --- a/src/dispatcher/notifications.js +++ b/src/dispatcher/notifications.js @@ -8,17 +8,45 @@ import type {Store} from '../reducers/index.js'; import type Logger from '../fb-stubs/Logger.js'; import type {PluginNotification} from '../reducers/notifications'; +import type {FlipperPlugin} from '../plugin.js'; import {selectPlugin} from '../reducers/connections'; +import {setActiveNotifications} from '../reducers/notifications'; import {textContent} from '../utils/index'; +import {clientPlugins} from '../plugins/index.js'; export default (store: Store, logger: Logger) => { const knownNotifications: Set = new Set(); + const knownPluginStates: Map = new Map(); + store.subscribe(() => { - const { - activeNotifications, - blacklistedPlugins, - } = store.getState().notifications; + const {notifications, pluginStates} = store.getState(); + + Object.keys(pluginStates).forEach(key => { + if (knownPluginStates.get(key) !== pluginStates[key]) { + knownPluginStates.set(key, pluginStates[key]); + const [client, pluginId] = key.split('#'); + const persistingPlugin: ?Class> = clientPlugins.find( + (p: Class>) => + p.id === pluginId && p.getActiveNotifications, + ); + + if (persistingPlugin) { + store.dispatch( + setActiveNotifications({ + // $FlowFixMe: Ensured getActiveNotifications is implemented in filter + notifications: persistingPlugin.getActiveNotifications( + pluginStates[key], + ), + client, + pluginId, + }), + ); + } + } + }); + + const {activeNotifications, blacklistedPlugins} = notifications; activeNotifications.forEach((n: PluginNotification) => { if ( diff --git a/src/plugin.js b/src/plugin.js index 4cbbf34b9..87a20c84a 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -38,7 +38,6 @@ export type Props = { logger: Logger, persistedState: T, setPersistedState: (state: $Shape) => void, - setActiveNotifications: (Array) => void, target: PluginTarget, deepLinkPayload: ?string, }; @@ -97,10 +96,6 @@ export class FlipperBasePlugin< throw new TypeError(`Reducer ${actionData.type} isn't a function`); } } - - componentDidUpdate(props: Props<*>, state: State): void { - props.setActiveNotifications(this.computeNotifications(props, state)); - } } export class FlipperDevicePlugin extends FlipperBasePlugin< @@ -132,6 +127,7 @@ export class FlipperPlugin extends FlipperBasePlugin< P, > { static persistedStateReducer: ?(persistedState: P, data: Object) => $Shape

; + static getActiveNotifications: ?(persistedState: P) => Array; constructor(props: Props<*>) { super(props);