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