Skip to content

Commit

Permalink
refactor(search): move matchmaking logic inside a custom hook
Browse files Browse the repository at this point in the history
  • Loading branch information
prisca-c committed Sep 6, 2024
1 parent 554c02c commit 558a044
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 57 deletions.
65 changes: 65 additions & 0 deletions inertia/features/matchmaking/use_matchmaking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useEffect, useState } from 'react'
import { useTransmit } from '~/hooks/use_transmit'
import { useTranslation } from 'react-i18next'
import { Api } from '~/services/api'
import { router } from '@inertiajs/react'
import type { SearchProps } from '~/pages/search'

export const useMatchmaking = (props: SearchProps) => {
const { user, existingSession } = props
const [queueCount, setQueueCount] = useState(0)
const { subscription: userListener } = useTransmit({ url: `game/user/${user.id}` })
const { subscription: queueListener } = useTransmit({ url: 'game/search' })

const { t } = useTranslation()

const registerToQueue = async () => {
const response: { message: string; queueCount: number } = await new Api().post('/game/search')
setQueueCount(response.queueCount)
}

useEffect(() => {
if (existingSession) {
router.visit(`/game/session/${existingSession}`)
return
}
registerToQueue()
}, [])

userListener?.create()
queueListener?.create()

userListener?.onMessage(async (message: { status: string; sessionId: string }) => {
if (message.status === 'accept') {
await new Api().get(`/game/session/${message.sessionId}/accept`)
return
}

if (message.status === 'removed') {
await queueListener?.delete()
await userListener?.delete()
return router.visit('/game')
}

if (message.status === 'start') {
return router.visit(`/game/session/${message.sessionId}`)
}
})

queueListener?.onMessage((message: { queueCount: number }) => {
setQueueCount(message.queueCount)
})

const cancelQueue = async () => {
await new Api().delete('/game/search')
await queueListener?.delete()
await userListener?.delete()
return router.visit('/game')
}

return {
cancelQueue,
queueCount,
t,
}
}
61 changes: 4 additions & 57 deletions inertia/pages/search.tsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,15 @@
import { useTransmit } from '~/hooks/use_transmit'
import User from '#models/user'
import { useEffect, useState } from 'react'
import { Api } from '~/services/api'
import { router } from '@inertiajs/react'
import type { GameSessionId } from '#features/game_session/types/game_session'
import { Button } from '~/features/utils/components/button'
import { useTranslation } from 'react-i18next'
import { useMatchmaking } from '~/features/matchmaking/use_matchmaking'

type Props = {
export type SearchProps = {
user: User
existingSession: GameSessionId
}

export default function Search(props: Props) {
const { user, existingSession } = props
const [queueCount, setQueueCount] = useState(0)
const { subscription: userListener } = useTransmit({ url: `game/user/${user.id}` })
const { subscription: queueListener } = useTransmit({ url: 'game/search' })

const { t } = useTranslation()

const registerToQueue = async () => {
const response: { message: string; queueCount: number } = await new Api().post('/game/search')
setQueueCount(response.queueCount)
}

useEffect(() => {
if (existingSession) {
router.visit(`/game/session/${existingSession}`)
return
}
registerToQueue()
}, [])

userListener?.create()
queueListener?.create()

userListener?.onMessage(async (message: { status: string; sessionId: string }) => {
if (message.status === 'accept') {
await new Api().get(`/game/session/${message.sessionId}/accept`)
return
}

if (message.status === 'removed') {
await queueListener?.delete()
await userListener?.delete()
return router.visit('/game')
}

if (message.status === 'start') {
return router.visit(`/game/session/${message.sessionId}`)
}
})

queueListener?.onMessage((message: { queueCount: number }) => {
setQueueCount(message.queueCount)
})

const cancelQueue = async () => {
await new Api().delete('/game/search')
await queueListener?.delete()
await userListener?.delete()
return router.visit('/game')
}
export default function Search(props: SearchProps) {
const { queueCount, cancelQueue, t } = useMatchmaking(props)

return (
<div className={'text-center'}>
Expand Down

0 comments on commit 558a044

Please sign in to comment.