import React, { useCallback } from 'react'; import { authState } from './lib/personium_auth_adapter'; import { atom, useRecoilState, useSetRecoilState } from 'recoil'; import { $barInstalled } from './common/auth'; const $installStatus = atom({ key: 'bar_install_status', default: [], }); const $installing = atom({ key: 'bar_installing', defualt: false, }); export function PersoniumBarInstaller() { const [installStatus, setInstallStatus] = useRecoilState($installStatus); const [installing, setInstalling] = useRecoilState($installing); const setBarInstalled = useSetRecoilState($barInstalled); const handleClick = useCallback(async () => { let pollingStatusID = -1; function updateInstallStatus(text) { setInstallStatus(c => [...c, { time: Date.now(), text }]); } if (authState.accessToken.access_token === undefined) { setInstalling(true); return () => { setInstalling(false); }; } if (installing) return; setInstalling(true); const { access_token } = authState.accessToken; const res = await fetch( 'https://app-personium-trails.appdev.personium.io/__/app-personium-trails.bar' ); if (res.status !== 200) { throw new Error('Downloading Barfile is failed'); } // download to memory const buff = await res.arrayBuffer(); console.log(`Downloaded ${buff.byteLength} bytes`); const boxURL = `${authState._targetCell}app-personium-trails`; const sendRes = await fetch(boxURL, { method: 'MKCOL', body: buff, headers: { Authorization: `Bearer ${access_token}`, 'Content-Type': 'application/zip', }, redirect: 'manual', }); if (sendRes.status === 202) { // Accepted // const boxStatusURL = sendRes.headers.get('location'); pollingStatusID = setInterval(async () => { const boxStatus = await fetch(boxURL, { headers: { Authorization: `Bearer ${access_token}`, }, }).then(res => res.json()); const statusText = boxStatus.box.status === 'ready' ? boxStatus.box.status : `${boxStatus.box.status} ${boxStatus.box.progress}`; updateInstallStatus(statusText); if (boxStatus.box.status === 'ready') { clearInterval(pollingStatusID); // update boxURL authState .updateBoxUrl() .then(() => { console.log('bar installation is done'); setBarInstalled(true); }) .catch(res => { console.log('bar installation is failed', res); setBarInstalled(false); }); } }, 500); } else { const err = await sendRes.json(); updateInstallStatus(err.message.value); } }, [installing, setInstallStatus, setInstalling, setBarInstalled]); if (authState.accessToken === null) { return <h1>Login First</h1>; } return ( <> <h1>Install Application</h1> <div> <button onClick={handleClick} disabled={installing}> Start Install </button> </div> <div> {installStatus.map(item => { return <p key={`installation-status-${item.time}`}>{item.text}</p>; })} </div> </> ); }