import React from 'react'; import lbry from '../lbry.js'; import {Link, WatchLink} from '../component/link.js'; import {Menu, MenuItem} from '../component/menu.js'; import FormField from '../component/form.js'; import FileTile from '../component/file-tile.js'; import Modal from '../component/modal.js'; import {BusyMessage, Thumbnail} from '../component/common.js'; var moreMenuStyle = { position: 'absolute', display: 'block', top: '26px', right: '13px', }; var MyFilesRowMoreMenu = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired, path: React.PropTypes.string.isRequired, completed: React.PropTypes.bool.isRequired, lbryUri: React.PropTypes.string.isRequired, }, handleRevealClicked: function() { lbry.revealFile(this.props.path); }, handleRemoveClicked: function() { lbry.deleteFile(this.props.lbryUri, false); }, handleDeleteClicked: function() { this.setState({ modal: 'confirmDelete', }); }, handleDeleteConfirmed: function() { lbry.deleteFile(this.props.lbryUri); this.setState({ modal: null, }); }, closeModal: function() { this.setState({ modal: null, }); }, getInitialState: function() { return { modal: null, }; }, render: function() { return (
{/* @TODO: Switch to OS specific wording */}
Are you sure you'd like to delete {this.props.title}? This will {this.props.completed ? ' stop the download and ' : ''} permanently remove the file from your system.
); } }); var moreButtonColumnStyle = { height: '120px', display: 'flex', alignItems: 'center', justifyContent: 'center', }, moreButtonContainerStyle = { display: 'block', position: 'relative', }, moreButtonStyle = { fontSize: '1.3em', }, progressBarStyle = { height: '15px', width: '230px', backgroundColor: '#444', border: '2px solid #eee', display: 'inline-block', }, artStyle = { maxHeight: '100px', maxWidth: '100%', display: 'block', marginLeft: 'auto', marginRight: 'auto', }; var 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: {}, 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 {completed, written_bytes, total_bytes, lbry_uri, file_name, download_path, stopped, metadata, sd_hash} = fileInfo; if (!metadata || seenUris[lbry_uri]) { continue; } seenUris[lbry_uri] = true; let {title, thumbnail} = metadata; if (!fileInfo.pending && typeof metadata == 'object') { var {title, thumbnail} = metadata; var pending = false; } else { var title = null; var thumbnail = null; var pending = true; } var ratioLoaded = written_bytes / total_bytes; var mediaType = lbry.getMediaType(metadata.content_type, file_name); var showWatchButton = (mediaType == 'video'); content.push(); } } return (
Sort by { ' ' } {content}
); } }); export default MyFilesPage;