2018-03-23 22:12:46 +02:00

104 lines
3.1 KiB
JavaScript

/* eslint no-underscore-dangle: 0 */
import React from 'react';
import { NativeModules } from 'react-native';
import parse from 'url-parse';
import addons from '@storybook/addons';
import createChannel from '@storybook/channel-websocket';
import { EventEmitter } from 'events';
import { StoryStore, ClientApi } from '@storybook/core/client';
import OnDeviceUI from './components/OnDeviceUI';
import StoryView from './components/StoryView';
export default class Preview {
constructor() {
this._addons = {};
this._decorators = [];
this._events = new EventEmitter();
this._stories = new StoryStore();
this._clientApi = new ClientApi({ storyStore: this._stories });
[
'storiesOf',
'setAddon',
'addDecorator',
'addParameters',
'clearDecorators',
'getStorybook',
].forEach(method => {
this[method] = this._clientApi[method].bind(this._clientApi);
});
}
configure(loadStories, module) {
loadStories();
if (module && module.hot) {
module.hot.accept(() => this._sendSetStories());
// TODO remove all global decorators on dispose
}
}
getStorybookUI(params = {}) {
return () => {
let webUrl = null;
let channel = null;
try {
channel = addons.getChannel();
} catch (e) {
// getChannel throws if the channel is not defined,
// which is fine in this case (we will define it below)
}
if (params.resetStorybook || !channel) {
const host = params.host || parse(NativeModules.SourceCode.scriptURL).hostname;
const port = params.port !== false ? `:${params.port || 7007}` : '';
const query = params.query || '';
const { secured } = params;
const websocketType = secured ? 'wss' : 'ws';
const httpType = secured ? 'https' : 'http';
const url = `${websocketType}://${host}${port}/${query}`;
webUrl = `${httpType}://${host}${port}`;
channel = createChannel({ url });
addons.setChannel(channel);
channel.emit('channelCreated');
}
channel.on('getStories', () => this._sendSetStories());
channel.on('setCurrentStory', d => this._selectStory(d));
this._events.on('setCurrentStory', d => this._selectStory(d));
this._sendSetStories();
this._sendGetCurrentStory();
// finally return the preview component
return params.onDeviceUI
? <OnDeviceUI
stories={this._stories}
events={this._events}
url={webUrl}
animated={params.onDeviceUIAnimated}
/>
: <StoryView url={webUrl} events={this._events} />;
};
}
_sendSetStories() {
const channel = addons.getChannel();
const stories = this._stories.dumpStoryBook();
channel.emit('setStories', { stories });
}
_sendGetCurrentStory() {
const channel = addons.getChannel();
channel.emit('getCurrentStory');
}
_selectStory(selection) {
const { kind, story } = selection;
const storyFn = this._stories.getStoryWithContext(kind, story);
this._events.emit('story', storyFn, selection);
}
}