2016-12-23 07:57:01 +01:00
import React from 'react' ;
import lbry from '../lbry.js' ;
import { Link , DownloadLink , WatchLink } from '../component/link.js' ;
import { Thumbnail , TruncatedText , CreditAmount } from '../component/common.js' ;
let FileTile = React . createClass ( {
2017-01-02 08:01:55 +01:00
_isMounted : false ,
2017-01-09 04:41:04 +01:00
_fileInfoCheckInterval : 5000 ,
2017-01-02 08:01:55 +01:00
2016-12-25 06:12:50 +01:00
propTypes : {
2017-01-06 12:27:43 +01:00
metadata : React . PropTypes . object . isRequired ,
2017-01-09 04:36:49 +01:00
fileInfo : React . PropTypes . string ,
2017-01-06 12:27:43 +01:00
name : React . PropTypes . string ,
sdHash : React . PropTypes . string ,
available : React . PropTypes . bool ,
isMine : React . PropTypes . bool ,
local : React . PropTypes . bool ,
2016-12-25 06:12:50 +01:00
cost : React . PropTypes . number ,
2017-01-06 12:27:43 +01:00
costIncludesData : React . PropTypes . bool ,
2016-12-25 06:12:50 +01:00
} ,
2017-01-02 08:01:55 +01:00
updateFileInfo : function ( progress = null ) {
2017-01-09 04:41:04 +01:00
const updateFileInfoCallback = ( ( fileInfo ) => {
2017-01-02 08:01:55 +01:00
if ( ! this . _isMounted || 'fileInfo' in this . props ) {
/ * *
* The component was unmounted , or a file info data structure has now been provided by the
* containing component .
* /
return ;
}
this . setState ( {
2017-01-06 12:27:43 +01:00
fileInfo : fileInfo || null ,
local : ! ! fileInfo ,
2017-01-02 08:01:55 +01:00
} ) ;
2017-01-09 04:41:04 +01:00
setTimeout ( ( ) => { this . updateFileInfo ( ) } , this . _fileInfoCheckInterval ) ;
2017-01-02 08:01:55 +01:00
} ) ;
if ( 'sdHash' in this . props ) {
2017-01-09 04:41:04 +01:00
lbry . getFileInfoBySdHash ( this . props . sdHash , updateFileInfoCallback ) ;
2017-01-06 12:27:43 +01:00
this . getIsMineIfNeeded ( this . props . sdHash ) ;
2017-01-02 08:01:55 +01:00
} else if ( 'name' in this . props ) {
2017-01-06 12:27:43 +01:00
lbry . getFileInfoByName ( this . props . name , ( fileInfo ) => {
this . getIsMineIfNeeded ( fileInfo . sd _hash ) ;
2017-01-09 04:41:04 +01:00
updateFileInfoCallback ( fileInfo ) ;
2017-01-06 12:27:43 +01:00
} ) ;
2017-01-02 08:01:55 +01:00
} else {
throw new Error ( "No progress, stream name or sd hash passed to FileTile" ) ;
}
} ,
2017-01-06 12:27:43 +01:00
getIsMineIfNeeded : function ( sdHash ) {
if ( this . state . isMine !== null ) {
// The info was already provided by this.props.isMine
return ;
}
lbry . getMyClaims ( ( claimsInfo ) => {
for ( let { value } of claimsInfo ) {
if ( JSON . parse ( value ) . sources . lbry _sd _hash == sdHash ) {
this . setState ( {
isMine : true ,
} ) ;
return ;
}
}
this . setState ( {
isMine : false ,
} ) ;
} ) ;
} ,
2016-12-23 07:57:01 +01:00
getInitialState : function ( ) {
return {
downloading : false ,
isHovered : false ,
cost : null ,
costIncludesData : null ,
2017-01-02 08:01:55 +01:00
fileInfo : 'fileInfo' in this . props ? this . props . fileInfo : null ,
2017-01-06 12:27:43 +01:00
isMine : 'isMine' in this . props ? this . props . isMine : null ,
local : 'local' in this . props ? this . props . local : null ,
2016-12-23 07:57:01 +01:00
}
} ,
2016-12-25 06:12:50 +01:00
getDefaultProps : function ( ) {
return {
compact : false ,
}
} ,
2016-12-23 07:57:01 +01:00
handleMouseOver : function ( ) {
this . setState ( {
isHovered : true ,
} ) ;
} ,
handleMouseOut : function ( ) {
this . setState ( {
isHovered : false ,
} ) ;
} ,
componentWillMount : function ( ) {
2017-01-06 12:27:43 +01:00
this . updateFileInfo ( ) ;
2016-12-23 07:57:01 +01:00
if ( 'cost' in this . props ) {
this . setState ( {
cost : this . props . cost ,
costIncludesData : this . props . costIncludesData ,
} ) ;
} else {
lbry . getCostInfoForName ( this . props . name , ( { cost , includesData } ) => {
this . setState ( {
cost : cost ,
costIncludesData : includesData ,
} ) ;
} ) ;
}
} ,
2017-01-02 08:01:55 +01:00
componentDidMount : function ( ) {
this . _isMounted = true ;
} ,
componentWillUnmount : function ( ) {
this . _isMounted = false ;
} ,
2016-12-23 07:57:01 +01:00
render : function ( ) {
2017-01-06 12:27:43 +01:00
if ( this . state . isMine === null || this . state . local === null ) {
// Can't render until we know whether we own the file and if we have a local copy
return null ;
}
2017-01-02 08:01:55 +01:00
const obscureNsfw = ! lbry . getClientSetting ( 'showNsfw' ) && this . props . nsfw ;
let downloadLinkExtraProps = { } ;
2017-01-06 12:27:43 +01:00
if ( this . state . fileInfo === null ) {
downloadLinkExtraProps . state = 'not-started' ;
} else if ( ! this . state . fileInfo . completed ) {
downloadLinkExtraProps . state = 'downloading' ;
const { written _bytes , total _bytes , path } = this . state . fileInfo ;
downloadLinkExtraProps . progress = written _bytes / total _bytes ;
} else {
downloadLinkExtraProps . state = 'done' ;
downloadLinkExtraProps . path = this . state . fileInfo . download _path ;
2017-01-02 08:01:55 +01:00
}
2016-12-23 07:57:01 +01:00
return (
< section className = { 'file-tile card ' + ( obscureNsfw ? 'card-obscured ' : '' ) + ( this . props . compact ? 'file-tile--compact' : '' ) } onMouseEnter = { this . handleMouseOver } onMouseLeave = { this . handleMouseOut } >
< div className = "row-fluid card-content file-tile__row" >
< div className = "span3" >
2017-01-06 12:27:43 +01:00
< a href = { '/?show=' + this . props . name } > < Thumbnail className = "file-tile__thumbnail" src = { this . props . metadata . thumbnail } alt = { 'Photo for ' + ( this . props . metadata . title || this . props . name ) } / > < / a >
2016-12-23 07:57:01 +01:00
< / d i v >
< div className = "span9" >
2017-01-06 12:27:43 +01:00
{ this . state . cost !== null && ! this . state . local
2016-12-23 07:57:01 +01:00
? < span className = "file-tile__cost" >
< CreditAmount amount = { this . state . cost } isEstimate = { ! this . state . costIncludesData } / >
< / s p a n >
: null }
< div className = "meta" > < a href = { '/?show=' + this . props . name } > lbry : //{this.props.name}</a></div>
< h3 className = { 'file-tile__title ' + ( this . props . compact ? 'file-tile__title--compact' : '' ) } >
< a href = { '/?show=' + this . props . name } >
< TruncatedText lines = { 3 } >
2017-01-06 12:27:43 +01:00
{ this . props . metadata . title }
2016-12-23 07:57:01 +01:00
< / T r u n c a t e d T e x t >
< / a >
< / h 3 >
< div >
2017-01-06 12:27:43 +01:00
{ this . props . metadata . content _type . startsWith ( 'video/' ) ? < WatchLink streamName = { this . props . name } button = "primary" / > : null }
2016-12-26 06:59:15 +01:00
{ ! this . props . isMine
2017-01-09 11:43:57 +01:00
? < DownloadLink streamName = { this . props . name } metadata = { this . props . metadata } button = "text" { ... downloadLinkExtraProps } / >
2016-12-26 06:59:15 +01:00
: null }
< / d i v >
2016-12-23 07:57:01 +01:00
< p className = "file-tile__description" >
< TruncatedText lines = { 3 } >
2017-01-06 12:27:43 +01:00
{ this . props . metadata . description }
2016-12-23 07:57:01 +01:00
< / T r u n c a t e d T e x t >
< / p >
< / d i v >
< / d i v >
2016-12-23 08:02:05 +01:00
{ obscureNsfw && this . state . isHovered
? < div className = 'card-overlay' >
2016-12-23 07:57:01 +01:00
< p >
This content is Not Safe For Work .
To view adult content , please change your < Link href = "?settings" label = "Settings" / > .
< / p >
< / d i v >
2016-12-23 08:02:05 +01:00
: null }
2016-12-23 07:57:01 +01:00
< / s e c t i o n >
) ;
}
} ) ;
export default FileTile ;