123 lines
3.5 KiB
JavaScript
123 lines
3.5 KiB
JavaScript
import { useCallback, useEffect, useState } from "react";
|
|
import { Alert } from "react-native";
|
|
import * as Updates from "expo-updates";
|
|
import AsyncStorage from "~/storage/memoryAsyncStorage";
|
|
import { STORAGE_KEYS } from "~/storage/storageKeys";
|
|
import useNow from "~/hooks/useNow";
|
|
import * as Sentry from "@sentry/react-native";
|
|
|
|
import env from "~/env";
|
|
import { treeActions } from "~/stores";
|
|
const UPDATE_CHECK_INTERVAL = 24 * 60 * 60 * 1000;
|
|
|
|
const applyUpdate = async () => {
|
|
treeActions.suspendTree();
|
|
try {
|
|
await Updates.fetchUpdateAsync();
|
|
// await Updates.reloadAsync();
|
|
} catch (error) {
|
|
Sentry.captureException(error);
|
|
console.log("Error applying update:", error);
|
|
// await Updates.reloadAsync(); // https://github.com/expo/expo/issues/14359#issuecomment-1159558604
|
|
}
|
|
};
|
|
|
|
const checkForUpdate = async () => {
|
|
if (env.LOCAL_DEV) {
|
|
return;
|
|
}
|
|
try {
|
|
const lastCheckString = await AsyncStorage.getItem(
|
|
STORAGE_KEYS.LAST_UPDATE_CHECK_TIME,
|
|
);
|
|
const lastCheck = lastCheckString ? new Date(lastCheckString) : null;
|
|
const nowDate = new Date();
|
|
|
|
if (!lastCheck || nowDate - lastCheck > UPDATE_CHECK_INTERVAL) {
|
|
await AsyncStorage.setItem(
|
|
STORAGE_KEYS.LAST_UPDATE_CHECK_TIME,
|
|
nowDate.toISOString(),
|
|
);
|
|
|
|
const update = await Updates.checkForUpdateAsync();
|
|
if (!update.isAvailable) {
|
|
return false;
|
|
}
|
|
const remoteUpdate = update.manifest;
|
|
const remoteCreatedAt = new Date(remoteUpdate.createdAt).getTime();
|
|
// const currentCreatedAt = Updates.manifest.commitTime; // buggy commitTime
|
|
const currentCreatedAt = env.BUILD_TIME;
|
|
// console.log(
|
|
// "DEBUG_AS remoteUpdate",
|
|
// `${remoteCreatedAt} > ${currentCreatedAt}`,
|
|
// remoteCreatedAt > currentCreatedAt,
|
|
// );
|
|
// console.log("DEBUG_AS Updates.manifest", Updates.manifest);
|
|
|
|
if (remoteCreatedAt > currentCreatedAt) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.log("Error checking for updates:", error);
|
|
}
|
|
};
|
|
|
|
export function useUpdatesCheck() {
|
|
const [updateAvailable, setUpdateAvailable] = useState(false);
|
|
const now = useNow();
|
|
|
|
useEffect(() => {
|
|
const updateAvailability = async () => {
|
|
const isAvailable = await checkForUpdate();
|
|
setUpdateAvailable(isAvailable);
|
|
};
|
|
updateAvailability();
|
|
}, [now]); // trigger every minute
|
|
|
|
return { updateAvailable, setUpdateAvailable };
|
|
}
|
|
|
|
export function useUpdates() {
|
|
const { isUpdatePending } = Updates.useUpdates();
|
|
|
|
useEffect(() => {
|
|
if (isUpdatePending) {
|
|
// Update has successfully downloaded; apply it now
|
|
(async () => {
|
|
await Updates.reloadAsync();
|
|
treeActions.triggerReload();
|
|
})();
|
|
}
|
|
}, [isUpdatePending]);
|
|
|
|
const { updateAvailable, setUpdateAvailable } = useUpdatesCheck();
|
|
|
|
const showAlert = useCallback(() => {
|
|
Alert.alert(
|
|
"Mise à jour disponible",
|
|
"Une nouvelle mise à jour est disponible. Souhaitez vous l'appliquer ?",
|
|
[
|
|
{
|
|
text: "Me rappeler plus tard",
|
|
onPress: () => setUpdateAvailable(false),
|
|
},
|
|
{ text: "Mettre à jour maintenant", onPress: applyUpdate },
|
|
],
|
|
);
|
|
}, [setUpdateAvailable]);
|
|
|
|
useEffect(() => {
|
|
if (updateAvailable) {
|
|
showAlert();
|
|
}
|
|
}, [showAlert, updateAvailable]);
|
|
}
|
|
|
|
// export async function installUpdateIfAvailable() {
|
|
// if (await checkForUpdate()) {
|
|
// await applyUpdate();
|
|
// }
|
|
// }
|