diff --git a/bin/files.js b/bin/files.js index 71b5918..4a4d4c8 100644 --- a/bin/files.js +++ b/bin/files.js @@ -6,13 +6,17 @@ const clog = new LogType("Fichier") const os = require("os"); const uuid = require('uuid'); var mime = require('mime-types'); +const { set } = require("../main") + +// check if shared folder exist, if not create it +if(!fs.existsSync(__glob.SHARED)) { + fs.mkdirSync(__glob.SHARED) +} module.exports.getFiles = function(root) { var response = new Object() response.content = new Array() - response.root = root - response.parent = path.dirname(root) try{ @@ -20,8 +24,13 @@ module.exports.getFiles = function(root) { if(root == "homepath") { root = os.homedir() - response.root = root - + + } + + if(root == "sharepath") { + + root = __glob.SHARED + } @@ -48,6 +57,178 @@ module.exports.getFiles = function(root) { response.content = "NOT_PERMITTED" } + response.root = root + response.parent = path.dirname(root) + + return response -} \ No newline at end of file +} + +module.exports.createFolder = function(root) { + + // Check if folder already exist + + if(!fs.existsSync(root)) { + + try { + fs.mkdirSync(root) + return "OK" + } catch(err) { + + return "NOT_PERMITTED" + } + + } else { + + return 'EXIST' + } + +} + +module.exports.deleteFile = function(root) { + + if(fs.existsSync(root)) { + + try { + + fs.rmSync(root, { recursive: true, force: true }) + return "OK" + } catch(err) { + console.log(err) + return "NOT_PERMITTED" + } + } else { + + return "NOT_EXIST" + } +} + +module.exports.renameFile = function(settings) { + + if(fs.existsSync(settings.root)) { + + try { + + fs.renameSync(settings.root + path.sep + settings.oldName, settings.root + path.sep + settings.newName) + return "OK" + } catch(err) { + + return "NOT_PERMITTED" + } + } else { + + return "NOT_EXIST" + } +} + +module.exports.shareFile = function(settings) { + + //It's gonna coopy the file in the shared folder + // And return the link of the file + // The link is gonna be like this : http://localhost:3000/shared/name of file + // The file is gonna be in the shared folder + + if(fs.existsSync(settings.root)) { + + try { + + fs.copyFileSync(settings.root + path.sep + settings.name, __glob.SHARED + path.sep + settings.name) + // return the link of the file shared + if(process.env.DEV) { + return "http://localhost:3001/shared/" + settings.name + + } else { + return "https://neutral.raphix.fr/shared/" + settings.name + + } + + } catch(err) { + console.log(err) + return "NOT_PERMITTED" + } + } else { + + return "NOT_EXIST" + } +} + + +module.exports.getFile = function(root) { + + if(fs.existsSync(root)) { + + try { + + return fs.readFileSync(root, "utf-8") + } catch(err) { + console.log(err) + return "NOT_PERMITTED" + } + } else { + + return "NOT_EXIST" + } + +} + +module.exports.saveFile = function(settings) { + + try { + + fs.writeFileSync(settings.root + path.sep + settings.name, settings.content) + return "OK" + } catch(err) { + console.log(err) + return "NOT_PERMITTED" + } +} + +module.exports.downloadFile = function(root) { + + if(fs.existsSync(root)) { + + try { + + return fs.readFileSync(root) + } catch(err) { + console.log(err) + return "NOT_PERMITTED" + } + } else { + + return "NOT_EXIST" + } +} + + + +module.exports.uploadFile = function(settings) { + + try { + + fs.writeFileSync(settings.root + path.sep + settings.name, settings.file) + return "OK" + } catch(err) { + console.log(err) + return "NOT_PERMITTED" + } +} + +module.exports.newFile = function(settings) { + + if(!fs.existsSync(settings)) { + + try { + + fs.writeFileSync(settings, "") + return "OK" + } catch(err) { + console.log(err) + return "NOT_PERMITTED" + } + } else { + + return "EXIST" + } + } \ No newline at end of file diff --git a/bin/global-variables.js b/bin/global-variables.js index a4d275d..180e0ba 100644 --- a/bin/global-variables.js +++ b/bin/global-variables.js @@ -8,7 +8,8 @@ const __glob = { ICON: root + path.sep + "public" + path.sep + 'images' + path.sep + "FormatLogo_WHITE.ico", DATA: root + path.sep + "data", USERS: root + path.sep + "data" + path.sep + "users.json", - CONFIG: root + path.sep + "data" + path.sep + "config.json" + CONFIG: root + path.sep + "data" + path.sep + "config.json", + SHARED: root + path.sep + "data" + path.sep + "shared", }; diff --git a/bin/server.js b/bin/server.js index 8a702a0..050d409 100644 --- a/bin/server.js +++ b/bin/server.js @@ -30,9 +30,9 @@ module.exports.serverIO = function(server) { if(user) { plog.log("Connexion au panel par '" + user.username + "' avec le socket : " + socket.id) user.setLastLogin(new Date()) - /* - GET REQUEST - */ + /** + * GET REQUEST + */ // Get Users GetRequest("USERINFO", () => { @@ -40,11 +40,56 @@ module.exports.serverIO = function(server) { GetAnswer("USERINFO", {username: user.username, display_name: user.display_name ,picture: user.picture, permission: user.permission}) }) + /** + * POST REQUEST + */ + PostRequest("FX_GET", (root) => { PostAnswer("FX_GET", files.getFiles(root)) }) + PostRequest("FX_NEW_FOLDER", (root) => { + + PostAnswer("FX_NEW_FOLDER", files.createFolder(root)) + }) + + PostRequest("FX_DELETE", (root) => { + + PostAnswer("FX_DELETE", files.deleteFile(root)) + } ) + + PostRequest("FX_RENAME", (settings) => { + + PostAnswer("FX_RENAME", files.renameFile(settings)) + }) + + PostRequest("FX_SHARE", (settings) => { + + PostAnswer("FX_SHARE", files.shareFile(settings)) + }) + + PostRequest("FX_GETFILE", (root) => { + + PostAnswer("FX_GETFILE", files.getFile(root)) + }) + + PostRequest("FX_SAVEFILE", (settings) => { + + PostAnswer("FX_SAVEFILE", files.saveFile(settings)) + }) + + PostRequest("FX_NEW_FILE", (settings) => { + + PostAnswer("FX_NEW_FILE", files.newFile(settings)) + }) + + PostRequest("FX_UPLOAD", (settings) => { + + PostAnswer("FX_UPLOAD", files.uploadFile(settings)) + + }) + socket.on("disconnect", () => { plog.log("Déconnexion au panel par '" + user.username + "' avec le socket : " + socket.id) diff --git a/main.js b/main.js index 4c09c35..d8a00d6 100644 --- a/main.js +++ b/main.js @@ -42,13 +42,12 @@ function setup() { app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); - - app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))) + app.use("/shared", express.static(__glob.SHARED)) getRouters() users.fetchUsers() diff --git a/public/javascripts/basics.js b/public/javascripts/basics.js index f7162ac..d727e47 100644 --- a/public/javascripts/basics.js +++ b/public/javascripts/basics.js @@ -23,6 +23,8 @@ class InfoPop { this.element.innerHTML = " " this.element.style.fontSize = "14px" this.element.style.position = "sticky" + this.element.style.width = this.element.parentElement.offsetWidth + "px" + this.element.style.textAlign = "center" } clear() { @@ -44,6 +46,11 @@ class InfoPop { this.element.innerHTML = " " + text } + setSize(size) { + + this.element.style.fontSize = size + } + } @@ -65,11 +72,15 @@ document.oncontextmenu = function(e) { } +var zIndex = 5 class ViewWindow { ViewHTML = null ViewProperties =null ViewSpanInteger = null + ViewPopupSpanInteger = null + ViewPopupHTML = null + ViewPopupTitle = null constructor(properties) { if(!viewsAccessible.has(properties.title)) { @@ -78,6 +89,7 @@ class ViewWindow { this.ViewHTML = `
+

