2016-12-23 01:57:01 -05:00
import React from 'react' ;
import lbry from '../lbry.js' ;
2017-04-18 15:14:42 -04:00
import lbryuri from '../lbryuri.js' ;
2017-01-21 16:31:41 -05:00
import { Link } from '../component/link.js' ;
2017-01-12 21:03:34 -05:00
import { FileActions } from '../component/file-actions.js' ;
2017-04-13 14:52:26 -04:00
import { Thumbnail , TruncatedText , FilePrice } from '../component/common.js' ;
2017-04-11 22:01:45 -04:00
import UriIndicator from '../component/channel-indicator.js' ;
2016-12-23 01:57:01 -05:00
2017-01-12 22:23:12 -05:00
/*should be merged into FileTile once FileTile is refactored to take a single id*/
2017-01-13 12:13:46 -05:00
export let FileTileStream = React . createClass ( {
2017-01-13 17:47:48 -05:00
_fileInfoSubscribeId : null ,
_isMounted : null ,
2017-01-12 21:03:34 -05:00
propTypes : {
2017-04-08 02:34:51 -04:00
uri : React . PropTypes . string ,
2017-04-13 16:35:40 -04:00
metadata : React . PropTypes . object ,
2017-04-10 21:24:35 -04:00
contentType : React . PropTypes . string . isRequired ,
2017-03-08 02:17:16 -05:00
outpoint : React . PropTypes . string ,
2017-04-10 21:24:35 -04:00
hasSignature : React . PropTypes . bool ,
signatureIsValid : React . PropTypes . bool ,
2017-01-13 17:47:48 -05:00
hideOnRemove : React . PropTypes . bool ,
2017-01-13 12:13:46 -05:00
hidePrice : React . PropTypes . bool ,
2017-01-13 17:18:37 -05:00
obscureNsfw : React . PropTypes . bool
2017-01-06 06:27:43 -05:00
} ,
2016-12-23 01:57:01 -05:00
getInitialState : function ( ) {
return {
2017-01-12 21:03:34 -05:00
showNsfwHelp : false ,
2017-01-19 04:58:11 -05:00
isHidden : false ,
2016-12-23 01:57:01 -05:00
}
} ,
2016-12-25 00:12:50 -05:00
getDefaultProps : function ( ) {
return {
2017-01-12 21:03:34 -05:00
obscureNsfw : ! lbry . getClientSetting ( 'showNsfw' ) ,
2017-04-10 21:24:35 -04:00
hidePrice : false ,
hasSignature : false ,
2016-12-25 00:12:50 -05:00
}
} ,
2017-01-13 17:47:48 -05:00
componentDidMount : function ( ) {
this . _isMounted = true ;
if ( this . props . hideOnRemove ) {
2017-03-26 14:30:18 -04:00
this . _fileInfoSubscribeId = lbry . fileInfoSubscribe ( this . props . outpoint , this . onFileInfoUpdate ) ;
2017-01-13 17:47:48 -05:00
}
} ,
componentWillUnmount : function ( ) {
if ( this . _fileInfoSubscribeId ) {
2017-03-08 02:17:16 -05:00
lbry . fileInfoUnsubscribe ( this . props . outpoint , this . _fileInfoSubscribeId ) ;
2017-01-13 17:47:48 -05:00
}
} ,
onFileInfoUpdate : function ( fileInfo ) {
if ( ! fileInfo && this . _isMounted && this . props . hideOnRemove ) {
this . setState ( {
isHidden : true
} ) ;
}
} ,
2016-12-23 01:57:01 -05:00
handleMouseOver : function ( ) {
2017-04-10 21:24:35 -04:00
if ( this . props . obscureNsfw && this . props . metadata && this . props . metadata . nsfw ) {
2017-01-12 21:03:34 -05:00
this . setState ( {
showNsfwHelp : true ,
} ) ;
}
2016-12-23 01:57:01 -05:00
} ,
handleMouseOut : function ( ) {
2017-01-12 21:03:34 -05:00
if ( this . state . showNsfwHelp ) {
this . setState ( {
showNsfwHelp : false ,
} ) ;
}
2016-12-23 01:57:01 -05:00
} ,
render : function ( ) {
2017-01-21 01:52:32 -05:00
if ( this . state . isHidden ) {
2017-01-13 17:47:48 -05:00
return null ;
}
2017-04-18 15:14:42 -04:00
const uri = lbryuri . normalize ( this . props . uri ) ;
2017-04-10 21:24:35 -04:00
const metadata = this . props . metadata ;
2017-04-13 16:35:40 -04:00
const isConfirmed = ! ! metadata ;
2017-04-18 15:14:42 -04:00
const title = isConfirmed ? metadata . title : uri ;
2017-01-30 02:26:30 -05:00
const obscureNsfw = this . props . obscureNsfw && isConfirmed && metadata . nsfw ;
2016-12-23 01:57:01 -05:00
return (
2017-04-10 08:32:40 -04:00
< section className = { 'file-tile card ' + ( obscureNsfw ? 'card--obscured ' : '' ) } onMouseEnter = { this . handleMouseOver } onMouseLeave = { this . handleMouseOut } >
< div className = { "row-fluid card__inner file-tile__row" } >
2017-04-17 08:27:39 -04:00
< div className = "span3 file-tile__thumbnail-container" >
2017-04-18 15:14:42 -04:00
< a href = { '?show=' + uri } > < Thumbnail className = "file-tile__thumbnail" { ... metadata && metadata . thumbnail ? { src : metadata . thumbnail } : { } } alt = { 'Photo for ' + this . props . uri } / > < / a >
2016-12-23 01:57:01 -05:00
< / d i v >
< div className = "span9" >
2017-04-10 08:32:40 -04:00
< div className = "card__title-primary" >
2017-04-17 08:27:39 -04:00
{ ! this . props . hidePrice
? < FilePrice uri = { this . props . uri } / >
: null }
2017-04-18 15:14:42 -04:00
< div className = "meta" > < a href = { '?show=' + this . props . uri } > { uri } < / a > < / d i v >
2017-04-10 08:32:40 -04:00
< h3 >
2017-04-19 15:54:57 -04:00
< a href = { '?show=' + uri } title = { title } >
2017-04-10 08:32:40 -04:00
< TruncatedText lines = { 1 } >
{ title }
< / T r u n c a t e d T e x t >
< / a >
< / h 3 >
< / d i v >
< div className = "card__content" >
< p className = "file-tile__description" >
2017-04-17 08:27:39 -04:00
< TruncatedText lines = { 2 } >
2017-04-10 08:32:40 -04:00
{ isConfirmed
2017-04-11 22:01:45 -04:00
? metadata . description
: < span className = "empty" > This file is pending confirmation . < / s p a n > }
2017-04-10 08:32:40 -04:00
< / T r u n c a t e d T e x t >
2017-04-11 22:01:45 -04:00
< / p >
< / d i v >
2017-04-10 08:32:40 -04:00
< / d i v >
< / d i v >
{ this . state . showNsfwHelp
? < div className = 'card-overlay' >
< p >
This content is Not Safe For Work .
To view adult content , please change your < Link className = "button-text" href = "?settings" label = "Settings" / > .
< / p >
< / d i v >
: null }
< / s e c t i o n >
) ;
}
} ) ;
export let FileCardStream = React . createClass ( {
_fileInfoSubscribeId : null ,
_isMounted : null ,
2017-04-10 14:12:07 -04:00
_metadata : null ,
2017-04-10 08:32:40 -04:00
propTypes : {
2017-04-10 14:12:07 -04:00
uri : React . PropTypes . string ,
claimInfo : React . PropTypes . object ,
2017-04-10 08:32:40 -04:00
outpoint : React . PropTypes . string ,
hideOnRemove : React . PropTypes . bool ,
hidePrice : React . PropTypes . bool ,
obscureNsfw : React . PropTypes . bool
} ,
getInitialState : function ( ) {
return {
showNsfwHelp : false ,
isHidden : false ,
}
} ,
getDefaultProps : function ( ) {
return {
obscureNsfw : ! lbry . getClientSetting ( 'showNsfw' ) ,
2017-04-11 22:01:45 -04:00
hidePrice : false ,
hasSignature : false ,
2017-04-10 08:32:40 -04:00
}
} ,
componentDidMount : function ( ) {
this . _isMounted = true ;
if ( this . props . hideOnRemove ) {
this . _fileInfoSubscribeId = lbry . fileInfoSubscribe ( this . props . outpoint , this . onFileInfoUpdate ) ;
}
} ,
componentWillUnmount : function ( ) {
if ( this . _fileInfoSubscribeId ) {
lbry . fileInfoUnsubscribe ( this . props . outpoint , this . _fileInfoSubscribeId ) ;
}
} ,
onFileInfoUpdate : function ( fileInfo ) {
if ( ! fileInfo && this . _isMounted && this . props . hideOnRemove ) {
this . setState ( {
isHidden : true
} ) ;
}
} ,
handleMouseOver : function ( ) {
2017-04-11 22:01:45 -04:00
this . setState ( {
hovered : true ,
} ) ;
2017-04-10 08:32:40 -04:00
} ,
handleMouseOut : function ( ) {
2017-04-11 22:01:45 -04:00
this . setState ( {
hovered : false ,
} ) ;
2017-04-10 08:32:40 -04:00
} ,
render : function ( ) {
if ( this . state . isHidden ) {
return null ;
}
2017-04-18 15:14:42 -04:00
const uri = lbryuri . normalize ( this . props . uri ) ;
2017-04-10 08:32:40 -04:00
const metadata = this . props . metadata ;
2017-04-13 16:35:40 -04:00
const isConfirmed = ! ! metadata ;
2017-04-18 15:14:42 -04:00
const title = isConfirmed ? metadata . title : uri ;
2017-04-10 08:32:40 -04:00
const obscureNsfw = this . props . obscureNsfw && isConfirmed && metadata . nsfw ;
2017-04-18 15:14:42 -04:00
const primaryUrl = '?show=' + uri ;
2017-04-10 08:32:40 -04:00
return (
2017-04-11 22:01:45 -04:00
< section className = { 'card card--small card--link ' + ( obscureNsfw ? 'card--obscured ' : '' ) } onMouseEnter = { this . handleMouseOver } onMouseLeave = { this . handleMouseOut } >
2017-04-10 08:32:40 -04:00
< div className = "card__inner" >
2017-04-11 22:01:45 -04:00
< a href = { primaryUrl } className = "card__link" >
< div className = "card__title-identity" >
2017-04-19 15:54:57 -04:00
< h5 title = { title } > < TruncatedText lines = { 1 } > { title } < / T r u n c a t e d T e x t > < / h 5 >
2017-04-11 22:01:45 -04:00
< div className = "card__subtitle" >
2017-04-13 14:52:26 -04:00
{ ! this . props . hidePrice ? < span style = { { float : "right" } } > < FilePrice uri = { this . props . uri } metadata = { metadata } / > < / s p a n > : n u l l }
2017-04-18 15:14:42 -04:00
< UriIndicator uri = { uri } metadata = { metadata } contentType = { this . props . contentType }
2017-04-11 22:01:45 -04:00
hasSignature = { this . props . hasSignature } signatureIsValid = { this . props . signatureIsValid } / >
< / d i v >
< / d i v >
< div className = "card__media" style = { { backgroundImage : "url('" + metadata . thumbnail + "')" } } > < / d i v >
< div className = "card__content card__subtext card__subtext--two-lines" >
< TruncatedText lines = { 2 } >
{ isConfirmed
? metadata . description
: < span className = "empty" > This file is pending confirmation . < / s p a n > }
2016-12-23 01:57:01 -05:00
< / T r u n c a t e d T e x t >
2017-04-11 22:01:45 -04:00
< / d i v >
< / a >
{ this . state . showNsfwHelp && this . state . hovered
? < div className = 'card-overlay' >
< p >
This content is Not Safe For Work .
To view adult content , please change your < Link className = "button-text" href = "?settings" label = "Settings" / > .
< / p >
< / d i v >
2017-04-10 08:32:40 -04:00
: null }
2016-12-23 01:57:01 -05:00
< / d i v >
< / s e c t i o n >
) ;
}
} ) ;
2017-01-13 12:13:46 -05:00
export let FileTile = React . createClass ( {
2017-01-12 22:23:12 -05:00
_isMounted : false ,
propTypes : {
2017-04-08 02:34:51 -04:00
uri : React . PropTypes . string . isRequired ,
2017-01-12 22:23:12 -05:00
} ,
getInitialState : function ( ) {
return {
2017-03-08 02:17:16 -05:00
outpoint : null ,
2017-04-08 02:34:51 -04:00
claimInfo : null
2017-01-12 22:23:12 -05:00
}
} ,
2017-04-30 23:38:14 -04:00
resolve : function ( uri ) {
lbry . resolve ( { uri : uri } ) . then ( ( resolutionInfo ) => {
2017-04-13 14:52:26 -04:00
if ( this . _isMounted && resolutionInfo && resolutionInfo . claim && resolutionInfo . claim . value &&
2017-04-30 23:38:14 -04:00
resolutionInfo . claim . value . stream && resolutionInfo . claim . value . stream . metadata ) {
2017-02-19 18:45:03 -05:00
// In case of a failed lookup, metadata will be null, in which case the component will never display
2017-01-12 22:23:12 -05:00
this . setState ( {
2017-04-13 14:52:26 -04:00
claimInfo : resolutionInfo . claim ,
2017-01-12 22:23:12 -05:00
} ) ;
}
} ) ;
} ,
2017-04-30 23:38:14 -04:00
componentWillReceiveProps : function ( nextProps ) {
if ( nextProps . uri != this . props . uri ) {
this . setState ( this . getInitialState ( ) ) ;
this . resolve ( nextProps . uri ) ;
}
} ,
componentDidMount : function ( ) {
this . _isMounted = true ;
this . resolve ( this . props . uri ) ;
} ,
2017-01-12 22:23:12 -05:00
componentWillUnmount : function ( ) {
this . _isMounted = false ;
} ,
render : function ( ) {
2017-04-10 21:24:35 -04:00
if ( ! this . state . claimInfo ) {
2017-04-17 17:51:18 -04:00
if ( this . props . displayStyle == 'card' ) {
return < FileCardStream outpoint = { null } metadata = { { title : this . props . uri , description : "Loading..." } } contentType = { null } hidePrice = { true }
hasSignature = { false } signatureIsValid = { false } uri = { this . props . uri } / >
}
2017-04-30 23:38:14 -04:00
if ( this . props . showEmpty )
{
return < div className = "empty" > Empty file tile for { this . props . uri } < / d i v >
}
2017-01-12 22:23:12 -05:00
return null ;
}
2017-04-10 21:24:35 -04:00
const { txid , nout , has _signature , signature _is _valid ,
value : { stream : { metadata , source : { contentType } } } } = this . state . claimInfo ;
2017-04-11 22:01:45 -04:00
2017-04-10 14:12:07 -04:00
return this . props . displayStyle == 'card' ?
< FileCardStream outpoint = { txid + ':' + nout } metadata = { metadata } contentType = { contentType }
hasSignature = { has _signature } signatureIsValid = { signature _is _valid } { ... this . props } / > :
< FileTileStream outpoint = { txid + ':' + nout } metadata = { metadata } contentType = { contentType }
hasSignature = { has _signature } signatureIsValid = { signature _is _valid } { ... this . props } / > ;
2017-01-12 22:23:12 -05:00
}
2017-01-24 22:19:38 -05:00
} ) ;