Skip to content

Instantly share code, notes, and snippets.

@ljmotta
Last active October 2, 2020 13:43
Show Gist options
  • Save ljmotta/e0308bc981e0a4f1236dab5089326419 to your computer and use it in GitHub Desktop.
Save ljmotta/e0308bc981e0a4f1236dab5089326419 to your computer and use it in GitHub Desktop.
PingPong
export interface PingPong extends PingPongApi {
reactComponent?(): React.ReactNode;
}
export function init(args: { container: HTMLElement; bus: EnvelopeBus; pingPongViewFactory: PingPongFactory }) {
const envelope = new Envelope<
PingPongEnvelopeApi,
PingPongChannelApi,
PingPongEnvelopeViewApi,
PingPongEnvelopeContext
>(args.bus);
const envelopeViewDelegate = async () => {
const ref = React.createRef<PingPongEnvelopeViewApi>();
return new Promise<PingPongEnvelopeViewApi>((res) =>
ReactDOM.render(<PingPongEnvelopeView ref={ref} />, args.container, () => res(ref.current!))
);
};
const context: PingPongEnvelopeContext = {};
return envelope.start(envelopeViewDelegate, context, {
create: (apiFactoryArgs) => new PingPongEnvelopeApiImpl(apiFactoryArgs, args.pingPongViewFactory),
});
}
export class PingPongEnvelopeApiImpl implements PingPongEnvelopeApi {
constructor(
private readonly args: EnvelopeApiFactoryArgs<
PingPongEnvelopeApi,
PingPongChannelApi,
PingPongEnvelopeViewApi,
PingPongEnvelopeContext
>,
private readonly pingPongViewFactory: PingPongFactory
) {}
public async pingPongView__init(association: Association, initArgs: PingPongInitArgs) {
this.args.envelopeBusController.associate(association.origin, association.envelopeServerId);
const pingPongView = this.pingPongViewFactory.create(initArgs, this.args.envelopeBusController.client);
await this.args.view.setView(pingPongView);
}
}
export interface PingPongEnvelopeViewApi {
setView(page: PingPong): Promise<void>;
}
export const PingPongEnvelopeView = React.forwardRef((props, forwardedRef) => {
const [view, setView] = useState<PingPong>();
useImperativeHandle(forwardedRef, () => ({ setView: setView }), []);
return (
<div className={"ping-pong-view--main"}>
{view && (
<>
<h2>This is an implementation of Ping-Pong View</h2>
<p className={"ping-pong-view--p-iframe"}> The {"<iframe>"} border is green </p>
<p className={"ping-pong-view--p-ping-pong"}> The Ping-Pong View implementation border is red </p>
<div id={"ping-pong-view-container"} className={"ping-pong-view-container"}>
{view?.reactComponent?.()}
</div>
</>
)}
</div>
);
});
export interface PingPongFactory {
create(initArgs: PingPongInitArgs, channelApi: MessageBusClient<PingPongChannelApi>): PingPong;
}
export class PingPongReactImplFactory implements PingPongFactory {
public create(initArgs: PingPongInitArgs, channelApi: MessageBusClient<PingPongChannelApi>) {
const ref = React.createRef<PingPongApi>();
const pingPongView: PingPong = {
reactComponent: () => <PingPongReactImpl initArgs={initArgs} channelApi={channelApi} ref={ref} />,
};
return pingPongView;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment