189 lines
6.6 KiB
JavaScript
189 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 };
|