2016-11-22 14:19:08 -06:00
import React from 'react' ;
2017-04-23 16:56:50 +07:00
import lbryuri from 'lbryuri.js' ;
import { Icon , CreditAmount } from 'component/common.js' ;
2017-04-07 12:15:22 +07:00
import Link from 'component/link' ;
2016-11-22 14:19:08 -06:00
2017-04-22 20:17:01 +07:00
let Header = React . createClass ( {
2017-04-26 23:54:53 -04:00
_balanceSubscribeId : null ,
2017-04-27 09:17:18 -04:00
_isMounted : false ,
2017-04-26 23:54:53 -04:00
2017-04-30 23:38:14 -04:00
propTypes : {
onSearch : React . PropTypes . func . isRequired ,
onSubmit : React . PropTypes . func . isRequired
} ,
2016-08-07 18:13:17 -04:00
getInitialState : function ( ) {
return {
2017-04-26 23:54:53 -04:00
balance : 0
2016-08-07 18:13:17 -04:00
} ;
} ,
2016-08-07 22:48:45 -04:00
componentDidMount : function ( ) {
2017-04-27 09:17:18 -04:00
this . _isMounted = true ;
2017-04-26 23:54:53 -04:00
this . _balanceSubscribeId = lbry . balanceSubscribe ( ( balance ) => {
2017-04-27 09:17:18 -04:00
if ( this . _isMounted ) {
this . setState ( { balance : balance } ) ;
}
2017-04-26 23:54:53 -04:00
} ) ;
2016-08-07 20:20:14 -04:00
} ,
2016-08-07 22:48:45 -04:00
componentWillUnmount : function ( ) {
2017-04-27 09:17:18 -04:00
this . _isMounted = false ;
2017-04-26 23:54:53 -04:00
if ( this . _balanceSubscribeId ) {
lbry . balanceUnsubscribe ( this . _balanceSubscribeId )
2016-08-07 22:48:45 -04:00
}
2016-08-07 20:20:14 -04:00
} ,
2017-04-26 23:54:53 -04:00
render : function ( ) {
2017-04-27 09:17:18 -04:00
return < header id = "header" >
2017-04-26 23:54:53 -04:00
< div className = "header__item" >
2017-04-30 20:15:21 -04:00
< Link onClick = { ( ) => { lbry . back ( ) } } button = "alt button--flat" icon = "icon-arrow-left" / >
2017-04-26 23:54:53 -04:00
< / div >
< div className = "header__item" >
< Link href = "?discover" button = "alt button--flat" icon = "icon-home" / >
< / div >
< div className = "header__item header__item--wunderbar" >
2017-04-30 20:15:21 -04:00
< WunderBar address = { this . props . address } icon = { this . props . wunderBarIcon }
2017-04-30 23:38:14 -04:00
onSearch = { this . props . onSearch } onSubmit = { this . props . onSubmit } viewingPage = { this . props . viewingPage } / >
2017-04-26 23:54:53 -04:00
< / div >
< div className = "header__item" >
< Link href = "?wallet" button = "text" icon = "icon-bank" label = { lbry . formatCredits ( this . state . balance , 1 ) } > < / Link >
< / div >
< div className = "header__item" >
< Link button = "primary button--flat" href = "?publish" icon = "icon-upload" label = "Publish" / >
< / div >
< div className = "header__item" >
< Link button = "alt button--flat" href = "?downloaded" icon = "icon-folder" / >
< / div >
< div className = "header__item" >
< Link button = "alt button--flat" href = "?settings" icon = "icon-gear" / >
< / div >
< / header >
}
} ) ;
2017-05-01 18:31:13 -04:00
class WunderBar extends React . PureComponent {
static propTypes = {
2017-04-30 23:38:14 -04:00
onSearch : React . PropTypes . func . isRequired ,
onSubmit : React . PropTypes . func . isRequired
2017-05-01 18:31:13 -04:00
}
2017-04-30 20:15:21 -04:00
2017-05-01 18:31:13 -04:00
constructor ( props ) {
super ( props ) ;
this . _userTypingTimer = null ;
this . _input = null ;
this . _stateBeforeSearch = null ;
this . _resetOnNextBlur = true ;
this . onChange = this . onChange . bind ( this ) ;
this . onFocus = this . onFocus . bind ( this ) ;
this . onBlur = this . onBlur . bind ( this ) ;
this . onKeyPress = this . onKeyPress . bind ( this ) ;
this . onReceiveRef = this . onReceiveRef . bind ( this ) ;
this . state = {
2017-04-26 23:54:53 -04:00
address : this . props . address ,
icon : this . props . icon
} ;
2017-05-01 18:31:13 -04:00
}
componentWillUnmount ( ) {
2017-04-26 23:54:53 -04:00
if ( this . userTypingTimer ) {
clearTimeout ( this . _userTypingTimer ) ;
}
2017-05-01 18:31:13 -04:00
}
onChange ( event ) {
2016-08-07 20:57:12 -04:00
2017-04-26 23:54:53 -04:00
if ( this . _userTypingTimer )
2016-08-07 20:57:12 -04:00
{
2017-04-26 23:54:53 -04:00
clearTimeout ( this . _userTypingTimer ) ;
2016-08-07 20:57:12 -04:00
}
2017-04-26 23:54:53 -04:00
this . setState ( { address : event . target . value } )
2017-04-30 20:15:21 -04:00
let searchTerm = event . target . value ;
2017-04-26 23:54:53 -04:00
this . _userTypingTimer = setTimeout ( ( ) => {
2017-04-30 23:38:14 -04:00
this . _resetOnNextBlur = false ;
2016-08-07 22:48:45 -04:00
this . props . onSearch ( searchTerm ) ;
} , 800 ) ; // 800ms delay, tweak for faster/slower
2017-05-01 18:31:13 -04:00
}
2017-04-30 23:01:43 +07:00
2017-04-26 23:54:53 -04:00
componentWillReceiveProps ( nextProps ) {
2017-04-30 23:38:14 -04:00
if ( nextProps . viewingPage !== this . props . viewingPage || nextProps . address != this . props . address ) {
2017-04-26 23:54:53 -04:00
this . setState ( { address : nextProps . address , icon : nextProps . icon } ) ;
}
2017-05-01 18:31:13 -04:00
}
onFocus ( ) {
2017-04-26 23:54:53 -04:00
this . _stateBeforeSearch = this . state ;
let newState = {
2017-04-27 09:17:18 -04:00
icon : "icon-search" ,
isActive : true
2017-04-26 23:54:53 -04:00
}
2017-05-01 18:31:13 -04:00
2017-04-26 23:54:53 -04:00
this . _focusPending = true ;
2017-04-30 20:15:21 -04:00
//below is hacking, improved when we have proper routing
if ( ! this . state . address . startsWith ( 'lbry://' ) && this . state . icon !== "icon-search" ) //onFocus, if they are not on an exact URL or a search page, clear the bar
2017-04-26 23:54:53 -04:00
{
2017-04-30 04:06:50 -04:00
newState . address = '' ;
2017-04-26 23:54:53 -04:00
}
this . setState ( newState ) ;
2017-05-01 18:31:13 -04:00
}
onBlur ( ) {
2017-04-30 23:38:14 -04:00
let commonState = { isActive : false } ;
if ( this . _resetOnNextBlur ) {
this . setState ( Object . assign ( { } , this . _stateBeforeSearch , commonState ) ) ;
this . _input . value = this . state . address ;
} else {
this . _resetOnNextBlur = true ;
this . _stateBeforeSearch = this . state ;
this . setState ( commonState ) ;
}
2017-05-01 18:31:13 -04:00
}
componentDidUpdate ( ) {
2017-04-26 23:54:53 -04:00
this . _input . value = this . state . address ;
if ( this . _input && this . _focusPending ) {
this . _input . select ( ) ;
this . _focusPending = false ;
}
2017-05-01 18:31:13 -04:00
}
onKeyPress ( event ) {
2017-04-30 23:38:14 -04:00
if ( event . charCode == 13 && this . _input . value ) {
2017-05-01 18:31:13 -04:00
let uri = null ,
method = "onSubmit" ;
2017-05-01 15:59:40 -04:00
this . _resetOnNextBlur = false ;
2017-05-01 18:31:13 -04:00
clearTimeout ( this . _userTypingTimer ) ;
try {
uri = lbryuri . normalize ( this . _input . value ) ;
this . setState ( { value : uri } ) ;
} catch ( error ) { //then it's not a valid URL, so let's search
uri = this . _input . value ;
method = "onSearch" ;
}
this . props [ method ] ( uri ) ;
2017-05-01 15:59:40 -04:00
this . _input . blur ( ) ;
2017-04-30 23:38:14 -04:00
}
2017-05-01 18:31:13 -04:00
}
onReceiveRef ( ref ) {
2017-04-26 23:54:53 -04:00
this . _input = ref ;
2017-05-01 18:31:13 -04:00
}
render ( ) {
2017-04-30 04:06:50 -04:00
return (
< div className = { 'wunderbar' + ( this . state . isActive ? ' wunderbar--active' : '' ) } >
{ this . state . icon ? < Icon fixed icon = { this . state . icon } / > : '' }
< input className = "wunderbar__input" type = "search" placeholder = "Type a LBRY address or search term"
ref = { this . onReceiveRef }
onFocus = { this . onFocus }
onBlur = { this . onBlur }
onChange = { this . onChange }
2017-04-30 23:38:14 -04:00
onKeyPress = { this . onKeyPress }
2017-04-30 04:06:50 -04:00
value = { this . state . address }
placeholder = "Find movies, music, games, and more" / >
2017-04-26 23:54:53 -04:00
< / div >
2017-04-30 04:06:50 -04:00
) ;
2016-08-07 16:10:44 -04:00
}
2017-05-01 18:31:13 -04:00
}
2016-08-27 10:12:56 -04:00
2016-11-22 14:19:08 -06:00
export default Header ;