2020-08-02 12:28:50 +01:00
import * as React from 'react' ;
import { useEffect } from 'react' ;
2020-11-07 15:59:37 +00:00
import useSyncTargetUpgrade , { SyncTargetUpgradeResult } from '@joplin/lib/services/synchronizer/gui/useSyncTargetUpgrade' ;
2020-08-02 12:28:50 +01:00
const { render } = require ( 'react-dom' ) ;
const ipcRenderer = require ( 'electron' ) . ipcRenderer ;
2021-01-22 17:41:11 +00:00
import Setting from '@joplin/lib/models/Setting' ;
2022-04-20 17:34:58 +01:00
import restart from '../services/restart' ;
2025-05-19 15:00:49 -07:00
import shim from '@joplin/lib/shim' ;
2020-08-02 12:28:50 +01:00
2020-11-12 19:13:28 +00:00
function useAppCloseHandler ( upgradeResult : SyncTargetUpgradeResult ) {
2023-02-20 12:02:29 -03:00
useEffect ( ( ) = > {
2020-08-02 12:28:50 +01:00
async function onAppClose() {
let canClose = true ;
if ( ! upgradeResult . done ) {
2025-05-19 15:00:49 -07:00
canClose = await shim . showConfirmationDialog ( 'The synchronisation target upgrade is still running and it is recommanded to let it finish. Close the application anyway?' ) ;
2020-08-02 12:28:50 +01:00
}
if ( canClose ) {
// We set the state back to IDLE so that the app can start normally and
// potentially the user can fix issues if any, export the data, etc.
// The message to upgrade will show up again if they try to sync.
Setting . setValue ( 'sync.upgradeState' , Setting . SYNC_UPGRADE_STATE_IDLE ) ;
await Setting . saveAll ( ) ;
}
ipcRenderer . send ( 'asynchronous-message' , 'appCloseReply' , {
canClose : canClose ,
} ) ;
}
ipcRenderer . on ( 'appClose' , onAppClose ) ;
return ( ) = > {
ipcRenderer . off ( 'appClose' , onAppClose ) ;
} ;
} , [ upgradeResult . done ] ) ;
}
function useStyle() {
2023-02-20 12:02:29 -03:00
useEffect ( ( ) = > {
2020-08-02 12:28:50 +01:00
const element = document . createElement ( 'style' ) ;
element . appendChild ( document . createTextNode ( `
body {
font - family : sans - serif ;
padding : 5px 20 px ;
color : # 333333 ;
}
. errorBox {
border : 1px solid red ;
padding : 5px 20 px ;
background - color : # ffeeee ;
}
pre {
overflow - x : scroll ;
}
` ));
document . head . appendChild ( element ) ;
} , [ ] ) ;
}
2020-11-12 19:13:28 +00:00
function useRestartOnDone ( upgradeResult : SyncTargetUpgradeResult ) {
2023-02-20 12:02:29 -03:00
useEffect ( ( ) = > {
2020-08-29 19:12:02 +01:00
if ( upgradeResult . done && ! upgradeResult . error ) {
2022-04-20 17:34:58 +01:00
void restart ( ) ;
2020-08-02 12:28:50 +01:00
}
2022-08-19 12:10:04 +01:00
// eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied
2020-08-02 12:28:50 +01:00
} , [ upgradeResult . done ] ) ;
}
function Root_UpgradeSyncTarget() {
const upgradeResult = useSyncTargetUpgrade ( ) ;
useStyle ( ) ;
useRestartOnDone ( upgradeResult ) ;
useAppCloseHandler ( upgradeResult ) ;
function renderUpgradeError() {
if ( ! upgradeResult . error ) return null ;
return (
< div className = "errorBox" >
< h2 > Error < / h2 >
< p > The sync target could not be upgraded due to an error . For support , please copy the < em > complete < / em > content of this page and paste it in the forum : https : //discourse.joplinapp.org/</p>
< p > The full error was : < / p >
< p > { upgradeResult . error . message } < / p >
< pre > { upgradeResult . error . stack } < / pre >
< / div >
) ;
}
return (
< div >
< h2 > Joplin upgrade in progress . . . < / h2 >
< p > Please wait while the sync target is being upgraded . It may take a few seconds or a few minutes depending on the upgrade . The application will automatically restart once it is completed . < / p >
{ renderUpgradeError ( ) }
< / div >
) ;
}
render ( < Root_UpgradeSyncTarget / > , document . getElementById ( 'react-root' ) ) ;