2016-07-30 10:29:13 +02:00
var searchInputStyle = {
width : '400px' ,
2016-04-10 02:00:56 +02:00
display : 'block' ,
marginBottom : '48px' ,
marginLeft : 'auto' ,
2016-07-30 10:29:13 +02:00
marginRight : 'auto'
2016-04-10 02:00:56 +02:00
} ,
fetchResultsStyle = {
color : '#888' ,
textAlign : 'center' ,
fontSize : '1.2em'
} ;
var SearchActive = React . createClass ( {
render : function ( ) {
return (
< section style = { fetchResultsStyle } >
Looking up the Dewey Decimals
< span className = "busy-indicator" > < / s p a n >
< / s e c t i o n >
) ;
}
} ) ;
var searchNoResultsStyle = {
textAlign : 'center'
} , searchNoResultsMessageStyle = {
fontStyle : 'italic' ,
marginRight : '5px'
} ;
var SearchNoResults = React . createClass ( {
render : function ( ) {
return (
< section style = { searchNoResultsStyle } >
< span style = { searchNoResultsMessageStyle } > No one has checked anything in for { this . props . query } yet . < / s p a n >
< Link label = "Be the first" href = "javascript:alert('aww I do nothing')" / >
< / s e c t i o n >
) ;
}
} ) ;
var SearchResults = React . createClass ( {
render : function ( ) {
var rows = [ ] ;
this . props . results . forEach ( function ( result ) {
rows . push (
2016-06-27 22:40:49 +02:00
< SearchResultRow name = { result . name } title = { result . title } imgUrl = { result . thumbnail }
2016-04-10 02:00:56 +02:00
description = { result . description } cost _est = { result . cost _est } / >
) ;
} ) ;
return (
< section > { rows } < / s e c t i o n >
) ;
}
} ) ;
2016-07-14 03:46:26 +02:00
var
searchRowImgStyle = {
maxWidth : '100%' ,
maxHeight : '250px' ,
2016-04-10 02:00:56 +02:00
display : 'block' ,
marginLeft : 'auto' ,
marginRight : 'auto' ,
float : 'left'
} ,
2016-07-14 03:46:26 +02:00
searchRowTitleStyle = {
fontWeight : 'bold'
} ,
2016-04-10 02:00:56 +02:00
searchRowCostStyle = {
float : 'right' ,
marginLeft : '20px' ,
marginTop : '5px' ,
display : 'inline-block'
} ,
searchRowNameStyle = {
fontSize : '0.9em' ,
color : '#666' ,
marginBottom : '24px' ,
clear : 'both'
} ,
searchRowDescriptionStyle = {
color : '#444' ,
marginBottom : '24px' ,
fontSize : '0.9em'
} ;
var SearchResultRow = React . createClass ( {
2016-04-21 12:55:41 +02:00
getInitialState : function ( ) {
return {
downloading : false
}
} ,
2016-04-10 02:00:56 +02:00
render : function ( ) {
return (
< div className = "row-fluid" >
< div className = "span3" >
2016-04-25 12:58:40 +02:00
< img src = { this . props . imgUrl } alt = { 'Photo for ' + ( this . props . title || this . props . name ) } style = { searchRowImgStyle } / >
2016-04-10 02:00:56 +02:00
< / d i v >
< div className = "span9" >
< span style = { searchRowCostStyle } >
< CreditAmount amount = { this . props . cost _est } isEstimate = { true } / >
< / s p a n >
2016-07-18 18:22:45 +02:00
< h2 style = { searchRowTitleStyle } > < a href = { '/?show=' + this . props . name } > { this . props . title } < / a > < / h 2 >
2016-05-18 14:28:13 +02:00
< div style = { searchRowNameStyle } > lbry : //{this.props.name}</div>
2016-04-10 02:00:56 +02:00
< p style = { searchRowDescriptionStyle } > { this . props . description } < / p >
< div >
2016-05-18 14:28:13 +02:00
< WatchLink streamName = { this . props . name } button = "primary" / >
< DownloadLink streamName = { this . props . name } button = "alt" / >
2016-04-10 02:00:56 +02:00
< / d i v >
< / d i v >
< / d i v >
) ;
}
} ) ;
2016-05-16 15:20:32 +02:00
var featuredContentItemStyle = {
fontSize : '0.95em' ,
2016-07-05 07:39:53 +02:00
marginTop : '10px' ,
2016-07-14 03:46:26 +02:00
maxHeight : '220px'
2016-05-16 15:20:32 +02:00
} , featuredContentItemImgStyle = {
2016-07-14 03:46:26 +02:00
maxWidth : '100%' ,
maxHeight : '100%' ,
2016-05-16 15:20:32 +02:00
display : 'block' ,
marginLeft : 'auto' ,
marginRight : 'auto' ,
2016-05-20 12:01:17 +02:00
marginTop : '5px' ,
2016-07-14 03:46:26 +02:00
} , featuredContentHeaderStyle = {
fontWeight : 'bold' ,
marginBottom : '5px'
} , featuredContentSubheaderStyle = {
marginBottom : '10px' ,
fontSize : '0.9em'
2016-05-16 15:20:32 +02:00
} , featuredContentItemDescriptionStyle = {
color : '#444' ,
marginBottom : '5px' ,
fontSize : '0.9em' ,
} , featuredContentItemCostStyle = {
2016-07-14 03:46:26 +02:00
float : 'right'
2016-05-16 15:20:32 +02:00
} ;
var FeaturedContentItem = React . createClass ( {
2016-07-27 12:25:26 +02:00
_maxDescriptionLength : 250 ,
2016-05-16 15:20:32 +02:00
propTypes : {
name : React . PropTypes . string ,
} ,
getInitialState : function ( ) {
return {
metadata : null ,
title : null ,
2016-07-05 03:55:58 +02:00
amount : 0.0 ,
2016-05-16 15:20:32 +02:00
} ;
} ,
componentWillMount : function ( ) {
lbry . resolveName ( this . props . name , ( metadata ) => {
this . setState ( {
metadata : metadata ,
2016-06-27 22:40:49 +02:00
title : metadata . title || ( 'lbry://' + this . props . name ) ,
2016-05-16 15:20:32 +02:00
} )
} ) ;
2016-07-30 10:23:41 +02:00
lbry . getCostEstimate ( this . props . name , ( amount ) => {
2016-07-05 03:55:58 +02:00
this . setState ( {
2016-07-30 10:23:41 +02:00
amount : amount ,
2016-07-05 03:55:58 +02:00
} ) ;
} ) ;
2016-05-16 15:20:32 +02:00
} ,
render : function ( ) {
if ( this . state . metadata == null ) {
// Still waiting for metadata
return null ;
}
var metadata = this . state . metadata ;
2016-07-05 07:39:53 +02:00
if ( 'narrow' in this . props ) {
// Workaround -- narrow thumbnails look a bit funky without some extra left margin.
// Find a way to do this in CSS.
var thumbStyle = Object . assign ( { } , featuredContentItemImgStyle , {
position : 'relative' ,
maxHeight : '102px' ,
left : '13px' ,
} ) ;
} else {
var thumbStyle = featuredContentItemImgStyle ;
}
2016-05-20 12:01:17 +02:00
return (
< div className = "row-fluid" style = { featuredContentItemStyle } >
< div className = "span4" >
2016-07-05 07:39:53 +02:00
< img src = { metadata . thumbnail } alt = { 'Photo for ' + this . state . title } style = { thumbStyle } / >
2016-05-16 15:20:32 +02:00
< / d i v >
2016-05-20 12:01:17 +02:00
< div className = "span8" >
2016-07-18 00:16:57 +02:00
< h4 style = { featuredContentHeaderStyle } > < a href = { '/?show=' + this . props . name } > { this . state . title } < / a > < / h 4 >
2016-07-14 03:46:26 +02:00
< div style = { featuredContentSubheaderStyle } >
< div style = { featuredContentItemCostStyle } > < CreditAmount amount = { this . state . amount } isEstimate = { true } / > < / d i v >
2016-05-20 12:01:17 +02:00
< WatchLink streamName = { this . props . name } / >
2016-07-14 03:46:26 +02:00
& nbsp ; & nbsp ; & nbsp ;
2016-05-20 12:01:17 +02:00
< DownloadLink streamName = { this . props . name } / >
< / d i v >
2016-07-27 12:25:26 +02:00
< p style = { featuredContentItemDescriptionStyle } > { metadata . description . slice ( 0 , this . _maxDescriptionLength ) +
( metadata . description . length > this . _maxDescriptionLength ? ' ...' : '' ) } < / p >
2016-05-20 12:01:17 +02:00
< / d i v >
< / d i v > ) ;
2016-05-16 15:20:32 +02:00
}
} ) ;
var featuredContentStyle = {
width : '100%' ,
2016-07-05 07:39:53 +02:00
marginTop : '-8px' ,
2016-07-26 14:02:55 +02:00
} , featuredContentLegendStyle = {
fontSize : '12px' ,
color : '#aaa' ,
verticalAlign : '15%' ,
2016-05-16 15:20:32 +02:00
} ;
var FeaturedContent = React . createClass ( {
render : function ( ) {
return ( < section style = { featuredContentStyle } >
2016-07-26 14:02:55 +02:00
< div className = "row-fluid" >
< div className = "span6" >
< h3 > Featured Content < / h 3 >
< / d i v >
< div className = "span6" >
< h3 > Community Content < Link style = { featuredContentLegendStyle } label = "What's this?" tooltip = 'Community Content is a public space where anyone can share content with the rest of the LBRY community. Bid on the names "one," "two," "three" and "four" to put your content here!' / > < / h 3 >
< / d i v >
< / d i v >
2016-05-16 15:20:32 +02:00
< div className = "row-fluid" >
2016-07-05 03:55:58 +02:00
< div className = "span6" >
< FeaturedContentItem name = "what" / >
< / d i v >
< div className = "span6" >
2016-07-27 12:24:10 +02:00
< FeaturedContentItem name = "one" / >
2016-07-26 14:02:55 +02:00
< / d i v >
< / d i v >
< div className = "row-fluid" >
< div className = "span6" >
2016-07-27 12:24:10 +02:00
< FeaturedContentItem name = "itsadisaster" narrow / >
2016-07-26 14:02:55 +02:00
< / d i v >
< div className = "span6" >
< FeaturedContentItem name = "two" / >
2016-07-14 03:46:26 +02:00
< / d i v >
< / d i v >
< div className = "row-fluid" >
< div className = "span6" >
< FeaturedContentItem name = "keynesvhayek" / >
< / d i v >
2016-07-26 14:02:55 +02:00
< div className = "span6" >
< FeaturedContentItem name = "three" / >
< / d i v >
< / d i v >
< div className = "row-fluid" >
2016-07-14 03:46:26 +02:00
< div className = "span6" >
2016-07-05 03:55:58 +02:00
< FeaturedContentItem name = "meetlbry1" / >
< / d i v >
2016-07-26 14:02:55 +02:00
< div className = "span6" >
< FeaturedContentItem name = "four" / >
< / d i v >
2016-05-16 15:20:32 +02:00
< / d i v >
< / s e c t i o n > ) ;
}
} ) ;
2016-04-10 02:00:56 +02:00
var discoverMainStyle = {
color : '#333'
} ;
var Discover = React . createClass ( {
userTypingTimer : null ,
getInitialState : function ( ) {
return {
results : [ ] ,
searching : false ,
query : ''
} ;
} ,
search : function ( ) {
if ( this . state . query )
{
console . log ( 'search' ) ;
lbry . search ( this . state . query , this . searchCallback . bind ( this , this . state . query ) ) ;
}
else
{
this . setState ( {
searching : false ,
results : [ ]
} ) ;
}
} ,
searchCallback : function ( originalQuery , results ) {
if ( this . state . searching ) //could have canceled while results were pending, in which case nothing to do
{
this . setState ( {
results : results ,
searching : this . state . query != originalQuery , //multiple searches can be out, we're only done if we receive one we actually care about
} ) ;
}
} ,
onQueryChange : function ( event ) {
if ( this . userTypingTimer )
{
clearTimeout ( this . userTypingTimer ) ;
}
//@TODO: Switch to React.js timing
this . userTypingTimer = setTimeout ( this . search , 800 ) ; // 800ms delay, tweak for faster/slower
this . setState ( {
searching : event . target . value . length > 0 ,
query : event . target . value
} ) ;
} ,
render : function ( ) {
console . log ( this . state ) ;
return (
< main style = { discoverMainStyle } >
2016-07-30 10:29:13 +02:00
< section > < input type = "search" style = { searchInputStyle } onChange = { this . onQueryChange }
placeholder = "Find movies, music, games, and more" / > < / s e c t i o n >
2016-04-10 02:00:56 +02:00
{ this . state . searching ? < SearchActive / > : null }
2016-05-18 14:49:08 +02:00
{ ! this . state . searching && this . state . query && this . state . results . length ? < SearchResults results = { this . state . results } / > : null }
{ ! this . state . searching && this . state . query && ! this . state . results . length ? < SearchNoResults query = { this . state . query } / > : null }
2016-07-05 03:55:58 +02:00
{ ! this . state . query && ! this . state . searching ? < FeaturedContent / > : null }
2016-04-10 02:00:56 +02:00
< / m a i n >
) ;
}
} ) ;
var logoStyle = {
padding : '48px 12px' ,
textAlign : 'center' ,
maxHeight : '80px' ,
} ,
imgStyle = { //@TODO: remove this, img should be properly scaled once size is settled
height : '80px'
} ;
var Header = React . createClass ( {
render : function ( ) {
return (
< header >
2016-04-20 13:51:31 +02:00
< TopBar / >
2016-04-10 02:00:56 +02:00
< div style = { logoStyle } >
< img src = "./img/lbry-dark-1600x528.png" style = { imgStyle } / >
< / d i v >
< / h e a d e r >
) ;
}
} ) ;
var topBarStyle = {
2016-05-23 15:56:21 +02:00
'float' : 'right' ,
'position' : 'relative' ,
'height' : '26px' ,
2016-05-20 13:20:35 +02:00
} ,
2016-04-10 02:00:56 +02:00
balanceStyle = {
2016-07-05 07:39:53 +02:00
'marginRight' : '5px' ,
'position' : 'relative' ,
'top' : '1px' ,
2016-04-10 02:00:56 +02:00
} ;
2016-05-23 15:56:21 +02:00
var mainMenuStyle = {
position : 'absolute' ,
top : '26px' ,
right : '0px' ,
} ;
var MainMenu = React . createClass ( {
render : function ( ) {
2016-05-23 19:00:04 +02:00
var isLinux = /linux/i . test ( navigator . userAgent ) ; // @TODO: find a way to use getVersionInfo() here without messy state management
2016-07-19 04:37:19 +02:00
2016-05-23 15:56:21 +02:00
return (
2016-05-28 12:22:09 +02:00
< div style = { mainMenuStyle } >
< Menu { ... this . props } >
2016-05-27 13:07:21 +02:00
< MenuItem href = '/?files' label = "My Files" icon = 'icon-cloud-download' / >
2016-07-19 04:37:19 +02:00
< MenuItem href = '/?wallet' label = "My Wallet" icon = 'icon-bank' / >
2016-05-27 13:07:21 +02:00
< MenuItem href = '/?settings' label = "Settings" icon = 'icon-gear' / >
2016-07-15 14:04:47 +02:00
< MenuItem href = '/?publish' label = "Publish" icon = 'icon-upload' / >
2016-05-27 13:07:21 +02:00
< MenuItem href = '/?help' label = "Help" icon = 'icon-question-circle' / >
{ isLinux ? < MenuItem href = "/?start" label = "Exit LBRY" icon = "icon-close" / >
: null }
< / M e n u >
2016-05-23 15:56:21 +02:00
< / d i v >
) ;
}
} ) ;
2016-04-10 02:00:56 +02:00
var TopBar = React . createClass ( {
getInitialState : function ( ) {
return {
2016-04-20 13:51:31 +02:00
balance : 0 ,
2016-04-10 02:00:56 +02:00
} ;
} ,
componentDidMount : function ( ) {
lbry . getBalance ( function ( balance ) {
this . setState ( {
balance : balance
} ) ;
} . bind ( this ) ) ;
} ,
2016-05-23 15:56:21 +02:00
onClose : function ( ) {
window . location . href = "?start" ;
} ,
2016-04-10 02:00:56 +02:00
render : function ( ) {
return (
< span className = 'top-bar' style = { topBarStyle } >
< span style = { balanceStyle } >
< CreditAmount amount = { this . state . balance } / >
< / s p a n >
2016-05-28 12:22:09 +02:00
< Link ref = "menuButton" title = "LBRY Menu" icon = "icon-bars" / >
< MainMenu toggleButton = { this . refs . menuButton } / >
2016-04-10 02:00:56 +02:00
< / s p a n >
) ;
}
} ) ;
var HomePage = React . createClass ( {
2016-05-09 23:25:34 +02:00
componentDidMount : function ( ) {
lbry . getStartNotice ( function ( notice ) {
if ( notice ) {
alert ( notice ) ;
}
} ) ;
} ,
2016-04-10 02:00:56 +02:00
render : function ( ) {
return (
2016-05-23 14:16:14 +02:00
< div className = "page" >
2016-04-10 02:00:56 +02:00
< Header / >
< Discover / >
< / d i v >
) ;
}
2016-04-20 13:51:31 +02:00
} ) ;