Merge pull request #62 from lbryio/my-files-tabs

Separate tabs for Downloaded and Published files in My Files
This commit is contained in:
alexliebowitz 2016-09-24 03:01:54 -04:00 committed by GitHub
commit ac1b504dcf
5 changed files with 117 additions and 17 deletions

View file

@ -89,6 +89,12 @@ var App = React.createClass({
'?claim' : 'Claim Beta Code',
'?referral' : 'Check Referral Credit',
};
case 'downloaded':
case 'published':
return {
'?downloaded': 'Downloaded',
'?published': 'Published',
};
default:
return null;
}
@ -105,8 +111,10 @@ var App = React.createClass({
return <WatchPage name={this.state.pageArgs} />;
case 'report':
return <ReportPage />;
case 'files':
return <MyFilesPage />;
case 'downloaded':
return <MyFilesPage show="downloaded" />;
case 'published':
return <MyFilesPage show="published" />;
case 'start':
return <StartPage />;
case 'claim':

View file

@ -32,7 +32,7 @@ var Drawer = React.createClass({
</div>
<DrawerItem href='/?discover' viewingPage={this.props.viewingPage} label="Discover" icon="icon-search" />
<DrawerItem href='/?publish' viewingPage={this.props.viewingPage} label="Publish" icon="icon-upload" />
<DrawerItem href='/?files' viewingPage={this.props.viewingPage} label="My Files" icon='icon-cloud-download' />
<DrawerItem href='/?downloaded' viewingPage={this.props.viewingPage} label="My Files" icon='icon-cloud-download' />
<DrawerItem href="/?wallet" viewingPage={this.props.viewingPage} label="My Wallet" badge={lbry.formatCredits(this.state.balance) } icon="icon-bank" />
<DrawerItem href='/?settings' viewingPage={this.props.viewingPage} label="Settings" icon='icon-gear' />
<DrawerItem href='/?help' viewingPage={this.props.viewingPage} label="Help" icon='icon-question-circle' />

View file

@ -138,6 +138,10 @@ lbry.getClaimInfo = function(name, callback) {
lbry.call('get_claim_info', { name: name }, callback);
}
lbry.getMyClaim = function(name, callback) {
lbry.call('get_my_claim', { name: name }, callback);
}
lbry.getCostEstimate = function(name, callback) {
lbry.call('get_est_cost', { name: name }, callback);
}
@ -169,14 +173,42 @@ lbry.revealFile = function(path, callback) {
lbry.call('reveal', { path: path }, callback);
}
lbry.publish = function(params, callback, errorCallback) {
lbry.getFileInfoWhenListed = function(name, callback, timeoutCallback, tryNum=0) {
// Calls callback with file info when it appears in the list of files returned by lbry.getFilesInfo().
// If timeoutCallback is provided, it will be called if the file fails to appear.
lbry.getFilesInfo(function(filesInfo) {
for (var fileInfo of filesInfo) {
if (fileInfo.lbry_uri == name) {
callback(fileInfo);
return;
}
}
if (tryNum <= 200) {
setTimeout(function() { lbry.getFileInfoWhenListed(name, callback, timeoutCallback, tryNum + 1) }, 250);
} else if (timeoutCallback) {
timeoutCallback();
}
});
}
lbry.publish = function(params, fileListedCallback, publishedCallback, errorCallback) {
// Publishes a file.
// The optional fileListedCallback is called when the file becomes available in
// lbry.getFilesInfo() during the publish process.
// Use ES6 named arguments instead of directly passing param dict?
lbry.call('publish', params, callback, (errorInfo) => {
lbry.call('publish', params, publishedCallback, (errorInfo) => {
errorCallback({
name: fault.fault,
message: fault.faultString,
});
});
if (fileListedCallback) {
lbry.getFileInfoWhenListed(params.name, function(fileInfo) {
fileListedCallback(fileInfo);
});
}
}
lbry.getVersionInfo = function(callback) {

View file

@ -110,6 +110,7 @@ var MyFilesRow = React.createClass({
{this.props.completed ? 'Download complete' : (parseInt(this.props.ratioLoaded * 100) + '%')}
<div>{ pauseLink }</div>
<div>{ watchButton }</div>
{this.props.available ? null : <p><em>This file is uploading to Reflector. Reflector is a service that hosts a copy of the file on LBRY's servers so that it's available even if no one with the file is online.</em></p>}
</div>
)
}
@ -131,34 +132,91 @@ var MyFilesRow = React.createClass({
});
var MyFilesPage = React.createClass({
fileTimeout: null,
_fileTimeout: null,
_fileInfoCheckNum: 0,
_filesOwnership: {},
getInitialState: function() {
return {
filesInfo: null,
filesOwnershipLoaded: false,
filesAvailable: {},
};
},
getDefaultProps: function() {
return {
show: null,
};
},
componentDidMount: function() {
document.title = "My Files";
},
componentWillMount: function() {
this.getFilesOwnership();
this.updateFilesInfo();
},
componentWillUnmount: function() {
if (this.fileTimeout)
if (this._fileTimeout)
{
clearTimeout(this.fileTimeout);
clearTimeout(this._fileTimeout);
}
},
getFilesOwnership: function() {
lbry.getFilesInfo((filesInfo) => {
var ownershipLoadedCount = 0;
for (let i = 0; i < filesInfo.length; i++) {
let fileInfo = filesInfo[i];
lbry.getMyClaim(fileInfo.lbry_uri, (claim) => {
this._filesOwnership[fileInfo.lbry_uri] = !!claim;
ownershipLoadedCount++;
if (ownershipLoadedCount >= filesInfo.length) {
this.setState({
filesOwnershipLoaded: true,
});
}
});
}
});
},
updateFilesInfo: function() {
lbry.getFilesInfo((filesInfo) => {
if (!filesInfo) {
filesInfo = [];
}
if (!(this._fileInfoCheckNum % 5)) {
// Time to update file availability status
for (let fileInfo of filesInfo) {
let name = fileInfo.lbry_uri;
lbry.search(name, (results) => {
var result = results[0];
var available = result.name == name && result.available;
if (typeof this.state.filesAvailable[name] === 'undefined' || available != this.state.filesAvailable[name]) {
var newFilesAvailable = Object.assign({}, this.state.filesAvailable);
newFilesAvailable[name] = available;
this.setState({
filesAvailable: newFilesAvailable,
});
}
});
}
}
this._fileInfoCheckNum += 1;
this.setState({
filesInfo: (filesInfo ? filesInfo : []),
filesInfo: filesInfo,
});
this.fileTimeout = setTimeout(() => { this.updateFilesInfo() }, 1000);
this._fileTimeout = setTimeout(() => { this.updateFilesInfo() }, 1000);
});
},
render: function() {
if (this.state.filesInfo === null) {
if (this.state.filesInfo === null || !this.state.filesOwnershipLoaded) {
return (
<main className="page">
<BusyMessage message="Loading" />
@ -176,7 +234,8 @@ var MyFilesPage = React.createClass({
let {completed, written_bytes, total_bytes, lbry_uri, file_name, download_path,
stopped, metadata} = fileInfo;
if (!metadata || seenUris[lbry_uri])
if (!metadata || seenUris[lbry_uri] || (this.props.show == 'downloaded' && this._filesOwnership[lbry_uri]) ||
(this.props.show == 'published' && !this._filesOwnership[lbry_uri]))
{
continue;
}
@ -201,7 +260,8 @@ var MyFilesPage = React.createClass({
content.push(<MyFilesRow key={lbry_uri} lbryUri={lbry_uri} title={title || ('lbry://' + lbry_uri)} completed={completed} stopped={stopped}
ratioLoaded={ratioLoaded} imgUrl={thumbnail} path={download_path}
showWatchButton={showWatchButton} pending={pending} />);
showWatchButton={showWatchButton} pending={pending}
available={this.state.filesAvailable[lbry_uri]} />);
}
}
return (

View file

@ -86,11 +86,11 @@ var PublishPage = React.createClass({
console.log(publishArgs);
lbry.publish(publishArgs, (message) => {
this.handlePublishSuccess();
this.handlePublishStarted();
this.setState({
submitting: false,
});
}, (error) => {
}, null, (error) => {
this.handlePublishError(error);
this.setState({
submitting: false,
@ -131,10 +131,10 @@ var PublishPage = React.createClass({
submitting: false,
};
},
handlePublishSuccess: function() {
handlePublishStarted: function() {
alert(`Your file ${this.refs.meta_title.getValue()} has been published to LBRY at the address lbry://${this.state.name}!\n\n` +
`You will now be taken to your My Files page, where your newly published file will be listed. Your file will take a few minutes to appear for other LBRY users; until then it will be listed as "pending."`);
window.location = "?files";
window.location = "?published";
},
handlePublishError: function(error) {
alert(`The following error occurred when attempting to publish your file:\n\n` +