Redux #115

Merged
6ea86b96 merged 57 commits from redux into redux 2017-05-05 22:55:12 +02:00
19 changed files with 450 additions and 336 deletions
Showing only changes of commit b0f32aebc7 - Show all commits

View file

@ -9,9 +9,13 @@ import {
} from 'selectors/wallet'
import {
selectSearchTerm,
selectCurrentUriCostInfo,
selectCurrentUriFileInfo,
} from 'selectors/content'
import {
selectCurrentUriFileInfo,
} from 'selectors/file_info'
import {
selectCurrentUriCostInfo,
} from 'selectors/cost_info'
import {
selectCurrentResolvedUriClaimOutpoint,
} from 'selectors/content'
@ -45,32 +49,6 @@ export function doResolveUri(uri) {
}
}
export function doFetchCurrentUriFileInfo() {
return function(dispatch, getState) {
const state = getState()
const uri = selectCurrentUri(state)
const outpoint = selectCurrentResolvedUriClaimOutpoint(state)
dispatch({
type: types.FETCH_FILE_INFO_STARTED,
data: {
uri,
outpoint,
}
})
lbry.file_list({ outpoint: outpoint, full_status: true }).then(([fileInfo]) => {
dispatch({
type: types.FETCH_FILE_INFO_COMPLETED,
data: {
uri,
fileInfo,
}
})
})
}
}
export function doFetchDownloadedContent() {
return function(dispatch, getState) {
const state = getState()
@ -147,30 +125,6 @@ export function doFetchFeaturedContent() {
}
}
export function doFetchCurrentUriCostInfo() {
return function(dispatch, getState) {
const state = getState()
const uri = selectCurrentUri(state)
dispatch({
type: types.FETCH_COST_INFO_STARTED,
data: {
uri,
}
})
lbry.getCostInfo(uri).then(costInfo => {
dispatch({
type: types.FETCH_COST_INFO_COMPLETED,
data: {
uri,
costInfo,
}
})
})
}
}
export function doUpdateLoadStatus(uri, outpoint) {
return function(dispatch, getState) {
const state = getState()
@ -277,13 +231,12 @@ export function doWatchVideo() {
const costInfo = selectCurrentUriCostInfo(state)
const { cost } = costInfo
// NOTE: we have to check written bytes because a file may be "completed"
// but then deleted on the file system. In which case we are going to need
// to dispatch a load event again to redownload it
if (fileInfo.completed && fileInfo.written_bytes > 0) {
// we already fully downloaded the file
if (fileInfo && fileInfo.completed) {
return Promise.resolve()
}
// the file is free or we have partially downloaded it
if (cost <= 0.01 || fileInfo.download_directory) {
dispatch(doLoadVideo())
return Promise.resolve()

View file

@ -0,0 +1,30 @@
import * as types from 'constants/action_types'
import {
selectCurrentUri,
} from 'selectors/app'
import lbry from 'lbry'
export function doFetchCurrentUriCostInfo() {
return function(dispatch, getState) {
const state = getState()
const uri = selectCurrentUri(state)
dispatch({
type: types.FETCH_COST_INFO_STARTED,
data: {
uri,
}
})
lbry.getCostInfo(uri).then(costInfo => {
dispatch({
type: types.FETCH_COST_INFO_COMPLETED,
data: {
uri,
costInfo,
}
})
})
}
}

View file

@ -0,0 +1,34 @@
import * as types from 'constants/action_types'
import lbry from 'lbry'
import {
selectCurrentUri,
} from 'selectors/app'
import {
selectCurrentUriClaimOutpoint,
} from 'selectors/claims'
export function doFetchCurrentUriFileInfo() {
return function(dispatch, getState) {
const state = getState()
const uri = selectCurrentUri(state)
const outpoint = selectCurrentUriClaimOutpoint(state)
dispatch({
type: types.FETCH_FILE_INFO_STARTED,
data: {
uri,
outpoint,
}
})
lbry.file_list({ outpoint: outpoint, full_status: true }).then(([fileInfo]) => {
dispatch({
type: types.FETCH_FILE_INFO_COMPLETED,
data: {
uri,
fileInfo,
}
})
})
}
}

View file

@ -3,12 +3,12 @@ import {
connect
} from 'react-redux'
import {
selectResolvedUris,
} from 'selectors/content'
selectClaimsByUri,
} from 'selectors/claims'
import FileTile from './view'
const select = (state) => ({
resolvedUris: (uri) => selectResolvedUris(state)[uri],
claims: (uri) => selectClaimsByUri(state)[uri],
})
const perform = (dispatch) => ({

View file

@ -10,13 +10,11 @@ class FileTile extends React.Component {
render() {
const {
displayStyle,
uri,
claim,
uri
} = this.props
const resolvedUri = this.props.resolvedUris(uri) || {}
const claimInfo = resolvedUri.claim
if(!claim) {
const claimInfo = this.props.claims(uri)
if(!claimInfo) {
if (displayStyle == 'card') {
return <FileCardStream uri={uri} />
}

View file

@ -16,8 +16,14 @@ import {
selectLoadingCurrentUri,
selectCurrentUriFileReadyToPlay,
selectCurrentUriIsPlaying,
selectDownloadingCurrentUri,
} from 'selectors/content'
import {
selectCurrentUriFileInfo,
selectDownloadingCurrentUri,
} from 'selectors/file_info'
import {
selectCurrentUriCostInfo,
} from 'selectors/cost_info'
import Video from './view'
const select = (state) => ({

View file

@ -11,7 +11,6 @@ const communityCategoryToolTipText = ('Community Content is a public space where
const FeaturedCategory = (props) => {
const {
category,
resolvedUris,
names,
} = props
@ -19,7 +18,7 @@ const FeaturedCategory = (props) => {
<h3 className="card-row__header">{category}
{category && category.match(/^community/i) && <ToolTip label="What's this?" body={communityCategoryToolTipText} className="tooltip--header" />}
</h3>
{names.map(name => <FileTile key={name} displayStyle="card" uri={name} />)}
{names && names.map(name => <FileTile key={name} displayStyle="card" uri={name} />)}
</div>
}

View file

@ -6,15 +6,21 @@ import {
selectCurrentUri,
} from 'selectors/app'
import {
selectCurrentResolvedUriClaim,
selectCurrentUriIsDownloaded,
} from 'selectors/file_info'
import {
selectCurrentUriClaim,
} from 'selectors/claims'
import {
selectCurrentUriFileInfo,
} from 'selectors/file_info'
import {
selectCurrentUriCostInfo,
} from 'selectors/content'
} from 'selectors/cost_info'
import ShowPage from './view'
const select = (state) => ({
claim: selectCurrentResolvedUriClaim(state),
claim: selectCurrentUriClaim(state),
uri: selectCurrentUri(state),
isDownloaded: selectCurrentUriIsDownloaded(state),
fileInfo: selectCurrentUriFileInfo(state),

View file

@ -0,0 +1,27 @@
import * as types from 'constants/action_types'
const reducers = {}
const defaultState = {
}
reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
const {
uri,
certificate,
} = action.data
if (!certificate) return state
const newByUri = Object.assign({}, state.byUri)
newByUri[uri] = certificate
return Object.assign({}, state, {
byUri: newByUri,
})
}
export default function reducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

24
ui/js/reducers/claims.js Normal file
View file

@ -0,0 +1,24 @@
import * as types from 'constants/action_types'
const reducers = {}
const defaultState = {
}
reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
const {
uri,
claim,
} = action.data
const newByUri = Object.assign({}, state.byUri)
newByUri[uri] = claim
return Object.assign({}, state, {
byUri: newByUri,
})
}
export default function reducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

View file

@ -41,10 +41,7 @@ reducers[types.RESOLVE_URI_STARTED] = function(state, action) {
reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
const {
uri,
claim,
certificate,
} = action.data
const resolvedUris = Object.assign({}, state.resolvedUris)
const resolvingUris = state.resolvingUris
const index = state.resolvingUris.indexOf(uri)
const newResolvingUris = [
@ -52,14 +49,7 @@ reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
...resolvingUris.slice(index + 1)
]
resolvedUris[uri] = {
claim: claim,
certificate: certificate,
}
const newState = Object.assign({}, state, {
resolvedUris: resolvedUris,
resolvingUris: newResolvingUris,
})
@ -106,78 +96,6 @@ reducers[types.FETCH_PUBLISHED_CONTENT_COMPLETED] = function(state, action) {
})
}
reducers[types.FETCH_FILE_INFO_STARTED] = function(state, action) {
const {
uri,
output,
} = action.data
const newFetchingFileInfos = Object.assign({}, state.fetchingFileInfos)
newFetchingFileInfos[uri] = true
return Object.assign({}, state, {
fetchingFileInfos: newFetchingFileInfos,
})
}
reducers[types.FETCH_FILE_INFO_COMPLETED] = function(state, action) {
const {
uri,
fileInfo,
} = action.data
const newFetchingFileInfos = Object.assign({}, state.fetchingFileInfos)
const fileInfos = Object.assign({}, state.fileInfos)
const byUri = Object.assign({}, fileInfos.byUri)
byUri[uri] = Object.assign({}, fileInfo)
delete newFetchingFileInfos[uri]
const newFileInfos = Object.assign({}, fileInfos, {
byUri: byUri,
})
return Object.assign({}, state, {
fetchingFileInfos: newFetchingFileInfos,
fileInfos: newFileInfos,
})
}
reducers[types.FETCH_COST_INFO_STARTED] = function(state, action) {
const {
uri,
} = action.data
const fetchingCostInfos = Object.assign({}, state.fetchingCostInfos)
fetchingCostInfos[uri] = true
return Object.assign({}, state, {
fetchingCostInfos,
})
}
reducers[types.FETCH_COST_INFO_COMPLETED] = function(state, action) {
const {
uri,
costInfo,
} = action.data
const newFetchingCostInfos = Object.assign({}, state.fetchingCostInfos)
const costInfos = Object.assign({}, state.costInfos)
const byUri = Object.assign({}, costInfos.byUri)
byUri[uri] = costInfo
delete newFetchingCostInfos[uri]
const newCostInfos = Object.assign({}, costInfos, {
byUri: byUri,
})
return Object.assign({}, state, {
fetchingCostInfos: newFetchingCostInfos,
costInfos: newCostInfos,
})
}
reducers[types.LOADING_VIDEO_STARTED] = function(state, action) {
const {
uri,
@ -208,60 +126,6 @@ reducers[types.LOADING_VIDEO_FAILED] = function(state, action) {
})
}
reducers[types.DOWNLOADING_STARTED] = function(state, action) {
const {
uri,
fileInfo,
} = action.data
const newDownloading = Object.assign({}, state.downloading)
const newByUri = Object.assign({}, newDownloading.byUri)
const newLoading = Object.assign({}, state.loading)
const newLoadingByUri = Object.assign({}, newLoading.byUri)
const newFileInfos = Object.assign({}, state.fileInfos)
const newFileInfosByUri = Object.assign({}, newFileInfos.byUri)
newByUri[uri] = true
newDownloading.byUri = newByUri
delete newLoadingByUri[uri]
newLoading.byUri = newLoadingByUri
newFileInfosByUri[uri] = fileInfo
newFileInfos.byUri = newFileInfosByUri
return Object.assign({}, state, {
downloading: newDownloading,
loading: newLoading,
fileInfos: newFileInfos,
})
}
reducers[types.DOWNLOADING_COMPLETED] =
reducers[types.DOWNLOADING_PROGRESSED] = function(state, action) {
const {
uri,
fileInfo,
} = action.data
const fileInfos = Object.assign({}, state.fileInfos)
const byUri = Object.assign({}, fileInfos.byUri)
byUri[uri] = fileInfo
fileInfos.byUri = byUri
return Object.assign({}, state, {
fileInfos: fileInfos,
})
}
reducers[types.PLAY_VIDEO_STARTED] = function(state, action) {
const {
uri,
} = action.data
return Object.assign({}, state, {
nowPlaying: uri,
})
}
export default function reducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);

View file

@ -0,0 +1,40 @@
import * as types from 'constants/action_types'
const reducers = {}
const defaultState = {
}
reducers[types.FETCH_COST_INFO_STARTED] = function(state, action) {
const {
uri,
} = action.data
const newFetching = Object.assign({}, state.fetching)
newFetching[uri] = true
return Object.assign({}, state, {
fetching: newFetching,
})
}
reducers[types.FETCH_COST_INFO_COMPLETED] = function(state, action) {
const {
uri,
costInfo,
} = action.data
const newByUri = Object.assign({}, state.byUri)
const newFetching = Object.assign({}, state.fetching)
newByUri[uri] = costInfo
delete newFetching[uri]
return Object.assign({}, state, {
byUri: newByUri,
fetching: newFetching,
})
}
export default function reducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

View file

@ -0,0 +1,92 @@
import * as types from 'constants/action_types'
const reducers = {}
const defaultState = {
}
reducers[types.FETCH_FILE_INFO_STARTED] = function(state, action) {
const {
uri,
} = action.data
const newFetching = Object.assign({}, state.fetching)
newFetching[uri] = true
return Object.assign({}, state, {
fetching: newFetching,
})
}
reducers[types.FETCH_FILE_INFO_COMPLETED] = function(state, action) {
const {
uri,
fileInfo,
} = action.data
const newByUri = Object.assign({}, state.byUri)
const newFetching = Object.assign({}, state.fetching)
newByUri[uri] = fileInfo || {}
delete newFetching[uri]
return Object.assign({}, state, {
byUri: newByUri,
fetching: newFetching,
})
}
reducers[types.DOWNLOADING_STARTED] = function(state, action) {
const {
uri,
fileInfo,
} = action.data
const newByUri = Object.assign({}, state.byUri)
const newDownloading = Object.assign({}, state.downloading)
newDownloading[uri] = true
newByUri[uri] = fileInfo
return Object.assign({}, state, {
downloading: newDownloading,
byUri: newByUri,
})
}
reducers[types.DOWNLOADING_PROGRESSED] = function(state, action) {
const {
uri,
fileInfo,
} = action.data
const newByUri = Object.assign({}, state.byUri)
const newDownloading = Object.assign({}, state.downloading)
newByUri[uri] = fileInfo
newDownloading[uri] = true
return Object.assign({}, state, {
byUri: newByUri,
downloading: newDownloading
})
}
reducers[types.DOWNLOADING_COMPLETED] = function(state, action) {
const {
uri,
fileInfo,
} = action.data
const newByUri = Object.assign({}, state.byUri)
const newDownloading = Object.assign({}, state.downloading)
newByUri[uri] = fileInfo
delete newDownloading[uri]
return Object.assign({}, state, {
byUri: newByUri,
downloading: newDownloading
})
}
export default function reducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

24
ui/js/selectors/claims.js Normal file
View file

@ -0,0 +1,24 @@
import {
createSelector,
} from 'reselect'
import {
selectCurrentUri,
} from 'selectors/app'
export const _selectState = state => state.claims || {}
export const selectClaimsByUri = createSelector(
_selectState,
(state) => state.byUri || {}
)
export const selectCurrentUriClaim = createSelector(
selectCurrentUri,
selectClaimsByUri,
(uri, byUri) => byUri[uri] || {}
)
export const selectCurrentUriClaimOutpoint = createSelector(
selectCurrentUriClaim,
(claim) => `${claim.txid}:${claim.nout}`
)

View file

@ -4,6 +4,14 @@ import {
selectCurrentPage,
selectCurrentUri,
} from 'selectors/app'
import {
selectCurrentUriCostInfo,
selectFetchingCurrentUriCostInfo,
} from 'selectors/cost_info'
import {
selectCurrentUriFileInfo,
selectFetchingCurrentUriFileInfo,
} from 'selectors/file_info'
export const _selectState = state => state.content || {}
@ -37,48 +45,6 @@ export const shouldFetchFeaturedContent = createSelector(
}
)
export const selectResolvedUris = createSelector(
_selectState,
(state) => state.resolvedUris || {}
)
export const selectCurrentResolvedUri = createSelector(
selectCurrentUri,
selectResolvedUris,
(uri, resolvedUris) => resolvedUris[uri] || {}
)
export const selectCurrentResolvedUriClaim = createSelector(
selectCurrentResolvedUri,
(uri) => uri.claim || {}
)
export const selectCurrentResolvedUriClaimOutpoint = createSelector(
selectCurrentResolvedUriClaim,
(claim) => `${claim.txid}:${claim.nout}`
)
export const selectFileInfos = createSelector(
_selectState,
(state) => state.fileInfos || {}
)
export const selectFileInfosByUri = createSelector(
selectFileInfos,
(fileInfos) => fileInfos.byUri || {}
)
export const selectCurrentUriFileInfo = createSelector(
selectCurrentUri,
selectFileInfosByUri,
(uri, byUri) => byUri[uri]
)
export const selectCurrentUriIsDownloaded = createSelector(
selectCurrentUriFileInfo,
(fileInfo) => fileInfo && fileInfo.length > 0
)
export const selectFetchingFileInfos = createSelector(
_selectState,
(state) => state.fetchingFileInfos || {}
@ -91,73 +57,6 @@ export const selectCurrentUriFileReadyToPlay = createSelector(
(fileInfo) => (fileInfo || {}).written_bytes > 0
)
export const selectIsFetchingCurrentUriFileInfo = createSelector(
selectFetchingFileInfos,
selectCurrentUri,
(fetching, uri) => !!fetching[uri]
)
export const selectCurrentUriIsPlaying = createSelector(
_selectState,
selectCurrentUri,
(state, uri) => state.nowPlaying == uri
)
export const selectCostInfos = createSelector(
_selectState,
(state) => state.costInfos || {}
)
export const selectCostInfosByUri = createSelector(
selectCostInfos,
(costInfos) => costInfos.byUri || {}
)
export const selectFetchingCostInfos = createSelector(
_selectState,
(state) => state.fetchingCostInfos || {}
)
export const selectIsFetchingCurrentUriCostInfo = createSelector(
selectFetchingCostInfos,
selectCurrentUri,
(fetching, uri) => !!fetching[uri]
)
export const selectCurrentUriCostInfo = createSelector(
selectCurrentUri,
selectCostInfosByUri,
(uri, byUri) => byUri[uri] || {}
)
export const shouldFetchCurrentUriCostInfo = createSelector(
selectCurrentPage,
selectCurrentUri,
selectIsFetchingCurrentUriCostInfo,
selectCurrentUriCostInfo,
(page, uri, fetching, costInfo) => {
if (page != 'show') return false
if (fetching) return false
if (Object.keys(costInfo).length != 0) return false
return true
}
)
export const shouldFetchCurrentUriFileInfo = createSelector(
selectCurrentPage,
selectCurrentUri,
selectIsFetchingCurrentUriFileInfo,
selectCurrentUriFileInfo,
(page, uri, fetching, fileInfo) => {
if (page != 'show') return false
if (fetching) return false
if (fileInfo != undefined) return false
return true
}
)
export const selectFetchingDownloadedContent = createSelector(
_selectState,
(state) => !!state.fetchingDownloadedContent
@ -214,22 +113,6 @@ export const selectLoadingCurrentUri = createSelector(
(byUri, uri) => !!byUri[uri]
)
export const selectDownloading = createSelector(
_selectState,
(state) => state.downloading || {}
)
export const selectDownloadingByUri = createSelector(
selectDownloading,
(downloading) => downloading.byUri || {}
)
export const selectDownloadingCurrentUri = createSelector(
selectCurrentUri,
selectDownloadingByUri,
(uri, byUri) => byUri[uri]
)
export const shouldFetchPublishedContent = createSelector(
selectDaemonReady,
selectCurrentPage,

View file

@ -0,0 +1,44 @@
import { createSelector } from 'reselect'
import {
selectCurrentUri,
selectCurrentPage,
} from 'selectors/app'
export const _selectState = state => state.costInfo || {}
export const selectAllCostInfoByUri = createSelector(
_selectState,
(state) => state.byUri || {}
)
export const selectCurrentUriCostInfo = createSelector(
selectCurrentUri,
selectAllCostInfoByUri,
(uri, byUri) => byUri[uri] || {}
)
export const selectFetchingCostInfo = createSelector(
_selectState,
(state) => state.fetching || {}
)
export const selectFetchingCurrentUriCostInfo = createSelector(
selectCurrentUri,
selectFetchingCostInfo,
(uri, byUri) => !!byUri[uri]
)
export const shouldFetchCurrentUriCostInfo = createSelector(
selectCurrentPage,
selectCurrentUri,
selectFetchingCurrentUriCostInfo,
selectCurrentUriCostInfo,
(page, uri, fetching, costInfo) => {
if (page != 'show') return false
if (fetching) return false
if (Object.keys(costInfo).length != 0) return false
return true
}
)

View file

@ -0,0 +1,74 @@
import {
createSelector,
} from 'reselect'
import {
selectCurrentUri,
selectCurrentPage,
} from 'selectors/app'
export const _selectState = state => state.fileInfo || {}
export const selectAllFileInfoByUri = createSelector(
_selectState,
(state) => state.byUri || {}
)
export const selectCurrentUriRawFileInfo = createSelector(
selectCurrentUri,
selectAllFileInfoByUri,
(uri, byUri) => byUri[uri]
)
export const selectCurrentUriFileInfo = createSelector(
selectCurrentUriRawFileInfo,
(fileInfo) => fileInfo
)
export const selectFetchingFileInfo = createSelector(
_selectState,
(state) => state.fetching || {}
)
export const selectFetchingCurrentUriFileInfo = createSelector(
selectCurrentUri,
selectFetchingFileInfo,
(uri, byUri) => !!byUri[uri]
)
export const selectDownloading = createSelector(
_selectState,
(state) => state.downloading || {}
)
export const selectDownloadingByUri = createSelector(
selectDownloading,
(downloading) => downloading.byUri || {}
)
export const selectDownloadingCurrentUri = createSelector(
selectCurrentUri,
selectDownloadingByUri,
(uri, byUri) => !!byUri[uri]
)
export const selectCurrentUriIsDownloaded = createSelector(
selectCurrentUriFileInfo,
(fileInfo) => {
return fileInfo && (fileInfo.written_bytes > 0 || fileInfo.completed)
}
)
export const shouldFetchCurrentUriFileInfo = createSelector(
selectCurrentPage,
selectCurrentUri,
selectFetchingCurrentUriFileInfo,
selectCurrentUriFileInfo,
(page, uri, fetching, fileInfo) => {
if (page != 'show') return false
if (fetching) return false
if (fileInfo != undefined) return false
return true
}
)

View file

@ -6,7 +6,11 @@ import {
createLogger
} from 'redux-logger'
import appReducer from 'reducers/app';
import certificatesReducer from 'reducers/certificates'
import claimsReducer from 'reducers/claims'
import contentReducer from 'reducers/content';
import costInfoReducer from 'reducers/cost_info'
import fileInfoReducer from 'reducers/file_info'
import rewardsReducer from 'reducers/rewards'
import searchReducer from 'reducers/search'
import walletReducer from 'reducers/wallet'
@ -43,7 +47,11 @@ function enableBatching(reducer) {
const reducers = redux.combineReducers({
app: appReducer,
certificates: certificatesReducer,
claims: claimsReducer,
fileInfo: fileInfoReducer,
content: contentReducer,
costInfo: costInfoReducer,
rewards: rewardsReducer,
search: searchReducer,
wallet: walletReducer,

View file

@ -6,9 +6,13 @@ import {
shouldFetchFeaturedContent,
shouldFetchDownloadedContent,
shouldFetchPublishedContent,
shouldFetchCurrentUriFileInfo,
shouldFetchCurrentUriCostInfo,
} from 'selectors/content'
import {
shouldFetchCurrentUriFileInfo,
} from 'selectors/file_info'
import {
shouldFetchCurrentUriCostInfo,
} from 'selectors/cost_info'
import {
doFetchTransactions,
doGetNewAddress,
@ -17,9 +21,13 @@ import {
doFetchFeaturedContent,
doFetchDownloadedContent,
doFetchPublishedContent,
doFetchCurrentUriFileInfo,
doFetchCurrentUriCostInfo,
} from 'actions/content'
import {
doFetchCurrentUriFileInfo,
} from 'actions/file_info'
import {
doFetchCurrentUriCostInfo,
} from 'actions/cost_info'
const triggers = []