import * as React from 'react' ; import { Button } from 'react-bootstrap' ; import { ArrowClockwise } from 'react-bootstrap-icons' ; interface Props { period : number ; onRefresh : ( ) => Promise < void > ; } interface State { isRefreshing : boolean ; seconds : number ; } /**
 * Refreshing actually takes very little time, causing the refresh button to briefly flicker.
 * This controls how long to delay a "fake" refresh.
 */ const fakeRefreshDuration = 250 ; /**
 * Component for an auto-refresh button.
 */ class AutoRefreshButton extends React . Component < Props , State > { tickInterval ? : number ; constructor ( props ) { super ( props ) ; this . state = { isRefreshing : false , seconds : props . period , } ; } /**
     * Function called once per tick (every second).
     */ tick = async ( ) : Promise < void > => { const { period } = this . props ; const { isRefreshing , seconds } = this . state ; if ( isRefreshing ) { return ; } if ( seconds <= 0 ) { clearInterval ( this . tickInterval ) ; this . setState ( { isRefreshing : true , } ) ; await this . props . onRefresh ( ) ; this . setState ( { isRefreshing : false , seconds : period , } ) ; this . tickInterval = setInterval ( this . tick , 1000 ) ; } else { this . setState ( { seconds : this . state . seconds - 1 , } ) ; } } ; refreshNow = async ( ) : Promise < void > => { const { period } = this . props ; const { isRefreshing } = this . state ; if ( isRefreshing ) { return ; } clearInterval ( this . tickInterval ) ; this . setState ( { isRefreshing : true , } ) ; await this . props . onRefresh ( ) ; await new Promise ( resolve => setTimeout ( resolve , fakeRefreshDuration ) ) ; this . setState ( { isRefreshing : false , seconds : period , } ) ; this . tickInterval = setInterval ( this . tick , 1000 ) ; } ; componentDidMount ( ) { this . tickInterval = setInterval ( this . tick , 1000 ) ; } componentWillUnmount ( ) { clearInterval ( this . tickInterval ) ; } render ( ) { const { isRefreshing , seconds } = this . state ; const appearRefreshing = isRefreshing || seconds <= 0 ; const text = ! appearRefreshing ? `Refreshing in ${ seconds }` : 'Refreshing...' ; return ( < div style = { { display : 'flex' , alignItems : 'center' , alignContent : 'center' } } > < pre style = { { fontSize : 13 , margin : 0 } } > { text } < /pre> < Button variant = "secondary" className = "ml-3" size = "sm" disabled = { appearRefreshing } onClick = { this . refreshNow } style = { { cursor : appearRefreshing ? 'progress' : 'pointer' } } > < ArrowClockwise /> < /Button> < /div>); } } export default AutoRefreshButton ;