Explorar el Código

allow user to load world proto from folder

Nikolay Suslov hace 4 años
padre
commit
3b7000ea2f
Se han modificado 5 ficheros con 594 adiciones y 5 borrados
  1. 132 5
      public/app.js
  2. 13 0
      public/lib/index.css
  3. 0 0
      public/lib/wt/buffer5.6.0.min.js
  4. 447 0
      public/lib/wt/drag-drop.js
  5. 2 0
      public/loadLibs.js

+ 132 - 5
public/app.js

@@ -676,8 +676,8 @@ class App {
     _LCSDB.on('auth',
       async function (ack) {
         if (ack.sea.pub) {
-          document.querySelector("#profile")._status = "User: " + _LCSDB.user().is.alias //+' pub: ' + this.db.user().is.pub;
-          document.querySelector("#profile").$update();
+          document.querySelector("#profile")._refresh("User: " + _LCSDB.user().is.alias); //+' pub: ' + this.db.user().is.pub;
+          //document.querySelector("#profile").$update();
         }
       })
 
@@ -685,24 +685,146 @@ class App {
     el.setAttribute("id", "userProfile");
     document.body.appendChild(el);
 
+    let dragDropWorldsArea = {
+      $cell: true,
+      $type: 'div',
+      id: "ddWorlds",
+      class: 'dragdropArea',
+      _ddText: '',
+      _refresh: function (aText) {
+        this._ddText = aText;
+
+      },
+      $init: function () {
+        console.log('init d&d area');
+        this._refresh('Drag & Drop a folder with world files here...');
+        let self = this;
+        DragDrop("#ddWorlds",
+        {
+          onDrop: function (files, pos, fileList, directories) {
+            console.log('onDrop: ' + files.length + ' files at ' + pos.x + ', ' + pos.y);
+            //let worldsObj = {};
+            let worlds = _LCSDB.user().get('worlds');
+
+            files.forEach(function (file) {
+              let world = {};
+
+              if ((file.name.indexOf('.yaml') !== -1) ||
+                (file.type == "text/javascript") || 
+                (file.type == "text/html") || 
+                (file.type == "application/json")) {
+
+              console.log('- ' + file.name + ' (' + file.size + ') (' + file.type + ')');
+
+              // convert the file to a Buffer that we can use!
+              const reader = new FileReader()
+              reader.addEventListener('load', e => {
+                // e.target.result is an ArrayBuffer
+                const arr = new Uint8Array(e.target.result)
+                const fileBuffer = new buffer.Buffer(arr);
+                const fileSource = fileBuffer.toString();
+                // do something with the buffer!
+
+                  var entryName = file.fullPath.slice(1).split(".").join("_");
+                  let worldName = entryName.split("/")[0];
+                  let userPub = _LCSDB.user().is.pub;
+          
+                    //let modified = new Date().valueOf();
+                    let created = new Date().valueOf();
+          
+                    let obj = {
+                      'file': fileSource,
+                      'modified': created,
+                      'created': created
+          
+                    }
+
+                      world[worldName] = {
+                        'parent': '-',
+                        'owner': userPub,
+                        'featured': true,
+                        'published': true
+                      }
+                    
+          
+                    let entry = entryName.replace(worldName + '/', "");
+                    world[worldName][entry] = obj;
+                    console.log(world);
+
+                    worlds.put(world);
+                  
+              })
+              reader.addEventListener('error', err => {
+                console.error('FileReader error' + err)
+              })
+              reader.readAsArrayBuffer(file)
+
+            }
+
+            })
+            //console.log('Worlds', worldsObj);
+            console.log('files array', files)
+            console.log('FileList object', fileList)
+            console.log('directories array', directories)
+            self._refresh(directories.map(el=>{return el.name}).toString());
+          },
+          onDropText: function (text, pos) {
+            console.log('onDropText: ' + text + ' at ' + pos.x + ', ' + pos.y)
+          }
+        }
+        )
+      },
+      $update: function () {
+
+        this.$components = [
+          {
+            $type: "h5",
+            class: "mdc-typography--headline5",
+            $text: this._ddText
+          }
+        ]
+
+      }
+    }
+
+
     let userProfile = {
       $type: 'div',
       id: "profile",
       _status: "",
+      _refresh: function(status){
+        this._status = status;
+      },
       $init: function () {
         this._status = "user is not signed in..."
       },
       $update: function () {
+        var ddarea = {};
+
+        if(_LCSDB.user().is){
+          ddarea = dragDropWorldsArea
+        }
+
         this.$components = [
           {
-            $type: "h1",
-            class: "mdc-typography--headline4",
+            $type: "h3",
+            class: "mdc-typography--headline3",
             $text: this._status //"Profile for: " + this.db.user().is.alias
-          }
+          },
+          _app.widgets.divider,
+          {
+            $type: "h4",
+            class: "mdc-typography--headline4",
+            $text: 'Load my world\'s protos:' //"Profile for: " + this.db.user().is.alias
+          },
+          ddarea
         ]
       }
     }
 
+   
+
+
     document.querySelector("#userProfile").$cell({
       $cell: true,
       $type: "div",
@@ -2016,10 +2138,15 @@ class App {
       )
       .then(r => Promise.all(Object.keys(r).map(k => {
         let objEl = r[k][1];
+        if(objEl){
         let obj = Object.entries(objEl).filter(el => el[0].includes('_info_vwf_json'));
         if (obj) {
           return { world: r[k][0], states: obj }
         }
+      } else {
+        return { world: r[k][0], states: [] }
+      }
+
       }
 
       )

+ 13 - 0
public/lib/index.css

@@ -464,4 +464,17 @@ text-shadow: 0px 0px 0 rgba(0, 0, 0, 0.3);
 
 #hello {
   color: rgb(95, 95, 95)
+}
+
+
+.dragdropArea {
+  width: 400px;
+  height: 200px;
+  border-width: medium;
+  border: rgb(3, 81, 137);
+  border-style: dotted;
+}
+
+.drag {
+  border: 5px solid rgba(195, 0, 0, 0.751);
 }

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
public/lib/wt/buffer5.6.0.min.js


+ 447 - 0
public/lib/wt/drag-drop.js

@@ -0,0 +1,447 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.DragDrop = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things.  But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals.  It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+    throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+    throw new Error('clearTimeout has not been defined');
+}
+(function () {
+    try {
+        if (typeof setTimeout === 'function') {
+            cachedSetTimeout = setTimeout;
+        } else {
+            cachedSetTimeout = defaultSetTimout;
+        }
+    } catch (e) {
+        cachedSetTimeout = defaultSetTimout;
+    }
+    try {
+        if (typeof clearTimeout === 'function') {
+            cachedClearTimeout = clearTimeout;
+        } else {
+            cachedClearTimeout = defaultClearTimeout;
+        }
+    } catch (e) {
+        cachedClearTimeout = defaultClearTimeout;
+    }
+} ())
+function runTimeout(fun) {
+    if (cachedSetTimeout === setTimeout) {
+        //normal enviroments in sane situations
+        return setTimeout(fun, 0);
+    }
+    // if setTimeout wasn't available but was latter defined
+    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+        cachedSetTimeout = setTimeout;
+        return setTimeout(fun, 0);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedSetTimeout(fun, 0);
+    } catch(e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+            return cachedSetTimeout.call(null, fun, 0);
+        } catch(e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+            return cachedSetTimeout.call(this, fun, 0);
+        }
+    }
+
+
+}
+function runClearTimeout(marker) {
+    if (cachedClearTimeout === clearTimeout) {
+        //normal enviroments in sane situations
+        return clearTimeout(marker);
+    }
+    // if clearTimeout wasn't available but was latter defined
+    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+        cachedClearTimeout = clearTimeout;
+        return clearTimeout(marker);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedClearTimeout(marker);
+    } catch (e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
+            return cachedClearTimeout.call(null, marker);
+        } catch (e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+            return cachedClearTimeout.call(this, marker);
+        }
+    }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    if (!draining || !currentQueue) {
+        return;
+    }
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = runTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        runTimeout(drainQueue);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],2:[function(require,module,exports){
+(function (process){
+module.exports = runParallel
+
+function runParallel (tasks, cb) {
+  var results, pending, keys
+  var isSync = true
+
+  if (Array.isArray(tasks)) {
+    results = []
+    pending = tasks.length
+  } else {
+    keys = Object.keys(tasks)
+    results = {}
+    pending = keys.length
+  }
+
+  function done (err) {
+    function end () {
+      if (cb) cb(err, results)
+      cb = null
+    }
+    if (isSync) process.nextTick(end)
+    else end()
+  }
+
+  function each (i, err, result) {
+    results[i] = result
+    if (--pending === 0 || err) {
+      done(err)
+    }
+  }
+
+  if (!pending) {
+    // empty
+    done(null)
+  } else if (keys) {
+    // object
+    keys.forEach(function (key) {
+      tasks[key](function (err, result) { each(key, err, result) })
+    })
+  } else {
+    // array
+    tasks.forEach(function (task, i) {
+      task(function (err, result) { each(i, err, result) })
+    })
+  }
+
+  isSync = false
+}
+
+}).call(this,require('_process'))
+},{"_process":1}],"/":[function(require,module,exports){
+module.exports = dragDrop
+
+const parallel = require('run-parallel')
+
+function dragDrop (elem, listeners) {
+  if (typeof elem === 'string') {
+    const selector = elem
+    elem = window.document.querySelector(elem)
+    if (!elem) {
+      throw new Error(`"${selector}" does not match any HTML elements`)
+    }
+  }
+
+  if (!elem) {
+    throw new Error(`"${elem}" is not a valid HTML element`)
+  }
+
+  if (typeof listeners === 'function') {
+    listeners = { onDrop: listeners }
+  }
+
+  let timeout
+
+  elem.addEventListener('dragenter', onDragEnter, false)
+  elem.addEventListener('dragover', onDragOver, false)
+  elem.addEventListener('dragleave', onDragLeave, false)
+  elem.addEventListener('drop', onDrop, false)
+
+  // Function to remove drag-drop listeners
+  return function remove () {
+    removeDragClass()
+    elem.removeEventListener('dragenter', onDragEnter, false)
+    elem.removeEventListener('dragover', onDragOver, false)
+    elem.removeEventListener('dragleave', onDragLeave, false)
+    elem.removeEventListener('drop', onDrop, false)
+  }
+
+  function onDragEnter (e) {
+    if (listeners.onDragEnter) {
+      listeners.onDragEnter(e)
+    }
+
+    // Prevent event
+    e.stopPropagation()
+    e.preventDefault()
+    return false
+  }
+
+  function onDragOver (e) {
+    e.stopPropagation()
+    e.preventDefault()
+
+    if (listeners.onDragOver) {
+      listeners.onDragOver(e)
+    }
+
+    if (e.dataTransfer.items) {
+      // Only add "drag" class when `items` contains items that are able to be
+      // handled by the registered listeners (files vs. text)
+      const items = Array.from(e.dataTransfer.items)
+      const fileItems = items.filter(item => { return item.kind === 'file' })
+      const textItems = items.filter(item => { return item.kind === 'string' })
+
+      if (fileItems.length === 0 && !listeners.onDropText) return
+      if (textItems.length === 0 && !listeners.onDrop) return
+      if (fileItems.length === 0 && textItems.length === 0) return
+    }
+
+    elem.classList.add('drag')
+    clearTimeout(timeout)
+
+    e.dataTransfer.dropEffect = 'copy'
+
+    return false
+  }
+
+  function onDragLeave (e) {
+    e.stopPropagation()
+    e.preventDefault()
+
+    if (listeners.onDragLeave) {
+      listeners.onDragLeave(e)
+    }
+
+    clearTimeout(timeout)
+    timeout = setTimeout(removeDragClass, 50)
+
+    return false
+  }
+
+  function onDrop (e) {
+    e.stopPropagation()
+    e.preventDefault()
+
+    if (listeners.onDragLeave) {
+      listeners.onDragLeave(e)
+    }
+
+    clearTimeout(timeout)
+    removeDragClass()
+
+    const pos = {
+      x: e.clientX,
+      y: e.clientY
+    }
+
+    // text drop support
+    const text = e.dataTransfer.getData('text')
+    if (text && listeners.onDropText) {
+      listeners.onDropText(text, pos)
+    }
+
+    // File drop support. The `dataTransfer.items` API supports directories, so we
+    // use it instead of `dataTransfer.files`, even though it's much more
+    // complicated to use.
+    // See: https://github.com/feross/drag-drop/issues/39
+    if (listeners.onDrop && e.dataTransfer.items) {
+      const fileList = e.dataTransfer.files
+
+      // Handle directories in Chrome using the proprietary FileSystem API
+      const items = Array.from(e.dataTransfer.items).filter(item => {
+        return item.kind === 'file'
+      })
+
+      if (items.length === 0) return
+
+      parallel(items.map(item => {
+        return cb => {
+          processEntry(item.webkitGetAsEntry(), cb)
+        }
+      }), (err, results) => {
+        // This catches permission errors with file:// in Chrome. This should never
+        // throw in production code, so the user does not need to use try-catch.
+        if (err) throw err
+
+        const entries = results.flat(Infinity)
+
+        const files = entries.filter(item => {
+          return item.isFile
+        })
+
+        const directories = entries.filter(item => {
+          return item.isDirectory
+        })
+
+        listeners.onDrop(files, pos, fileList, directories)
+      })
+    }
+
+    return false
+  }
+
+  function removeDragClass () {
+    elem.classList.remove('drag')
+  }
+}
+
+function processEntry (entry, cb) {
+  let entries = []
+
+  if (entry.isFile) {
+    entry.file(file => {
+      file.fullPath = entry.fullPath // preserve pathing for consumer
+      file.isFile = true
+      file.isDirectory = false
+      cb(null, file)
+    }, err => {
+      cb(err)
+    })
+  } else if (entry.isDirectory) {
+    const reader = entry.createReader()
+    readEntries(reader)
+  }
+
+  function readEntries (reader) {
+    reader.readEntries(entries_ => {
+      if (entries_.length > 0) {
+        entries = entries.concat(Array.from(entries_))
+        readEntries(reader) // continue reading entries until `readEntries` returns no more
+      } else {
+        doneEntries()
+      }
+    })
+  }
+
+  function doneEntries () {
+    parallel(entries.map(entry => {
+      return cb => {
+        processEntry(entry, cb)
+      }
+    }), (err, results) => {
+      if (err) {
+        cb(err)
+      } else {
+        results.push({
+          fullPath: entry.fullPath,
+          name: entry.name,
+          isFile: false,
+          isDirectory: true
+        })
+        cb(null, results)
+      }
+    })
+  }
+}
+
+},{"run-parallel":2}]},{},[])("/")
+});

+ 2 - 0
public/loadLibs.js

@@ -11,6 +11,8 @@ loadjs([
     '/lib/mdc/dist/material-components-web.min.js',
     '/lib/ace/ace.js',
     '/lib/yamljs/dist/yaml.js',
+    '/lib/wt/drag-drop.js',
+    '/lib/wt/buffer5.6.0.min.js'
 ],'forall', {
     async: false
 });

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio