much progress towards a working merge
This commit is contained in:
parent
d94ef70f60
commit
36a992343f
42 changed files with 713 additions and 932 deletions
|
@ -12,7 +12,6 @@ Web UI version numbers should always match the corresponding version of LBRY App
|
|||
* The app is much more responsive switching pages. It no longer reloads the entire page and all assets on each page change.
|
||||
* lbry.js now offers a subscription model for wallet balance similar to file info.
|
||||
* Fixed file info subscribes not being unsubscribed in unmount.
|
||||
* Fixed drawer not highlighting selected page.
|
||||
* You can now make API calls directly on the lbry module, e.g. lbry.peer_list()
|
||||
* New-style API calls return promises instead of using callbacks
|
||||
* Wherever possible, use outpoints for unique IDs instead of names or SD hashes
|
||||
|
|
|
@ -32,18 +32,6 @@ export function doNavigate(path) {
|
|||
export function doLogoClick() {
|
||||
}
|
||||
|
||||
export function doOpenDrawer() {
|
||||
return {
|
||||
type: types.OPEN_DRAWER
|
||||
}
|
||||
}
|
||||
|
||||
export function doCloseDrawer() {
|
||||
return {
|
||||
type: types.CLOSE_DRAWER
|
||||
}
|
||||
}
|
||||
|
||||
export function doOpenModal(modal) {
|
||||
return {
|
||||
type: types.OPEN_MODAL,
|
||||
|
@ -59,6 +47,12 @@ export function doCloseModal() {
|
|||
}
|
||||
}
|
||||
|
||||
export function doHistoryBack() {
|
||||
return {
|
||||
type: types.HISTORY_BACK
|
||||
}
|
||||
}
|
||||
|
||||
export function doUpdateDownloadProgress(percent) {
|
||||
return {
|
||||
type: types.UPGRADE_DOWNLOAD_PROGRESSED,
|
||||
|
@ -153,12 +147,8 @@ export function doCheckUpgradeAvailable() {
|
|||
return function(dispatch, getState) {
|
||||
const state = getState()
|
||||
|
||||
lbry.checkNewVersionAvailable(({isAvailable}) => {
|
||||
if (!isAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
lbry.getVersionInfo((versionInfo) => {
|
||||
lbry.getVersionInfo().then(({remoteVersion, upgradeAvailable}) => {
|
||||
if (upgradeAvailable) {
|
||||
dispatch({
|
||||
type: types.UPDATE_VERSION,
|
||||
data: {
|
||||
|
@ -171,7 +161,7 @@ export function doCheckUpgradeAvailable() {
|
|||
modal: 'upgrade'
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ export function doFetchPublishedContent() {
|
|||
}
|
||||
}
|
||||
|
||||
export function doFetchFeaturedContent() {
|
||||
export function doFetchFeaturedUris() {
|
||||
return function(dispatch, getState) {
|
||||
const state = getState()
|
||||
|
||||
|
@ -130,11 +130,20 @@ export function doFetchFeaturedContent() {
|
|||
})
|
||||
|
||||
const success = ({ Categories, Uris }) => {
|
||||
|
||||
let featuredUris = {}
|
||||
|
||||
Categories.forEach((category) => {
|
||||
if (Uris[category] && Uris[category].length) {
|
||||
featuredUris[category] = Uris[category]
|
||||
}
|
||||
})
|
||||
|
||||
dispatch({
|
||||
type: types.FETCH_FEATURED_CONTENT_COMPLETED,
|
||||
data: {
|
||||
categories: Categories,
|
||||
uris: Uris,
|
||||
uris: featuredUris,
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -146,6 +155,13 @@ export function doFetchFeaturedContent() {
|
|||
}
|
||||
|
||||
const failure = () => {
|
||||
dispatch({
|
||||
type: types.FETCH_FEATURED_CONTENT_COMPLETED,
|
||||
data: {
|
||||
categories: [],
|
||||
uris: {}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
lbryio.call('discover', 'list', { version: "early-access" } )
|
||||
|
|
|
@ -41,6 +41,7 @@ export function doGetNewAddress() {
|
|||
type: types.GET_NEW_ADDRESS_STARTED
|
||||
})
|
||||
|
||||
console.log('do get new address');
|
||||
lbry.wallet_new_address().then(function(address) {
|
||||
localStorage.setItem('wallet_address', address);
|
||||
dispatch({
|
||||
|
|
320
ui/js/app.js
320
ui/js/app.js
|
@ -14,322 +14,4 @@ const app = {
|
|||
}
|
||||
}
|
||||
global.app = app;
|
||||
module.exports = app;
|
||||
|
||||
//
|
||||
// import React from 'react';
|
||||
// import {Line} from 'rc-progress';
|
||||
//
|
||||
// import lbry from './lbry.js';
|
||||
// import SettingsPage from './page/settings.js';
|
||||
// import HelpPage from './page/help.js';
|
||||
// import WatchPage from './page/watch.js';
|
||||
// import ReportPage from './page/report.js';
|
||||
// import StartPage from './page/start.js';
|
||||
// import RewardsPage from './page/rewards.js';
|
||||
// import RewardPage from './page/reward.js';
|
||||
// import WalletPage from './page/wallet.js';
|
||||
// import ShowPage from './page/show.js';
|
||||
// import PublishPage from './page/publish.js';
|
||||
// import SearchPage from './page/search.js';
|
||||
// import DiscoverPage from './page/discover.js';
|
||||
// import DeveloperPage from './page/developer.js';
|
||||
// import lbryuri from './lbryuri.js';
|
||||
// import {FileListDownloaded, FileListPublished} from './page/file-list.js';
|
||||
// import Header from './component/header.js';
|
||||
// import {Modal, ExpandableModal} from './component/modal.js';
|
||||
// import {Link} from './component/link';
|
||||
//
|
||||
//
|
||||
// const {remote, ipcRenderer, shell} = require('electron');
|
||||
// const {download} = remote.require('electron-dl');
|
||||
// const path = require('path');
|
||||
// const app = require('electron').remote.app;
|
||||
// const fs = remote.require('fs');
|
||||
//
|
||||
//
|
||||
// var App = React.createClass({
|
||||
// _error_key_labels: {
|
||||
// connectionString: 'API connection string',
|
||||
// method: 'Method',
|
||||
// params: 'Parameters',
|
||||
// code: 'Error code',
|
||||
// message: 'Error message',
|
||||
// data: 'Error data',
|
||||
// },
|
||||
// _fullScreenPages: ['watch'],
|
||||
// _storeHistoryOfNextRender: false,
|
||||
//
|
||||
// _upgradeDownloadItem: null,
|
||||
// _isMounted: false,
|
||||
// _version: null,
|
||||
// getUpdateUrl: function() {
|
||||
// switch (process.platform) {
|
||||
// case 'darwin':
|
||||
// return 'https://lbry.io/get/lbry.dmg';
|
||||
// case 'linux':
|
||||
// return 'https://lbry.io/get/lbry.deb';
|
||||
// case 'win32':
|
||||
// return 'https://lbry.io/get/lbry.exe';
|
||||
// default:
|
||||
// throw 'Unknown platform';
|
||||
// }
|
||||
// },
|
||||
// // Hard code the filenames as a temporary workaround, because
|
||||
// // electron-dl throws errors when you try to get the filename
|
||||
// getUpgradeFilename: function() {
|
||||
// switch (process.platform) {
|
||||
// case 'darwin':
|
||||
// return `LBRY-${this._version}.dmg`;
|
||||
// case 'linux':
|
||||
// return `LBRY_${this._version}_amd64.deb`;
|
||||
// case 'windows':
|
||||
// return `LBRY.Setup.${this._version}.exe`;
|
||||
// default:
|
||||
// throw 'Unknown platform';
|
||||
// }
|
||||
// },
|
||||
// getViewingPageAndArgs: function(address) {
|
||||
// // For now, routes are in format ?page or ?page=args
|
||||
// let [isMatch, viewingPage, pageArgs] = address.match(/\??([^=]*)(?:=(.*))?/);
|
||||
// return {
|
||||
// viewingPage: viewingPage,
|
||||
// pageArgs: pageArgs === undefined ? null : decodeURIComponent(pageArgs)
|
||||
// };
|
||||
// },
|
||||
// getInitialState: function() {
|
||||
// return Object.assign(this.getViewingPageAndArgs(window.location.search), {
|
||||
// viewingPage: 'discover',
|
||||
// appUrl: null,
|
||||
// errorInfo: null,
|
||||
// modal: null,
|
||||
// downloadProgress: null,
|
||||
// downloadComplete: false,
|
||||
// });
|
||||
// },
|
||||
// componentWillMount: function() {
|
||||
// window.addEventListener("popstate", this.onHistoryPop);
|
||||
//
|
||||
// document.addEventListener('unhandledError', (event) => {
|
||||
// this.alertError(event.detail);
|
||||
// });
|
||||
//
|
||||
// //open links in external browser and skip full redraw on changing page
|
||||
// document.addEventListener('click', (event) => {
|
||||
// var target = event.target;
|
||||
// while (target && target !== document) {
|
||||
// if (target.matches('a[href^="http"]')) {
|
||||
// event.preventDefault();
|
||||
// shell.openExternal(target.href);
|
||||
// return;
|
||||
// }
|
||||
// if (target.matches('a[href^="?"]')) {
|
||||
// event.preventDefault();
|
||||
// if (this._isMounted) {
|
||||
// let appUrl = target.getAttribute('href');
|
||||
// this._storeHistoryOfNextRender = true;
|
||||
// this.setState(Object.assign({}, this.getViewingPageAndArgs(appUrl), { appUrl: appUrl }));
|
||||
// document.body.scrollTop = 0;
|
||||
// }
|
||||
// }
|
||||
// target = target.parentNode;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// if (!sessionStorage.getItem('upgradeSkipped')) {
|
||||
// lbry.getVersionInfo().then(({remoteVersion, upgradeAvailable}) => {
|
||||
// if (upgradeAvailable) {
|
||||
// this._version = remoteVersion;
|
||||
// this.setState({
|
||||
// modal: 'upgrade',
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
// closeModal: function() {
|
||||
// this.setState({
|
||||
// modal: null,
|
||||
// });
|
||||
// },
|
||||
// componentDidMount: function() {
|
||||
// this._isMounted = true;
|
||||
// },
|
||||
// componentWillUnmount: function() {
|
||||
// this._isMounted = false;
|
||||
// window.removeEventListener("popstate", this.onHistoryPop);
|
||||
// },
|
||||
// onHistoryPop: function() {
|
||||
// this.setState(this.getViewingPageAndArgs(location.search));
|
||||
// },
|
||||
// onSearch: function(term) {
|
||||
// this._storeHistoryOfNextRender = true;
|
||||
// const isShow = term.startsWith('lbry://');
|
||||
// this.setState({
|
||||
// viewingPage: isShow ? "show" : "search",
|
||||
// appUrl: (isShow ? "?show=" : "?search=") + encodeURIComponent(term),
|
||||
// pageArgs: term
|
||||
// });
|
||||
// },
|
||||
// onSubmit: function(uri) {
|
||||
// this._storeHistoryOfNextRender = true;
|
||||
// this.setState({
|
||||
// address: uri,
|
||||
// appUrl: "?show=" + encodeURIComponent(uri),
|
||||
// viewingPage: "show",
|
||||
// pageArgs: uri
|
||||
// })
|
||||
// },
|
||||
// handleUpgradeClicked: function() {
|
||||
// // Make a new directory within temp directory so the filename is guaranteed to be available
|
||||
// const dir = fs.mkdtempSync(app.getPath('temp') + require('path').sep);
|
||||
//
|
||||
// let options = {
|
||||
// onProgress: (p) => this.setState({downloadProgress: Math.round(p * 100)}),
|
||||
// directory: dir,
|
||||
// };
|
||||
// download(remote.getCurrentWindow(), this.getUpdateUrl(), options)
|
||||
// .then(downloadItem => {
|
||||
// /**
|
||||
// * TODO: get the download path directly from the download object. It should just be
|
||||
// * downloadItem.getSavePath(), but the copy on the main process is being garbage collected
|
||||
// * too soon.
|
||||
// */
|
||||
//
|
||||
// this._upgradeDownloadItem = downloadItem;
|
||||
// this._upgradeDownloadPath = path.join(dir, this.getUpgradeFilename());
|
||||
// this.setState({
|
||||
// downloadComplete: true
|
||||
// });
|
||||
// });
|
||||
// this.setState({modal: 'downloading'});
|
||||
// },
|
||||
// handleStartUpgradeClicked: function() {
|
||||
// ipcRenderer.send('upgrade', this._upgradeDownloadPath);
|
||||
// },
|
||||
// cancelUpgrade: function() {
|
||||
// if (this._upgradeDownloadItem) {
|
||||
// /*
|
||||
// * Right now the remote reference to the download item gets garbage collected as soon as the
|
||||
// * the download is over (maybe even earlier), so trying to cancel a finished download may
|
||||
// * throw an error.
|
||||
// */
|
||||
// try {
|
||||
// this._upgradeDownloadItem.cancel();
|
||||
// } catch (err) {
|
||||
// // Do nothing
|
||||
// }
|
||||
// }
|
||||
// this.setState({
|
||||
// downloadProgress: null,
|
||||
// downloadComplete: false,
|
||||
// modal: null,
|
||||
// });
|
||||
// },
|
||||
// handleSkipClicked: function() {
|
||||
// sessionStorage.setItem('upgradeSkipped', true);
|
||||
// this.setState({
|
||||
// modal: null,
|
||||
// });
|
||||
// },
|
||||
// alertError: function(error) {
|
||||
// var errorInfoList = [];
|
||||
// for (let key of Object.keys(error)) {
|
||||
// let val = typeof error[key] == 'string' ? error[key] : JSON.stringify(error[key]);
|
||||
// let label = this._error_key_labels[key];
|
||||
// errorInfoList.push(<li key={key}><strong>{label}</strong>: <code>{val}</code></li>);
|
||||
// }
|
||||
//
|
||||
// this.setState({
|
||||
// modal: 'error',
|
||||
// errorInfo: <ul className="error-modal__error-list">{errorInfoList}</ul>,
|
||||
// });
|
||||
// },
|
||||
// getContentAndAddress: function()
|
||||
// {
|
||||
// switch(this.state.viewingPage)
|
||||
// {
|
||||
// case 'search':
|
||||
// return [this.state.pageArgs ? this.state.pageArgs : "Search", 'icon-search', <SearchPage query={this.state.pageArgs} />];
|
||||
// case 'settings':
|
||||
// return ["Settings", "icon-gear", <SettingsPage />];
|
||||
// case 'help':
|
||||
// return ["Help", "icon-question", <HelpPage />];
|
||||
// case 'report':
|
||||
// return ['Report an Issue', 'icon-file', <ReportPage />];
|
||||
// case 'downloaded':
|
||||
// return ["Downloads & Purchases", "icon-folder", <FileListDownloaded />];
|
||||
// case 'published':
|
||||
// return ["Publishes", "icon-folder", <FileListPublished />];
|
||||
// case 'start':
|
||||
// return ["Start", "icon-file", <StartPage />];
|
||||
// case 'rewards':
|
||||
// return ["Rewards", "icon-bank", <RewardsPage />];
|
||||
// case 'wallet':
|
||||
// case 'send':
|
||||
// case 'receive':
|
||||
// return [this.state.viewingPage.charAt(0).toUpperCase() + this.state.viewingPage.slice(1), "icon-bank", <WalletPage viewingPage={this.state.viewingPage} />]
|
||||
// case 'show':
|
||||
// return [lbryuri.normalize(this.state.pageArgs), "icon-file", <ShowPage uri={this.state.pageArgs} />];
|
||||
// case 'publish':
|
||||
// return ["Publish", "icon-upload", <PublishPage />];
|
||||
// case 'developer':
|
||||
// return ["Developer", "icon-file", <DeveloperPage />];
|
||||
// case 'discover':
|
||||
// default:
|
||||
// return ["Home", "icon-home", <DiscoverPage />];
|
||||
// }
|
||||
// },
|
||||
// render: function() {
|
||||
// let [address, wunderBarIcon, mainContent] = this.getContentAndAddress();
|
||||
//
|
||||
// lbry.setTitle(address);
|
||||
//
|
||||
// if (this._storeHistoryOfNextRender) {
|
||||
// this._storeHistoryOfNextRender = false;
|
||||
// history.pushState({}, document.title, this.state.appUrl);
|
||||
// }
|
||||
//
|
||||
// return (
|
||||
// this._fullScreenPages.includes(this.state.viewingPage) ?
|
||||
// mainContent :
|
||||
// <div id="window">
|
||||
// <Header onSearch={this.onSearch} onSubmit={this.onSubmit} address={address} wunderBarIcon={wunderBarIcon} viewingPage={this.state.viewingPage} />
|
||||
// <div id="main-content">
|
||||
// {mainContent}
|
||||
// </div>
|
||||
// <Modal isOpen={this.state.modal == 'upgrade'} contentLabel="Update available"
|
||||
// type="confirm" confirmButtonLabel="Upgrade" abortButtonLabel="Skip"
|
||||
// onConfirmed={this.handleUpgradeClicked} onAborted={this.handleSkipClicked}>
|
||||
// Your version of LBRY is out of date and may be unreliable or insecure.
|
||||
// </Modal>
|
||||
// <Modal isOpen={this.state.modal == 'downloading'} contentLabel="Downloading Update" type="custom">
|
||||
// Downloading Update{this.state.downloadProgress ? `: ${this.state.downloadProgress}%` : null}
|
||||
// <Line percent={this.state.downloadProgress} strokeWidth="4"/>
|
||||
// {this.state.downloadComplete ? (
|
||||
// <div>
|
||||
// <br />
|
||||
// <p>Click "Begin Upgrade" to start the upgrade process.</p>
|
||||
// <p>The app will close, and you will be prompted to install the latest version of LBRY.</p>
|
||||
// <p>After the install is complete, please reopen the app.</p>
|
||||
// </div>
|
||||
// ) : null }
|
||||
// <div className="modal__buttons">
|
||||
// {this.state.downloadComplete
|
||||
// ? <Link button="primary" label="Begin Upgrade" className="modal__button" onClick={this.handleStartUpgradeClicked} />
|
||||
// : null}
|
||||
// <Link button="alt" label="Cancel" className="modal__button" onClick={this.cancelUpgrade} />
|
||||
// </div>
|
||||
// </Modal>
|
||||
// <ExpandableModal isOpen={this.state.modal == 'error'} contentLabel="Error" className="error-modal"
|
||||
// overlayClassName="error-modal-overlay" onConfirmed={this.closeModal}
|
||||
// extraContent={this.state.errorInfo}>
|
||||
// <h3 className="modal__header">Error</h3>
|
||||
//
|
||||
// <div className="error-modal__content">
|
||||
// <div><img className="error-modal__warning-symbol" src={lbry.imagePath('warning.png')} /></div>
|
||||
// <p>We're sorry that LBRY has encountered an error. This has been reported and we will investigate the problem.</p>
|
||||
// </div>
|
||||
// </ExpandableModal>
|
||||
// </div>
|
||||
// );
|
||||
module.exports = app;
|
|
@ -10,8 +10,6 @@ import {
|
|||
} from 'selectors/app'
|
||||
import {
|
||||
doCheckUpgradeAvailable,
|
||||
doOpenDrawer,
|
||||
doCloseDrawer,
|
||||
doOpenModal,
|
||||
doCloseModal,
|
||||
doSearch,
|
||||
|
@ -21,15 +19,12 @@ import App from './view'
|
|||
const select = (state) => ({
|
||||
currentPage: selectCurrentPage(state),
|
||||
modal: selectCurrentModal(state),
|
||||
drawerOpen: selectDrawerOpen(state),
|
||||
headerLinks: selectHeaderLinks(state),
|
||||
searchTerm: selectSearchTerm(state)
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
checkUpgradeAvailable: () => dispatch(doCheckUpgradeAvailable()),
|
||||
openDrawer: () => dispatch(doOpenDrawer()),
|
||||
closeDrawer: () => dispatch(doCloseDrawer()),
|
||||
openModal: () => dispatch(doOpenModal()),
|
||||
closeModal: () => dispatch(doCloseModal()),
|
||||
})
|
||||
|
|
|
@ -1,26 +1,13 @@
|
|||
import React from 'react'
|
||||
|
||||
import lbry from 'lbry.js';
|
||||
import Router from 'component/router'
|
||||
import Header from 'component/header';
|
||||
import {Modal, ExpandableModal} from 'component/modal.js';
|
||||
import ErrorModal from 'component/errorModal'
|
||||
import DownloadingModal from 'component/downloadingModal'
|
||||
import UpgradeModal from 'component/upgradeModal'
|
||||
import Link from 'component/link';
|
||||
import {Line} from 'rc-progress';
|
||||
|
||||
const App = React.createClass({
|
||||
// Temporary workaround since electron-dl throws errors when you try to get the filename
|
||||
getViewingPageAndArgs: function(address) {
|
||||
// For now, routes are in format ?page or ?page=args
|
||||
let [isMatch, viewingPage, pageArgs] = address.match(/\??([^=]*)(?:=(.*))?/);
|
||||
return {
|
||||
viewingPage: viewingPage,
|
||||
pageArgs: pageArgs === undefined ? null : pageArgs
|
||||
};
|
||||
},
|
||||
componentWillMount: function() {
|
||||
class App extends React.Component {
|
||||
componentWillMount() {
|
||||
document.addEventListener('unhandledError', (event) => {
|
||||
this.props.alertError(event.detail);
|
||||
});
|
||||
|
@ -28,24 +15,20 @@ const App = React.createClass({
|
|||
if (!this.props.upgradeSkipped) {
|
||||
this.props.checkUpgradeAvailable()
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
currentPage,
|
||||
openDrawer,
|
||||
closeDrawer,
|
||||
openModal,
|
||||
closeModal,
|
||||
modal,
|
||||
drawerOpen,
|
||||
headerLinks,
|
||||
search,
|
||||
searchTerm,
|
||||
} = this.props
|
||||
const searchQuery = (currentPage == 'discover' && searchTerm ? searchTerm : '')
|
||||
|
||||
return <div id="window" className={ drawerOpen ? 'drawer-open' : 'drawer-closed' }>
|
||||
<Header onOpenDrawer={openDrawer} initialQuery={searchQuery} onSearch={search} links={headerLinks} />
|
||||
return <div id="window">
|
||||
<Header initialQuery={searchQuery} onSearch={() => { alert('header search'); }}
|
||||
onSubmit={() => { alert('header submit'); }} links={headerLinks} />
|
||||
<div id="main-content">
|
||||
<Router />
|
||||
</div>
|
||||
|
@ -54,6 +37,6 @@ const App = React.createClass({
|
|||
{modal == 'error' && <ErrorModal />}
|
||||
</div>
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default App
|
||||
|
|
|
@ -2,7 +2,8 @@ import React from "react";
|
|||
import lbryio from "../lbryio.js";
|
||||
import Modal from "./modal.js";
|
||||
import ModalPage from "./modal-page.js";
|
||||
import {Link, RewardLink} from "../component/link";
|
||||
import Link from "component/link"
|
||||
import {RewardLink} from 'component/reward-link';
|
||||
import {FormRow} from "../component/form.js";
|
||||
import {CreditAmount, Address} from "../component/common.js";
|
||||
import {getLocal, getSession, setSession, setLocal} from '../utils.js';
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect
|
||||
} from 'react-redux'
|
||||
import Drawer from './view'
|
||||
import {
|
||||
doNavigate,
|
||||
doCloseDrawer,
|
||||
doLogoClick,
|
||||
} from 'actions/app'
|
||||
import {
|
||||
doUpdateBalance,
|
||||
} from 'actions/wallet'
|
||||
import {
|
||||
selectCurrentPage,
|
||||
} from 'selectors/app'
|
||||
import {
|
||||
selectBalance,
|
||||
} from 'selectors/wallet'
|
||||
|
||||
const select = (state) => ({
|
||||
currentPage: selectCurrentPage(state),
|
||||
balance: selectBalance(state),
|
||||
})
|
||||
|
||||
const perform = {
|
||||
linkClick: doNavigate,
|
||||
logoClick: doLogoClick,
|
||||
closeDrawerClick: doCloseDrawer,
|
||||
updateBalance: doUpdateBalance,
|
||||
}
|
||||
|
||||
export default connect(select, perform)(Drawer)
|
|
@ -1,68 +0,0 @@
|
|||
import lbry from 'lbry.js';
|
||||
import React from 'react';
|
||||
import Link from 'component/link';
|
||||
|
||||
const DrawerItem = (props) => {
|
||||
const {
|
||||
currentPage,
|
||||
href,
|
||||
subPages,
|
||||
badge,
|
||||
label,
|
||||
linkClick,
|
||||
icon,
|
||||
} = props
|
||||
const isSelected = (
|
||||
currentPage == href.substr(0) ||
|
||||
(subPages && subPages.indexOf(currentPage) != -1)
|
||||
)
|
||||
|
||||
return <Link icon={icon} badge={badge} label={label} onClick={() => linkClick(href)} className={ 'drawer-item ' + (isSelected ? 'drawer-item-selected' : '') } />
|
||||
}
|
||||
|
||||
var drawerImageStyle = { //@TODO: remove this, img should be properly scaled once size is settled
|
||||
height: '36px'
|
||||
};
|
||||
|
||||
class Drawer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this._balanceSubscribeId = null
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { updateBalance } = this.props
|
||||
|
||||
this._balanceSubscribeId = lbry.balanceSubscribe((balance) => {
|
||||
updateBalance(balance)
|
||||
});
|
||||
}
|
||||
componentWillUnmount() {
|
||||
if (this._balanceSubscribeId) {
|
||||
lbry.balanceUnsubscribe(this._balanceSubscribeId)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
closeDrawerClick,
|
||||
logoClick,
|
||||
balance,
|
||||
} = this.props
|
||||
|
||||
return(<nav id="drawer">
|
||||
<div id="drawer-handle">
|
||||
<Link title="Close" onClick={closeDrawerClick} icon="icon-bars" className="close-drawer-link"/>
|
||||
<a href="discover" onMouseUp={logoClick}><img src={lbry.imagePath("lbry-dark-1600x528.png")} style={drawerImageStyle}/></a>
|
||||
</div>
|
||||
<DrawerItem {...this.props} href='discover' label="Discover" icon="icon-search" />
|
||||
<DrawerItem {...this.props} href='publish' label="Publish" icon="icon-upload" />
|
||||
<DrawerItem {...this.props} href='downloaded' subPages={['published']} label="My Files" icon='icon-cloud-download' />
|
||||
<DrawerItem {...this.props} href="wallet" subPages={['send', 'receive', 'claim']} label="My Wallet" badge={lbry.formatCredits(balance) } icon="icon-bank" />
|
||||
<DrawerItem {...this.props} href='settings' label="Settings" icon='icon-gear' />
|
||||
<DrawerItem {...this.props} href='help' label="Help" icon='icon-question-circle' />
|
||||
</nav>)
|
||||
}
|
||||
}
|
||||
|
||||
export default Drawer;
|
|
@ -3,31 +3,21 @@ import {
|
|||
connect
|
||||
} from 'react-redux'
|
||||
import {
|
||||
selectCurrentPage,
|
||||
selectHeaderLinks,
|
||||
selectPageTitle,
|
||||
} from 'selectors/app'
|
||||
selectBalance
|
||||
} from 'selectors/wallet'
|
||||
import {
|
||||
doNavigate,
|
||||
doHistoryBack,
|
||||
} from 'actions/app'
|
||||
import {
|
||||
doSearchContent,
|
||||
doActivateSearch,
|
||||
doDeactivateSearch,
|
||||
} from 'actions/search'
|
||||
import Header from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
currentPage: selectCurrentPage(state),
|
||||
subLinks: selectHeaderLinks(state),
|
||||
pageTitle: selectPageTitle(state),
|
||||
balance: lbry.formatCredits(selectBalance(state), 1)
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
navigate: (path) => dispatch(doNavigate(path)),
|
||||
search: (query) => dispatch(doSearchContent(query)),
|
||||
activateSearch: () => dispatch(doActivateSearch()),
|
||||
deactivateSearch: () => setTimeout(() => { dispatch(doDeactivateSearch()) }, 50),
|
||||
back: () => dispatch(doHistoryBack()),
|
||||
})
|
||||
|
||||
export default connect(select, perform)(Header)
|
||||
|
|
|
@ -1,193 +1,37 @@
|
|||
import React from 'react';
|
||||
import lbryuri from 'lbryuri.js';
|
||||
import {Icon, CreditAmount} from 'component/common.js';
|
||||
import Link from 'component/link';
|
||||
import WunderBar from 'component/wunderbar';
|
||||
|
||||
let Header = React.createClass({
|
||||
_balanceSubscribeId: null,
|
||||
_isMounted: false,
|
||||
|
||||
propTypes: {
|
||||
onSearch: React.PropTypes.func.isRequired,
|
||||
onSubmit: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
balance: 0
|
||||
};
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this._isMounted = true;
|
||||
this._balanceSubscribeId = lbry.balanceSubscribe((balance) => {
|
||||
if (this._isMounted) {
|
||||
this.setState({balance: balance});
|
||||
}
|
||||
});
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
this._isMounted = false;
|
||||
if (this._balanceSubscribeId) {
|
||||
lbry.balanceUnsubscribe(this._balanceSubscribeId)
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
return <header id="header">
|
||||
<div className="header__item">
|
||||
<Link onClick={() => { lbry.back() }} button="alt button--flat" icon="icon-arrow-left" />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link href="?discover" button="alt button--flat" icon="icon-home" />
|
||||
</div>
|
||||
<div className="header__item header__item--wunderbar">
|
||||
<WunderBar address={this.props.address} icon={this.props.wunderBarIcon}
|
||||
onSearch={this.props.onSearch} onSubmit={this.props.onSubmit} viewingPage={this.props.viewingPage} />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link href="?wallet" button="text" icon="icon-bank" label={lbry.formatCredits(this.state.balance, 1)} ></Link>
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link button="primary button--flat" href="?publish" icon="icon-upload" label="Publish" />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link button="alt button--flat" href="?downloaded" icon="icon-folder" />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link button="alt button--flat" href="?settings" icon="icon-gear" />
|
||||
</div>
|
||||
</header>
|
||||
}
|
||||
});
|
||||
|
||||
class WunderBar extends React.PureComponent {
|
||||
static propTypes = {
|
||||
onSearch: React.PropTypes.func.isRequired,
|
||||
onSubmit: React.PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._userTypingTimer = null;
|
||||
this._input = null;
|
||||
this._stateBeforeSearch = null;
|
||||
this._resetOnNextBlur = true;
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.onFocus = this.onFocus.bind(this);
|
||||
this.onBlur = this.onBlur.bind(this);
|
||||
this.onKeyPress = this.onKeyPress.bind(this);
|
||||
this.onReceiveRef = this.onReceiveRef.bind(this);
|
||||
this.state = {
|
||||
address: this.props.address,
|
||||
icon: this.props.icon
|
||||
};
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.userTypingTimer) {
|
||||
clearTimeout(this._userTypingTimer);
|
||||
}
|
||||
}
|
||||
|
||||
onChange(event) {
|
||||
|
||||
if (this._userTypingTimer)
|
||||
{
|
||||
clearTimeout(this._userTypingTimer);
|
||||
}
|
||||
|
||||
this.setState({ address: event.target.value })
|
||||
|
||||
let searchTerm = event.target.value;
|
||||
|
||||
this._userTypingTimer = setTimeout(() => {
|
||||
this._resetOnNextBlur = false;
|
||||
this.props.onSearch(searchTerm);
|
||||
}, 800); // 800ms delay, tweak for faster/slower
|
||||
}
|
||||
export const Header = (props) => {
|
||||
const {
|
||||
balance,
|
||||
back,
|
||||
navigate
|
||||
} = props
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.viewingPage !== this.props.viewingPage || nextProps.address != this.props.address) {
|
||||
this.setState({ address: nextProps.address, icon: nextProps.icon });
|
||||
}
|
||||
}
|
||||
|
||||
onFocus() {
|
||||
this._stateBeforeSearch = this.state;
|
||||
let newState = {
|
||||
icon: "icon-search",
|
||||
isActive: true
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
newState.address = '';
|
||||
}
|
||||
this.setState(newState);
|
||||
}
|
||||
|
||||
onBlur() {
|
||||
let commonState = {isActive: false};
|
||||
if (this._resetOnNextBlur) {
|
||||
this.setState(Object.assign({}, this._stateBeforeSearch, commonState));
|
||||
this._input.value = this.state.address;
|
||||
} else {
|
||||
this._resetOnNextBlur = true;
|
||||
this._stateBeforeSearch = this.state;
|
||||
this.setState(commonState);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this._input.value = this.state.address;
|
||||
if (this._input && this._focusPending) {
|
||||
this._input.select();
|
||||
this._focusPending = false;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyPress(event) {
|
||||
if (event.charCode == 13 && this._input.value) {
|
||||
|
||||
let uri = null,
|
||||
method = "onSubmit";
|
||||
|
||||
this._resetOnNextBlur = false;
|
||||
clearTimeout(this._userTypingTimer);
|
||||
|
||||
try {
|
||||
uri = lbryuri.normalize(this._input.value);
|
||||
this.setState({ value: uri });
|
||||
} catch (error) { //then it's not a valid URL, so let's search
|
||||
uri = this._input.value;
|
||||
method = "onSearch";
|
||||
}
|
||||
|
||||
this.props[method](uri);
|
||||
this._input.blur();
|
||||
}
|
||||
}
|
||||
|
||||
onReceiveRef(ref) {
|
||||
this._input = ref;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={'wunderbar' + (this.state.isActive ? ' wunderbar--active' : '')}>
|
||||
{this.state.icon ? <Icon fixed icon={this.state.icon} /> : '' }
|
||||
<input className="wunderbar__input" type="search" placeholder="Type a LBRY address or search term"
|
||||
ref={this.onReceiveRef}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
onChange={this.onChange}
|
||||
onKeyPress={this.onKeyPress}
|
||||
value={this.state.address}
|
||||
placeholder="Find movies, music, games, and more" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return <header id="header">
|
||||
<div className="header__item">
|
||||
<Link onClick={back} button="alt button--flat" icon="icon-arrow-left" />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link onClick={() => navigate('discover')} button="alt button--flat" icon="icon-home" />
|
||||
</div>
|
||||
<div className="header__item header__item--wunderbar">
|
||||
<WunderBar/>
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link onClick={() => navigate('wallet')} button="text" icon="icon-bank" label={balance} ></Link>
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link onClick={() => navigate('publish')} button="primary button--flat" icon="icon-upload" label="Publish" />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link onClick={() => navigate('downloaded')} button="alt button--flat" icon="icon-folder" />
|
||||
</div>
|
||||
<div className="header__item">
|
||||
<Link onClick={() => navigate('settings')} button="alt button--flat" icon="icon-gear" />
|
||||
</div>
|
||||
</header>
|
||||
}
|
||||
|
||||
export default Header;
|
||||
|
|
21
ui/js/component/navMain/index.jsx
Normal file
21
ui/js/component/navMain/index.jsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
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)
|
22
ui/js/component/navMain/view.jsx
Normal file
22
ui/js/component/navMain/view.jsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
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
|
7
ui/js/component/navSettings/index.jsx
Normal file
7
ui/js/component/navSettings/index.jsx
Normal file
|
@ -0,0 +1,7 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect,
|
||||
} from 'react-redux'
|
||||
import NavSettings from './view'
|
||||
|
||||
export default connect(null, null)(NavSettings)
|
11
ui/js/component/navSettings/view.jsx
Normal file
11
ui/js/component/navSettings/view.jsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
import React from 'react';
|
||||
import NavMain from 'component/navMain'
|
||||
|
||||
export const NavSettings = () => {
|
||||
return <NavMain links={{
|
||||
'settings': 'Settings',
|
||||
'help' : 'Help'
|
||||
}} />;
|
||||
}
|
||||
|
||||
export default NavSettings
|
7
ui/js/component/navWallet/index.jsx
Normal file
7
ui/js/component/navWallet/index.jsx
Normal file
|
@ -0,0 +1,7 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect,
|
||||
} from 'react-redux'
|
||||
import NavWallet from './view'
|
||||
|
||||
export default connect(null, null)(NavWallet)
|
13
ui/js/component/navWallet/view.jsx
Normal file
13
ui/js/component/navWallet/view.jsx
Normal file
|
@ -0,0 +1,13 @@
|
|||
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,13 +4,15 @@ import HelpPage from 'page/help';
|
|||
import ReportPage from 'page/report.js';
|
||||
import StartPage from 'page/start.js';
|
||||
import WalletPage from 'page/wallet';
|
||||
import ShowPage from 'page/showPage';
|
||||
import FilePage from 'page/filePage';
|
||||
import PublishPage from 'page/publish';
|
||||
import DiscoverPage from 'page/discover';
|
||||
import SplashScreen from 'component/splash.js';
|
||||
import DeveloperPage from 'page/developer.js';
|
||||
import RewardsPage from 'page/rewards.js';
|
||||
import FileListDownloaded from 'page/fileListDownloaded'
|
||||
import FileListPublished from 'page/fileListPublished'
|
||||
import ChannelPage from 'page/channel'
|
||||
|
||||
const route = (page, routesMap) => {
|
||||
const component = routesMap[page]
|
||||
|
@ -34,10 +36,12 @@ const Router = (props) => {
|
|||
'wallet': <WalletPage {...props} />,
|
||||
'send': <WalletPage {...props} />,
|
||||
'receive': <WalletPage {...props} />,
|
||||
'show': <ShowPage {...props} />,
|
||||
'show': <FilePage {...props} />,
|
||||
'channel': <ChannelPage {...props} />,
|
||||
'publish': <PublishPage {...props} />,
|
||||
'developer': <DeveloperPage {...props} />,
|
||||
'discover': <DiscoverPage {...props} />,
|
||||
'rewards': <RewardsPage {...props} />,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
const SubHeader = (props) => {
|
||||
const {
|
||||
subLinks,
|
||||
currentPage,
|
||||
navigate,
|
||||
} = props
|
||||
|
||||
const links = [],
|
||||
viewingUrl = '?' + this.props.viewingPage;
|
||||
|
||||
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" + (this.props.modifier ? ' sub-header--' + this.props.modifier : '')}>{links}</nav>
|
||||
)
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import {SubHeader} from '../component/sub-header.js';
|
||||
|
||||
export let WalletNav = React.createClass({
|
||||
render: function () {
|
||||
return <SubHeader modifier="constrained" viewingPage={this.props.viewingPage} links={{
|
||||
'?wallet': 'Overview',
|
||||
'?send': 'Send',
|
||||
'?receive': 'Receive',
|
||||
'?rewards': 'Rewards'
|
||||
}} />;
|
||||
}
|
||||
});
|
32
ui/js/component/wunderbar/index.js
Normal file
32
ui/js/component/wunderbar/index.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect
|
||||
} from 'react-redux'
|
||||
import {
|
||||
selectWunderBarAddress,
|
||||
selectWunderBarIcon
|
||||
} from 'selectors/app'
|
||||
import {
|
||||
doNavigate,
|
||||
} from 'actions/app'
|
||||
import {
|
||||
doSearchContent,
|
||||
doActivateSearch,
|
||||
doDeactivateSearch,
|
||||
} from 'actions/search'
|
||||
import Wunderbar from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
address: selectWunderBarAddress(state),
|
||||
icon: selectWunderBarIcon(state)
|
||||
})
|
||||
|
||||
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),
|
||||
})
|
||||
|
||||
export default connect(select, perform)(Wunderbar)
|
136
ui/js/component/wunderbar/view.jsx
Normal file
136
ui/js/component/wunderbar/view.jsx
Normal file
|
@ -0,0 +1,136 @@
|
|||
import React from 'react';
|
||||
import lbryuri from 'lbryuri.js';
|
||||
import {Icon} from 'component/common.js';
|
||||
|
||||
class WunderBar extends React.PureComponent {
|
||||
static propTypes = {
|
||||
onSearch: React.PropTypes.func.isRequired,
|
||||
onSubmit: React.PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this._userTypingTimer = null;
|
||||
this._input = null;
|
||||
this._stateBeforeSearch = null;
|
||||
this._resetOnNextBlur = true;
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.onFocus = this.onFocus.bind(this);
|
||||
this.onBlur = this.onBlur.bind(this);
|
||||
this.onKeyPress = this.onKeyPress.bind(this);
|
||||
this.onReceiveRef = this.onReceiveRef.bind(this);
|
||||
this.state = {
|
||||
address: this.props.address,
|
||||
icon: this.props.icon
|
||||
};
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.userTypingTimer) {
|
||||
clearTimeout(this._userTypingTimer);
|
||||
}
|
||||
}
|
||||
|
||||
onChange(event) {
|
||||
|
||||
if (this._userTypingTimer)
|
||||
{
|
||||
clearTimeout(this._userTypingTimer);
|
||||
}
|
||||
|
||||
this.setState({ address: event.target.value })
|
||||
|
||||
let searchTerm = event.target.value;
|
||||
|
||||
this._userTypingTimer = setTimeout(() => {
|
||||
this._resetOnNextBlur = false;
|
||||
this.props.onSearch(searchTerm);
|
||||
}, 800); // 800ms delay, tweak for faster/slower
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.viewingPage !== this.props.viewingPage || nextProps.address != this.props.address) {
|
||||
this.setState({ address: nextProps.address, icon: nextProps.icon });
|
||||
}
|
||||
}
|
||||
|
||||
onFocus() {
|
||||
this._stateBeforeSearch = this.state;
|
||||
let newState = {
|
||||
icon: "icon-search",
|
||||
isActive: true
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
newState.address = '';
|
||||
}
|
||||
this.setState(newState);
|
||||
}
|
||||
|
||||
onBlur() {
|
||||
let commonState = {isActive: false};
|
||||
if (this._resetOnNextBlur) {
|
||||
this.setState(Object.assign({}, this._stateBeforeSearch, commonState));
|
||||
this._input.value = this.state.address;
|
||||
} else {
|
||||
this._resetOnNextBlur = true;
|
||||
this._stateBeforeSearch = this.state;
|
||||
this.setState(commonState);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this._input.value = this.state.address;
|
||||
if (this._input && this._focusPending) {
|
||||
this._input.select();
|
||||
this._focusPending = false;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyPress(event) {
|
||||
if (event.charCode == 13 && this._input.value) {
|
||||
|
||||
let uri = null,
|
||||
method = "onSubmit";
|
||||
|
||||
this._resetOnNextBlur = false;
|
||||
clearTimeout(this._userTypingTimer);
|
||||
|
||||
try {
|
||||
uri = lbryuri.normalize(this._input.value);
|
||||
this.setState({ value: uri });
|
||||
} catch (error) { //then it's not a valid URL, so let's search
|
||||
uri = this._input.value;
|
||||
method = "onSearch";
|
||||
}
|
||||
|
||||
this.props[method](uri);
|
||||
this._input.blur();
|
||||
}
|
||||
}
|
||||
|
||||
onReceiveRef(ref) {
|
||||
this._input = ref;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={'wunderbar' + (this.state.isActive ? ' wunderbar--active' : '')}>
|
||||
{this.state.icon ? <Icon fixed icon={this.state.icon} /> : '' }
|
||||
<input className="wunderbar__input" type="search" placeholder="Type a LBRY address or search term"
|
||||
ref={this.onReceiveRef}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
onChange={this.onChange}
|
||||
onKeyPress={this.onKeyPress}
|
||||
value={this.state.address}
|
||||
placeholder="Find movies, music, games, and more" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default WunderBar;
|
|
@ -1,9 +1,7 @@
|
|||
export const NAVIGATE = 'NAVIGATE'
|
||||
export const OPEN_MODAL = 'OPEN_MODAL'
|
||||
export const CLOSE_MODAL = 'CLOSE_MODAL'
|
||||
|
||||
export const OPEN_DRAWER = 'OPEN_DRAWER'
|
||||
export const CLOSE_DRAWER = 'CLOSE_DRAWER'
|
||||
export const HISTORY_BACK = 'HISTORY_BACK'
|
||||
|
||||
export const DAEMON_READY = 'DAEMON_READY'
|
||||
|
||||
|
|
|
@ -155,10 +155,6 @@ lbry.checkFirstRun = function(callback) {
|
|||
lbry.call('is_first_run', {}, callback);
|
||||
}
|
||||
|
||||
lbry.getNewAddress = function(callback) {
|
||||
lbry.call('wallet_new_address', {}, callback);
|
||||
}
|
||||
|
||||
lbry.getUnusedAddress = function(callback) {
|
||||
lbry.call('wallet_unused_address', {}, callback);
|
||||
}
|
||||
|
@ -174,7 +170,7 @@ lbry.getDaemonSettings = function(callback) {
|
|||
lbry.setDaemonSettings = function(settings, callback) {
|
||||
lbry.call('set_settings', settings, callback);
|
||||
}
|
||||
|
||||
|
||||
lbry.setDaemonSetting = function(setting, value, callback) {
|
||||
var setSettingsArgs = {};
|
||||
setSettingsArgs[setting] = value;
|
||||
|
@ -640,19 +636,19 @@ lbry.claim_list_mine = function(params={}) {
|
|||
});
|
||||
}
|
||||
|
||||
const claimCacheKey = 'resolve_claim_cache';
|
||||
lbry._claimCache = getLocal(claimCacheKey, {});
|
||||
lbry.resolve = function(params={}) {
|
||||
const claimCacheKey = 'resolve_claim_cache',
|
||||
claimCache = getSession(claimCacheKey, {})
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!params.uri) {
|
||||
throw "Resolve has hacked cache on top of it that requires a URI"
|
||||
}
|
||||
if (params.uri && claimCache[params.uri] !== undefined) {
|
||||
resolve(claimCache[params.uri]);
|
||||
if (params.uri && lbry._claimCache[params.uri] !== undefined) {
|
||||
resolve(lbry._claimCache[params.uri]);
|
||||
} else {
|
||||
lbry.call('resolve', params, function(data) {
|
||||
claimCache[params.uri] = data;
|
||||
setSession(claimCacheKey, claimCache)
|
||||
lbry._claimCache[params.uri] = data;
|
||||
setLocal(claimCacheKey, lbry._claimCache)
|
||||
resolve(data)
|
||||
}, reject)
|
||||
}
|
||||
|
@ -660,20 +656,18 @@ lbry.resolve = function(params={}) {
|
|||
}
|
||||
|
||||
// Adds caching.
|
||||
lbry._settingsPromise = null;
|
||||
lbry.settings_get = function(params={}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (params.allow_cached) {
|
||||
const cached = getSession('settings');
|
||||
if (cached) {
|
||||
return resolve(cached);
|
||||
}
|
||||
}
|
||||
|
||||
if (params.allow_cached && lbry._settingsPromise) {
|
||||
return lbry._settingsPromise;
|
||||
}
|
||||
lbry._settingsPromise = new Promise((resolve, reject) => {
|
||||
lbry.call('settings_get', {}, (settings) => {
|
||||
setSession('settings', settings);
|
||||
resolve(settings);
|
||||
});
|
||||
}, reject);
|
||||
});
|
||||
return lbry._settingsPromise;
|
||||
}
|
||||
|
||||
// lbry.get = function(params={}) {
|
||||
|
|
17
ui/js/page/channel/index.js
Normal file
17
ui/js/page/channel/index.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
connect
|
||||
} from 'react-redux'
|
||||
import {
|
||||
selectCurrentUriTitle,
|
||||
} from 'selectors/app'
|
||||
import ChannelPage from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
title: selectCurrentUriTitle(state)
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
})
|
||||
|
||||
export default connect(select, perform)(ChannelPage)
|
22
ui/js/page/channel/view.jsx
Normal file
22
ui/js/page/channel/view.jsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
import React from 'react';
|
||||
|
||||
const ChannelPage = (props) => {
|
||||
const {
|
||||
title
|
||||
} = props
|
||||
|
||||
return <main className="main--single-column">
|
||||
<section className="card">
|
||||
<div className="card__inner">
|
||||
<div className="card__title-identity"><h1>{title}</h1></div>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<p>
|
||||
This channel page is a stub.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
}
|
||||
|
||||
export default ChannelPage;
|
|
@ -3,7 +3,7 @@ import {
|
|||
connect
|
||||
} from 'react-redux'
|
||||
import {
|
||||
selectFeaturedContentByCategory
|
||||
selectFeaturedUris
|
||||
} from 'selectors/content'
|
||||
import {
|
||||
doSearchContent,
|
||||
|
@ -17,11 +17,7 @@ import {
|
|||
import DiscoverPage from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
featuredContentByCategory: selectFeaturedContentByCategory(state),
|
||||
isSearching: selectIsSearching(state),
|
||||
query: selectSearchQuery(state),
|
||||
results: selectCurrentSearchResults(state),
|
||||
searchActive: selectSearchActivated(state),
|
||||
featuredUris: selectFeaturedUris(state),
|
||||
})
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
|
|
|
@ -22,44 +22,65 @@ const FeaturedCategory = (props) => {
|
|||
</div>
|
||||
}
|
||||
|
||||
let DiscoverPage = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {
|
||||
featuredUris: {},
|
||||
failed: false
|
||||
};
|
||||
},
|
||||
componentWillMount: function() {
|
||||
lbryio.call('discover', 'list', { version: "early-access" } ).then(({Categories, Uris}) => {
|
||||
let featuredUris = {}
|
||||
Categories.forEach((category) => {
|
||||
if (Uris[category] && Uris[category].length) {
|
||||
featuredUris[category] = Uris[category]
|
||||
}
|
||||
})
|
||||
this.setState({ featuredUris: featuredUris });
|
||||
}, () => {
|
||||
this.setState({
|
||||
failed: true
|
||||
})
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
return <main>{
|
||||
this.state.failed ?
|
||||
<div className="empty">Failed to load landing content.</div> :
|
||||
<div>
|
||||
{
|
||||
Object.keys(this.state.featuredUris).map((category) => {
|
||||
return this.state.featuredUris[category].length ?
|
||||
<FeaturedCategory key={category} category={category} names={this.state.featuredUris[category]} /> :
|
||||
'';
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}</main>;
|
||||
}
|
||||
})
|
||||
const DiscoverPage = (props) => {
|
||||
const {
|
||||
featuredUris
|
||||
} = props
|
||||
|
||||
return <main>{
|
||||
Object.keys(featuredUris).length === 0 ?
|
||||
<div className="empty">Failed to load landing content.</div> :
|
||||
<div>
|
||||
{
|
||||
Object.keys(featuredUris).map((category) => {
|
||||
return featuredUris[category].length ?
|
||||
<FeaturedCategory key={category} category={category} names={featuredUris[category]} /> :
|
||||
'';
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}</main>
|
||||
}
|
||||
|
||||
//
|
||||
// let DiscoverPage = React.createClass({
|
||||
// getInitialState: function() {
|
||||
// return {
|
||||
// featuredUris: {},
|
||||
// failed: false
|
||||
// };
|
||||
// },
|
||||
// componentWillMount: function() {
|
||||
// lbryio.call('discover', 'list', { version: "early-access" } ).then(({Categories, Uris}) => {
|
||||
// let featuredUris = {}
|
||||
// Categories.forEach((category) => {
|
||||
// if (Uris[category] && Uris[category].length) {
|
||||
// featuredUris[category] = Uris[category]
|
||||
// }
|
||||
// })
|
||||
// this.setState({ featuredUris: featuredUris });
|
||||
// }, () => {
|
||||
// this.setState({
|
||||
// failed: true
|
||||
// })
|
||||
// });
|
||||
// },
|
||||
// render: function() {
|
||||
// return <main>{
|
||||
// this.state.failed ?
|
||||
// <div className="empty">Failed to load landing content.</div> :
|
||||
// <div>
|
||||
// {
|
||||
// Object.keys(this.state.featuredUris).map((category) => {
|
||||
// return this.state.featuredUris[category].length ?
|
||||
// <FeaturedCategory key={category} category={category} names={this.state.featuredUris[category]} /> :
|
||||
// '';
|
||||
// })
|
||||
// }
|
||||
// </div>
|
||||
// }</main>;
|
||||
// }
|
||||
// })
|
||||
|
||||
// const DiscoverPage = (props) => {
|
||||
// const {
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
import {
|
||||
selectCurrentUriCostInfo,
|
||||
} from 'selectors/cost_info'
|
||||
import ShowPage from './view'
|
||||
import FilePage from './view'
|
||||
|
||||
const select = (state) => ({
|
||||
claim: selectCurrentUriClaim(state),
|
||||
|
@ -30,4 +30,4 @@ const select = (state) => ({
|
|||
const perform = (dispatch) => ({
|
||||
})
|
||||
|
||||
export default connect(select, perform)(ShowPage)
|
||||
export default connect(select, perform)(FilePage)
|
|
@ -16,27 +16,20 @@ import UriIndicator from 'component/uriIndicator';
|
|||
const FormatItem = (props) => {
|
||||
const {
|
||||
contentType,
|
||||
metadata,
|
||||
metadata: {
|
||||
thumbnail,
|
||||
author,
|
||||
title,
|
||||
description,
|
||||
language,
|
||||
license,
|
||||
},
|
||||
cost,
|
||||
uri,
|
||||
outpoint,
|
||||
costIncludesData,
|
||||
}
|
||||
} = props
|
||||
|
||||
const mediaType = lbry.getMediaType(contentType);
|
||||
|
||||
return (
|
||||
<table className="table-standard">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Content-Type</td><td>{contentType}</td>
|
||||
<td>Content-Type</td><td>{mediaType}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Author</td><td>{author}</td>
|
||||
|
@ -52,23 +45,6 @@ const FormatItem = (props) => {
|
|||
)
|
||||
}
|
||||
|
||||
let ChannelPage = React.createClass({
|
||||
render: function() {
|
||||
return <main className="main--single-column">
|
||||
<section className="card">
|
||||
<div className="card__inner">
|
||||
<div className="card__title-identity"><h1>{this.props.title}</h1></div>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<p>
|
||||
This channel page is a stub.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
}
|
||||
});
|
||||
|
||||
let FilePage = React.createClass({
|
||||
_isMounted: false,
|
||||
|
||||
|
@ -267,8 +243,6 @@ let ShowPage = React.createClass({
|
|||
}
|
||||
</div>
|
||||
</section>;
|
||||
} else if (this.state.claimType == "channel") {
|
||||
innerContent = <ChannelPage title={this._uri} />
|
||||
} else {
|
||||
let channelUriObj = lbryuri.parse(this._uri)
|
||||
delete channelUriObj.path;
|
||||
|
@ -289,4 +263,105 @@ let ShowPage = React.createClass({
|
|||
}
|
||||
});
|
||||
|
||||
export default ShowPage;
|
||||
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,6 +2,7 @@
|
|||
import React from 'react';
|
||||
import lbry from 'lbry.js';
|
||||
import Link from 'component/link';
|
||||
import NavSettings from 'component/navSettings';
|
||||
import {version as uiVersion} from 'json!../../../package.json';
|
||||
|
||||
var HelpPage = React.createClass({
|
||||
|
@ -49,58 +50,71 @@ var HelpPage = React.createClass({
|
|||
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<NavSettings />
|
||||
<section className="card">
|
||||
<h3>Read the FAQ</h3>
|
||||
<p>Our FAQ answers many common questions.</p>
|
||||
<p><Link href="https://lbry.io/faq" label="Read the FAQ" icon="icon-question" button="alt"/></p>
|
||||
<div className="card__title-primary">
|
||||
<h3>Read the FAQ</h3>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<p>Our FAQ answers many common questions.</p>
|
||||
<p><Link href="https://lbry.io/faq" label="Read the FAQ" icon="icon-question" button="alt"/></p>
|
||||
</div>
|
||||
</section>
|
||||
<section className="card">
|
||||
<h3>Get Live Help</h3>
|
||||
<p>
|
||||
Live help is available most hours in the <strong>#help</strong> channel of our Slack chat room.
|
||||
</p>
|
||||
<p>
|
||||
<Link button="alt" label="Join Our Slack" icon="icon-slack" href="https://slack.lbry.io" />
|
||||
</p>
|
||||
<div className="card__title-primary">
|
||||
<h3>Get Live Help</h3>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<p>
|
||||
Live help is available most hours in the <strong>#help</strong> channel of our Slack chat room.
|
||||
</p>
|
||||
<p>
|
||||
<Link button="alt" label="Join Our Slack" icon="icon-slack" href="https://slack.lbry.io" />
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<section className="card">
|
||||
<h3>Report a Bug</h3>
|
||||
<p>Did you find something wrong?</p>
|
||||
<p><Link href="?report" label="Submit a Bug Report" icon="icon-bug" button="alt" /></p>
|
||||
<div className="meta">Thanks! LBRY is made by its users.</div>
|
||||
<div className="card__title-primary"><h3>Report a Bug</h3></div>
|
||||
<div className="card__content">
|
||||
<p>Did you find something wrong?</p>
|
||||
<p><Link href="?report" label="Submit a Bug Report" icon="icon-bug" button="alt" /></p>
|
||||
<div className="meta">Thanks! LBRY is made by its users.</div>
|
||||
</div>
|
||||
</section>
|
||||
{!ver ? null :
|
||||
<section className="card">
|
||||
<h3>About</h3>
|
||||
{ver.lbrynet_update_available || ver.lbryum_update_available ?
|
||||
<section className="card">
|
||||
<div className="card__title-primary"><h3>About</h3></div>
|
||||
<div className="card__content">
|
||||
{ver.lbrynet_update_available || ver.lbryum_update_available ?
|
||||
<p>A newer version of LBRY is available. <Link href={newVerLink} label={`Download LBRY ${ver.remote_lbrynet} now!`} /></p>
|
||||
: <p>Your copy of LBRY is up to date.</p>
|
||||
}
|
||||
<table className="table-standard">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>daemon (lbrynet)</th>
|
||||
<td>{ver.lbrynet_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>wallet (lbryum)</th>
|
||||
<td>{ver.lbryum_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>interface</th>
|
||||
<td>{uiVersion}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Platform</th>
|
||||
<td>{platform}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Installation ID</th>
|
||||
<td>{this.state.lbryId}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
: <p>Your copy of LBRY is up to date.</p>
|
||||
}
|
||||
<table className="table-standard">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>daemon (lbrynet)</th>
|
||||
<td>{ver.lbrynet_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>wallet (lbryum)</th>
|
||||
<td>{ver.lbryum_version}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>interface</th>
|
||||
<td>{uiVersion}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Platform</th>
|
||||
<td>{platform}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Installation ID</th>
|
||||
<td>{this.state.lbryId}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
</main>
|
||||
);
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import React from 'react';
|
||||
import lbry from 'lbry';
|
||||
import lbryio from 'lbryio';
|
||||
import {CreditAmount, Icon} from 'component/common.js';
|
||||
import rewards from 'rewards';
|
||||
import Modal from 'component/modal';
|
||||
import {WalletNav} from 'component/wallet-nav ewar';
|
||||
import NavWallet from 'component/navWallet';
|
||||
import {RewardLink} from 'component/reward-link';
|
||||
|
||||
const RewardTile = React.createClass({
|
||||
|
@ -36,7 +33,7 @@ const RewardTile = React.createClass({
|
|||
}
|
||||
});
|
||||
|
||||
var RewardsPage = React.createClass({
|
||||
export let RewardsPage = React.createClass({
|
||||
componentWillMount: function() {
|
||||
this.loadRewards()
|
||||
},
|
||||
|
@ -58,7 +55,7 @@ var RewardsPage = React.createClass({
|
|||
render: function() {
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<WalletNav viewingPage="rewards"/>
|
||||
<NavWallet />
|
||||
<div>
|
||||
{!this.state.userRewards
|
||||
? (this.state.failed ? <div className="empty">Failed to load rewards.</div> : '')
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
import React from 'react';
|
||||
import {FormField, FormRow} from '../component/form.js';
|
||||
import {SubHeader} from '../component/sub-header.js';
|
||||
import NavSettings from 'component/navSettings';
|
||||
import lbry from '../lbry.js';
|
||||
|
||||
export let SettingsNav = React.createClass({
|
||||
render: function() {
|
||||
return <SubHeader modifier="constrained" viewingPage={this.props.viewingPage} links={{
|
||||
'?settings': 'Settings',
|
||||
'?help' : 'Help'
|
||||
}} />;
|
||||
}
|
||||
});
|
||||
|
||||
var SettingsPage = React.createClass({
|
||||
_onSettingSaveSuccess: function() {
|
||||
// This is bad.
|
||||
|
@ -100,7 +91,7 @@ var SettingsPage = React.createClass({
|
|||
*/
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<SettingsNav viewingPage="settings" />
|
||||
<NavSettings />
|
||||
<section className="card">
|
||||
<div className="card__content">
|
||||
<h3>Download Directory</h3>
|
||||
|
|
|
@ -2,6 +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 {
|
||||
FormField,
|
||||
FormRow
|
||||
|
@ -247,6 +248,7 @@ const WalletPage = (props) => {
|
|||
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<NavWallet />
|
||||
<section className="card">
|
||||
<div className="card__title-primary">
|
||||
<h3>Balance</h3>
|
||||
|
|
|
@ -6,7 +6,6 @@ const defaultState = {
|
|||
isLoaded: false,
|
||||
currentPath: 'discover',
|
||||
platform: process.platform,
|
||||
drawerOpen: sessionStorage.getItem('drawerOpen') || true,
|
||||
upgradeSkipped: sessionStorage.getItem('upgradeSkipped'),
|
||||
daemonReady: false,
|
||||
platform: window.navigator.platform,
|
||||
|
@ -84,20 +83,6 @@ reducers[types.CLOSE_MODAL] = function(state, action) {
|
|||
})
|
||||
}
|
||||
|
||||
reducers[types.OPEN_DRAWER] = function(state, action) {
|
||||
sessionStorage.setItem('drawerOpen', false)
|
||||
return Object.assign({}, state, {
|
||||
drawerOpen: true
|
||||
})
|
||||
}
|
||||
|
||||
reducers[types.CLOSE_DRAWER] = function(state, action) {
|
||||
sessionStorage.setItem('drawerOpen', false)
|
||||
return Object.assign({}, state, {
|
||||
drawerOpen: false
|
||||
})
|
||||
}
|
||||
|
||||
reducers[types.UPGRADE_DOWNLOAD_PROGRESSED] = function(state, action) {
|
||||
return Object.assign({}, state, {
|
||||
downloadProgress: action.data.percent
|
||||
|
|
|
@ -12,15 +12,15 @@ reducers[types.FETCH_FEATURED_CONTENT_STARTED] = function(state, action) {
|
|||
|
||||
reducers[types.FETCH_FEATURED_CONTENT_COMPLETED] = function(state, action) {
|
||||
const {
|
||||
uris
|
||||
uris,
|
||||
success
|
||||
} = action.data
|
||||
const newFeaturedContent = Object.assign({}, state.featuredContent, {
|
||||
byCategory: uris,
|
||||
})
|
||||
|
||||
|
||||
return Object.assign({}, state, {
|
||||
fetchingFeaturedContent: false,
|
||||
featuredContent: newFeaturedContent
|
||||
fetchingFeaturedContentFailed: !success,
|
||||
featuredUris: uris
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ rewards.claimReward = function (type) {
|
|||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
lbry.wallet_new_address().then((address) => {
|
||||
lbry.wallet_unused_address().then((address) => {
|
||||
const params = {
|
||||
reward_type: type,
|
||||
wallet_address: address,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { createSelector } from 'reselect'
|
||||
import {createSelector} from 'reselect'
|
||||
|
||||
export const _selectState = state => state.app || {}
|
||||
|
||||
|
@ -22,35 +22,98 @@ export const selectCurrentUri = createSelector(
|
|||
(path) => {
|
||||
if (path.match(/=/)) {
|
||||
return path.split('=')[1]
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const selectCurrentUriTitle = createSelector(
|
||||
_selectState,
|
||||
(state) => "fix me"
|
||||
)
|
||||
|
||||
export const selectPageTitle = createSelector(
|
||||
selectCurrentPage,
|
||||
selectCurrentUri,
|
||||
(page, uri) => {
|
||||
switch(page)
|
||||
{
|
||||
case 'discover':
|
||||
return 'Discover'
|
||||
switch (page) {
|
||||
case 'search':
|
||||
return 'Search'
|
||||
case 'settings':
|
||||
return 'Settings'
|
||||
case 'help':
|
||||
return 'Help'
|
||||
case 'report':
|
||||
return 'Report'
|
||||
case 'wallet':
|
||||
case 'send':
|
||||
case 'receive':
|
||||
case 'rewards':
|
||||
return 'Wallet'
|
||||
return page.charAt(0).toUpperCase() + page.slice(1)
|
||||
case 'show':
|
||||
return lbryuri.normalize(page)
|
||||
case 'downloaded':
|
||||
return 'My Files'
|
||||
return 'Downloads & Purchases'
|
||||
case 'published':
|
||||
return 'My Files'
|
||||
return 'Publishes'
|
||||
case 'start':
|
||||
return 'Start'
|
||||
case 'publish':
|
||||
return 'Publish'
|
||||
case 'help':
|
||||
return 'Help'
|
||||
case 'developer':
|
||||
return 'Developer'
|
||||
case 'discover':
|
||||
return 'Home'
|
||||
default:
|
||||
return 'LBRY';
|
||||
return '';
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const selectWunderBarAddress = createSelector(
|
||||
selectPageTitle,
|
||||
(title) => title
|
||||
)
|
||||
|
||||
export const selectWunderBarIcon = createSelector(
|
||||
selectCurrentPage,
|
||||
selectCurrentUri,
|
||||
(page, uri) => {
|
||||
switch (page) {
|
||||
case 'search':
|
||||
return 'icon-search'
|
||||
case 'settings':
|
||||
return 'icon-gear'
|
||||
case 'help':
|
||||
return 'icon-question'
|
||||
case 'report':
|
||||
return 'icon-file'
|
||||
case 'downloaded':
|
||||
return 'icon-folder'
|
||||
case 'published':
|
||||
return 'icon-folder'
|
||||
case 'start':
|
||||
return 'icon-file'
|
||||
case 'rewards':
|
||||
return 'icon-bank'
|
||||
case 'wallet':
|
||||
case 'send':
|
||||
case 'receive':
|
||||
return 'icon-bank'
|
||||
case 'show':
|
||||
return 'icon-file'
|
||||
case 'publish':
|
||||
return 'icon-upload'
|
||||
case 'developer':
|
||||
return 'icon-file'
|
||||
case 'developer':
|
||||
return 'icon-code'
|
||||
case 'discover':
|
||||
return 'icon-home'
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -115,24 +178,18 @@ export const selectDownloadComplete = createSelector(
|
|||
(state) => state.upgradeDownloadCompleted
|
||||
)
|
||||
|
||||
export const selectDrawerOpen = createSelector(
|
||||
_selectState,
|
||||
(state) => state.drawerOpen
|
||||
)
|
||||
|
||||
export const selectHeaderLinks = createSelector(
|
||||
selectCurrentPage,
|
||||
(page) => {
|
||||
switch(page)
|
||||
{
|
||||
switch (page) {
|
||||
case 'wallet':
|
||||
case 'send':
|
||||
case 'receive':
|
||||
case 'rewards':
|
||||
return {
|
||||
'wallet' : 'Overview',
|
||||
'send' : 'Send',
|
||||
'receive' : 'Receive',
|
||||
'wallet': 'Overview',
|
||||
'send': 'Send',
|
||||
'receive': 'Receive',
|
||||
'rewards': 'Rewards',
|
||||
};
|
||||
case 'downloaded':
|
||||
|
|
|
@ -7,26 +7,21 @@ import {
|
|||
|
||||
export const _selectState = state => state.content || {}
|
||||
|
||||
export const selectFeaturedContent = createSelector(
|
||||
export const selectFeaturedUris = createSelector(
|
||||
_selectState,
|
||||
(state) => state.featuredContent || {}
|
||||
(state) => state.featuredUris || {}
|
||||
)
|
||||
|
||||
export const selectFeaturedContentByCategory = createSelector(
|
||||
selectFeaturedContent,
|
||||
(featuredContent) => featuredContent.byCategory || {}
|
||||
)
|
||||
|
||||
export const selectFetchingFeaturedContent = createSelector(
|
||||
export const selectFetchingFeaturedUris = createSelector(
|
||||
_selectState,
|
||||
(state) => !!state.fetchingFeaturedContent
|
||||
)
|
||||
|
||||
export const shouldFetchFeaturedContent = createSelector(
|
||||
export const shouldFetchFeaturedUris = createSelector(
|
||||
selectDaemonReady,
|
||||
selectCurrentPage,
|
||||
selectFetchingFeaturedContent,
|
||||
selectFeaturedContentByCategory,
|
||||
selectFetchingFeaturedUris,
|
||||
selectFeaturedUris,
|
||||
(daemonReady, page, fetching, byCategory) => {
|
||||
if (!daemonReady) return false
|
||||
if (page != 'discover') return false
|
||||
|
|
|
@ -3,7 +3,7 @@ import {
|
|||
shouldGetReceiveAddress,
|
||||
} from 'selectors/wallet'
|
||||
import {
|
||||
shouldFetchFeaturedContent,
|
||||
shouldFetchFeaturedUris,
|
||||
shouldFetchDownloadedContent,
|
||||
shouldFetchPublishedContent,
|
||||
} from 'selectors/content'
|
||||
|
@ -21,7 +21,7 @@ import {
|
|||
doGetNewAddress,
|
||||
} from 'actions/wallet'
|
||||
import {
|
||||
doFetchFeaturedContent,
|
||||
doFetchFeaturedUris,
|
||||
doFetchDownloadedContent,
|
||||
doFetchPublishedContent,
|
||||
} from 'actions/content'
|
||||
|
@ -48,8 +48,8 @@ triggers.push({
|
|||
})
|
||||
|
||||
triggers.push({
|
||||
selector: shouldFetchFeaturedContent,
|
||||
action: doFetchFeaturedContent,
|
||||
selector: shouldFetchFeaturedUris,
|
||||
action: doFetchFeaturedUris,
|
||||
})
|
||||
|
||||
triggers.push({
|
||||
|
|
|
@ -60,11 +60,9 @@ nav.sub-header
|
|||
{
|
||||
text-transform: uppercase;
|
||||
padding: 0 0 $spacing-vertical;
|
||||
&.sub-header--constrained {
|
||||
max-width: $width-page-constrained;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
max-width: $width-page-constrained;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
> a
|
||||
{
|
||||
$sub-header-selected-underline-height: 2px;
|
||||
|
|
Loading…
Add table
Reference in a new issue