Advertisement
Arinek

FileExplorer.js

Apr 24th, 2024
502
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { ArinekHTML } from "ArinekOS/ArinekHTML.js";
  2. import { Collection } from "ArinekOS/Collection.js";
  3.  
  4.  
  5. /** @param {NS} ns */
  6. export async function main(ns) {
  7.     let fileExplorer = new FileExplorer(ns);
  8.     fileExplorer.start();
  9. }
  10.  
  11. class FileExplorer {
  12.     parser;
  13.     data;
  14.     doc;
  15.     fileExplorer;
  16.  
  17.     #ns;
  18.     #host_server;
  19.     #current_path;
  20.     #selected_files;
  21.  
  22.     /**
  23.      * @param {NS} ns
  24.      */
  25.     constructor(ns) {
  26.         this.#ns = ns;
  27.         this.#host_server = ns.getHostname();
  28.         this.#current_path = "";
  29.         this.#selected_files = [];
  30.  
  31.         this.parser = new ArinekHTML(ns, "ArinekOS/FileExplorer/Content/index.html.txt");
  32.         this.data = new Collection();
  33.         this.doc = eval("document");
  34.         this.fileExplorer = this.openWindow();
  35.  
  36.         this.addCSS("ArinekOS/FileExplorer/Content/styles.css.txt");
  37.     }
  38.  
  39.     start() {
  40.         this.update();
  41.     }
  42.  
  43.     openWindow() {
  44.         this.#ns.alert("<div id='explorer-window' class='explorer-window'></div>");
  45.         const fileExplorerWindow = this.doc.getElementById("explorer-window");
  46.  
  47.         return fileExplorerWindow;
  48.     }
  49.  
  50.     /**
  51.       * @param {string} css_file
  52.       */
  53.     addCSS(css_file) {
  54.         const css = this.#ns.read(css_file);
  55.  
  56.         // Add the css to the game
  57.         let styleDiv = this.doc.getElementById('myCustomStyles');
  58.         if (!styleDiv) {
  59.             // Make a new new div
  60.             styleDiv = this.doc.createElement("div");
  61.             styleDiv.id = 'myCustomStyles';
  62.             this.doc.getElementsByTagName('head')[0].appendChild(styleDiv);
  63.         }
  64.         styleDiv.innerHTML = "<style>" + css + "</style>";
  65.     }
  66.  
  67.     update() {
  68.         let fileTree = new Folder(this.#ns, this.#current_path, this.#host_server);
  69.         let terminal = new FakeTerminal(this.doc);
  70.  
  71.         this.data.add("folders", fileTree.subfolder_names);
  72.         this.data.add("files", fileTree.files);
  73.         this.data.add("selected_files", this.#selected_files);
  74.         this.data.add("current_path", this.#current_path);
  75.  
  76.         this.parser.parse(this.data);
  77.         this.fileExplorer.innerHTML = this.parser.html;
  78.  
  79.         let folder_divs = this.doc.getElementsByClassName("explorer-directory");
  80.         for (let folder_div of folder_divs) {
  81.             folder_div.addEventListener("dblclick", e => {
  82.                 const folder = fileTree.getFolderByName(folder_div.id);
  83.                 this.#current_path = folder.path;
  84.                 this.#selected_files = [];
  85.                 this.update();
  86.             })
  87.         }
  88.  
  89.         let file_divs = this.doc.getElementsByClassName("explorer-file");
  90.         for (let file_div of file_divs) {
  91.             file_div.addEventListener("click", e => {
  92.                 const file = this.#current_path + file_div.id;
  93.                 this.toggleSelectedFile(file);
  94.                 this.update();
  95.             });
  96.         }
  97.  
  98.         let openButton = this.doc.getElementById("explorer-open");
  99.         openButton.addEventListener("click", e => {
  100.             terminal.openFiles(this.#selected_files);
  101.  
  102.         });
  103.  
  104.         let removeButton = this.doc.getElementById("explorer-remove");
  105.         removeButton.addEventListener("click", e => {
  106.             terminal.removeFiles(this.#selected_files);
  107.         });
  108.     }
  109.  
  110.     toggleSelectedFile(file) {
  111.         if (this.#selected_files.includes(file)) {
  112.             this.#selected_files = this.#selected_files.filter(selected_file => selected_file !== file);
  113.         } else {
  114.             this.#selected_files.push(file);
  115.         }
  116.     }
  117. }
  118.  
  119. class Folder {
  120.     path;
  121.     subfolders;
  122.     files;
  123.     #ns;
  124.     #host_server;
  125.  
  126.  
  127.     /**
  128.      * @param {NS} ns
  129.      * @param {string} path
  130.      * @param {string} host_server
  131.      */
  132.     constructor(ns, path, host_server) {
  133.         this.#ns = ns;
  134.         this.#host_server = host_server;
  135.         this.path = path;
  136.  
  137.         this.subfolders = this.getFiles(this.#ns, this.path).folders;
  138.         this.files = this.getFiles(this.#ns, this.path).files;
  139.     }
  140.  
  141.     getFiles() {
  142.         let files = this.#ns.ls(this.#host_server, this.path);
  143.         let folders = [];
  144.  
  145.         const nextFolderIndex = this.path.length;
  146.  
  147.         for (let file of files) {
  148.             const endOfNextFolderIndex = file.indexOf("/", nextFolderIndex + 1);
  149.             if (endOfNextFolderIndex !== -1) {
  150.                 const folder_name = file.slice(nextFolderIndex, endOfNextFolderIndex);
  151.                 const folder_path = file.slice(0, endOfNextFolderIndex + 1);
  152.  
  153.                 const folder = new Folder(this.#ns, folder_path, this.#host_server);
  154.  
  155.                 if (folders.every(folder => folder.path !== folder_path)) folders.push(folder);
  156.             }
  157.         }
  158.  
  159.         files = files.filter(file => file.slice(nextFolderIndex + 1).indexOf("/") === -1);
  160.         return {
  161.             folders: folders,
  162.             files: files
  163.         };
  164.     }
  165.  
  166.     get name() {
  167.         let lastIndex = this.path.lastIndexOf("/");
  168.         let temp = this.path.slice(0, lastIndex);
  169.         lastIndex = temp.lastIndexOf("/");
  170.  
  171.         if (lastIndex === -1) return temp;
  172.         return temp.slice(lastIndex + 1);
  173.     }
  174.  
  175.     get subfolder_names() {
  176.         let names = [];
  177.         for (const subfolder of this.subfolders) {
  178.             names.push(subfolder.name);
  179.         }
  180.         return names;
  181.     }
  182.  
  183.     getFolderByName(name) {
  184.         return this.subfolders.find(subfolder => subfolder.name === name);
  185.     }
  186. }
  187.  
  188. class FakeTerminal {
  189.     #terminal;
  190.  
  191.     /**
  192.      * @param {document} doc
  193.      */
  194.     constructor(doc) {
  195.         this.#terminal = doc.getElementById("terminal-input");
  196.     }
  197.  
  198.     runCommand(command) {
  199.         // Print the command to the terminal input field
  200.         this.#terminal.value = command;
  201.  
  202.         // Get a reference to the React event handler.
  203.         const handler = Object.keys(this.#terminal)[1];
  204.  
  205.         // Perform an onChange event to set some internal values.
  206.         this.#terminal[handler].onChange({ target: this.#terminal });
  207.  
  208.         // Simulate an enter press
  209.         this.#terminal[handler].onKeyDown({ key: 'Enter', preventDefault: () => null });
  210.     }
  211.  
  212.     openFiles(files) {
  213.         let command = "nano";
  214.         for (const file of files) {
  215.             command += " " + file;
  216.         }
  217.  
  218.         this.runCommand(command);
  219.     }
  220.  
  221.     async removeFiles(files) {
  222.         let command = "";
  223.         for (let file of files) {
  224.             command += "rm " + file + ";";
  225.         }
  226.         this.runCommand(command);
  227.     }
  228. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement