mirror of
https://github.com/ericasch6/scrum-poker-internal.git
synced 2026-10-13 17:12:08 +00:00
Merge pull request #7 from ericasch6/codex/remove-moderator-throw-throttle
removed throttle for mod
This commit is contained in:
@@ -29,15 +29,17 @@ class RoomEmoteService
|
||||
]);
|
||||
}
|
||||
|
||||
$rateLimitKey = "room-emote:{$room->id}:{$player->id}";
|
||||
if (! $player->isModerator()) {
|
||||
$rateLimitKey = "room-emote:{$room->id}:{$player->id}";
|
||||
|
||||
abort_if(
|
||||
RateLimiter::tooManyAttempts($rateLimitKey, 10),
|
||||
429,
|
||||
'Bitte warte kurz, bevor du erneut wirfst.',
|
||||
);
|
||||
abort_if(
|
||||
RateLimiter::tooManyAttempts($rateLimitKey, 10),
|
||||
429,
|
||||
'Bitte warte kurz, bevor du erneut wirfst.',
|
||||
);
|
||||
|
||||
RateLimiter::hit($rateLimitKey, 10);
|
||||
RateLimiter::hit($rateLimitKey, 10);
|
||||
}
|
||||
|
||||
PaperBallThrown::dispatch(
|
||||
Str::uuid()->toString(),
|
||||
|
||||
@@ -21,6 +21,7 @@ const { activePaperBalls, hitPlayerIds, throwingAtPlayerId, throwPaperBall } =
|
||||
usePaperBallToss({
|
||||
roomId: () => props.room.id,
|
||||
currentPlayerId: () => props.currentPlayer.id,
|
||||
currentPlayerIsModerator: () => props.currentPlayer.is_moderator,
|
||||
board: gameBoard,
|
||||
});
|
||||
|
||||
@@ -115,7 +116,9 @@ const voteCount = computed(
|
||||
:revealed="room.revealed"
|
||||
:presenter-mode="presenterMode"
|
||||
:is-paper-ball-hit="hitPlayerIds.includes(player.id)"
|
||||
:throw-disabled="throwingAtPlayerId !== null"
|
||||
:throw-disabled="
|
||||
!currentPlayer.is_moderator && throwingAtPlayerId !== null
|
||||
"
|
||||
@throw-paper-ball="throwPaperBall"
|
||||
/>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ const THROW_BUTTON_COOLDOWN = 550;
|
||||
export function usePaperBallToss({
|
||||
roomId,
|
||||
currentPlayerId,
|
||||
currentPlayerIsModerator,
|
||||
board,
|
||||
}: PaperBallTossOptions) {
|
||||
const activePaperBalls = ref<PaperBallFlight[]>([]);
|
||||
@@ -35,9 +36,11 @@ export function usePaperBallToss({
|
||||
}
|
||||
|
||||
async function throwPaperBall(targetPlayerId: number): Promise<void> {
|
||||
const shouldApplyCooldown = !currentPlayerIsModerator();
|
||||
|
||||
if (
|
||||
targetPlayerId === currentPlayerId() ||
|
||||
throwingAtPlayerId.value !== null
|
||||
(shouldApplyCooldown && throwingAtPlayerId.value !== null)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@@ -52,7 +55,9 @@ export function usePaperBallToss({
|
||||
return;
|
||||
}
|
||||
|
||||
throwingAtPlayerId.value = targetPlayerId;
|
||||
if (shouldApplyCooldown) {
|
||||
throwingAtPlayerId.value = targetPlayerId;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(throwPaperBallRoute(roomId()).url, {
|
||||
@@ -91,11 +96,13 @@ export function usePaperBallToss({
|
||||
} catch {
|
||||
toast.error('Der Papierknäuel konnte nicht geworfen werden.');
|
||||
} finally {
|
||||
schedule(() => {
|
||||
if (throwingAtPlayerId.value === targetPlayerId) {
|
||||
throwingAtPlayerId.value = null;
|
||||
}
|
||||
}, THROW_BUTTON_COOLDOWN);
|
||||
if (shouldApplyCooldown) {
|
||||
schedule(() => {
|
||||
if (throwingAtPlayerId.value === targetPlayerId) {
|
||||
throwingAtPlayerId.value = null;
|
||||
}
|
||||
}, THROW_BUTTON_COOLDOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ export type PaperBallFlight = {
|
||||
export type PaperBallTossOptions = {
|
||||
roomId: () => string;
|
||||
currentPlayerId: () => number;
|
||||
currentPlayerIsModerator: () => boolean;
|
||||
board: Ref<HTMLElement | null>;
|
||||
};
|
||||
|
||||
|
||||
@@ -59,6 +59,58 @@ test('a participant can throw a realtime paper ball at another player', function
|
||||
->and($room->state_version)->toBe($stateVersion);
|
||||
});
|
||||
|
||||
test('moderator paper ball throws are not rate limited', function () {
|
||||
Event::fake([PaperBallThrown::class]);
|
||||
$room = createEmoteRoom();
|
||||
$moderator = $room->players()->create([
|
||||
'name' => 'Eric',
|
||||
'is_moderator' => true,
|
||||
]);
|
||||
$target = $room->players()->create([
|
||||
'name' => 'Anna',
|
||||
'is_moderator' => false,
|
||||
]);
|
||||
|
||||
for ($throwCount = 0; $throwCount < 11; $throwCount++) {
|
||||
$this->withSession(["room_players.{$room->id}" => $moderator->id])
|
||||
->postJson(route('room.emote.paper-ball.store', $room), [
|
||||
'target_player_id' => $target->id,
|
||||
])
|
||||
->assertNoContent();
|
||||
}
|
||||
|
||||
Event::assertDispatchedTimes(PaperBallThrown::class, 11);
|
||||
});
|
||||
|
||||
test('participant paper ball throws remain rate limited', function () {
|
||||
Event::fake([PaperBallThrown::class]);
|
||||
$room = createEmoteRoom();
|
||||
$moderator = $room->players()->create([
|
||||
'name' => 'Eric',
|
||||
'is_moderator' => true,
|
||||
]);
|
||||
$participant = $room->players()->create([
|
||||
'name' => 'Anna',
|
||||
'is_moderator' => false,
|
||||
]);
|
||||
|
||||
for ($throwCount = 0; $throwCount < 10; $throwCount++) {
|
||||
$this->withSession(["room_players.{$room->id}" => $participant->id])
|
||||
->postJson(route('room.emote.paper-ball.store', $room), [
|
||||
'target_player_id' => $moderator->id,
|
||||
])
|
||||
->assertNoContent();
|
||||
}
|
||||
|
||||
$this->withSession(["room_players.{$room->id}" => $participant->id])
|
||||
->postJson(route('room.emote.paper-ball.store', $room), [
|
||||
'target_player_id' => $moderator->id,
|
||||
])
|
||||
->assertTooManyRequests();
|
||||
|
||||
Event::assertDispatchedTimes(PaperBallThrown::class, 10);
|
||||
});
|
||||
|
||||
test('a participant cannot throw a paper ball at themselves', function () {
|
||||
Event::fake([PaperBallThrown::class]);
|
||||
$room = createEmoteRoom();
|
||||
|
||||
Reference in New Issue
Block a user