From 36a992343f56a3f85ae7459c685cdfe56bd6193c Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Wed, 3 May 2017 23:44:08 -0400 Subject: [PATCH] much progress towards a working merge --- CHANGELOG.md | 1 - ui/js/actions/app.js | 28 +- ui/js/actions/content.js | 20 +- ui/js/actions/wallet.js | 1 + ui/js/app.js | 320 +-------------------- ui/js/component/app/index.js | 5 - ui/js/component/app/view.jsx | 35 +-- ui/js/component/auth.js | 3 +- ui/js/component/drawer/index.jsx | 33 --- ui/js/component/drawer/view.jsx | 68 ----- ui/js/component/header/index.js | 20 +- ui/js/component/header/view.jsx | 216 ++------------ ui/js/component/navMain/index.jsx | 21 ++ ui/js/component/navMain/view.jsx | 22 ++ ui/js/component/navSettings/index.jsx | 7 + ui/js/component/navSettings/view.jsx | 11 + ui/js/component/navWallet/index.jsx | 7 + ui/js/component/navWallet/view.jsx | 13 + ui/js/component/router/view.jsx | 8 +- ui/js/component/sub-header.js | 22 -- ui/js/component/wallet-nav.js | 12 - ui/js/component/wunderbar/index.js | 32 +++ ui/js/component/wunderbar/view.jsx | 136 +++++++++ ui/js/constants/action_types.js | 4 +- ui/js/lbry.js | 34 +-- ui/js/page/channel/index.js | 17 ++ ui/js/page/channel/view.jsx | 22 ++ ui/js/page/discover/index.js | 8 +- ui/js/page/discover/view.jsx | 97 ++++--- ui/js/page/{showPage => filePage}/index.js | 4 +- ui/js/page/{showPage => filePage}/view.jsx | 135 +++++++-- ui/js/page/help/view.jsx | 102 ++++--- ui/js/page/rewards.js | 9 +- ui/js/page/settings.js | 13 +- ui/js/page/wallet/view.jsx | 2 + ui/js/reducers/app.js | 15 - ui/js/reducers/content.js | 10 +- ui/js/rewards.js | 2 +- ui/js/selectors/app.js | 97 +++++-- ui/js/selectors/content.js | 17 +- ui/js/triggers.js | 8 +- ui/scss/component/_header.scss | 8 +- 42 files changed, 713 insertions(+), 932 deletions(-) delete mode 100644 ui/js/component/drawer/index.jsx delete mode 100644 ui/js/component/drawer/view.jsx create mode 100644 ui/js/component/navMain/index.jsx create mode 100644 ui/js/component/navMain/view.jsx create mode 100644 ui/js/component/navSettings/index.jsx create mode 100644 ui/js/component/navSettings/view.jsx create mode 100644 ui/js/component/navWallet/index.jsx create mode 100644 ui/js/component/navWallet/view.jsx delete mode 100644 ui/js/component/sub-header.js delete mode 100644 ui/js/component/wallet-nav.js create mode 100644 ui/js/component/wunderbar/index.js create mode 100644 ui/js/component/wunderbar/view.jsx create mode 100644 ui/js/page/channel/index.js create mode 100644 ui/js/page/channel/view.jsx rename ui/js/page/{showPage => filePage}/index.js (89%) rename ui/js/page/{showPage => filePage}/view.jsx (69%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54c22c93c..72cb1ce2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js index d2c7679f3..1f384cbd5 100644 --- a/ui/js/actions/app.js +++ b/ui/js/actions/app.js @@ -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' } }) - }); + } }); } } diff --git a/ui/js/actions/content.js b/ui/js/actions/content.js index fb24a0458..76622b84b 100644 --- a/ui/js/actions/content.js +++ b/ui/js/actions/content.js @@ -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" } ) diff --git a/ui/js/actions/wallet.js b/ui/js/actions/wallet.js index 79b22d8d6..1faae7a5d 100644 --- a/ui/js/actions/wallet.js +++ b/ui/js/actions/wallet.js @@ -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({ diff --git a/ui/js/app.js b/ui/js/app.js index 88ad0eef8..51e097da2 100644 --- a/ui/js/app.js +++ b/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(
  • {label}: {val}
  • ); -// } -// -// this.setState({ -// modal: 'error', -// errorInfo: , -// }); -// }, -// getContentAndAddress: function() -// { -// switch(this.state.viewingPage) -// { -// case 'search': -// return [this.state.pageArgs ? this.state.pageArgs : "Search", 'icon-search', ]; -// case 'settings': -// return ["Settings", "icon-gear", ]; -// case 'help': -// return ["Help", "icon-question", ]; -// case 'report': -// return ['Report an Issue', 'icon-file', ]; -// case 'downloaded': -// return ["Downloads & Purchases", "icon-folder", ]; -// case 'published': -// return ["Publishes", "icon-folder", ]; -// case 'start': -// return ["Start", "icon-file", ]; -// case 'rewards': -// return ["Rewards", "icon-bank", ]; -// case 'wallet': -// case 'send': -// case 'receive': -// return [this.state.viewingPage.charAt(0).toUpperCase() + this.state.viewingPage.slice(1), "icon-bank", ] -// case 'show': -// return [lbryuri.normalize(this.state.pageArgs), "icon-file", ]; -// case 'publish': -// return ["Publish", "icon-upload", ]; -// case 'developer': -// return ["Developer", "icon-file", ]; -// case 'discover': -// default: -// return ["Home", "icon-home", ]; -// } -// }, -// 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 : -//
    -//
    -//
    -// {mainContent} -//
    -// -// Your version of LBRY is out of date and may be unreliable or insecure. -// -// -// Downloading Update{this.state.downloadProgress ? `: ${this.state.downloadProgress}%` : null} -// -// {this.state.downloadComplete ? ( -//
    -//
    -//

    Click "Begin Upgrade" to start the upgrade process.

    -//

    The app will close, and you will be prompted to install the latest version of LBRY.

    -//

    After the install is complete, please reopen the app.

    -//
    -// ) : null } -//
    -// {this.state.downloadComplete -// ? -// : null} -// -//
    -//
    -// -//

    Error

    -// -//
    -//
    -//

    We're sorry that LBRY has encountered an error. This has been reported and we will investigate the problem.

    -//
    -//
    -//
    -// ); \ No newline at end of file +module.exports = app; \ No newline at end of file diff --git a/ui/js/component/app/index.js b/ui/js/component/app/index.js index 0920e51d8..95ca69761 100644 --- a/ui/js/component/app/index.js +++ b/ui/js/component/app/index.js @@ -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()), }) diff --git a/ui/js/component/app/view.jsx b/ui/js/component/app/view.jsx index 944547044..92cb7d662 100644 --- a/ui/js/component/app/view.jsx +++ b/ui/js/component/app/view.jsx @@ -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
    -
    + return
    +
    { alert('header search'); }} + onSubmit={() => { alert('header submit'); }} links={headerLinks} />
    @@ -54,6 +37,6 @@ const App = React.createClass({ {modal == 'error' && }
    } -}); +} export default App diff --git a/ui/js/component/auth.js b/ui/js/component/auth.js index 2575d2e9c..261b065b1 100644 --- a/ui/js/component/auth.js +++ b/ui/js/component/auth.js @@ -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'; diff --git a/ui/js/component/drawer/index.jsx b/ui/js/component/drawer/index.jsx deleted file mode 100644 index 3c4c524b0..000000000 --- a/ui/js/component/drawer/index.jsx +++ /dev/null @@ -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) diff --git a/ui/js/component/drawer/view.jsx b/ui/js/component/drawer/view.jsx deleted file mode 100644 index da65cd523..000000000 --- a/ui/js/component/drawer/view.jsx +++ /dev/null @@ -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 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() - } -} - -export default Drawer; diff --git a/ui/js/component/header/index.js b/ui/js/component/header/index.js index 44efdc355..2a10b5e81 100644 --- a/ui/js/component/header/index.js +++ b/ui/js/component/header/index.js @@ -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) diff --git a/ui/js/component/header/view.jsx b/ui/js/component/header/view.jsx index 92a45cad9..0707b7e10 100644 --- a/ui/js/component/header/view.jsx +++ b/ui/js/component/header/view.jsx @@ -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 - } -}); - -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 ( -
    - {this.state.icon ? : '' } - -
    - ); - } + return } export default Header; diff --git a/ui/js/component/navMain/index.jsx b/ui/js/component/navMain/index.jsx new file mode 100644 index 000000000..2c27c39a5 --- /dev/null +++ b/ui/js/component/navMain/index.jsx @@ -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) diff --git a/ui/js/component/navMain/view.jsx b/ui/js/component/navMain/view.jsx new file mode 100644 index 000000000..f10f07a6b --- /dev/null +++ b/ui/js/component/navMain/view.jsx @@ -0,0 +1,22 @@ +import React from 'react'; + +export const NavMain = (props) => { + const { + links, + currentPage, + navigate, + } = props + + return ( + + ) +} + +export default NavMain \ No newline at end of file diff --git a/ui/js/component/navSettings/index.jsx b/ui/js/component/navSettings/index.jsx new file mode 100644 index 000000000..9fb7efb4d --- /dev/null +++ b/ui/js/component/navSettings/index.jsx @@ -0,0 +1,7 @@ +import React from 'react' +import { + connect, +} from 'react-redux' +import NavSettings from './view' + +export default connect(null, null)(NavSettings) diff --git a/ui/js/component/navSettings/view.jsx b/ui/js/component/navSettings/view.jsx new file mode 100644 index 000000000..099e2acae --- /dev/null +++ b/ui/js/component/navSettings/view.jsx @@ -0,0 +1,11 @@ +import React from 'react'; +import NavMain from 'component/navMain' + +export const NavSettings = () => { + return ; +} + +export default NavSettings \ No newline at end of file diff --git a/ui/js/component/navWallet/index.jsx b/ui/js/component/navWallet/index.jsx new file mode 100644 index 000000000..4ace4d388 --- /dev/null +++ b/ui/js/component/navWallet/index.jsx @@ -0,0 +1,7 @@ +import React from 'react' +import { + connect, +} from 'react-redux' +import NavWallet from './view' + +export default connect(null, null)(NavWallet) diff --git a/ui/js/component/navWallet/view.jsx b/ui/js/component/navWallet/view.jsx new file mode 100644 index 000000000..c076e9c67 --- /dev/null +++ b/ui/js/component/navWallet/view.jsx @@ -0,0 +1,13 @@ +import React from 'react'; +import NavMain from 'component/navMain' + +export const NavWallet = () => { + return +} + +export default NavWallet \ No newline at end of file diff --git a/ui/js/component/router/view.jsx b/ui/js/component/router/view.jsx index 78246c0b6..f8b4c300b 100644 --- a/ui/js/component/router/view.jsx +++ b/ui/js/component/router/view.jsx @@ -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': , 'send': , 'receive': , - 'show': , + 'show': , + 'channel': , 'publish': , 'developer': , 'discover': , + 'rewards': , }) } diff --git a/ui/js/component/sub-header.js b/ui/js/component/sub-header.js deleted file mode 100644 index 061b0e942..000000000 --- a/ui/js/component/sub-header.js +++ /dev/null @@ -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( - navigate(link)} key={link} className={link == currentPage ? 'sub-header-selected' : 'sub-header-unselected' }> - {subLinks[link]} - - ); - } - - return ( - - ) -} \ No newline at end of file diff --git a/ui/js/component/wallet-nav.js b/ui/js/component/wallet-nav.js deleted file mode 100644 index 51cd9278b..000000000 --- a/ui/js/component/wallet-nav.js +++ /dev/null @@ -1,12 +0,0 @@ -import {SubHeader} from '../component/sub-header.js'; - -export let WalletNav = React.createClass({ - render: function () { - return ; - } -}); \ No newline at end of file diff --git a/ui/js/component/wunderbar/index.js b/ui/js/component/wunderbar/index.js new file mode 100644 index 000000000..85551e637 --- /dev/null +++ b/ui/js/component/wunderbar/index.js @@ -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) diff --git a/ui/js/component/wunderbar/view.jsx b/ui/js/component/wunderbar/view.jsx new file mode 100644 index 000000000..821e9bfc0 --- /dev/null +++ b/ui/js/component/wunderbar/view.jsx @@ -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 ( +
    + {this.state.icon ? : '' } + +
    + ); + } +} + +export default WunderBar; diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index 80eecab79..14f6c7b88 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -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' diff --git a/ui/js/lbry.js b/ui/js/lbry.js index 5fd96595a..b5238764e 100644 --- a/ui/js/lbry.js +++ b/ui/js/lbry.js @@ -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={}) { diff --git a/ui/js/page/channel/index.js b/ui/js/page/channel/index.js new file mode 100644 index 000000000..50100b244 --- /dev/null +++ b/ui/js/page/channel/index.js @@ -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) diff --git a/ui/js/page/channel/view.jsx b/ui/js/page/channel/view.jsx new file mode 100644 index 000000000..587c7237e --- /dev/null +++ b/ui/js/page/channel/view.jsx @@ -0,0 +1,22 @@ +import React from 'react'; + +const ChannelPage = (props) => { + const { + title + } = props + + return
    +
    +
    +

    {title}

    +
    +
    +

    + This channel page is a stub. +

    +
    +
    +
    +} + +export default ChannelPage; diff --git a/ui/js/page/discover/index.js b/ui/js/page/discover/index.js index bb2d97e49..5a1c14328 100644 --- a/ui/js/page/discover/index.js +++ b/ui/js/page/discover/index.js @@ -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) => ({ diff --git a/ui/js/page/discover/view.jsx b/ui/js/page/discover/view.jsx index 5c4c4e511..d476f8780 100644 --- a/ui/js/page/discover/view.jsx +++ b/ui/js/page/discover/view.jsx @@ -22,44 +22,65 @@ const FeaturedCategory = (props) => {
    } -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
    { - this.state.failed ? -
    Failed to load landing content.
    : -
    - { - Object.keys(this.state.featuredUris).map((category) => { - return this.state.featuredUris[category].length ? - : - ''; - }) - } -
    - }
    ; - } -}) +const DiscoverPage = (props) => { + const { + featuredUris + } = props + + return
    { + Object.keys(featuredUris).length === 0 ? +
    Failed to load landing content.
    : +
    + { + Object.keys(featuredUris).map((category) => { + return featuredUris[category].length ? + : + ''; + }) + } +
    + }
    +} + +// +// 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
    { +// this.state.failed ? +//
    Failed to load landing content.
    : +//
    +// { +// Object.keys(this.state.featuredUris).map((category) => { +// return this.state.featuredUris[category].length ? +// : +// ''; +// }) +// } +//
    +// }
    ; +// } +// }) // const DiscoverPage = (props) => { // const { diff --git a/ui/js/page/showPage/index.js b/ui/js/page/filePage/index.js similarity index 89% rename from ui/js/page/showPage/index.js rename to ui/js/page/filePage/index.js index 4ba0ba729..d553517c2 100644 --- a/ui/js/page/showPage/index.js +++ b/ui/js/page/filePage/index.js @@ -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) diff --git a/ui/js/page/showPage/view.jsx b/ui/js/page/filePage/view.jsx similarity index 69% rename from ui/js/page/showPage/view.jsx rename to ui/js/page/filePage/view.jsx index 8e46b619c..6bb9099f6 100644 --- a/ui/js/page/showPage/view.jsx +++ b/ui/js/page/filePage/view.jsx @@ -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 ( - + @@ -52,23 +45,6 @@ const FormatItem = (props) => { ) } -let ChannelPage = React.createClass({ - render: function() { - return
    -
    -
    -

    {this.props.title}

    -
    -
    -

    - This channel page is a stub. -

    -
    -
    -
    - } -}); - let FilePage = React.createClass({ _isMounted: false, @@ -267,8 +243,6 @@ let ShowPage = React.createClass({ } ; - } else if (this.state.claimType == "channel") { - innerContent = } 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 ( +//
    +//
    +//
    +//

    {uri}

    +//
    +//
    +//

    +// This location is not yet in use. +// { ' ' } +// navigate('publish')} label="Put something here" />. +//

    +//
    +//
    +//
    +// ) +// } +// +// return ( +//
    +//
    +// { contentType && contentType.startsWith('video/') ? +//
    +//
    +//
    +//
    +// {isDownloaded === false +// ? +// : null} +//

    {title}

    +// { uriLookupComplete ? +//
    +//
    +// +//
    +//
    +// +//
    +//
    : '' } +//
    +// { uriLookupComplete ? +//
    +//
    +// {metadata.description} +//
    +//
    +// :
    } +//
    +// { metadata ? +//
    +// +//
    : '' } +//
    +// +//
    +//
    +//
    +// ) +// } \ No newline at end of file diff --git a/ui/js/page/help/view.jsx b/ui/js/page/help/view.jsx index b5fe61787..095435e20 100644 --- a/ui/js/page/help/view.jsx +++ b/ui/js/page/help/view.jsx @@ -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 (
    +
    -

    Read the FAQ

    -

    Our FAQ answers many common questions.

    -

    +
    +

    Read the FAQ

    +
    +
    +

    Our FAQ answers many common questions.

    +

    +
    -

    Get Live Help

    -

    - Live help is available most hours in the #help channel of our Slack chat room. -

    -

    - -

    +
    +

    Get Live Help

    +
    +
    +

    + Live help is available most hours in the #help channel of our Slack chat room. +

    +

    + +

    +
    -

    Report a Bug

    -

    Did you find something wrong?

    -

    -
    Thanks! LBRY is made by its users.
    +

    Report a Bug

    +
    +

    Did you find something wrong?

    +

    +
    Thanks! LBRY is made by its users.
    +
    {!ver ? null : -
    -

    About

    - {ver.lbrynet_update_available || ver.lbryum_update_available ? +
    +

    About

    +
    + {ver.lbrynet_update_available || ver.lbryum_update_available ?

    A newer version of LBRY is available.

    - :

    Your copy of LBRY is up to date.

    - } -
    Content-Type{contentType}Content-Type{mediaType}
    Author{author}
    - - - - - - - - - - - - - - - - - - - - - - -
    daemon (lbrynet){ver.lbrynet_version}
    wallet (lbryum){ver.lbryum_version}
    interface{uiVersion}
    Platform{platform}
    Installation ID{this.state.lbryId}
    - + :

    Your copy of LBRY is up to date.

    + } + + + + + + + + + + + + + + + + + + + + + + + +
    daemon (lbrynet){ver.lbrynet_version}
    wallet (lbryum){ver.lbryum_version}
    interface{uiVersion}
    Platform{platform}
    Installation ID{this.state.lbryId}
    + + } ); diff --git a/ui/js/page/rewards.js b/ui/js/page/rewards.js index 2419ec97d..5b9bb8352 100644 --- a/ui/js/page/rewards.js +++ b/ui/js/page/rewards.js @@ -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 (
    - +
    {!this.state.userRewards ? (this.state.failed ?
    Failed to load rewards.
    : '') diff --git a/ui/js/page/settings.js b/ui/js/page/settings.js index 09f45a9c5..61a9ae879 100644 --- a/ui/js/page/settings.js +++ b/ui/js/page/settings.js @@ -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 ; - } -}); - var SettingsPage = React.createClass({ _onSettingSaveSuccess: function() { // This is bad. @@ -100,7 +91,7 @@ var SettingsPage = React.createClass({ */ return (
    - +

    Download Directory

    diff --git a/ui/js/page/wallet/view.jsx b/ui/js/page/wallet/view.jsx index e1c458f68..cebe970ed 100644 --- a/ui/js/page/wallet/view.jsx +++ b/ui/js/page/wallet/view.jsx @@ -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 (
    +

    Balance

    diff --git a/ui/js/reducers/app.js b/ui/js/reducers/app.js index 43ae54090..b370ed22c 100644 --- a/ui/js/reducers/app.js +++ b/ui/js/reducers/app.js @@ -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 diff --git a/ui/js/reducers/content.js b/ui/js/reducers/content.js index 6c36daf0c..4f9d54594 100644 --- a/ui/js/reducers/content.js +++ b/ui/js/reducers/content.js @@ -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 }) } diff --git a/ui/js/rewards.js b/ui/js/rewards.js index 399965db2..840c22c81 100644 --- a/ui/js/rewards.js +++ b/ui/js/rewards.js @@ -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, diff --git a/ui/js/selectors/app.js b/ui/js/selectors/app.js index e0d1a7a43..29ca4db02 100644 --- a/ui/js/selectors/app.js +++ b/ui/js/selectors/app.js @@ -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': diff --git a/ui/js/selectors/content.js b/ui/js/selectors/content.js index 87b91182d..05e9f2ef9 100644 --- a/ui/js/selectors/content.js +++ b/ui/js/selectors/content.js @@ -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 diff --git a/ui/js/triggers.js b/ui/js/triggers.js index 41d0e0763..3d4633061 100644 --- a/ui/js/triggers.js +++ b/ui/js/triggers.js @@ -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({ diff --git a/ui/scss/component/_header.scss b/ui/scss/component/_header.scss index 0071f01f9..1343ddf86 100644 --- a/ui/scss/component/_header.scss +++ b/ui/scss/component/_header.scss @@ -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;