From b07ed6868895f883640fc003ba4f5cc108c27b3e Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 13 Aug 2014 18:30:28 -0400 Subject: pull in minotaur --- public/assets/javascripts/ui/_router.js | 1 + 1 file changed, 1 insertion(+) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index d07810e..794079e 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -27,6 +27,7 @@ var SiteRouter = Router.extend({ "/profile": 'profile', "/profile/edit": 'editProfile', + "/profile/:name": 'profile', "/about/:name/edit": 'editDocument', "/about/new": 'newDocument', -- cgit v1.2.3-70-g09d2 From 410607684c7273a61f937635b41397208e245473 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 14 Aug 2014 13:57:42 -0400 Subject: autosave --- .../javascripts/rectangles/engine/scenery/move.js | 8 ++- .../rectangles/engine/scenery/resize.js | 3 + .../javascripts/rectangles/engine/scenery/undo.js | 18 ++++++ .../assets/javascripts/rectangles/models/wall.js | 3 + .../assets/javascripts/rectangles/util/minotaur.js | 67 ++++++++++++---------- .../javascripts/ui/builder/BuilderSettings.js | 3 + .../assets/javascripts/ui/editor/EditorSettings.js | 10 +++- public/assets/javascripts/ui/editor/MediaEditor.js | 1 + public/assets/javascripts/ui/lib/FormView.js | 28 +++++++-- public/assets/javascripts/ui/lib/View.js | 17 +++--- views/partials/scripts.ejs | 1 + 11 files changed, 111 insertions(+), 48 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/engine/scenery/move.js b/public/assets/javascripts/rectangles/engine/scenery/move.js index c3f78d7..edeb24b 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/move.js +++ b/public/assets/javascripts/rectangles/engine/scenery/move.js @@ -30,6 +30,9 @@ Scenery.move = function(base){ redo: { id: base.id }, }) + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) + Scenery.remove(base.id) return } @@ -81,7 +84,10 @@ Scenery.move = function(base){ undo: oldState, redo: base.serialize(), }) - + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) + oldState = null } diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index c5c754a..6b2e52c 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -200,6 +200,9 @@ Scenery.resize = new function(){ redo: obj.serialize(), }) + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) + document.body.classList.remove("dragging") } diff --git a/public/assets/javascripts/rectangles/engine/scenery/undo.js b/public/assets/javascripts/rectangles/engine/scenery/undo.js index 7798550..54ab755 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/undo.js +++ b/public/assets/javascripts/rectangles/engine/scenery/undo.js @@ -4,9 +4,15 @@ type: "create-scenery", undo: function(state){ Scenery.remove(state.id) + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) }, redo: function(state){ Scenery.deserialize([ state ]) + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) }, }, { @@ -19,6 +25,9 @@ if (editor.permissions.resize) { Scenery.resize.show(scenery) } + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) }, redo: function(state){ var scenery = Scenery.find(state.id) @@ -30,15 +39,24 @@ Scenery.resize.rotate_dots() Scenery.resize.move_dots() } + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) }, }, { type: "destroy-scenery", undo: function(state){ Scenery.deserialize([ state ]) + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) }, redo: function(state){ Scenery.remove(state.id) + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) }, }, diff --git a/public/assets/javascripts/rectangles/models/wall.js b/public/assets/javascripts/rectangles/models/wall.js index 6e2c728..fa09444 100644 --- a/public/assets/javascripts/rectangles/models/wall.js +++ b/public/assets/javascripts/rectangles/models/wall.js @@ -50,6 +50,9 @@ window.Wall = (function(){ undo: { id: scenery.id }, redo: scenery.serialize(), }) + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) } else if (Scenery.nextWallpaper) { base.wallpaper() diff --git a/public/assets/javascripts/rectangles/util/minotaur.js b/public/assets/javascripts/rectangles/util/minotaur.js index 6eb36ec..039a053 100644 --- a/public/assets/javascripts/rectangles/util/minotaur.js +++ b/public/assets/javascripts/rectangles/util/minotaur.js @@ -1,54 +1,59 @@ (function(){ var Monitor = function () { - var base = this; - base.$el = $("#minotaur"); - base.timeout = null; - base.delay = 500; - base.objects = {}; + var base = this + base.$el = $("#minotaur") + base.timeout = null + base.delay = 500 + base.objects = {} base.init = function () { - base.$el.addClass('saved'); - base.$el.click(base.save); + base.$el.removeClass() + base.$el.click(base.save) } base.watch = function (object) { - base.objects[object.type] = base.objects[object.type] || {}; - base.objects[object.type][object.id] = object; - base.clear(); - base.timeout = setTimeout(base.save, base.delay); + base.objects[object.type] = base.objects[object.type] || {} + base.objects[object.type][object._id] = object + base.clear() + base.timeout = setTimeout(base.save, base.delay) + } + + base.unwatch = function (object) { + if (base.objects[object.type] && base.objects[object.type][object._id]) { + delete base.objects[object.type][object._id] + } } base.clear = function () { - if (base.timeout) clearTimeout(base.timeout); - base.timeout = false; + if (base.timeout) clearTimeout(base.timeout) + base.timeout = false } base.save = function () { - var saving = false; - base.clear(); + var saving = false + base.clear() for (var type in base.objects) { for (var id in base.objects[type]) { - if (base.timeout) - return; - var obj = base.objects[type][id]; - if (obj) obj.save(function(){ - base.$el.removeClass('unsaved saving').addClass('saved'); - saving = true; - }); - base.objects[type][id] = false; + var obj = base.objects[type][id] + if (obj) { + obj.save(null, function(){ base.hide() }, function(){}) + } + delete base.objects[type][id] + saving = true } } - if (saving) { - base.$el.removeClass('unsaved saved').addClass('saving'); - } - else { - base.$el.removeClass('unsaved saving').addClass('saved'); - } - - base.objects = {}; + saving ? base.show() : base.hide() + } + + base.show = function () { + base.$el.removeClass().addClass('saving') + } + + base.hide = function () { + base.$el.removeClass() } base.init(); diff --git a/public/assets/javascripts/ui/builder/BuilderSettings.js b/public/assets/javascripts/ui/builder/BuilderSettings.js index c551f95..0091454 100644 --- a/public/assets/javascripts/ui/builder/BuilderSettings.js +++ b/public/assets/javascripts/ui/builder/BuilderSettings.js @@ -122,6 +122,9 @@ var BuilderSettings = FormView.extend({ this.$name.val(data.name) this.action = this.updateAction + Minotaur.unwatch(this) + Minotaur.hide() + window.history.pushState(null, document.title, "/layout/" + data.slug) }, diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js index d6a79fb..9d75f66 100644 --- a/public/assets/javascripts/ui/editor/EditorSettings.js +++ b/public/assets/javascripts/ui/editor/EditorSettings.js @@ -5,7 +5,7 @@ var EditorSettings = FormView.extend({ createAction: "/api/project/new", updateAction: "/api/project/edit", destroyAction: "/api/project/destroy", - + events: { "keydown": 'stopPropagation', "keydown [name=name]": 'enterSubmit', @@ -32,7 +32,10 @@ var EditorSettings = FormView.extend({ data.rooms && Rooms.deserialize(data.rooms) data.startPosition && scene.camera.move(data.startPosition) - if (! data.isNew) { + if (data.isNew) { + this.$name.val( "Room " + moment().format("DD/MM/YYYY ha") ) + } + else { // console.log(data) this.$id.val( data._id ) @@ -130,6 +133,9 @@ var EditorSettings = FormView.extend({ this.$name.val(data.name) this.action = this.updateAction + Minotaur.unwatch(this) + Minotaur.hide() + window.history.pushState(null, document.title, "/project/" + data.slug + "/edit") }, diff --git a/public/assets/javascripts/ui/editor/MediaEditor.js b/public/assets/javascripts/ui/editor/MediaEditor.js index e3a8f2e..cc924da 100644 --- a/public/assets/javascripts/ui/editor/MediaEditor.js +++ b/public/assets/javascripts/ui/editor/MediaEditor.js @@ -4,6 +4,7 @@ var MediaEditor = FormView.extend({ events: { "keydown": 'stopPropagation', + "focus [name]": "clearMinotaur", "click [data-role=play-media]": "togglePaused", "mousedown [name=keyframe]": "stopPropagation", "mousedown": "stopPropagation", diff --git a/public/assets/javascripts/ui/lib/FormView.js b/public/assets/javascripts/ui/lib/FormView.js index 219952d..ab33bc0 100644 --- a/public/assets/javascripts/ui/lib/FormView.js +++ b/public/assets/javascripts/ui/lib/FormView.js @@ -54,15 +54,20 @@ var FormView = View.extend({ return fd }, - save: function(e){ - e.preventDefault() + save: function(e, successCallback, errorCallback){ + e && e.preventDefault() this.$errors.hide().css("opacity", 0.0); if (this.validate) { var errors = this.validate() if (errors && errors.length) { - this.showErrors(errors) + if (errorCallback) { + errorCallback(errors) + } + else { + this.showErrors(errors) + } return } } @@ -74,18 +79,29 @@ var FormView = View.extend({ dataType: "json", processData: false, contentType: false, - }); + }) + request.done($.proxy(function (response) { if (response.error) { var errors = [] for (var key in response.error.errors) { errors.push(response.error.errors[key].message); } - this.showErrors(errors) + if (errorCallback) { + errorCallback(errors) + } + else { + this.showErrors(errors) + } return } else { - this.success && this.success(response) + if (successCallback) { + successCallback(response) + } + if (this.success) { + this.success(response) + } } }, this)); } diff --git a/public/assets/javascripts/ui/lib/View.js b/public/assets/javascripts/ui/lib/View.js index 999a0e5..d94e6db 100644 --- a/public/assets/javascripts/ui/lib/View.js +++ b/public/assets/javascripts/ui/lib/View.js @@ -1,13 +1,14 @@ var View = (function($, _){ var View = function(options) { - this.cid = _.uniqueId('view'); + this._id = _.uniqueId('view') + this.type = "view" options || (options = {}); - _.extend(this, _.pick(options, viewOptions)); - this._ensureElement(); - this.initialize.apply(this, arguments); - this.delegateEvents(); - }; + _.extend(this, _.pick(options, viewOptions)) + this._ensureElement() + this.initialize.apply(this, arguments) + this.delegateEvents() + } var delegateEventSplitter = /^(\S+)\s*(.*)$/; @@ -58,7 +59,7 @@ var View = (function($, _){ var match = key.match(delegateEventSplitter); var eventName = match[1], selector = match[2]; method = _.bind(method, this); - eventName += '.delegateEvents' + this.cid; + eventName += '.delegateEvents' + this._id; if (selector === '') { this.$el.on(eventName, method); } else { @@ -70,7 +71,7 @@ var View = (function($, _){ // Clears all callbacks previously bound to the view with `delegateEvents`. undelegateEvents: function() { - this.$el.off('.delegateEvents' + this.cid); + this.$el.off('.delegateEvents' + this._id); return this; }, diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index dfb3a83..4839de8 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -30,6 +30,7 @@ + -- cgit v1.2.3-70-g09d2 From 63da3ba331aa3d9714151ba5f502e6e1851d75bb Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 14 Aug 2014 15:21:48 -0400 Subject: only clobber thumbnail if layout changed --- .../assets/javascripts/ui/editor/EditorSettings.js | 19 ++++++++++++++++-- server/lib/api/projects.js | 23 +++++++++++++--------- 2 files changed, 31 insertions(+), 11 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js index 9d75f66..e9239e4 100644 --- a/public/assets/javascripts/ui/editor/EditorSettings.js +++ b/public/assets/javascripts/ui/editor/EditorSettings.js @@ -37,11 +37,12 @@ var EditorSettings = FormView.extend({ } else { // console.log(data) + this.thumbnailIsStale() this.$id.val( data._id ) this.$name.val( data.name ) this.$description.val( data.description ) - data.privacy && this.$privacy.find("[value=" + data.privacy + "]").prop('checked', "checked") + data.privacy && this.$privacy.find("[value=" + data.privacy + "]").prop("checked", "checked") data.media && Scenery.deserialize(data.media) } @@ -124,10 +125,24 @@ var EditorSettings = FormView.extend({ fd.append( "walls", JSON.stringify( Rooms.serializeWalls() ) ) fd.append( "media", JSON.stringify( Scenery.serialize() ) ) fd.append( "startPosition", JSON.stringify( app.position(scene.camera) ) ) - fd.append( "thumbnail", dataUriToBlob(map.canvas.toDataURL()) ) + + if (this.thumbnailIsStale()) { + fd.append( "thumbnail", dataUriToBlob(map.canvas.toDataURL()) ) + } return fd }, + thumbnailState: null, + thumbnailIsStale: function(){ + var newState = JSON.stringify( Rooms.serialize() ) + + if (newState !== this.thumbnailState) { + this.thumbnailState = newState + return true + } + return false + }, + success: function(data){ this.$id.val(data._id) this.$name.val(data.name) diff --git a/server/lib/api/projects.js b/server/lib/api/projects.js index fc54a5f..bd3cb81 100644 --- a/server/lib/api/projects.js +++ b/server/lib/api/projects.js @@ -72,15 +72,20 @@ var projects = { data.slug = util.slugify(data.name) data.description = util.sanitize(data.description) - upload.put("projects", req.files.thumbnail, { - unacceptable: function(err){ - res.json({ error: { errors: { thumbnail: { message: "Problem saving thumbnail: " + err } } } }) - }, - success: function(url){ - data.photo = url - done() - } - }) + if (req.files.thumbnail) { + upload.put("projects", req.files.thumbnail, { + unacceptable: function(err){ + res.json({ error: { errors: { thumbnail: { message: "Problem saving thumbnail: " + err } } } }) + }, + success: function(url){ + data.photo = url + done() + } + }) + } + else { + done() + } function done() { Project.findOne({ _id: _id }, function(err, doc){ -- cgit v1.2.3-70-g09d2 From 4ec4b0e42c06b63962658ae8b886ee9466d09a21 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Fri, 22 Aug 2014 12:54:27 -0400 Subject: reject image if it doesnt fit --- .../assets/javascripts/mx/primitives/mx.image.js | 3 ++- .../rectangles/engine/scenery/_scenery.js | 14 +++++++---- .../rectangles/engine/scenery/types/_object.js | 5 +--- .../rectangles/engine/scenery/types/image.js | 11 ++++++++- .../javascripts/rectangles/models/surface.js | 3 --- .../assets/javascripts/rectangles/models/wall.js | 25 +++++++++----------- public/assets/javascripts/ui/editor/MediaViewer.js | 27 ++++++++++++++-------- 7 files changed, 51 insertions(+), 37 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/mx/primitives/mx.image.js b/public/assets/javascripts/mx/primitives/mx.image.js index a640620..575e9c0 100644 --- a/public/assets/javascripts/mx/primitives/mx.image.js +++ b/public/assets/javascripts/mx/primitives/mx.image.js @@ -10,7 +10,7 @@ MX.Image = MX.Object3D.extend({ this.z = ops.z || 0 this.scale = ops.scale || 1 this.backface = ops.backface || false - + ops.className && this.el.classList.add(ops.className) this.backface && this.el.classList.add("backface-visible") this.el.classList.add("image") @@ -27,6 +27,7 @@ MX.Image = MX.Object3D.extend({ var image = new Image() image.onload = function(){ + if (! layer.ops) return layer.scale = layer.ops.scale || 1 layer.width = layer.ops.width || image.naturalWidth layer.height = layer.ops.height || image.naturalHeight diff --git a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js index 58592d4..119391d 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js +++ b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js @@ -35,8 +35,14 @@ var Scenery = new function(){ var scene_media = base.add(opt) // test if scenery was placed here - base.nextMedia = null - return scene_media + if (! scene_media.bounds) { + base.remove( scene_media.id ) + return null + } + else { + base.nextMedia = null + return scene_media + } } base.find = function(id){ @@ -44,9 +50,9 @@ var Scenery = new function(){ } base.remove = function(id){ - var media = base.list[id] + var scene_media = base.list[id] delete base.list[id] - media && media.destroy() + scene_media && scene_media.destroy() } base.uid = new UidGenerator(base.list) diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js index 7b716f6..effee2a 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js @@ -28,14 +28,11 @@ Scenery.types.base = Fiber.extend(function(base){ }, recenter: function () { + if (! this.bounds) return var center = this.bounds.center() center.a -= this.dimensions.a / 2 center.b -= this.dimensions.b / 2 - console.log(center+"") var mx_position = this.wall.positionToMx( center, this.dimensions ) - console.log(mx_position) - console.log(this.wall.surface.faces.join("\n")) - // also supply scale? this.mx.move(mx_position) this.position.assign(center) }, diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/image.js b/public/assets/javascripts/rectangles/engine/scenery/types/image.js index 1582e0f..3bee827 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/image.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/image.js @@ -12,11 +12,20 @@ Scenery.types.image = Scenery.types.base.extend(function(base){ this.bind() if (opt.data) { + console.log(opt.wall) + // console.log(opt.data.position) + if (opt.wall) { + var position = opt.wall.mxToPosition(opt.data.position) + console.log(position.a) + opt.index = opt.wall.surface.index_for_x( position.a, 0 ) + console.log(opt.index) + } + this.set_wall(opt) this.deserialize(opt.data) } else { this.set_wall(opt) - this.recenter() + this.bounds && this.recenter() } }, diff --git a/public/assets/javascripts/rectangles/models/surface.js b/public/assets/javascripts/rectangles/models/surface.js index a700fd4..9c45eaf 100644 --- a/public/assets/javascripts/rectangles/models/surface.js +++ b/public/assets/javascripts/rectangles/models/surface.js @@ -150,9 +150,6 @@ Surface.prototype.index_for_x = function(x, min_i){ min_i = min_i || 0 - if (x < 0 || x > this.width) { - return -1 - } for (var i = min_i; i < this.faces.length; i++) { if (this.faces[i].x.contains(x)) { return i diff --git a/public/assets/javascripts/rectangles/models/wall.js b/public/assets/javascripts/rectangles/models/wall.js index a8bcbd8..f6742ad 100644 --- a/public/assets/javascripts/rectangles/models/wall.js +++ b/public/assets/javascripts/rectangles/models/wall.js @@ -51,9 +51,7 @@ }, mousemove: function(e){ }, - mousedown: function(){ - // base.randomize_colors() - // console.log(sidesToString(base.side)) + mousedown: function(e){ if (Scenery.nextMedia) { var scenery = Scenery.addNextToWall({ wall: base, @@ -61,7 +59,10 @@ }) // scenery was not placed - if (! scenery) return + if (! scenery) { + e.stopPropagation() + return + } UndoStack.push({ type: 'create-scenery', @@ -125,22 +126,18 @@ var position = new vec2(0,0) switch (this.side) { case FRONT: - position.a = mx.x - mx.width / 2 - position.b = mx.y - mx.height / 2 - break case BACK: - position.a = mx.x - mx.width / 2 - position.b = mx.y - mx.height / 2 + position.a = mx.x + position.b = mx.y break case LEFT: - position.a = mx.z - mx.width / 2 - position.b = mx.y - mx.height / 2 - break case RIGHT: - position.a = mx.z - mx.width / 2 - position.b = mx.y - mx.height / 2 + position.a = mx.z + position.b = mx.y break } +// if (mx.width) { position.a -= mx.width / 2 } +// if (mx.height) { position.b -= mx.height / 2 } return position } diff --git a/public/assets/javascripts/ui/editor/MediaViewer.js b/public/assets/javascripts/ui/editor/MediaViewer.js index 5540023..40bfe80 100644 --- a/public/assets/javascripts/ui/editor/MediaViewer.js +++ b/public/assets/javascripts/ui/editor/MediaViewer.js @@ -133,7 +133,9 @@ var MediaViewer = ModalView.extend({ var $floatingImg = $('.floatingImg'); Scenery.nextMedia = media - console.log(media.type) + +// console.log(media.type) + switch (media.type) { case "video": $floatingImg.attr('src', '/assets/img/playbutton.png') @@ -150,18 +152,23 @@ var MediaViewer = ModalView.extend({ function _followCursor(e) { $floatingImg.parent().css({ top: (e.pageY - (height / 2)) + 'px', - left: (e.pageX - (width / 2)) + 'px' + left: (e.pageX - (width / 2)) + 'px', }); } - $(window).on('mousemove', _followCursor); - $(window).one('click', function () { + function _hideCursor (e) { + if (Scenery.nextMedia) { + return + } var $floatingImg = $('.floatingImg') - $floatingImg.attr('src', ''); - $(window).off('mousemove', _followCursor); - $floatingImg.parent().removeClass('edit'); - }); - $ants.addClass('edit'); - _followCursor(e); + $floatingImg.attr('src', '') + $(window).off('mousemove', _followCursor) + $(window).off('mousedown', _hideCursor) + $floatingImg.parent().removeClass('edit') + } + $(window).on('mousemove', _followCursor) + $(window).on('mousedown', _hideCursor) + $ants.addClass('edit') + _followCursor(e) }, }) -- cgit v1.2.3-70-g09d2