📄 P2PContext.js
/home/palash/git/site/node_modules/new_site/src/components/study/P2PContext.js
Language: js • Lines: 101
// P2PContext.js
import React, { createContext, useContext, useState, useEffect, useRef } from 'react';
import { Peer } from 'peerjs';

const P2PContext = createContext();

export function P2PProvider({ children }) {
    const [peerId, setPeerId] = useState('');
    const [connection, setConnection] = useState(null);
    const [isConnected, setIsConnected] = useState(false);

    // Dynamic shared quiz state
    const [quizState, setQuizState] = useState({
        activeApp: 'menu',

        wordScreen: 1,
        words: [],
        selectedLangs: {},

        // Lifted WordQuiz states
        currentWordIndex: 0,
        score: 0,
        total: 0,
        correct: 0,
        wrong: 0,
        quizEnded: false,
        status: 'Not Started',
        answer: ''
    });

    const peerRef = useRef(null);

    const getPairingUrl = (id) => {
        const url = new window.URL(window.location.href);
        url.searchParams.set('pairWith', id);
        return url.toString();
    };

    useEffect(() => {
        const peer = new Peer(undefined, {
            host: '0.peerjs.com',
            port: 443,
            secure: true,
            pingInterval: 5000
        });
        peerRef.current = peer;

        peer.on('open', (id) => {
            setPeerId(id);
            const urlParams = new URLSearchParams(window.location.search);
            const pairId = urlParams.get('pairWith');
            if (pairId) {
                const conn = peer.connect(pairId);
                handleConnection(conn);
            }
        });

        peer.on('connection', (conn) => {
            handleConnection(conn);
        });

        return () => peer.destroy();
    }, []);

    const handleConnection = (conn) => {
        setConnection(conn);

        conn.on('open', () => {
            setIsConnected(true);
        });

        conn.on('data', (incomingData) => {
            setQuizState(incomingData);
        });

        conn.on('close', () => {
            setIsConnected(false);
            setConnection(null);
        });
    };

    const sendStateUpdate = (updatedState) => {
        setQuizState((prevState) => {
            const mergedState = { ...prevState, ...updatedState };
            if (connection && isConnected) {
                connection.send(mergedState); 
            }

            console.log("Merged state", mergedState);
            return mergedState; 
        });
    };

    return (
        <P2PContext.Provider value={{ peerId, isConnected, quizState, sendStateUpdate, getPairingUrl }}>
            {children}
        </P2PContext.Provider>
    );
}

export const useP2P = () => useContext(P2PContext);