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(
-
+ 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 (
+
{
+ Object.keys(links).map((link) => {
+ console.log(link + " vs " + currentPage);
+ return navigate(link)} key={link} className={link == currentPage ? 'sub-header-selected' : 'sub-header-unselected' }>
+ {links[link]}
+
+ })
+ }
+ )
+}
+
+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 (
-
{links}
- )
-}
\ 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
+
+
+
+
+ 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