2016-11-22 21:19:08 +01:00
import React from 'react' ;
2017-05-01 05:38:14 +02:00
import lbryuri from '../lbryuri.js' ;
2016-11-22 21:19:08 +01:00
import { Link } from './link.js' ;
2017-04-27 05:54:53 +02:00
import { Icon , CreditAmount } from './common.js' ;
2016-11-22 21:19:08 +01:00
2016-08-07 22:10:44 +02:00
var Header = React . createClass ( {
2017-04-27 05:54:53 +02:00
_balanceSubscribeId : null ,
2017-04-27 15:17:18 +02:00
_isMounted : false ,
2017-04-27 05:54:53 +02:00
2017-05-01 05:38:14 +02:00
propTypes : {
onSearch : React . PropTypes . func . isRequired ,
onSubmit : React . PropTypes . func . isRequired
} ,
2016-08-08 00:13:17 +02:00
getInitialState : function ( ) {
return {
2017-04-27 05:54:53 +02:00
balance : 0
2016-08-08 00:13:17 +02:00
} ;
} ,
2016-08-08 04:48:45 +02:00
componentDidMount : function ( ) {
2017-04-27 15:17:18 +02:00
this . _isMounted = true ;
2017-04-27 05:54:53 +02:00
this . _balanceSubscribeId = lbry . balanceSubscribe ( ( balance ) => {
2017-04-27 15:17:18 +02:00
if ( this . _isMounted ) {
this . setState ( { balance : balance } ) ;
}
2017-04-27 05:54:53 +02:00
} ) ;
2016-08-08 02:20:14 +02:00
} ,
2016-08-08 04:48:45 +02:00
componentWillUnmount : function ( ) {
2017-04-27 15:17:18 +02:00
this . _isMounted = false ;
2017-04-27 05:54:53 +02:00
if ( this . _balanceSubscribeId ) {
lbry . balanceUnsubscribe ( this . _balanceSubscribeId )
2016-08-08 04:48:45 +02:00
}
2016-08-08 02:20:14 +02:00
} ,
2017-04-27 05:54:53 +02:00
render : function ( ) {
2017-04-27 15:17:18 +02:00
return < header id = "header" >
2017-04-27 05:54:53 +02:00
< div className = "header__item" >
2017-05-01 02:15:21 +02:00
< Link onClick = { ( ) => { lbry . back ( ) } } button = "alt button--flat" icon = "icon-arrow-left" / >
2017-04-27 05:54:53 +02:00
< / d i v >
< div className = "header__item" >
< Link href = "?discover" button = "alt button--flat" icon = "icon-home" / >
< / d i v >
< div className = "header__item header__item--wunderbar" >
2017-05-01 02:15:21 +02:00
< WunderBar address = { this . props . address } icon = { this . props . wunderBarIcon }
2017-05-01 05:38:14 +02:00
onSearch = { this . props . onSearch } onSubmit = { this . props . onSubmit } viewingPage = { this . props . viewingPage } / >
2017-04-27 05:54:53 +02:00
< / d i v >
< div className = "header__item" >
< Link href = "?wallet" button = "text" icon = "icon-bank" label = { lbry . formatCredits ( this . state . balance , 1 ) } > < / L i n k >
< / d i v >
< div className = "header__item" >
< Link button = "primary button--flat" href = "?publish" icon = "icon-upload" label = "Publish" / >
< / d i v >
< div className = "header__item" >
< Link button = "alt button--flat" href = "?downloaded" icon = "icon-folder" / >
< / d i v >
< div className = "header__item" >
< Link button = "alt button--flat" href = "?settings" icon = "icon-gear" / >
< / d i v >
< / h e a d e r >
}
} ) ;
let WunderBar = React . createClass ( {
_userTypingTimer : null ,
_input : null ,
_stateBeforeSearch : null ,
2017-05-01 05:38:14 +02:00
_resetOnNextBlur : true ,
2017-04-27 05:54:53 +02:00
2017-05-01 02:15:21 +02:00
propTypes : {
2017-05-01 05:38:14 +02:00
onSearch : React . PropTypes . func . isRequired ,
onSubmit : React . PropTypes . func . isRequired
2017-05-01 02:15:21 +02:00
} ,
2017-04-27 05:54:53 +02:00
getInitialState : function ( ) {
return {
address : this . props . address ,
icon : this . props . icon
} ;
} ,
componentWillUnmount : function ( ) {
if ( this . userTypingTimer ) {
clearTimeout ( this . _userTypingTimer ) ;
}
2016-08-08 02:20:14 +02:00
} ,
2017-04-27 05:54:53 +02:00
onChange : function ( event ) {
2016-08-08 02:57:12 +02:00
2017-04-27 05:54:53 +02:00
if ( this . _userTypingTimer )
2016-08-08 02:57:12 +02:00
{
2017-04-27 05:54:53 +02:00
clearTimeout ( this . _userTypingTimer ) ;
2016-08-08 02:57:12 +02:00
}
2017-04-27 05:54:53 +02:00
this . setState ( { address : event . target . value } )
2017-05-01 02:15:21 +02:00
let searchTerm = event . target . value ;
2017-04-27 05:54:53 +02:00
this . _userTypingTimer = setTimeout ( ( ) => {
2017-05-01 05:38:14 +02:00
this . _resetOnNextBlur = false ;
2016-08-08 04:48:45 +02:00
this . props . onSearch ( searchTerm ) ;
} , 800 ) ; // 800ms delay, tweak for faster/slower
2016-08-08 02:57:12 +02:00
} ,
2017-04-27 05:54:53 +02:00
componentWillReceiveProps ( nextProps ) {
2017-05-01 05:38:14 +02:00
if ( nextProps . viewingPage !== this . props . viewingPage || nextProps . address != this . props . address ) {
2017-04-27 05:54:53 +02:00
this . setState ( { address : nextProps . address , icon : nextProps . icon } ) ;
}
} ,
onFocus : function ( ) {
this . _stateBeforeSearch = this . state ;
let newState = {
2017-04-27 15:17:18 +02:00
icon : "icon-search" ,
isActive : true
2017-04-27 05:54:53 +02:00
}
// this._input.value = ""; //trigger placeholder
this . _focusPending = true ;
2017-05-01 02:15:21 +02: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-27 05:54:53 +02:00
{
2017-04-30 10:06:50 +02:00
newState . address = '' ;
2017-04-27 05:54:53 +02:00
}
this . setState ( newState ) ;
} ,
onBlur : function ( ) {
2017-05-01 05:38:14 +02: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-04-27 05:54:53 +02:00
} ,
componentDidUpdate : function ( ) {
this . _input . value = this . state . address ;
if ( this . _input && this . _focusPending ) {
this . _input . select ( ) ;
this . _focusPending = false ;
}
} ,
2017-05-01 05:38:14 +02:00
onKeyPress : function ( event ) {
if ( event . charCode == 13 && this . _input . value ) {
2017-05-01 21:59:40 +02:00
let uri = lbryuri . normalize ( this . _input . value ) ;
2017-05-01 05:38:14 +02:00
clearTimeout ( this . _userTypingTimer ) ;
2017-05-01 21:59:40 +02:00
this . props . onSubmit ( uri ) ;
this . setState ( { value : uri } )
this . _resetOnNextBlur = false ;
this . _input . blur ( ) ;
2017-05-01 05:38:14 +02:00
}
} ,
2017-04-27 05:54:53 +02:00
onReceiveRef : function ( ref ) {
this . _input = ref ;
} ,
2016-08-07 22:10:44 +02:00
render : function ( ) {
2017-04-30 10:06:50 +02: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-05-01 05:38:14 +02:00
onKeyPress = { this . onKeyPress }
2017-04-30 10:06:50 +02:00
value = { this . state . address }
placeholder = "Find movies, music, games, and more" / >
2017-04-27 05:54:53 +02:00
< / d i v >
2017-04-30 10:06:50 +02:00
) ;
2016-08-07 22:10:44 +02:00
}
2017-04-27 05:54:53 +02:00
} )
2016-08-27 16:12:56 +02:00
2017-04-27 15:17:18 +02:00
export let SubHeader = React . createClass ( {
2016-08-27 16:12:56 +02:00
render : function ( ) {
2017-04-27 15:17:18 +02:00
let links = [ ] ,
2016-08-27 16:12:56 +02:00
viewingUrl = '?' + this . props . viewingPage ;
2017-01-13 04:36:03 +01:00
2016-08-27 16:12:56 +02:00
for ( let link of Object . keys ( this . props . links ) ) {
links . push (
< a href = { link } key = { link } className = { viewingUrl == link ? 'sub-header-selected' : 'sub-header-unselected' } >
{ this . props . links [ link ] }
< / a >
) ;
}
return (
2017-04-27 15:17:18 +02:00
< nav className = { 'sub-header' + ( this . props . modifier ? ' sub-header--' + this . props . modifier : '' ) } >
2016-08-27 16:12:56 +02:00
{ links }
< / n a v >
) ;
}
2016-11-22 21:19:08 +01:00
} ) ;
export default Header ;