2018-08-13 18:23:01 +02:00
// @flow
2018-11-08 20:48:38 +01:00
import type { Status } from 'types/status' ;
2018-03-26 23:32:43 +02:00
import * as React from 'react' ;
2018-10-29 18:23:53 +01:00
import * as MODALS from 'constants/modal_types' ;
import { Lbry } from 'lbry-redux' ;
2018-07-18 21:48:30 +02:00
import ModalWalletUnlock from 'modal/modalWalletUnlock' ;
2017-12-21 22:08:54 +01:00
import ModalIncompatibleDaemon from 'modal/modalIncompatibleDaemon' ;
import ModalUpgrade from 'modal/modalUpgrade' ;
import ModalDownloading from 'modal/modalDownloading' ;
2018-08-13 18:23:01 +02:00
import LoadScreen from './internal/load-screen' ;
2016-11-22 21:19:08 +01:00
2018-11-08 20:48:38 +01:00
const ONE _MINUTE = 60 * 1000 ;
2018-03-26 23:32:43 +02:00
type Props = {
checkDaemonVersion : ( ) => Promise < any > ,
2018-07-18 21:48:30 +02:00
notifyUnlockWallet : ( ) => Promise < any > ,
2018-08-13 18:23:01 +02:00
daemonVersionMatched : boolean ,
onReadyToLaunch : ( ) => void ,
2018-08-16 07:17:15 +02:00
authenticate : ( ) => void ,
2019-01-10 02:38:26 +01:00
hideModal : ( ) => void ,
2018-10-29 18:23:53 +01:00
modal : ? {
2018-04-23 20:02:06 +02:00
id : string ,
} ,
2018-03-26 23:32:43 +02:00
} ;
2017-05-17 10:10:25 +02:00
2018-03-26 23:32:43 +02:00
type State = {
details : string ,
message : string ,
2018-07-18 21:48:30 +02:00
launchedModal : boolean ,
2018-11-08 20:48:38 +01:00
error : boolean ,
2019-01-10 02:38:26 +01:00
isRunning : boolean ,
launchWithIncompatibleDaemon : boolean ,
2018-03-26 23:32:43 +02:00
} ;
2019-01-10 02:38:26 +01:00
export default class SplashScreen extends React . PureComponent < Props , State > {
2018-03-26 23:32:43 +02:00
constructor ( props : Props ) {
2017-05-17 10:10:25 +02:00
super ( props ) ;
this . state = {
2018-08-13 18:37:02 +02:00
details : _ _ ( 'Starting up' ) ,
2017-12-21 22:08:54 +01:00
message : _ _ ( 'Connecting' ) ,
2018-07-18 21:48:30 +02:00
launchedModal : false ,
2019-03-08 20:20:17 +01:00
error : false ,
2019-01-10 02:38:26 +01:00
launchWithIncompatibleDaemon : false ,
isRunning : false ,
2017-05-17 10:10:25 +02:00
} ;
2018-08-20 18:33:36 +02:00
2018-11-12 19:22:51 +01:00
( this : any ) . renderModals = this . renderModals . bind ( this ) ;
2019-01-10 02:38:26 +01:00
( this : any ) . runWithIncompatibleDaemon = this . runWithIncompatibleDaemon . bind ( this ) ;
2018-08-20 18:33:36 +02:00
this . hasRecordedUser = false ;
2018-11-08 20:48:38 +01:00
this . timeout = undefined ;
2017-05-17 10:10:25 +02:00
}
2018-08-13 18:23:01 +02:00
componentDidMount ( ) {
const { checkDaemonVersion } = this . props ;
2018-11-08 20:48:38 +01:00
this . adjustErrorTimeout ( ) ;
2018-08-13 18:23:01 +02:00
Lbry . connect ( )
2018-12-05 22:09:11 +01:00
. then ( checkDaemonVersion )
2018-08-13 18:23:01 +02:00
. then ( ( ) => {
this . updateStatus ( ) ;
} )
. catch ( ( ) => {
this . setState ( {
message : _ _ ( 'Connection Failure' ) ,
details : _ _ (
'Try closing all LBRY processes and starting again. If this still happens, your anti-virus software or firewall may be preventing LBRY from connecting. Contact hello@lbry.io if you think this is a software bug.'
) ,
} ) ;
} ) ;
}
2018-11-08 20:48:38 +01:00
componentDidUpdate ( ) {
this . adjustErrorTimeout ( ) ;
}
componentWillUnmount ( ) {
if ( this . timeout ) {
clearTimeout ( this . timeout ) ;
}
}
adjustErrorTimeout ( ) {
if ( this . timeout ) {
clearTimeout ( this . timeout ) ;
}
// Every time we make it to a new step in the daemon startup process, reset the timer
// If nothing changes after 1 minute, show the error message.
this . timeout = setTimeout ( ( ) => {
this . setState ( { error : true } ) ;
} , ONE _MINUTE ) ;
}
2017-05-17 10:10:25 +02:00
updateStatus ( ) {
2018-12-05 22:09:11 +01:00
Lbry . status ( ) . then ( status => {
this . updateStatusCallback ( status ) ;
} ) ;
2017-05-17 10:10:25 +02:00
}
2019-03-07 22:46:15 +01:00
updateStatusCallback ( status : Status ) {
2018-12-05 22:09:11 +01:00
const { notifyUnlockWallet , authenticate , modal } = this . props ;
2018-07-18 21:48:30 +02:00
const { launchedModal } = this . state ;
2018-08-16 07:17:15 +02:00
2018-11-08 20:48:38 +01:00
if ( status . error ) {
2019-03-05 05:46:57 +01:00
this . setState ( { error : true } ) ;
2018-11-08 20:48:38 +01:00
return ;
}
2018-08-20 18:33:36 +02:00
if ( ! this . hasRecordedUser && status ) {
2018-08-16 07:17:15 +02:00
authenticate ( ) ;
2018-08-20 18:33:36 +02:00
this . hasRecordedUser = true ;
2018-08-16 07:17:15 +02:00
}
2018-11-08 20:48:38 +01:00
const { wallet , blockchain _headers : blockchainHeaders } = status ;
// If the wallet is locked, stop doing anything and make the user input their password
if ( wallet && wallet . is _locked ) {
2018-12-04 21:30:14 +01:00
// Clear the error timeout, it might sit on this step for a while until someone enters their password
if ( this . timeout ) {
clearTimeout ( this . timeout ) ;
}
2018-12-05 22:09:11 +01:00
// Make sure there isn't another active modal (like INCOMPATIBLE_DAEMON)
if ( launchedModal === false && ! modal ) {
2018-08-13 18:23:01 +02:00
this . setState ( { launchedModal : true } , ( ) => notifyUnlockWallet ( ) ) ;
}
2018-08-15 21:56:42 +02:00
} else if ( status . is _running ) {
2018-12-04 21:30:14 +01:00
// If we cleared the error timout due to a wallet being locked, make sure to start it back up
if ( ! this . timeout ) {
2019-03-07 22:46:15 +01:00
this . adjustErrorTimeout ( ) ;
2018-12-04 21:30:14 +01:00
}
2016-04-14 08:27:06 +02:00
2019-02-18 18:33:02 +01:00
Lbry . resolve ( { urls : 'lbry://one' } ) . then ( ( ) => {
2019-01-10 02:38:26 +01:00
this . setState ( { isRunning : true } , ( ) => this . continueAppLaunch ( ) ) ;
2016-04-14 08:27:06 +02:00
} ) ;
2018-11-08 20:48:38 +01:00
2017-01-18 16:29:47 +01:00
return ;
2018-11-08 20:48:38 +01:00
} else if ( blockchainHeaders ) {
const blockChainHeaders = blockchainHeaders ;
if ( blockChainHeaders . download _progress < 100 ) {
this . setState ( {
message : _ _ ( 'Blockchain Sync' ) ,
details : ` ${ _ _ ( 'Catching up with the blockchain' ) } ( ${
blockchainHeaders . download _progress
} % ) ` ,
} ) ;
}
} else if ( wallet && wallet . blocks _behind > 0 ) {
const format = wallet . blocks _behind === 1 ? '%s block behind' : '%s blocks behind' ;
2018-07-18 21:48:30 +02:00
this . setState ( {
2018-08-13 18:23:01 +02:00
message : _ _ ( 'Blockchain Sync' ) ,
2018-11-08 20:48:38 +01:00
details : _ _ ( format , wallet . blocks _behind ) ,
2018-07-18 21:48:30 +02:00
} ) ;
2018-11-08 20:48:38 +01:00
} else if ( wallet && wallet . blocks _behind === 0 ) {
2017-07-29 23:52:32 +02:00
this . setState ( {
2018-08-13 18:23:01 +02:00
message : 'Network Loading' ,
details : 'Initializing LBRY service...' ,
2017-07-29 23:52:32 +02:00
} ) ;
}
2018-11-08 20:48:38 +01:00
2017-01-18 16:29:47 +01:00
setTimeout ( ( ) => {
2017-04-09 17:06:23 +02:00
this . updateStatus ( ) ;
2017-01-18 16:29:47 +01:00
} , 500 ) ;
2017-05-17 10:10:25 +02:00
}
2019-01-10 02:38:26 +01:00
runWithIncompatibleDaemon ( ) {
const { hideModal } = this . props ;
hideModal ( ) ;
this . setState ( { launchWithIncompatibleDaemon : true } , ( ) => this . continueAppLaunch ( ) ) ;
}
continueAppLaunch ( ) {
const { daemonVersionMatched , onReadyToLaunch } = this . props ;
const { isRunning , launchWithIncompatibleDaemon } = this . state ;
if ( daemonVersionMatched ) {
onReadyToLaunch ( ) ;
} else if ( launchWithIncompatibleDaemon && isRunning ) {
// The user may have decided to run the app with mismatched daemons
// They could make this decision before the daemon is finished starting up
// If it isn't running, this function will be called after the daemon is started
onReadyToLaunch ( ) ;
}
}
2018-08-20 18:33:36 +02:00
hasRecordedUser : boolean ;
2018-11-08 20:48:38 +01:00
timeout : ? TimeoutID ;
2018-08-20 18:33:36 +02:00
2018-11-12 19:22:51 +01:00
renderModals ( ) {
2018-10-29 18:23:53 +01:00
const { modal } = this . props ;
const modalId = modal && modal . id ;
2018-04-23 20:02:06 +02:00
2018-11-12 19:22:51 +01:00
if ( ! modalId ) {
return null ;
}
switch ( modalId ) {
case MODALS . INCOMPATIBLE _DAEMON :
2019-01-10 02:38:26 +01:00
return < ModalIncompatibleDaemon onContinueAnyway = { this . runWithIncompatibleDaemon } / > ;
2018-11-12 19:22:51 +01:00
case MODALS . WALLET _UNLOCK :
return < ModalWalletUnlock / > ;
case MODALS . UPGRADE :
return < ModalUpgrade / > ;
case MODALS . DOWNLOADING :
return < ModalDownloading / > ;
default :
return null ;
}
}
render ( ) {
2018-12-05 22:09:11 +01:00
const { message , details , error } = this . state ;
2018-11-12 19:22:51 +01:00
2017-06-06 23:19:12 +02:00
return (
2018-03-26 23:32:43 +02:00
< React.Fragment >
2019-03-08 20:20:17 +01:00
< LoadScreen message = { message } details = { details } error = { error } / >
2017-07-19 23:05:08 +02:00
{ / * T e m p h a c k : d o n ' t s h o w a n y m o d a l s o n s p l a s h s c r e e n d a e m o n i s r u n n i n g ;
daemon doesn ' t let you quit during startup , so the "Quit" buttons
in the modals won ' t work . * / }
2018-12-05 22:09:11 +01:00
{ this . renderModals ( ) }
2018-03-26 23:32:43 +02:00
< / React.Fragment >
2017-06-06 23:19:12 +02:00
) ;
2016-04-10 02:00:56 +02:00
}
2017-05-17 10:10:25 +02:00
}