${properties.title}

@@ -85,6 +97,8 @@ class ViewWindow {
+
+
` this.ViewSpanInteger = document.createElement("div") @@ -103,10 +117,15 @@ class ViewWindow { let isDragging = false; let offsetX, offsetY; - + windowDiv.style.zIndex = zIndex + 1 + header.addEventListener('mousedown', (e) => { isDragging = true; - + + zIndex+=2 + windowDiv.style.zIndex = zIndex + + // Enregistrez la position de la souris par rapport à la fenêtre offsetX = e.clientX - windowDiv.getBoundingClientRect().left; offsetY = e.clientY - windowDiv.getBoundingClientRect().top; @@ -145,7 +164,7 @@ class ViewWindow { destroy() { const win = getID(`${this.ViewProperties.title}_window`) - win.outerHTML = "" + win.outerHTML = " " viewsAccessible.delete(this.ViewProperties.title) } @@ -159,6 +178,66 @@ class ViewWindow { return this.ViewProperties.title } + + + createPopup(properties) { + + this.ViewPopupHTML = `
+
+

${properties.title}

+ +
+ ${properties.content} +
` + + const contentDiv = getID(this.ViewProperties.title + "_content") + const popupDiv = getID(this.ViewProperties.title + "_popupDiv") + this.ViewPopupSpanInteger = document.createElement("div") + popupDiv.appendChild(this.ViewPopupSpanInteger); + this.ViewPopupSpanInteger.outerHTML = this.ViewPopupHTML + + this.ViewPopupTitle = properties.title + + const popup = getID(properties.title + "_popup") + const popupClose = getID(properties.title + "_popupClose") + + popupClose.addEventListener("click", () => { + + this.destroyPopup() + + }) + + // Center the popup to the window div + + popup.style.left = (contentDiv.offsetWidth / 2) - (popup.offsetWidth / 2) + "px" + popup.style.top = (contentDiv.offsetHeight / 2) - (popup.offsetHeight / 2) + "px" + + // Render parent element styled blur + contentDiv.classList.add("blur") + + // Disable all interractions like click and events with contentDiv children + + for(var child of contentDiv.children) { + + child.style.pointerEvents = "none" + } + + } + + destroyPopup() { + + const contentDiv = getID(this.ViewProperties.title + "_content") + for(var child of contentDiv.children) { + + child.style.pointerEvents = "unset" + } + contentDiv.classList.remove("blur") + + const popup = getID(this.ViewPopupTitle + "_popup") + popup.outerHTML = "" + + } + } createView("files_explorer") @@ -211,6 +290,10 @@ class DroppableMenu { this.DMSpanInteger.outerHTML = this.options.join('') const menu = getID(`dm-${this.id}`) + + menu.style.zIndex = zIndex + 2 + zIndex+=1 + menu.style.left = (xMousePos - 40) + "px" menu.style.top = (yMousePos - 40) + "px" @@ -229,6 +312,17 @@ class DroppableMenu { } + get(action) { + + return getID(this.id + "_" + action) + } + + hide() { + + const menu = getID(`dm-${this.id}`) + menu.outerHTML = "" + + } } diff --git a/public/javascripts/filexplorer.js b/public/javascripts/filexplorer.js index bbe22bf..f0a7142 100644 --- a/public/javascripts/filexplorer.js +++ b/public/javascripts/filexplorer.js @@ -20,16 +20,24 @@ function generateFileExplorer() { }) } + function goSharePath() { + const rFiles = post("FX_GET", "sharepath") + + rFiles.then((result) => { + loadFiles(result) + }) + } View.setContent(`
- + +
- - + +
@@ -40,6 +48,195 @@ function generateFileExplorer() { const rootInput = getID(View.getViewTitle() + '_rootInput') const explorer = getID(View.getViewTitle() + '_explorer') + const newFolder = getID(View.getViewTitle() + '_newFolder') + const newFile = getID(View.getViewTitle() + '_newFile') + const home = getID(View.getViewTitle() + '_home') + const sharebtn = getID(View.getViewTitle() + '_sharebtn') + + home.addEventListener("click", () => { + + goHomePath() + + }) + + sharebtn.addEventListener("click", () => { + + goSharePath() + + }) + + newFolder.addEventListener("click", () => { + + View.createPopup({ + title: ` Nouveau dossier`, + content: ` + +
+ + `}) + + const foldername = getID(View.getViewTitle() + "_foldername") + const foldercreate = getID(View.getViewTitle() + "_foldercreate") + const folderInfo = new InfoPop(View.getViewTitle() + "_folderInfo") + + folderInfo.setSize("13px") + + + foldercreate.addEventListener("click", () => { + folderInfo.clear() + if(foldername.value.length < 1) { + folderInfo.err("Le nom du dossier est trop court.") + return + } + + const regex = new RegExp(/^[a-zA-Z0-9-_]+$/) + + if(!regex.test(foldername.value) | foldername.value.replace(/\s/g, '').length < 1) { + folderInfo.err("Le nom du dossier est invalide.") + return + } + + const reqFiles = post("FX_NEW_FOLDER", rootInput.value + "/" + foldername.value) + reqFiles.then((result) => { + if(result == "OK") { + View.destroyPopup(` Nouveau dossier`) + const reqFiles = post("FX_GET", rootInput.value) + reqFiles.then((result) => { + loadFiles(result) + }) + } else if(result == "EXIST") { + folderInfo.err("Le dossier existe déjà.") + } else if(result == "NOT_PERMITTED") { + folderInfo.err("Vous n'avez pas les permissions pour créer un dossier ici.") + } else { + folderInfo.err("Une erreur est survenue.") + } + }) + + + }) + + + + }) + + + // Create a new file with a popup wth 2 options, upload or create, if create give a input name or if upload, upload a file + + newFile.addEventListener("click", () => { + + View.createPopup({ + title: ` Nouveau fichier`, + content: ` + +
+ + + `}) + + const filename = getID(View.getViewTitle() + "_filename") + const filecreate = getID(View.getViewTitle() + "_filecreate") + const fileupload = getID(View.getViewTitle() + "_fileupload") + const fileInfo = new InfoPop(View.getViewTitle() + "_fileInfo") + + fileInfo.setSize("13px") + + filecreate.addEventListener("click", () => { + + fileInfo.clear() + if(filename.value.length < 1) { + fileInfo.err("Le nom du fichier est trop court.") + return + } + + const regex = new RegExp(/^[a-zA-Z0-9-_.]+$/) + + if(!regex.test(filename.value) | filename.value.replace(/\s/g, '').length < 1) { + fileInfo.err("Le nom du fichier est invalide.") + return + } + + const reqFiles = post("FX_NEW_FILE", rootInput.value + "/" + filename.value) + reqFiles.then((result) => { + if(result == "OK") { + View.destroyPopup(` Nouveau fichier`) + const reqFiles = post("FX_GET", rootInput.value) + reqFiles.then((result) => { + loadFiles(result) + }) + } else if(result == "EXIST") { + fileInfo.err("Le fichier existe déjà.") + } else if(result == "NOT_PERMITTED") { + fileInfo.err("Vous n'avez pas les permissions pour créer un fichier ici.") + } else { + fileInfo.err("Une erreur est survenue.") + } + }) + + + }) + + fileupload.addEventListener("click", () => { + + fileInfo.clear() + View.destroyPopup(` Nouveau fichier`) + View.createPopup({ + title: ` Upload`, + content: ` + +
+ + `}) + + const fileuploadInput = getID(View.getViewTitle() + "_fileuploadInput") + const fileuploadBtn = getID(View.getViewTitle() + "_fileuploadBtn") + const fileuploadInfo = new InfoPop(View.getViewTitle() + "_fileuploadInfo") + + fileuploadBtn.addEventListener("click", () => { + + fileuploadInfo.clear() + if(fileuploadInput.files.length < 1) { + fileuploadInfo.err("Aucun fichier sélectionné.") + return + } + + const file = fileuploadInput.files[0] + + const reqFiles = post("FX_UPLOAD", {name: file.name ,root: rootInput.value, file: file}) + + reqFiles.then((result) => { + + if(result == "OK") { + View.destroyPopup(` Upload`) + const reqFiles = post("FX_GET", rootInput.value) + reqFiles.then((result) => { + loadFiles(result) + }) + } + if(result == "EXIST") { + fileuploadInfo.err("Le fichier existe déjà.") + } + if(result == "NOT_PERMITTED") { + fileuploadInfo.err("Vous n'avez pas les permissions pour uploader un fichier ici.") + } + if(result == "NOT_FILE") { + fileuploadInfo.err("Le fichier n'est pas valide.") + } + if(result == "NOT_EXIST") { + fileuploadInfo.err("Le fichier n'existe pas.") + } + if(result == "TOO_BIG") { + fileuploadInfo.err("Le fichier est trop volumineux.") + } + if(result == "ERROR") { + fileuploadInfo.err("Une erreur est survenue.") + } + }) + }) + }) + }) + + rootInput.addEventListener("change", () => { @@ -64,20 +261,21 @@ function generateFileExplorer() { explorer.innerHTML = "

Ce dossier n'existe pas.

" } else { - fileElements.unshift(`

Revenir au dossier parent

`) + for(const file of files.content) { - // Convert all file.size to a human readable format with units - - file.size = bytesToSize(file.size) - - //Tell if the file is a directory or not - if(file.directory) { file.size = "Dossier" + + } else { + console.log('------------') + console.log(file.size) + console.log(bytesToSize(file.size)) + console.log('------------') + file.size = bytesToSize(file.size) } - fileElements.push(`
+ fileElements.push(`
${getIcon(file)}

${file.name}

@@ -85,23 +283,32 @@ function generateFileExplorer() {

Taille : ${file.size}

Date de modification : ${getFormattedDate(file.lastedition)}

`) + + } + // Sort the files by directory and then by name + + fileElements.sort((a, b) => { + if(a.includes("Dossier") && !b.includes("Dossier")) { + return -1 + } else if(!a.includes("Dossier") && b.includes("Dossier")) { + return 1 + } else { + return 0 + } + + }) + + fileElements.unshift(`

Revenir au dossier parent

`) + } - explorer.innerHTML = fileElements.join("") const parent = document.getElementById("fx-parent") - const home = document.getElementById("fx-home") - - home.addEventListener("click", () => { - - goHomePath() - - }) - + parent.addEventListener("click", () => { const reqFiles = post("FX_GET", files.parent) @@ -116,10 +323,17 @@ function generateFileExplorer() { // If it's a directory, get the file directory and make the request to get the files in it and loadIt for(const file of files.content) { + + const dropMenu = new DroppableMenu({ + "id": file.id + }) + + + const element = document.getElementById(file.id) if(file.directory) { - const element = document.getElementById(file.id) + element.addEventListener("click", () => { const reqFiles = post("FX_GET", file.fileDirectory) @@ -127,9 +341,260 @@ function generateFileExplorer() { loadFiles(result) }) }) + } else { + + element.addEventListener("dblclick", () => { + editFile() + }) + + dropMenu.add("edit", " Editer") + dropMenu.add("share", " Partager") + dropMenu.add("download", " Télécharger") } - } + dropMenu.add("rename", " Renommer") + + dropMenu.add("delete", " Supprimer") + + + getID(file.id).addEventListener("contextmenu", () => { + dropMenu.show() + dropMenu.get("delete").addEventListener("click", () => { + dropMenu.hide() + const reqFiles = post("FX_DELETE", file.fileDirectory) + reqFiles.then((result) => { + if(result == "OK") { + const reqFiles = post("FX_GET", files.root) + reqFiles.then((result) => { + loadFiles(result) + }) + } else if(result == "NOT_PERMITTED") { + const reqFiles = post("FX_GET", files.root) + reqFiles.then((result) => { + loadFiles(result) + }) + View.createPopup({ + title: ` Erreur`, + content: `

Vous n'avez pas les permissions pour supprimer ce fichier.

` + }) + } else { + const reqFiles = post("FX_GET", files.root) + reqFiles.then((result) => { + loadFiles(result) + }) + View.createPopup({ + title: ` Erreur`, + content: `

Une erreur est survenue.

` + }) + + } + }) + }) + dropMenu.get("rename").addEventListener("click", () => { + + dropMenu.hide() + View.createPopup({ + title: ` Renommer`, + content: ` + +
+ + `}) + + const rename = getID(View.getViewTitle() + "_rename") + const renameBtn = getID(View.getViewTitle() + "_renameBtn") + const renameInfo = new InfoPop(View.getViewTitle() + "_renameInfo") + renameInfo.setSize("13px") + rename.value = file.name + rename.focus() + rename.select() + + renameBtn.addEventListener("click", () => { + renameInfo.clear() + if(rename.value.length < 1) { + renameInfo.err("Le nom du fichier / dossier est trop court.") + return + } + + const regex = new RegExp(/^[a-zA-Z0-9-_]+$/) + + if(!regex.test(rename.value) | rename.value.replace(/\s/g, '').length < 1) { + renameInfo.err("Le nom du fichier / dossier est invalide.") + return + } + + const reqFiles = post("FX_RENAME", {root: files.root, oldName: file.name, newName: rename.value}) + reqFiles.then((result) => { + if(result == "OK") { + View.destroyPopup(` Renommer`) + const reqFiles = post("FX_GET", files.root) + reqFiles.then((result) => { + loadFiles(result) + }) + } else if(result == "EXIST") { + renameInfo.err("Le fichier / dossier existe déjà.") + } else if(result == "NOT_PERMITTED") { + renameInfo.err("Vous n'avez pas les permissions pour renommer ce fichier / dossier.") + } else { + renameInfo.err("Une erreur est survenue.") + } + }) + + }) + + }) + + if(!file.directory) { + dropMenu.get("share").addEventListener("click", () => { + dropMenu.hide() + const reqFiles = post("FX_SHARE", {root: files.root, name: file.name}) + reqFiles.then((result) => { + if(result == "NOT_PERMITTED") { + View.createPopup({ + title: ` Erreur`, + content: `

Vous n'avez pas les permissions pour partager ce fichier.

` + }) + } else { + View.createPopup({ + title: ` Partager`, + content: ` + +
+ + `}) + + const sharelink = getID(View.getViewTitle() + "_sharelink") + const shareBtn = getID(View.getViewTitle() + "_shareBtn") + const shareInfo = new InfoPop(View.getViewTitle() + "_shareInfo") + shareInfo.setSize("13px") + sharelink.value = result + sharelink.focus() + sharelink.select() + + shareBtn.addEventListener("click", () => { + sharelink.focus() + sharelink.select() + window.navigator.clipboard.writeText(sharelink.value) + shareInfo.ok("Copié !") + }) + } + }) + }) + // Edit file with an ViewWindow with 2 options close & save and the name of the window is like File - Editor + + dropMenu.get("edit").addEventListener("click", () => { + dropMenu.hide() + + editFile() + + }) + + dropMenu.get("download").addEventListener("click", () => { + dropMenu.hide() + const reqFiles = post("FX_GETFILE", file.fileDirectory) + reqFiles.then((result) => { + if(result == "NOT_PERMITTED") { + View.createPopup({ + title: ` Erreur`, + content: `

Vous n'avez pas les permissions pour télécharger ce fichier.

` + }) + } else { + // Make Download using result + const element = document.createElement('a'); + element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(result)); + element.setAttribute('download', file.name); + element.style.display = 'none'; + document.body.appendChild(element); + element.click(); + document.body.removeChild(element); + + } + }) + }) + + + + } + + }) + + + + + + function editFile() { + const reqFiles = post("FX_GETFILE", file.fileDirectory) + reqFiles.then((result) => { + if(result == "NOT_PERMITTED") { + View.createPopup({ + title: ` Erreur`, + content: `

Vous n'avez pas les permissions pour éditer ce fichier.

` + }) + } else { + const editor = new ViewWindow({ + title: ` Editeur - ${file.fileDirectory}`, + width: "1000px", + height: "600px" + }) + + editor.setContent(` + +
+ +
+ + + + `) + + + const editorSave = getID(editor.getViewTitle() + "_save") + const editorContent = getID(editor.getViewTitle() + "_editorContent") + + // Sauvegarder le fichier en l'envoyant + + editorSave.addEventListener("click", () => { + + const reqFiles = post("FX_SAVEFILE", {root: files.root, name: file.name, content: editorContent.value}) + reqFiles.then((result) => { + if(result == "OK") { + editor.destroy() + const reqFiles = post("FX_GET", files.root) + reqFiles.then((result) => { + loadFiles(result) + }) + } else if(result == "NOT_PERMITTED") { + View.createPopup({ + title: ` Erreur`, + content: `

Vous n'avez pas les permissions pour éditer ce fichier.

` + }) + } else { + View.createPopup({ + title: ` Erreur`, + content: `

Une erreur est survenue.

` + }) + } + }) + }) + + + + //forbid textarea resize + editorContent.style.resize = "none" + + + editorClose.addEventListener("click", () => { + + editor.destroy() + }) + + + } + + }) + } + + } } @@ -140,19 +605,6 @@ function generateFileExplorer() { } -function createFileMenu(idCreated) { - - const dropMenu = new DroppableMenu({ - "id": idCreated - }) - - dropMenu.add("rename", " Renommer") - dropMenu.add("share", " Partager") - dropMenu.add("delete", " Supprimer") - - - dropMenu.show() -} function getIcon(file) { if(file.type == "application/json") { @@ -188,7 +640,7 @@ function getIcon(file) { } if(file.type == "application/javascript") { - return '' + return '' } if(file.type == "image/png" | file.type == "image/jpeg") { diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 1e2046b..81fd2c5 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -1,4 +1,5 @@ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap'); +@import url('https://fonts.cdnfonts.com/css/gunship'); body { padding: 2%; @@ -20,10 +21,10 @@ html { background-color: transparent; outline: none; - border-radius: 0.5vw; + border-radius: 10px; border: 1px solid currentColor; color: currentColor; - padding: 0.5vw; + padding: 10px; transition: 0.2s; cursor: pointer; } @@ -125,7 +126,7 @@ code { background-color: #3D3B3C; padding: 0.3vw; - border-radius: 0.5vw; + border-radius: 10px; } p { @@ -207,6 +208,11 @@ a { /* Logo */ +.logo { + + user-select: none; +} + @media (max-width: 640px) { .logo { @@ -262,36 +268,39 @@ a { width: 500px; height: 400px; - border-radius: 0.5vw; + border-radius: 10px; display: flex; padding: 2%; flex-direction: column; justify-content: space-between; background-color: #605e5863; + backdrop-filter: blur(10px); } .panel-box { width: 900px; height: 500px; - border-radius: 0.5vw; + border-radius: 10px; display: flex; padding: 2%; flex-direction: column; justify-content: space-between; background-color: #605e5863; gap: 50px; + backdrop-filter: blur(10px); } .subpanel-box { width: 900px; height: 50px; - border-radius: 0.5vw; + border-radius: 10px; padding: 2%; display: flex; justify-content: space-between; background-color: #605e5863; + backdrop-filter: blur(10px); } .subpanel-image { @@ -421,17 +430,47 @@ a { font-size: 72px; } +.view-popup { + position: absolute; + background-color: #3D3B3C; + backdrop-filter: blur(10px); + display: flex; + flex-direction: column; + gap: 20px; + align-items: center; + justify-content: center; + padding: 2%; + border-radius: 10px; +} + +.view-popup-bar { + + display: flex; + justify-content: space-between; + flex-direction: row; + align-items: center; + gap: 20px; + width: 100%; +} + +.blur { + + filter: blur(10px); +} /*ViewWindow*/ .view-window { position: absolute; + display: flex; + flex-direction: column; z-index: 1; background-color: #605e58c1; backdrop-filter: blur(10px); - border-radius: 0.5vw; + border-radius: 10px; -webkit-user-drag: auto; + } .view-window-header { @@ -441,11 +480,20 @@ a { align-items: center; padding: 10px; background-color: rgba(33, 32, 33, 0.753); - border-top-right-radius: 0.5vw; - border-top-left-radius: 0.5vw; + border-top-right-radius: 10px; + border-top-left-radius: 10px; user-select: none; } +.view-window-content { + + height: 100%; + display: flex; + flex-direction: column; + width: 100%; + +} + /* Files Explorer */ @@ -459,7 +507,7 @@ a { .fx-root-input { background-color: #323031; border: solid 1px #323031; - border-radius: 0.5vw; + border-radius: 10px; padding: 1%; color: white; outline:0px; @@ -472,7 +520,7 @@ a { flex-direction: column; overflow-y: auto ; height: 450px; - gap: 20px + } .fx-element { @@ -517,13 +565,30 @@ a { .fx-bar-actions { - width: 30%; + width: 33%; display: flex; flex-direction: row; - gap: 10px; + justify-content: end; + gap: 10px; } +.fx-editor-content { + + background-color: transparent; + color: white; + border: none; + padding: 15px; + height: 100%; + +} + +.fx-editor-content:focus { + + outline: none; +} + + /* ===== Scrollbar CSS ===== */ /* Firefox */ * { @@ -553,7 +618,7 @@ a { display: flex; flex-direction: column; width: 150px; - border-radius: 0.5vw; + border-radius: 10px; z-index: 3; height: auto; }