Commit 076ff1c9 authored by Grant's avatar Grant
Browse files

server now notifies the client when the canvas isn't cached

- added foundation for server-sent alerts (related #53)
parent 0e973160
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
/**
 * Handle alerts sent by the server (moderation or internal)
 */

import { IAlert } from "@sc07-canvas/lib/src/net";
import { toast } from "react-toastify";

/**
 * Handles IAlert outside of react
 * @param alert
 */
export const handleAlert = (alert: IAlert) => {
  switch (alert.is) {
    case "toast":
      handleToast(alert);
      break;
    case "modal":
      handleModal(alert);
      break;
  }
};

export const handleDismiss = (id: string) => {
  toast.dismiss(id);
};

const handleToast = (alert: IAlert<"toast">) => {
  const Body = (
    <>
      <b>{alert.title}</b>
      {alert.body && <> {alert.body}</>}
    </>
  );

  toast(Body, {
    toastId: alert.id,
    type: alert.severity,
    autoClose: alert.autoDismiss ? 5000 : false,
  });
};

const handleModal = (alert: IAlert<"modal">) => {
  window.alert("alerts#handleModal triggered, but no implementation exists");
};
+4 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ import {
  Subscription,
} from "@sc07-canvas/lib/src/net";
import { toast } from "react-toastify";
import { handleAlert, handleDismiss } from "./alerts";

export interface INetworkEvents {
  connected: () => void;
@@ -121,6 +122,9 @@ class Network extends EventEmitter<INetworkEvents> {
    this.socket.on("heatmap", (heatmap) => {
      this.emit("heatmap", heatmap);
    });

    this.socket.on("alert", handleAlert);
    this.socket.on("alert_dismiss", handleDismiss);
  }

  subscribe(subscription: Subscription) {
+21 −0
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ export interface ServerToClientEvents {
    color: number
  ) => void;

  alert: (alert: IAlert) => void;
  alert_dismiss: (id: string) => void;

  /* --- subscribe events --- */

  /**
@@ -57,6 +60,24 @@ export interface IPosition {
  y: number;
}

export type IAlert<Is extends "toast" | "modal" = "toast" | "modal"> = {
  is: Is;
  action: "system" | "moderation";
  id?: string;
  title: string;
  body?: string;
} & (
  | {
      is: "toast";
      severity: "info" | "success" | "warning" | "error" | "default";
      autoDismiss: boolean;
    }
  | {
      is: "modal";
      dismissable: boolean;
    }
);

// other

export type Pixel = {
+13 −0
Original line number Diff line number Diff line
@@ -166,6 +166,8 @@ class Canvas {
   * @returns 1D array of pixel values
   */
  async canvasToRedis() {
    const now = Date.now();
    Logger.info("Starting canvasToRedis...");
    const redis = await Redis.getClient();

    const dbpixels = await prisma.pixel.findMany({
@@ -198,6 +200,11 @@ class Canvas {

    await redis.set(Redis.key("canvas"), pixels.join(","), { EX: 60 * 5 });

    Logger.info(
      "Finished canvasToRedis in " +
        ((Date.now() - now) / 1000).toFixed(2) +
        "s"
    );
    return pixels;
  }

@@ -234,6 +241,12 @@ class Canvas {
    await redis.set(Redis.key("canvas"), pixels.join(","), { EX: 60 * 5 });
  }

  async isPixelArrayCached() {
    const redis = await Redis.getClient();

    return await redis.exists(Redis.key("canvas"));
  }

  async getPixelsArray() {
    const redis = await Redis.getClient();

+28 −3
Original line number Diff line number Diff line
@@ -181,9 +181,34 @@ export class SocketServer {
    }

    socket.emit("config", getClientConfig());
    {
      let _clientNotifiedAboutCache = false;
      Canvas.isPixelArrayCached().then((cached) => {
        if (!cached) {
          _clientNotifiedAboutCache = true;
          socket.emit("alert", {
            id: "canvas_cache_pending",
            is: "toast",
            action: "system",
            severity: "info",
            title: "Canvas loading",
            body: "Canvas not cached, this may take a couple seconds",
            autoDismiss: true,
          });
        }
      });
      Canvas.getPixelsArray().then((pixels) => {
        socket.emit("canvas", pixels);
        socket.emit("alert_dismiss", "canvas_cache_pending");
        socket.emit("alert", {
          is: "toast",
          action: "system",
          severity: "success",
          title: "Canvas loaded!",
          autoDismiss: true,
        });
      });
    }

    socket.on("disconnect", () => {
      Logger.debug(`Socket ${socket.id} disconnected`);