make page changes fast #25
12 changed files with 111 additions and 41 deletions
|
@ -8,6 +8,10 @@ Web UI version numbers should always match the corresponding version of LBRY App
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
|
* 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()
|
* 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
|
* New-style API calls return promises instead of using callbacks
|
||||||
* Wherever possible, use outpoints for unique IDs instead of names or SD hashes
|
* Wherever possible, use outpoints for unique IDs instead of names or SD hashes
|
|
@ -61,7 +61,7 @@ function getPidsForProcessName(name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWindow () {
|
function createWindow () {
|
||||||
win = new BrowserWindow({backgroundColor: '#155b4a'})
|
win = new BrowserWindow({backgroundColor: '#155B4A'}) //$color-primary
|
||||||
win.maximize()
|
win.maximize()
|
||||||
//win.webContents.openDevTools()
|
//win.webContents.openDevTools()
|
||||||
win.loadURL(`file://${__dirname}/dist/index.html`)
|
win.loadURL(`file://${__dirname}/dist/index.html`)
|
||||||
|
|
43
ui/js/app.js
43
ui/js/app.js
|
@ -40,8 +40,15 @@ var App = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_upgradeDownloadItem: null,
|
_upgradeDownloadItem: null,
|
||||||
|
_isMounted: false,
|
||||||
_version: null,
|
_version: null,
|
||||||
|
|
||||||
|
// Temporary workaround since electron-dl throws errors when you try to get the filename
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
address: window.location.search
|
||||||
|
};
|
||||||
|
},
|
||||||
getUpdateUrl: function() {
|
getUpdateUrl: function() {
|
||||||
switch (process.platform) {
|
switch (process.platform) {
|
||||||
case 'darwin':
|
case 'darwin':
|
||||||
|
@ -68,31 +75,33 @@ var App = React.createClass({
|
||||||
throw 'Unknown platform';
|
throw 'Unknown platform';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getInitialState: function() {
|
getViewingPageAndArgs: function(address) {
|
||||||
// For now, routes are in format ?page or ?page=args
|
// For now, routes are in format ?page or ?page=args
|
||||||
var match, param, val, viewingPage,
|
let [isMatch, viewingPage, pageArgs] = address.match(/\??([^=]*)(?:=(.*))?/);
|
||||||
drawerOpenRaw = sessionStorage.getItem('drawerOpen');
|
|
||||||
|
|
||||||
[match, viewingPage, val] = window.location.search.match(/\??([^=]*)(?:=(.*))?/);
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
viewingPage: viewingPage,
|
viewingPage: viewingPage,
|
||||||
|
pageArgs: pageArgs === undefined ? null : pageArgs
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getInitialState: function() {
|
||||||
|
var match, param, val, viewingPage, pageArgs,
|
||||||
|
drawerOpenRaw = sessionStorage.getItem('drawerOpen');
|
||||||
|
|
||||||
|
return Object.assign(this.getViewingPageAndArgs(this.props.address), {
|
||||||
drawerOpen: drawerOpenRaw !== null ? JSON.parse(drawerOpenRaw) : true,
|
drawerOpen: drawerOpenRaw !== null ? JSON.parse(drawerOpenRaw) : true,
|
||||||
pageArgs: typeof val !== 'undefined' ? val : null,
|
|
||||||
errorInfo: null,
|
errorInfo: null,
|
||||||
modal: null,
|
modal: null,
|
||||||
downloadProgress: null,
|
downloadProgress: null,
|
||||||
downloadComplete: false,
|
downloadComplete: false,
|
||||||
};
|
});
|
||||||
},
|
},
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
document.addEventListener('unhandledError', (event) => {
|
document.addEventListener('unhandledError', (event) => {
|
||||||
this.alertError(event.detail);
|
this.alertError(event.detail);
|
||||||
});
|
});
|
||||||
|
|
||||||
//open links in external browser
|
//open links in external browser and skip full redraw on changing page
|
||||||
document.addEventListener('click', function(event) {
|
document.addEventListener('click', (event) => {
|
||||||
var target = event.target;
|
var target = event.target;
|
||||||
while (target && target !== document) {
|
while (target && target !== document) {
|
||||||
if (target.matches('a[href^="http"]')) {
|
if (target.matches('a[href^="http"]')) {
|
||||||
|
@ -100,6 +109,12 @@ var App = React.createClass({
|
||||||
shell.openExternal(target.href);
|
shell.openExternal(target.href);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (target.matches('a[href^="?"]')) {
|
||||||
|
event.preventDefault();
|
||||||
|
if (this._isMounted) {
|
||||||
|
this.setState(this.getViewingPageAndArgs(target.getAttribute('href')));
|
||||||
|
}
|
||||||
|
}
|
||||||
target = target.parentNode;
|
target = target.parentNode;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -132,6 +147,12 @@ var App = React.createClass({
|
||||||
modal: null,
|
modal: null,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
componentDidMount: function() {
|
||||||
|
this._isMounted = true;
|
||||||
|
},
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
this._isMounted = false;
|
||||||
|
},
|
||||||
handleUpgradeClicked: function() {
|
handleUpgradeClicked: function() {
|
||||||
// Make a new directory within temp directory so the filename is guaranteed to be available
|
// 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);
|
const dir = fs.mkdtempSync(app.getPath('temp') + require('path').sep);
|
||||||
|
|
|
@ -9,7 +9,7 @@ var DrawerItem = React.createClass({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var isSelected = (this.props.viewingPage == this.props.href.substr(2) ||
|
var isSelected = (this.props.viewingPage == this.props.href.substr(1) ||
|
||||||
this.props.subPages.indexOf(this.props.viewingPage) != -1);
|
this.props.subPages.indexOf(this.props.viewingPage) != -1);
|
||||||
return <Link {...this.props} className={ 'drawer-item ' + (isSelected ? 'drawer-item-selected' : '') } />
|
return <Link {...this.props} className={ 'drawer-item ' + (isSelected ? 'drawer-item-selected' : '') } />
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,11 @@ var drawerImageStyle = { //@TODO: remove this, img should be properly scaled onc
|
||||||
};
|
};
|
||||||
|
|
||||||
var Drawer = React.createClass({
|
var Drawer = React.createClass({
|
||||||
|
_balanceSubscribeId: null,
|
||||||
|
|
||||||
handleLogoClicked: function(event) {
|
handleLogoClicked: function(event) {
|
||||||
if ((event.ctrlKey || event.metaKey) && event.shiftKey) {
|
if ((event.ctrlKey || event.metaKey) && event.shiftKey) {
|
||||||
window.location.href = 'index.html?developer'
|
window.location.href = '?developer'
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -32,25 +34,30 @@ var Drawer = React.createClass({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
lbry.getBalance(function(balance) {
|
this._balanceSubscribeId = lbry.balanceSubscribe(function(balance) {
|
||||||
this.setState({
|
this.setState({
|
||||||
balance: balance
|
balance: balance
|
||||||
});
|
});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
if (this._balanceSubscribeId) {
|
||||||
|
lbry.balanceUnsubscribe(this._balanceSubscribeId)
|
||||||
|
}
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<nav id="drawer">
|
<nav id="drawer">
|
||||||
<div id="drawer-handle">
|
<div id="drawer-handle">
|
||||||
<Link title="Close" onClick={this.props.onCloseDrawer} icon="icon-bars" className="close-drawer-link"/>
|
<Link title="Close" onClick={this.props.onCloseDrawer} icon="icon-bars" className="close-drawer-link"/>
|
||||||
<a href="index.html?discover" onMouseUp={this.handleLogoClicked}><img src={lbry.imagePath("lbry-dark-1600x528.png")} style={drawerImageStyle}/></a>
|
<a href="?discover" onMouseUp={this.handleLogoClicked}><img src={lbry.imagePath("lbry-dark-1600x528.png")} style={drawerImageStyle}/></a>
|
||||||
</div>
|
</div>
|
||||||
<DrawerItem href='index.html?discover' viewingPage={this.props.viewingPage} label="Discover" icon="icon-search" />
|
<DrawerItem href='?discover' viewingPage={this.props.viewingPage} label="Discover" icon="icon-search" />
|
||||||
<DrawerItem href='index.html?publish' viewingPage={this.props.viewingPage} label="Publish" icon="icon-upload" />
|
<DrawerItem href='?publish' viewingPage={this.props.viewingPage} label="Publish" icon="icon-upload" />
|
||||||
<DrawerItem href='index.html?downloaded' subPages={['published']} viewingPage={this.props.viewingPage} label="My Files" icon='icon-cloud-download' />
|
<DrawerItem href='?downloaded' subPages={['published']} viewingPage={this.props.viewingPage} label="My Files" icon='icon-cloud-download' />
|
||||||
<DrawerItem href="index.html?wallet" subPages={['send', 'receive', 'claim', 'referral']} viewingPage={this.props.viewingPage} label="My Wallet" badge={lbry.formatCredits(this.state.balance) } icon="icon-bank" />
|
<DrawerItem href="?wallet" subPages={['send', 'receive', 'claim', 'referral']} viewingPage={this.props.viewingPage} label="My Wallet" badge={lbry.formatCredits(this.state.balance) } icon="icon-bank" />
|
||||||
<DrawerItem href='index.html?settings' viewingPage={this.props.viewingPage} label="Settings" icon='icon-gear' />
|
<DrawerItem href='?settings' viewingPage={this.props.viewingPage} label="Settings" icon='icon-gear' />
|
||||||
<DrawerItem href='index.html?help' viewingPage={this.props.viewingPage} label="Help" icon='icon-question-circle' />
|
<DrawerItem href='?help' viewingPage={this.props.viewingPage} label="Help" icon='icon-question-circle' />
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,6 +276,9 @@ export let FileActions = React.createClass({
|
||||||
},
|
},
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
this._isMounted = false;
|
this._isMounted = false;
|
||||||
|
if (this._fileInfoSubscribeId) {
|
||||||
|
lbry.fileInfoUnsubscribe(this.props.outpoint, this._fileInfoSubscribeId);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
const fileInfo = this.state.fileInfo;
|
const fileInfo = this.state.fileInfo;
|
||||||
|
|
|
@ -79,7 +79,7 @@ export let FileTileStream = React.createClass({
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
this._isMounted = true;
|
this._isMounted = true;
|
||||||
if (this.props.hideOnRemove) {
|
if (this.props.hideOnRemove) {
|
||||||
lbry.fileInfoSubscribe(this.props.outpoint, this.onFileInfoUpdate);
|
this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.outpoint, this.onFileInfoUpdate);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
|
@ -121,15 +121,15 @@ export let FileTileStream = React.createClass({
|
||||||
<section className={ 'file-tile card ' + (obscureNsfw ? 'card-obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
|
<section className={ 'file-tile card ' + (obscureNsfw ? 'card-obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
|
||||||
<div className={"row-fluid card-content file-tile__row"}>
|
<div className={"row-fluid card-content file-tile__row"}>
|
||||||
<div className="span3">
|
<div className="span3">
|
||||||
<a href={'/?show=' + this.props.name}><Thumbnail className="file-tile__thumbnail" src={metadata.thumbnail} alt={'Photo for ' + (title || this.props.name)} /></a>
|
<a href={'?show=' + this.props.name}><Thumbnail className="file-tile__thumbnail" src={metadata.thumbnail} alt={'Photo for ' + (title || this.props.name)} /></a>
|
||||||
</div>
|
</div>
|
||||||
<div className="span9">
|
<div className="span9">
|
||||||
{ !this.props.hidePrice
|
{ !this.props.hidePrice
|
||||||
? <FilePrice name={this.props.name} />
|
? <FilePrice name={this.props.name} />
|
||||||
: null}
|
: null}
|
||||||
<div className="meta"><a href={'index.html?show=' + this.props.name}>{'lbry://' + this.props.name}</a></div>
|
<div className="meta"><a href={'?show=' + this.props.name}>{'lbry://' + this.props.name}</a></div>
|
||||||
<h3 className="file-tile__title">
|
<h3 className="file-tile__title">
|
||||||
<a href={'index.html?show=' + this.props.name}>
|
<a href={'?show=' + this.props.name}>
|
||||||
<TruncatedText lines={1}>
|
<TruncatedText lines={1}>
|
||||||
{title}
|
{title}
|
||||||
</TruncatedText>
|
</TruncatedText>
|
||||||
|
|
|
@ -223,7 +223,7 @@ lbry.stopFile = function(name, callback) {
|
||||||
|
|
||||||
lbry.removeFile = function(outpoint, deleteTargetFile=true, callback) {
|
lbry.removeFile = function(outpoint, deleteTargetFile=true, callback) {
|
||||||
this._removedFiles.push(outpoint);
|
this._removedFiles.push(outpoint);
|
||||||
this._updateSubscribedFileInfo(outpoint);
|
this._updateFileInfoSubscribers(outpoint);
|
||||||
|
|
||||||
lbry.file_delete({
|
lbry.file_delete({
|
||||||
outpoint: outpoint,
|
outpoint: outpoint,
|
||||||
|
@ -405,9 +405,11 @@ lbry.stop = function(callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
lbry.fileInfo = {};
|
lbry.fileInfo = {};
|
||||||
lbry._fileInfoSubscribeIdCounter = 0;
|
lbry._subscribeIdCount = 0;
|
||||||
lbry._fileInfoSubscribeCallbacks = {};
|
lbry._fileInfoSubscribeCallbacks = {};
|
||||||
lbry._fileInfoSubscribeInterval = 5000;
|
lbry._fileInfoSubscribeInterval = 5000;
|
||||||
|
lbry._balanceSubscribeCallbacks = {};
|
||||||
|
lbry._balanceSubscribeInterval = 5000;
|
||||||
lbry._removedFiles = [];
|
lbry._removedFiles = [];
|
||||||
lbry._claimIdOwnershipCache = {};
|
lbry._claimIdOwnershipCache = {};
|
||||||
|
|
||||||
|
@ -419,9 +421,9 @@ lbry._updateClaimOwnershipCache = function(claimId) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
lbry._updateSubscribedFileInfo = function(outpoint) {
|
lbry._updateFileInfoSubscribers = function(outpoint) {
|
||||||
const callSubscribedCallbacks = (outpoint, fileInfo) => {
|
const callSubscribedCallbacks = (outpoint, fileInfo) => {
|
||||||
for (let [subscribeId, callback] of Object.entries(this._fileInfoSubscribeCallbacks[outpoint])) {
|
for (let callback of Object.values(this._fileInfoSubscribeCallbacks[outpoint])) {
|
||||||
callback(fileInfo);
|
callback(fileInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,7 +448,7 @@ lbry._updateSubscribedFileInfo = function(outpoint) {
|
||||||
|
|
||||||
if (Object.keys(this._fileInfoSubscribeCallbacks[outpoint]).length) {
|
if (Object.keys(this._fileInfoSubscribeCallbacks[outpoint]).length) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this._updateSubscribedFileInfo(outpoint);
|
this._updateFileInfoSubscribers(outpoint);
|
||||||
}, lbry._fileInfoSubscribeInterval);
|
}, lbry._fileInfoSubscribeInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,14 +459,39 @@ lbry.fileInfoSubscribe = function(outpoint, callback) {
|
||||||
lbry._fileInfoSubscribeCallbacks[outpoint] = {};
|
lbry._fileInfoSubscribeCallbacks[outpoint] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const subscribeId = ++lbry._fileInfoSubscribeIdCounter;
|
const subscribeId = ++lbry._subscribeIdCount;
|
||||||
lbry._fileInfoSubscribeCallbacks[outpoint][subscribeId] = callback;
|
lbry._fileInfoSubscribeCallbacks[outpoint][subscribeId] = callback;
|
||||||
lbry._updateSubscribedFileInfo(outpoint);
|
lbry._updateFileInfoSubscribers(outpoint);
|
||||||
return subscribeId;
|
return subscribeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
lbry.fileInfoUnsubscribe = function(name, subscribeId) {
|
lbry.fileInfoUnsubscribe = function(outpoint, subscribeId) {
|
||||||
delete lbry._fileInfoSubscribeCallbacks[name][subscribeId];
|
delete lbry._fileInfoSubscribeCallbacks[outpoint][subscribeId];
|
||||||
|
}
|
||||||
|
|
||||||
|
lbry._updateBalanceSubscribers = function() {
|
||||||
|
lbry.get_balance().then(function(balance) {
|
||||||
|
for (let callback of Object.values(lbry._balanceSubscribeCallbacks)) {
|
||||||
|
callback(balance);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (Object.keys(lbry._balanceSubscribeCallbacks).length) {
|
||||||
|
setTimeout(() => {
|
||||||
|
lbry._updateBalanceSubscribers();
|
||||||
|
}, lbry._balanceSubscribeInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lbry.balanceSubscribe = function(callback) {
|
||||||
|
const subscribeId = ++lbry._subscribeIdCount;
|
||||||
|
lbry._balanceSubscribeCallbacks[subscribeId] = callback;
|
||||||
|
lbry._updateBalanceSubscribers();
|
||||||
|
return subscribeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
lbry.balanceUnsubscribe = function(subscribeId) {
|
||||||
|
delete lbry._balanceSubscribeCallbacks[subscribeId];
|
||||||
}
|
}
|
||||||
|
|
||||||
lbry.showMenuIfNeeded = function() {
|
lbry.showMenuIfNeeded = function() {
|
||||||
|
|
|
@ -41,7 +41,7 @@ export let FileListDownloaded = React.createClass({
|
||||||
} else if (!this.state.fileInfos.length) {
|
} else if (!this.state.fileInfos.length) {
|
||||||
return (
|
return (
|
||||||
<main className="page">
|
<main className="page">
|
||||||
<span>You haven't downloaded anything from LBRY yet. Go <Link href="/index.html?discover" label="search for your first download" />!</span>
|
<span>You haven't downloaded anything from LBRY yet. Go <Link href="?discover" label="search for your first download" />!</span>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -90,7 +90,7 @@ export let FileListPublished = React.createClass({
|
||||||
else if (!this.state.fileInfos.length) {
|
else if (!this.state.fileInfos.length) {
|
||||||
return (
|
return (
|
||||||
<main className="page">
|
<main className="page">
|
||||||
<span>You haven't published anything to LBRY yet.</span> Try <Link href="index.html?publish" label="publishing" />!
|
<span>You haven't published anything to LBRY yet.</span> Try <Link href="?publish" label="publishing" />!
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ var HelpPage = React.createClass({
|
||||||
<section className="card">
|
<section className="card">
|
||||||
<h3>Report a Bug</h3>
|
<h3>Report a Bug</h3>
|
||||||
<p>Did you find something wrong?</p>
|
<p>Did you find something wrong?</p>
|
||||||
<p><Link href="index.html?report" label="Submit a Bug Report" icon="icon-bug" button="alt" /></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="meta">Thanks! LBRY is made by its users.</div>
|
||||||
</section>
|
</section>
|
||||||
{!ver ? null :
|
{!ver ? null :
|
||||||
|
|
|
@ -155,7 +155,7 @@ var DetailPage = React.createClass({
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<h2>No content</h2>
|
<h2>No content</h2>
|
||||||
There is no content available at the name <strong>lbry://{this.props.name}</strong>. If you reached this page from a link within the LBRY interface, please <Link href="index.html?report" label="report a bug" />. Thanks!
|
There is no content available at the name <strong>lbry://{this.props.name}</strong>. If you reached this page from a link within the LBRY interface, please <Link href="?report" label="report a bug" />. Thanks!
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -243,6 +243,8 @@ var TransactionList = React.createClass({
|
||||||
|
|
||||||
|
|
||||||
var WalletPage = React.createClass({
|
var WalletPage = React.createClass({
|
||||||
|
_balanceSubscribeId: null,
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
viewingPage: React.PropTypes.string,
|
viewingPage: React.PropTypes.string,
|
||||||
},
|
},
|
||||||
|
@ -259,12 +261,17 @@ var WalletPage = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
lbry.getBalance((results) => {
|
this._balanceSubscribeId = lbry.balanceSubscribe((results) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
balance: results,
|
balance: results,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
if (this._balanceSubscribeId) {
|
||||||
|
lbry.balanceUnsubscribe(this._balanceSubscribeId);
|
||||||
|
}
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<main className="page">
|
<main className="page">
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
.load-screen {
|
.load-screen {
|
||||||
color: white;
|
color: white;
|
||||||
|
background: $color-primary;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
min-width: 100vw;
|
min-width: 100vw;
|
||||||
|
|
Loading…
Reference in a new issue