@@ -116,7 +106,7 @@ export let FileTileStream = React.createClass({
-
+
{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;
}
diff --git a/js/lbry.js b/js/lbry.js
index d79bb8454..925f13b34 100644
--- a/js/lbry.js
+++ b/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];
}
diff --git a/js/page/file-list.js b/js/page/file-list.js
new file mode 100644
index 000000000..9b4a7674f
--- /dev/null
+++ b/js/page/file-list.js
@@ -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 (
+
+
+
+ );
+ } else if (!this.state.fileInfos.length) {
+ return (
+
+ You haven't downloaded anything from LBRY yet. Go !
+
+ );
+ } else {
+ return (
+
+
+
+ );
+ }
+ }
+});
+
+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 (
+
+
+
+ );
+ }
+ else if (!this.state.fileInfos.length) {
+ return (
+
+ You haven't published anything to LBRY yet. Try !
+
+ );
+ }
+ else {
+ return (
+
+
+
+ );
+ }
+ }
+});
+
+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();
+ }
+
+ return (
+
+
+ Sort by { ' ' }
+
+
+
+
+
+
+ {content}
+
+ );
+ }
+});
\ No newline at end of file
diff --git a/js/page/my_files.js b/js/page/my_files.js
deleted file mode 100644
index 6571e7291..000000000
--- a/js/page/my_files.js
+++ /dev/null
@@ -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 (
-
-
-
- );
- } else if (!this.state.filesInfo.length) {
- return (
-
- {this.props.show == 'downloaded'
- ? You haven't downloaded anything from LBRY yet. Go !
- : You haven't published anything to LBRY yet.}
-
- );
- } 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();
- }
- }
- return (
-
-
- Sort by { ' ' }
-
-
-
-
-
-
- {content}
-
- );
- }
-});
\ No newline at end of file
diff --git a/scss/_gui.scss b/scss/_gui.scss
index 137c60b24..7a464a794 100644
--- a/scss/_gui.scss
+++ b/scss/_gui.scss
@@ -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;
}