Skip to content
This repository has been archived by the owner on Nov 10, 2017. It is now read-only.

Queue messages before open #21

Merged
merged 1 commit into from
Jun 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 84 additions & 60 deletions dist/server/public/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -34558,6 +34558,7 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Connection = undefined;

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

Expand All @@ -34573,93 +34574,116 @@

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var ReactNativeProvider = function (_Provider) {
_inherits(ReactNativeProvider, _Provider);

function ReactNativeProvider() {
_classCallCheck(this, ReactNativeProvider);
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ReactNativeProvider).call(this));
var Connection = exports.Connection = function () {
function Connection(address) {
_classCallCheck(this, Connection);

_this.socket = new WebSocket('ws://' + location.host);
_this.socket.onopen = function () {
_this.sendInit();
_this.sendGetStories();
};
return _this;
this._buffer = [];
this._socket = new WebSocket(address);
this._socket.onopen = this.onopen.bind(this);
this._socket.onerror = this.onerror.bind(this);
this._socket.onclose = this.onclose.bind(this);
this._socket.onmessage = this.onmessage.bind(this);
this._handler = Function();
}

_createClass(ReactNativeProvider, [{
key: 'sendInit',
value: function sendInit() {
this.socket.send(JSON.stringify({ type: 'init', data: { clientType: 'browser' } }));
_createClass(Connection, [{
key: 'setHandler',
value: function setHandler(fn) {
this._handler = fn;
}
}, {
key: 'sendGetStories',
value: function sendGetStories() {
this.socket.send(JSON.stringify({ type: 'getStories', data: {} }));
key: 'onopen',
value: function onopen() {
var _this = this;

this._buffer.forEach(function (message) {
return _this._socket.send(message);
});
}
}, {
key: 'sendSelectStory',
value: function sendSelectStory(selection) {
this.socket.send(JSON.stringify({ type: 'selectStory', data: selection }));
key: 'onerror',
value: function onerror(e) {
console.warn('websocket connection error', e.message);
}
}, {
key: 'handleMessage',
value: function handleMessage(api, message) {
switch (message.type) {
case 'addAction':
api.addAction(message.data.action);
break;
case 'setStories':
api.setStories(message.data.stories);
break;
case 'selectStory':
api.selectStory(message.data.kind, message.data.story);
break;
case 'applyShortcut':
api.handleShortcut(message.data.event);
break;
default:
console.error('unknown message type:', message.type, message);
}
key: 'onclose',
value: function onclose(e) {
console.warn('websocket connection closed', e.code, e.reason);
}
}, {
key: 'onmessage',
value: function onmessage(e) {
var message = JSON.parse(e.data);
this._handler(message.type, message.data);
}
}, {
key: 'send',
value: function send(type, data) {
var message = JSON.stringify({ type: type, data: data });
if (this._socket.readyState === WebSocket.OPEN) {
this._socket.send(message);
} else {
this._buffer.push(message);
}
}
}]);

return Connection;
}();

var ReactNativeProvider = function (_Provider) {
_inherits(ReactNativeProvider, _Provider);

function ReactNativeProvider() {
_classCallCheck(this, ReactNativeProvider);

var _this2 = _possibleConstructorReturn(this, Object.getPrototypeOf(ReactNativeProvider).call(this));

_this2.conn = new Connection('ws://' + location.host);
_this2.conn.send('init', { clientType: 'browser' });
_this2.conn.send('getStories', {});
return _this2;
}

_createClass(ReactNativeProvider, [{
key: 'handleAPI',
value: function handleAPI(api) {
var _this2 = this;
var _this3 = this;

api.onStory(function (kind, story) {
_this2.sendSelectStory({ kind: kind, story: story });
_this3.conn.send('selectStory', { kind: kind, story: story });
});

// listen for events
this.socket.onmessage = function (e) {
var message = JSON.parse(e.data);
_this2.handleMessage(api, message);
};

// an error occurred
this.socket.onerror = function (e) {
console.warn('websocket connection error', e.message);
};

// connection closed
this.socket.onclose = function (e) {
console.warn('websocket connection closed', e.code, e.reason);
};
// listen for events from connection
this.conn.setHandler(function (type, data) {
switch (type) {
case 'addAction':
api.addAction(data.action);
break;
case 'setStories':
api.setStories(data.stories);
break;
case 'selectStory':
api.selectStory(data.kind, data.story);
break;
default:
console.error('unknown message type:', type);
}
});
}
}, {
key: 'renderPreview',
value: function renderPreview(selectedKind, selectedStory) {
if (selectedKind && selectedStory) {
this.sendSelectStory({ kind: selectedKind, story: selectedStory });
var selection = { kind: selectedKind, story: selectedStory };
this.conn.send('selectStory', selection);
}
return _react2.default.createElement(_preview2.default, null);
}
Expand Down
104 changes: 57 additions & 47 deletions src/client/manager/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,83 @@ import React from 'react';
import { Provider } from '@kadira/storybook-ui';
import Preview from './preview';

export default class ReactNativeProvider extends Provider {
constructor() {
super();
export class Connection {
constructor(address) {
this._buffer = [];
this._socket = new WebSocket(address);
this._socket.onopen = this.onopen.bind(this);
this._socket.onerror = this.onerror.bind(this);
this._socket.onclose = this.onclose.bind(this);
this._socket.onmessage = this.onmessage.bind(this);
this._handler = Function();
}

this.socket = new WebSocket(`ws://${location.host}`);
this.socket.onopen = () => {
this.sendInit();
this.sendGetStories();
};
setHandler(fn) {
this._handler = fn;
}

sendInit() {
this.socket.send(JSON.stringify({type: 'init', data: {clientType: 'browser'}}));
onopen() {
this._buffer.forEach(message => this._socket.send(message));
}

sendGetStories() {
this.socket.send(JSON.stringify({type: 'getStories', data: {}}));
onerror(e) {
console.warn('websocket connection error', e.message);
}

sendSelectStory(selection) {
this.socket.send(JSON.stringify({type: 'selectStory', data: selection}));
onclose(e) {
console.warn('websocket connection closed', e.code, e.reason);
}

handleMessage(api, message) {
switch (message.type) {
case 'addAction':
api.addAction(message.data.action);
break;
case 'setStories':
api.setStories(message.data.stories);
break;
case 'selectStory':
api.selectStory(message.data.kind, message.data.story);
break;
case 'applyShortcut':
api.handleShortcut(message.data.event);
break;
default:
console.error('unknown message type:', message.type, message);
onmessage(e) {
const message = JSON.parse(e.data);
this._handler(message.type, message.data);
}

send(type, data) {
const message = JSON.stringify({type, data});
if (this._socket.readyState === WebSocket.OPEN) {
this._socket.send(message);
} else {
this._buffer.push(message);
}
}
}

export default class ReactNativeProvider extends Provider {
constructor() {
super();
this.conn = new Connection(`ws://${location.host}`);
this.conn.send('init', {clientType: 'browser'});
this.conn.send('getStories', {});
}

handleAPI(api) {
api.onStory((kind, story) => {
this.sendSelectStory({kind, story});
this.conn.send('selectStory', {kind, story});
});

// listen for events
this.socket.onmessage = (e) => {
const message = JSON.parse(e.data);
this.handleMessage(api, message);
};

// an error occurred
this.socket.onerror = (e) => {
console.warn('websocket connection error', e.message);
};

// connection closed
this.socket.onclose = (e) => {
console.warn('websocket connection closed', e.code, e.reason);
};
// listen for events from connection
this.conn.setHandler((type, data) => {
switch (type) {
case 'addAction':
api.addAction(data.action);
break;
case 'setStories':
api.setStories(data.stories);
break;
case 'selectStory':
api.selectStory(data.kind, data.story);
break;
default:
console.error('unknown message type:', type);
}
});
}

renderPreview(selectedKind, selectedStory) {
if (selectedKind && selectedStory) {
this.sendSelectStory({kind: selectedKind, story: selectedStory});
const selection = {kind: selectedKind, story: selectedStory};
this.conn.send('selectStory', selection);
}
return <Preview />;
}
Expand Down