diff --git a/src/App.tsx b/src/App.tsx
index 6f04dca..f7a78c6 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -10,37 +10,60 @@ import LogoutPage from './app/auth/pages/LogoutPage.tsx'
import UnauthorizedHandler from './app/auth/components/UnauthorizedHandler.tsx'
import AdminPage from './app/admin/pages/AdminPage.tsx'
import SignupCodesManagementPage from './app/admin/pages/subpages/SignupCodesManagementPage.tsx'
-import RefreshUser from './app/auth/components/RefreshUser.tsx'
+import { useUser } from './app/user/userStore.ts'
+import { useEffect, useMemo } from 'react'
-function App() {
+export default function App() {
const postService = new PostsService()
const mediaService = new MediaService()
- const authService = new AuthService()
+ const authService = useMemo(() => new AuthService(), [])
+
+ const { user, setUser } = useUser()
+
+ const userId = user?.userId ?? null
+
+ useEffect(() => {
+ if (userId == null) {
+ return
+ }
+
+ const timeouts: number[] = []
+
+ timeouts.push(
+ setTimeout(async function refreshUser() {
+ const userInfo = await authService.refreshUser(userId)
+
+ setUser(userInfo)
+
+ timeouts.push(setTimeout(refreshUser, 60_000))
+ }),
+ )
+
+ return () => {
+ timeouts.forEach(clearTimeout)
+ }
+ }, [authService, setUser, userId])
return (
-
-
+
+ }
+ />
+ } />
+ } />
+ } />
+ } />
+ }>
}
+ path={'codes'}
+ element={}
/>
- } />
- } />
- } />
- } />
- }>
- }
- />
-
-
-
+
+
)
}
-
-export default App
diff --git a/src/app/auth/authService.ts b/src/app/auth/authService.ts
index 293c242..bdd721c 100644
--- a/src/app/auth/authService.ts
+++ b/src/app/auth/authService.ts
@@ -2,6 +2,7 @@ import { dispatchMessage } from '../messageBus/messageBus.ts'
import client from '../api/client.ts'
import { ProblemDetails } from '../../types'
import { SignupCode } from './signupCode.ts'
+import { User } from '../user/userStore.ts'
export class AuthService {
constructor() {}
@@ -64,9 +65,9 @@ export class AuthService {
return res.data.signupCodes.map(SignupCode.fromDto)
}
- async refreshUser(userId: string) {
+ async refreshUser(userId: string): Promise {
if (this.getCookie('hasSession') !== 'true') {
- return
+ return null
}
const res = await client.GET(`/auth/user/{userId}`, {
@@ -76,11 +77,7 @@ export class AuthService {
credentials: 'include',
})
- if (!res.data) {
- dispatchMessage('auth:user-refresh-failed', null)
- } else {
- dispatchMessage('auth:user-refreshed', { ...res.data })
- }
+ return res.data ?? null
}
private getCookie(cookieName: string): string | undefined {
diff --git a/src/app/auth/pages/SignupPage.tsx b/src/app/auth/pages/SignupPage.tsx
index ba3b994..19b2ab4 100644
--- a/src/app/auth/pages/SignupPage.tsx
+++ b/src/app/auth/pages/SignupPage.tsx
@@ -52,9 +52,7 @@ export default function SignupPage({ authService }: SignupPageProps) {
}
}, [code, signupCode])
- useEffect(() => {
- console.debug('signup code', signupCode)
- }, [signupCode])
+ useEffect(() => {}, [signupCode])
const onSubmit = async (e: FormEvent) => {
e.preventDefault()
diff --git a/src/app/user/userStore.ts b/src/app/user/userStore.ts
index 49107fc..f52d391 100644
--- a/src/app/user/userStore.ts
+++ b/src/app/user/userStore.ts
@@ -23,9 +23,9 @@ addMessageListener('auth:registered', setUser)
addMessageListener('auth:logged-out', setUser)
export const useUser = () => {
- const [user] = useStore(userStore)
+ const [user, setUser] = useStore(userStore)
- return { user }
+ return { user, setUser }
}
function loadStoredUser(): User | null {
diff --git a/src/hooks/useOnMounted.ts b/src/hooks/useOnMounted.ts
new file mode 100644
index 0000000..2053977
--- /dev/null
+++ b/src/hooks/useOnMounted.ts
@@ -0,0 +1,17 @@
+import { useEffect, useRef } from 'react'
+
+export function useOnMounted(callback: () => void | Promise) {
+ const isMounted = useRef(false)
+
+ useEffect(() => {
+ if (isMounted.current) return
+ isMounted.current = true
+
+ const timeoutId = setTimeout(callback)
+
+ return () => {
+ isMounted.current = false
+ clearTimeout(timeoutId)
+ }
+ }, [callback])
+}
diff --git a/src/utils/store.ts b/src/utils/store.ts
index 5db61dc..ae99ef7 100644
--- a/src/utils/store.ts
+++ b/src/utils/store.ts
@@ -1,4 +1,4 @@
-import { useEffect, useState } from 'react'
+import { useCallback, useEffect, useState } from 'react'
export interface Store {
getState: () => T
@@ -37,7 +37,21 @@ export function createStore(initialState: T): Store
export function useStore(store: Store) {
const [selectedState, setSelectedState] = useState(() => store.getState())
- useEffect(() => store.subscribe((newState) => setSelectedState(newState)), [store])
+ useEffect(() => {
+ const unsubscribe = store.subscribe((newState) => setSelectedState(newState))
- return [selectedState, setSelectedState] as const
+ return () => {
+ unsubscribe()
+ }
+ }, [store])
+
+ const setState = useCallback(
+ (nextState: T | ((prevState: T) => T)) => {
+ setSelectedState(nextState)
+ store.setState(nextState)
+ },
+ [store],
+ )
+
+ return [selectedState, setState] as const
}