From ca9139ecc694a80462fed63a9c919cf4bdb91b37 Mon Sep 17 00:00:00 2001 From: ambar Date: Thu, 9 Sep 2021 10:13:37 +0800 Subject: [PATCH] fix: dispose subscription in MessageContext --- .../src/components/PlayerContainer.tsx | 2 +- .../griffith/src/contexts/MessageContext.tsx | 56 +++++++++---------- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/packages/griffith/src/components/PlayerContainer.tsx b/packages/griffith/src/components/PlayerContainer.tsx index 8a9f8ed5..e63aea21 100644 --- a/packages/griffith/src/components/PlayerContainer.tsx +++ b/packages/griffith/src/components/PlayerContainer.tsx @@ -22,7 +22,7 @@ type Props = { sources: PlaySourceMap onBeforePlay?: (...args: any[]) => any onEvent?: (...args: any[]) => any - dispatchRef?: React.Ref + dispatchRef?: React.MutableRefObject initialObjectFit?: ObjectFit useMSE?: boolean defaultQuality?: RealQuality diff --git a/packages/griffith/src/contexts/MessageContext.tsx b/packages/griffith/src/contexts/MessageContext.tsx index 9d9b49a5..639d9a4f 100644 --- a/packages/griffith/src/contexts/MessageContext.tsx +++ b/packages/griffith/src/contexts/MessageContext.tsx @@ -1,5 +1,4 @@ import React from 'react' -import PropTypes from 'prop-types' import EventEmitter from 'eventemitter3' import {EVENTS, createMessageHelper} from 'griffith-message' @@ -43,65 +42,62 @@ type MessageProviderProps = { id: string targetOrigin: string enableCrossWindow?: boolean - onEvent?: Function - dispatchRef?: React.Ref + onEvent?: (name: string, data?: any) => any + dispatchRef?: React.MutableRefObject< + MessageContextValue['dispatchAction'] | null + > } +type MessageHelper = ReturnType +type AnyFunction = (...args: any[]) => void + export class MessageProvider extends React.PureComponent { static defaultProps = { targetOrigin: '*', } - crossWindowEventSubscription: any - crossWindowMessageSubscription: any - dispatchCrossWindowMessage: any - emitter: any + crossWindowMessageSubscription?: ReturnType + emitter: EventEmitter + crossWindowMessager: MessageHelper subscribeCrossWindowMessage: any - constructor(props: any) { + constructor(props: MessageProviderProps) { super(props) this.emitter = new EventEmitter() const {id, targetOrigin} = this.props - const {subscribeMessage, dispatchMessage} = createMessageHelper( - id, - targetOrigin - ) + this.crossWindowMessager = createMessageHelper(id, targetOrigin) - this.subscribeCrossWindowMessage = subscribeMessage - this.dispatchCrossWindowMessage = dispatchMessage - if ((this.props as any).dispatchRef) { - ;(this.props as any).dispatchRef.current = - this.externalContextValue.dispatchAction + if (this.props.dispatchRef) { + this.props.dispatchRef.current = this.externalContextValue.dispatchAction } - Promise.resolve().then(() => + void Promise.resolve().then(() => this.emitEvent(EVENTS.PLAYER.SUBSCRIPTION_READY) ) } componentDidMount() { - if ((this.props as any).enableCrossWindow) { - this.crossWindowMessageSubscription = this.subscribeCrossWindowMessage( - this.dispatchAction - ) + if (this.props.enableCrossWindow) { + this.crossWindowMessageSubscription = + this.crossWindowMessager.subscribeMessage(this.dispatchAction) } } componentWillUnmount() { - if (this.crossWindowEventSubscription) { - this.crossWindowEventSubscription.unsubscribe() + if (this.crossWindowMessageSubscription) { + this.crossWindowMessageSubscription.unsubscribe() } } emitEvent = (eventName: any, data?: any) => { this.emitter.emit(eventName, {__type__: EVENT_TYPE, data}) - ;(this.props as any).onEvent?.(eventName, data) - if ((this.props as any).enableCrossWindow) { - this.dispatchCrossWindowMessage(window.parent, eventName, data) + this.props.onEvent?.(eventName, data) + if (this.props.enableCrossWindow) { + this.crossWindowMessager.dispatchMessage(window.parent, eventName, data) } } - subscribeEvent = (eventName: any, listener: any) => { + subscribeEvent = (eventName: any, listener: AnyFunction) => { const realListener = ({__type__, data}: any = {}) => { if (__type__ === EVENT_TYPE) { listener(data) @@ -114,11 +110,11 @@ export class MessageProvider extends React.PureComponent { } } - dispatchAction = (actionName: any, data: any) => { + dispatchAction = (actionName: string, data?: any) => { this.emitter.emit(actionName, {__type__: ACTION_TYPE, data}) } - subscribeAction = (eventName: any, listener: any) => { + subscribeAction = (eventName: any, listener: AnyFunction) => { const realListener = ({__type__, data}: any) => { if (__type__ === ACTION_TYPE) { listener(data)