Skip to content

Commit

Permalink
Merge pull request #9 from medayo/feat/server4storybook
Browse files Browse the repository at this point in the history
Feat/server4storybook
  • Loading branch information
virus2016 authored Oct 17, 2018
2 parents 10e44f4 + db46965 commit b54f5b9
Show file tree
Hide file tree
Showing 28 changed files with 1,263 additions and 366 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ coverage/
.DS_Store
.vs/
.expo/
demo/
bin/
test/
coolstorybook/
3 changes: 3 additions & 0 deletions .watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ignore_dirs": ["test", "coolstorybook"]
}
2 changes: 1 addition & 1 deletion App.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DemoApp } from './dist/example/app';
import { DemoApp } from './demo/example/app';

const app = DemoApp;

Expand Down
26 changes: 26 additions & 0 deletions example/TextInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { Text, View } from 'react-native';
import { CoolStorybookService } from '../lib/client/snapshot.service';
import { addStoriesOf, CreateStory } from '../lib/client/stories.component';

interface ITextInfo {
children: string;
}

@CreateStory('This tests the component with text "Expo is awesome"',
() => <ExampleText>Expo is awesome</ExampleText>,
{ transparent: false })
export class ExampleText extends React.Component<ITextInfo, any> {
constructor(props: any) {
super(props);
}

public componentDidMount() {
addStoriesOf('ExampleText', 'This was the render of: ' + this.props.children, () => this.render());
}
public render() {
return (
<Text>{this.props.children}</Text>
);
}
}
33 changes: 29 additions & 4 deletions example/app.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,44 @@
import * as React from 'react';
import { View } from 'react-native';
import { Snapshot } from '../lib/snapshot.component';
import { TouchableOpacity, View, ViewStyle } from 'react-native';
import { CoolStorybook } from '../lib/client/snapshot.component';
import { CoolStorybookService } from '../lib/client/snapshot.service';
import './stories/text.story';
import { ExampleText } from './TextInfo';

const container: ViewStyle = {
alignItems: 'center',
flex: 1,
justifyContent: 'center',
};
export class DemoApp extends React.Component<any, any> {

constructor(props: any) {
super(props);
this.sendStories = this.sendStories.bind(this);
}

public componentDidMount() {
this.sendStories();
}
public render() {

return (
<View>
<Snapshot />
<View style={{ flex: 1 }}>
<CoolStorybook
host='http://192.168.1.102:3000'
ref={(ref) => CoolStorybookService.setRef(ref)}
/>
<View style={container}>
<ExampleText>This is a demo of Expo-Cool-Storybook</ExampleText>
<TouchableOpacity onPress={this.sendStories}>
<ExampleText>Tap here to recapture and send!</ExampleText>
</TouchableOpacity>
</View>
</View>
);
}

private sendStories() {
CoolStorybookService.sendAllStories();
}
}
12 changes: 6 additions & 6 deletions example/stories/text.story.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import { Text } from 'react-native';
import { storiesOf } from '../../lib/';
import { storiesOf } from '../../lib/client';

