import { el , setChildren , mount , unmount , setStyle } from 'redom' ; import { EventEmitter } from '@byungi/event-emitter' ; import { AcceptNanoPayment , PaymentError } from '../types' ; import { containerStyle , bodyStyle , contentStyle , colors } from './style' ; import { createHeader } from './elements/header' ; import { createStatusBar } from './elements/statusBar' ; import { createFooter } from './elements/footer' ; import { createLoadingScene } from './scenes/loading' ; import { createPaymentScene } from './scenes/payment' ; import { createSuccessScene } from './scenes/success' ; import { createFailureScene } from './scenes/failure' ; import { formatSeconds } from '../utils' ; type DOMEvents = { close : ( ) => void ; } ; type DOMScene = 'loading' | 'payment' | 'success' | 'failure' ; export const createDOM = ( ) => { let scene = 'loading' ; const eventEmitter = new EventEmitter < DOMEvents > ( ) ; const handleCloseButtonClick = ( ) => eventEmitter . emit ( 'close' ) ; const container = el ( 'div' , { id : 'accept-nano' , style : containerStyle } ) ; const main = el ( 'div' , { id : 'accept-nano-body' , style : bodyStyle } ) ; const header = createHeader ( { onClose : handleCloseButtonClick } ) ; const statusBar = createStatusBar ( ) ; const content = el ( 'div' , { style : contentStyle } ) ; const footer = createFooter ( ) ; setChildren ( main , [ header , statusBar , content , footer ] ) ; let countdownSeconds = 0 ; let countdownInterval = undefined ; const startCoundownInterval = ( seconds ) => { countdownSeconds = seconds ; countdownInterval = setInterval ( ( ) => { countdownSeconds = countdownSeconds - 1 ; statusBar . textContent = `Waiting For Payment (${ formatSeconds ( countdownSeconds ) })` ; } , 1000 ) ; } ; const clearCountdownInterval = ( ) => { clearInterval ( countdownInterval ) ; } ; return { on : eventEmitter . once . bind ( eventEmitter ) , mount : ( ) => mount ( document . body , container ) , unmount : ( ) => { clearCountdownInterval ( ) ; unmount ( document . body , container ) ; } , renderLoading : ( ) => { scene = 'loading' ; setChildren ( container , [ createLoadingScene ( ) ] ) ; } , renderPayment : ( payment ) => { if ( scene === 'payment' ) return ; scene = 'payment' ; createPaymentScene ( payment ) . then ( paymentScene => { startCoundownInterval ( payment . remainingSeconds ) ; setChildren ( content , [ paymentScene ] ) ; setChildren ( container , [ main ] ) ; } ) ; } , renderSuccess : ( ) => { if ( scene === 'success' ) return ; scene = 'success' ; clearCountdownInterval ( ) ; statusBar . textContent = 'Success' ; setStyle ( statusBar , { background : colors . green } ) ; setChildren ( content , [ createSuccessScene ( { onClose : handleCloseButtonClick } ) , ] ) ; setChildren ( container , [ main ] ) ; } , renderFailure : ( error ) => { if ( scene === 'failure' ) return ; scene = 'failure' ; clearCountdownInterval ( ) ; statusBar . textContent = 'Error!' ; setStyle ( statusBar , { background : colors . red } ) ; setChildren ( content , [ createFailureScene ( { error , onClose : handleCloseButtonClick } ) , ] ) ; setChildren ( container , [ main ] ) ; } } ; } ; export type DOM = ReturnType < typeof createDOM > ;