timhaley94/holdem

View on GitHub
server/src/api/socket/room/index.js

Summary

Maintainability
A
0 mins
Test Coverage
F
26%
const { Room } = require('../../../domain');
const Views = require('../../views');
const events = require('../events');

const ROOM_ID = Symbol('roomId');

const socketRoomName = (id) => `room-${id}`;

function onStart(io) {
  Room.listener.listen(
    async (id) => {
      try {
        const room = await Room.retrieve({ id });

        io.emit(
          events.room.updated,
          Views.Room(room),
        );
      } catch (_e) {
        io.emit(
          events.room.deleted,
          id,
        );
      }
    },
  );
}

function getUserId(socket) {
  return socket.decoded_token.data.id;
}

function getRoomId(socket) {
  return socket[ROOM_ID] || null;
}

function setRoomId(socket, value) {
  socket[ROOM_ID] = value; // eslint-disable-line no-param-reassign
}

async function joinRoom(socket, id) {
  setRoomId(socket, id);

  await new Promise((resolve) => {
    socket.join(
      socketRoomName(id),
      resolve,
    );
  });
}

async function leaveRoom(socket) {
  const id = getRoomId(socket);

  if (id) {
    await new Promise((resolve) => {
      socket.leave(
        socketRoomName(id),
        resolve,
      );
    });

    setRoomId(socket, null);
  }
}

function sendMessage(socket, message) {
  const userId = getUserId(socket);
  const id = getRoomId(socket);

  if (id) {
    const name = events.room.message;
    const payload = {
      message,
      userId,
      timestamp: new Date(),
    };

    socket.emit(name, payload);
    socket.to(
      socketRoomName(id),
    ).emit(name, payload);
  }
}

function onConnect(socket) {
  const wrap = (fn) => (...args) => fn(socket, ...args);

  socket.on(events.room.join, wrap(joinRoom));
  socket.on(events.room.leave, wrap(leaveRoom));
  socket.on(events.room.send_message, wrap(sendMessage));
}

async function onDisconnect(socket) {
  await leaveRoom(socket);
}

module.exports = {
  onStart,
  onConnect,
  onDisconnect,
};