diff --git a/react/actions/show.js b/react/actions/show.js index 67bbecdd..db7e0794 100644 --- a/react/actions/show.js +++ b/react/actions/show.js @@ -2,7 +2,7 @@ import * as actions from 'constants/show_action_types'; export function updateRequestWithChannelRequest (name, id) { return { - type: actions.REQUEST_UPDATE_CHANNEL, + type: actions.REQUEST_CHANNEL_UPDATE, data: { name, id, @@ -12,7 +12,7 @@ export function updateRequestWithChannelRequest (name, id) { export function updateRequestWithAssetRequest (name, id, channelName, channelId, extension) { return { - type: actions.REQUEST_UPDATE_CLAIM, + type: actions.REQUEST_CLAIM_UPDATE, data: { name, modifier: { @@ -27,6 +27,13 @@ export function updateRequestWithAssetRequest (name, id, channelName, channelId, }; }; +export function updateRequestError (error) { + return { + type: actions.REQUEST_ERROR_UPDATE, + data: error, + }; +} + export function updateChannelData (name, longId, shortId) { return { type: actions.CHANNEL_DATA_UPDATE, @@ -70,9 +77,9 @@ export function fileRequested (name, claimId) { }; }; -export function updateFileIsAvailable (status) { +export function updateFileAvailability (status) { return { - type: actions.FILE_IS_AVAILABLE_UPDATE, + type: actions.FILE_AVAILABILITY_UPDATE, data: status, }; }; @@ -83,3 +90,10 @@ export function updateShowAssetError (error) { data: error, }; }; + +export function updateDisplayAssetError (error) { + return { + type: actions.DISPLAY_ASSET_ERROR, + data: error, + }; +}; diff --git a/react/containers/AssetDisplay/index.js b/react/components/AssetDisplay/index.js similarity index 84% rename from react/containers/AssetDisplay/index.js rename to react/components/AssetDisplay/index.js index 8b807cdc..1250c997 100644 --- a/react/containers/AssetDisplay/index.js +++ b/react/components/AssetDisplay/index.js @@ -4,8 +4,8 @@ import { fileRequested } from 'actions/show'; const mapStateToProps = ({ show }) => { return { - error : show.showAsset.error, - status : show.showAsset.status, + error : show.displayAsset.error, + status : show.displayAsset.status, claimData: show.showAsset.claimData, }; }; diff --git a/react/containers/AssetDisplay/view.jsx b/react/components/AssetDisplay/view.jsx similarity index 91% rename from react/containers/AssetDisplay/view.jsx rename to react/components/AssetDisplay/view.jsx index c7da2366..fa719ac9 100644 --- a/react/containers/AssetDisplay/view.jsx +++ b/react/components/AssetDisplay/view.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import ProgressBar from 'components/ProgressBar/index'; +import ProgressBar from 'components/ProgressBar'; import { LOCAL_CHECK, UNAVAILABLE, ERROR, AVAILABLE } from 'constants/asset_display_states'; class AssetDisplay extends React.Component { @@ -7,9 +7,7 @@ class AssetDisplay extends React.Component { this.props.onFileRequest(this.props.claimData.name, this.props.claimData.claimId); } render () { - const status = this.props.status; - const error = this.props.error; - const { name, claimId, contentType, fileExt, thumbnail } = this.props.claimData; + const { status, error, claimData: { name, claimId, contentType, fileExt, thumbnail } } = this.props; return (
{(status === LOCAL_CHECK) && diff --git a/react/components/AssetInfo/index.js b/react/components/AssetInfo/index.js index b45d60a2..a4cd0814 100644 --- a/react/components/AssetInfo/index.js +++ b/react/components/AssetInfo/index.js @@ -1,179 +1,19 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Link } from 'react-router-dom'; +import { connect } from 'react-redux'; +import View from './view'; -class AssetInfo extends React.Component { - constructor (props) { - super(props); - this.state = { - showDetails: false, - }; - this.toggleDetails = this.toggleDetails.bind(this); - this.copyToClipboard = this.copyToClipboard.bind(this); - } - toggleDetails () { - if (this.state.showDetails) { - return this.setState({showDetails: false}); - } - this.setState({showDetails: true}); - } - copyToClipboard (event) { - var elementToCopy = event.target.dataset.elementtocopy; - var element = document.getElementById(elementToCopy); - element.select(); - try { - document.execCommand('copy'); - } catch (err) { - this.setState({error: 'Oops, unable to copy'}); - } - } - render () { - const { channelName, certificateId, description, name, claimId, fileExt, contentType, thumbnail, host, shortId } = this.props; - return ( -
- {channelName && -
-
- Channel: -
-
- {channelName} -
-
- } - - {description && -
- {description} -
- } - -
- -
-
- Embed: -
-
-
-
- - {(contentType === 'video/mp4') ? ( - `}/> - ) : ( - `} - /> - )} -
-
-
- -
-
-
-
-
- -
-
-
- Share: -
-
- -
-
-
- - { this.state.showDetails && -
-
-
-
- Claim Name: -
- {name} -
-
-
-
- Claim Id: -
- {claimId} -
-
-
-
- File Type: -
- {contentType ? `${contentType}` : 'unknown'} -
-
-
-
-
- Report -
-
-
- } -
- -
-
- ); - } +const mapStateToProps = ({ show }) => { + return { + shortId : show.showAsset.shortId, + channelName : show.showAsset.claimData.channelName, + certificateId: show.showAsset.claimData.certificateId, + description : show.showAsset.claimData.description, + name : show.showAsset.claimData.name, + claimId : show.showAsset.claimData.claimId, + fileExt : show.showAsset.claimData.fileExt, + contentType : show.showAsset.claimData.contentType, + thumbnail : show.showAsset.claimData.thumbnail, + host : show.showAsset.claimData.host, + }; }; -AssetInfo.propTypes = { - channelName : PropTypes.string, - certificateId: PropTypes.string, - description : PropTypes.string, - shortId : PropTypes.string.isRequired, - name : PropTypes.string.isRequired, - claimId : PropTypes.string.isRequired, - contentType : PropTypes.string.isRequired, - fileExt : PropTypes.string.isRequired, - thumbnail : PropTypes.string, - host : PropTypes.string.isRequired, -}; - -export default AssetInfo; +export default connect(mapStateToProps, null)(View); diff --git a/react/components/AssetInfo/view.jsx b/react/components/AssetInfo/view.jsx new file mode 100644 index 00000000..9d53637d --- /dev/null +++ b/react/components/AssetInfo/view.jsx @@ -0,0 +1,165 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + +class AssetInfo extends React.Component { + constructor (props) { + super(props); + this.state = { + showDetails: false, + }; + this.toggleDetails = this.toggleDetails.bind(this); + this.copyToClipboard = this.copyToClipboard.bind(this); + } + toggleDetails () { + if (this.state.showDetails) { + return this.setState({showDetails: false}); + } + this.setState({showDetails: true}); + } + copyToClipboard (event) { + var elementToCopy = event.target.dataset.elementtocopy; + var element = document.getElementById(elementToCopy); + element.select(); + try { + document.execCommand('copy'); + } catch (err) { + this.setState({error: 'Oops, unable to copy'}); + } + } + render () { + const { shortId, channelName, certificateId, description, name, claimId, fileExt, contentType, thumbnail, host } = this.props; + return ( +
+ {channelName && +
+
+ Channel: +
+
+ {channelName} +
+
+ } + + {description && +
+ {description} +
+ } + +
+ +
+
+ Embed: +
+
+
+
+ + {(contentType === 'video/mp4') ? ( + `}/> + ) : ( + `} + /> + )} +
+
+
+ +
+
+
+
+
+ +
+
+
+ Share: +
+
+ +
+
+
+ + { this.state.showDetails && +
+
+
+
+ Claim Name: +
+ {name} +
+
+
+
+ Claim Id: +
+ {claimId} +
+
+
+
+ File Type: +
+ {contentType ? `${contentType}` : 'unknown'} +
+
+
+
+
+ Report +
+
+
+ } +
+ +
+
+ ); + } +}; + +export default AssetInfo; diff --git a/react/components/AssetTitle/index.js b/react/components/AssetTitle/index.js index f943a940..970bbe6f 100644 --- a/react/components/AssetTitle/index.js +++ b/react/components/AssetTitle/index.js @@ -1,11 +1,10 @@ -import React from 'react'; +import { connect } from 'react-redux'; +import View from './view'; -const AssetTitle = ({title}) => { - return ( -
- {title} -
- ); +const mapStateToProps = ({ show }) => { + return { + title: show.showAsset.claimData.title, + }; }; -export default AssetTitle; +export default connect(mapStateToProps, null)(View); diff --git a/react/components/AssetTitle/view.jsx b/react/components/AssetTitle/view.jsx new file mode 100644 index 00000000..f943a940 --- /dev/null +++ b/react/components/AssetTitle/view.jsx @@ -0,0 +1,11 @@ +import React from 'react'; + +const AssetTitle = ({title}) => { + return ( +
+ {title} +
+ ); +}; + +export default AssetTitle; diff --git a/react/components/ShowAssetDetails/index.js b/react/components/ShowAssetDetails/index.js index 0348c443..9d3f8eb8 100644 --- a/react/components/ShowAssetDetails/index.js +++ b/react/components/ShowAssetDetails/index.js @@ -1,57 +1,10 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import NavBar from 'containers/NavBar'; -import AssetTitle from 'components/AssetTitle'; -import AssetDisplay from 'containers/AssetDisplay'; -import AssetInfo from 'components/AssetInfo'; +import { connect } from 'react-redux'; +import View from './view'; -class ShowAssetDetails extends React.Component { - render () { - const { error, claimData: { title, channelName, certificateId, description, name, claimId, fileExt, contentType, thumbnail, host }, shortId } = this.props; - return ( -
- - {error && -
-

{error}

-
- } - {this.props.claimData && -
-
- -
-
-
- -
-
-
- -
-
-
- } -
- ); - } +const mapStateToProps = ({ show }) => { + return { + claimData: show.showAsset.claimData, + }; }; -ShowAssetDetails.propTypes = { - error : PropTypes.string, - claimData: PropTypes.object.isRequired, - shortId : PropTypes.string.isRequired, -}; - -export default ShowAssetDetails; +export default connect(mapStateToProps, null)(View); diff --git a/react/components/ShowAssetDetails/view.jsx b/react/components/ShowAssetDetails/view.jsx new file mode 100644 index 00000000..c1bf7e6a --- /dev/null +++ b/react/components/ShowAssetDetails/view.jsx @@ -0,0 +1,39 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import NavBar from 'containers/NavBar'; +import AssetTitle from 'components/AssetTitle'; +import AssetDisplay from 'components/AssetDisplay'; +import AssetInfo from 'components/AssetInfo'; + +class ShowAssetDetails extends React.Component { + render () { + const { claimData } = this.props; + return ( +
+ + {claimData && +
+
+ +
+
+
+ +
+
+
+ +
+
+
+ } +
+ ); + } +}; + +ShowAssetDetails.propTypes = { + error: PropTypes.string, +}; + +export default ShowAssetDetails; diff --git a/react/components/ShowAssetLite/index.js b/react/components/ShowAssetLite/index.js index 024d7184..b47c7407 100644 --- a/react/components/ShowAssetLite/index.js +++ b/react/components/ShowAssetLite/index.js @@ -1,30 +1,11 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Link } from 'react-router-dom'; -import AssetDisplay from 'containers/AssetDisplay'; +import { connect } from 'react-redux'; +import View from './view'; -class ShowLite extends React.Component { - render () { - const { error, claimData: { name, claimId } } = this.props; - return ( -
- {error && -

{error}

- } - {this.props.claimData && -
- - hosted via Spee.ch -
- } -
- ); - } +const mapStateToProps = ({ show }) => { + return { + name : show.showAsset.claimData.name, + claimId: show.showAsset.claimData.claimId, + }; }; -ShowLite.propTypes = { - error : PropTypes.string, - claimData: PropTypes.object.isRequired, -}; - -export default ShowLite; +export default connect(mapStateToProps, null)(View); diff --git a/react/components/ShowAssetLite/view.jsx b/react/components/ShowAssetLite/view.jsx new file mode 100644 index 00000000..74dc1beb --- /dev/null +++ b/react/components/ShowAssetLite/view.jsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import AssetDisplay from 'components/AssetDisplay'; + +class ShowLite extends React.Component { + render () { + const { name, claimId } = this.props; + return ( +
+ { (name && claimId) && +
+ + hosted via Spee.ch +
+ } +
+ ); + } +}; + +export default ShowLite; diff --git a/react/constants/show_action_types.js b/react/constants/show_action_types.js index 7ade6448..b9078f96 100644 --- a/react/constants/show_action_types.js +++ b/react/constants/show_action_types.js @@ -1,8 +1,10 @@ -export const REQUEST_UPDATE_CHANNEL = 'REQUEST_UPDATE_CHANNEL'; -export const REQUEST_UPDATE_CLAIM = 'REQUEST_UPDATE_CLAIM'; +export const REQUEST_CHANNEL_UPDATE = 'REQUEST_CHANNEL_UPDATE'; +export const REQUEST_CLAIM_UPDATE = 'REQUEST_CLAIM_UPDATE'; +export const REQUEST_ERROR_UPDATE = 'REQUEST_ERROR_UPDATE'; export const CHANNEL_DATA_UPDATE = 'CHANNEL_DATA_UPDATE'; export const CHANNEL_CLAIMS_DATA_UPDATE = 'CHANNEL_CLAIMS_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 FILE_AVAILABILITY_UPDATE = 'FILE_AVAILABILITY_UPDATE'; export const SHOW_ASSET_ERROR = 'SHOW_ASSET_ERROR'; +export const DISPLAY_ASSET_ERROR = 'DISPLAY_ASSET_ERROR'; diff --git a/react/containers/ChannelClaimsDisplay/view.jsx b/react/containers/ChannelClaimsDisplay/view.jsx index 7740b6db..571bbd15 100644 --- a/react/containers/ChannelClaimsDisplay/view.jsx +++ b/react/containers/ChannelClaimsDisplay/view.jsx @@ -1,5 +1,5 @@ -import React from 'react/index'; -import AssetPreview from 'components/AssetPreview/index'; +import React from 'react'; +import AssetPreview from 'components/AssetPreview'; import request from 'utils/request'; class ChannelClaimsDisplay extends React.Component { diff --git a/react/containers/ShowAsset/index.js b/react/containers/ShowAsset/index.js index eacf3794..c8949a6b 100644 --- a/react/containers/ShowAsset/index.js +++ b/react/containers/ShowAsset/index.js @@ -1,24 +1,29 @@ import { connect } from 'react-redux'; import View from './view'; -import { updateAssetClaimData } from 'actions/show'; +import { updateAssetClaimData, updateShowAssetError } from 'actions/show'; const mapStateToProps = ({ show }) => { return { modifier : show.assetRequest.modifier, - claim : show.assetRequest.name, + name : show.assetRequest.name, extension: show.assetRequest.extension, + error : show.showAsset.error, claimData: show.showAsset.claimData, - shortId : show.showAsset.shortId, }; }; const mapDispatchToProps = dispatch => { return { + onShowAssetError: (error) => { + dispatch(updateShowAssetError(error)); + }, onAssetClaimDataUpdate: (claimData, shortId) => { dispatch(updateAssetClaimData(claimData, shortId)); + dispatch(updateShowAssetError(null)); // clear any errors }, onAssetClaimDataClear: () => { dispatch(updateAssetClaimData(null, null)); + dispatch(updateShowAssetError(null)); // clear any errors }, }; }; diff --git a/react/containers/ShowAsset/view.jsx b/react/containers/ShowAsset/view.jsx index 3926200d..ff52c6bd 100644 --- a/react/containers/ShowAsset/view.jsx +++ b/react/containers/ShowAsset/view.jsx @@ -6,17 +6,11 @@ import request from 'utils/request'; class ShowAsset extends React.Component { constructor (props) { super(props); - this.state = { - error: null, - }; this.getLongClaimId = this.getLongClaimId.bind(this); this.getClaimData = this.getClaimData.bind(this); } componentDidMount () { - console.log('ShowAsset did mount'); - console.log('ShowAsset props', this.props); - const modifier = this.props.modifier; - const name = this.props.claim; + const { name, modifier } = this.props; // create request params let body = {}; if (modifier) { @@ -41,11 +35,10 @@ class ShowAsset extends React.Component { return Promise.all([this.getShortClaimId(claimLongId, name), this.getClaimData(claimLongId, name)]); }) .then(([shortId, claimData]) => { - this.setState({error: null}); // note: move this to redux level this.props.onAssetClaimDataUpdate(claimData, shortId); }) .catch(error => { - this.setState({error}); + this.props.onShowAssetError(error); }); } getLongClaimId (params) { @@ -101,26 +94,25 @@ class ShowAsset extends React.Component { this.props.onAssetClaimDataClear(); } render () { - if (this.props.claimData) { - if (this.props.extension) { + const { error, claimData, extension } = this.props; + if (error) { + return ( +

{error}

+ ); + } + if (claimData) { + if (extension) { return ( - + ); } else { return ( - + ); } }; return ( -
+
); } }; diff --git a/react/containers/ShowPage/index.js b/react/containers/ShowPage/index.js index c27ab8e3..857bc56c 100644 --- a/react/containers/ShowPage/index.js +++ b/react/containers/ShowPage/index.js @@ -4,7 +4,7 @@ import View from './view'; const mapStateToProps = ({ show }) => { return { - requestType: show.requestType, + requestType: show.request.type, }; }; diff --git a/react/reducers/show.js b/react/reducers/show.js index d47cf666..dc5dd915 100644 --- a/react/reducers/show.js +++ b/react/reducers/show.js @@ -3,7 +3,10 @@ import { CHANNEL, ASSET } from 'constants/show_request_types'; import { LOCAL_CHECK, ERROR } from 'constants/asset_display_states'; const initialState = { - requestType : null, + request: { + error: null, + type : null, + }, channelRequest: { name: null, id : null, @@ -34,10 +37,13 @@ const initialState = { }, showAsset: { error : null, - status : LOCAL_CHECK, claimData: null, shortId : null, }, + displayAsset: { + error : null, + status: LOCAL_CHECK, + }, }; /* @@ -46,16 +52,26 @@ Reducers describe how the application's state changes in response to actions export default function (state = initialState, action) { switch (action.type) { - case actions.REQUEST_UPDATE_CHANNEL: + case actions.REQUEST_CHANNEL_UPDATE: return Object.assign({}, state, { - requestType : CHANNEL, + request: Object.assign({}, state.request, { + type: CHANNEL, + }), channelRequest: action.data, }); - case actions.REQUEST_UPDATE_CLAIM: + case actions.REQUEST_CLAIM_UPDATE: return Object.assign({}, state, { - requestType : ASSET, + request: Object.assign({}, state.request, { + type: ASSET, + }), assetRequest: action.data, }); + case actions.REQUEST_ERROR_UPDATE: + return Object.assign({}, state, { + request: Object.assign({}, state.request, { + error: action.data, + }), + }); case actions.CHANNEL_DATA_UPDATE: return Object.assign({}, state, { showChannel: Object.assign({}, state.showChannel, { @@ -75,15 +91,21 @@ export default function (state = initialState, action) { 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, + }), + }); + case actions.FILE_AVAILABILITY_UPDATE: + return Object.assign({}, state, { + displayAsset: Object.assign({}, state.displayAsset, { + status: action.data, + }), + }); + case actions.DISPLAY_ASSET_ERROR: + return Object.assign({}, state, { + displayAsset: Object.assign({}, state.displayAsset, { error : action.data, status: ERROR, }), diff --git a/react/sagas/show.js b/react/sagas/show.js index 1a591b67..d5798ff6 100644 --- a/react/sagas/show.js +++ b/react/sagas/show.js @@ -1,6 +1,6 @@ import { call, put, takeLatest } from 'redux-saga/effects'; import * as actions from 'constants/show_action_types'; -import { updateFileIsAvailable, updateShowAssetError } from 'actions/show'; +import { updateFileAvailability, updateDisplayAssetError } from 'actions/show'; import { UNAVAILABLE, AVAILABLE } from 'constants/asset_display_states'; import { checkFileAvailability, triggerClaimGet } from 'api/fileApi'; @@ -12,27 +12,27 @@ function* retriveFile (action) { try { ({ success, message, data: isAvailable } = yield call(checkFileAvailability, name, claimId)); } catch (error) { - return yield put(updateShowAssetError(error.message)); + return yield put(updateDisplayAssetError(error.message)); }; if (success) { if (isAvailable) { - return yield put(updateFileIsAvailable(AVAILABLE)); + return yield put(updateFileAvailability(AVAILABLE)); } - yield put(updateFileIsAvailable(UNAVAILABLE)); + yield put(updateFileAvailability(UNAVAILABLE)); } else { - yield put(updateShowAssetError(message)); + yield put(updateDisplayAssetError(message)); } // initiate get request for the file try { ({ success, message } = yield call(triggerClaimGet, name, claimId)); } catch (error) { - return yield put(updateShowAssetError(error.message)); + return yield put(updateDisplayAssetError(error.message)); }; if (success) { console.log('/api/glaim-get response:', message); - yield put(updateFileIsAvailable(AVAILABLE)); + yield put(updateFileAvailability(AVAILABLE)); } else { - yield put(updateShowAssetError(message)); + yield put(updateDisplayAssetError(message)); } } diff --git a/routes/api-routes.js b/routes/api-routes.js index bd596014..47610188 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -207,7 +207,7 @@ module.exports = (app) => { res.status(200).json({success: false, message: error.message}); }); }); - app.post('/api/claim/long-id', ({ ip, originalUrl, body, params }, res) => { + app.get('/api/claim/long-id', ({ ip, originalUrl, body, params }, res) => { logger.debug('body:', body); const channelName = body.channelName; const channelClaimId = body.channelClaimId;