added saga for asset display
This commit is contained in:
parent
3e8f7ee150
commit
c9d4aed229
14 changed files with 224 additions and 152 deletions
|
@ -49,6 +49,7 @@
|
||||||
"react-redux": "^5.0.6",
|
"react-redux": "^5.0.6",
|
||||||
"react-router-dom": "^4.2.2",
|
"react-router-dom": "^4.2.2",
|
||||||
"redux": "^3.7.2",
|
"redux": "^3.7.2",
|
||||||
|
"redux-saga": "^0.16.0",
|
||||||
"request": "^2.83.0",
|
"request": "^2.83.0",
|
||||||
"request-promise": "^4.2.2",
|
"request-promise": "^4.2.2",
|
||||||
"sequelize": "^4.1.0",
|
"sequelize": "^4.1.0",
|
||||||
|
@ -62,6 +63,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "^6.26.0",
|
"babel-core": "^6.26.0",
|
||||||
"babel-loader": "^7.1.2",
|
"babel-loader": "^7.1.2",
|
||||||
|
"babel-polyfill": "^6.26.0",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
"babel-preset-stage-2": "^6.24.1",
|
"babel-preset-stage-2": "^6.24.1",
|
||||||
|
|
|
@ -59,3 +59,27 @@ export function updateAssetClaimData (data, shortId) {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function fileRequested (name, claimId) {
|
||||||
|
return {
|
||||||
|
type: actions.FILE_REQUESTED,
|
||||||
|
data: {
|
||||||
|
name,
|
||||||
|
claimId,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function updateFileIsAvailable (status) {
|
||||||
|
return {
|
||||||
|
type: actions.FILE_IS_AVAILABLE_UPDATE,
|
||||||
|
data: status,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export function updateShowAssetError (error) {
|
||||||
|
return {
|
||||||
|
type: actions.SHOW_ASSET_ERROR,
|
||||||
|
data: error,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import ProgressBar from 'components/ProgressBar';
|
|
||||||
import Request from 'utils/request';
|
|
||||||
import { LOCAL_CHECK, SEARCHING, UNAVAILABLE, AVAILABLE } from 'constants/asset_display_states';
|
|
||||||
|
|
||||||
class AssetDisplay extends React.Component {
|
|
||||||
constructor (props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
error : null,
|
|
||||||
status: LOCAL_CHECK,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
componentDidMount () {
|
|
||||||
this.isLocalFileAvailableOnServer()
|
|
||||||
.then(isAvailable => {
|
|
||||||
if (!isAvailable) {
|
|
||||||
this.setState({status: SEARCHING});
|
|
||||||
return this.triggerGetAssetOnServer();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.setState({status: AVAILABLE});
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
this.setState({
|
|
||||||
status: UNAVAILABLE,
|
|
||||||
error : error.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
isLocalFileAvailableOnServer () {
|
|
||||||
console.log(`checking if file is available for ${this.props.name}#${this.props.claimId}`);
|
|
||||||
const url = `/api/file-is-available/${this.props.name}/${this.props.claimId}`;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
Request(url)
|
|
||||||
.then(({success, message, data: isAvailable}) => {
|
|
||||||
if (success) {
|
|
||||||
console.log('/api/file-is-available response:', isAvailable);
|
|
||||||
return resolve(isAvailable);
|
|
||||||
}
|
|
||||||
reject(new Error(message));
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
triggerGetAssetOnServer () {
|
|
||||||
console.log(`getting claim for ${this.props.name}#${this.props.claimId}`);
|
|
||||||
const url = `/api/claim-get/${this.props.name}/${this.props.claimId}`;
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
Request(url)
|
|
||||||
.then(({success, message}) => {
|
|
||||||
console.log('/api/claim-get response:', success, message);
|
|
||||||
if (success) {
|
|
||||||
return resolve(true);
|
|
||||||
}
|
|
||||||
reject(new Error(message));
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
render () {
|
|
||||||
return (
|
|
||||||
<div id="asset-display-component">
|
|
||||||
{(this.state.status === LOCAL_CHECK) &&
|
|
||||||
<div>
|
|
||||||
<p>Checking to see if Spee.ch has your asset locally...</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{(this.state.status === SEARCHING) &&
|
|
||||||
<div>
|
|
||||||
<p>Sit tight, we're searching the LBRY blockchain for your asset!</p>
|
|
||||||
<ProgressBar size={12}/>
|
|
||||||
<p>Curious what magic is happening here? <a className="link--primary" target="blank" href="https://lbry.io/faq/what-is-lbry">Learn more.</a></p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{(this.state.status === UNAVAILABLE) &&
|
|
||||||
<div>
|
|
||||||
<p>Unfortunately, we couldn't download your asset from LBRY. You can help us out by sharing the below error message in the <a className="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">LBRY discord</a>.</p>
|
|
||||||
<i><p id="error-message">{this.state.error}</p></i>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{(this.state.status === AVAILABLE) &&
|
|
||||||
(() => {
|
|
||||||
switch (this.props.contentType) {
|
|
||||||
case 'image/jpeg':
|
|
||||||
case 'image/jpg':
|
|
||||||
case 'image/png':
|
|
||||||
return (
|
|
||||||
<img className="asset" src={this.props.src} alt={this.props.name}/>
|
|
||||||
);
|
|
||||||
case 'image/gif':
|
|
||||||
return (
|
|
||||||
<img className="asset" src={this.props.src} alt={this.props.name}/>
|
|
||||||
);
|
|
||||||
case 'video/mp4':
|
|
||||||
return (
|
|
||||||
<video id="video" className="asset" controls poster={this.props.thumbnail}>
|
|
||||||
<source src={this.props.src}/>
|
|
||||||
<p>Your browser does not support the <code>video</code> element.</p>
|
|
||||||
</video>
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
return (
|
|
||||||
<p>Unsupported file type</p>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AssetDisplay.propTypes = {
|
|
||||||
name : PropTypes.string.isRequired,
|
|
||||||
claimId : PropTypes.string.isRequired,
|
|
||||||
src : PropTypes.string.isRequired,
|
|
||||||
contentType: PropTypes.string.isRequired,
|
|
||||||
fileExt : PropTypes.string.isRequired,
|
|
||||||
thumbnail : PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AssetDisplay;
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import NavBar from 'containers/NavBar';
|
import NavBar from 'containers/NavBar';
|
||||||
import AssetTitle from 'components/AssetTitle';
|
import AssetTitle from 'components/AssetTitle';
|
||||||
import AssetDisplay from 'components/AssetDisplay';
|
import AssetDisplay from 'containers/AssetDisplay';
|
||||||
import AssetInfo from 'components/AssetInfo';
|
import AssetInfo from 'components/AssetInfo';
|
||||||
|
|
||||||
class ShowAssetDetails extends React.Component {
|
class ShowAssetDetails extends React.Component {
|
||||||
|
@ -25,14 +25,7 @@ class ShowAssetDetails extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
<div className="column column--5 column--sml-10 align-content-top">
|
<div className="column column--5 column--sml-10 align-content-top">
|
||||||
<div className="row row--padded">
|
<div className="row row--padded">
|
||||||
<AssetDisplay
|
<AssetDisplay />
|
||||||
name={this.props.claimData.name}
|
|
||||||
claimId={this.props.claimData.claimId}
|
|
||||||
src={`/${this.props.claimData.claimId}/${this.props.claimData.name}.${this.props.claimData.fileExt}`}
|
|
||||||
contentType={this.props.claimData.contentType}
|
|
||||||
fileExt={this.props.claimData.fileExt}
|
|
||||||
thumbnail={this.props.claimData.thumbnail}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div><div className="column column--5 column--sml-10 align-content-top">
|
</div><div className="column column--5 column--sml-10 align-content-top">
|
||||||
<div className="row row--padded">
|
<div className="row row--padded">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import AssetDisplay from 'components/AssetDisplay';
|
import AssetDisplay from 'containers/AssetDisplay';
|
||||||
|
|
||||||
class ShowLite extends React.Component {
|
class ShowLite extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export const LOCAL_CHECK = 'LOCAL_CHECK';
|
export const LOCAL_CHECK = 'LOCAL_CHECK';
|
||||||
export const SEARCHING = 'SEARCHING';
|
|
||||||
export const UNAVAILABLE = 'UNAVAILABLE';
|
export const UNAVAILABLE = 'UNAVAILABLE';
|
||||||
|
export const ERROR = 'ERROR';
|
||||||
export const AVAILABLE = 'AVAILABLE';
|
export const AVAILABLE = 'AVAILABLE';
|
||||||
|
|
|
@ -3,3 +3,6 @@ export const REQUEST_UPDATE_CLAIM = 'REQUEST_UPDATE_CLAIM';
|
||||||
export const CHANNEL_DATA_UPDATE = 'CHANNEL_DATA_UPDATE';
|
export const CHANNEL_DATA_UPDATE = 'CHANNEL_DATA_UPDATE';
|
||||||
export const CHANNEL_CLAIMS_DATA_UPDATE = 'CHANNEL_CLAIMS_DATA_UPDATE';
|
export const CHANNEL_CLAIMS_DATA_UPDATE = 'CHANNEL_CLAIMS_DATA_UPDATE';
|
||||||
export const ASSET_CLAIM_DATA_UPDATE = 'ASSET_CLAIM_DATA_UPDATE';
|
export const ASSET_CLAIM_DATA_UPDATE = 'ASSET_CLAIM_DATA_UPDATE';
|
||||||
|
export const FILE_REQUESTED = 'FILE_REQUESTED';
|
||||||
|
export const FILE_IS_AVAILABLE_UPDATE = 'FILE_IS_AVAILABLE_UPDATE';
|
||||||
|
export const SHOW_ASSET_ERROR = 'SHOW_ASSET_ERROR';
|
||||||
|
|
21
react/containers/AssetDisplay/index.js
Normal file
21
react/containers/AssetDisplay/index.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import View from './view';
|
||||||
|
import { fileRequested } from 'actions/show';
|
||||||
|
|
||||||
|
const mapStateToProps = ({ show }) => {
|
||||||
|
return {
|
||||||
|
error : show.showAsset.error,
|
||||||
|
status : show.showAsset.status,
|
||||||
|
claimData: show.showAsset.claimData,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => {
|
||||||
|
return {
|
||||||
|
onFileRequest: (name, claimId) => {
|
||||||
|
dispatch(fileRequested(name, claimId));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(View);
|
79
react/containers/AssetDisplay/view.jsx
Normal file
79
react/containers/AssetDisplay/view.jsx
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ProgressBar from 'components/ProgressBar/index';
|
||||||
|
import { LOCAL_CHECK, UNAVAILABLE, ERROR, AVAILABLE } from 'constants/asset_display_states';
|
||||||
|
|
||||||
|
class AssetDisplay extends React.Component {
|
||||||
|
componentDidMount () {
|
||||||
|
this.props.onFileRequest(this.props.claimData.name, this.props.claimData.claimId);
|
||||||
|
}
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
// if (nextProps.name !== this.props.name && nextProps.claimId !== this.props.claimId) {
|
||||||
|
// this.props.onCheckServerForFile(nextProps.name, nextProps.claimId);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
const status = this.props.status;
|
||||||
|
const error = this.props.error;
|
||||||
|
const { name, claimId, contentType, fileExt, thumbnail } = this.props.claimData;
|
||||||
|
return (
|
||||||
|
<div id="asset-display-component">
|
||||||
|
{(status === LOCAL_CHECK) &&
|
||||||
|
<div>
|
||||||
|
<p>Checking to see if Spee.ch has your asset locally...</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{(status === UNAVAILABLE) &&
|
||||||
|
<div>
|
||||||
|
<p>Sit tight, we're searching the LBRY blockchain for your asset!</p>
|
||||||
|
<ProgressBar size={12}/>
|
||||||
|
<p>Curious what magic is happening here? <a className="link--primary" target="blank" href="https://lbry.io/faq/what-is-lbry">Learn more.</a></p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{(status === ERROR) &&
|
||||||
|
<div>
|
||||||
|
<p>Unfortunately, we couldn't download your asset from LBRY. You can help us out by sharing the below error message in the <a className="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">LBRY discord</a>.</p>
|
||||||
|
<i><p id="error-message">{error}</p></i>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{(status === AVAILABLE) &&
|
||||||
|
(() => {
|
||||||
|
switch (contentType) {
|
||||||
|
case 'image/jpeg':
|
||||||
|
case 'image/jpg':
|
||||||
|
case 'image/png':
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
className="asset"
|
||||||
|
src={`/${claimId}/${name}.${fileExt}`}
|
||||||
|
alt={name}/>
|
||||||
|
);
|
||||||
|
case 'image/gif':
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
className="asset"
|
||||||
|
src={`/${claimId}/${name}.${fileExt}`}
|
||||||
|
alt={name}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
case 'video/mp4':
|
||||||
|
return (
|
||||||
|
<video id="video" className="asset" controls poster={thumbnail}>
|
||||||
|
<source
|
||||||
|
src={`/${claimId}/${name}.${fileExt}`}
|
||||||
|
/>
|
||||||
|
<p>Your browser does not support the <code>video</code> element.</p>
|
||||||
|
</video>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<p>Unsupported file type</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AssetDisplay;
|
|
@ -7,8 +7,8 @@ const mapStateToProps = ({ show }) => {
|
||||||
modifier : show.assetRequest.modifier,
|
modifier : show.assetRequest.modifier,
|
||||||
claim : show.assetRequest.name,
|
claim : show.assetRequest.name,
|
||||||
extension: show.assetRequest.extension,
|
extension: show.assetRequest.extension,
|
||||||
claimData: show.showAsset.claimData.data,
|
claimData: show.showAsset.claimData,
|
||||||
shortId : show.showAsset.claimData.shortId,
|
shortId : show.showAsset.shortId,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
import { createStore } from 'redux';
|
import { createStore, applyMiddleware, compose } from 'redux';
|
||||||
import Reducer from 'reducers';
|
import Reducer from 'reducers';
|
||||||
|
import createSagaMiddleware from 'redux-saga';
|
||||||
|
import rootSaga from 'sagas';
|
||||||
import Root from './root';
|
import Root from './root';
|
||||||
|
|
||||||
|
const sagaMiddleware = createSagaMiddleware();
|
||||||
|
const middleware = applyMiddleware(sagaMiddleware);
|
||||||
|
|
||||||
let store = createStore(
|
let store = createStore(
|
||||||
Reducer,
|
Reducer,
|
||||||
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
|
compose(middleware, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
sagaMiddleware.run(rootSaga);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<Root store={store} />,
|
<Root store={store} />,
|
||||||
document.getElementById('react-app')
|
document.getElementById('react-app')
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as actions from 'constants/show_action_types';
|
import * as actions from 'constants/show_action_types';
|
||||||
import { CHANNEL, ASSET } from 'constants/show_request_types';
|
import { CHANNEL, ASSET } from 'constants/show_request_types';
|
||||||
|
import { LOCAL_CHECK, ERROR } from 'constants/asset_display_states';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
requestType : null,
|
requestType : null,
|
||||||
|
@ -32,11 +33,11 @@ const initialState = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
showAsset: {
|
showAsset: {
|
||||||
claimData: {
|
error : null,
|
||||||
data : null,
|
status : LOCAL_CHECK,
|
||||||
|
claimData: null,
|
||||||
shortId : null,
|
shortId : null,
|
||||||
},
|
},
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -69,9 +70,23 @@ export default function (state = initialState, action) {
|
||||||
});
|
});
|
||||||
case actions.ASSET_CLAIM_DATA_UPDATE:
|
case actions.ASSET_CLAIM_DATA_UPDATE:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
showAsset: {
|
showAsset: Object.assign({}, state.showAsset, {
|
||||||
claimData: action.data,
|
claimData: action.data.data,
|
||||||
},
|
shortId : action.data.shortId,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
case actions.FILE_IS_AVAILABLE_UPDATE:
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
showAsset: Object.assign({}, state.showAsset, {
|
||||||
|
status: action.data,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
case actions.SHOW_ASSET_ERROR:
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
showAsset: Object.assign({}, state.showAsset, {
|
||||||
|
error : action.data,
|
||||||
|
status: ERROR,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|
57
react/sagas/index.js
Normal file
57
react/sagas/index.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import { call, put, all, takeLatest } from 'redux-saga/effects';
|
||||||
|
import Request from 'utils/request';
|
||||||
|
import * as actions from 'constants/show_action_types';
|
||||||
|
import { updateFileIsAvailable, updateShowAssetError } from 'actions/show';
|
||||||
|
import { UNAVAILABLE, AVAILABLE } from 'constants/asset_display_states';
|
||||||
|
|
||||||
|
function* helloSaga () {
|
||||||
|
console.log('Hello Sagas!');
|
||||||
|
}
|
||||||
|
|
||||||
|
function* retriveFile (action) {
|
||||||
|
const name = action.data.name;
|
||||||
|
const claimId = action.data.claimId;
|
||||||
|
// see if the file is available
|
||||||
|
console.log(`checking if file is available for ${name}#${claimId}`);
|
||||||
|
let url = `/api/file-is-available/${name}/${claimId}`;
|
||||||
|
let success, message, isAvailable;
|
||||||
|
try {
|
||||||
|
({ success, message, data: isAvailable } = yield call(Request, url));
|
||||||
|
} catch (error) {
|
||||||
|
return yield put(updateShowAssetError(error.message));
|
||||||
|
};
|
||||||
|
if (success) {
|
||||||
|
console.log('/api/file-is-available response:', isAvailable);
|
||||||
|
if (isAvailable) {
|
||||||
|
return yield put(updateFileIsAvailable(AVAILABLE));
|
||||||
|
}
|
||||||
|
yield put(updateFileIsAvailable(UNAVAILABLE));
|
||||||
|
} else {
|
||||||
|
yield put(updateShowAssetError(message));
|
||||||
|
}
|
||||||
|
// initiate get request for the file
|
||||||
|
console.log(`getting claim for ${name}#${claimId}`);
|
||||||
|
url = `/api/claim-get/${name}/${claimId}`;
|
||||||
|
try {
|
||||||
|
({ success, message } = yield call(Request, url));
|
||||||
|
} catch (error) {
|
||||||
|
return yield put(updateShowAssetError(error.message));
|
||||||
|
};
|
||||||
|
if (success) {
|
||||||
|
console.log('/api/glaim-get response:', message);
|
||||||
|
yield put(updateFileIsAvailable(AVAILABLE));
|
||||||
|
} else {
|
||||||
|
yield put(updateShowAssetError(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function* watchUpdateFileIsAvailable () {
|
||||||
|
yield takeLatest(actions.FILE_REQUESTED, retriveFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function* rootSaga () {
|
||||||
|
yield all([
|
||||||
|
helloSaga(),
|
||||||
|
watchUpdateFileIsAvailable(),
|
||||||
|
]);
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ const Path = require('path');
|
||||||
const REACT_ROOT = Path.resolve(__dirname, 'react/');
|
const REACT_ROOT = Path.resolve(__dirname, 'react/');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry : ['whatwg-fetch', './react/index.js'],
|
entry : ['babel-polyfill', 'whatwg-fetch', './react/index.js'],
|
||||||
output: {
|
output: {
|
||||||
path : Path.join(__dirname, '/public/bundle/'),
|
path : Path.join(__dirname, '/public/bundle/'),
|
||||||
filename: 'bundle.js',
|
filename: 'bundle.js',
|
||||||
|
|
Loading…
Reference in a new issue