import React, { useState, useEffect } from 'react';
import Link from 'next/link';
import copy from 'copy-to-clipboard';
import protobuf from 'protobufjs';
import {
useWaku,
useContentPair,
useLightPush,
useStoreMessages,
useFilterMessages,
} from '@waku/react';
import { message } from '@waku/core';
import Loading from './Loading';
const ChatMessage = new protobuf.Type('ChatMessage')
.add(new protobuf.Field('timestamp', 1, 'uint64'))
.add(new protobuf.Field('sender', 2, 'string'))
.add(new protobuf.Field('message', 3, 'string'));
export default function Room(props) {
const { node } = useWaku();
const [nodeStart, setNodeStart] = useState(false);
const [move, setMove] = useState(false);
const [boxes, setBoxes] = useState({});
const [player, setPlayer] = useState(false);
const [opponentJoined, setOpponentJoined] = useState(null);
const [winner, setWinner] = useState(null);
const [winningPattern, setWinningPattern] = useState(null);
const { decoder, encoder } = useContentPair();
const { messages: storeMessages } = useStoreMessages({
node,
decoder,
});
const { messages: filterMessages } = useFilterMessages({ node, decoder });
const { push } = useLightPush({ node, encoder });
async function sendMessage(sender, message) {
const protoMessage = ChatMessage.create({
timestamp: Date.now(),
sender,
message,
});
const serialisedMessage = ChatMessage.encode(protoMessage).finish();
const timestamp = new Date();
await push({
payload: serialisedMessage,
timestamp,
});
console.log('MESSAGE PUSHED');
}
function decodeMessage(wakuMessage) {
if (!wakuMessage.payload) return;
const { timestamp, sender, message } = ChatMessage.decode(wakuMessage.payload);
if (!timestamp || !sender || !message) return;
const time = new Date();
time.setTime(Number(timestamp));
return {
message,
timestamp: time,
sender,
timestampInt: wakuMessage.timestamp,
};
}
useEffect(() => {
if (node !== undefined) {
if (player === false) {
const p =
sessionStorage.getItem('roomId') == props.room && sessionStorage.getItem('player') == 'x'
? 'x'
: 'o';
setPlayer(p);
if (p === 'o') {
sendMessage('o', 'joined');
}
}
setNodeStart(true);
}
}, [node]);
useEffect(() => {
let messages = storeMessages.concat(filterMessages);
let b = {};
let o = false;
messages = messages.map((message) => decodeMessage(message));
messages.forEach((message) => {
if (message.message === 'joined') {
o = true;
return;
}
if (message.message === 'winner') {
return;
}
b = { ...b, [message.message]: message.sender };
});
const winningCombinations = [
['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9'],
['1', '4', '7'],
['2', '5', '8'],
['3', '6', '9'],
['1', '5', '9'],
['3', '5', '7'],
];
let winner = null;
let temp = null;
let winningPattern = null;
winningCombinations.forEach((combination) => {
if (winner !== null) {
return;
}
for (let [i, c] of combination.entries()) {
if (b[c] === undefined) {
temp = null;
break;
} else {
if (temp === null) {
temp = b[c];
continue;
} else {
if (temp === b[c]) {
if (i === 2) {
winner = temp;
winningPattern = combination;
}
continue;
}
}
}
}
});
setWinner(winner);
setWinningPattern(winningPattern);
setOpponentJoined(o);
setBoxes(b);
}, [storeMessages, filterMessages]);
if (!nodeStart || !player || opponentJoined === null) {
return
Waku status : active
Peers : {node?.libp2p?.getPeers()?.length ?? '-'}
Game URL
https://waku-xo.vercel.app/game/{props.room}