123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- import React, { useContext } from "react";
- import {
- useItemActions,
- useMessage,
- useBoardConfig,
- useWire,
- } from "react-sync-board";
- import { useTranslation } from "react-i18next";
- import SubscribeSessionEvents from "./SubscribeSessionEvents";
- import { updateSession, getSession, getGame } from "../utils/api";
- import demoEn from "../games/demo_en.json?url";
- import demoFr from "../games/demo_fr.json?url";
- import demoIt from "../games/demo_it.json?url"
- export const SessionContext = React.createContext({});
- const demos = {
- fr: demoFr,
- it: demoIt
- };
- const emtpyBoard = {
- items: [],
- availableItems: [],
- board: {
- translations: [
- {
- language: "fr",
- name: "Choisissez un jeu",
- description: "...",
- },
- {
- language: "it",
- name: "Scegli un gioco",
- description: "...",
- },
- ],
- defaultName: "Choose a game",
- defaultLanguage: "en",
- defaultDescription: "...",
- gridSize: 1,
- },
- };
- export const SessionProvider = ({ sessionId, fromGameId, children }) => {
- const { i18n } = useTranslation();
- const { setItemList, getItemList } = useItemActions();
- const { messages, setMessages } = useMessage();
- const [availableItems, setAvailableItems] = React.useState([]);
- const [boardConfig, setBoardConfig] = useBoardConfig();
- const [sessionLoaded, setSessionLoaded] = React.useState(false);
- const [currentGameId, setCurrentGameId] = React.useState(fromGameId);
- const { wire } = useWire("board");
- const loadSession = React.useCallback(async () => {
- let sessionData;
- // Init session from server
- try {
- // First from session if exists
- sessionData = await getSession(sessionId);
- const sessionGameId = sessionData.gameId;
- // Update availableItems from original game
- if (sessionGameId) {
- const { availableItems } = await getGame(sessionGameId);
- sessionData.availableItems = availableItems;
- setCurrentGameId(sessionGameId);
- }
- } catch {
- if (fromGameId) {
- // Then from initial game
- if (fromGameId === "demo") {
- const foundLang = i18n.languages.find((lang) => demos[lang]);
- if (foundLang) {
- sessionData = await (await fetch(demos[foundLang])).json();
- } else {
- sessionData = await (await fetch(demoEn)).json();
- }
- } else {
- sessionData = await getGame(fromGameId);
- }
- } else {
- // Empty board
- sessionData = emtpyBoard;
- }
- }
- return sessionData;
- }, [fromGameId, i18n.languages, sessionId]);
- const setSession = React.useCallback(
- async (newData, sync = false) => {
- const { availableItems, items, board, messages = [] } = newData;
- setAvailableItems(availableItems);
- // The filter prevents the empty item bug or missing type on reload
- setItemList(items.filter((item) => item && item.type));
- setBoardConfig(board, false);
- setMessages(messages);
- if (sync) {
- // Send loadSession event for other user
- wire.publish("loadSession", newData);
- }
- setSessionLoaded(true);
- },
- [wire, setBoardConfig, setItemList, setMessages]
- );
- const getCurrentSession = React.useCallback(async () => {
- const currentSession = {
- items: await getItemList(),
- board: boardConfig,
- availableItems: availableItems,
- messages: messages.slice(-50),
- timestamp: Date.now(),
- gameId: fromGameId,
- };
- return currentSession;
- }, [availableItems, boardConfig, fromGameId, getItemList, messages]);
- const changeGame = React.useCallback(
- async (newGameId) => {
- const newGame = await getGame(newGameId);
- const currentSession = getCurrentSession();
- setSession({ ...currentSession, ...newGame }, true);
- },
- [getCurrentSession, setSession]
- );
- const saveSession = React.useCallback(async () => {
- const currentSession = await getCurrentSession();
- if (currentSession.items.length) {
- try {
- return await updateSession(sessionId, currentSession);
- } catch (e) {
- console.log(e);
- }
- }
- }, [getCurrentSession, sessionId]);
- return (
- <SessionContext.Provider
- value={{
- loadSession,
- changeGame,
- setSession,
- getSession: getCurrentSession,
- saveSession,
- sessionLoaded,
- sessionId,
- gameId: currentGameId,
- availableItems,
- boardConfig,
- messages,
- }}
- >
- {children}
- <SubscribeSessionEvents
- getSession={getCurrentSession}
- setSession={setSession}
- />
- </SessionContext.Provider>
- );
- };
- export const useSession = () => {
- return useContext(SessionContext);
- };
- export default useSession;
|