115 lines
3.2 KiB
JavaScript
115 lines
3.2 KiB
JavaScript
/**
|
|
* This file is part of the SplendidBear Websites' projects.
|
|
*
|
|
* Copyright (c) 2026 @ www.splendidbear.org
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
import { useQuery, useMutation } from '@tanstack/react-query';
|
|
|
|
/**
|
|
* Game Data Provider Hook
|
|
* Centralized API communication layer for game-related queries and mutations
|
|
*/
|
|
const useGameDataProvider = gameAssoc => {
|
|
// Queries
|
|
const connectQuery = useQuery({
|
|
queryKey: ['game-connect', gameAssoc],
|
|
queryFn: () => fetch(`/api/game/connect/${gameAssoc}`)
|
|
.then(r => r.text())
|
|
.then(b64 => JSON.parse(window.atob(b64))),
|
|
enabled: false,
|
|
retry: false,
|
|
});
|
|
|
|
// Mutations
|
|
const startMutation = useMutation({
|
|
mutationFn: () => fetch('/api/game/start', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ gameAssoc }),
|
|
}).then(r => r.json()),
|
|
});
|
|
|
|
const joinMutation = useMutation({
|
|
mutationFn: () => fetch(`/api/game/join/${gameAssoc}`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
}),
|
|
});
|
|
|
|
const stepMutation = useMutation({
|
|
mutationFn: dataPack => fetch(`/api/game/step/${gameAssoc}`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(dataPack),
|
|
}).then(r => r.json()),
|
|
});
|
|
|
|
const heartbeatMutation = useMutation({
|
|
mutationFn: color => fetch(`/api/game/heartbeat/${gameAssoc}`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ color }),
|
|
}).then(r => r.json()),
|
|
});
|
|
|
|
const challengeRespondMutation = useMutation({
|
|
mutationFn: ({ challengerGameAssoc, accepted, targetGameAssoc }) => fetch('/api/game/challenge/respond/' + challengerGameAssoc, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ accepted, targetGameAssoc }),
|
|
}).then(r => r.json()),
|
|
});
|
|
|
|
const leaveMutation = useMutation({
|
|
mutationFn: () => fetch(`/api/game/leave/${gameAssoc}`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
}).then(r => r.json()),
|
|
});
|
|
|
|
return {
|
|
// Queries
|
|
connectQuery,
|
|
// Mutations
|
|
startMutation,
|
|
joinMutation,
|
|
stepMutation,
|
|
heartbeatMutation,
|
|
challengeRespondMutation,
|
|
leaveMutation,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Lobby Data Provider Hook
|
|
* Centralized API communication layer for lobby-related queries and mutations
|
|
*/
|
|
export const useLobbyDataProvider = () => {
|
|
const waitingPlayersQuery = useQuery({
|
|
queryKey: ['game-waiting'],
|
|
queryFn: () => fetch('/api/game/waiting')
|
|
.then(r => r.json()),
|
|
});
|
|
|
|
const challengeMutation = useMutation({
|
|
mutationFn: ({ targetGameAssoc, challengerGameAssoc }) => fetch(`/api/game/challenge/${targetGameAssoc}`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ challengerGameAssoc }),
|
|
}).then(r => r.json()),
|
|
});
|
|
|
|
return {
|
|
// Queries
|
|
waitingPlayersQuery,
|
|
// Mutations
|
|
challengeMutation,
|
|
};
|
|
};
|
|
|
|
export default useGameDataProvider;
|