feat: added laravel reverb and websocket, also emote throwing added

This commit is contained in:
2026-08-16 17:10:42 +02:00
parent 50e9fbd0b0
commit 6f47ed0674
30 changed files with 2244 additions and 34 deletions
@@ -0,0 +1,94 @@
import { router } from '@inertiajs/vue3';
import { onScopeDispose, watch } from 'vue';
import { getEcho } from '@/lib/echo';
import type { RoomStateChangedPayload } from '@/types/room';
const ROOM_EVENT = '.room.state.changed';
export function useRoomRealtime(
roomId: () => string,
stateVersion: () => number,
): void {
let reloadInProgress = false;
let pendingVersion = 0;
let disposed = false;
function reloadRoom(): void {
if (reloadInProgress || disposed) {
return;
}
reloadInProgress = true;
router.reload({
only: ['room', 'currentPlayer'],
onFinish: () => {
reloadInProgress = false;
if (disposed) {
return;
}
if (pendingVersion > stateVersion()) {
reloadRoom();
return;
}
pendingVersion = stateVersion();
},
});
}
function handleRoomChange(payload: RoomStateChangedPayload): void {
if (
typeof payload.version !== 'number' ||
payload.version <= Math.max(stateVersion(), pendingVersion)
) {
return;
}
pendingVersion = payload.version;
if (payload.change === 'room_deleted') {
router.visit('/', { replace: true });
return;
}
reloadRoom();
}
const stopWatchingRoom = watch(
roomId,
(nextRoomId, _previousRoomId, onCleanup) => {
const echo = getEcho();
const channelName = `rooms.${nextRoomId}`;
pendingVersion = stateVersion();
echo.channel(channelName).listen(ROOM_EVENT, handleRoomChange);
onCleanup(() => {
echo.leaveChannel(channelName);
});
},
{ immediate: true },
);
const stopWatchingVersion = watch(
stateVersion,
(version) => {
if (!reloadInProgress) {
pendingVersion = Math.max(pendingVersion, version);
}
},
{ flush: 'sync' },
);
onScopeDispose(() => {
disposed = true;
stopWatchingRoom();
stopWatchingVersion();
});
}