flushing out ide mode
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 20 Apr 2022 15:00:42 +0000 (15:00 +0000)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 20 Apr 2022 15:00:42 +0000 (15:00 +0000)
static/src/folders.js
static/src/index.js
templates/index.html

index 5dc1e03efbd03793851879871a7a6595c2dbbc29..9adec43fd0a85fa3ba07dfadd2e6f1902470c056 100644 (file)
@@ -67,6 +67,10 @@ class FolderSystem {
     }
 
     create_directory(path) {
+        if (path == "") {
+            return { type:"dir", elems:this.folders }
+        }
+
         let parts = path.split("/");
         let name = parts.at(-1);
 
@@ -101,25 +105,73 @@ class FolderSystem {
         return root[root.length - 1];
     }
 
+    get_containing_directory(path) {
+        let last_slash = path.lastIndexOf("/");
+        if (last_slash == -1) return "";
+
+        return path.substring(0, last_slash);
+    }
+
+    create_file(path, contents) {
+        let containing_dir = this.get_containing_directory(path);
+        let dir = this.create_directory(containing_dir);
+
+        let filename = path.substring(path.lastIndexOf("/") + 1);
+
+        let existing = dir.elems.find(x => x == filename)
+        if (existing) {
+            return existing;
+        }
+
+        dir.elems.push({
+            name: filename,
+            type: "file",
+            contents
+        })
+
+        return dir.elems[dir.elems.length - 1];
+    }
+
+    remove(path) {
+        let containing_dir = this.get_containing_directory(path);
+        let dir = this.create_directory(containing_dir);
+
+        let filename = path.substring(path.lastIndexOf("/") + 1);
+        dir.elems.splice(dir.elems.findIndex(x => x.name == filename), 1);
+    }
+
+    // Returns null if the item at the path does not exist
     lookup(path) {
         let parts = path.split("/");
+        
+        let root = { type:"dir", elems:this.folders };
+        let i;
+        for (i=0; i<parts.length; i++) {
+            if (root.type == "dir") {
+                let elems = root.elems.filter(x => x.name == parts[i]);
+                if (elems.length != 1) {
+                    root = null;
+                    break;
+                }
 
-        let root = this.folders;
-        for (let part of parts) {
-            if (!Array.isArray(root)) return null;
+                root = elems[0];
 
-            let elems = root.filter((x) => x.name == part);
-            if (elems.length != 1) return null;
+            } else if (root.type == "file") {
+                if (root.name != parts[i] || i != parts.length - 1) {
+                    root = null;
+                }
 
-            root = elems[0];
-            if (root.type == "dir") {
-                root = root.elems;
+                break;
             }
         }
 
         return root;
     }
 
+    move_file(old_path, new_path) {
+        let existing = this.lookup(old_path);
+    }
+
     build_folder_view(onclick, selector=".folder-root") {
         let $root = $(selector);
 
@@ -127,7 +179,7 @@ class FolderSystem {
             let output = "";
             switch (t.type) {
                 case "dir": {
-                    output += `<div class="folder-item directory ${t.state}">
+                    output += `<div class="folder-item directory ${t.state}" data-filename="${name}">
                     <i class="fa ${t.state == "open" ? "fa-folder-open" : "fa-folder"}"></i>
                     ${t.name}
                     <i class="folder-item-button fa fa-trash"></i>
@@ -175,6 +227,8 @@ class FolderSystem {
 
         $root.html(root_html);
         $root.find(".folder-item").click(onclick);
+        $root.find(".folder-item i.fa-pencil-alt").click(folder_start_rename);
+        $root.find(".folder-item i.fa-trash").click(folder_start_remove);
     }
 
     save() {
@@ -260,11 +314,8 @@ function folder_item_click(e) {
     let $target = $(e.target);
 
     if ($target.hasClass("file")) {
-        let editor = ace.edit("code-editor");
         let filename = $target.attr("data-filename");
-        let file = folders.lookup(filename);
-        editor.setValue(file.contents);
-        editor.clearSelection();
+        folder_open_file(filename);
     }
 
     if ($target.hasClass("directory")) {
@@ -278,4 +329,71 @@ function folder_item_click(e) {
             $target.next().removeClass("hidden");
         }
     }
-}
\ No newline at end of file
+}
+
+function folder_open_file(filename) {
+    let editor = ace.edit("code-editor");
+    let file = folders.lookup(filename);
+    editor.setValue(file.contents);
+    editor.clearSelection();
+}
+
+function folder_start_create_file() {
+    let $modal = $("#create-file-modal");
+    $modal.find("input").val("");
+    $modal.modal();
+}
+
+function folder_finalize_create_file() {
+    let $modal = $("#create-file-modal");
+    let path = $modal.find("input").val();
+
+    folders.create_file(path, "");
+    folders.save();
+    folders.build_folder_view(folder_item_click);
+
+    folder_open_file(path);
+
+    $.modal.close();
+}
+
+function folder_start_rename(e) {
+    let filename = $(e.target).parent().attr("data-filename");
+    let $modal = $("#rename-modal");
+    $modal.find("input").val(filename);
+    $modal.attr("data-filename", filename);
+    $modal.modal();
+}
+
+function folder_finalize_rename(e) {
+    let $modal = $("#rename-modal");
+    let current_filename = $modal.attr("data-filename");
+    let new_filename = $modal.find("input").val();
+    $.modal.close();
+
+    folders.move_file(current_filename, new_filename);
+    folders.save();
+    folders.build_folder_view(folder_item_click);
+
+    folder_open_file(new_filename);
+}
+
+function folder_start_remove(e) {
+    let filename = $(e.target).parent().attr("data-filename");
+    let $modal = $("#remove-modal");
+    $modal.find("p").html(`Are you sure you want to remove ${filename}?`);
+    $modal.attr("data-filename", filename);
+    $modal.modal();
+}
+
+function folder_finalize_remove() {
+    let $modal = $("#remove-modal");
+    let filename = $modal.attr("data-filename");
+
+    folders.remove(filename);
+    folders.save();
+    folders.build_folder_view(folder_item_click);
+
+    $.modal.close();
+}
+
index dfdeaa83fc49a00df04b38794525704869fc30fe..4223ee9b7c94a47fadaad8727368ecd610aa8228 100644 (file)
@@ -2,6 +2,7 @@ let wasm_worker = null;
 let editor_keybind_mode = "normal";
 let editor_theme = "chrome";
 let ui_theme = "dark";
+let ui_mode = "simple";
 
 let input_shared_buffer  = new SharedArrayBuffer(1024 * Uint8Array.BYTES_PER_ELEMENT);
 let canvas_shared_buffer = new SharedArrayBuffer(7 * Int32Array.BYTES_PER_ELEMENT);
@@ -197,23 +198,29 @@ function change_ui_mode(value) {
     } else {
         disable_ide_mode();
     }
+
+    ui_mode = value;
+    persist_settings();
 }
 
 function persist_settings() {
     localStorage["editor_theme"] = editor_theme;
     localStorage["editor_keybind_mode"] = editor_keybind_mode;
     localStorage["ui_theme"] = ui_theme;
+    localStorage["ui_mode"] = ui_mode;
 }
 
 function load_settings() {
     editor_theme = localStorage["editor_theme"];
     editor_keybind_mode = localStorage["editor_keybind_mode"];
     ui_theme = localStorage["ui_theme"] || ui_theme;
+    ui_mode = localStorage["ui_mode"] || ui_mode;
 
     load_split_sizes();
     change_editor_theme(editor_theme);
     change_keybindings(editor_keybind_mode);
     change_ui_theme(ui_theme);
+    change_ui_mode(ui_mode);
 }
 
 async function handle_drop(e) {
@@ -329,7 +336,6 @@ window.onload = () => {
 
     populate_examples();
     load_settings();
-    change_ui_mode("ide");
 
     make_resizer("main-horizontal-divider", "--folder-width", "", (e) => {
         save_split_sizes();
index 6b18f7f1e292bb7797d45a67582de330e20f63ee..c519b881c20b138955a4b9bdd0a62c10457e4922 100644 (file)
@@ -51,7 +51,7 @@
             <div class="tab-line"><span>Storage</span></div>
             <div class="menu-bar" style="border-bottom: 2px solid var(--light-background-color); margin-bottom: 12px">
                 <div style="text-align: center">
-                    <button title="New File" onclick="prompt_create_file()"><i class="fas fa-plus"></i></button>
+                    <button title="New File" onclick="folder_start_create_file()"><i class="fas fa-plus"></i></button>
                     <button title="Save" onclick="prompt_save()"><i class="fas fa-save"></i></button>
                     <button title="Upload" onclick="prompt_upload()"><i class="fas fa-upload"></i></button>
                     <button title="Download" onclick="prompt_download()"><i class="fas fa-download"></i></button>
 
             <div class="file-list"> </div>
         </div>
+
+        <div id="create-file-modal" class="modal">
+            <h2>Create File</h2>
+            <input type="text" name="create-name" placeholder="Path" value="" />
+            <br/>
+            <button onclick="folder_finalize_create_file()">Create</button>
+        </div>
+
+        <div id="rename-modal" class="modal">
+            <h2>Rename</h2>
+            <input type="text" id="rename-name" name="rename-name" placeholder="Name" value="" />
+            <br/>
+            <button onclick="folder_finalize_rename()">Rename</button>
+        </div>
+
+        <div id="remove-modal" class="modal">
+            <h2>Remove</h2>
+            <p></p>
+            <br/>
+            <button onclick="folder_finalize_remove()">Remove</button>
+        </div>
     </body>
 </html>