mirror of
https://github.com/ericasch6/scrum-poker-internal.git
synced 2026-10-14 13:55:28 +00:00
kick forever
This commit is contained in:
@@ -32,7 +32,6 @@ class RoomJoinController extends Controller
|
||||
$room !== null
|
||||
&& ! $room->isClosed()
|
||||
&& $existingPlayer instanceof Player
|
||||
&& $existingPlayer->inactive_at === null
|
||||
) {
|
||||
return to_route('room.show', $room);
|
||||
}
|
||||
|
||||
@@ -113,12 +113,6 @@ class EnsureRoomParticipant
|
||||
]);
|
||||
}
|
||||
|
||||
if ($player->inactive_at !== null) {
|
||||
return to_route('room.join', [
|
||||
'join_code' => $room->join_code,
|
||||
]);
|
||||
}
|
||||
|
||||
$player->markAsSeen();
|
||||
$request->attributes->set('currentPlayer', $player);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class KickRoomPlayerRequest extends FormRequest
|
||||
return null;
|
||||
}
|
||||
|
||||
return $room->activePlayers()->find((int) $playerId);
|
||||
return $room->players()->find((int) $playerId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,9 +18,8 @@ class DashboardRoomResource extends JsonResource
|
||||
'join_code' => $this->resource->join_code,
|
||||
'current_round' => $this->resource->current_round,
|
||||
'players_count' => $this->resource->players_count,
|
||||
'active_player_count' => $this->resource->active_player_count,
|
||||
'players' => $this->resource->relationLoaded('activePlayers')
|
||||
? $this->resource->activePlayers
|
||||
'players' => $this->resource->relationLoaded('players')
|
||||
? $this->resource->players
|
||||
->map(fn ($player): array => [
|
||||
'id' => $player->id,
|
||||
'name' => $player->name,
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Player;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Queue\Queueable;
|
||||
|
||||
class MarkInactivePlayers implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
Player::query()
|
||||
->whereNull('inactive_at')
|
||||
->where('last_seen_at', '<=', now()->subHour())
|
||||
->update([
|
||||
'inactive_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Enums\RoomStateChange;
|
||||
use App\Events\RoomStateChanged;
|
||||
use App\Models\Player;
|
||||
use App\Models\Room;
|
||||
use App\Services\Rooms\RoomRealtimeStateService;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Queue\Queueable;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class RemoveAbsentPlayers implements ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
public function handle(RoomRealtimeStateService $realtimeState): void
|
||||
{
|
||||
$cutoff = now()->subHour();
|
||||
|
||||
Player::query()
|
||||
->where(function ($query) use ($cutoff): void {
|
||||
$query->where('last_seen_at', '<=', $cutoff)
|
||||
->orWhere(function ($query) use ($cutoff): void {
|
||||
$query->whereNull('last_seen_at')
|
||||
->where('created_at', '<=', $cutoff);
|
||||
});
|
||||
})
|
||||
->select(['id', 'room_id'])
|
||||
->chunkById(100, function ($players) use ($cutoff, $realtimeState): void {
|
||||
foreach ($players as $player) {
|
||||
$room = DB::transaction(function () use ($player, $cutoff): ?Room {
|
||||
$room = Room::withTrashed()
|
||||
->lockForUpdate()
|
||||
->find($player->room_id);
|
||||
|
||||
if ($room === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$currentPlayer = $room->players()
|
||||
->lockForUpdate()
|
||||
->find($player->id);
|
||||
|
||||
if ($currentPlayer === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$lastActivity = $currentPlayer->last_seen_at ?? $currentPlayer->created_at;
|
||||
|
||||
if ($lastActivity === null || $lastActivity->greaterThan($cutoff)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$currentPlayer->delete();
|
||||
$room->update([
|
||||
'state_version' => $room->state_version + 1,
|
||||
]);
|
||||
|
||||
return $room;
|
||||
});
|
||||
|
||||
if ($room !== null && ! $room->trashed()) {
|
||||
RoomStateChanged::dispatch(
|
||||
$room->id,
|
||||
$room->state_version,
|
||||
RoomStateChange::PlayerKicked,
|
||||
$realtimeState->for($room),
|
||||
$player->id,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@@ -16,7 +15,6 @@ use Illuminate\Support\Carbon;
|
||||
* @property string $name
|
||||
* @property bool $is_moderator
|
||||
* @property Carbon|null $last_seen_at
|
||||
* @property Carbon|null $inactive_at
|
||||
* @property Carbon|null $created_at
|
||||
* @property Carbon|null $updated_at
|
||||
* @property-read Room $room
|
||||
@@ -30,7 +28,6 @@ class Player extends Model
|
||||
'name',
|
||||
'is_moderator',
|
||||
'last_seen_at',
|
||||
'inactive_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
@@ -38,7 +35,6 @@ class Player extends Model
|
||||
return [
|
||||
'is_moderator' => 'boolean',
|
||||
'last_seen_at' => 'datetime',
|
||||
'inactive_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -85,14 +81,4 @@ class Player extends Model
|
||||
'last_seen_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder<Player> $query
|
||||
* @return Builder<Player>
|
||||
*/
|
||||
public function scopeActive(Builder $query): Builder
|
||||
{
|
||||
return $query->whereNull('inactive_at');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,12 +93,6 @@ class Room extends Model
|
||||
|
||||
}
|
||||
|
||||
/** @return HasMany<Player, $this> */
|
||||
public function activePlayers(): HasMany
|
||||
{
|
||||
return $this->hasMany(Player::class)->whereNull('inactive_at');
|
||||
}
|
||||
|
||||
/** @return BelongsTo<User, $this> */
|
||||
public function owner(): BelongsTo
|
||||
{
|
||||
|
||||
@@ -16,13 +16,12 @@ class DashboardRoomService
|
||||
$ownedRooms = $user
|
||||
->ownedRooms()
|
||||
->with([
|
||||
'activePlayers' => fn ($query) => $query
|
||||
'players' => fn ($query) => $query
|
||||
->select(['id', 'room_id', 'user_id', 'name', 'is_moderator', 'created_at'])
|
||||
->orderByDesc('is_moderator')
|
||||
->orderBy('created_at'),
|
||||
])
|
||||
->withCount('players')
|
||||
->withCount(['activePlayers as active_player_count'])
|
||||
->orderByRaw('closed_at IS NOT NULL')
|
||||
->orderByDesc('last_activity_at')
|
||||
->get();
|
||||
@@ -30,7 +29,6 @@ class DashboardRoomService
|
||||
$favoriteRooms = $user
|
||||
->favoriteRooms()
|
||||
->withCount('players')
|
||||
->withCount(['activePlayers as active_player_count'])
|
||||
->orderByRaw('closed_at IS NOT NULL')
|
||||
->orderByDesc('last_activity_at')
|
||||
->get();
|
||||
|
||||
@@ -20,7 +20,6 @@ class RoomPageService
|
||||
|
||||
$room->load([
|
||||
'players' => fn ($query) => $query
|
||||
->active()
|
||||
->select(['id', 'room_id', 'user_id', 'name', 'is_moderator', 'created_at'])
|
||||
->orderByDesc('is_moderator')
|
||||
->orderBy('created_at'),
|
||||
|
||||
@@ -80,7 +80,6 @@ class RoomParticipationService
|
||||
} else {
|
||||
$player->update([
|
||||
'last_seen_at' => now(),
|
||||
'inactive_at' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -150,16 +149,13 @@ class RoomParticipationService
|
||||
]);
|
||||
$change = RoomStateChange::PlayerJoined;
|
||||
} else {
|
||||
if ($player->inactive_at !== null) {
|
||||
$change = RoomStateChange::PlayerJoined;
|
||||
} elseif ($player->name !== $playerName) {
|
||||
if ($player->name !== $playerName) {
|
||||
$change = RoomStateChange::PlayerUpdated;
|
||||
}
|
||||
|
||||
$updates = [
|
||||
'name' => $playerName,
|
||||
'last_seen_at' => now(),
|
||||
'inactive_at' => null,
|
||||
];
|
||||
|
||||
if (
|
||||
@@ -282,14 +278,14 @@ class RoomParticipationService
|
||||
?User $user,
|
||||
?Player $currentPlayer,
|
||||
): void {
|
||||
$stateVersion = DB::transaction(function () use ($room, $player, $user, $currentPlayer): ?int {
|
||||
$stateVersion = DB::transaction(function () use ($room, $player, $user, $currentPlayer): int {
|
||||
$lockedRoom = Room::query()
|
||||
->lockForUpdate()
|
||||
->findOrFail($room->id);
|
||||
|
||||
$lockedCurrentPlayer = $currentPlayer === null
|
||||
? null
|
||||
: $lockedRoom->activePlayers()
|
||||
: $lockedRoom->players()
|
||||
->lockForUpdate()
|
||||
->find($currentPlayer->id);
|
||||
$isOwner = $user !== null && $lockedRoom->owner_id === $user->id;
|
||||
@@ -312,13 +308,7 @@ class RoomParticipationService
|
||||
403,
|
||||
);
|
||||
|
||||
if ($lockedPlayer->inactive_at !== null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$lockedPlayer->update([
|
||||
'inactive_at' => now(),
|
||||
]);
|
||||
$lockedPlayer->delete();
|
||||
$lockedRoom->update([
|
||||
'last_activity_at' => now(),
|
||||
'state_version' => $lockedRoom->state_version + 1,
|
||||
@@ -327,10 +317,6 @@ class RoomParticipationService
|
||||
return $lockedRoom->state_version;
|
||||
});
|
||||
|
||||
if ($stateVersion === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
RoomStateChanged::dispatch(
|
||||
$room->id,
|
||||
$stateVersion,
|
||||
|
||||
@@ -32,7 +32,6 @@ class RoomRealtimeStateService
|
||||
$room->refresh();
|
||||
$room->load([
|
||||
'players' => fn ($query) => $query
|
||||
->active()
|
||||
->select(['id', 'room_id', 'user_id', 'name', 'is_moderator', 'created_at'])
|
||||
->orderByDesc('is_moderator')
|
||||
->orderBy('created_at'),
|
||||
|
||||
Reference in New Issue
Block a user