Redux #115
18 changed files with 473 additions and 44 deletions
|
@ -1,6 +1,12 @@
|
||||||
import * as types from 'constants/action_types'
|
import * as types from 'constants/action_types'
|
||||||
import lbry from 'lbry'
|
import lbry from 'lbry'
|
||||||
import lbryio from 'lbryio';
|
import lbryio from 'lbryio';
|
||||||
|
import {
|
||||||
|
selectCurrentUri,
|
||||||
|
} from 'selectors/app'
|
||||||
|
import {
|
||||||
|
selectCurrentResolvedUriClaimOutpoint,
|
||||||
|
} from 'selectors/content'
|
||||||
|
|
||||||
export function doResolveUri(dispatch, uri) {
|
export function doResolveUri(dispatch, uri) {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -25,6 +31,34 @@ export function doResolveUri(dispatch, uri) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doFetchCurrentUriFileInfo() {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
const state = getState()
|
||||||
|
const uri = selectCurrentUri(state)
|
||||||
|
const outpoint = selectCurrentResolvedUriClaimOutpoint(state)
|
||||||
|
|
||||||
|
console.log(outpoint)
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.FETCH_FILE_INFO_STARTED,
|
||||||
|
data: {
|
||||||
|
uri,
|
||||||
|
outpoint,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
lbry.file_list({ outpoint }).then(fileInfo => {
|
||||||
|
dispatch({
|
||||||
|
type: types.FETCH_FILE_INFO_COMPLETED,
|
||||||
|
data: {
|
||||||
|
uri,
|
||||||
|
fileInfo,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function doFetchDownloadedContent() {
|
export function doFetchDownloadedContent() {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
const state = getState()
|
const state = getState()
|
||||||
|
@ -100,3 +134,27 @@ export function doFetchFeaturedContent() {
|
||||||
.then(success, failure)
|
.then(success, failure)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
36
ui/js/actions/rewards.js
Normal file
36
ui/js/actions/rewards.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import * as types from 'constants/action_types'
|
||||||
|
import lbry from 'lbry'
|
||||||
|
import lbryio from 'lbryio';
|
||||||
|
import rewards from 'rewards'
|
||||||
|
|
||||||
|
export function doFetchRewards() {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
const state = getState()
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.FETCH_REWARDS_STARTED,
|
||||||
|
})
|
||||||
|
|
||||||
|
lbryio.call('reward', 'list', {}).then(function(userRewards) {
|
||||||
|
dispatch({
|
||||||
|
type: types.FETCH_REWARDS_COMPLETED,
|
||||||
|
data: { userRewards }
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doClaimReward(rewardType) {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
try {
|
||||||
|
rewards.claimReward(rewards[rewardType])
|
||||||
|
dispatch({
|
||||||
|
type: types.REWARD_CLAIMED,
|
||||||
|
data: {
|
||||||
|
reward: rewards[rewardType]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch(err) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,16 @@ import React from 'react'
|
||||||
import {
|
import {
|
||||||
connect
|
connect
|
||||||
} from 'react-redux'
|
} from 'react-redux'
|
||||||
|
import {
|
||||||
|
doNavigate,
|
||||||
|
} from 'actions/app'
|
||||||
import FileCardStream from './view'
|
import FileCardStream from './view'
|
||||||
|
|
||||||
export default connect()(FileCardStream)
|
const select = (state) => ({
|
||||||
|
})
|
||||||
|
|
||||||
|
const perform = (dispatch) => ({
|
||||||
|
navigate: (path) => dispatch(doNavigate(path)),
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(select, perform)(FileCardStream)
|
||||||
|
|
|
@ -71,11 +71,11 @@ const FileCardStream = React.createClass({
|
||||||
const isConfirmed = !!metadata;
|
const isConfirmed = !!metadata;
|
||||||
const title = isConfirmed ? metadata.title : uri;
|
const title = isConfirmed ? metadata.title : uri;
|
||||||
const obscureNsfw = this.props.obscureNsfw && isConfirmed && metadata.nsfw;
|
const obscureNsfw = this.props.obscureNsfw && isConfirmed && metadata.nsfw;
|
||||||
const primaryUrl = '?show=' + uri;
|
const primaryUrl = 'show=' + uri;
|
||||||
return (
|
return (
|
||||||
<section className={ 'card card--small card--link ' + (obscureNsfw ? 'card--obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
|
<section className={ 'card card--small card--link ' + (obscureNsfw ? 'card--obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
|
||||||
<div className="card__inner">
|
<div className="card__inner">
|
||||||
<a href={primaryUrl} className="card__link">
|
<a href="#" onClick={() => this.props.navigate(primaryUrl)} className="card__link">
|
||||||
<div className="card__title-identity">
|
<div className="card__title-identity">
|
||||||
<h5 title={title}><TruncatedText lines={1}>{title}</TruncatedText></h5>
|
<h5 title={title}><TruncatedText lines={1}>{title}</TruncatedText></h5>
|
||||||
<div className="card__subtitle">
|
<div className="card__subtitle">
|
||||||
|
|
|
@ -4,7 +4,7 @@ import HelpPage from 'page/help';
|
||||||
import ReportPage from 'page/report.js';
|
import ReportPage from 'page/report.js';
|
||||||
import StartPage from 'page/start.js';
|
import StartPage from 'page/start.js';
|
||||||
import WalletPage from 'page/wallet';
|
import WalletPage from 'page/wallet';
|
||||||
import DetailPage from 'page/show.js';
|
import ShowPage from 'page/showPage';
|
||||||
import PublishPage from 'page/publish.js';
|
import PublishPage from 'page/publish.js';
|
||||||
import DiscoverPage from 'page/discover';
|
import DiscoverPage from 'page/discover';
|
||||||
import SplashScreen from 'component/splash.js';
|
import SplashScreen from 'component/splash.js';
|
||||||
|
@ -35,7 +35,7 @@ const Router = (props) => {
|
||||||
'wallet': <WalletPage {...props} />,
|
'wallet': <WalletPage {...props} />,
|
||||||
'send': <WalletPage {...props} />,
|
'send': <WalletPage {...props} />,
|
||||||
'receive': <WalletPage {...props} />,
|
'receive': <WalletPage {...props} />,
|
||||||
'show': <DetailPage {...props} />,
|
'show': <ShowPage {...props} />,
|
||||||
'publish': <PublishPage {...props} />,
|
'publish': <PublishPage {...props} />,
|
||||||
'developer': <DeveloperPage {...props} />,
|
'developer': <DeveloperPage {...props} />,
|
||||||
'discover': <DiscoverPage {...props} />,
|
'discover': <DiscoverPage {...props} />,
|
||||||
|
|
|
@ -43,3 +43,7 @@ export const FETCH_DOWNLOADED_CONTENT_STARTED = 'FETCH_DOWNLOADED_CONTENT_STARTE
|
||||||
export const FETCH_DOWNLOADED_CONTENT_COMPLETED = 'FETCH_DOWNLOADED_CONTENT_COMPLETED'
|
export const FETCH_DOWNLOADED_CONTENT_COMPLETED = 'FETCH_DOWNLOADED_CONTENT_COMPLETED'
|
||||||
export const FETCH_PUBLISHED_CONTENT_STARTED = 'FETCH_PUBLISHED_CONTENT_STARTED'
|
export const FETCH_PUBLISHED_CONTENT_STARTED = 'FETCH_PUBLISHED_CONTENT_STARTED'
|
||||||
export const FETCH_PUBLISHED_CONTENT_COMPLETED = 'FETCH_PUBLISHED_CONTENT_COMPLETED'
|
export const FETCH_PUBLISHED_CONTENT_COMPLETED = 'FETCH_PUBLISHED_CONTENT_COMPLETED'
|
||||||
|
export const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'
|
||||||
|
export const FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'
|
||||||
|
export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'
|
||||||
|
export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED'
|
||||||
|
|
|
@ -14,7 +14,7 @@ const FeaturedCategory = (props) => {
|
||||||
resolvedUris,
|
resolvedUris,
|
||||||
names,
|
names,
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
return <div className="card-row card-row--small">
|
return <div className="card-row card-row--small">
|
||||||
<h3 className="card-row__header">{category}
|
<h3 className="card-row__header">{category}
|
||||||
{category && category.match(/^community/i) && <ToolTip label="What's this?" body={communityCategoryToolTipText} className="tooltip--header" />}
|
{category && category.match(/^community/i) && <ToolTip label="What's this?" body={communityCategoryToolTipText} className="tooltip--header" />}
|
||||||
|
|
27
ui/js/page/showPage/index.js
Normal file
27
ui/js/page/showPage/index.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {
|
||||||
|
connect
|
||||||
|
} from 'react-redux'
|
||||||
|
import {
|
||||||
|
selectCurrentUri,
|
||||||
|
} from 'selectors/app'
|
||||||
|
import {
|
||||||
|
selectCurrentResolvedUriClaim,
|
||||||
|
selectCurrentUriIsDownloaded,
|
||||||
|
selectCurrentUriFileInfo,
|
||||||
|
selectCurrentUriCostInfo,
|
||||||
|
} from 'selectors/content'
|
||||||
|
import ShowPage from './view'
|
||||||
|
|
||||||
|
const select = (state) => ({
|
||||||
|
claim: selectCurrentResolvedUriClaim(state),
|
||||||
|
uri: selectCurrentUri(state),
|
||||||
|
isDownloaded: selectCurrentUriIsDownloaded(state),
|
||||||
|
fileInfo: selectCurrentUriFileInfo(state),
|
||||||
|
costInfo: selectCurrentUriCostInfo(state),
|
||||||
|
})
|
||||||
|
|
||||||
|
const perform = (dispatch) => ({
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(select, perform)(ShowPage)
|
|
@ -1,12 +1,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import lbry from '../lbry.js';
|
import lbry from 'lbry.js';
|
||||||
import lighthouse from '../lighthouse.js';
|
import lighthouse from 'lighthouse.js';
|
||||||
import lbryuri from '../lbryuri.js';
|
import lbryuri from 'lbryuri.js';
|
||||||
import Video from 'component/video'
|
import {Video} from 'page/watch.js'
|
||||||
import {TruncatedText, Thumbnail, FilePrice, BusyMessage} from '../component/common.js';
|
import {
|
||||||
import {FileActions} from '../component/file-actions.js';
|
TruncatedText,
|
||||||
import UriIndicator from '../component/channel-indicator.js';
|
Thumbnail,
|
||||||
|
FilePrice,
|
||||||
|
BusyMessage
|
||||||
|
} from 'component/common.js';
|
||||||
|
import {FileActions} from 'component/file-actions.js';
|
||||||
import Link from 'component/link';
|
import Link from 'component/link';
|
||||||
|
import UriIndicator from 'component/channel-indicator.js';
|
||||||
|
|
||||||
var FormatItem = React.createClass({
|
var FormatItem = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -16,11 +21,8 @@ var FormatItem = React.createClass({
|
||||||
outpoint: React.PropTypes.string,
|
outpoint: React.PropTypes.string,
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
const {author, language, license} = this.props.metadata;
|
const {thumbnail, author, title, description, language, license} = this.props.metadata;
|
||||||
|
const mediaType = lbry.getMediaType(this.props.contentType);
|
||||||
if (!this.props.contentType && [author, language, license].filter((val) => {return !!val; }).length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<table className="table-standard">
|
<table className="table-standard">
|
||||||
|
@ -243,21 +245,21 @@ let ShowPage = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const metadata = this.state.metadata,
|
const metadata = this.state.metadata,
|
||||||
title = metadata ? this.state.metadata.title : this._uri;
|
title = metadata ? this.state.metadata.title : this._uri;
|
||||||
|
|
||||||
let innerContent = "";
|
let innerContent = "";
|
||||||
|
|
||||||
if (!this.state.uriLookupComplete || this.state.isFailed) {
|
if (!this.state.uriLookupComplete || this.state.isFailed) {
|
||||||
innerContent = <section className="card">
|
innerContent = <section className="card">
|
||||||
<div className="card__inner">
|
<div className="card__inner">
|
||||||
<div className="card__title-identity"><h1>{title}</h1></div>
|
<div className="card__title-identity"><h1>{title}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
{ this.state.uriLookupComplete ?
|
{ this.state.uriLookupComplete ?
|
||||||
<p>This location is not yet in use. { ' ' }<Link href="?publish" label="Put something here" />.</p> :
|
<p>This location is not yet in use. { ' ' }<Link href="?publish" label="Put something here" />.</p> :
|
||||||
<BusyMessage message="Loading magic decentralized data..." />
|
<BusyMessage message="Loading magic decentralized data..." />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</section>;
|
</section>;
|
||||||
} else if (this.state.claimType == "channel") {
|
} else if (this.state.claimType == "channel") {
|
||||||
innerContent = <ChannelPage title={this._uri} />
|
innerContent = <ChannelPage title={this._uri} />
|
||||||
|
@ -282,3 +284,87 @@ let ShowPage = React.createClass({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ShowPage;
|
export default ShowPage;
|
||||||
|
|
||||||
|
//
|
||||||
|
// const ShowPage = (props) => {
|
||||||
|
// const {
|
||||||
|
// claim,
|
||||||
|
// uri,
|
||||||
|
// isDownloaded,
|
||||||
|
// fileInfo,
|
||||||
|
// costInfo,
|
||||||
|
// } = props
|
||||||
|
// const {
|
||||||
|
// txid,
|
||||||
|
// nout,
|
||||||
|
// has_signature,
|
||||||
|
// signature_is_valid,
|
||||||
|
// value,
|
||||||
|
// } = claim
|
||||||
|
// const {
|
||||||
|
// stream,
|
||||||
|
// } = value
|
||||||
|
// const {
|
||||||
|
// metadata,
|
||||||
|
// source,
|
||||||
|
// } = stream
|
||||||
|
// const {
|
||||||
|
// title,
|
||||||
|
// } = metadata
|
||||||
|
// const {
|
||||||
|
// contentType,
|
||||||
|
// } = source
|
||||||
|
// const {
|
||||||
|
// cost,
|
||||||
|
// includesData,
|
||||||
|
// } = costInfo
|
||||||
|
// const costIncludesData = includesData
|
||||||
|
//
|
||||||
|
// const outpoint = txid + ':' + nout;
|
||||||
|
// const uriLookupComplete = !!claim
|
||||||
|
// const hasSignature = has_signature
|
||||||
|
// const signatureIsValid = signature_is_valid
|
||||||
|
//
|
||||||
|
// return (
|
||||||
|
// <main className="main--single-column">
|
||||||
|
// <section className="show-page-media">
|
||||||
|
// { contentType && contentType.startsWith('video/') ?
|
||||||
|
// <Video className="video-embedded" uri={uri} metadata={metadata} outpoint={outpoint} /> :
|
||||||
|
// (metadata ? <Thumbnail src={metadata.thumbnail} /> : <Thumbnail />) }
|
||||||
|
// </section>
|
||||||
|
// <section className="card">
|
||||||
|
// <div className="card__inner">
|
||||||
|
// <div className="card__title-identity">
|
||||||
|
// {isDownloaded === false
|
||||||
|
// ? <span style={{float: "right"}}><FilePrice uri={uri} metadata={metadata} /></span>
|
||||||
|
// : null}
|
||||||
|
// <h1>{title}</h1>
|
||||||
|
// { uriLookupComplete ?
|
||||||
|
// <div>
|
||||||
|
// <div className="card__subtitle">
|
||||||
|
// <UriIndicator uri={uri} hasSignature={hasSignature} signatureIsValid={signatureIsValid} />
|
||||||
|
// </div>
|
||||||
|
// <div className="card__actions">
|
||||||
|
// <FileActions uri={uri} outpoint={outpoint} metadata={metadata} contentType={contentType} />
|
||||||
|
// </div>
|
||||||
|
// </div> : '' }
|
||||||
|
// </div>
|
||||||
|
// { uriLookupComplete ?
|
||||||
|
// <div>
|
||||||
|
// <div className="card__content card__subtext card__subtext card__subtext--allow-newlines">
|
||||||
|
// {metadata.description}
|
||||||
|
// </div>
|
||||||
|
// </div>
|
||||||
|
// : <div className="card__content"><BusyMessage message="Loading magic decentralized data..." /></div> }
|
||||||
|
// </div>
|
||||||
|
// { metadata ?
|
||||||
|
// <div className="card__content">
|
||||||
|
// <FormatItem metadata={metadata} contentType={contentType} cost={cost} uri={uri} outpoint={outpoint} costIncludesData={costIncludesData} />
|
||||||
|
// </div> : '' }
|
||||||
|
// <div className="card__content">
|
||||||
|
// <Link href="https://lbry.io/dmca" label="report" className="button-text-help" />
|
||||||
|
// </div>
|
||||||
|
// </section>
|
||||||
|
// </main>
|
||||||
|
// )
|
||||||
|
// }
|
|
@ -3,7 +3,7 @@ import * as types from 'constants/action_types'
|
||||||
const reducers = {}
|
const reducers = {}
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
isLoaded: false,
|
isLoaded: false,
|
||||||
currentPage: 'discover',
|
currentPath: 'discover',
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
drawerOpen: sessionStorage.getItem('drawerOpen') || true,
|
drawerOpen: sessionStorage.getItem('drawerOpen') || true,
|
||||||
upgradeSkipped: sessionStorage.getItem('upgradeSkipped'),
|
upgradeSkipped: sessionStorage.getItem('upgradeSkipped'),
|
||||||
|
@ -12,7 +12,7 @@ const defaultState = {
|
||||||
|
|
||||||
reducers[types.NAVIGATE] = function(state, action) {
|
reducers[types.NAVIGATE] = function(state, action) {
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
currentPage: action.data.path
|
currentPath: action.data.path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,78 @@ 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] = 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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export default function reducer(state = defaultState, action) {
|
export default function reducer(state = defaultState, action) {
|
||||||
const handler = reducers[action.type];
|
const handler = reducers[action.type];
|
||||||
if (handler) return handler(state, action);
|
if (handler) return handler(state, action);
|
||||||
|
|
11
ui/js/reducers/rewards.js
Normal file
11
ui/js/reducers/rewards.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import * as types from 'constants/action_types'
|
||||||
|
|
||||||
|
const reducers = {}
|
||||||
|
const defaultState = {
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function reducer(state = defaultState, action) {
|
||||||
|
const handler = reducers[action.type];
|
||||||
|
if (handler) return handler(state, action);
|
||||||
|
return state;
|
||||||
|
}
|
|
@ -4,23 +4,27 @@ export const _selectState = state => state.app || {}
|
||||||
|
|
||||||
export const selectIsLoaded = createSelector(
|
export const selectIsLoaded = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => {
|
(state) => state.isLoaded
|
||||||
return state.isLoaded
|
)
|
||||||
}
|
|
||||||
|
export const selectCurrentPath = createSelector(
|
||||||
|
_selectState,
|
||||||
|
(state) => state.currentPath
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectCurrentPage = createSelector(
|
export const selectCurrentPage = createSelector(
|
||||||
_selectState,
|
selectCurrentPath,
|
||||||
(state) => {
|
(path) => path.split('=')[0]
|
||||||
return state.currentPage
|
)
|
||||||
}
|
|
||||||
|
export const selectCurrentUri = createSelector(
|
||||||
|
selectCurrentPath,
|
||||||
|
(path) => path.split('://')[1]
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectPlatform = createSelector(
|
export const selectPlatform = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => {
|
(state) => state.platform
|
||||||
return state.platform
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectUpdateUrl = createSelector(
|
export const selectUpdateUrl = createSelector(
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { createSelector } from 'reselect'
|
||||||
import {
|
import {
|
||||||
selectDaemonReady,
|
selectDaemonReady,
|
||||||
selectCurrentPage,
|
selectCurrentPage,
|
||||||
|
selectCurrentUri,
|
||||||
} from 'selectors/app'
|
} from 'selectors/app'
|
||||||
|
|
||||||
export const _selectState = state => state.content || {}
|
export const _selectState = state => state.content || {}
|
||||||
|
@ -41,6 +42,109 @@ export const selectResolvedUris = createSelector(
|
||||||
(state) => state.resolvedUris || {}
|
(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 || {}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const selectIsFetchingCurrentUriFileInfo = createSelector(
|
||||||
|
selectFetchingFileInfos,
|
||||||
|
selectCurrentUri,
|
||||||
|
(fetching, uri) => !!fetching[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(
|
export const selectFetchingDownloadedContent = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => !!state.fetchingDownloadedContent
|
(state) => !!state.fetchingDownloadedContent
|
||||||
|
|
3
ui/js/selectors/rewards.js
Normal file
3
ui/js/selectors/rewards.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { createSelector } from 'reselect'
|
||||||
|
|
||||||
|
export const _selectState = state => state.rewards || {}
|
|
@ -95,7 +95,7 @@ export const shouldCheckAddressIsMine = createSelector(
|
||||||
|
|
||||||
export const selectDraftTransaction = createSelector(
|
export const selectDraftTransaction = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
(state) => state.draftTransaction || buildDraftTransaction()
|
(state) => state.draftTransaction || {}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const selectDraftTransactionAmount = createSelector(
|
export const selectDraftTransactionAmount = createSelector(
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
} from 'redux-logger'
|
} from 'redux-logger'
|
||||||
import appReducer from 'reducers/app';
|
import appReducer from 'reducers/app';
|
||||||
import contentReducer from 'reducers/content';
|
import contentReducer from 'reducers/content';
|
||||||
|
import rewardsReducer from 'reducers/rewards'
|
||||||
import walletReducer from 'reducers/wallet'
|
import walletReducer from 'reducers/wallet'
|
||||||
|
|
||||||
function isFunction(object) {
|
function isFunction(object) {
|
||||||
|
@ -20,6 +21,7 @@ function isNotFunction(object) {
|
||||||
const reducers = redux.combineReducers({
|
const reducers = redux.combineReducers({
|
||||||
app: appReducer,
|
app: appReducer,
|
||||||
content: contentReducer,
|
content: contentReducer,
|
||||||
|
rewards: rewardsReducer,
|
||||||
wallet: walletReducer,
|
wallet: walletReducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -32,10 +34,10 @@ if (env === 'development') {
|
||||||
middleware.push(logger)
|
middleware.push(logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
var createStoreWithMiddleware = redux.compose(
|
const createStoreWithMiddleware = redux.compose(
|
||||||
redux.applyMiddleware(...middleware)
|
redux.applyMiddleware(...middleware)
|
||||||
)(redux.createStore);
|
)(redux.createStore);
|
||||||
|
|
||||||
var reduxStore = createStoreWithMiddleware(reducers);
|
const reduxStore = createStoreWithMiddleware(reducers);
|
||||||
|
|
||||||
export default reduxStore;
|
export default reduxStore;
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {
|
||||||
shouldFetchFeaturedContent,
|
shouldFetchFeaturedContent,
|
||||||
shouldFetchDownloadedContent,
|
shouldFetchDownloadedContent,
|
||||||
shouldFetchPublishedContent,
|
shouldFetchPublishedContent,
|
||||||
|
shouldFetchCurrentUriFileInfo,
|
||||||
|
shouldFetchCurrentUriCostInfo,
|
||||||
} from 'selectors/content'
|
} from 'selectors/content'
|
||||||
import {
|
import {
|
||||||
doFetchTransactions,
|
doFetchTransactions,
|
||||||
|
@ -15,6 +17,8 @@ import {
|
||||||
doFetchFeaturedContent,
|
doFetchFeaturedContent,
|
||||||
doFetchDownloadedContent,
|
doFetchDownloadedContent,
|
||||||
doFetchPublishedContent,
|
doFetchPublishedContent,
|
||||||
|
doFetchCurrentUriFileInfo,
|
||||||
|
doFetchCurrentUriCostInfo,
|
||||||
} from 'actions/content'
|
} from 'actions/content'
|
||||||
|
|
||||||
const triggers = []
|
const triggers = []
|
||||||
|
@ -44,7 +48,15 @@ triggers.push({
|
||||||
action: doFetchPublishedContent,
|
action: doFetchPublishedContent,
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log(triggers)
|
triggers.push({
|
||||||
|
selector: shouldFetchCurrentUriFileInfo,
|
||||||
|
action: doFetchCurrentUriFileInfo,
|
||||||
|
})
|
||||||
|
|
||||||
|
triggers.push({
|
||||||
|
selector: shouldFetchCurrentUriCostInfo,
|
||||||
|
action: doFetchCurrentUriCostInfo,
|
||||||
|
})
|
||||||
|
|
||||||
const runTriggers = function() {
|
const runTriggers = function() {
|
||||||
triggers.forEach(function(trigger) {
|
triggers.forEach(function(trigger) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue