/**
 * React Native SQLite Demo
 * Copyright (c) 2018-2020 Bruce Lefebvre <bruce@brucelefebvre.com>
 * https://github.com/blefebvre/react-native-sqlite-demo/blob/master/LICENSE
 */ import { Alert } from "react-native" ; import RNRestart from "react-native-restart" ; import { DropboxDatabaseSync } from "../sync/dropbox/DropboxDatabaseSync" ; import { DropboxAuthorize } from "../sync/dropbox/DropboxAuthorize" ; export type SynchronizerFunction = ( ) => void ; export type PrepareForUpdateFunction = ( ) => Promise < void > ; const dropboxSync = new DropboxDatabaseSync ( ) ; const dropboxAuth = new DropboxAuthorize ( ) ; export function useDatabaseSync ( prepareForDatabaseUpdate ) { async function reconcileDatabaseChanges ( ) { let anUpdateToTheDatabaseExists ; const hasBeenSynced = await dropboxSync . hasSynced ( ) ; if ( hasBeenSynced === false ) { return ; } const updateExists = await dropboxSync . hasRemoteUpdate ( ) ; anUpdateToTheDatabaseExists = updateExists ; const wasLastUploadCompleted = await dropboxSync . hasLastUploadCompleted ( ) ; console . log ( `[DatabaseSynchronizer] Checking for an update to the database! wasLastUploadCompleted = ${ wasLastUploadCompleted } and anUpdateToTheDatabaseExists = ${ anUpdateToTheDatabaseExists }` ) ; try { if ( wasLastUploadCompleted === false && anUpdateToTheDatabaseExists === false ) { console . log ( "[DatabaseSynchronizer] the local DB needs to be uploaded! Queuing an upload now." ) ; return dropboxSync . upload ( ) ; } else if ( wasLastUploadCompleted && anUpdateToTheDatabaseExists === false ) { console . log ( "[DatabaseSynchronizer] the local DB is up-to-date with the Dropbox backup." ) ; return Promise . resolve ( ) ; } else if ( wasLastUploadCompleted && anUpdateToTheDatabaseExists ) { console . log ( "[DatabaseSynchronizer] Update alert! There has been an update made to the DB file by another device." ) ; promptToUpdateDatabase ( ) ; return Promise . resolve ( ) ; } else if ( wasLastUploadCompleted === false && anUpdateToTheDatabaseExists ) { console . log ( "[DatabaseSynchronizer] last backup WAS NOT completed AND there IS an update on Dropbox! Prompt to replace DB." ) ; promptToReplaceDatabase ( ) ; return Promise . resolve ( ) ; } else { console . error ( `[DatabaseSynchronizer] ERROR: what state is this? wasLastUploadCompleted = ${ wasLastUploadCompleted } anUpdateToTheDatabaseExists = ${ anUpdateToTheDatabaseExists }` ) ; return Promise . resolve ( ) ; } } catch ( reason ) { console . error ( "[DatabaseSynchronizer] error in reconcileDatabaseChanges():" , reason ) ; } } function promptToUpdateDatabase ( ) { Alert . alert ( "Update database?" , "The synced database on Dropbox has changed since you last ran the app on this device." , [ { text : "Apply update from Dropbox" , onPress : ( ) => downloadAndApplyUpdate ( ) , } , { text : "Cancel (unlink Dropbox)" , onPress : ( ) => dropboxAuth . revokeAuthorization ( ) , } , ] , { cancelable : false } ) ; } function promptToReplaceDatabase ( ) { Alert . alert ( "Replace local database?" , "The synced database on Dropbox has changed since you last ran the app on this device. Would you like to overwrite the current database with the version on Dropbox?" , [ { text : "Yes, replace the current database" , onPress : ( ) => downloadAndApplyUpdate ( ) , } , { text : "Cancel (unlink Dropbox)" , onPress : ( ) => dropboxAuth . revokeAuthorization ( ) , } , ] , { cancelable : false } ) ; } function downloadAndApplyUpdate ( ) { console . log ( "[DatabaseSynchronizer] User chose to apply the remote update." ) ; prepareForDatabaseUpdate ( ) . then ( ( ) => { return dropboxSync . download ( ) ; } ) . then ( ( ) => { console . log ( "[DatabaseSynchronizer] DB download success! Reloading app." ) ; RNRestart . Restart ( ) ; } ) . catch ( ( reason ) => { console . error ( "[DatabaseSynchronizer] Error downloading Dropbox database copy. Reason:" , reason ) ; RNRestart . Restart ( ) ; } ) ; } return function syncDatabase ( ) : Promise < void > { return Promise . resolve ( false ) . then ( ( isConnected ) => { if ( isConnected ) { console . log ( "[DatabaseSynchronizer] App is online! Check for an update." ) ; return reconcileDatabaseChanges ( ) ; } } ) ; } ; }