whiteboard/scripts/s_whiteboard.js

190 lines
6.6 KiB
JavaScript

//This file is only for saving the whiteboard.
import fs from "fs";
import config from "./config/config.js";
import { getSafeFilePath } from "./utils.js";
const FILE_DATABASE_FOLDER = "savedBoards";
var savedBoards = {};
var savedUndos = {};
var saveDelay = {};
if (config.backend.enableFileDatabase) {
// make sure that folder with saved boards exists
fs.mkdirSync(FILE_DATABASE_FOLDER, {
// this option also mutes an error if path exists
recursive: true,
});
}
/**
* Get the file path for a whiteboard.
* @param {string} wid Whiteboard id to get the path for
* @returns {string} File path to the whiteboard
* @throws {Error} if wid contains potentially unsafe directory characters
*/
function fileDatabasePath(wid) {
return getSafeFilePath(FILE_DATABASE_FOLDER, wid + ".json");
}
const s_whiteboard = {
handleEventsAndData: function (content) {
var tool = content["t"]; //Tool witch is used
var wid = content["wid"]; //whiteboard ID
var username = content["username"];
if (tool === "clear") {
//Clear the whiteboard
delete savedBoards[wid];
delete savedUndos[wid];
// delete the corresponding file too
fs.unlink(fileDatabasePath(wid), function (err) {
if (err) {
return console.log(err);
}
});
} else if (tool === "undo") {
//Undo an action
if (!savedUndos[wid]) {
savedUndos[wid] = [];
}
let savedBoard = this.loadStoredData(wid);
if (savedBoard) {
for (var i = savedBoards[wid].length - 1; i >= 0; i--) {
if (savedBoards[wid][i]["username"] == username) {
var drawId = savedBoards[wid][i]["drawId"];
for (var i = savedBoards[wid].length - 1; i >= 0; i--) {
if (
savedBoards[wid][i]["drawId"] == drawId &&
savedBoards[wid][i]["username"] == username
) {
savedUndos[wid].push(savedBoards[wid][i]);
savedBoards[wid].splice(i, 1);
}
}
break;
}
}
if (savedUndos[wid].length > 1000) {
savedUndos[wid].splice(0, savedUndos[wid].length - 1000);
}
}
} else if (tool === "redo") {
if (!savedUndos[wid]) {
savedUndos[wid] = [];
}
let savedBoard = this.loadStoredData(wid);
for (var i = savedUndos[wid].length - 1; i >= 0; i--) {
if (savedUndos[wid][i]["username"] == username) {
var drawId = savedUndos[wid][i]["drawId"];
for (var i = savedUndos[wid].length - 1; i >= 0; i--) {
if (
savedUndos[wid][i]["drawId"] == drawId &&
savedUndos[wid][i]["username"] == username
) {
savedBoard.push(savedUndos[wid][i]);
savedUndos[wid].splice(i, 1);
}
}
break;
}
}
} else if (
[
"line",
"pen",
"rect",
"circle",
"eraser",
"addImgBG",
"recSelect",
"eraseRec",
"addTextBox",
"setTextboxText",
"removeTextbox",
"setTextboxPosition",
"setTextboxFontSize",
"setTextboxFontColor",
].includes(tool)
) {
let savedBoard = this.loadStoredData(wid);
//Save all this actions
delete content["wid"]; //Delete id from content so we don't store it twice
if (tool === "setTextboxText") {
for (var i = savedBoard.length - 1; i >= 0; i--) {
//Remove old textbox tex -> dont store it twice
if (
savedBoard[i]["t"] === "setTextboxText" &&
savedBoard[i]["d"][0] === content["d"][0]
) {
savedBoard.splice(i, 1);
}
}
}
savedBoard.push(content);
}
this.saveToDB(wid);
},
saveToDB: function (wid) {
if (config.backend.enableFileDatabase) {
//Save whiteboard to file
if (!saveDelay[wid]) {
saveDelay[wid] = true;
setTimeout(function () {
saveDelay[wid] = false;
if (savedBoards[wid]) {
fs.writeFile(
fileDatabasePath(wid),
JSON.stringify(savedBoards[wid]),
(err) => {
if (err) {
return console.log(err);
}
}
);
}
}, 1000 * 10); //Save after 10 sec
}
}
},
// Load saved whiteboard
loadStoredData: function (wid) {
if (wid in savedBoards) {
return savedBoards[wid];
}
savedBoards[wid] = [];
// try to load from DB
if (config.backend.enableFileDatabase) {
//read saved board from file
var filePath = fileDatabasePath(wid);
if (fs.existsSync(filePath)) {
var data = fs.readFileSync(filePath);
if (data) {
savedBoards[wid] = JSON.parse(data);
}
}
}
return savedBoards[wid];
},
copyStoredData: function (sourceWid, targetWid) {
const sourceData = this.loadStoredData(sourceWid);
if (sourceData.length === 0 || this.loadStoredData(targetWid).lenght > 0) {
return;
}
savedBoards[targetWid] = sourceData.slice();
this.saveToDB(targetWid);
},
saveData: function (wid, data) {
const existingData = this.loadStoredData(wid);
if (existingData.length > 0 || !data) {
return;
}
savedBoards[wid] = JSON.parse(data);
this.saveToDB(wid);
},
};
export { s_whiteboard as default };