diff --git a/ui/js/actions/availability.js b/ui/js/actions/availability.js new file mode 100644 index 000000000..d5d14fa19 --- /dev/null +++ b/ui/js/actions/availability.js @@ -0,0 +1,21 @@ +import * as types from 'constants/action_types' +import lbry from 'lbry' + +export function doFetchUriAvailability(uri) { + return function(dispatch, getState) { + dispatch({ + type: types.FETCH_AVAILABILITY_STARTED, + data: { uri } + }) + + lbry.get_availability({ uri }, (availability) => { + dispatch({ + type: types.FETCH_AVAILABILITY_COMPLETED', + data: { + availability, + uri, + } + }) + } + } +} diff --git a/ui/js/actions/content.js b/ui/js/actions/content.js index c37ad032c..76f7d5af8 100644 --- a/ui/js/actions/content.js +++ b/ui/js/actions/content.js @@ -1,6 +1,7 @@ import * as types from 'constants/action_types' import lbry from 'lbry' import lbryio from 'lbryio' +import lbryuri from 'lbryuri' import { selectCurrentUri, } from 'selectors/app' @@ -113,7 +114,9 @@ export function doFetchFeaturedContent() { }) Object.keys(Uris).forEach((category) => { - Uris[category].forEach((uri) => dispatch(doResolveUri(uri))) + Uris[category].forEach((uri) => { + dispatch(doResolveUri(lbryuri.normalize(uri))) + }) }) } diff --git a/ui/js/actions/search.js b/ui/js/actions/search.js index a44ec964f..a4b1e83c4 100644 --- a/ui/js/actions/search.js +++ b/ui/js/actions/search.js @@ -32,7 +32,7 @@ export function doSearchContent(query) { contentName: result.name, claimId: result.channel_id || result.claim_id, }) - dispatch(doResolveUri(uri.split('://')[1])) + dispatch(doResolveUri(uri)) }) dispatch({ diff --git a/ui/js/component/fileActions/index.js b/ui/js/component/fileActions/index.js new file mode 100644 index 000000000..d17e57af8 --- /dev/null +++ b/ui/js/component/fileActions/index.js @@ -0,0 +1,21 @@ +import React from 'react' +import { + connect, +} from 'react-redux' +import { + selectObscureNsfw, + selectHidePrice, + selectHasSignature, +} from 'selectors/app' +import FileActions from './view' + +const select = (state) => ({ + obscureNsfw: selectObscureNsfw(state), + hidePrice: selectHidePrice(state), + hasSignature: selectHasSignature(state), +}) + +const perform = { +} + +export default connect(select, perform)(FileActions) diff --git a/ui/js/component/file-actions.js b/ui/js/component/fileActions/view.jsx similarity index 95% rename from ui/js/component/file-actions.js rename to ui/js/component/fileActions/view.jsx index 2829615cc..96267dbd8 100644 --- a/ui/js/component/file-actions.js +++ b/ui/js/component/fileActions/view.jsx @@ -1,16 +1,16 @@ import React from 'react'; -import lbry from '../lbry.js'; -import lbryuri from '../lbryuri.js'; +import lbry from 'lbry'; +import lbryuri from 'lbryuri'; +import {Icon, FilePrice} from 'component/common'; +import {Modal} from 'component/modal'; +import {FormField} from 'component/form'; import Link from 'component/link'; -import {Icon, FilePrice} from '../component/common.js'; -import Modal from './modal.js'; -import FormField from './form.js'; -import {ToolTip} from '../component/tooltip.js'; -import {DropDownMenu, DropDownMenuItem} from './menu.js'; +import {ToolTip} from 'component/tooltip'; +import {DropDownMenu, DropDownMenuItem} from 'component/menu'; const {shell} = require('electron'); -let FileActionsRow = React.createClass({ +const FileActionsRow = React.createClass({ _isMounted: false, _fileInfoSubscribeId: null, @@ -192,7 +192,7 @@ let FileActionsRow = React.createClass({ } }); -export let FileActions = React.createClass({ +const FileActions = React.createClass({ _isMounted: false, _fileInfoSubscribeId: null, @@ -268,3 +268,5 @@ export let FileActions = React.createClass({ ); } }); + +export default FileActions diff --git a/ui/js/component/fileCardStream/index.js b/ui/js/component/fileCardStream/index.js index 854ae624f..14e3dc7f9 100644 --- a/ui/js/component/fileCardStream/index.js +++ b/ui/js/component/fileCardStream/index.js @@ -5,13 +5,40 @@ import { import { doNavigate, } from 'actions/app' +import { + selectHidePrice, + selectObscureNsfw, +} from 'selectors/app' +import { + makeSelectClaimForUri, + makeSelectSourceForUri, + makeSelectMetadataForUri, +} from 'selectors/claims' +import { + makeSelectFileInfoForUri, +} from 'selectors/file_info' import FileCardStream from './view' -const select = (state) => ({ -}) +const makeSelect = () => { + const selectClaimForUri = makeSelectClaimForUri() + const selectFileInfoForUri = makeSelectFileInfoForUri() + const selectMetadataForUri = makeSelectMetadataForUri() + const selectSourceForUri = makeSelectSourceForUri() + const select = (state, props) => ({ + claim: selectClaimForUri(state, props), + fileInfo: selectFileInfoForUri(state, props), + hidePrice: selectHidePrice(state), + obscureNsfw: selectObscureNsfw(state), + hasSignature: false, + metadata: selectMetadataForUri(state, props), + source: selectSourceForUri(state, props), + }) + + return select +} const perform = (dispatch) => ({ navigate: (path) => dispatch(doNavigate(path)), }) -export default connect(select, perform)(FileCardStream) +export default connect(makeSelect, perform)(FileCardStream) diff --git a/ui/js/component/fileCardStream/view.jsx b/ui/js/component/fileCardStream/view.jsx index 74c01d863..d2bd9a1c3 100644 --- a/ui/js/component/fileCardStream/view.jsx +++ b/ui/js/component/fileCardStream/view.jsx @@ -2,70 +2,63 @@ import React from 'react'; import lbry from 'lbry.js'; import lbryuri from 'lbryuri.js'; import Link from 'component/link'; -import {FileActions} from 'component/file-actions.js'; -import {Thumbnail, TruncatedText, FilePrice} from 'component/common.js'; -import UriIndicator from 'component/channel-indicator.js'; +import {Thumbnail, TruncatedText, FilePrice} from 'component/common'; +import UriIndicator from 'component/channel-indicator'; -const FileCardStream = React.createClass({ - _fileInfoSubscribeId: null, - _isMounted: null, - _metadata: null, - - - propTypes: { - uri: React.PropTypes.string, - claimInfo: React.PropTypes.object, - outpoint: React.PropTypes.string, - hideOnRemove: React.PropTypes.bool, - hidePrice: React.PropTypes.bool, - obscureNsfw: React.PropTypes.bool - }, - getInitialState: function() { - return { +class FileCardStream extends React.Component { + constructor(props) { + super(props) + this._fileInfoSubscribeId = null + this._isMounted = null + this._metadata = null + this.state = { showNsfwHelp: false, isHidden: false, } - }, - getDefaultProps: function() { - return { - obscureNsfw: !lbry.getClientSetting('showNsfw'), - hidePrice: false, - hasSignature: false, - } - }, - componentDidMount: function() { + } + + componentDidMount() { this._isMounted = true; if (this.props.hideOnRemove) { this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.outpoint, this.onFileInfoUpdate); } - }, - componentWillUnmount: function() { + } + + componentWillUnmount() { if (this._fileInfoSubscribeId) { lbry.fileInfoUnsubscribe(this.props.outpoint, this._fileInfoSubscribeId); } - }, - onFileInfoUpdate: function(fileInfo) { + } + + onFileInfoUpdate(fileInfo) { if (!fileInfo && this._isMounted && this.props.hideOnRemove) { this.setState({ isHidden: true }); } - }, - handleMouseOver: function() { + } + + handleMouseOver() { this.setState({ hovered: true, }); - }, - handleMouseOut: function() { + } + + handleMouseOut() { this.setState({ hovered: false, }); - }, - render: function() { + } + + render() { if (this.state.isHidden) { return null; } + if (!this.props.metadata) { + return null + } + const uri = lbryuri.normalize(this.props.uri); const metadata = this.props.metadata; const isConfirmed = !!metadata; @@ -73,13 +66,13 @@ const FileCardStream = React.createClass({ const obscureNsfw = this.props.obscureNsfw && isConfirmed && metadata.nsfw; const primaryUrl = 'show=' + uri; return ( -
+
this.props.navigate(primaryUrl)} className="card__link">
{title}
- { !this.props.hidePrice ? : null} + { !this.props.hidePrice ? : null}
@@ -105,6 +98,6 @@ const FileCardStream = React.createClass({
); } -}); +} export default FileCardStream diff --git a/ui/js/component/fileList/view.jsx b/ui/js/component/fileList/view.jsx index 7d1cc9409..a119f8792 100644 --- a/ui/js/component/fileList/view.jsx +++ b/ui/js/component/fileList/view.jsx @@ -79,9 +79,7 @@ const FileList = React.createClass({ const uri = lbryuri.build({contentName: name, channelName: channel_name}); seenUris[name] = true; - content.push(); + content.push() } return ( diff --git a/ui/js/component/fileTile/index.js b/ui/js/component/fileTile/index.js index 07c696f81..5703e28cd 100644 --- a/ui/js/component/fileTile/index.js +++ b/ui/js/component/fileTile/index.js @@ -3,15 +3,25 @@ import { connect } from 'react-redux' import { - selectClaimsByUri, + makeSelectClaimForUri, } from 'selectors/claims' +import { + makeSelectFileInfoForUri, +} from 'selectors/file_info' import FileTile from './view' -const select = (state) => ({ - claims: (uri) => selectClaimsByUri(state)[uri], -}) +const makeSelect = () => { + const selectClaimForUri = makeSelectClaimForUri() + const selectFileInfoForUri = makeSelectFileInfoForUri() + const select = (state, props) => ({ + claim: selectClaimForUri(state, props), + fileInfo: selectFileInfoForUri(state, props), + }) + + return select +} const perform = (dispatch) => ({ }) -export default connect(select, perform)(FileTile) +export default connect(makeSelect, perform)(FileTile) diff --git a/ui/js/component/fileTile/view.jsx b/ui/js/component/fileTile/view.jsx index dfea32731..c85309995 100644 --- a/ui/js/component/fileTile/view.jsx +++ b/ui/js/component/fileTile/view.jsx @@ -10,11 +10,11 @@ class FileTile extends React.Component { render() { const { displayStyle, - uri + uri, + claim, } = this.props - const claimInfo = this.props.claims(uri) - if(!claimInfo) { + if(!claim) { if (displayStyle == 'card') { return } @@ -22,9 +22,9 @@ class FileTile extends React.Component { } return displayStyle == 'card' ? - + : - + } } diff --git a/ui/js/component/fileTileStream/index.js b/ui/js/component/fileTileStream/index.js index 03aaa299a..c297eec25 100644 --- a/ui/js/component/fileTileStream/index.js +++ b/ui/js/component/fileTileStream/index.js @@ -5,13 +5,46 @@ import { import { doNavigate, } from 'actions/app' +import { + makeSelectClaimForUri, + makeSelectSourceForUri, + makeSelectMetadataForUri, +} from 'selectors/claims' +import { + makeSelectFileInfoForUri, +} from 'selectors/file_info' +import { + makeSelectFetchingAvailabilityForUri, + makeSelectAvailabilityForUri, +} from 'selectors/availability' +import { + selectObscureNsfw, +} from 'selectors/app' import FileTileStream from './view' -const select = (state) => ({ -}) +const makeSelect = () => { + const selectClaimForUri = makeSelectClaimForUri() + const selectFileInfoForUri = makeSelectFileInfoForUri() + const selectFetchingAvailabilityForUri = makeSelectFetchingAvailabilityForUri() + const selectAvailabilityForUri = makeSelectAvailabilityForUri() + const selectMetadataForUri = makeSelectMetadataForUri() + const selectSourceForUri = makeSelectSourceForUri() + + const select = (state, props) => ({ + claim: selectClaimForUri(state, props), + fileInfo: selectFileInfoForUri(state, props), + fetchingAvailability: selectFetchingAvailabilityForUri(state, props), + selectAvailabilityForUri: selectAvailabilityForUri(state, props), + obscureNswf: selectObscureNsfw(state), + metadata: selectMetadataForUri(state, props), + source: selectSourceForUri(state, props), + }) + + return select +} const perform = (dispatch) => ({ navigate: (path) => dispatch(doNavigate(path)) }) -export default connect(select, perform)(FileTileStream) +export default connect(makeSelect, perform)(FileTileStream) diff --git a/ui/js/component/fileTileStream/view.jsx b/ui/js/component/fileTileStream/view.jsx index ec710b717..f5a0c218a 100644 --- a/ui/js/component/fileTileStream/view.jsx +++ b/ui/js/component/fileTileStream/view.jsx @@ -2,86 +2,76 @@ import React from 'react'; import lbry from 'lbry.js'; import lbryuri from 'lbryuri.js'; import Link from 'component/link'; -import { - FileActions -} from 'component/file-actions.js'; +import FileActions from 'component/fileActions'; import {Thumbnail, TruncatedText, FilePrice} from 'component/common.js'; import UriIndicator from 'component/channel-indicator.js'; /*should be merged into FileTile once FileTile is refactored to take a single id*/ -const FileTileStream = React.createClass({ - _fileInfoSubscribeId: null, - _isMounted: null, - - propTypes: { - uri: React.PropTypes.string, - metadata: React.PropTypes.object, - contentType: React.PropTypes.string.isRequired, - outpoint: React.PropTypes.string, - hasSignature: React.PropTypes.bool, - signatureIsValid: React.PropTypes.bool, - hideOnRemove: React.PropTypes.bool, - hidePrice: React.PropTypes.bool, - obscureNsfw: React.PropTypes.bool - }, - getInitialState: function() { - return { +class FileTileStream extends React.Component { + constructor(props) { + super(props) + this._fileInfoSubscribeId = null + this._isMounted = null + this.state = { showNsfwHelp: false, isHidden: false, } - }, - getDefaultProps: function() { - return { - obscureNsfw: !lbry.getClientSetting('showNsfw'), - hidePrice: false, - hasSignature: false, - } - }, - componentDidMount: function() { + } + + componentDidMount() { this._isMounted = true; if (this.props.hideOnRemove) { this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.outpoint, this.onFileInfoUpdate); } - }, - componentWillUnmount: function() { + } + + componentWillUnmount() { if (this._fileInfoSubscribeId) { lbry.fileInfoUnsubscribe(this.props.outpoint, this._fileInfoSubscribeId); } - }, - onFileInfoUpdate: function(fileInfo) { + } + + onFileInfoUpdate(fileInfo) { if (!fileInfo && this._isMounted && this.props.hideOnRemove) { this.setState({ isHidden: true }); } - }, - handleMouseOver: function() { + } + + handleMouseOver() { if (this.props.obscureNsfw && this.props.metadata && this.props.metadata.nsfw) { this.setState({ showNsfwHelp: true, }); } - }, - handleMouseOut: function() { + } + + handleMouseOut() { if (this.state.showNsfwHelp) { this.setState({ showNsfwHelp: false, }); } - }, - render: function() { + } + + render() { if (this.state.isHidden) { return null; } + const { + metadata, + navigate, + } = this.props + const uri = lbryuri.normalize(this.props.uri); - const metadata = this.props.metadata; const isConfirmed = !!metadata; const title = isConfirmed ? metadata.title : uri; const obscureNsfw = this.props.obscureNsfw && isConfirmed && metadata.nsfw; - const { navigate } = this.props + return ( -
+
navigate(`show=${uri}`)}> @@ -101,7 +91,6 @@ const FileTileStream = React.createClass({
-

@@ -125,6 +114,6 @@ const FileTileStream = React.createClass({

); } -}); +} export default FileTileStream diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index 568a85e70..cb5657d59 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -54,6 +54,8 @@ export const DOWNLOADING_STARTED = 'DOWNLOADING_STARTED' export const DOWNLOADING_PROGRESSED = 'DOWNLOADING_PROGRESSED' export const DOWNLOADING_COMPLETED = 'DOWNLOADING_COMPLETED' export const PLAY_VIDEO_STARTED = 'PLAY_VIDEO_STARTED' +export const FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED' +export const FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED' // Search export const SEARCH_STARTED = 'SEARCH_STARTED' diff --git a/ui/js/page/showPage/view.jsx b/ui/js/page/showPage/view.jsx index 8ff3b9ca9..9ba48cbf3 100644 --- a/ui/js/page/showPage/view.jsx +++ b/ui/js/page/showPage/view.jsx @@ -9,7 +9,7 @@ import { FilePrice, BusyMessage } from 'component/common.js'; -import {FileActions} from 'component/file-actions.js'; +import FileActions from 'component/fileActions'; import Link from 'component/link'; import UriIndicator from 'component/channel-indicator.js'; diff --git a/ui/js/reducers/app.js b/ui/js/reducers/app.js index 855330de3..4fa7442ba 100644 --- a/ui/js/reducers/app.js +++ b/ui/js/reducers/app.js @@ -1,4 +1,5 @@ import * as types from 'constants/action_types' +import lbry from 'lbry' const reducers = {} const defaultState = { @@ -9,6 +10,9 @@ const defaultState = { upgradeSkipped: sessionStorage.getItem('upgradeSkipped'), daemonReady: false, platform: window.navigator.platform, + obscureNsfw: !lbry.getClientSetting('showNsfw'), + hidePrice: false, + hasSignature: false, } reducers[types.NAVIGATE] = function(state, action) { diff --git a/ui/js/reducers/availability.js b/ui/js/reducers/availability.js new file mode 100644 index 000000000..6c0e28a8b --- /dev/null +++ b/ui/js/reducers/availability.js @@ -0,0 +1,45 @@ +import * as types from 'constants/action_types' + +const reducers = {} +const defaultState = { +} + +reducers[types.FETCH_AVAILABILITY_STARTED] = function(state, action) { + const { + uri, + } = action.data + const newFetching = Object.assign({}, state.fetching) + const newByUri = Object.assign({}, newFetching.byUri) + + newByUri[uri] = true + newFetching.byUri = newByUri + + return Object.assign({}, state, { + fetching: newFetching, + }) +} + +reducers[types.FETCH_AVAILABILITY_COMPLETED] = function(state, action) { + const { + uri, + availability, + } = action.data + const newFetching = Object.assign({}, state.fetching) + const newFetchingByUri = Object.assign({}, newFetching.byUri) + const newAvailabilityByUri = Object.assign({}, state.byUri) + + delete newFetchingByUri[uri] + newFetching.byUri = newFetchingByUri + newAvailabilityByUri[uri] = availability + + return Object.assign({}, state, { + fetching: newFetching, + byUri: newAvailabilityByUri + }) +} + +export default function reducer(state = defaultState, action) { + const handler = reducers[action.type]; + if (handler) return handler(state, action); + return state; +} diff --git a/ui/js/reducers/claims.js b/ui/js/reducers/claims.js index 30d6fa4e2..3fbf181d6 100644 --- a/ui/js/reducers/claims.js +++ b/ui/js/reducers/claims.js @@ -1,4 +1,5 @@ import * as types from 'constants/action_types' +import lbryuri from 'lbryuri' const reducers = {} const defaultState = { diff --git a/ui/js/reducers/search.js b/ui/js/reducers/search.js index 1fd73d10b..50a38966f 100644 --- a/ui/js/reducers/search.js +++ b/ui/js/reducers/search.js @@ -1,4 +1,5 @@ import * as types from 'constants/action_types' +import lbryuri from 'lbryuri' const reducers = {} const defaultState = { @@ -18,10 +19,11 @@ reducers[types.SEARCH_STARTED] = function(state, action) { reducers[types.SEARCH_COMPLETED] = function(state, action) { const { query, + results, } = action.data const oldResults = Object.assign({}, state.results) const newByQuery = Object.assign({}, oldResults.byQuery) - newByQuery[query] = action.data.results + newByQuery[query] = results const newResults = Object.assign({}, oldResults, { byQuery: newByQuery }) diff --git a/ui/js/selectors/app.js b/ui/js/selectors/app.js index 929967c87..7105bc16b 100644 --- a/ui/js/selectors/app.js +++ b/ui/js/selectors/app.js @@ -19,7 +19,13 @@ export const selectCurrentPage = createSelector( export const selectCurrentUri = createSelector( selectCurrentPath, - (path) => path.split('://')[1] + (path) => { + if (path.match(/=/)) { + return path.split('=')[1] + } else { + return undefined + } + } ) export const selectPlatform = createSelector( @@ -145,3 +151,18 @@ export const selectDaemonReady = createSelector( _selectState, (state) => state.daemonReady ) + +export const selectObscureNsfw = createSelector( + _selectState, + (state) => !!state.obscureNsfw +) + +export const selectHidePrice = createSelector( + _selectState, + (state) => !!state.hidePrice +) + +export const selectHasSignature = createSelector( + _selectState, + (state) => !!state.hasSignature +) diff --git a/ui/js/selectors/availability.js b/ui/js/selectors/availability.js new file mode 100644 index 000000000..0588c1528 --- /dev/null +++ b/ui/js/selectors/availability.js @@ -0,0 +1,42 @@ +import { + createSelector, +} from 'reselect' + +const _selectState = state => state.availability + +export const selectAvailabilityByUri = createSelector( + _selectState, + (state) => state.byUri || {} +) + +export const selectFetchingAvailability = createSelector( + _selectState, + (state) => state.fetching || {} +) + +export const selectFetchingAvailabilityByUri = createSelector( + selectFetchingAvailability, + (fetching) => fetching.byUri || {} +) + +const selectAvailabilityForUri = (state, props) => { + return selectAvailabilityByUri(state)[props.uri] +} + +export const makeSelectAvailabilityForUri = () => { + return createSelector( + selectAvailabilityForUri, + (availability) => availability + ) +} + +const selectFetchingAvailabilityForUri = (state, props) => { + return selectFetchingAvailabilityByUri(state)[props.uri] +} + +export const makeSelectFetchingAvailabilityForUri = () => { + return createSelector( + selectFetchingAvailabilityForUri, + (fetching) => fetching + ) +} diff --git a/ui/js/selectors/claims.js b/ui/js/selectors/claims.js index 1b43b4900..3b35ce92f 100644 --- a/ui/js/selectors/claims.js +++ b/ui/js/selectors/claims.js @@ -1,6 +1,7 @@ import { createSelector, } from 'reselect' +import lbryuri from 'lbryuri' import { selectCurrentUri, } from 'selectors/app' @@ -22,3 +23,43 @@ export const selectCurrentUriClaimOutpoint = createSelector( selectCurrentUriClaim, (claim) => `${claim.txid}:${claim.nout}` ) + +const selectClaimForUri = (state, props) => { + const uri = lbryuri.normalize(props.uri) + return selectClaimsByUri(state)[uri] +} + +export const makeSelectClaimForUri = () => { + return createSelector( + selectClaimForUri, + (claim) => claim + ) +} + +const selectMetadataForUri = (state, props) => { + const claim = selectClaimForUri(state, props) + const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata + + return metadata ? metadata : undefined +} + +export const makeSelectMetadataForUri = () => { + return createSelector( + selectMetadataForUri, + (metadata) => metadata + ) +} + +const selectSourceForUri = (state, props) => { + const claim = selectClaimForUri(state, props) + const source = claim && claim.value && claim.value.stream && claim.value.stream.source + + return source ? source : undefined +} + +export const makeSelectSourceForUri = () => { + return createSelector( + selectSourceForUri, + (source) => source + ) +} diff --git a/ui/js/selectors/file_info.js b/ui/js/selectors/file_info.js index 298be45f3..c26b5dcc8 100644 --- a/ui/js/selectors/file_info.js +++ b/ui/js/selectors/file_info.js @@ -72,3 +72,13 @@ export const shouldFetchCurrentUriFileInfo = createSelector( } ) +const selectFileInfoForUri = (state, props) => { + return selectAllFileInfoByUri(state)[props.uri] +} + +export const makeSelectFileInfoForUri = () => { + return createSelector( + selectFileInfoForUri, + (fileInfo) => fileInfo + ) +} diff --git a/ui/js/store.js b/ui/js/store.js index fce2c0ef3..462c6a5d0 100644 --- a/ui/js/store.js +++ b/ui/js/store.js @@ -6,6 +6,7 @@ import { createLogger } from 'redux-logger' import appReducer from 'reducers/app'; +import availabilityReducer from 'reducers/availability' import certificatesReducer from 'reducers/certificates' import claimsReducer from 'reducers/claims' import contentReducer from 'reducers/content'; @@ -47,6 +48,7 @@ function enableBatching(reducer) { const reducers = redux.combineReducers({ app: appReducer, + availability: availabilityReducer, certificates: certificatesReducer, claims: claimsReducer, fileInfo: fileInfoReducer,