多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.6 KiB

import { useGlobalActions } from './actions'
import { useGlobalGetters } from './getters'
import { useGlobalState } from './state'
import type { UseGlobalReturn } from './types'
import { createGlobalState, useNuxtApp, watch } from '#imports'
export * from './types'
/**
* Global state is injected by {@link import('~/plugins/state') state} plugin into our nuxt app (available as `$state`).
* You can still call `useGlobal` to receive the `$state` object and access the global state.
* If it's not available yet, a new global state object is created and injected into the nuxt app.
*
* Part of the state is stored in {@link WindowLocalStorage localStorage}, so it will be available even if the user closes the browser tab.
* Check the {@link StoredState StoredState} type for more information.
*
* @example
* ```js
* import { useNuxtApp } from '#imports'
*
* const { $state } = useNuxtApp()
*
* const token = $state.token.value
* const user = $state.user.value
* ```
*
* @example
* ```js
* import { useGlobal } from '#imports'
*
* const globalState = useGlobal()
*
* cont token = globalState.token.value
* const user = globalState.user.value
*
* console.log(state.isLoading.value) // isLoading = true if any api request is still running
* ```
*/
export const useGlobal = createGlobalState((): UseGlobalReturn => {
const { provide } = useNuxtApp()
const state = useGlobalState()
const getters = useGlobalGetters(state)
const actions = useGlobalActions(state)
/** try to refresh token before expiry (5 min before expiry) */
watch(
() =>
!!(
state.jwtPayload.value &&
state.jwtPayload.value.exp &&
state.jwtPayload.value.exp - 5 * 60 < state.timestamp.value / 1000
),
async (expiring: boolean) => {
if (getters.signedIn.value && state.jwtPayload.value && expiring) {
await actions.refreshToken()
}
},
{ immediate: true },
)
watch(
state.jwtPayload,
(nextPayload) => {
if (nextPayload) {
state.user.value = {
// keep existing props if user id same as before
...(state.user.value?.id === nextPayload.id ? state.user.value || {} : {}),
id: nextPayload.id,
email: nextPayload.email,
firstname: nextPayload.firstname,
lastname: nextPayload.lastname,
roles: nextPayload.roles,
display_name: nextPayload.display_name,
}
}
},
{ immediate: true },
)
const globalState = { ...state, ...getters, ...actions } as UseGlobalReturn
/** provide a fresh state instance into nuxt app */
provide('state', globalState)
return globalState
})