Redux #115
31 changed files with 451 additions and 687 deletions
|
@ -6,6 +6,7 @@ import {
|
|||
selectUpgradeDownloadItem,
|
||||
selectUpgradeFilename,
|
||||
selectPageTitle,
|
||||
selectCurrentPath,
|
||||
} from 'selectors/app'
|
||||
|
||||
const {remote, ipcRenderer, shell} = require('electron');
|
||||
|
@ -16,6 +17,11 @@ const fs = remote.require('fs');
|
|||
|
||||
export function doNavigate(path) {
|
||||
return function(dispatch, getState) {
|
||||
const state = getState()
|
||||
const previousPath = selectCurrentPath(state)
|
||||
const previousTitle = selectPageTitle(state)
|
||||
history.pushState(state, previousTitle, previousPath);
|
||||
|
||||
dispatch({
|
||||
type: types.NAVIGATE,
|
||||
data: {
|
||||
|
@ -23,8 +29,8 @@ export function doNavigate(path) {
|
|||
}
|
||||
})
|
||||
|
||||
const state = getState()
|
||||
const pageTitle = selectPageTitle(state)
|
||||
|
||||
window.document.title = pageTitle
|
||||
}
|
||||
}
|
||||
|
@ -48,8 +54,12 @@ export function doCloseModal() {
|
|||
}
|
||||
|
||||
export function doHistoryBack() {
|
||||
return {
|
||||
type: types.HISTORY_BACK
|
||||
return function(dispatch, getState) {
|
||||
if (window.history.length > 1) {
|
||||
window.history.back();
|
||||
} else {
|
||||
dispatch(doNavigate('discover'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +162,7 @@ export function doCheckUpgradeAvailable() {
|
|||
dispatch({
|
||||
type: types.UPDATE_VERSION,
|
||||
data: {
|
||||
version: versionInfo.lbrynet_version
|
||||
version: remoteVersion,
|
||||
}
|
||||
})
|
||||
dispatch({
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react'
|
||||
import lbry from 'lbry'
|
||||
import {
|
||||
connect
|
||||
} from 'react-redux'
|
||||
|
|
|
@ -13,6 +13,7 @@ const Link = (props) => {
|
|||
button,
|
||||
hidden,
|
||||
disabled,
|
||||
children,
|
||||
} = props
|
||||
|
||||
const className = (props.className || '') +
|
||||
|
@ -22,8 +23,8 @@ const Link = (props) => {
|
|||
|
||||
|
||||
let content;
|
||||
if (props.children) {
|
||||
content = this.props.children
|
||||
if (children) {
|
||||
content = children
|
||||
} else {
|
||||
content = (
|
||||
<span {... 'button' in props ? {className: 'button__content'} : {}}>
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect,
|
||||
} from 'react-redux'
|
||||
import {
|
||||
selectCurrentPage,
|
||||
} from 'selectors/app'
|
||||
import {
|
||||
doNavigate,
|
||||
} from 'actions/app'
|
||||
import NavMain from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
currentPage: selectCurrentPage(state)
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
navigate: (path) => dispatch(doNavigate(path))
|
||||
})
|
||||
|
||||
export default connect(select, perform)(NavMain)
|
|
@ -1,22 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
export const NavMain = (props) => {
|
||||
const {
|
||||
links,
|
||||
currentPage,
|
||||
navigate,
|
||||
} = props
|
||||
|
||||
return (
|
||||
<nav className="sub-header">{
|
||||
Object.keys(links).map((link) => {
|
||||
console.log(link + " vs " + currentPage);
|
||||
return <a href="#" onClick={() => navigate(link)} key={link} className={link == currentPage ? 'sub-header-selected' : 'sub-header-unselected' }>
|
||||
{links[link]}
|
||||
</a>
|
||||
})
|
||||
}</nav>
|
||||
)
|
||||
}
|
||||
|
||||
export default NavMain
|
|
@ -1,7 +0,0 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect,
|
||||
} from 'react-redux'
|
||||
import NavSettings from './view'
|
||||
|
||||
export default connect(null, null)(NavSettings)
|
|
@ -1,11 +0,0 @@
|
|||
import React from 'react';
|
||||
import NavMain from 'component/navMain'
|
||||
|
||||
export const NavSettings = () => {
|
||||
return <NavMain links={{
|
||||
'settings': 'Settings',
|
||||
'help' : 'Help'
|
||||
}} />;
|
||||
}
|
||||
|
||||
export default NavSettings
|
|
@ -1,7 +0,0 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect,
|
||||
} from 'react-redux'
|
||||
import NavWallet from './view'
|
||||
|
||||
export default connect(null, null)(NavWallet)
|
|
@ -1,13 +0,0 @@
|
|||
import React from 'react';
|
||||
import NavMain from 'component/navMain'
|
||||
|
||||
export const NavWallet = () => {
|
||||
return <NavMain links={{
|
||||
'wallet': 'Overview',
|
||||
'send': 'Send',
|
||||
'receive': 'Receive',
|
||||
'rewards': 'Rewards'
|
||||
}} />
|
||||
}
|
||||
|
||||
export default NavWallet
|
|
@ -4,7 +4,7 @@ import HelpPage from 'page/help';
|
|||
import ReportPage from 'page/report.js';
|
||||
import StartPage from 'page/start.js';
|
||||
import WalletPage from 'page/wallet';
|
||||
import FilePage from 'page/filePage';
|
||||
import ShowPage from 'page/showPage'
|
||||
import PublishPage from 'page/publish';
|
||||
import DiscoverPage from 'page/discover';
|
||||
import SplashScreen from 'component/splash.js';
|
||||
|
@ -13,6 +13,7 @@ import RewardsPage from 'page/rewards.js';
|
|||
import FileListDownloaded from 'page/fileListDownloaded'
|
||||
import FileListPublished from 'page/fileListPublished'
|
||||
import ChannelPage from 'page/channel'
|
||||
import SearchPage from 'page/search'
|
||||
|
||||
const route = (page, routesMap) => {
|
||||
const component = routesMap[page]
|
||||
|
@ -36,12 +37,13 @@ const Router = (props) => {
|
|||
'wallet': <WalletPage {...props} />,
|
||||
'send': <WalletPage {...props} />,
|
||||
'receive': <WalletPage {...props} />,
|
||||
'show': <FilePage {...props} />,
|
||||
'show': <ShowPage {...props} />,
|
||||
'channel': <ChannelPage {...props} />,
|
||||
'publish': <PublishPage {...props} />,
|
||||
'developer': <DeveloperPage {...props} />,
|
||||
'discover': <DiscoverPage {...props} />,
|
||||
'rewards': <RewardsPage {...props} />,
|
||||
'search': <SearchPage {...props} />,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
23
ui/js/component/subHeader/index.js
Normal file
23
ui/js/component/subHeader/index.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect,
|
||||
} from 'react-redux'
|
||||
import {
|
||||
selectCurrentPage,
|
||||
selectHeaderLinks,
|
||||
} from 'selectors/app'
|
||||
import {
|
||||
doNavigate,
|
||||
} from 'actions/app'
|
||||
import SubHeader from './view'
|
||||
|
||||
const select = (state, props) => ({
|
||||
currentPage: selectCurrentPage(state),
|
||||
subLinks: selectHeaderLinks(state),
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
navigate: (path) => dispatch(doNavigate(path)),
|
||||
})
|
||||
|
||||
export default connect(select, perform)(SubHeader)
|
28
ui/js/component/subHeader/view.jsx
Normal file
28
ui/js/component/subHeader/view.jsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
import React from 'react'
|
||||
|
||||
const SubHeader = (props) => {
|
||||
const {
|
||||
subLinks,
|
||||
currentPage,
|
||||
navigate,
|
||||
modifier,
|
||||
} = props
|
||||
|
||||
const links = []
|
||||
|
||||
for(let link of Object.keys(subLinks)) {
|
||||
links.push(
|
||||
<a href="#" onClick={() => navigate(link)} key={link} className={link == currentPage ? 'sub-header-selected' : 'sub-header-unselected' }>
|
||||
{subLinks[link]}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<nav className={'sub-header' + (modifier ? ' sub-header--' + modifier : '')}>
|
||||
{links}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
export default SubHeader
|
|
@ -25,8 +25,8 @@ const perform = (dispatch) => ({
|
|||
// navigate: (path) => dispatch(doNavigate(path)),
|
||||
onSearch: (query) => dispatch(doSearchContent(query)),
|
||||
onSubmit: (query) => dispatch(doSearchContent(query)),
|
||||
// activateSearch: () => dispatch(doActivateSearch()),
|
||||
// deactivateSearch: () => setTimeout(() => { dispatch(doDeactivateSearch()) }, 50),
|
||||
activateSearch: () => dispatch(doActivateSearch()),
|
||||
deactivateSearch: () => setTimeout(() => { dispatch(doDeactivateSearch()) }, 50),
|
||||
})
|
||||
|
||||
export default connect(select, perform)(Wunderbar)
|
||||
|
|
|
@ -61,6 +61,8 @@ class WunderBar extends React.PureComponent {
|
|||
isActive: true
|
||||
}
|
||||
|
||||
this.props.activateSearch()
|
||||
|
||||
this._focusPending = true;
|
||||
//below is hacking, improved when we have proper routing
|
||||
if (!this.state.address.startsWith('lbry://') && this.state.icon !== "icon-search") //onFocus, if they are not on an exact URL or a search page, clear the bar
|
||||
|
@ -71,6 +73,7 @@ class WunderBar extends React.PureComponent {
|
|||
}
|
||||
|
||||
onBlur() {
|
||||
this.props.deactivateSearch()
|
||||
let commonState = {isActive: false};
|
||||
if (this._resetOnNextBlur) {
|
||||
this.setState(Object.assign({}, this._stateBeforeSearch, commonState));
|
||||
|
|
|
@ -8,6 +8,7 @@ import rewards from 'rewards.js';
|
|||
import lbryio from 'lbryio.js';
|
||||
import {BusyMessage, Thumbnail} from 'component/common.js';
|
||||
import FileList from 'component/fileList'
|
||||
import SubHeader from 'component/subHeader'
|
||||
|
||||
class FileListDownloaded extends React.Component {
|
||||
render() {
|
||||
|
@ -17,25 +18,21 @@ class FileListDownloaded extends React.Component {
|
|||
navigate,
|
||||
} = this.props
|
||||
|
||||
let content
|
||||
if (fetching) {
|
||||
return (
|
||||
<main className="page">
|
||||
<BusyMessage message="Loading" />
|
||||
</main>
|
||||
);
|
||||
content = <BusyMessage message="Loading" />
|
||||
} else if (!downloadedContent.length) {
|
||||
return (
|
||||
<main className="page">
|
||||
<span>You haven't downloaded anything from LBRY yet. Go <Link href="#" onClick={() => navigate('discover')} label="search for your first download" />!</span>
|
||||
</main>
|
||||
);
|
||||
content = <span>You haven't downloaded anything from LBRY yet. Go <Link href="#" onClick={() => navigate('discover')} label="search for your first download" />!</span>
|
||||
} else {
|
||||
return (
|
||||
<main className="page">
|
||||
<FileList fileInfos={downloadedContent} hidePrices={true} />
|
||||
</main>
|
||||
);
|
||||
content = <FileList fileInfos={downloadedContent} hidePrices={true} />
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="page">
|
||||
<SubHeader />
|
||||
{content}
|
||||
</main>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import rewards from 'rewards.js';
|
|||
import lbryio from 'lbryio.js';
|
||||
import {BusyMessage, Thumbnail} from 'component/common.js';
|
||||
import FileList from 'component/fileList'
|
||||
import SubHeader from 'component/subHeader'
|
||||
|
||||
class FileListPublished extends React.Component {
|
||||
componentDidUpdate() {
|
||||
|
@ -15,17 +16,20 @@ class FileListPublished extends React.Component {
|
|||
}
|
||||
|
||||
_requestPublishReward() {
|
||||
lbryio.call('reward', 'list', {}).then(function(userRewards) {
|
||||
//already rewarded
|
||||
if (userRewards.filter(function (reward) {
|
||||
return reward.RewardType == rewards.TYPE_FIRST_PUBLISH && reward.TransactionID
|
||||
}).length) {
|
||||
return
|
||||
}
|
||||
else {
|
||||
rewards.claimReward(rewards.TYPE_FIRST_PUBLISH).catch(() => {})
|
||||
}
|
||||
})
|
||||
// TODO this is throwing an error now
|
||||
// Error: LBRY internal API is disabled
|
||||
//
|
||||
// lbryio.call('reward', 'list', {}).then(function(userRewards) {
|
||||
// //already rewarded
|
||||
// if (userRewards.filter(function (reward) {
|
||||
// return reward.RewardType == rewards.TYPE_FIRST_PUBLISH && reward.TransactionID
|
||||
// }).length) {
|
||||
// return
|
||||
// }
|
||||
// else {
|
||||
// rewards.claimReward(rewards.TYPE_FIRST_PUBLISH).catch(() => {})
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -35,92 +39,22 @@ class FileListPublished extends React.Component {
|
|||
navigate,
|
||||
} = this.props
|
||||
|
||||
let content
|
||||
if (fetching) {
|
||||
return (
|
||||
<main className="page">
|
||||
<BusyMessage message="Loading" />
|
||||
</main>
|
||||
);
|
||||
content = <BusyMessage message="Loading" />
|
||||
} else if (!publishedContent.length) {
|
||||
return (
|
||||
<main className="page">
|
||||
<span>You haven't downloaded anything from LBRY yet. Go <Link href="#" onClick={() => navigate('discover')} label="search for your first download" />!</span>
|
||||
</main>
|
||||
);
|
||||
content = <span>You haven't downloaded anything from LBRY yet. Go <Link href="#" onClick={() => navigate('discover')} label="search for your first download" />!</span>
|
||||
} else {
|
||||
return (
|
||||
<main className="page">
|
||||
<FileList fileInfos={publishedContent} hidePrices={true} />
|
||||
</main>
|
||||
);
|
||||
content = <FileList fileInfos={publishedContent} hidePrices={true} />
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="page">
|
||||
<SubHeader />
|
||||
{content}
|
||||
</main>
|
||||
)
|
||||
}
|
||||
}
|
||||
// const FileListPublished = React.createClass({
|
||||
// _isMounted: false,
|
||||
|
||||
// getInitialState: function () {
|
||||
// return {
|
||||
// fileInfos: null,
|
||||
// };
|
||||
// },
|
||||
// _requestPublishReward: function() {
|
||||
// lbryio.call('reward', 'list', {}).then(function(userRewards) {
|
||||
// //already rewarded
|
||||
// if (userRewards.filter(function (reward) {
|
||||
// return reward.RewardType == rewards.TYPE_FIRST_PUBLISH && reward.TransactionID;
|
||||
// }).length) {
|
||||
// return;
|
||||
// }
|
||||
// else {
|
||||
// rewards.claimReward(rewards.TYPE_FIRST_PUBLISH).catch(() => {})
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
// componentDidMount: function () {
|
||||
// this._isMounted = true;
|
||||
// this._requestPublishReward();
|
||||
// document.title = "Published Files";
|
||||
|
||||
// lbry.claim_list_mine().then((claimInfos) => {
|
||||
// if (!this._isMounted) { return; }
|
||||
|
||||
// lbry.file_list().then((fileInfos) => {
|
||||
// if (!this._isMounted) { return; }
|
||||
|
||||
// const myClaimOutpoints = claimInfos.map(({txid, nout}) => txid + ':' + nout);
|
||||
// this.setState({
|
||||
// fileInfos: fileInfos.filter(({outpoint}) => myClaimOutpoints.includes(outpoint)),
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// },
|
||||
// componentWillUnmount: function() {
|
||||
// this._isMounted = false;
|
||||
// },
|
||||
// render: function () {
|
||||
// if (this.state.fileInfos === null) {
|
||||
// return (
|
||||
// <main className="page">
|
||||
// <BusyMessage message="Loading" />
|
||||
// </main>
|
||||
// );
|
||||
// }
|
||||
// else if (!this.state.fileInfos.length) {
|
||||
// return (
|
||||
// <main className="page">
|
||||
// <span>You haven't published anything to LBRY yet.</span> Try <Link href="?publish" label="publishing" />!
|
||||
// </main>
|
||||
// );
|
||||
// }
|
||||
// else {
|
||||
// return (
|
||||
// <main className="page">
|
||||
// <FileList fileInfos={this.state.fileInfos} />
|
||||
// </main>
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
export default FileListPublished
|
||||
|
|
|
@ -45,323 +45,85 @@ const FormatItem = (props) => {
|
|||
)
|
||||
}
|
||||
|
||||
let FilePage = React.createClass({
|
||||
_isMounted: false,
|
||||
const FilePage = (props) => {
|
||||
const {
|
||||
claim,
|
||||
navigate,
|
||||
claim: {
|
||||
txid,
|
||||
nout,
|
||||
has_signature: hasSignature,
|
||||
signature_is_valid: signatureIsValid,
|
||||
value,
|
||||
value: {
|
||||
stream,
|
||||
stream: {
|
||||
metadata,
|
||||
source,
|
||||
metadata: {
|
||||
title,
|
||||
} = {},
|
||||
source: {
|
||||
contentType,
|
||||
} = {},
|
||||
} = {},
|
||||
} = {},
|
||||
},
|
||||
uri,
|
||||
isDownloaded,
|
||||
fileInfo,
|
||||
costInfo,
|
||||
costInfo: {
|
||||
cost,
|
||||
includesData: costIncludesData,
|
||||
} = {},
|
||||
} = props
|
||||
|
||||
propTypes: {
|
||||
uri: React.PropTypes.string,
|
||||
},
|
||||
const outpoint = txid + ':' + nout;
|
||||
const uriLookupComplete = !!claim && Object.keys(claim).length
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
cost: null,
|
||||
costIncludesData: null,
|
||||
isDownloaded: null,
|
||||
};
|
||||
},
|
||||
const channelUriObj = lbryuri.parse(uri)
|
||||
delete channelUriObj.path;
|
||||
delete channelUriObj.contentName;
|
||||
const channelUri = signatureIsValid && hasSignature && channelUriObj.isChannel ? lbryuri.build(channelUriObj, false) : null;
|
||||
const uriIndicator = <UriIndicator uri={uri} />
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._isMounted = false;
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
if (nextProps.outpoint != this.props.outpoint || nextProps.uri != this.props.uri) {
|
||||
this.loadCostAndFileState(nextProps.uri, nextProps.outpoint);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._isMounted = true;
|
||||
this.loadCostAndFileState(this.props.uri, this.props.outpoint);
|
||||
},
|
||||
|
||||
loadCostAndFileState: function(uri, outpoint) {
|
||||
lbry.file_list({outpoint: outpoint}).then((fileInfo) => {
|
||||
if (this._isMounted) {
|
||||
this.setState({
|
||||
isDownloaded: fileInfo.length > 0,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
lbry.getCostInfo(uri).then(({cost, includesData}) => {
|
||||
if (this._isMounted) {
|
||||
this.setState({
|
||||
cost: cost,
|
||||
costIncludesData: includesData,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const metadata = this.props.metadata,
|
||||
title = metadata ? this.props.metadata.title : this.props.uri,
|
||||
uriIndicator = <UriIndicator uri={uri} hasSignature={hasSignature} signatureIsValid={signatureIsValid} />
|
||||
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<section className="show-page-media">
|
||||
{ this.props.contentType && this.props.contentType.startsWith('video/') ?
|
||||
<Video className="video-embedded" uri={this.props.uri} metadata={metadata} outpoint={this.props.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={lbryuri.normalize(uri)} metadata={metadata} /></span>
|
||||
: null}
|
||||
<h1>{title}</h1>
|
||||
<div className="card__subtitle">
|
||||
{ this.props.channelUri ?
|
||||
<Link href={"?show=" + this.props.channelUri }>{uriIndicator}</Link> :
|
||||
uriIndicator}
|
||||
</div>
|
||||
<div className="card__actions">
|
||||
<FileActions uri={uri} outpoint={outpoint} metadata={metadata} contentType={contentType} /></div>
|
||||
</div>
|
||||
<div className="card__content card__subtext card__subtext card__subtext--allow-newlines">
|
||||
{metadata.description}
|
||||
</div>
|
||||
</div>
|
||||
{ metadata ?
|
||||
<div className="card__content">
|
||||
<FormatItem metadata={metadata} contentType={this.state.contentType} cost={this.state.cost} uri={this.props.uri} outpoint={this.props.outpoint} costIncludesData={this.state.costIncludesData} />
|
||||
</div> : '' }
|
||||
<div className="card__content">
|
||||
<Link href="https://lbry.io/dmca" label="report" className="button-text-help" />
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
let ShowPage = React.createClass({
|
||||
_uri: null,
|
||||
_isMounted: false,
|
||||
|
||||
propTypes: {
|
||||
uri: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
outpoint: null,
|
||||
metadata: null,
|
||||
contentType: null,
|
||||
hasSignature: false,
|
||||
claimType: null,
|
||||
signatureIsValid: false,
|
||||
cost: null,
|
||||
costIncludesData: null,
|
||||
uriLookupComplete: null,
|
||||
isFailed: false,
|
||||
};
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._isMounted = false;
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
if (nextProps.uri != this.props.uri) {
|
||||
this.setState(this.getInitialState());
|
||||
this.loadUri(nextProps.uri);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._isMounted = true;
|
||||
this.loadUri(this.props.uri);
|
||||
},
|
||||
|
||||
loadUri: function(uri) {
|
||||
this._uri = lbryuri.normalize(uri);
|
||||
|
||||
lbry.resolve({uri: this._uri}).then((resolveData) => {
|
||||
const isChannel = resolveData && resolveData.claims_in_channel;
|
||||
if (!this._isMounted) {
|
||||
return;
|
||||
}
|
||||
if (resolveData) {
|
||||
let newState = { uriLookupComplete: true }
|
||||
if (!isChannel) {
|
||||
let {claim: {txid: txid, nout: nout, has_signature: has_signature, signature_is_valid: signature_is_valid, value: {stream: {metadata: metadata, source: {contentType: contentType}}}}} = resolveData;
|
||||
|
||||
Object.assign(newState, {
|
||||
claimType: "file",
|
||||
metadata: metadata,
|
||||
outpoint: txid + ':' + nout,
|
||||
hasSignature: has_signature,
|
||||
signatureIsValid: signature_is_valid,
|
||||
contentType: contentType
|
||||
});
|
||||
|
||||
|
||||
lbry.setTitle(metadata.title ? metadata.title : this._uri)
|
||||
|
||||
} else {
|
||||
let {certificate: {txid: txid, nout: nout, has_signature: has_signature}} = resolveData;
|
||||
Object.assign(newState, {
|
||||
claimType: "channel",
|
||||
outpoint: txid + ':' + nout,
|
||||
txid: txid,
|
||||
metadata: {
|
||||
title:resolveData.certificate.name
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.setState(newState);
|
||||
|
||||
} else {
|
||||
this.setState(Object.assign({}, this.getInitialState(), {
|
||||
uriLookupComplete: true,
|
||||
isFailed: true
|
||||
}));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
const metadata = this.state.metadata,
|
||||
title = metadata ? this.state.metadata.title : this._uri;
|
||||
|
||||
let innerContent = "";
|
||||
|
||||
if (!this.state.uriLookupComplete || this.state.isFailed) {
|
||||
innerContent = <section className="card">
|
||||
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} /> :
|
||||
(Object.keys(metadata).length > 0 ? <Thumbnail src={metadata.thumbnail} /> : <Thumbnail />) }
|
||||
</section>
|
||||
<section className="card">
|
||||
<div className="card__inner">
|
||||
<div className="card__title-identity"><h1>{title}</h1></div>
|
||||
<div className="card__title-identity">
|
||||
{isDownloaded === false
|
||||
? <span style={{float: "right"}}><FilePrice uri={lbryuri.normalize(uri)} /></span>
|
||||
: null}
|
||||
<h1>{title}</h1>
|
||||
<div className="card__subtitle">
|
||||
{ channelUri ?
|
||||
<Link href={"?show=" + channelUri }>{uriIndicator}</Link> :
|
||||
uriIndicator}
|
||||
</div>
|
||||
<div className="card__actions">
|
||||
<FileActions uri={uri} /></div>
|
||||
</div>
|
||||
<div className="card__content card__subtext card__subtext card__subtext--allow-newlines">
|
||||
{metadata.description}
|
||||
</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">
|
||||
{ this.state.uriLookupComplete ?
|
||||
<p>This location is not yet in use. { ' ' }<Link href="?publish" label="Put something here" />.</p> :
|
||||
<BusyMessage message="Loading magic decentralized data..." />
|
||||
}
|
||||
<Link href="https://lbry.io/dmca" label="report" className="button-text-help" />
|
||||
</div>
|
||||
</section>;
|
||||
} else {
|
||||
let channelUriObj = lbryuri.parse(this._uri)
|
||||
delete channelUriObj.path;
|
||||
delete channelUriObj.contentName;
|
||||
const channelUri = this.state.signatureIsValid && this.state.hasSignature && channelUriObj.isChannel ? lbryuri.build(channelUriObj, false) : null;
|
||||
innerContent = <FilePage
|
||||
uri={this._uri}
|
||||
channelUri={channelUri}
|
||||
outpoint={this.state.outpoint}
|
||||
metadata={metadata}
|
||||
contentType={this.state.contentType}
|
||||
hasSignature={this.state.hasSignature}
|
||||
signatureIsValid={this.state.signatureIsValid}
|
||||
/>;
|
||||
}
|
||||
|
||||
return <main className="main--single-column">{innerContent}</main>;
|
||||
}
|
||||
});
|
||||
</section>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
export default FilePage;
|
||||
|
||||
//
|
||||
// const ShowPage = (props) => {
|
||||
// const {
|
||||
// claim,
|
||||
// navigate,
|
||||
// claim: {
|
||||
// txid,
|
||||
// nout,
|
||||
// has_signature: hasSignature,
|
||||
// signature_is_valid: signatureIsValid,
|
||||
// value,
|
||||
// value: {
|
||||
// stream,
|
||||
// stream: {
|
||||
// metadata,
|
||||
// source,
|
||||
// metadata: {
|
||||
// title,
|
||||
// } = {},
|
||||
// source: {
|
||||
// contentType,
|
||||
// } = {},
|
||||
// } = {},
|
||||
// } = {},
|
||||
// },
|
||||
// uri,
|
||||
// isDownloaded,
|
||||
// fileInfo,
|
||||
// costInfo,
|
||||
// costInfo: {
|
||||
// cost,
|
||||
// includesData: costIncludesData,
|
||||
// } = {},
|
||||
// } = props
|
||||
//
|
||||
// const outpoint = txid + ':' + nout;
|
||||
// const uriLookupComplete = !!claim && Object.keys(claim).length
|
||||
//
|
||||
// if (props.isFailed) {
|
||||
// return (
|
||||
// <main className="main--single-column">
|
||||
// <section className="card">
|
||||
// <div className="card__inner">
|
||||
// <div className="card__title-identity"><h1>{uri}</h1></div>
|
||||
// </div>
|
||||
// <div className="card__content">
|
||||
// <p>
|
||||
// This location is not yet in use.
|
||||
// { ' ' }
|
||||
// <Link href="#" onClick={() => navigate('publish')} label="Put something here" />.
|
||||
// </p>
|
||||
// </div>
|
||||
// </section>
|
||||
// </main>
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// 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={lbryuri.normalize(uri)} /></span>
|
||||
// : null}
|
||||
// <h1>{title}</h1>
|
||||
// { uriLookupComplete ?
|
||||
// <div>
|
||||
// <div className="card__subtitle">
|
||||
// <UriIndicator uri={uri} />
|
||||
// </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>
|
||||
// )
|
||||
// }
|
|
@ -2,7 +2,7 @@
|
|||
import React from 'react';
|
||||
import lbry from 'lbry.js';
|
||||
import Link from 'component/link';
|
||||
import NavSettings from 'component/navSettings';
|
||||
import SubHeader from 'component/subHeader'
|
||||
import {version as uiVersion} from 'json!../../../package.json';
|
||||
|
||||
var HelpPage = React.createClass({
|
||||
|
@ -50,7 +50,7 @@ var HelpPage = React.createClass({
|
|||
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<NavSettings />
|
||||
<SubHeader />
|
||||
<section className="card">
|
||||
<div className="card__title-primary">
|
||||
<h3>Read the FAQ</h3>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import lbryio from 'lbryio';
|
||||
import {CreditAmount, Icon} from 'component/common.js';
|
||||
import NavWallet from 'component/navWallet';
|
||||
import SubHeader from 'component/subHeader'
|
||||
import {RewardLink} from 'component/reward-link';
|
||||
|
||||
const RewardTile = React.createClass({
|
||||
|
@ -55,7 +55,7 @@ export let RewardsPage = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<NavWallet />
|
||||
<SubHeader />
|
||||
<div>
|
||||
{!this.state.userRewards
|
||||
? (this.state.failed ? <div className="empty">Failed to load rewards.</div> : '')
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
import React from 'react';
|
||||
import lbry from '../lbry.js';
|
||||
import lbryio from '../lbryio.js';
|
||||
import lbryuri from '../lbryuri.js';
|
||||
import lighthouse from '../lighthouse.js';
|
||||
import {FileTile, FileTileStream} from '../component/file-tile.js';
|
||||
import {Link} from '../component/link';
|
||||
import {ToolTip} from '../component/tooltip.js';
|
||||
import {BusyMessage} from '../component/common.js';
|
||||
|
||||
var SearchNoResults = React.createClass({
|
||||
render: function() {
|
||||
return <section>
|
||||
<span className="empty">
|
||||
No one has checked anything in for {this.props.query} yet.
|
||||
<Link label="Be the first" href="?publish" />
|
||||
</span>
|
||||
</section>;
|
||||
}
|
||||
});
|
||||
|
||||
var SearchResultList = React.createClass({
|
||||
render: function() {
|
||||
var rows = [],
|
||||
seenNames = {}; //fix this when the search API returns claim IDs
|
||||
|
||||
for (let {name, claim, claim_id, channel_name, channel_id, txid, nout} of this.props.results) {
|
||||
const uri = lbryuri.build({
|
||||
channelName: channel_name,
|
||||
contentName: name,
|
||||
claimId: channel_id || claim_id,
|
||||
});
|
||||
|
||||
rows.push(
|
||||
<FileTileStream key={uri} uri={uri} outpoint={txid + ':' + nout} metadata={claim.stream.metadata} contentType={claim.stream.source.contentType} />
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>{rows}</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
let SearchResults = React.createClass({
|
||||
propTypes: {
|
||||
query: React.PropTypes.string.isRequired
|
||||
},
|
||||
|
||||
_isMounted: false,
|
||||
|
||||
search: function(term) {
|
||||
lighthouse.search(term).then(this.searchCallback);
|
||||
if (!this.state.searching) {
|
||||
this.setState({ searching: true })
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount: function () {
|
||||
this._isMounted = true;
|
||||
this.search(this.props.query);
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function (nextProps) {
|
||||
if (nextProps.query != this.props.query) {
|
||||
this.search(nextProps.query);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount: function () {
|
||||
this._isMounted = false;
|
||||
},
|
||||
|
||||
getInitialState: function () {
|
||||
return {
|
||||
results: [],
|
||||
searching: true
|
||||
};
|
||||
},
|
||||
|
||||
searchCallback: function (results) {
|
||||
if (this._isMounted) //could have canceled while results were pending, in which case nothing to do
|
||||
{
|
||||
this.setState({
|
||||
results: results,
|
||||
searching: false //multiple searches can be out, we're only done if we receive one we actually care about
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
render: function () {
|
||||
return this.state.searching ?
|
||||
<BusyMessage message="Looking up the Dewey Decimals" /> :
|
||||
(this.state.results && this.state.results.length ?
|
||||
<SearchResultList results={this.state.results} /> :
|
||||
<SearchNoResults query={this.props.query} />);
|
||||
}
|
||||
});
|
||||
|
||||
let SearchPage = React.createClass({
|
||||
|
||||
_isMounted: false,
|
||||
|
||||
propTypes: {
|
||||
query: React.PropTypes.string.isRequired
|
||||
},
|
||||
|
||||
isValidUri: function(query) {
|
||||
try {
|
||||
lbryuri.parse(query);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._isMounted = true;
|
||||
lighthouse.search(this.props.query).then(this.searchCallback);
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this._isMounted = false;
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
results: [],
|
||||
searching: true
|
||||
};
|
||||
},
|
||||
|
||||
searchCallback: function(results) {
|
||||
if (this._isMounted) //could have canceled while results were pending, in which case nothing to do
|
||||
{
|
||||
this.setState({
|
||||
results: results,
|
||||
searching: false //multiple searches can be out, we're only done if we receive one we actually care about
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
{ this.isValidUri(this.props.query) ?
|
||||
<section className="section-spaced">
|
||||
<h3 className="card-row__header">
|
||||
Exact URL
|
||||
<ToolTip label="?" body="This is the resolution of a LBRY URL and not controlled by LBRY Inc." className="tooltip--header"/>
|
||||
</h3>
|
||||
<FileTile uri={this.props.query} showEmpty={true} />
|
||||
</section> : '' }
|
||||
<section className="section-spaced">
|
||||
<h3 className="card-row__header">
|
||||
Search Results for {this.props.query}
|
||||
<ToolTip label="?" body="These search results are provided by LBRY Inc." className="tooltip--header"/>
|
||||
</h3>
|
||||
<SearchResults query={this.props.query} />
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default SearchPage;
|
30
ui/js/page/search/index.js
Normal file
30
ui/js/page/search/index.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect,
|
||||
} from 'react-redux'
|
||||
import {
|
||||
doSearchContent,
|
||||
} from 'actions/search'
|
||||
import {
|
||||
selectIsSearching,
|
||||
selectSearchQuery,
|
||||
selectCurrentSearchResults,
|
||||
selectSearchActivated,
|
||||
} from 'selectors/search'
|
||||
import {
|
||||
doNavigate,
|
||||
} from 'actions/app'
|
||||
import SearchPage from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
isSearching: selectIsSearching(state),
|
||||
query: selectSearchQuery(state),
|
||||
results: selectCurrentSearchResults(state),
|
||||
searchActive: selectSearchActivated(state),
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
navigate: (path) => dispatch(doNavigate(path)),
|
||||
})
|
||||
|
||||
export default connect(select, perform)(SearchPage)
|
92
ui/js/page/search/view.jsx
Normal file
92
ui/js/page/search/view.jsx
Normal file
|
@ -0,0 +1,92 @@
|
|||
import React from 'react';
|
||||
import lbry from 'lbry';
|
||||
import lbryio from 'lbryio';
|
||||
import lbryuri from 'lbryuri';
|
||||
import lighthouse from 'lighthouse';
|
||||
import FileTile from 'component/fileTile'
|
||||
import FileTileStream from 'component/fileTileStream'
|
||||
import Link from 'component/link'
|
||||
import {ToolTip} from 'component/tooltip.js';
|
||||
import {BusyMessage} from 'component/common.js';
|
||||
|
||||
const SearchNoResults = (props) => {
|
||||
const {
|
||||
navigate,
|
||||
query,
|
||||
} = props
|
||||
|
||||
return <section>
|
||||
<span className="empty">
|
||||
No one has checked anything in for {query} yet.
|
||||
<Link label="Be the first" href="#" onClick={() => navigate('publish')} />
|
||||
</span>
|
||||
</section>;
|
||||
}
|
||||
|
||||
const SearchResultList = (props) => {
|
||||
const {
|
||||
results,
|
||||
} = props
|
||||
|
||||
const rows = [],
|
||||
seenNames = {}; //fix this when the search API returns claim IDs
|
||||
|
||||
for (let {name, claim, claim_id, channel_name, channel_id, txid, nout} of results) {
|
||||
const uri = lbryuri.build({
|
||||
channelName: channel_name,
|
||||
contentName: name,
|
||||
claimId: channel_id || claim_id,
|
||||
});
|
||||
|
||||
rows.push(
|
||||
<FileTileStream key={uri} uri={uri} />
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div>{rows}</div>
|
||||
);
|
||||
}
|
||||
|
||||
const SearchResults = (props) => {
|
||||
const {
|
||||
searching,
|
||||
results,
|
||||
query,
|
||||
} = props
|
||||
|
||||
return (
|
||||
searching ?
|
||||
<BusyMessage message="Looking up the Dewey Decimals" /> :
|
||||
(results && results.length) ?
|
||||
<SearchResultList {...props} /> :
|
||||
<SearchNoResults {...props} />
|
||||
)
|
||||
}
|
||||
|
||||
const SearchPage = (props) => {
|
||||
const isValidUri = (query) => true
|
||||
const {
|
||||
query,
|
||||
} = props
|
||||
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
{ isValidUri(query) ?
|
||||
<section className="section-spaced">
|
||||
<h3 className="card-row__header">
|
||||
Exact URL
|
||||
<ToolTip label="?" body="This is the resolution of a LBRY URL and not controlled by LBRY Inc." className="tooltip--header" />
|
||||
</h3>
|
||||
<FileTile uri={query} showEmpty={true} />
|
||||
</section> : '' }
|
||||
<section className="section-spaced">
|
||||
<h3 className="card-row__header">
|
||||
Search Results for {query}
|
||||
<ToolTip label="?" body="These search results are provided by LBRY, Inc." className="tooltip--header" />
|
||||
</h3>
|
||||
<SearchResults {...props} />
|
||||
</section>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
export default SearchPage;
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import {FormField, FormRow} from '../component/form.js';
|
||||
import NavSettings from 'component/navSettings';
|
||||
import SubHeader from 'component/subHeader'
|
||||
import lbry from '../lbry.js';
|
||||
|
||||
var SettingsPage = React.createClass({
|
||||
|
@ -91,7 +91,7 @@ var SettingsPage = React.createClass({
|
|||
*/
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<NavSettings />
|
||||
<SubHeader />
|
||||
<section className="card">
|
||||
<div className="card__content">
|
||||
<h3>Download Directory</h3>
|
||||
|
|
35
ui/js/page/showPage/index.js
Normal file
35
ui/js/page/showPage/index.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect
|
||||
} from 'react-redux'
|
||||
import {
|
||||
selectCurrentUri,
|
||||
} from 'selectors/app'
|
||||
import {
|
||||
selectCurrentUriIsDownloaded,
|
||||
} from 'selectors/file_info'
|
||||
import {
|
||||
selectCurrentUriClaim,
|
||||
} from 'selectors/claims'
|
||||
import {
|
||||
selectCurrentUriFileInfo,
|
||||
} from 'selectors/file_info'
|
||||
import {
|
||||
selectCurrentUriCostInfo,
|
||||
} from 'selectors/cost_info'
|
||||
import ShowPage from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
claim: selectCurrentUriClaim(state),
|
||||
uri: selectCurrentUri(state),
|
||||
isDownloaded: selectCurrentUriIsDownloaded(state),
|
||||
fileInfo: selectCurrentUriFileInfo(state),
|
||||
costInfo: selectCurrentUriCostInfo(state),
|
||||
isFailed: false,
|
||||
claimType: 'file',
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
})
|
||||
|
||||
export default connect(select, perform)(ShowPage)
|
72
ui/js/page/showPage/view.jsx
Normal file
72
ui/js/page/showPage/view.jsx
Normal file
|
@ -0,0 +1,72 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
BusyMessage,
|
||||
} from 'component/common';
|
||||
import FilePage from 'page/filePage'
|
||||
|
||||
const ShowPage = (props) => {
|
||||
const {
|
||||
claim,
|
||||
navigate,
|
||||
claim: {
|
||||
txid,
|
||||
nout,
|
||||
has_signature: hasSignature,
|
||||
signature_is_valid: signatureIsValid,
|
||||
value,
|
||||
value: {
|
||||
stream,
|
||||
stream: {
|
||||
metadata,
|
||||
source,
|
||||
metadata: {
|
||||
title,
|
||||
} = {},
|
||||
source: {
|
||||
contentType,
|
||||
} = {},
|
||||
} = {},
|
||||
} = {},
|
||||
},
|
||||
uri,
|
||||
isDownloaded,
|
||||
fileInfo,
|
||||
costInfo,
|
||||
costInfo: {
|
||||
cost,
|
||||
includesData: costIncludesData,
|
||||
} = {},
|
||||
isFailed,
|
||||
claimType,
|
||||
} = props
|
||||
|
||||
const outpoint = txid + ':' + nout;
|
||||
const uriLookupComplete = !!claim && Object.keys(claim).length
|
||||
const pageTitle = metadata ? metadata.title : uri;
|
||||
|
||||
let innerContent = "";
|
||||
|
||||
if (!uriLookupComplete || isFailed) {
|
||||
innerContent = <section className="card">
|
||||
<div className="card__inner">
|
||||
<div className="card__title-identity"><h1>{pageTitle}</h1></div>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
{ uriLookupComplete ?
|
||||
<p>This location is not yet in use. { ' ' }<Link href="#" onClick={() => navigate('publish')} label="Put something here" />.</p> :
|
||||
<BusyMessage message="Loading magic decentralized data..." />
|
||||
}
|
||||
</div>
|
||||
</section>;
|
||||
} else if (claimType == "channel") {
|
||||
innerContent = <ChannelPage title={uri} />
|
||||
} else {
|
||||
innerContent = <FilePage uri={uri} />
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="main--single-column">{innerContent}</main>
|
||||
)
|
||||
}
|
||||
|
||||
export default ShowPage
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import lbry from 'lbry.js';
|
||||
import Link from 'component/link';
|
||||
import Modal from 'component/modal';
|
||||
import NavWallet from 'component/navWallet';
|
||||
import SubHeader from 'component/subHeader'
|
||||
import {
|
||||
FormField,
|
||||
FormRow
|
||||
|
@ -248,7 +248,7 @@ const WalletPage = (props) => {
|
|||
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<NavWallet />
|
||||
<SubHeader />
|
||||
<section className="card">
|
||||
<div className="card__title-primary">
|
||||
<h3>Balance</h3>
|
||||
|
|
|
@ -8,7 +8,6 @@ const defaultState = {
|
|||
platform: process.platform,
|
||||
upgradeSkipped: sessionStorage.getItem('upgradeSkipped'),
|
||||
daemonReady: false,
|
||||
platform: window.navigator.platform,
|
||||
obscureNsfw: !lbry.getClientSetting('showNsfw'),
|
||||
hidePrice: false,
|
||||
hasSignature: false,
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import {createSelector} from 'reselect'
|
||||
import {
|
||||
selectIsSearching,
|
||||
selectSearchActivated,
|
||||
} from 'selectors/search'
|
||||
|
||||
export const _selectState = state => state.app || {}
|
||||
|
||||
|
@ -14,7 +18,12 @@ export const selectCurrentPath = createSelector(
|
|||
|
||||
export const selectCurrentPage = createSelector(
|
||||
selectCurrentPath,
|
||||
(path) => path.split('=')[0]
|
||||
selectSearchActivated,
|
||||
(path, searchActivated) => {
|
||||
if (searchActivated) return 'search'
|
||||
|
||||
return path.split('=')[0]
|
||||
}
|
||||
)
|
||||
|
||||
export const selectCurrentUri = createSelector(
|
||||
|
@ -198,6 +207,12 @@ export const selectHeaderLinks = createSelector(
|
|||
'downloaded': 'Downloaded',
|
||||
'published': 'Published',
|
||||
};
|
||||
case 'settings':
|
||||
case 'help':
|
||||
return {
|
||||
'settings': 'Settings',
|
||||
'help': 'Help',
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
"node-sass": "^3.13.0",
|
||||
"webpack": "^1.13.3",
|
||||
"webpack-dev-server": "^2.4.4",
|
||||
"webpack-notifier": "^1.5.0",
|
||||
"webpack-target-electron-renderer": "^0.4.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
const path = require('path');
|
||||
const WebpackNotifierPlugin = require('webpack-notifier')
|
||||
|
||||
const appPath = path.resolve(__dirname, 'js');
|
||||
|
||||
const PATHS = {
|
||||
|
@ -21,6 +23,9 @@ module.exports = {
|
|||
root: appPath,
|
||||
extensions: ['', '.js', '.jsx', '.css'],
|
||||
},
|
||||
plugins: [
|
||||
new WebpackNotifierPlugin(),
|
||||
],
|
||||
module: {
|
||||
preLoaders: [
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue