Skip to content

Commit

Permalink
refactor: move pre-ready up to separate module
Browse files Browse the repository at this point in the history
  • Loading branch information
garrappachc committed Dec 13, 2024
1 parent 2f85d55 commit 18b108c
Show file tree
Hide file tree
Showing 19 changed files with 149 additions and 51 deletions.
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ await app.register((await import('./statistics')).default)
await app.register((await import('./twitch-tv')).default)
await app.register((await import('./admin')).default)
await app.register((await import('./hall-of-game')).default)
await app.register((await import('./pre-ready')).default)

await app.listen({ host: environment.APP_HOST, port: environment.APP_PORT })
22 changes: 0 additions & 22 deletions src/players/plugins/timeout-pre-ready.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/queue/pre-ready/cancel.ts → src/pre-ready/cancel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { players } from '../../players'
import type { SteamId64 } from '../../shared/types/steam-id-64'
import { players } from '../players'
import type { SteamId64 } from '../shared/types/steam-id-64'

export async function cancel(player: SteamId64) {
await players.update(player, { $unset: { preReadyUntil: 1 } })
Expand Down
22 changes: 22 additions & 0 deletions src/pre-ready/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import fp from 'fastify-plugin'
import { cancel } from './cancel'
import { isPreReadied } from './is-pre-readied'
import { start } from './start'
import { toggle } from './toggle'
import { resolve } from 'node:path'

export const preReady = {
cancel,
isPreReadied,
start,
toggle,
} as const

export default fp(
async app => {
await app.register((await import('@fastify/autoload')).default, {
dir: resolve(import.meta.dirname, 'plugins'),
})
},
{ name: 'pre-ready up' },
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { players } from '../../players'
import type { SteamId64 } from '../../shared/types/steam-id-64'
import { players } from '../players'
import type { SteamId64 } from '../shared/types/steam-id-64'

export async function isPreReadied(player: SteamId64) {
const p = await players.bySteamId(player)
Expand Down
33 changes: 33 additions & 0 deletions src/pre-ready/plugins/auto-cancel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import fp from 'fastify-plugin'
import { collections } from '../../database/collections'
import { update } from '../../players/update'
import { secondsToMilliseconds } from 'date-fns'
import { events } from '../../events'
import { safe } from '../../utils/safe'

async function process() {
const toRemove = await collections.players.find({ preReadyUntil: { $lte: new Date() } }).toArray()
for (const p of toRemove) {
await update(p.steamId, { $unset: { preReadyUntil: 1 } })
}
}

export default fp(
async () => {
setInterval(process, secondsToMilliseconds(1))

events.on(
'game:created',
safe(async ({ game }) => {
await Promise.all(
game.slots.map(
async ({ player }) => await update(player, { $unset: { preReadyUntil: 1 } }),
),
)
}),
)
},
{
name: 'auto cancel pre-ready up',
},
)
6 changes: 3 additions & 3 deletions src/queue/pre-ready/start.ts → src/pre-ready/start.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { configuration } from '../../configuration'
import { players } from '../../players'
import type { SteamId64 } from '../../shared/types/steam-id-64'
import { configuration } from '../configuration'
import { players } from '../players'
import type { SteamId64 } from '../shared/types/steam-id-64'

export async function start(player: SteamId64) {
const timeout = await configuration.get('queue.pre_ready_up_timeout')
Expand Down
2 changes: 1 addition & 1 deletion src/queue/pre-ready/toggle.ts → src/pre-ready/toggle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SteamId64 } from '../../shared/types/steam-id-64'
import type { SteamId64 } from '../shared/types/steam-id-64'
import { cancel } from './cancel'
import { isPreReadied } from './is-pre-readied'
import { start } from './start'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export async function PreReadyUpButton(props: { actor?: SteamId64 | undefined })
class="button button--lighter min-w-[200px]"
id="pre-ready-up-button"
name="prereadytoggle"
ws-send
hx-trigger="click"
disabled={!isInQueue}
aria-selected={timeLeft > 0}
>
Expand All @@ -49,7 +51,7 @@ PreReadyUpButton.enable = () => {
<div id="notify-container" hx-swap-oob="beforeend">
<script type="module" id={id}>{`
document.getElementById('pre-ready-up-button').disabled = false;
setTimeout(() => document.getElementById('${id}').remove());
document.getElementById('${id}').remove();
`}</script>
</div>
)
Expand All @@ -61,7 +63,7 @@ PreReadyUpButton.disable = () => {
<div id="notify-container" hx-swap-oob="beforeend">
<script type="module" id={id}>{`
document.getElementById('pre-ready-up-button').disabled = true;
setTimeout(() => document.getElementById('${id}').remove());
document.getElementById('${id}').remove();
`}</script>
</div>
)
Expand Down
6 changes: 6 additions & 0 deletions src/queue/join.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { QueueSlotModel } from '../database/models/queue-slot.model'
import { QueueState } from '../database/models/queue-state.model'
import { events } from '../events'
import { logger } from '../logger'
import { preReady } from '../pre-ready'
import type { SteamId64 } from '../shared/types/steam-id-64'
import { getState } from './get-state'
import { mutex } from './mutex'
Expand Down Expand Up @@ -69,6 +70,11 @@ export async function join(slotId: number, steamId: SteamId64): Promise<QueueSlo

const slots = [oldSlot, targetSlot].filter(Boolean) as QueueSlotModel[]
events.emit('queue/slots:updated', { slots })

if (targetSlot?.ready) {
await preReady.start(steamId)
}

return slots
})
}
2 changes: 1 addition & 1 deletion src/queue/kick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { SteamId64 } from '../shared/types/steam-id-64'
import { getMapVoteResults } from './get-map-vote-results'
import { getState } from './get-state'
import { mutex } from './mutex'
import { preReady } from './pre-ready'
import { preReady } from '../pre-ready'

export async function kick(...steamIds: SteamId64[]): Promise<QueueSlotModel[]> {
return await mutex.runExclusive(async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/queue/leave.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { SteamId64 } from '../shared/types/steam-id-64'
import { getMapVoteResults } from './get-map-vote-results'
import { getState } from './get-state'
import { mutex } from './mutex'
import { preReady } from './pre-ready'
import { preReady } from '../pre-ready'

export async function leave(steamId: SteamId64): Promise<QueueSlotModel> {
return await mutex.runExclusive(async () => {
Expand Down
4 changes: 2 additions & 2 deletions src/queue/plugins/gateway-listeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import type { SteamId64 } from '../../shared/types/steam-id-64'
import { markAsFriend } from '../mark-as-friend'
import { getState } from '../get-state'
import { QueueState } from '../../database/models/queue-state.model'
import { PreReadyUpButton } from '../views/html/pre-ready-up-button'
import { preReady } from '../pre-ready'
import { PreReadyUpButton } from '../../pre-ready/views/html/pre-ready-up-button'
import { preReady } from '../../pre-ready'

export default fp(
// eslint-disable-next-line @typescript-eslint/require-await
Expand Down
2 changes: 1 addition & 1 deletion src/queue/plugins/sync-clients.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { BanAlerts } from '../views/html/ban-alerts'
import type { ObjectId } from 'mongodb'
import { whenGameEnds } from '../../games/when-game-ends'
import { CurrentPlayerCount } from '../views/html/current-player-count'
import { PreReadyUpButton } from '../views/html/pre-ready-up-button'
import { PreReadyUpButton } from '../../pre-ready/views/html/pre-ready-up-button'

export default fp(
// eslint-disable-next-line @typescript-eslint/require-await
Expand Down
11 changes: 0 additions & 11 deletions src/queue/pre-ready/index.ts

This file was deleted.

2 changes: 2 additions & 0 deletions src/queue/ready-up.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { logger } from '../logger'
import type { SteamId64 } from '../shared/types/steam-id-64'
import { getState } from './get-state'
import { mutex } from './mutex'
import { preReady } from '../pre-ready'

export async function readyUp(steamId: SteamId64): Promise<QueueSlotModel> {
return await mutex.runExclusive(async () => {
Expand All @@ -25,6 +26,7 @@ export async function readyUp(steamId: SteamId64): Promise<QueueSlotModel> {
}

events.emit('queue/slots:updated', { slots: [slot] })
await preReady.start(steamId)
return slot
})
}
2 changes: 1 addition & 1 deletion src/queue/views/html/queue.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { StreamList } from './stream-list'
import { BanAlerts } from './ban-alerts'
import { AcceptRulesDialog } from './accept-rules-dialog'
import { CurrentPlayerCount } from './current-player-count'
import { PreReadyUpButton } from './pre-ready-up-button'
import { PreReadyUpButton } from '../../../pre-ready/views/html/pre-ready-up-button'

export async function QueuePage(props: { user?: User | undefined }) {
const slots = await collections.queueSlots.find().toArray()
Expand Down
48 changes: 47 additions & 1 deletion tests/10-queue/07-pre-ready-up.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { mergeTests } from '@playwright/test'
import { accessMongoDb } from '../fixtures/access-mongo-db'
import { secondsToMilliseconds } from 'date-fns'
import { minutesToMilliseconds, secondsToMilliseconds } from 'date-fns'
import { launchGame, expect } from '../fixtures/launch-game'

const test = mergeTests(accessMongoDb, launchGame)
Expand Down Expand Up @@ -91,3 +91,49 @@ test('pre-ready up readies up when the queue is ready', async ({
}
}
})

test('pre-ready up enables automatically after readying up', async ({
users,
players,
desiredSlots,
}) => {
const polemic = users.byName('Polemic')
const shadowhunter = users.byName('Shadowhunter')

await Promise.all(
players
.filter(p => p.playerName !== 'Polemic')
.map(async user => {
const page = await user.queuePage()
await page.goto()
const slot = desiredSlots.get(user.playerName)!
await page.slot(slot).join()
}),
)

const page = await polemic.queuePage()
await page.goto()
await page.slot(desiredSlots.get('Polemic')!).join()
await expect(page.preReadyUpButton()).toHaveAttribute('aria-selected')

{
const page = await shadowhunter.queuePage()
await page.readyUpDialog().readyUp()
await expect(page.preReadyUpButton()).toHaveAttribute('aria-selected')
}

await Promise.all(
players.map(async user => {
const page = await user.queuePage()
const slot = desiredSlots.get(user.playerName)!

if (!(await page.slot(slot).isReady())) {
await page.readyUpDialog().notReady()
}

if (await page.slot(slot).isTaken()) {
await page.leaveQueue(minutesToMilliseconds(1))
}
}),
)
})
21 changes: 20 additions & 1 deletion tests/pages/queue.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ class QueueSlot {
this.locator = this.page.getByLabel(`Queue slot ${this.slotNumber}`, { exact: true })
}

async isTaken() {
return this.locator.locator('player-info').isVisible()
}

async isReady() {
return (await this.locator.locator('.player-info').getAttribute('data-player-ready')) === 'true'
}

joinButton() {
return this.locator.getByRole('button', {
name: `Join queue on slot ${this.slotNumber}`,
Expand Down Expand Up @@ -46,8 +54,19 @@ class ReadyUpDialog {
}
}

notReadyButton() {
return this.page.getByRole('button', { name: `No, I can't play now` })
}

async notReady() {
await this.page.getByRole('button', { name: `No, I can't play now` }).click()
const button = this.notReadyButton()
try {
await button.click({ timeout: secondsToMilliseconds(5) })
} catch (error) {
if (error instanceof errors.TimeoutError) {
return
}
}
}
}

Expand Down

0 comments on commit 18b108c

Please sign in to comment.