file list refactor
This commit is contained in:
parent
3b7d093201
commit
7f135275df
7 changed files with 225 additions and 254 deletions
|
@ -4,7 +4,6 @@ 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 {MyFilesPage} from './page/my_files.js';
|
||||
import StartPage from './page/start.js';
|
||||
import ClaimCodePage from './page/claim_code.js';
|
||||
import ReferralPage from './page/referral.js';
|
||||
|
@ -14,6 +13,7 @@ import PublishPage from './page/publish.js';
|
|||
import DiscoverPage from './page/discover.js';
|
||||
import SplashScreen from './component/splash.js';
|
||||
import DeveloperPage from './page/developer.js';
|
||||
import {FileListDownloaded, FileListPublished} from './page/file-list.js';
|
||||
import Drawer from './component/drawer.js';
|
||||
import Header from './component/header.js';
|
||||
import Modal from './component/modal.js';
|
||||
|
@ -164,9 +164,9 @@ var App = React.createClass({
|
|||
case 'report':
|
||||
return <ReportPage />;
|
||||
case 'downloaded':
|
||||
return <MyFilesPage show="downloaded" />;
|
||||
return <FileListDownloaded />;
|
||||
case 'published':
|
||||
return <MyFilesPage show="published" />;
|
||||
return <FileListPublished />;
|
||||
case 'start':
|
||||
return <StartPage />;
|
||||
case 'claim':
|
||||
|
|
|
@ -56,11 +56,10 @@ export let FileActions = React.createClass({
|
|||
|
||||
propTypes: {
|
||||
streamName: React.PropTypes.string,
|
||||
sdHash: React.PropTypes.string,
|
||||
sdHash: React.PropTypes.string.isRequired,
|
||||
metadata: React.PropTypes.object,
|
||||
path: React.PropTypes.string,
|
||||
hidden: React.PropTypes.bool,
|
||||
onRemoveConfirmed: React.PropTypes.func,
|
||||
deleteChecked: React.PropTypes.bool,
|
||||
},
|
||||
getInitialState: function() {
|
||||
|
@ -137,9 +136,10 @@ export let FileActions = React.createClass({
|
|||
});
|
||||
},
|
||||
handleRemoveConfirmed: function() {
|
||||
lbry.deleteFile(this.props.sdHash || this.props.streamName, this.state.deleteChecked);
|
||||
if (this.props.onRemoveConfirmed) {
|
||||
this.props.onRemoveConfirmed();
|
||||
if (this.props.streamName) {
|
||||
lbry.deleteFile(this.props.streamName, this.state.deleteChecked);
|
||||
} else {
|
||||
alert('this file cannot be deleted because lbry is a retarded piece of shit');
|
||||
}
|
||||
this.setState({
|
||||
modal: null,
|
||||
|
@ -155,20 +155,12 @@ export let FileActions = React.createClass({
|
|||
},
|
||||
componentDidMount: function() {
|
||||
this._isMounted = true;
|
||||
|
||||
if ('sdHash' in this.props) {
|
||||
alert('render by sd hash is broken');
|
||||
lbry.fileInfoSubscribeByStreamHash(this.props.sdHash, this.fileInfoU);
|
||||
} else if ('streamName' in this.props) {
|
||||
this._fileInfoSubscribeId = lbry.fileInfoSubscribeByName(this.props.streamName, this.onFileInfoUpdate);
|
||||
} else {
|
||||
throw new Error("No stream name or sd hash passed to FileTile");
|
||||
}
|
||||
this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.sdHash, this.onFileInfoUpdate);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
this._isMounted = false;
|
||||
if (this._fileInfoSubscribeId) {
|
||||
lbry.fileInfoUnsubscribe(this.props.streamName, this._fileInfoSubscribeId);
|
||||
lbry.fileInfoUnsubscribe(this.props.sdHash, this._fileInfoSubscribeId);
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
|
@ -178,7 +170,7 @@ export let FileActions = React.createClass({
|
|||
}
|
||||
const openInFolderMessage = window.navigator.platform.startsWith('Mac') ? 'Open in Finder' : 'Open in Folder',
|
||||
showMenu = !this.state.attemptingRemove && this.state.fileInfo !== null;
|
||||
|
||||
|
||||
let linkBlock;
|
||||
if (this.state.attemptingRemove || (this.state.fileInfo === false && !this.state.attemptingDownload)) {
|
||||
linkBlock = <Link button="text" label="Download" icon="icon-download" onClick={this.onDownloadClick} />;
|
||||
|
|
|
@ -55,8 +55,7 @@ export let FileTileStream = React.createClass({
|
|||
metadata: React.PropTypes.object,
|
||||
sdHash: React.PropTypes.string,
|
||||
hidePrice: React.PropTypes.bool,
|
||||
obscureNsfw: React.PropTypes.bool,
|
||||
hideOnRemove: React.PropTypes.bool
|
||||
obscureNsfw: React.PropTypes.bool
|
||||
},
|
||||
getInitialState: function() {
|
||||
return {
|
||||
|
@ -66,7 +65,6 @@ export let FileTileStream = React.createClass({
|
|||
},
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
hideOnRemove: false,
|
||||
obscureNsfw: !lbry.getClientSetting('showNsfw'),
|
||||
hidePrice: false
|
||||
}
|
||||
|
@ -85,19 +83,11 @@ export let FileTileStream = React.createClass({
|
|||
});
|
||||
}
|
||||
},
|
||||
onRemove: function() {
|
||||
this.setState({
|
||||
isRemoved: true,
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
if (this.props.metadata === null || (this.props.hideOnRemove && this.state.isRemoved)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const metadata = this.props.metadata || {},
|
||||
obscureNsfw = this.props.obscureNsfw && metadata.nsfw,
|
||||
title = metadata.title ? metadata.title : ('lbry://' + this.props.name);
|
||||
|
||||
return (
|
||||
<section className={ 'file-tile card ' + (obscureNsfw ? 'card-obscured ' : '') } onMouseEnter={this.handleMouseOver} onMouseLeave={this.handleMouseOut}>
|
||||
<div className="row-fluid card-content file-tile__row">
|
||||
|
@ -116,7 +106,7 @@ export let FileTileStream = React.createClass({
|
|||
</TruncatedText>
|
||||
</a>
|
||||
</h3>
|
||||
<FileActions streamName={this.props.name} metadata={metadata} />
|
||||
<FileActions streamName={this.props.name} sdHash={this.props.sdHash} metadata={metadata} />
|
||||
<p className="file-tile__description">
|
||||
<TruncatedText lines={3}>
|
||||
{metadata.description}
|
||||
|
@ -141,7 +131,7 @@ export let FileTile = React.createClass({
|
|||
_isMounted: false,
|
||||
|
||||
propTypes: {
|
||||
name: React.PropTypes.string
|
||||
name: React.PropTypes.string.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -167,7 +157,7 @@ export let FileTile = React.createClass({
|
|||
this._isMounted = false;
|
||||
},
|
||||
render: function() {
|
||||
if (this.state.metadata === null || this.state.sdHash === null) {
|
||||
if (!this.state.metadata || !this.state.sdHash) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
28
js/lbry.js
28
js/lbry.js
|
@ -472,43 +472,37 @@ lbry._updateClaimOwnershipCache = function(claimId) {
|
|||
});
|
||||
};
|
||||
|
||||
lbry._updateSubscribedFileInfoByName = function(name) {
|
||||
lbry.getFileInfoByName(name, (fileInfo) => {
|
||||
lbry._updateSubscribedFileInfo = function(sdHash) {
|
||||
lbry.getFileInfoBySdHash(sdHash, (fileInfo) => {
|
||||
if (fileInfo) {
|
||||
if (this._claimIdOwnershipCache[fileInfo.claim_id] === undefined) {
|
||||
lbry._updateClaimOwnershipCache(fileInfo.claim_id);
|
||||
}
|
||||
fileInfo.isMine = !!this._claimIdOwnershipCache[fileInfo.claim_id];
|
||||
}
|
||||
Object.keys(this._fileInfoSubscribeCallbacks[name]).forEach(function(subscribeId) {
|
||||
lbry._fileInfoSubscribeCallbacks[name][subscribeId](fileInfo);
|
||||
Object.keys(this._fileInfoSubscribeCallbacks[sdHash]).forEach(function(subscribeId) {
|
||||
lbry._fileInfoSubscribeCallbacks[sdHash][subscribeId](fileInfo);
|
||||
});
|
||||
});
|
||||
if (Object.keys(this._fileInfoSubscribeCallbacks[name]).length) {
|
||||
if (Object.keys(this._fileInfoSubscribeCallbacks[sdHash]).length) {
|
||||
setTimeout(() => {
|
||||
this._updateSubscribedFileInfoByName(name)
|
||||
this._updateSubscribedFileInfo(sdHash)
|
||||
}, lbry._fileInfoSubscribeInterval);
|
||||
}
|
||||
}
|
||||
|
||||
lbry.fileInfoSubscribeByName = function(name, callback) {
|
||||
if (!lbry._fileInfoSubscribeCallbacks[name])
|
||||
lbry.fileInfoSubscribe = function(sdHash, callback) {
|
||||
if (!lbry._fileInfoSubscribeCallbacks[sdHash])
|
||||
{
|
||||
lbry._fileInfoSubscribeCallbacks[name] = {};
|
||||
lbry._fileInfoSubscribeCallbacks[sdHash] = {};
|
||||
}
|
||||
|
||||
const subscribeId = ++lbry._fileInfoSubscribeIdCounter;
|
||||
lbry._fileInfoSubscribeCallbacks[name][subscribeId] = callback;
|
||||
lbry._updateSubscribedFileInfoByName(name);
|
||||
lbry._fileInfoSubscribeCallbacks[sdHash][subscribeId] = callback;
|
||||
lbry._updateSubscribedFileInfo(sdHash);
|
||||
return subscribeId;
|
||||
}
|
||||
|
||||
// lbry.fileInfoSubscribeByStreamHash = function(sdHash, callback) {
|
||||
// lbry.getFileInfoBySdHash(this.props.sdHash, this.updateFileInfoCallback);
|
||||
// this.getIsMineIfNeeded(this.props.sdHash);
|
||||
// setTimeout(() => { this.updateFileInfo() }, this._fileInfoCheckInterval);
|
||||
// }
|
||||
|
||||
lbry.fileInfoUnsubscribe = function(name, subscribeId) {
|
||||
delete lbry._fileInfoSubscribeCallbacks[name][subscribeId];
|
||||
}
|
||||
|
|
194
js/page/file-list.js
Normal file
194
js/page/file-list.js
Normal file
|
@ -0,0 +1,194 @@
|
|||
import React from 'react';
|
||||
import lbry from '../lbry.js';
|
||||
import {Link} from '../component/link.js';
|
||||
import FormField from '../component/form.js';
|
||||
import {FileTileStream} from '../component/file-tile.js';
|
||||
import {BusyMessage, Thumbnail} from '../component/common.js';
|
||||
|
||||
|
||||
export let FileListDownloaded = React.createClass({
|
||||
_isMounted: false,
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
fileInfos: null,
|
||||
};
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this._isMounted = true;
|
||||
document.title = "Downloaded Files";
|
||||
|
||||
let publishedFilesSdHashes = [];
|
||||
lbry.getMyClaims((claimsInfo) => {
|
||||
|
||||
if (!this._isMounted) { return; }
|
||||
|
||||
for (let claimInfo of claimsInfo) {
|
||||
let metadata = JSON.parse(claimInfo.value);
|
||||
publishedFilesSdHashes.push(metadata.sources.lbry_sd_hash);
|
||||
}
|
||||
|
||||
lbry.getFilesInfo((fileInfos) => {
|
||||
if (!this._isMounted) { return; }
|
||||
|
||||
this.setState({
|
||||
fileInfos: fileInfos.filter(({sd_hash}) => {
|
||||
return publishedFilesSdHashes.indexOf(sd_hash) == -1;
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
if (this.state.fileInfos === null) {
|
||||
return (
|
||||
<main className="page">
|
||||
<BusyMessage message="Loading" />
|
||||
</main>
|
||||
);
|
||||
} else if (!this.state.fileInfos.length) {
|
||||
return (
|
||||
<main className="page">
|
||||
<span>You haven't downloaded anything from LBRY yet. Go <Link href="/" label="search for your first download" />!</span>
|
||||
</main>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<main className="page">
|
||||
<FileList fileInfos={this.state.fileInfos} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export let FileListPublished = React.createClass({
|
||||
_isMounted: false,
|
||||
|
||||
getInitialState: function () {
|
||||
return {
|
||||
fileInfos: null,
|
||||
};
|
||||
},
|
||||
componentDidMount: function () {
|
||||
this._isMounted = true;
|
||||
document.title = "Published Files";
|
||||
|
||||
lbry.getMyClaims((claimsInfo) => {
|
||||
/**
|
||||
* Build newFileInfos as a sparse array and drop elements in at the same position they
|
||||
* occur in claimsInfo, so the order is preserved even if the API calls inside this loop
|
||||
* return out of order.
|
||||
*/
|
||||
let newFileInfos = Array(claimsInfo.length),
|
||||
claimInfoProcessedCount = 0;
|
||||
|
||||
for (let [i, claimInfo] of claimsInfo.entries()) {
|
||||
let metadata = JSON.parse(claimInfo.value);
|
||||
lbry.getFileInfoBySdHash(metadata.sources.lbry_sd_hash, (fileInfo) => {
|
||||
claimInfoProcessedCount++;
|
||||
if (fileInfo !== false) {
|
||||
newFileInfos[i] = fileInfo;
|
||||
}
|
||||
if (claimInfoProcessedCount >= claimsInfo.length) {
|
||||
/**
|
||||
* newfileInfos may have gaps from claims that don't have associated files in
|
||||
* lbrynet, so filter out any missing elements
|
||||
*/
|
||||
this.setState({
|
||||
fileInfos: newFileInfos.filter(function () {
|
||||
return true
|
||||
}),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
if (this.state.fileInfos === null) {
|
||||
return (
|
||||
<main className="page">
|
||||
<BusyMessage message="Loading" />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
else if (!this.state.fileInfos.length) {
|
||||
return (
|
||||
<main className="page">
|
||||
<span>You haven't published anything to LBRY yet.</span> Try <Link href="/?publish" label="publishing" />!
|
||||
</main>
|
||||
);
|
||||
}
|
||||
else {
|
||||
return (
|
||||
<main className="page">
|
||||
<FileList fileInfos={this.state.fileInfos} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export let FileList = React.createClass({
|
||||
_sortFunctions: {
|
||||
date: function(fileInfos) {
|
||||
return fileInfos.reverse();
|
||||
},
|
||||
title: function(fileInfos) {
|
||||
return fileInfos.sort(function(a, b) {
|
||||
return ((a.metadata ? a.metadata.title.toLowerCase() : a.name) >
|
||||
(b.metadata ? b.metadata.title.toLowerCase() : b.name));
|
||||
});
|
||||
},
|
||||
filename: function(fileInfos) {
|
||||
return fileInfos.sort(function(a, b) {
|
||||
return (a.file_name.toLowerCase() >
|
||||
b.file_name.toLowerCase());
|
||||
});
|
||||
},
|
||||
},
|
||||
propTypes: {
|
||||
fileInfos: React.PropTypes.array.isRequired
|
||||
},
|
||||
getInitialState: function() {
|
||||
return {
|
||||
sortBy: 'date',
|
||||
};
|
||||
},
|
||||
handleSortChanged: function(event) {
|
||||
this.setState({
|
||||
sortBy: event.target.value,
|
||||
});
|
||||
},
|
||||
render: function() {
|
||||
var content = [],
|
||||
seenUris = {};
|
||||
|
||||
const fileInfosSorted = this._sortFunctions[this.state.sortBy](this.props.fileInfos);
|
||||
for (let fileInfo of fileInfosSorted) {
|
||||
let {lbry_uri, sd_hash, metadata} = fileInfo;
|
||||
|
||||
if (!metadata || seenUris[lbry_uri]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
seenUris[lbry_uri] = true;
|
||||
content.push(<FileTileStream key={lbry_uri} name={lbry_uri} hideOnRemove={true} sdHash={sd_hash} hidePrice={true} metadata={metadata} />);
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
<span className='sort-section'>
|
||||
Sort by { ' ' }
|
||||
<FormField type="select" onChange={this.handleSortChanged}>
|
||||
<option value="date">Date</option>
|
||||
<option value="title">Title</option>
|
||||
<option value="filename">File name</option>
|
||||
</FormField>
|
||||
</span>
|
||||
{content}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -1,196 +0,0 @@
|
|||
import React from 'react';
|
||||
import lbry from '../lbry.js';
|
||||
import {Link} from '../component/link.js';
|
||||
import FormField from '../component/form.js';
|
||||
import {FileTileStream} from '../component/file-tile.js';
|
||||
import {BusyMessage, Thumbnail} from '../component/common.js';
|
||||
|
||||
export let MyFilesPage = React.createClass({
|
||||
_fileTimeout: null,
|
||||
_fileInfoCheckRate: 300,
|
||||
_fileInfoCheckNum: 0,
|
||||
_sortFunctions: {
|
||||
date: function(filesInfo) {
|
||||
return filesInfo.reverse();
|
||||
},
|
||||
title: function(filesInfo) {
|
||||
return filesInfo.sort(function(a, b) {
|
||||
return ((a.metadata ? a.metadata.title.toLowerCase() : a.name) >
|
||||
(b.metadata ? b.metadata.title.toLowerCase() : b.name));
|
||||
});
|
||||
},
|
||||
filename: function(filesInfo) {
|
||||
return filesInfo.sort(function(a, b) {
|
||||
return (a.file_name.toLowerCase() >
|
||||
b.file_name.toLowerCase());
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
filesInfo: null,
|
||||
publishedFilesSdHashes: null,
|
||||
filesAvailable: null,
|
||||
sortBy: 'date',
|
||||
};
|
||||
},
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
show: null,
|
||||
};
|
||||
},
|
||||
componentDidMount: function() {
|
||||
document.title = "My Files";
|
||||
},
|
||||
componentWillMount: function() {
|
||||
if (this.props.show == 'downloaded') {
|
||||
this.getPublishedFilesSdHashes(() => {
|
||||
this.updateFilesInfo();
|
||||
});
|
||||
} else {
|
||||
this.updateFilesInfo();
|
||||
}
|
||||
},
|
||||
getPublishedFilesSdHashes: function(callback) {
|
||||
// Determines which files were published by the user and saves their SD hashes in
|
||||
// this.state.publishedFilesSdHashes. Used on the Downloads page to filter out claims published
|
||||
// by the user.
|
||||
var publishedFilesSdHashes = [];
|
||||
lbry.getMyClaims((claimsInfo) => {
|
||||
for (let claimInfo of claimsInfo) {
|
||||
let metadata = JSON.parse(claimInfo.value);
|
||||
publishedFilesSdHashes.push(metadata.sources.lbry_sd_hash);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
publishedFilesSdHashes: publishedFilesSdHashes,
|
||||
});
|
||||
callback();
|
||||
});
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
if (this._fileTimeout)
|
||||
{
|
||||
clearTimeout(this._fileTimeout);
|
||||
}
|
||||
},
|
||||
handleSortChanged: function(event) {
|
||||
this.setState({
|
||||
sortBy: event.target.value,
|
||||
});
|
||||
},
|
||||
updateFilesInfo: function() {
|
||||
this._fileInfoCheckNum += 1;
|
||||
|
||||
if (this.props.show == 'published') {
|
||||
// We're in the Published tab, so populate this.state.filesInfo with data from the user's claims
|
||||
lbry.getMyClaims((claimsInfo) => {
|
||||
/**
|
||||
* Build newFilesInfo as a sparse array and drop elements in at the same position they
|
||||
* occur in claimsInfo, so the order is preserved even if the API calls inside this loop
|
||||
* return out of order.
|
||||
*/
|
||||
|
||||
let newFilesInfo = Array(claimsInfo.length);
|
||||
let claimInfoProcessedCount = 0;
|
||||
for (let [i, claimInfo] of claimsInfo.entries()) {
|
||||
let metadata = JSON.parse(claimInfo.value);
|
||||
lbry.getFileInfoBySdHash(metadata.sources.lbry_sd_hash, (fileInfo) => {
|
||||
claimInfoProcessedCount++;
|
||||
if (fileInfo !== false) {
|
||||
newFilesInfo[i] = fileInfo;
|
||||
}
|
||||
if (claimInfoProcessedCount >= claimsInfo.length) {
|
||||
/**
|
||||
* newFilesInfo may have gaps from claims that don't have associated files in
|
||||
* lbrynet, so filter out any missing elements
|
||||
*/
|
||||
this.setState({
|
||||
filesInfo: newFilesInfo.filter(function() { return true }),
|
||||
});
|
||||
|
||||
this._fileTimeout = setTimeout(() => { this.updateFilesInfo() }, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// We're in the Downloaded tab, so populate this.state.filesInfo with files the user has in
|
||||
// lbrynet, with published files filtered out.
|
||||
lbry.getFilesInfo((filesInfo) => {
|
||||
this.setState({
|
||||
filesInfo: filesInfo.filter(({sd_hash}) => {
|
||||
return this.state.publishedFilesSdHashes.indexOf(sd_hash) == -1;
|
||||
}),
|
||||
});
|
||||
|
||||
let newFilesAvailable;
|
||||
if (!(this._fileInfoCheckNum % this._fileInfoCheckRate)) {
|
||||
// Time to update file availability status
|
||||
|
||||
newFilesAvailable = {};
|
||||
let filePeersCheckCount = 0;
|
||||
for (let {sd_hash} of filesInfo) {
|
||||
lbry.getPeersForBlobHash(sd_hash, (peers) => {
|
||||
filePeersCheckCount++;
|
||||
newFilesAvailable[sd_hash] = peers.length >= 0;
|
||||
if (filePeersCheckCount >= filesInfo.length) {
|
||||
this.setState({
|
||||
filesAvailable: newFilesAvailable,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this._fileTimeout = setTimeout(() => { this.updateFilesInfo() }, 1000);
|
||||
})
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
if (this.state.filesInfo === null || (this.props.show == 'downloaded' && this.state.publishedFileSdHashes === null)) {
|
||||
return (
|
||||
<main className="page">
|
||||
<BusyMessage message="Loading" />
|
||||
</main>
|
||||
);
|
||||
} else if (!this.state.filesInfo.length) {
|
||||
return (
|
||||
<main className="page">
|
||||
{this.props.show == 'downloaded'
|
||||
? <span>You haven't downloaded anything from LBRY yet. Go <Link href="/" label="search for your first download" />!</span>
|
||||
: <span>You haven't published anything to LBRY yet.</span>}
|
||||
</main>
|
||||
);
|
||||
} else {
|
||||
var content = [],
|
||||
seenUris = {};
|
||||
|
||||
const filesInfoSorted = this._sortFunctions[this.state.sortBy](this.state.filesInfo);
|
||||
for (let fileInfo of filesInfoSorted) {
|
||||
let {lbry_uri, sd_hash, metadata} = fileInfo;
|
||||
|
||||
if (!metadata || seenUris[lbry_uri]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
seenUris[lbry_uri] = true;
|
||||
content.push(<FileTileStream name={lbry_uri} sdHash={sd_hash} hideOnRemove={true} hidePrice={true} metadata={metadata} />);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<main className="page">
|
||||
<span className='sort-section'>
|
||||
Sort by { ' ' }
|
||||
<FormField type="select" onChange={this.handleSortChanged}>
|
||||
<option value="date">Date</option>
|
||||
<option value="title">Title</option>
|
||||
<option value="filename">File name</option>
|
||||
</FormField>
|
||||
</span>
|
||||
{content}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
});
|
|
@ -347,12 +347,6 @@ input[type="text"], input[type="search"]
|
|||
margin: 0px 6px;
|
||||
}
|
||||
|
||||
.error-modal__error-list {
|
||||
border: 1px solid #eee;
|
||||
padding: 8px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.error-modal-overlay {
|
||||
background: rgba(#000, .88);
|
||||
}
|
||||
|
@ -371,12 +365,15 @@ input[type="text"], input[type="search"]
|
|||
word-break: break-all;
|
||||
}
|
||||
|
||||
|
||||
.error-modal {
|
||||
max-width: none;
|
||||
width: 400px;
|
||||
}
|
||||
.error-modal__error-list { /*shitty hack/temp fix for long errors making modals unusable*/
|
||||
border: 1px solid #eee;
|
||||
padding: 8px;
|
||||
list-style: none;
|
||||
max-height: 400px;
|
||||
max-width: 400px;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue