From 4476ce3284b8c9370c00c6d8f2d5ae092c0650ca Mon Sep 17 00:00:00 2001 From: Florent Chehab Date: Sun, 10 May 2020 16:43:11 +0200 Subject: [PATCH] refacto: handling of smallest screen size as a whiteboard info * Also started a bit of config handling cleaning --- scripts/WhiteboardServerSideInfo.js | 55 +++++++++++++++- scripts/config.js | 40 ++++++++++++ scripts/server-backend.js | 98 +++++------------------------ src/index.html | 1 + src/js/main.js | 5 +- src/js/services/InfoService.js | 22 ++++++- src/js/whiteboard.js | 37 ++++++----- 7 files changed, 153 insertions(+), 105 deletions(-) diff --git a/scripts/WhiteboardServerSideInfo.js b/scripts/WhiteboardServerSideInfo.js index 7b075be..c846a87 100644 --- a/scripts/WhiteboardServerSideInfo.js +++ b/scripts/WhiteboardServerSideInfo.js @@ -1,4 +1,8 @@ +const config = require("./config"); + class WhiteboardServerSideInfo { + static defaultScreenResolution = { w: 1000, h: 1000 }; + constructor() { /** * @type {number} @@ -6,6 +10,12 @@ class WhiteboardServerSideInfo { */ this._nbConnectedUsers = 0; + /** + * @type {Map} + * @private + */ + this._screenResolutionByClients = new Map(); + /** * Variable to tell if these info have been sent or not * @@ -29,8 +39,37 @@ class WhiteboardServerSideInfo { return this._nbConnectedUsers > 0; } - asObject() { - return { nbConnectedUsers: this._nbConnectedUsers }; + /** + * Store information about the client's screen resolution + * + * @param {number} clientId + * @param {number} w client's width + * @param {number} h client's hight + */ + setScreenResolutionForClient(clientId, { w, h }) { + this._screenResolutionByClients.set(clientId, { w, h }); + this._hasNonSentUpdates = true; + } + + /** + * Delete the stored information about the client's screen resoltion + * @param clientId + */ + deleteScreenResolutionOfClient(clientId) { + this._screenResolutionByClients.delete(clientId); + this._hasNonSentUpdates = true; + } + + /** + * Get the smallest client's screen size on a whiteboard + * @return {{w: number, h: number}} + */ + getSmallestScreenResolution() { + const { _screenResolutionByClients: resolutions } = this; + return { + w: Math.min(...Array.from(resolutions.values()).map((res) => res.w)), + h: Math.min(...Array.from(resolutions.values()).map((res) => res.h)), + }; } infoWasSent() { @@ -40,6 +79,18 @@ class WhiteboardServerSideInfo { shouldSendInfo() { return this._hasNonSentUpdates; } + + asObject() { + const out = { + nbConnectedUsers: this._nbConnectedUsers, + }; + + if (!config.disableSmallestScreen) { + out.smallestScreenResolution = this.getSmallestScreenResolution(); + } + + return out; + } } module.exports = WhiteboardServerSideInfo; diff --git a/scripts/config.js b/scripts/config.js index 5f97f52..62a1f11 100644 --- a/scripts/config.js +++ b/scripts/config.js @@ -1,5 +1,45 @@ +const { getArgs } = require("./utils"); + const config = { + accessToken: "", + disableSmallestScreen: false, + webdav: false, + whiteboardInfoBroadcastFreq: 1, // once per second }; +/** + * Update the config based on the CLI args + * @param {object} startArgs + */ +function updateConfigFromStartArgs(startArgs) { + if (startArgs["accesstoken"]) { + config.accessToken = startArgs["accesstoken"]; + } + if (startArgs["disablesmallestscreen"]) { + config.disableSmallestScreen = true; + } + if (startArgs["webdav"]) { + config.webdav = true; + } +} + +/** + * Update the config based on the env variables + */ +function updateConfigFromEnv() { + if (process.env.accesstoken) { + config.accessToken = process.env.accesstoken; + } + if (process.env.disablesmallestscreen) { + config.disablesmallestscreen = true; + } + if (process.env.webdav) { + config.webdav = true; + } +} + +updateConfigFromEnv(); +updateConfigFromStartArgs(getArgs()); + module.exports = config; diff --git a/scripts/server-backend.js b/scripts/server-backend.js index 35a41d3..01ac837 100644 --- a/scripts/server-backend.js +++ b/scripts/server-backend.js @@ -1,13 +1,10 @@ const path = require("path"); -const { getArgs } = require("./utils"); const config = require("./config"); const WhiteboardServerSideInfo = require("./WhiteboardServerSideInfo"); function startBackendServer(port) { - var accessToken = ""; //Can be set here or as start parameter (node server.js --accesstoken=MYTOKEN) - var disableSmallestScreen = false; //Can be set to true if you dont want to show (node server.js --disablesmallestscreen=true) - var webdav = false; //Can be set to true if you want to allow webdav save (node server.js --webdav=true) + console.info("Starting backend server with config", config); var fs = require("fs-extra"); var express = require("express"); @@ -29,36 +26,8 @@ function startBackendServer(port) { server.listen(port); var io = require("socket.io")(server, { path: "/ws-api" }); console.log("Webserver & socketserver running on port:" + port); - if (process.env.accesstoken) { - accessToken = process.env.accesstoken; - } - if (process.env.disablesmallestscreen) { - disablesmallestscreen = true; - } - if (process.env.webdav) { - webdav = true; - } - var startArgs = getArgs(); - if (startArgs["accesstoken"]) { - accessToken = startArgs["accesstoken"]; - } - if (startArgs["disablesmallestscreen"]) { - disableSmallestScreen = true; - } - if (startArgs["webdav"]) { - webdav = true; - } - - if (accessToken !== "") { - console.log("AccessToken set to: " + accessToken); - } - if (disableSmallestScreen) { - console.log("Disabled showing smallest screen resolution!"); - } - if (webdav) { - console.log("Webdav save is enabled!"); - } + const { accessToken, webdav } = config; app.get("/api/loadwhiteboard", function (req, res) { var wid = req["query"]["wid"]; @@ -207,8 +176,6 @@ function startBackendServer(port) { } } - var smallestScreenResolutions = {}; - /** * @type {Map} */ @@ -229,20 +196,15 @@ function startBackendServer(port) { io.on("connection", function (socket) { var whiteboardId = null; socket.on("disconnect", function () { - if ( - smallestScreenResolutions && - smallestScreenResolutions[whiteboardId] && - socket && - socket.id - ) { - delete smallestScreenResolutions[whiteboardId][socket.id]; + const whiteboardServerSideInfo = infoByWhiteboard.get(whiteboardId); + + if (socket && socket.id) { + whiteboardServerSideInfo.deleteScreenResolutionOfClient(socket.id); } - const whiteboardServerSideInfo = infoByWhiteboard.get(whiteboardId); whiteboardServerSideInfo.decrementNbConnectedUsers(); if (whiteboardServerSideInfo.hasConnectedUser()) { socket.compress(false).broadcast.emit("refreshUserBadges", null); //Removes old user Badges - sendSmallestScreenResolution(); } else { infoByWhiteboard.delete(whiteboardId); } @@ -269,14 +231,10 @@ function startBackendServer(port) { const whiteboardServerSideInfo = infoByWhiteboard.get(whiteboardId); whiteboardServerSideInfo.incrementNbConnectedUsers(); - - smallestScreenResolutions[whiteboardId] = smallestScreenResolutions[whiteboardId] - ? smallestScreenResolutions[whiteboardId] - : {}; - smallestScreenResolutions[whiteboardId][socket.id] = content[ - "windowWidthHeight" - ] || { w: 10000, h: 10000 }; - sendSmallestScreenResolution(); + whiteboardServerSideInfo.setScreenResolutionForClient( + socket.id, + content["windowWidthHeight"] || WhiteboardServerSideInfo.defaultScreenResolution + ); } else { socket.emit("wrongAccessToken", true); } @@ -284,38 +242,14 @@ function startBackendServer(port) { socket.on("updateScreenResolution", function (content) { content = escapeAllContentStrings(content); - if ( - smallestScreenResolutions[whiteboardId] && - (accessToken === "" || accessToken == content["at"]) - ) { - smallestScreenResolutions[whiteboardId][socket.id] = content[ - "windowWidthHeight" - ] || { w: 10000, h: 10000 }; - sendSmallestScreenResolution(); + if (accessToken === "" || accessToken == content["at"]) { + const whiteboardServerSideInfo = infoByWhiteboard.get(whiteboardId); + whiteboardServerSideInfo.setScreenResolutionForClient( + socket.id, + content["windowWidthHeight"] || WhiteboardServerSideInfo.defaultScreenResolution + ); } }); - - function sendSmallestScreenResolution() { - if (disableSmallestScreen) { - return; - } - var smallestWidth = 10000; - var smallestHeight = 10000; - for (var i in smallestScreenResolutions[whiteboardId]) { - smallestWidth = - smallestWidth > smallestScreenResolutions[whiteboardId][i]["w"] - ? smallestScreenResolutions[whiteboardId][i]["w"] - : smallestWidth; - smallestHeight = - smallestHeight > smallestScreenResolutions[whiteboardId][i]["h"] - ? smallestScreenResolutions[whiteboardId][i]["h"] - : smallestHeight; - } - io.to(whiteboardId).emit("updateSmallestScreenResolution", { - w: smallestWidth, - h: smallestHeight, - }); - } }); //Prevent cross site scripting (xss) diff --git a/src/index.html b/src/index.html index 5284ee4..d5b3bd3 100644 --- a/src/index.html +++ b/src/index.html @@ -254,6 +254,7 @@

Whiteboard information:

# connected users: 0

+

Smallest screen resolution: Unknown.

# msg. sent to server: 0

# msg. received from server: 0

diff --git a/src/js/main.js b/src/js/main.js index dbdaa04..084c0fe 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -51,6 +51,7 @@ function main() { signaling_socket.on("whiteboardInfoUpdate", (info) => { InfoService.updateInfoFromServer(info); + whiteboard.updateSmallestScreenResolution(); }); signaling_socket.on("drawToWhiteboard", function (content) { @@ -69,10 +70,6 @@ function main() { } }); - signaling_socket.on("updateSmallestScreenResolution", function (widthHeight) { - whiteboard.updateSmallestScreenResolution(widthHeight["w"], widthHeight["h"]); - }); - signaling_socket.emit("joinWhiteboard", { wid: whiteboardId, at: accessToken, diff --git a/src/js/services/InfoService.js b/src/js/services/InfoService.js index 49af8c0..fbbe3d0 100644 --- a/src/js/services/InfoService.js +++ b/src/js/services/InfoService.js @@ -20,6 +20,13 @@ class InfoService { */ _nbConnectedUsers = 0; + /** + * + * @type {{w: number, h: number}} + * @private + */ + _smallestScreenResolution = undefined; + /** * @type {number} * @private @@ -41,9 +48,20 @@ class InfoService { /** * @param {number} nbConnectedUsers + * @param {{w: number, h: number}} smallestScreenResolution */ - updateInfoFromServer({ nbConnectedUsers }) { + updateInfoFromServer({ nbConnectedUsers, smallestScreenResolution = undefined }) { this._nbConnectedUsers = nbConnectedUsers; + if (smallestScreenResolution) { + this._smallestScreenResolution = smallestScreenResolution; + } + } + + /** + * @returns {(undefined|{w: number, h: number})} + */ + get smallestScreenResolution() { + return this._smallestScreenResolution; } incrementNbMessagesReceived() { @@ -58,6 +76,8 @@ class InfoService { $("#messageReceivedCount")[0].innerText = String(this._nbMessagesReceived); $("#messageSentCount")[0].innerText = String(this._nbMessagesSent); $("#connectedUsersCount")[0].innerText = String(this._nbConnectedUsers); + const { _smallestScreenResolution: ssr } = this; + $("#smallestScreenResolution")[0].innerText = ssr ? `(${ssr.w}, ${ssr.h})` : "Unknown"; } displayInfo() { diff --git a/src/js/whiteboard.js b/src/js/whiteboard.js index e9a9673..a2303b0 100644 --- a/src/js/whiteboard.js +++ b/src/js/whiteboard.js @@ -6,6 +6,7 @@ import { POINTER_EVENT_THRESHOLD_MIN_TIME_DELTA, } from "./const"; import ReadOnlyService from "./services/ReadOnlyService"; +import InfoService from "./services/InfoService"; const RAD_TO_DEG = 180.0 / Math.PI; const DEG_TO_RAD = Math.PI / 180.0; @@ -363,7 +364,7 @@ const whiteboard = { ```
- +
``` @@ -1061,21 +1062,25 @@ const whiteboard = { _this.setTextboxFontColor(_this.latestActiveTextBoxId, color); } }, - updateSmallestScreenResolution(width, height) { - this.backgroundGrid.empty(); - if (width < $(window).width() || height < $(window).height()) { - this.backgroundGrid.append( - '
' - ); - this.backgroundGrid.append( - '
smallest screen participating
' - ); + updateSmallestScreenResolution() { + const { smallestScreenResolution } = InfoService; + if (smallestScreenResolution) { + const { w: width, h: height } = smallestScreenResolution; + this.backgroundGrid.empty(); + if (width < $(window).width() || height < $(window).height()) { + this.backgroundGrid.append( + '
' + ); + this.backgroundGrid.append( + '
smallest screen participating
' + ); + } } }, handleEventsAndData: function (content, isNewData, doneCallback) {