close to finalizing folder system
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 20 Apr 2022 17:54:39 +0000 (17:54 +0000)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 20 Apr 2022 17:54:49 +0000 (17:54 +0000)
.gitignore
serve.py
static/css/index.css
static/src/folders.js
static/src/index.js
templates/index.html

index 76da001712686bb01ea7bf9fd89214bd951a4d1e..3d455148fd957b3fedb1933147ac906f9859df3a 100644 (file)
@@ -1 +1,4 @@
 __pycache__/**
+core_libraries/
+examples/
+permalinked/
\ No newline at end of file
index 7edf313986d8a0d5ff0a1c10150ba332e58c8fef..50ef5e89fc13b86d01924b282dcf3e4679ccb8e4 100644 (file)
--- a/serve.py
+++ b/serve.py
@@ -109,4 +109,39 @@ def get_permalinked(link):
 
 @app.route("/manifest.json")
 def get_manifest():
-    return send_file("static/manifest.json", mimetype="application/json")
\ No newline at end of file
+    return send_file("static/manifest.json", mimetype="application/json")
+
+@app.route("/core_libraries.json")
+def get_core_libraries():
+    import json
+    import os
+
+    def read_file(f):
+        with open(f) as file:
+            return file.read()
+
+    def build_dir(d):
+        filenames = [f for f in os.listdir(d) if os.path.isfile(os.path.join(d, f))]
+        dirnames  = [f for f in os.listdir(d) if os.path.isdir(os.path.join(d, f))]
+
+        out = []
+        out += [{
+            "name": name,
+            "type": "dir",
+            "state": "closed",
+            "elems": build_dir(os.path.join(d, name))
+        } for name in dirnames]
+
+        out += [{
+            "name": name,
+            "type": "file",
+            "contents": read_file(os.path.join(d, name))
+        } for name in filenames]
+        
+        return out
+
+
+    output = build_dir("./core_libraries")
+
+    response = flask.Response(json.dumps(output), mimetype="application/json")
+    return response
\ No newline at end of file
index d50e1d032b53240adaaca5cac556ea995ffdfb42..7c3f582598a2ebddf7b73e895af6a857ee39c616 100644 (file)
     --foreground-color: #000000;
 }
 
+.ui-blue-theme {
+    --terminal-background-color: #112233;
+    --terminal-foreground-color: #ffffff;
+    --background-color: #070723;
+    --light-background-color: #101046;
+    --active-color: #7777aa;
+    --foreground-color: #fff;
+}
+
 body {
     background: var(--background-color);
     color: var(--foreground-color);
index 9adec43fd0a85fa3ba07dfadd2e6f1902470c056..51a6f75c92b1e1cbac5eeec77713e50b2f015593 100644 (file)
@@ -1,69 +1,9 @@
 
 // Experimental Folder System
-/*
-    {
-        "name": "Examples",
-        "type": "dir",
-        "state": "open",
-        "elems": [
-            {
-                "name": "example 1",
-                "type": "file",
-            },
-            {
-                "name": "example 2",
-                "type": "file",
-            },
-            {
-                "name": "example 3",
-                "type": "file",
-            },
-            {
-                "name": "Built ins",
-                "type": "dir",
-                "state": "open",
-                "elems": [
-                    {
-                        "name": "example 1",
-                        "type": "file",
-                    },
-                    {
-                        "name": "example 2",
-                        "type": "file",
-                    },
-                    {
-                        "name": "example 3",
-                        "type": "file",
-                    },
-                ],
-            },
-        ],
-    },
-    {
-        "name": "Built ins",
-        "type": "dir",
-        "state": "open",
-        "elems": [
-            {
-                "name": "example 1",
-                "type": "file",
-            },
-            {
-                "name": "example 2",
-                "type": "file",
-            },
-            {
-                "name": "example 3",
-                "type": "file",
-            },
-        ],
-    },
-]
-*/
-
 class FolderSystem {
     constructor() {
         this.folders = [];
+        this.active_file_path = "";
     }
 
     create_directory(path) {
@@ -170,6 +110,16 @@ class FolderSystem {
 
     move_file(old_path, new_path) {
         let existing = this.lookup(old_path);
+
+        if (existing == null) return;
+
+        if (existing.type == "file") {
+            this.remove(old_path);
+            this.create_file(new_path, existing.contents);
+        } else {
+            let dirname = new_path.substring(new_path.lastIndexOf("/") + 1);
+            existing.name = dirname;
+        }
     }
 
     build_folder_view(onclick, selector=".folder-root") {
@@ -179,29 +129,35 @@ class FolderSystem {
             let output = "";
             switch (t.type) {
                 case "dir": {
-                    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>
-                    <i class="folder-item-button fa fa-pencil-alt"></i>
-                    </div>`;
-
                     t.elems.sort((a, b) => {
                         let av = a.type == "dir" ? 0 : 1;
                         let bv = b.type == "dir" ? 0 : 1;
 
                         if (av == bv) {
-                            return a.name < b.name ? -1 : 1;
+                            return a.name.localeCompare(b.name);
                         } else {
                             return av - bv;
                         }
                     })
 
-                    output += `<div class="folder ${t.state == "closed" ? "hidden" : ""}">`;
-                    for (let i of t.elems) {
-                        output += build(i, name + "/" + i.name);
+                    if (name != undefined) {
+                        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>
+                        <i class="folder-item-button fa fa-pencil-alt"></i>
+                        </div>`;
+
+                        output += `<div class="folder ${t.state == "closed" ? "hidden" : ""}">`;
+                        for (let i of t.elems) {
+                            output += build(i, name + "/" + i.name);
+                        }
+                        output += `</div>`;
+                    } else {
+                        for (let i of t.elems) {
+                            output += build(i, i.name);
+                        }
                     }
-                    output += `</div>`;
 
                     break;
                 }
@@ -220,10 +176,8 @@ class FolderSystem {
             return output;
         }
 
-        let root_html = "";
-        for (let elem of this.folders) {
-            root_html += build(elem, elem.name);
-        }
+        let root = {type:"dir", elems:this.folders};
+        let root_html = build(root);
 
         $root.html(root_html);
         $root.find(".folder-item").click(onclick);
@@ -245,7 +199,6 @@ class FolderSystem {
     }
 }
 
-
 async function enable_ide_mode() {
     $("#simple-menubar").addClass("hidden");
     $("#ide-menubar").removeClass("hidden");
@@ -260,6 +213,10 @@ async function enable_ide_mode() {
         await populate_examples_folder();
     }
 
+    if (folders.lookup("Core Libraries") == null) {
+        await populate_core_libraries_folder();
+    }
+
     await populate_simple_saved_folder();
 
     folders.save();
@@ -310,6 +267,12 @@ async function populate_simple_saved_folder() {
     }
 }
 
+async function populate_core_libraries_folder() {
+    let core_libs = await fetch(ROOT_ENDPOINT + "/core_libraries.json").then(x => x.json())
+    let core_dir = folders.create_directory("Core Libraries");
+    core_dir.elems = core_libs;
+}
+
 function folder_item_click(e) {
     let $target = $(e.target);
 
@@ -319,23 +282,37 @@ function folder_item_click(e) {
     }
 
     if ($target.hasClass("directory")) {
+        let dirname = $target.attr("data-filename");
+        let dir = folders.lookup(dirname);
+
         if ($target.hasClass("open")) {
             $target.removeClass("open").addClass("closed");
             $target.children("i").removeClass("fa-folder-open").addClass("fa-folder");
             $target.next().addClass("hidden");
+            dir.state = "closed";
         } else {
             $target.removeClass("closed").addClass("open");
             $target.children("i").removeClass("fa-folder").addClass("fa-folder-open");
             $target.next().removeClass("hidden");
+            dir.state = "open";
         }
     }
 }
 
 function folder_open_file(filename) {
     let editor = ace.edit("code-editor");
+    if (folders.active_file_path != "") {
+        let file = folders.lookup(folders.active_file_path);
+        if (file != null) {
+            file.contents = editor.getValue();
+            folders.save();
+        }
+    }
+
     let file = folders.lookup(filename);
     editor.setValue(file.contents);
     editor.clearSelection();
+    folders.active_file_path = filename;
 }
 
 function folder_start_create_file() {
@@ -397,3 +374,13 @@ function folder_finalize_remove() {
     $.modal.close();
 }
 
+function folder_save_current_file() {
+    let editor = ace.edit("code-editor");
+    if (folders.active_file_path != "") {
+        let file = folders.lookup(folders.active_file_path);
+        if (file != null) {
+            file.contents = editor.getValue();
+            folders.save();
+        }
+    }
+}
\ No newline at end of file
index 4223ee9b7c94a47fadaad8727368ecd610aa8228..cb117f952e0e0a1e13f8819c02f5902ed1668d40 100644 (file)
@@ -179,8 +179,11 @@ function change_ui_theme(value) {
 
     $("body").removeClass();
     if (value == "light") $("body").addClass("ui-light-theme");
+    if (value == "blue")  $("body").addClass("ui-blue-theme");
     if (value == "dark")  $("body").addClass("ui-dark-theme");
 
+    $("meta[name='theme-color']").attr("content", $("body").css("background-color"))
+
     ui_theme = value;
     persist_settings();
 }
index c519b881c20b138955a4b9bdd0a62c10457e4922..395ca659a7a06774c296a3ea5aa38543436afff2 100644 (file)
@@ -52,7 +52,7 @@
             <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="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="Save" onclick="folder_save_current_file()"><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>
@@ -93,6 +93,7 @@
             <label for="ui-theme">UI theme:</label>
             <select aria-label="Theme" name="ui-theme" id="ui-theme" onchange="change_ui_theme()">
                 <option value="dark">Dark</option>
+                <option value="blue">Blue</option>
                 <option value="light">Light</option>
             </select>