storiesOf('Circlebutton', module)
.add('with Text', () =>
<Text>gogogo</Text>,
storiesOf('Circlebutton', { transparent: false })
.addDetail('with Text', () =>
<Text>James</Text>,

)
.add('with Text 2', () =>
<Text>This is text2</Text>,
.addDetail('with Text 2', () =>
<Text>This is text212121221</Text>,
);
10 changes: 10 additions & 0 deletions lib/client/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { CoolStorybook } from './snapshot.component';
import { CoolStorybookService } from './snapshot.service';
import { CreateStory, storiesOf } from './stories.component';

export {
CoolStorybook,
storiesOf,
CreateStory,
CoolStorybookService,
};
78 changes: 78 additions & 0 deletions lib/client/snapshot.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Constants, takeSnapshotAsync } from 'expo';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { View } from 'react-native';
import { Story } from './story.component';
import { IStoriesOfOptions, StoryStorage } from './story.storage';
import { WebsocketService } from './websocket.service';

enum ImageType {
png = 'png',
jpg = 'jpg',
jpeg = 'jpeg',
webm = 'webm',
}

interface ICoolStoryBook {
host: string;
}

@observer export class CoolStorybook extends React.Component<ICoolStoryBook, {}> {
@observable private snapshot: { snapshot: string, type: string };
@observable private storyComponent: React.ReactNode;
@observable private snapshotRef: any;

constructor(props: Readonly<ICoolStoryBook>) {
super(props);
WebsocketService.start(props.host);
this.loaded = this.loaded.bind(this);
}

public render() {
return (
<View style={{ position: 'absolute', zIndex: -9999, top: -9999 }} ref={this.loaded}>
{this.storyComponent}
</View>
);
}

public async sendAllStories() {
const stories = StoryStorage.getAll();
for (const [key, detail] of Object.entries(stories)) {
await this.sendStory(detail, key);
}
}

public async sendStory(detail: { story: Story; options: IStoriesOfOptions; }, key: string) {
for (const story of detail.story.storyInfo) {
this.storyComponent = story.callback();
this.snapshot = await this.takeSnapshot(detail.options.transparent ? ImageType.png : ImageType.jpg);
await WebsocketService.emit('imageSent', {
device: Constants.deviceName,
image: this.snapshot.snapshot,
imageType: this.snapshot.type,
story,
storyName: key,
});
}
}

private takeSnapshot(type: ImageType = ImageType.png):
Promise<{ snapshot: string, type: string }> {
return new Promise((resolve) => {
setTimeout(async () => {
const result = await takeSnapshotAsync(this.snapshotRef, {
format: type,
result: 'base64',
});
resolve({ snapshot: result, type });
}, 50);
});

}

private loaded(ref: any) {
this.snapshotRef = ref;
}
}
22 changes: 22 additions & 0 deletions lib/client/snapshot.service.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { CoolStorybook } from './snapshot.component';
import { StoryStorage } from './story.storage';

class CoolStorybookServiceDef {
private ref: CoolStorybook;

public setRef(ref: CoolStorybook) {
this.ref = ref;
}

public sendAllStories() {
this.ref.sendAllStories();
}

public sendStory(storyName: string) {
const story = StoryStorage.get(storyName);
this.ref.sendStory(story, storyName);
}

}

export const CoolStorybookService = new CoolStorybookServiceDef();
50 changes: 50 additions & 0 deletions lib/client/stories.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

import { RenderFunction, Story } from './story.component';
import { IStoriesOfOptions, StoryStorage } from './story.storage';

export function storiesOf(
storyName: string,
options: IStoriesOfOptions): Story {

let getStory;
try {
getStory = StoryStorage.get(storyName).story;
} catch (err) {
getStory = new Story();
}
return StoryStorage.add(storyName, getStory, options);
}

export function addStoriesOf(
storyName: string,
detailOfStory: string,
render: RenderFunction,
options?: IStoriesOfOptions,
) {

const story = storiesOf(
storyName,
options);

story.addDetail(detailOfStory, render);
}

// tslint:disable-next-line:no-identical-functions
export function CreateStory(
detailOfStory: string,
render: RenderFunction,
options?: IStoriesOfOptions,
overideStoryClassName?: string,
) {
return (target: any) => {
addStoriesOf(
overideStoryClassName || target.name,
detailOfStory,
render,
options);
};
}

export function getStories() {
return StoryStorage.getAll();
}
2 changes: 1 addition & 1 deletion lib/story.component.tsx → lib/client/story.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export class Story {

public storyInfo: Array<{ storyName: string, callback: RenderFunction }> = [];

public add(storyName: string, callback: RenderFunction): this {
public addDetail(storyName: string, callback: RenderFunction): this {
this.storyInfo.push({
callback,
storyName,
Expand Down
34 changes: 34 additions & 0 deletions lib/client/story.storage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

import { Story } from './story.component';

export interface IStoriesOfOptions {
transparent?: boolean;
}

export class StoryStorageDef {

private stories: any = {};

public getAll(): Array<{
story: Story,
options: IStoriesOfOptions,
}> {
return this.stories;
}

public add(storyName: string, story: Story, options: IStoriesOfOptions = {}): Story {
this.stories[storyName] = { story, options };

return this.stories[storyName].story;
}

public get(storyName: string): {
story: Story,
options: IStoriesOfOptions,
} {
return this.stories[storyName];
}

}

export const StoryStorage = new StoryStorageDef();
20 changes: 20 additions & 0 deletions lib/client/websocket.service.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import SocketIOClient from 'socket.io-client';
class WebSocketDef {
private socket: SocketIOClient.Socket;

public start(host: string): any {
this.socket = SocketIOClient(host);
}

public emit(eventName: string, data: any): Promise<any> {
return new Promise((resolve, reject) => {
this.socket.on('compared', () => {
this.socket.off('compared');
resolve();
});
this.socket.emit(eventName, data);
});
}
}

export const WebsocketService = new WebSocketDef();
15 changes: 15 additions & 0 deletions lib/expo-cool-storybook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env node

import { parse, version } from 'commander';
import 'es6-shim';
import 'reflect-metadata';
import { WebsocketServer } from './server';

version('0.1.0')
.command('start [options...]')
.option('-p, --port <n>', 'An integer argument', parseInt)
.action((env, options: { port: number }) => {
WebsocketServer.start(options.port);
});

parse(process.argv);
7 changes: 0 additions & 7 deletions lib/index.tsx

This file was deleted.

Loading

0 comments on commit b54f5b9

Please sign in to comment.