import { useState , createContext , useContext , useEffect } from "react" ; import axios from 'axios' ; import { INSTANCE_MANAGER_ENDPOINT } from '../../config' ; import { IInstance } from '../../types' ; interface InstanceWithID extends IInstance { id : number ; } interface InstacenContextProps { instanceManagerEnabled : boolean | null ; instanceManagerAddress : string | null ; setupInstanceManager : ( address : string ) => void ; instances : InstanceWithID [ ] | null ; currentInstance : number | null ; addInstance : ( instance : IInstance ) => void ; removeInstance : ( id : number ) => void ; changeCurrentInstance : ( id : number ) => void ; clearAll : ( ) => void ; } const InstancesContext = createContext < InstacenContextProps | null > ( null ) ; const InstancesProvider = ( { children } ) => { const [ instanceManagerStatus , setInstanceManagerStatus ] = useState < boolean | null > ( null ) ; const [ instanceManagerAddress , setInstanceManagerAddress ] = useState < string | null > ( null ) ; const [ instances , setInstances ] = useState < InstanceWithID [ ] | null > ( null ) ; const [ currentInstance , setCurrentInstance ] = useState < number | null > ( null ) ; useEffect ( ( ) => { const _rawCurrentinstance = sessionStorage . getItem ( 'currentInstance' ) ; const _rawInstances = sessionStorage . getItem ( 'instances' ) ; const _rawInstanceManagerStatus = sessionStorage . getItem ( 'instanceManagerStatus' ) ; const _currentInstance = _rawCurrentinstance !== null ? parseInt ( _rawCurrentinstance ) : null ; const _instances = _rawInstances !== null ? JSON . parse ( _rawInstances ) : null ; const _instanceManagerStatus = _rawInstanceManagerStatus !== null ? ( _rawCurrentinstance === "true" ) : null ; const _instanceManagerAddress = sessionStorage . getItem ( 'instanceManagerAddress' ) ; setCurrentInstance ( _currentInstance ) ; setInstances ( _instances ) ; setInstanceManagerStatus ( _instanceManagerStatus ) ; setInstanceManagerAddress ( _instanceManagerAddress ) ; } , [ ] ) ; useEffect ( ( ) => { const getInstances = async ( ) => { try { const instanceManagerResponse = await axios . get ( `http://${ instanceManagerAddress }${ INSTANCE_MANAGER_ENDPOINT . PATH_INSTANCES }` ) ; const _instancesWithoutId = instanceManagerResponse . data ; if ( _instancesWithoutId . length > 0 ) { const _instances = _instancesWithoutId . map ( ( i , key ) => Object . assign ( { } , { ... i , id : key } ) ) ; setInstances ( _instances ) ; setCurrentInstance ( 0 ) ; sessionStorage . setItem ( 'instances' , JSON . stringify ( _instances ) ) ; sessionStorage . setItem ( 'currentInstance' , '0' ) ; } else { setInstanceManagerStatus ( false ) ; setInstanceManagerAddress ( null ) ; sessionStorage . setItem ( 'instanceManagerStatus' , 'false' ) ; sessionStorage . removeItem ( 'instanceManagerAddress' ) ; } } catch ( error ) { console . log ( "Cannot get instances from instance-manager" ) ; setInstanceManagerStatus ( false ) ; setInstanceManagerAddress ( null ) ; sessionStorage . setItem ( 'instanceManagerStatus' , 'false' ) ; sessionStorage . removeItem ( 'instanceManagerAddress' ) ; } } ; if ( instanceManagerStatus && instanceManagerAddress ) { console . log ( "Loading instances..." ) ; getInstances ( ) ; } } , [ instanceManagerStatus , instanceManagerAddress ] ) ; const setupInstanceManager = ( address ) => { setInstanceManagerAddress ( address ) ; setInstanceManagerStatus ( true ) ; sessionStorage . setItem ( 'instanceManagerAddress' , address ) ; sessionStorage . setItem ( 'instanceManagerStatus' , 'true' ) ; } ; const addInstance = ( _instance ) => { const _id = instances ? instances . length : 0 ; const _instances = instances && instances ?. length > 0 ? instances . concat ( [ { ... _instance , id : _id } ] ) : [ { ... _instance , id : _id } ] ; setInstances ( _instances ) ; setCurrentInstance ( _id ) ; sessionStorage . setItem ( 'instances' , JSON . stringify ( _instances ) ) ; sessionStorage . setItem ( 'currentInstance' , _id . toString ( ) ) ; } ; const removeInstance = ( id ) => { if ( instances && instances [ id ] ) { const _instances = instances ?. splice ( id , 1 ) ; setInstances ( _instances ) ; const _nextCurrentInstance = _instances . length === 0 ? null : id - 1 ; setCurrentInstance ( _nextCurrentInstance ) ; sessionStorage . setItem ( 'instances' , JSON . stringify ( _instances ) ) ; if ( _nextCurrentInstance !== null ) { sessionStorage . setItem ( 'currentInstance' , _nextCurrentInstance . toString ( ) ) ; } else { sessionStorage . removeItem ( 'currentInstance' ) ; } } } ; const changeCurrentInstance = ( id ) => { if ( instances && instances [ id ] ) { setCurrentInstance ( id ) ; sessionStorage . setItem ( 'currentInstance' , id . toString ( ) ) ; } } ; const clearAll = ( ) => { setInstanceManagerStatus ( null ) ; setInstanceManagerAddress ( null ) ; setInstances ( null ) ; setCurrentInstance ( null ) ; sessionStorage . removeItem ( 'instanceManagerStatus' ) ; sessionStorage . removeItem ( 'instanceManagerAddress' ) ; sessionStorage . removeItem ( 'instances' ) ; sessionStorage . removeItem ( 'currentInstance' ) ; } ; return ( < InstancesContext . Provider value = { { instances : instances , instanceManagerEnabled : instanceManagerStatus , instanceManagerAddress : instanceManagerAddress , setupInstanceManager : setupInstanceManager , addInstance : addInstance , removeInstance : removeInstance , changeCurrentInstance : changeCurrentInstance , currentInstance : currentInstance , clearAll : clearAll , } } > { children } < /InstancesContext.Provider>); } ; const useInstances = ( ) => { const context = useContext ( InstancesContext ) ; if ( ! context ) { throw new Error ( 'useInstances must be used within InstancesProvider' ) ; } return context ; } ; export { InstancesProvider , useInstances } ;