feat: dynamic frontend configuration

This commit is contained in:
Florent Chehab
2020-05-10 23:13:55 +02:00
parent 9fda0a2c4b
commit b0337d9f5b
10 changed files with 180 additions and 83 deletions

View File

@@ -1,3 +0,0 @@
export const POINTER_EVENT_THRESHOLD_MIN_DIST_DELTA = 1; // 1px
export const POINTER_EVENT_THRESHOLD_MIN_TIME_DELTA = 10; // 1ms
export const REFRESH_INFO_FREQUENCY = 5; // 5 times per second

View File

@@ -8,47 +8,48 @@ import pdfjsLib from "pdfjs-dist/webpack";
import shortcutFunctions from "./shortcutFunctions";
import ReadOnlyService from "./services/ReadOnlyService";
import InfoService from "./services/InfoService";
import { getQueryVariable, getSubDir } from "./utils";
import ConfigService from "./services/ConfigService";
let whiteboardId = getQueryVariable("whiteboardid");
const randomid = getQueryVariable("randomid");
if (randomid && !whiteboardId) {
//set random whiteboard on empty whiteboardid
whiteboardId = Array(2)
.fill(null)
.map(() => Math.random().toString(36).substr(2))
.join("");
const urlParams = new URLSearchParams(window.location.search);
urlParams.set("whiteboardid", whiteboardId);
window.location.search = urlParams;
}
whiteboardId = whiteboardId || "myNewWhiteboard";
whiteboardId = unescape(encodeURIComponent(whiteboardId)).replace(/[^a-zA-Z0-9 ]/g, "");
const myUsername = getQueryVariable("username") || "unknown" + (Math.random() + "").substring(2, 6);
const accessToken = getQueryVariable("accesstoken") || "";
// Custom Html Title
const title = getQueryVariable("title");
if (!title === false) {
document.title = decodeURIComponent(title);
}
const subdir = getSubDir();
let signaling_socket;
function main() {
var whiteboardId = getQueryVariable("whiteboardid");
var randomid = getQueryVariable("randomid");
if (randomid && !whiteboardId) {
//set random whiteboard on empty whiteboardid
whiteboardId = Array(2)
.fill(null)
.map(() => Math.random().toString(36).substr(2))
.join("");
const urlParams = new URLSearchParams(window.location.search);
urlParams.set("whiteboardid", whiteboardId);
window.location.search = urlParams;
}
whiteboardId = whiteboardId || "myNewWhiteboard";
whiteboardId = unescape(encodeURIComponent(whiteboardId)).replace(/[^a-zA-Z0-9 ]/g, "");
var myUsername = getQueryVariable("username");
var accessToken = getQueryVariable("accesstoken");
myUsername = myUsername || "unknown" + (Math.random() + "").substring(2, 6);
accessToken = accessToken || "";
var accessDenied = false;
// Custom Html Title
var title = getQueryVariable("title");
if (!title === false) {
document.title = decodeURIComponent(title);
}
var url = document.URL.substr(0, document.URL.lastIndexOf("/"));
var signaling_socket = null;
var urlSplit = url.split("/");
var subdir = "";
for (var i = 3; i < urlSplit.length; i++) {
subdir = subdir + "/" + urlSplit[i];
}
signaling_socket = io("", { path: subdir + "/ws-api" }); // Connect even if we are in a subdir behind a reverse proxy
signaling_socket.on("connect", function () {
console.log("Websocket connected!");
signaling_socket.on("whiteboardConfig", (serverResponse) => {
ConfigService.initFromServer(serverResponse);
// Inti whiteboard only when we have the config from the server
initWhiteboard();
});
signaling_socket.on("whiteboardInfoUpdate", (info) => {
InfoService.updateInfoFromServer(info);
whiteboard.updateSmallestScreenResolution();
@@ -63,6 +64,7 @@ function main() {
whiteboard.refreshUserBadges();
});
let accessDenied = false;
signaling_socket.on("wrongAccessToken", function () {
if (!accessDenied) {
accessDenied = true;
@@ -76,7 +78,9 @@ function main() {
windowWidthHeight: { w: $(window).width(), h: $(window).height() },
});
});
}
function initWhiteboard() {
$(document).ready(function () {
// by default set in readOnly mode
ReadOnlyService.activateReadOnlyMode();
@@ -599,7 +603,7 @@ function main() {
// fix bug cursor not showing up
whiteboard.refreshCursorAppearance();
if (process.env.NODE_ENV === "production") {
if (process.env.NODE_ENV === "production" && ConfigService.readOnlyOnWhiteboardLoad) {
ReadOnlyService.activateReadOnlyMode();
InfoService.hideInfo();
} else {
@@ -795,19 +799,6 @@ function main() {
}, 1000 * options.hideAfter);
}
}
// get 'GET' parameter by variable name
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return false;
}
}
export default main;

View File

@@ -0,0 +1,51 @@
class ConfigService {
/**
* @readonly
* @type {boolean}
*/
readOnlyOnWhiteboardLoad = false;
/**
* @readonly
* @type {boolean}
*/
showSmallestScreenIndicator = true;
/**
* @readonly
* @type {number}
*/
pointerEventsThresholdMinDistDelta = 0;
/**
* @readonly
* @type {number}
*/
pointerEventsThresholdMinTimeDelta = 0;
/**
* @readonly
* @type {number}
*/
refreshInfoInterval = 1000;
/**
* Init the service from the config sent by the server
*
* @param {object} serverResponse
*/
initFromServer(serverResponse) {
const { common } = serverResponse;
const { readOnlyOnWhiteboardLoad, showSmallestScreenIndicator, performance } = common;
this.readOnlyOnWhiteboardLoad = readOnlyOnWhiteboardLoad;
this.showSmallestScreenIndicator = showSmallestScreenIndicator;
this.pointerEventsThresholdMinDistDelta = performance.pointerEventsThreshold.minDistDelta;
this.pointerEventsThresholdMinTimeDelta = performance.pointerEventsThreshold.minTimeDelta;
this.refreshInfoInterval = 1000 / performance.refreshInfoFreq;
console.log("Whiteboard config from server:", serverResponse, "parsed:", this);
}
}
export default new ConfigService();

View File

@@ -1,6 +1,4 @@
import { REFRESH_INFO_FREQUENCY } from "../const";
const REFRESH_INTERVAL = 1000 / REFRESH_INFO_FREQUENCY;
import ConfigService from "./ConfigService";
/**
* Class the handle the information about the whiteboard
@@ -90,7 +88,7 @@ class InfoService {
// refresh only on a specific interval to reduce
// refreshing cost
this.refreshDisplayedInfo();
}, REFRESH_INTERVAL);
}, ConfigService.refreshInfoInterval);
}
hideInfo() {

View File

@@ -14,3 +14,31 @@ export function computeDist(p1, p2) {
export function getCurrentTimeMs() {
return new Date().getTime();
}
/**
* get 'GET' parameter by variable name
* @param variable
* @return {boolean|*}
*/
export function getQueryVariable(variable) {
const query = window.location.search.substring(1);
const vars = query.split("&");
for (let i = 0; i < vars.length; i++) {
const pair = vars[i].split("=");
if (pair[0] === variable) {
return pair[1];
}
}
return false;
}
export function getSubDir() {
const url = document.URL.substr(0, document.URL.lastIndexOf("/"));
const urlSplit = url.split("/");
let subdir = "";
for (let i = 3; i < urlSplit.length; i++) {
subdir = subdir + "/" + urlSplit[i];
}
return subdir;
}

View File

@@ -1,12 +1,9 @@
import { dom } from "@fortawesome/fontawesome-svg-core";
import { getCurrentTimeMs } from "./utils";
import Point from "./classes/Point";
import {
POINTER_EVENT_THRESHOLD_MIN_DIST_DELTA,
POINTER_EVENT_THRESHOLD_MIN_TIME_DELTA,
} from "./const";
import ReadOnlyService from "./services/ReadOnlyService";
import InfoService from "./services/InfoService";
import ConfigService from "./services/ConfigService";
const RAD_TO_DEG = 180.0 / Math.PI;
const DEG_TO_RAD = Math.PI / 180.0;
@@ -215,11 +212,11 @@ const whiteboard = {
const pointerSentTime = getCurrentTimeMs();
if (
pointerSentTime - _this.lastPointerSentTime >
POINTER_EVENT_THRESHOLD_MIN_TIME_DELTA
ConfigService.pointerEventsThresholdMinTimeDelta
) {
if (
_this.lastPointerPosition.distTo(currentPos) >
POINTER_EVENT_THRESHOLD_MIN_DIST_DELTA
ConfigService.pointerEventsThresholdMinDistDelta
) {
_this.lastPointerSentTime = pointerSentTime;
_this.lastPointerPosition = currentPos;
@@ -545,11 +542,14 @@ const whiteboard = {
});
const pointerSentTime = getCurrentTimeMs();
if (pointerSentTime - _this.lastPointerSentTime > POINTER_EVENT_THRESHOLD_MIN_TIME_DELTA) {
if (
pointerSentTime - _this.lastPointerSentTime >
ConfigService.pointerEventsThresholdMinTimeDelta
) {
const newPointerPosition = currentPos;
if (
_this.lastPointerPosition.distTo(newPointerPosition) >
POINTER_EVENT_THRESHOLD_MIN_DIST_DELTA
ConfigService.pointerEventsThresholdMinDistDelta
) {
_this.lastPointerSentTime = pointerSentTime;
_this.lastPointerPosition = newPointerPosition;
@@ -882,12 +882,12 @@ const whiteboard = {
// At least 100 ms between messages to reduce server load
if (
pointerSentTime - _this.lastPointerSentTime >
POINTER_EVENT_THRESHOLD_MIN_TIME_DELTA
ConfigService.pointerEventsThresholdMinTimeDelta
) {
// Minimal distance between messages to reduce server load
if (
_this.lastPointerPosition.distTo(newPointerPosition) >
POINTER_EVENT_THRESHOLD_MIN_DIST_DELTA
ConfigService.pointerEventsThresholdMinDistDelta
) {
_this.lastPointerSentTime = pointerSentTime;
_this.lastPointerPosition = newPointerPosition;