77 lines
2.6 KiB
TypeScript

import { Href, useRouter } from 'expo-router'
import { useRouteInfo } from 'expo-router/build/hooks'
import React, { ReactNode, useEffect } from 'react'
import { useAuth, useAuthLogin } from '@/hooks/useAuth'
import * as SecureStore from '@/utils/SecureStore'
import { useLoginMutation } from '@/hooks/mutations/useLoginMutation'
import { useGame, useSetPlayerId } from '@/hooks/useGame'
type Props = {
loginRedirect: Href
children: ReactNode
}
export default function LoginProvider({ loginRedirect, children }: Props) {
const router = useRouter()
const route = useRouteInfo()
const auth = useAuth()
const authLogin = useAuthLogin()
const loginMutation = useLoginMutation({
authLogin,
onError: ({ response }) => {
if (response)
authLogin({ name: auth.name ?? "", password: null, token: null })
else
authLogin({ name: auth.name ?? "", token: null })
}
})
const game = useGame()
const setPlayerId = useSetPlayerId()
useEffect(() => {
(async () => {
const storedName = await SecureStore.getItemAsync('apiName')
const storedToken = await SecureStore.getItemAsync('apiToken')
if (!auth.loggedIn && storedName !== null && storedName !== auth.name && storedToken !== auth.token) {
authLogin({ name: storedName, token: storedToken })
return
}
// Si on est pas connecté⋅e, on reste sur la fenêtre de connexion
if ((!auth.loggedIn || !auth.token) && route.pathname !== loginRedirect)
router.navigate(loginRedirect)
})()
}, [auth, authLogin, router, route])
useEffect(() => {
// Renouvellement auto du jeton d'authentification
const { name, token } = auth
const password = SecureStore.getItem('apiPassword')
if (name === null || (password === null && token === null) || loginMutation.isPending)
return
let waitTime = 0
if (token !== null && token !== undefined) {
const arrayToken = token.split('.')
const tokenPayload = JSON.parse(atob(arrayToken[1]))
const expTime: number = tokenPayload.exp * 1000
const now: number = Math.floor(new Date().getTime())
waitTime = expTime - now
const playerId = tokenPayload.playerId
if (playerId !== game.playerId)
setPlayerId(playerId)
}
const timeout = setTimeout(async () => {
const password = SecureStore.getItem('apiPassword')
if (password)
loginMutation.mutate({ name, password })
else
authLogin({ name: name, token: null })
}, waitTime)
return () => clearTimeout(timeout)
}, [auth, authLogin, loginMutation.status, game, setPlayerId])
return <>
{children}
</>
}