diff --git a/apps/fsapp.app/operations.js b/apps/fsapp.app/operations.js index d6478340..2e1a1eaa 100644 --- a/apps/fsapp.app/operations.js +++ b/apps/fsapp.app/operations.js @@ -58,374 +58,65 @@ async function filePickerAction(selected) { async function fileAction(selected) { if (selected.length === 1) { - // SINGLE FILE SELECTION // - var fileSelected = selected[0]; if (fileSelected.getAttribute("data-type") === "file") { console.debug("Clicked on file"); if ( - fileSelected - .getAttribute("data-path") - .split(".") - .slice("-2") - .join(".") === "app.zip" + fileSelected.getAttribute("data-path").endsWith(".app.zip") || + fileSelected.getAttribute("data-path").endsWith(".lib.zip") ) { - let data = await fs.promises.readFile( - fileSelected.getAttribute("data-path"), - ); - - const path = fileSelected - .getAttribute("data-path") - .split(".") - .slice(0, -1) - .join("."); - - const zip = await unzip(new Uint8Array(data)); - const manifest = JSON.parse( - new TextDecoder().decode(zip["manifest.json"]), - ); - const icon = new Blob([zip[manifest.icon]], { - type: mime.default.getType(manifest.icon), - }); - const win = anura.wm.create(instance, { - title: "", - width: "450px", - height: "525px", - }); - - const iframe = document.createElement("iframe"); - - iframe.setAttribute( - "src", - document.location.href.split("/").slice(0, -1).join("/") + - "/appview.html?manifest=" + - ExternalApp.serializeArgs([ - JSON.stringify(manifest), - URL.createObjectURL(icon), - "app", - ]), - ); - - iframe.style = - "top:0; left:0; bottom:0; right:0; width:100%; height:100%; border:none; margin:0; padding:0;"; - - win.content.appendChild(iframe); - - Object.assign(iframe.contentWindow, { - anura, - ExternalApp, - instance, - instanceWindow: win, - install: { - session: async () => { - anura.notifications.add({ - title: "Application Installing for Session", - description: `Application ${path.replace( - "//", - "/", - )} is being installed, please wait`, - timeout: 50000, - }); - await fs.mkdir(`${path.replace("//", "/")}`); - try { - for (const [ - relativePath, - content, - ] of Object.entries(zip)) { - if (relativePath.endsWith("/")) { - fs.mkdir(`${path}/${relativePath}`); - } else { - fs.writeFile( - `${path}/${relativePath}`, - await Buffer.from(content), - ); - } - } - await anura.registerExternalApp( - `/fs${path}`.replace("//", "/"), - ); - anura.notifications.add({ - title: "Application Installed for Session", - description: `Application ${path.replace( - "//", - "/", - )} has been installed temporarily, it will go away on refresh`, - timeout: 50000, - }); - } catch (e) { - console.error(e); - } - }, - permanent: async () => { - anura.notifications.add({ - title: "Application Installing", - description: `Application ${path.replace( - "//", - "/", - )} is being installed, please wait`, - timeout: 50000, - }); - await fs.promises.mkdir( - anura.settings.get("directories")["apps"] + - "/" + - path.split("/").slice("-1")[0], - ); - - try { - for (const [ - relativePath, - content, - ] of Object.entries(zip)) { - if (relativePath.endsWith("/")) { - await fs.promises.mkdir( - `${anura.settings.get("directories")["apps"]}/${path.split("/").slice("-1")[0]}/${relativePath}`, - ); - } else { - await fs.promises.writeFile( - `${anura.settings.get("directories")["apps"]}/${path.split("/").slice("-1")[0]}/${relativePath}`, - Buffer.from(content), - ); - } - } - await anura.registerExternalApp( - `/fs${anura.settings.get("directories")["apps"]}/${path.split("/").slice("-1")[0]}`.replace( - "//", - "/", - ), - ); - anura.notifications.add({ - title: "Application Installed", - description: `Application ${path.replace( - "//", - "/", - )} has been installed permanently`, - timeout: 50000, - }); - } catch (e) { - console.error(e); - } - }, - }, - }); - - iframe.contentWindow.addEventListener("load", () => { - const matter = document.createElement("link"); - matter.setAttribute("rel", "stylesheet"); - matter.setAttribute("href", "/assets/matter.css"); - iframe.contentDocument.head.appendChild(matter); - }); - } else if ( - fileSelected - .getAttribute("data-path") - .split(".") - .slice("-2") - .join(".") === "lib.zip" - ) { - const data = await fs.promises.readFile( - fileSelected.getAttribute("data-path"), - ); - - const path = fileSelected - .getAttribute("data-path") - .split(".") - .slice(0, -1) - .join("."); - - const zip = await unzip(new Uint8Array(data)); - const manifest = JSON.parse( - new TextDecoder().decode(zip["manifest.json"]), - ); - const icon = new Blob([zip[manifest.icon]], { - type: mime.default.getType(manifest.icon), - }); - - const win = anura.wm.create(instance, { - title: "", - width: "450px", - height: "525px", - }); - - const iframe = document.createElement("iframe"); + anura.files.open(fileSelected.getAttribute("data-path")); + } - iframe.setAttribute( - "src", - document.location.href.split("/").slice(0, -1).join("/") + - "/appview.html?manifest=" + - ExternalApp.serializeArgs([ - JSON.stringify(manifest), - URL.createObjectURL(icon), - "lib", - ]), + if (fileSelected.getAttribute("data-path").endsWith(".zip")) { + const data = await unzip( + await anura.fs.promises.readFile( + fileSelected.getAttribute("data-path"), + ), ); - - iframe.style = - "top:0; left:0; bottom:0; right:0; width:100%; height:100%; border:none; margin:0; padding:0;"; - - win.content.appendChild(iframe); - - Object.assign(iframe.contentWindow, { - anura, - ExternalApp, - instance, - instanceWindow: win, - install: { - session: async () => { - anura.notifications.add({ - title: "Library Installing for Session", - description: `Library ${path.replace( - "//", - "/", - )} is being installed, please wait`, - timeout: 50000, - }); - await fs.promises.mkdir(`${path}`); - - let filesRemaining = Object.keys(zip).length; - - Object.entries(zip).forEach( - async ([relativePath, content]) => { - if (relativePath.endsWith("/")) { - await fs.promises.mkdir( - `${path}/${relativePath}`, - ); - } else { - await fs.promises.writeFile( - `${path}/${relativePath}`, - Buffer.from(content), - ); - } - filesRemaining--; - if (filesRemaining === 0) { - await anura.registerExternalLib( - `/fs/${path}`.replace("//", "/"), - ); - anura.notifications.add({ - title: "Library Installed for Session", - description: `Library ${path.replace( - "//", - "/", - )} has been installed temporarily, it will go away on refresh`, - timeout: 50000, - }); - } - }, - function (e) { - console.error(e); - }, - ); - }, - permanent: async () => { - anura.notifications.add({ - title: "Library Installing", - description: `Library ${path.replace( - "//", - "/", - )} is being installed`, - timeout: 50000, - }); - await fs.mkdir( - anura.settings.get("directories")["libs"] + - "/" + - path.split("/").slice("-1")[0], - ); - - let filesRemaining = Object.keys(zip).length; - - Object.entries(zip).forEach( - async ([relativePath, content]) => { - if (relativePath.endsWith("/")) { - await fs.promises.mkdir( - `${anura.settings.get("directories")["libs"]}/${path.split("/").slice("-1")[0]}/${relativePath}`, - ); - } else { - await fs.promises.writeFile( - `${anura.settings.get("directories")["libs"]}/${path.split("/").slice("-1")[0]}/${relativePath}`, - Buffer.from(content), - ); - } - filesRemaining--; - if (filesRemaining === 0) { - await anura.registerExternalLib( - `/fs${anura.settings.get("directories")["libs"]}/${path.split("/").slice("-1")[0]}`.replace( - "//", - "/", - ), - ); - anura.notifications.add({ - title: "Library Installed", - description: `Library ${path.replace( - "//", - "/", - )} has been installed permanently`, - timeout: 50000, - }); - } - }, - function (e) { - console.error(e); - }, - ); - }, - }, - }); - - iframe.contentWindow.addEventListener("load", () => { - const matter = document.createElement("link"); - matter.setAttribute("rel", "stylesheet"); - matter.setAttribute("href", "/assets/matter.css"); - iframe.contentDocument.head.appendChild(matter); - }); - } else { - if (fileSelected.getAttribute("data-path").endsWith(".zip")) { - const data = await unzip( - await anura.fs.promises.readFile( - fileSelected.getAttribute("data-path"), - ), - ); - const root = - fileSelected - .getAttribute("data-path") - .split("/") - .slice(0, -1) - .join("/") + - "/" + - fileSelected - .getAttribute("data-path") - .split("/") - .pop() - .split(".") - .slice(0, -1) - .join(".") + - "/"; - // const folders = []; - const files = []; - for (const item in data) { - console.log(item); - if (item.endsWith("/")) { - // folders.push(item); - } else { - files.push([item, data[item]]); - } + const root = + fileSelected + .getAttribute("data-path") + .split("/") + .slice(0, -1) + .join("/") + + "/" + + fileSelected + .getAttribute("data-path") + .split("/") + .pop() + .split(".") + .slice(0, -1) + .join(".") + + "/"; + // const folders = []; + const files = []; + for (const item in data) { + console.log(item); + if (item.endsWith("/")) { + // folders.push(item); + } else { + files.push([item, data[item]]); } - const sh = new fs.Shell(); - // for (const folder of folders) { - // await sh.promises.mkdirp(root + folder); - // } + } + const sh = new fs.Shell(); + // for (const folder of folders) { + // await sh.promises.mkdirp(root + folder); + // } - for (const file of files) { - const container = - file[0].split("/").slice(0, -1).join("/") + "/"; - await sh.promises.mkdirp(root + container); + for (const file of files) { + const container = + file[0].split("/").slice(0, -1).join("/") + "/"; + await sh.promises.mkdirp(root + container); - await fs.promises.writeFile( - root + file[0], - Buffer.from(file[1]), - ); - } - reload(); - } else { - anura.files.open(fileSelected.getAttribute("data-path")); + await fs.promises.writeFile( + root + file[0], + Buffer.from(file[1]), + ); } + reload(); + } else { + anura.files.open(fileSelected.getAttribute("data-path")); } } else if (fileSelected.getAttribute("data-type") === "dir") { if ( @@ -435,117 +126,6 @@ async function fileAction(selected) { .slice("-1")[0] === "app" ) { try { - let data; - try { - data = await fs.promises.readFile( - `${fileSelected.getAttribute("data-path")}/manifest.json`, - ); - } catch { - console.debug( - "Changing folder to ", - fileSelected.getAttribute("data-path"), - ); - loadPath(fileSelected.getAttribute("data-path")); - return; - } - const manifest = JSON.parse(data); - if (anura.apps[manifest.package]) { - anura.apps[manifest.package].open(); - return; - } - - const iconData = await fs.promises.readFile( - `${fileSelected.getAttribute("data-path")}/${manifest.icon}`, - ); - - const icon = new Blob([iconData]); - - const win = anura.wm.create(instance, { - title: "", - width: "450px", - height: "525px", - }); - - const iframe = document.createElement("iframe"); - iframe.setAttribute( - "src", - document.location.href - .split("/") - .slice(0, -1) - .join("/") + - "/appview.html?manifest=" + - ExternalApp.serializeArgs([ - data.toString(), - URL.createObjectURL(icon), - "app", - ]), - ); - iframe.style = - "top:0; left:0; bottom:0; right:0; width:100%; height:100%; border:none; margin:0; padding:0;"; - - win.content.appendChild(iframe); - Object.assign(iframe.contentWindow, { - anura, - ExternalApp, - instance, - instanceWindow: win, - install: { - session: async () => { - await anura.registerExternalApp( - `/fs${fileSelected.getAttribute("data-path")}`.replace( - "//", - "/", - ), - ); - anura.notifications.add({ - title: "Application Installed for Session", - description: `Application ${fileSelected - .getAttribute("data-path") - .replace( - "//", - "/", - )} has been installed temporarily, it will go away on refresh`, - timeout: 50000, - }); - win.close(); - }, - permanent: async () => { - await fs.promises.rename( - fileSelected.getAttribute("data-path"), - anura.settings.get("directories")["apps"] + - "/" + - fileSelected - .getAttribute("data-path") - .split("/") - .slice("-1")[0], - ); - await anura.registerExternalApp( - `/fs${anura.settings.get("directories")["apps"]}/${fileSelected.getAttribute("data-path").split("/").slice("-1")[0]}`.replace( - "//", - "/", - ), - ); - anura.notifications.add({ - title: "Application Installed", - description: `Application ${fileSelected - .getAttribute("data-path") - .replace( - "//", - "/", - )} has been installed permanently`, - timeout: 50000, - }); - win.close(); - }, - }, - }); - - iframe.contentWindow.addEventListener("load", () => { - const matter = document.createElement("link"); - matter.setAttribute("rel", "stylesheet"); - matter.setAttribute("href", "/assets/matter.css"); - iframe.contentDocument.head.appendChild(matter); - }); } catch (e) { anura.dialog.alert( `There was an error: ${e}`, diff --git a/apps/libfileview.lib/fileHandler.js b/apps/libfileview.lib/fileHandler.js index 9e7427d2..2803f067 100644 --- a/apps/libfileview.lib/fileHandler.js +++ b/apps/libfileview.lib/fileHandler.js @@ -1,3 +1,5 @@ +import { createAppView } from "./pages/appview/appview.js"; + const icons = await (await fetch(localPathToURL("icons.json"))).json(); export function openFile(path) { @@ -117,7 +119,16 @@ export function openFile(path) { iframe.srcdoc = data; fileView.content.appendChild(iframe); } - + switch (path.split(".").slice("-2").join(".")) { + case "app.zip": + createAppView(path, "app"); + return; + case "lib.zip": + createAppView(path, "lib"); + return; + default: + break; + } let ext = path.split(".").slice("-1")[0]; switch (ext) { case "txt": diff --git a/apps/libfileview.lib/pages/appview/appview.html b/apps/libfileview.lib/pages/appview/appview.html new file mode 100644 index 00000000..7a150629 --- /dev/null +++ b/apps/libfileview.lib/pages/appview/appview.html @@ -0,0 +1,289 @@ + + + + + App Info Viewer + + + + +
+ +
+

+ +
+
+
+
+ +
+
+ + + + diff --git a/apps/libfileview.lib/pages/appview/appview.js b/apps/libfileview.lib/pages/appview/appview.js new file mode 100644 index 00000000..0c35cec2 --- /dev/null +++ b/apps/libfileview.lib/pages/appview/appview.js @@ -0,0 +1,271 @@ +const fflate = await anura.import("npm:fflate"); +const mime = await anura.import("npm:mime"); +const Buffer = Filer.Buffer; + +export async function createAppView(dataPath, type) { + let data = await anura.fs.promises.readFile(dataPath); + + const path = dataPath.split(".").slice(0, -1).join("."); + + const zip = await unzip(new Uint8Array(data)); + const manifest = JSON.parse(new TextDecoder().decode(zip["manifest.json"])); + const icon = new Blob([zip[manifest.icon]], { + type: mime.default.getType(manifest.icon), + }); + + const win = anura.wm.createGeneric({ + title: "", + width: "450px", + height: "525px", + }); + + win.onclose = () => { + URL.revokeObjectURL(icon); + }; + + const iframe = document.createElement("iframe"); + + iframe.setAttribute( + "src", + localPathToURL( + "appview.html?manifest=" + + ExternalApp.serializeArgs([ + JSON.stringify(manifest), + URL.createObjectURL(icon), + type, + ]), + ), + ); + + iframe.style = + "top:0; left:0; bottom:0; right:0; width:100%; height:100%; border:none; margin:0; padding:0;"; + + win.content.appendChild(iframe); + + Object.assign(iframe.contentWindow, { + anura, + ExternalApp, + instanceWindow: win, + install: { + session: async () => { + anura.notifications.add({ + title: "Installing for Session", + description: `${path.replace( + "//", + "/", + )} is being installed, please wait`, + timeout: 50000, + }); + await anura.fs.mkdir(`${path.replace("//", "/")}`); + try { + for (const [relativePath, content] of Object.entries(zip)) { + if (relativePath.endsWith("/")) { + anura.fs.mkdir(`${path}/${relativePath}`); + } else { + anura.fs.writeFile( + `${path}/${relativePath}`, + await Buffer.from(content), + ); + } + } + await anura.registerExternalApp( + `/fs${path}`.replace("//", "/"), + ); + anura.notifications.add({ + title: "Installed for Session", + description: `${path.replace( + "//", + "/", + )} has been installed temporarily, it will go away on refresh`, + timeout: 50000, + }); + } catch (e) { + console.error(e); + } + }, + permanent: async () => { + anura.notifications.add({ + title: "Installing", + description: `${path.replace( + "//", + "/", + )} is being installed, please wait`, + timeout: 50000, + }); + await anura.fs.promises.mkdir( + // this is a dumb hack but i dont want to make 2 functions + anura.settings.get("directories")[type + "s"] + + "/" + + path.split("/").slice("-1")[0], + ); + + try { + for (const [relativePath, content] of Object.entries(zip)) { + if (relativePath.endsWith("/")) { + await anura.fs.promises.mkdir( + `${anura.settings.get("directories")[type + "s"]}/${path.split("/").slice("-1")[0]}/${relativePath}`, + ); + } else { + await anura.fs.promises.writeFile( + `${anura.settings.get("directories")[type + "s"]}/${path.split("/").slice("-1")[0]}/${relativePath}`, + Buffer.from(content), + ); + } + } + await anura.registerExternalApp( + `/fs${anura.settings.get("directories")[type + "s"]}/${path.split("/").slice("-1")[0]}`.replace( + "//", + "/", + ), + ); + anura.notifications.add({ + title: "Installed", + description: `${path.replace( + "//", + "/", + )} has been installed permanently`, + timeout: 50000, + }); + } catch (e) { + console.error(e); + } + }, + }, + }); + + iframe.contentWindow.addEventListener("load", () => { + const matter = document.createElement("link"); + matter.setAttribute("rel", "stylesheet"); + matter.setAttribute("href", "/assets/matter.css"); + iframe.contentDocument.head.appendChild(matter); + }); +} + +// will do later +export async function createAppViewFolder() { + let data; + try { + data = await fs.promises.readFile( + `${fileSelected.getAttribute("data-path")}/manifest.json`, + ); + } catch { + console.debug( + "Changing folder to ", + fileSelected.getAttribute("data-path"), + ); + loadPath(fileSelected.getAttribute("data-path")); + return; + } + const manifest = JSON.parse(data); + if (anura.apps[manifest.package]) { + anura.apps[manifest.package].open(); + return; + } + if (anura.libs[manifest.package]) { + return; + } + + const iconData = await fs.promises.readFile( + `${fileSelected.getAttribute("data-path")}/${manifest.icon}`, + ); + + const icon = new Blob([iconData]); + + const win = anura.wm.create(instance, { + title: "", + width: "450px", + height: "525px", + }); + + const iframe = document.createElement("iframe"); + iframe.setAttribute( + "src", + document.location.href.split("/").slice(0, -1).join("/") + + "/appview.html?manifest=" + + ExternalApp.serializeArgs([ + data.toString(), + URL.createObjectURL(icon), + "app", + ]), + ); + iframe.style = + "top:0; left:0; bottom:0; right:0; width:100%; height:100%; border:none; margin:0; padding:0;"; + + win.content.appendChild(iframe); + Object.assign(iframe.contentWindow, { + anura, + ExternalApp, + instance, + instanceWindow: win, + install: { + session: async () => { + await anura.registerExternalApp( + `/fs${fileSelected.getAttribute("data-path")}`.replace( + "//", + "/", + ), + ); + anura.notifications.add({ + title: "Application Installed for Session", + description: `Application ${fileSelected + .getAttribute("data-path") + .replace( + "//", + "/", + )} has been installed temporarily, it will go away on refresh`, + timeout: 50000, + }); + win.close(); + }, + permanent: async () => { + await fs.promises.rename( + fileSelected.getAttribute("data-path"), + anura.settings.get("directories")["apps"] + + "/" + + fileSelected + .getAttribute("data-path") + .split("/") + .slice("-1")[0], + ); + await anura.registerExternalApp( + `/fs${anura.settings.get("directories")["apps"]}/${fileSelected.getAttribute("data-path").split("/").slice("-1")[0]}`.replace( + "//", + "/", + ), + ); + anura.notifications.add({ + title: "Application Installed", + description: `Application ${fileSelected + .getAttribute("data-path") + .replace("//", "/")} has been installed permanently`, + timeout: 50000, + }); + win.close(); + }, + }, + }); + + iframe.contentWindow.addEventListener("load", () => { + const matter = document.createElement("link"); + matter.setAttribute("rel", "stylesheet"); + matter.setAttribute("href", "/assets/matter.css"); + iframe.contentDocument.head.appendChild(matter); + }); +} + +function localPathToURL(path) { + return ( + import.meta.url.substring(0, import.meta.url.lastIndexOf("/")) + + "/" + + path + ); +} + +function unzip(zip) { + return new Promise((res, rej) => { + fflate.unzip(zip, (err, unzipped) => { + if (err) rej(err); + else res(unzipped); + }); + }); +}