class Finder{ static AppId = "Finder" /** * @param {string[]} args */ async NewWindow(args, runContext){ let newFinder = new FinderWindow() await newFinder.Init(args, runContext) } /** * @param {string} path * @returns {boolean} */ static async RenderProperites(path){ if (path == null || path ==""){ return } const params = new URLSearchParams({ path: path }) const response = await fetch(`/app/${Finder.AppId}/renderProps?` + params) if (response.status != 200){ WebDesktopEnvironment.Alert("Error in properties render") //TODO return false } const html = await response.text() let newWindow = WebDesktopEnvironment.CreateNewWindow(Finder.AppId, 350, 500 ) newWindow.innerHTML = html newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) { WebDesktopEnvironment.CloseWindow(newWindow) }) } } class FinderWindow{ curPath = "" fileView = undefined windowElem = undefined async Init(args, runContext){ if (args[1] === "-desktop"){ //todo pass div id, not div in args[] const params = new URLSearchParams({ isMobile: WebDesktopEnvironment.isMobile, path: args[0] }) const response = await fetch(`/app/${Finder.AppId}/renderDesktop?` + params, { method: "POST", body: JSON.stringify(runContext) }) if (response.status != 200){ WebDesktopEnvironment.Alert("Error in render desktop") //TODO } const html = await response.text() args[2].innerHTML = html this.fileView = new FileView( args[2].querySelector(".FileTileView"), (event) =>{this.Click(event)}, (event) => { this.RightClick(event) }, (event, draggedElem) => { this.DropEvent(event, draggedElem)}, () => { this.ReRenderDir() } ) this.RenderDir(args[0]) return } const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile}) const response = await fetch(`/app/${Finder.AppId}/render?` + params, { method: "POST", body: JSON.stringify(runContext) }) if (response.status != 200){ const error = await response.json() WebDesktopEnvironment.Alert(error.message) return } const html = await response.text() let newWindow = WebDesktopEnvironment.CreateNewWindow(Finder.AppId, 500, 350 ) newWindow.innerHTML = html this.fileView = new FileView( newWindow.querySelector(".FileTileView"), (event) => { this.Click(event) }, (event) => { this.RightClick(event) }, (event, draggedElem) => { this.DropEvent(event, draggedElem)}, () => { this.ReRenderDir() } ) newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) { WebDesktopEnvironment.CloseWindow(newWindow) }) newWindow.querySelector("#RootButton").addEventListener('click', () =>{ this.RenderDir('/') }) newWindow.querySelector("#HomeButton").addEventListener('click', () =>{ this.RenderDir('/home/user') }) let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".FileTileView")) this.windowElem = newWindow this.RenderDir(args[0]) } /** * @param {string} path */ RenderDir(path){ this.curPath = path this.fileView.OpenFolder(path) } ReRenderDir(){ this.RenderDir(this.curPath) } /** * @param {DragEvent} event * @param {HTMLElement} draggedElem */ async DropEvent(event){ // console.log(event.dataTransfer.getData("dropType")) if (event.dataTransfer.getData("dropType") == "move"){ const sourcePath= event.dataTransfer.getData("filePath") const targetPath = this.curPath + "/" + event.dataTransfer.getData("fileName") const res = await WebFS.MoveFile(sourcePath, targetPath) if (res){ this.ReRenderDir() } else { WebDesktopEnvironment.Alert("UWAGA TODO MOVE FILE ERROR") //TODO } } else { console.log(event, this.curPath) let files = event.dataTransfer.files for (let i = 0; i < files.length; i++) { const file = files[i]; console.log("file:" + file.name) const res = await WebFS.UploadFile(file, this.curPath) if (res){ this.ReRenderDir() } } return const params = new URLSearchParams({ parentPath: this.curPath, }) const response = await fetch('/fs/upload/?' + params, { method: "POST", //TODO Change to PUT? body: formData }) if (response.status != 200){ WebDesktopEnvironment.Alert("ERROR IN UPLOADING FILE")//TODO } else { this.ReRenderDir() } } } /** * @param {MouseEvent} event */ Click(event){ this.OpenFile(this.curPath, event.target.getAttribute("name"), event.target.getAttribute("filetype")) } /** * @param {string} filePath */ async OpenFile(parentPath, fileName, fileType){ // console.log(parentPath, fileName, fileType) // const splittedPath = filePath.split("/") // const fileName = splittedPath[splittedPath.length - 1] const fileExtension = fileName.split(".")[fileName.split(".").length - 1] //FIXME switch (true) { case fileType == "objectlink": WebDesktopEnvironment.Alert("Links not supported yet") break case fileType == "pathlink": let res = await WebFS.ReadPathLink(`${parentPath}/${fileName}`) console.log(res) this.OpenFile(res.parentPath, res.name, res.filetype) break case fileExtension == "app": WebDesktopEnvironment.Open(`${parentPath}/${fileName}`, []) break case fileExtension == "blog": WebDesktopEnvironment.Open(`/Applications/BlogViewer.app`, [`${parentPath}/${fileName}`]) break case fileType == "directory": WebDesktopEnvironment.Open(`/Applications/Finder.app`, [`${parentPath}/${fileName}`]) break case fileExtension == "blog": WebDesktopEnvironment.Open("/Applications/BlogViewer.app", [`${parentPath}/${fileName}`]) break case fileExtension == "jpeg" | fileExtension == "png": WebDesktopEnvironment.Open("img-viewer", [`${parentPath}/${fileName}`]) break; default: WebDesktopEnvironment.Alert("Unsupported file type") break; } } /** * @param {MouseEvent} event */ RightClick(event){ this.CreateContextMenu(event.target, [event.clientY, event.clientX]) } /** * @param {HTMLElement} target * @param {string[]} pos */ async CreateContextMenu(target, pos){ let context = "" const fileName = target.getAttribute("name") //TODO check for null const fileType = target.getAttribute("fileType") if (target.classList.contains("FileTileView")) { context = "FileTileView" } else { context = fileType } let path = "" if (fileName === null){ path = this.curPath } else { path = `${this.curPath}/${fileName}` } const params = new URLSearchParams({context: context, path: path}) const response = await fetch(`/app/${Finder.AppId}/contextMenu?` + params) if (response.status != 200){ WebDesktopEnvironment.Alert("ERROR in Context menu TODO"); //TODO return } const html = await response.text() let overlay = document.createElement("div") //TODO Move to WDE.CreateOverlay() overlay.setAttribute('id', 'finder-context-menu-overlay') overlay.style.position = 'absolute' overlay.style.width = "100%" overlay.style.height = "100%" let menu = document.createElement("div") menu.setAttribute('class', 'ContextMenu WindowFrameShadow') menu.style.position = 'absolute'; menu.style.top = pos[0] + "px"; menu.style.left = pos[1] + "px"; menu.innerHTML = html // menu.children[0].firstElementChild.remove() menu.children[0].lastElementChild.remove() //FIXME Can't ommit rendering of horLine in end of menu on backend overlay.appendChild(menu) document.body.appendChild(overlay) overlay.addEventListener('click', async (event) => { if (event.target.classList.contains("Row")){ //TODO add uuid id to rows to more accurate checks?? let res = false switch (event.target.children[0].getAttribute("action")) { case "createPathLink": res = await WebFS.CreatePathLink(`${this.curPath}/${fileName}`, `${this.curPath}/Link to ${fileName}` ) if (res){ this.ReRenderDir() } break case "createDir": res = await WebFS.CreateDirectory(`${this.curPath}`) console.log(res) if (res){ this.ReRenderDir() } break case "deleteFile": res = await WebFS.DeleteFile(`${this.curPath}/${fileName}`) console.log(res) if (res){ this.ReRenderDir() } break case "getInfo": Finder.RenderProperites(path) break case "openAsDir": WebDesktopEnvironment.Open(`/Applications/${Finder.AppId}.app`,[`${this.curPath}/${fileName}`]) break default: break; } } overlay.remove() }) overlay.addEventListener('contextmenu', (event) => { event.preventDefault(); overlay.remove() }) } }