Skip to content

Commit 2b9690c

Browse files
committed
major refactorings to fix remaining linting errors (handle it with care, major testing necessary)
1 parent 47c3825 commit 2b9690c

7 files changed

Lines changed: 218 additions & 404 deletions

File tree

client/src/layout.tsx

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import EventManager from "@lomray/event-manager"
22
import { useLocalStorage } from "@uidotdev/usehooks"
33
import boolifyString from "boolify-string"
4-
import { useEffect, useRef, useState } from "react"
4+
import { useEffect, useMemo, useRef, useState } from "react"
55
import Col from "react-bootstrap/Col"
66
import Container from "react-bootstrap/Container"
77
import Row from "react-bootstrap/Row"
@@ -33,18 +33,20 @@ import NotificationPlayer from "./notification-player"
3333
import SfxPlayer from "./sfx-player"
3434
import { refreshUserAuth } from "./user-auth"
3535

36-
function hasSamePermissions(a: User["permissions"], b: User["permissions"]) {
37-
const keys = Object.keys(a) as Array<keyof User["permissions"]>
38-
return keys.every((key) => a[key] === b[key])
39-
}
40-
41-
function hasSameUserIdentity(a: User, b: User) {
42-
return (
43-
a.id === b.id &&
44-
a.name === b.name &&
45-
a.virtual === b.virtual &&
46-
hasSamePermissions(a.permissions, b.permissions)
47-
)
36+
function parseCookieUser(cookieUser: unknown): User | null {
37+
if (cookieUser === undefined) return null
38+
39+
try {
40+
return User.parse({
41+
name: (cookieUser as User).name,
42+
id: (cookieUser as User).id,
43+
virtual: (cookieUser as User).virtual,
44+
valid_until: (cookieUser as User).valid_until,
45+
permissions: (cookieUser as User).permissions,
46+
})
47+
} catch {
48+
return null
49+
}
4850
}
4951

5052
export default function Layout() {
@@ -53,8 +55,10 @@ export default function Layout() {
5355
i18n: { language },
5456
} = useTranslation()
5557
const [cookies] = useCookies(["user"])
56-
const [user, setUser] = useState<User | null>(null)
57-
const [userValidUntil, setUserValidUntil] = useState<number | null>(null)
58+
const cookieUser = cookies.user
59+
const user = useMemo(() => parseCookieUser(cookieUser), [cookieUser])
60+
const userId = user?.id
61+
const userValidUntil = user?.valid_until.getTime() ?? null
5862
const [colorScheme] = useLocalStorage("colorScheme", "auto")
5963
const [welcome, setWelcome] = useLocalStorage("welcome")
6064
const prefersColorScheme = usePrefersColorScheme()
@@ -63,41 +67,17 @@ export default function Layout() {
6367
const hasValidatedStartupAuth = useRef(false)
6468

6569
useEffect(() => {
66-
if (hasValidatedStartupAuth.current || cookies.user === undefined)
67-
return
70+
if (hasValidatedStartupAuth.current || cookieUser === undefined) return
6871

6972
hasValidatedStartupAuth.current = true
7073
void refreshUserAuth()
71-
}, [cookies.user])
74+
}, [cookieUser])
7275

7376
useEffect(() => {
74-
if (cookies.user !== undefined) {
75-
try {
76-
const nextUser = User.parse({
77-
name: cookies.user.name,
78-
id: cookies.user.id,
79-
virtual: cookies.user.virtual,
80-
valid_until: cookies.user.valid_until,
81-
permissions: cookies.user.permissions,
82-
})
83-
84-
setUserValidUntil(nextUser.valid_until.getTime())
85-
setUser((current) =>
86-
current !== null && hasSameUserIdentity(current, nextUser)
87-
? current
88-
: nextUser,
89-
)
90-
} catch {
91-
setUser(null)
92-
setUserValidUntil(null)
93-
void refreshUserAuth()
94-
}
95-
} else {
96-
setUser(null)
97-
setUserValidUntil(null)
77+
if (cookieUser === undefined || user === null) {
9878
void refreshUserAuth()
9979
}
100-
}, [cookies.user])
80+
}, [cookieUser, user])
10181

10282
useEffect(() => {
10383
if (userValidUntil === null) return
@@ -117,7 +97,7 @@ export default function Layout() {
11797
useEffect(() => {
11898
let eventSource: EventSource | undefined
11999

120-
if (user !== null) {
100+
if (userId !== undefined) {
121101
eventSource = new EventSource("/api/events")
122102

123103
eventSource.addEventListener("create_game", (e) => {
@@ -160,7 +140,7 @@ export default function Layout() {
160140
return () => {
161141
if (eventSource) eventSource.close()
162142
}
163-
}, [user])
143+
}, [userId])
164144

165145
useEffect(() => {
166146
document.documentElement.lang = language

client/src/navigation.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import EventManager from "@lomray/event-manager"
22
import { useLocalStorage } from "@uidotdev/usehooks"
3-
import { type MouseEvent, useCallback, useEffect, useRef, useState } from "react"
3+
import {
4+
type MouseEvent,
5+
useCallback,
6+
useEffect,
7+
useRef,
8+
useState,
9+
} from "react"
410
import Container from "react-bootstrap/Container"
511
import Nav from "react-bootstrap/Nav"
612
import NavDropdown from "react-bootstrap/NavDropdown"
@@ -38,9 +44,8 @@ export default function Navigation({
3844
processing: 0,
3945
})
4046
const [, setWelcome] = useLocalStorage("welcome")
41-
const [popoverTarget, setPopoverTarget] = useState<HTMLAnchorElement | null>(
42-
null,
43-
)
47+
const [popoverTarget, setPopoverTarget] =
48+
useState<HTMLAnchorElement | null>(null)
4449
const popoverRef = useRef<HTMLDivElement | null>(null)
4550

4651
const handleResize = useCallback(() => {
@@ -186,7 +191,9 @@ export default function Navigation({
186191
<Nav.Item>
187192
<Nav.Link
188193
aria-expanded={showHitsStatus}
189-
onClick={(e: MouseEvent<HTMLAnchorElement>) => {
194+
onClick={(
195+
e: MouseEvent<HTMLAnchorElement>,
196+
) => {
190197
setShowHitsStatus(!showHitsStatus)
191198
setPopoverTarget(e.currentTarget)
192199
}}

0 commit comments

Comments
 (0)