server now notifies the client when the canvas isn't cached
- added foundation for server-sent alerts (related #53)
This commit is contained in:
parent
0e97316096
commit
076ff1c942
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* 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");
|
||||
};
|
|
@ -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) {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -181,9 +181,34 @@ export class SocketServer {
|
|||
}
|
||||
|
||||
socket.emit("config", getClientConfig());
|
||||
Canvas.getPixelsArray().then((pixels) => {
|
||||
socket.emit("canvas", pixels);
|
||||
});
|
||||
{
|
||||
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`);
|
||||
|
|
Loading…
Reference in New Issue