Skip to content

Commit

Permalink
refactor socket event handling
Browse files Browse the repository at this point in the history
  • Loading branch information
deveshidwivedi committed Jun 21, 2024
1 parent 3387d43 commit cfdd222
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 70 deletions.
9 changes: 7 additions & 2 deletions common/recoil/options/options.hooks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import {useRecoilValue} from "recoil";
import {useRecoilValue, useSetRecoilState} from "recoil";
import {optionsAtom} from "./options.atoms";

export const useOptions = () => {
const options= useRecoilValue(optionsAtom);
return options;
};
};

export const useSetOptions = () => {
const setOptions = useSetRecoilState(optionsAtom);
return setOptions;
}
2 changes: 1 addition & 1 deletion common/recoil/users/users.atoms.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {atom,selector} from "recoil";

export const usersAtom = atom<{ [key:string]: [number,number][][]}> ({
export const usersAtom = atom<{ [key:string]: Move[]}> ({
key: "users",
default: {},
});
Expand Down
12 changes: 7 additions & 5 deletions common/types/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ export declare global {
lineColor: string;
}

interface Move {
path: [number, number][];
options: CtxOptions;
}

interface ServerToClientEvents {
user_draw: (newMoves: [number, number][],
options: CtxOptions,
userId: string
) => void;
user_draw: (move: Move, userId: string) => void;
user_undo(userId: string): void;
mouse_moved: (x:number, y:number, socketId: string) => void;
users_in_room: (socketIds: string[]) => void;
user_disconnected: (socketId: string) => void;
}

interface ClientToServerEvents {
draw: (moves: [number, number][], options: CtxOptions) => void;
draw: (move: Move) => void;
mouse_move: (x:number, y:number) => void;
undo: () => void;
}
Expand Down
36 changes: 11 additions & 25 deletions modules/room/helpers/Canvas.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,36 @@
export const drawFromSocket = (
socketMoves: [number, number][],
socketOptions: CtxOptions,
export const handleMove = (
move: Move,
ctx: CanvasRenderingContext2D,
afterDraw: ()=> void
)=>{
const {options, path} = move;
const tempCtx = ctx;

if(tempCtx){
tempCtx.lineWidth= socketOptions.lineWidth;
tempCtx.strokeStyle= socketOptions.lineColor;
tempCtx.lineWidth= options.lineWidth;
tempCtx.strokeStyle= options.lineColor;

tempCtx.beginPath();
socketMoves.forEach(([x,y])=>{
path.forEach(([x,y])=>{
tempCtx.lineTo(x,y);
});
tempCtx.stroke();
tempCtx.closePath();
afterDraw();
}
};

export const drawOnUndo = (
ctx: CanvasRenderingContext2D,
savedMoves: [number, number][][],
users: {[key:string]: [number, number][][]}
savedMoves: Move[],
users: {[key: string]: Move[]}
) => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

Object.values(users).forEach((user)=>{
user.forEach((userMove)=>{
ctx.beginPath();
userMove.forEach(([x,y])=>{
ctx.lineTo(x,y);
});
ctx.stroke();
ctx.closePath();
});
user.forEach((move)=> handleMove(move,ctx));
});

savedMoves.forEach((movesArr)=> {
ctx.beginPath();
movesArr.forEach(([x,y])=>{
ctx.lineTo(x,y);
});
ctx.stroke();
ctx.closePath();
savedMoves.forEach((move)=> {
handleMove(move,ctx);
});


Expand Down
87 changes: 52 additions & 35 deletions modules/room/hooks/Canvas.hooks.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { useCallback, useEffect, useState } from "react";
import { socket } from "@/common/lib/socket";
import { useOptions } from "@/common/recoil/options";
import { drawOnUndo } from "../helpers/Canvas.helpers";
import { drawOnUndo, handleMove } from "../helpers/Canvas.helpers";
import usersAtom, { useUsers } from "@/common/recoil/users";
import { useBoardPosition } from "./useBoardPosition";
import { getPos } from "@/common/lib/getPos";
import { useSetRecoilState } from "recoil";

const savedMoves: [number, number][][] = [];
const savedMoves: Move[] = [];
let moves: [number, number][] = [];

export const useDraw = (
Expand Down Expand Up @@ -68,12 +68,16 @@ export const useDraw = (

const handleEndDrawing = () => {
if (!ctx || blocked) return;
setDrawing(false);
ctx.closePath();
setDrawing(false);

savedMoves.push(moves);
const move: Move= {
path: moves, options
}

savedMoves.push(move);

socket.emit("draw", moves, options);
socket.emit("draw", move);
moves = [];
handleEnd();
};
Expand All @@ -98,52 +102,65 @@ export const useDraw = (
// Hook to listen for user draw & undo events
export const useSocketDraw = (
ctx: CanvasRenderingContext2D | undefined,
drawing : boolean,
handleEnd: () => void
) => {
const setUsers = useSetRecoilState(usersAtom);

useEffect(() => {
socket.on("user_draw", (newMoves, options, userId) => {
if (ctx) {
ctx.lineWidth = options.lineWidth;
ctx.strokeStyle = options.lineColor;
ctx.beginPath();

newMoves.forEach(([x, y]) => {
ctx.lineTo(x, y);
});
ctx.stroke();
ctx.closePath();
handleEnd();
let movesToDrawLater: Move | undefined;
let userIdLater= "";
socket.on("user_draw", (move, userId) => {
if (ctx && !drawing) {
handleMove(move, ctx);

setUsers((prevUsers) => {
const newUsers = { ...prevUsers };
// newUsers[userId] is initialized as an array
if (!Array.isArray(newUsers[userId])) {
newUsers[userId] = [];
}
newUsers[userId] = [...newUsers[userId], newMoves];
// error maybe here
if (newUsers[userId]) newUsers[userId] = [...newUsers[userId], move];
return newUsers;
});
}else {
movesToDrawLater = move;
userIdLater = userId;
}
});

socket.on("user_undo", (userId) => {


return () => {
socket.off("user_draw");

if(movesToDrawLater && userIdLater && ctx){
handleMove(movesToDrawLater, ctx);
handleEnd();
setUsers((prevUsers) => {
const newUsers = { ...prevUsers };
if (Array.isArray(newUsers[userId])) {
newUsers[userId] = newUsers[userId].slice(0, -1);
}
if (ctx) {
drawOnUndo(ctx, savedMoves, newUsers);
handleEnd();
}
return newUsers;
});
newUsers[userIdLater]= [
...newUsers[userIdLater], movesToDrawLater as Move];
return newUsers;
})
}
};
}, [ctx, handleEnd, setUsers, drawing ]);

useEffect(()=> {
socket.on("user_undo", (userId) => {
setUsers((prevUsers) => {
const newUsers = { ...prevUsers };
if (Array.isArray(newUsers[userId])) {
newUsers[userId] = newUsers[userId].slice(0, -1);
}
if (ctx) {
drawOnUndo(ctx, savedMoves, newUsers);
handleEnd();
}
return newUsers;
});

});
return () => {
socket.off("user_draw");
socket.off("user_undo");
};
}, [ctx, handleEnd, setUsers]);
},[ctx, handleEnd, setUsers]);

};
4 changes: 2 additions & 2 deletions server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ io.on("connection", (socket)=>{
const allUsers= io.sockets.adapter.rooms.get("global");
if (allUsers) io.to("global").emit("users_in_room", [...allUsers]);

socket.on("draw", (moves, options)=>{
socket.on("draw", (move)=>{
console.log("drawing");
socket.broadcast.emit("user_draw", moves, options, socket.id);
socket.broadcast.emit("user_draw", move, socket.id);
});

socket.on("mouse_move", (x,y) => {
Expand Down

0 comments on commit cfdd222

Please sign in to comment.