From 0bf50fee4d35467c5335cbaf6c1ca3b7ae2dd1e4 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 12 Aug 2014 16:01:42 -0400 Subject: different ui on map editor --- public/assets/javascripts/ui/builder/BuilderToolbar.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/builder/BuilderToolbar.js b/public/assets/javascripts/ui/builder/BuilderToolbar.js index df98ab0..239b05e 100644 --- a/public/assets/javascripts/ui/builder/BuilderToolbar.js +++ b/public/assets/javascripts/ui/builder/BuilderToolbar.js @@ -6,9 +6,9 @@ var BuilderToolbar = View.extend({ "click [data-role='toggle-map-view']": 'toggleMap', "click [data-role='toggle-layout-settings']": 'toggleSettings', "click [data-role='undo']": 'undo', - "click [data-role='create-mode']": 'create', - "click [data-role='resize-mode']": 'resize', - "click [data-role='move-mode']": 'move', +// "click [data-role='create-mode']": 'create', +// "click [data-role='resize-mode']": 'resize', +// "click [data-role='move-mode']": 'move', "click [data-role='destroy-mode']": 'destroy', }, @@ -27,7 +27,8 @@ var BuilderToolbar = View.extend({ undo: function(){ }, - + +/* create: function(e){ var state = map.ui.permissions.toggle("create") $(".inuse").removeClass("inuse") @@ -45,7 +46,8 @@ var BuilderToolbar = View.extend({ $(".inuse").removeClass("inuse") $(e.currentTarget).toggleClass("inuse", state) }, - +*/ + destroy: function(e){ var state = map.ui.permissions.toggle("destroy") $(".inuse").removeClass("inuse") -- cgit v1.2.3-70-g09d2 From 838ccfe6c2125e464d3c95c6e222e7e762dc8fd2 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 12 Aug 2014 18:19:33 -0400 Subject: undo stack for undo/redo --- public/assets/javascripts/rectangles/_env.js | 14 +++++++++ .../javascripts/rectangles/engine/map/ui_editor.js | 21 +++++++++++-- .../javascripts/rectangles/engine/scenery/undo.js | 34 +++++++++++++++++----- .../assets/javascripts/rectangles/models/rect.js | 4 +++ .../assets/javascripts/rectangles/models/room.js | 8 +++++ .../assets/javascripts/rectangles/models/vec2.js | 4 +++ .../assets/javascripts/rectangles/models/wall.js | 2 -- public/assets/javascripts/rectangles/util/keys.js | 6 ++-- .../javascripts/rectangles/util/permissions.js | 13 ++++++--- .../javascripts/ui/builder/BuilderToolbar.js | 9 +++++- views/partials/scripts.ejs | 2 ++ 11 files changed, 98 insertions(+), 19 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/_env.js b/public/assets/javascripts/rectangles/_env.js index 3cfe969..4b14a21 100644 --- a/public/assets/javascripts/rectangles/_env.js +++ b/public/assets/javascripts/rectangles/_env.js @@ -35,6 +35,20 @@ environment.init = function(){ zoom: -4.8 }) } + + keys.on("z", function(e){ + e.preventDefault() + if (e.ctrlKey || e.metaKey) { + if (e.shiftKey) { + var canRedo = UndoStack.redo() + console.log("can redo", canRedo) + } + else { + var canUndo = UndoStack.undo() + console.log("can undo", canUndo) + } + } + }) } environment.update = function(t){ map.update() diff --git a/public/assets/javascripts/rectangles/engine/map/ui_editor.js b/public/assets/javascripts/rectangles/engine/map/ui_editor.js index 016a8ad..4b5f784 100644 --- a/public/assets/javascripts/rectangles/engine/map/ui_editor.js +++ b/public/assets/javascripts/rectangles/engine/map/ui_editor.js @@ -30,6 +30,7 @@ Map.UI.Editor = function(map){ // function down (e, cursor){ + var room cursor.x.div(map.dimensions.a).add(0.5).mul(map.dimensions.a / map.zoom).add(map.center.a) cursor.y.div(map.dimensions.b).sub(0.5).mul(map.dimensions.b / map.zoom).sub(map.center.b) @@ -52,8 +53,17 @@ Map.UI.Editor = function(map){ if (intersects.length && base.permissions.destroy) { base.mouse.down = false - Rooms.remove(intersects[0]) - app.tube("builder-destroy-room", intersects[0]) + + room = intersects[0] + + UndoStack.push({ + type: "destroy-room", + prev: room.clone(), + next: { id: room.id }, + }) + + Rooms.remove(room) + app.tube("builder-destroy-room", room) return } else if (intersects.length) { @@ -151,6 +161,13 @@ Map.UI.Editor = function(map){ cursor.x.abs().quantize(1) cursor.y.abs().quantize(1) var room = Rooms.add_with_rect( cursor ) + + UndoStack.push({ + type: "create-room", + prev: { id: room.id }, + next: room.clone() + }) + app.tube("builder-pick-room", room) } } diff --git a/public/assets/javascripts/rectangles/engine/scenery/undo.js b/public/assets/javascripts/rectangles/engine/scenery/undo.js index fb221f5..b10a101 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/undo.js +++ b/public/assets/javascripts/rectangles/engine/scenery/undo.js @@ -25,24 +25,44 @@ // { - type: "create-rectangle", - undo: function(state){ + type: "create-room", + undo: function(room){ + Rooms.remove(room) + Rooms.clipper.update() }, - redo: function(state){ + redo: function(room){ + Rooms.add(room) + Rooms.clipper.update() + app.tube("builder-pick-room", room) }, }, { - type: "update-rectangle", + type: "update-room", undo: function(state){ + var room = Rooms.list[state.id] + room.rect.assign( state.rect ) + room.height = state.height + Rooms.clipper.update() + app.tube("builder-pick-room", room) }, redo: function(state){ + var room = Rooms.list[state.id] + room.rect.assign( state.rect ) + room.height = state.height + Rooms.clipper.update() + app.tube("builder-pick-room", room) }, }, { - type: "destroy-rectangle", - undo: function(state){ + type: "destroy-room", + undo: function(room){ + Rooms.add(room) + Rooms.clipper.update() + app.tube("builder-pick-room", room) }, - redo: function(state){ + redo: function(room){ + Rooms.remove(room) + Rooms.clipper.update() }, }, diff --git a/public/assets/javascripts/rectangles/models/rect.js b/public/assets/javascripts/rectangles/models/rect.js index 58469bc..0642a65 100644 --- a/public/assets/javascripts/rectangles/models/rect.js +++ b/public/assets/javascripts/rectangles/models/rect.js @@ -39,6 +39,10 @@ Rect.prototype.clone = function(){ return new Rect( this.x.clone(), this.y.clone() ) } + Rect.prototype.assign = function(r) { + this.x.copy(r.x) + this.y.copy(r.y) + } Rect.prototype.center = function(){ return new vec2(this.x.midpoint(), this.y.midpoint()) } diff --git a/public/assets/javascripts/rectangles/models/room.js b/public/assets/javascripts/rectangles/models/room.js index c2850ba..6c0e1bb 100644 --- a/public/assets/javascripts/rectangles/models/room.js +++ b/public/assets/javascripts/rectangles/models/room.js @@ -40,6 +40,14 @@ this.focused = false } + Room.prototype.clone = function(){ + return new Room ({ + id: this.id, + rect: this.rect.clone(), + height: this.height, + }) + } + Room.prototype.toString = function(){ return this.rect.toString() } diff --git a/public/assets/javascripts/rectangles/models/vec2.js b/public/assets/javascripts/rectangles/models/vec2.js index 104c6f7..214feb9 100644 --- a/public/assets/javascripts/rectangles/models/vec2.js +++ b/public/assets/javascripts/rectangles/models/vec2.js @@ -17,6 +17,10 @@ vec2.prototype.clone = function(){ return new vec2(this.a, this.b) } + vec2.prototype.assign = function(v){ + this.a = v.a + this.b = v.b + } vec2.prototype.abs = function(){ if (this.b < this.a) { this.invert() diff --git a/public/assets/javascripts/rectangles/models/wall.js b/public/assets/javascripts/rectangles/models/wall.js index 027d5f5..91e7c18 100644 --- a/public/assets/javascripts/rectangles/models/wall.js +++ b/public/assets/javascripts/rectangles/models/wall.js @@ -146,8 +146,6 @@ window.Wall = (function(){ if (shouldFlip) { sortedWalls = sortedWalls.reverse() } - -console.log(sortedWalls.map(function(z){return useX ? z.x : z.z}).join(" ")) var len = sortedWalls.length diff --git a/public/assets/javascripts/rectangles/util/keys.js b/public/assets/javascripts/rectangles/util/keys.js index 5a5c9d2..62d763f 100644 --- a/public/assets/javascripts/rectangles/util/keys.js +++ b/public/assets/javascripts/rectangles/util/keys.js @@ -19,7 +19,7 @@ var keys = (function(){ break; default: if (keys.debug) console.log(key) - base.tube(key) + base.tube(key, e) break; } }) @@ -158,8 +158,8 @@ var keys = (function(){ 'backslash' : '220', 'closebracket' : '221', 'single_quote' : '222' - } - var KEY_NAMES = invert_hash(KEYCODES) + }, + KEY_NAMES = invert_hash(KEYCODES) return base })() \ No newline at end of file diff --git a/public/assets/javascripts/rectangles/util/permissions.js b/public/assets/javascripts/rectangles/util/permissions.js index 394b7d6..1b5a1b5 100644 --- a/public/assets/javascripts/rectangles/util/permissions.js +++ b/public/assets/javascripts/rectangles/util/permissions.js @@ -26,14 +26,12 @@ Permissions.prototype.assign = function (key, state) { Permissions.prototype.add = function (key) { var base = this - base[op] = true - return state + base[key] = true } Permissions.prototype.remove = function (key) { var base = this - base[op] = true - return state + base[key] = true } Permissions.prototype.clear = function () { @@ -42,3 +40,10 @@ Permissions.prototype.clear = function () { base[op] = false }) } + +Permissions.prototype.log = function () { + var base = this + base.keys.forEach(function(op){ + console.log(op, base[op]) + }) +} \ No newline at end of file diff --git a/public/assets/javascripts/ui/builder/BuilderToolbar.js b/public/assets/javascripts/ui/builder/BuilderToolbar.js index 239b05e..2eb7590 100644 --- a/public/assets/javascripts/ui/builder/BuilderToolbar.js +++ b/public/assets/javascripts/ui/builder/BuilderToolbar.js @@ -14,7 +14,14 @@ var BuilderToolbar = View.extend({ initialize: function(opt){ this.parent = opt.parent - map.ui.permissions.toggle() + this.resetPermissions() + }, + + resetPermissions: function(){ + map.ui.permissions.clear() + map.ui.permissions.add("create") + map.ui.permissions.add("move") + map.ui.permissions.add("resize") }, toggleMap: function(){ diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index a1f51ef..b63d1bf 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -28,6 +28,7 @@ + @@ -44,6 +45,7 @@ + -- cgit v1.2.3-70-g09d2 From a279338f4dff62d87021ca28252d68b0c586d3a7 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Wed, 13 Aug 2014 02:12:40 -0400 Subject: add measurement stuff to media editor --- .../javascripts/mx/extensions/mx.movements.js | 4 +- .../rectangles/engine/scenery/types/_object.js | 4 ++ .../javascripts/rectangles/util/measurement.js | 82 +++++++++++++++++++++ .../assets/javascripts/ui/builder/BuilderInfo.js | 83 ---------------------- public/assets/javascripts/ui/editor/MediaEditor.js | 34 +++++++-- public/assets/stylesheets/app.css | 7 ++ test/09-test-undo.js | 1 + views/controls/editor/media-editor.ejs | 20 ++++-- views/partials/scripts.ejs | 1 + 9 files changed, 138 insertions(+), 98 deletions(-) create mode 100644 public/assets/javascripts/rectangles/util/measurement.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/mx/extensions/mx.movements.js b/public/assets/javascripts/mx/extensions/mx.movements.js index 191088f..3b7d3e2 100644 --- a/public/assets/javascripts/mx/extensions/mx.movements.js +++ b/public/assets/javascripts/mx/extensions/mx.movements.js @@ -149,7 +149,8 @@ MX.Movements = function (cam) { case 32: // space moveUp = moveDown = false break - + +/* case 48: // 0 cam.rotationX = 0 cam.rotationY = 0 @@ -157,6 +158,7 @@ MX.Movements = function (cam) { cam.y = viewHeight cam.z = 0 break +*/ } }) diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js index 7202ce0..66e0faf 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js @@ -66,6 +66,10 @@ Scenery.types.base = Fiber.extend(function(base){ this.center = this.wall.center() }, + set_scale: function(scale){ + this.scale = this.mx.scale = this.mx.ops.scale = scale || 1.0 + }, + recenter: function(){ this.mx.move({ x: this.center.a, diff --git a/public/assets/javascripts/rectangles/util/measurement.js b/public/assets/javascripts/rectangles/util/measurement.js new file mode 100644 index 0000000..d6a0b35 --- /dev/null +++ b/public/assets/javascripts/rectangles/util/measurement.js @@ -0,0 +1,82 @@ +$.fn.resetUnitVal = function(){ + this.each(function(){ + var n = $(this).data("px") + $(this).unitVal(n) + }); +} + +$.fn.unitVal = function(n){ + var s + if (typeof n === "undefined") { + s = $(this).val() + n = stringToMeasurement( s ) + if (! n || isNaN(n)) { + n = $(this).data("px") + } + } + s = measurementToString( n ) + $(this).val( s ).data("px", n) + return n +} + +function measurementToString( n ) { + var s, ft, inch + switch (app.units) { + case 'm': + s = round(n/36 * 0.3048 * 100) / 100 + " m" + break + case 'ft': + ft = floor(n / 36) + inch = abs(round((n % 36) / 3)) + s = ft + "'" + if (inch > 0) { + s += " " + inch + '"' + } + break + case 'px': + default: + s = round(n) + " px" + break + } + return s +} +function stringToMeasurement( s ) { + var ft, inch, ft_in, type + if (! s.match(/[0-9]/)) { + return NaN + } + if (s.indexOf("'") !== -1 || s.indexOf('"') !== -1 || s.indexOf('ft') !== -1) { + ft_in = s.match(/[0-9.]+/g) + if (ft_in.length >= 2) { + ft = parseFloat( ft_in[0] ) + inch = parseFloat( ft_in[1] ) + } + else if (ft_in.length == 1) { + if (s.indexOf('"') !== -1) { + ft = 0 + inch = parseFloat( ft_in[0] ) + } + else { + ft = parseFloat( ft_in[0] ) + inch = 0 + } + } + else { + ft = inch = 0 + } + n = ft * 36 + inch * 3 + } + else if (s.indexOf("m") !== -1) { + n = parseFloat(s.match(/[0-9.]+/)) * 36 / 0.3048 + } + else if (s.indexOf("px") !== -1) { + n = parseFloat(s.match(/[0-9.]+/)) + } + else { + n = abs( stringToMeasurement( s + app.units ) ) + } + if (s.indexOf('-') !== -1) { + n *= -1 + } + return n +} diff --git a/public/assets/javascripts/ui/builder/BuilderInfo.js b/public/assets/javascripts/ui/builder/BuilderInfo.js index 56f1338..2fffdba 100644 --- a/public/assets/javascripts/ui/builder/BuilderInfo.js +++ b/public/assets/javascripts/ui/builder/BuilderInfo.js @@ -96,86 +96,3 @@ var BuilderInfo = View.extend({ }, }) - -$.fn.resetUnitVal = function(){ - this.each(function(){ - var n = $(this).data("px") - $(this).unitVal(n) - }); -} - -$.fn.unitVal = function(n){ - var s - if (typeof n === "undefined") { - s = $(this).val() - n = stringToMeasurement( s ) - if (! n || isNaN(n)) { - n = $(this).data("px") - } - } - s = measurementToString( n ) - $(this).val( s ).data("px", n) - return n -} - -function measurementToString( n ) { - var s, ft, inch - switch (app.units) { - case 'm': - s = round(n/36 * 0.3048 * 100) / 100 + " m" - break - case 'ft': - ft = floor(n / 36) - inch = abs(round((n % 36) / 3)) - s = ft + "'" - if (inch > 0) { - s += " " + inch + '"' - } - break - case 'px': - default: - s = round(n) + " px" - break - } - return s -} -function stringToMeasurement( s ) { - var ft, inch, ft_in, type - if (! s.match(/[0-9]/)) { - return NaN - } - if (s.indexOf("'") !== -1 || s.indexOf('"') !== -1 || s.indexOf('ft') !== -1) { - ft_in = s.match(/[0-9.]+/g) - if (ft_in.length >= 2) { - ft = parseFloat( ft_in[0] ) - inch = parseFloat( ft_in[1] ) - } - else if (ft_in.length == 1) { - if (s.indexOf('"') !== -1) { - ft = 0 - inch = parseFloat( ft_in[0] ) - } - else { - ft = parseFloat( ft_in[0] ) - inch = 0 - } - } - else { - ft = inch = 0 - } - n = ft * 36 + inch * 3 - } - else if (s.indexOf("m") !== -1) { - n = parseFloat(s.match(/[0-9.]+/)) * 36 / 0.3048 - } - else if (s.indexOf("px") !== -1) { - n = parseFloat(s.match(/[0-9.]+/)) - } - else { - n = abs( stringToMeasurement( s + app.units ) ) - } - if (s.indexOf('-') !== -1) { - n *= -1 - } - return n -} \ No newline at end of file diff --git a/public/assets/javascripts/ui/editor/MediaEditor.js b/public/assets/javascripts/ui/editor/MediaEditor.js index cd8fb63..b9eb8fc 100644 --- a/public/assets/javascripts/ui/editor/MediaEditor.js +++ b/public/assets/javascripts/ui/editor/MediaEditor.js @@ -11,6 +11,9 @@ var MediaEditor = FormView.extend({ "change [name=autoplay]": "setAutoplay", "change [name=loop]": "setLoop", "change [name=mute]": "setMute", + "change [name=width]": 'changeWidth', + "change [name=height]": 'changeHeight', + "change [name=units]": 'changeUnits', "click [data-role=destroy-media]": "destroy", }, @@ -22,8 +25,8 @@ var MediaEditor = FormView.extend({ this.$description = this.$("[name=description]") // image fields - this.$widthDimension = this.$("[name=width]") - this.$heightDimension = this.$("[name=height]") + this.$width = this.$("[name=width]") + this.$height = this.$("[name=height]") this.$units = this.$("[name=units]") // video fields @@ -55,16 +58,14 @@ var MediaEditor = FormView.extend({ this.$name.val(media.title) this.$description.val(media.description) + this.setDimensions() + this.$units.val( "ft" ) switch (media.type) { case "image": this.$(".image").show() this.$(".video").hide() - - this.$widthDimension.val( Number(media.widthDimension) || "" ) - this.$heightDimension.val( Number(media.heightDimension) || "" ) - this.$units.val( media.units || "cm" ) - + break case "youtube": @@ -113,6 +114,25 @@ var MediaEditor = FormView.extend({ this.scenery.mute(checked) }, + setDimensions: function(){ + this.$width.unitVal( Number(this.scenery.dimensions.a * this.scenery.scale) || "" ) + this.$height.unitVal( Number(this.scenery.dimensions.b * this.scenery.scale) || "" ) + }, + changeWidth: function(e){ + e.stopPropagation() + this.scenery.set_scale( this.$width.unitVal() / this.scenery.dimensions.a ) + this.setDimensions() + }, + changeHeight: function(e){ + e.stopPropagation() + this.scenery.set_scale( this.$height.unitVal() / this.scenery.dimensions.b ) + this.setDimensions() + }, + changeUnits: function(){ + app.units = this.$units.val() + this.$('.units').resetUnitVal() + }, + bind: function(scenery){ this.scenery = scenery this.scenery.mx.bound = true diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 1863add..8508cf7 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1295,6 +1295,13 @@ input[type="range"]::-webkit-slider-thumb { top: 0px; } +#mediaEditor .setting.number label { + width: 40px; +} +#mediaEditor .setting.number [type=text] { + width: 140px; +} + .playButton,.muteButton { color: white; background: black; diff --git a/test/09-test-undo.js b/test/09-test-undo.js index 17998a9..f774c04 100644 --- a/test/09-test-undo.js +++ b/test/09-test-undo.js @@ -1,5 +1,6 @@ var assert = require("assert") var UndoStack = require("../public/assets/javascripts/rectangles/util/undo.js") +UndoStack.debug = false describe('undo', function(){ diff --git a/views/controls/editor/media-editor.ejs b/views/controls/editor/media-editor.ejs index 5db1fb2..7f8f299 100644 --- a/views/controls/editor/media-editor.ejs +++ b/views/controls/editor/media-editor.ejs @@ -34,13 +34,19 @@ -
- Dimensions
- - - +
+
+ + +
+
+
diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index b63d1bf..087c0d7 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -23,6 +23,7 @@ + -- cgit v1.2.3-70-g09d2 From 14228e82f4836b1bffa3389aa9e8d12959aa3810 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 13 Aug 2014 13:25:44 -0400 Subject: embed privacy check --- .../assets/javascripts/mx/primitives/mx.video.js | 2 -- .../assets/javascripts/mx/primitives/mx.vimeo.js | 23 +++++++++++----------- .../assets/javascripts/mx/primitives/mx.youtube.js | 2 -- .../rectangles/engine/scenery/types/video.js | 3 ++- public/assets/javascripts/ui/lib/ModalView.js | 7 ++++--- public/assets/javascripts/ui/lib/Parser.js | 6 ++++++ 6 files changed, 23 insertions(+), 20 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/mx/primitives/mx.video.js b/public/assets/javascripts/mx/primitives/mx.video.js index 7c0cd33..12d3dcb 100644 --- a/public/assets/javascripts/mx/primitives/mx.video.js +++ b/public/assets/javascripts/mx/primitives/mx.video.js @@ -22,8 +22,6 @@ MX.Video = MX.Object3D.extend({ this.el.classList.add("mx-scenery") this.paused = !! this.media.autoplay this.muted = app.muted || !! this.media.mute - - this.load() }, load: function(ops){ diff --git a/public/assets/javascripts/mx/primitives/mx.vimeo.js b/public/assets/javascripts/mx/primitives/mx.vimeo.js index 5b22821..4922519 100644 --- a/public/assets/javascripts/mx/primitives/mx.vimeo.js +++ b/public/assets/javascripts/mx/primitives/mx.vimeo.js @@ -23,8 +23,6 @@ MX.Vimeo = MX.Object3D.extend({ this.paused = !! this.media.autoplay this.muted = app.muted || !! this.media.mute this.started = false - - this.load() }, load: function (ops) { @@ -42,23 +40,24 @@ MX.Vimeo = MX.Object3D.extend({ this.el.appendChild(preload) this.player = $f(preload) - this.player.addEvent('ready', this.ready.bind(this)) + this.player.addEvent('ready', $.proxy(this.ready, this)) }, ready: function(){ console.log("vimeo ready") + this.started = true // wait until ready before binding events. other events: play, pause - this.player.addEvent('play', this.onPlay.bind(this)) - this.player.addEvent('pause', this.onPause.bind(this)) - this.player.addEvent('finish', this.finished.bind(this)) + this.player.addEvent('play', $.proxy(this.onPlay, this)) + this.player.addEvent('pause', $.proxy(this.onPause, this)) + this.player.addEvent('finish', $.proxy(this.finished, this)) // this is async on vimeo so call it asap - this.player.api('getDuration', function(n){ + this.player.api('getDuration', $.proxy(function(n){ console.log("vimeo duration", n) this.player.duration = n - }.bind(this)) + }, this)) if (this.media.mute) { this.mute() @@ -91,9 +90,9 @@ MX.Vimeo = MX.Object3D.extend({ seek: function(n){ // defer seek until we have duration if (! this.duration()) { - setTimeout(function(){ + setTimeout($.proxy(function(){ this.seek(n) - }.bind(this), 300) + }, this), 300) return } @@ -109,9 +108,9 @@ MX.Vimeo = MX.Object3D.extend({ this.paused = false this.play() this.pause() - setTimeout(function(){ + setTimeout($.proxy(function(){ this.pause() - }.bind(this), 100) + }, this), 100) } }, diff --git a/public/assets/javascripts/mx/primitives/mx.youtube.js b/public/assets/javascripts/mx/primitives/mx.youtube.js index 7846649..873348f 100644 --- a/public/assets/javascripts/mx/primitives/mx.youtube.js +++ b/public/assets/javascripts/mx/primitives/mx.youtube.js @@ -22,8 +22,6 @@ MX.Youtube = MX.Object3D.extend({ this.el.classList.add("mx-scenery") this.paused = !! this.media.autoplay this.muted = app.muted || !! this.media.mute - - this.load() }, load: function (ops) { diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/video.js b/public/assets/javascripts/rectangles/engine/scenery/types/video.js index 79cfb1c..a8df875 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/video.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/video.js @@ -34,7 +34,8 @@ Scenery.types.video = Scenery.types.base.extend(function(base){ y: this.scale * this.media.height/2, backface: false, }) - scene.add( this.mx ) + scene.add(this.mx) + this.mx.load() }, play: function(){ diff --git a/public/assets/javascripts/ui/lib/ModalView.js b/public/assets/javascripts/ui/lib/ModalView.js index 957a54d..937c1e9 100644 --- a/public/assets/javascripts/ui/lib/ModalView.js +++ b/public/assets/javascripts/ui/lib/ModalView.js @@ -11,9 +11,10 @@ var ModalView = View.extend({ }, show: function(){ - $(".mediaDrawer").removeClass("active"); - this.$el.addClass("active"); - $("body").addClass("noOverflow"); + $(".mediaDrawer").removeClass("active") + $(".fileUpload").removeClass("active") + this.$el.addClass("active") + $("body").addClass("noOverflow") }, hide: function(){ diff --git a/public/assets/javascripts/ui/lib/Parser.js b/public/assets/javascripts/ui/lib/Parser.js index dfff7b2..8867c0b 100644 --- a/public/assets/javascripts/ui/lib/Parser.js +++ b/public/assets/javascripts/ui/lib/Parser.js @@ -84,8 +84,14 @@ var Parser = { type: 'GET', url: 'http://vimeo.com/api/v2/video/' + id + '.json', success: function(result){ + console.log(result) + // embed_privacy: "nowhere" if (result.length == 0) { return done(id, "", 640, 360) } var res = result[0] + if (res.embed_privacy != "anywhere") { + AlertModal.alert("Sorry, the author of this video has marked it private, preventing it from being embedded.", function(){}) + return + } done({ token: id, thumbnail: res.thumbnail_large, -- cgit v1.2.3-70-g09d2 From 90cb5b343f3d56372f9b43faf215ed80dd879fe1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 13 Aug 2014 16:12:02 -0400 Subject: undo for scenery stuff --- .../javascripts/rectangles/engine/map/ui_editor.js | 16 +++---- .../rectangles/engine/scenery/_scenery.js | 9 +++- .../javascripts/rectangles/engine/scenery/move.js | 20 +++++++++ .../rectangles/engine/scenery/resize.js | 13 +++++- .../javascripts/rectangles/engine/scenery/undo.js | 20 +++++++++ .../assets/javascripts/rectangles/models/wall.js | 8 +++- public/assets/javascripts/rectangles/util/undo.js | 52 ---------------------- .../javascripts/rectangles/util/undostack.js | 52 ++++++++++++++++++++++ public/assets/javascripts/ui/editor/MediaEditor.js | 8 ++-- public/assets/javascripts/ui/lib/Parser.js | 2 - test/09-test-undo.js | 16 +++---- views/partials/scripts.ejs | 2 +- 12 files changed, 139 insertions(+), 79 deletions(-) delete mode 100644 public/assets/javascripts/rectangles/util/undo.js create mode 100644 public/assets/javascripts/rectangles/util/undostack.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/engine/map/ui_editor.js b/public/assets/javascripts/rectangles/engine/map/ui_editor.js index c5c996c..9a557b9 100644 --- a/public/assets/javascripts/rectangles/engine/map/ui_editor.js +++ b/public/assets/javascripts/rectangles/engine/map/ui_editor.js @@ -58,8 +58,8 @@ Map.UI.Editor = function(map){ UndoStack.push({ type: "destroy-room", - prev: room.copy(), - next: { id: room.id }, + undo: room.copy(), + redo: { id: room.id }, }) Rooms.remove(room) @@ -164,8 +164,8 @@ Map.UI.Editor = function(map){ UndoStack.push({ type: "create-room", - prev: { id: room.id }, - next: room.copy() + undo: { id: room.id }, + redo: room.copy() }) app.tube("builder-pick-room", room) @@ -185,8 +185,8 @@ Map.UI.Editor = function(map){ UndoStack.push({ type: "update-room", - prev: oldState, - next: base.dragging.copy() + undo: oldState, + redo: base.dragging.copy() }) } @@ -211,8 +211,8 @@ Map.UI.Editor = function(map){ wheelTimeout = setTimeout(function(){ UndoStack.push({ type: "update-room", - prev: wheelState, - next: intersects[0].copy() + undo: wheelState, + redo: intersects[0].copy() }) Rooms.clipper.update() wheelState = null diff --git a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js index fe5f037..c96885c 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js +++ b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js @@ -30,10 +30,15 @@ var Scenery = new function(){ } base.addNextToWall = function(wall){ - base.add(wall, base.nextMedia) + var media = base.add(wall, base.nextMedia) base.nextMedia = null + return media } - + + base.find = function(id){ + return base.list[id] || null + } + base.remove = function(id){ var media = base.list[id] delete base.list[id] diff --git a/public/assets/javascripts/rectangles/engine/scenery/move.js b/public/assets/javascripts/rectangles/engine/scenery/move.js index 94a4e52..ef9bc32 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/move.js +++ b/public/assets/javascripts/rectangles/engine/scenery/move.js @@ -3,6 +3,7 @@ Scenery.move = function(base){ var x, y, z, bounds var dragging = false + var oldState this.bind = function(){ Scenery.mouse.bind_el(base.mx.el) @@ -23,6 +24,12 @@ Scenery.move = function(base){ function down (e, cursor){ if (e.target != base.mx.el) return; if (editor.permissions.destroy) { + UndoStack.push({ + type: 'destroy-scenery', + undo: base.serialize(), + redo: { id: base.id }, + }) + Scenery.remove(base.id) return } @@ -39,6 +46,7 @@ Scenery.move = function(base){ y = base.mx.y z = base.mx.z bounds = base.bounds + oldState = base.serialize() document.body.classList.add("dragging") } @@ -63,8 +71,20 @@ Scenery.move = function(base){ } function up (e, cursor){ + if (! dragging || ! oldState) return + dragging = false document.body.classList.remove("dragging") + + console.log("pushing", oldState, base.serialize()) + + UndoStack.push({ + type: 'update-scenery', + undo: oldState, + redo: base.serialize(), + }) + + oldState = null } function switch_wall (e, new_wall, cursor){ diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index df058bb..c5c754a 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -7,6 +7,7 @@ Scenery.resize = new function(){ var x, y, z, bounds var dragging = false var dimensions, position, scale + var oldState var dots = [], dot, selected_dot @@ -54,7 +55,7 @@ Scenery.resize = new function(){ } // move all the dots to the object's current position - base.move_dots = function(){ + base.move_dots = function(){ x = obj.mx.x + sin(rotationY) * dot_distance_from_picture y = obj.mx.y z = obj.mx.z - cos(rotationY) * dot_distance_from_picture @@ -88,7 +89,7 @@ Scenery.resize = new function(){ // pick a new object to focus on and show the dots base.show = function(new_object) { - if (obj === new_object) return + // if (obj === new_object) return obj = new_object base.add_dots() @@ -151,6 +152,7 @@ Scenery.resize = new function(){ dimensions = obj.dimensions position = new vec3(obj.mx.x, obj.mx.y, obj.mx.z) scale = obj.mx.scale + oldState = obj.serialize() document.body.classList.add("dragging") } @@ -191,6 +193,13 @@ Scenery.resize = new function(){ if (! editor.permissions.resize) { return } obj.scale = obj.mx.ops.scale = obj.mx.scale obj.set_wall() + + UndoStack.push({ + type: 'update-scenery', + undo: oldState, + redo: obj.serialize(), + }) + 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 4bdb2c4..7798550 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/undo.js +++ b/public/assets/javascripts/rectangles/engine/scenery/undo.js @@ -3,22 +3,42 @@ { type: "create-scenery", undo: function(state){ + Scenery.remove(state.id) }, redo: function(state){ + Scenery.deserialize([ state ]) }, }, { type: "update-scenery", undo: function(state){ + var scenery = Scenery.find(state.id) + scenery.deserialize(state) + scenery.set_wall(Rooms.walls[ state.wall_id ]) + + if (editor.permissions.resize) { + Scenery.resize.show(scenery) + } }, redo: function(state){ + var scenery = Scenery.find(state.id) + scenery.deserialize(state) + scenery.set_wall(Rooms.walls[ state.wall_id ]) + + if (editor.permissions.resize) { + Scenery.resize.show(scenery) + Scenery.resize.rotate_dots() + Scenery.resize.move_dots() + } }, }, { type: "destroy-scenery", undo: function(state){ + Scenery.deserialize([ state ]) }, redo: function(state){ + Scenery.remove(state.id) }, }, diff --git a/public/assets/javascripts/rectangles/models/wall.js b/public/assets/javascripts/rectangles/models/wall.js index 91e7c18..6e2c728 100644 --- a/public/assets/javascripts/rectangles/models/wall.js +++ b/public/assets/javascripts/rectangles/models/wall.js @@ -43,7 +43,13 @@ window.Wall = (function(){ // base.randomize_colors() // console.log(sidesToString(base.side)) if (Scenery.nextMedia) { - Scenery.addNextToWall(base) + var scenery = Scenery.addNextToWall(base) + + UndoStack.push({ + type: 'create-scenery', + undo: { id: scenery.id }, + redo: scenery.serialize(), + }) } else if (Scenery.nextWallpaper) { base.wallpaper() diff --git a/public/assets/javascripts/rectangles/util/undo.js b/public/assets/javascripts/rectangles/util/undo.js deleted file mode 100644 index dfc74dc..0000000 --- a/public/assets/javascripts/rectangles/util/undo.js +++ /dev/null @@ -1,52 +0,0 @@ -(function(){ - - var UndoStack = function(){ - this.debug = true - this.stack = [] - this.types = {} - this.pointer = -1 - } - UndoStack.prototype.push = function(action){ - this.pointer++ - this.stack[this.pointer] = action - this.purge() - } - UndoStack.prototype.purge = function(){ - if (this.stack.length-1 == this.pointer) return - this.stack.length = this.pointer+1 - } - UndoStack.prototype.undo = function(){ - if (this.pointer == -1) return false - var action = this.stack[this.pointer] - this.debug && console.log("undo", action.type) - this.types[ action.type ].undo(action.prev) - this.pointer-- - return this.pointer > -1 - } - UndoStack.prototype.redo = function(){ - if (this.pointer == this.stack.length-1) return false - this.pointer++ - var action = this.stack[this.pointer] - this.debug && console.log("redo", action.type) - this.types[ action.type ].redo(action.next) - return this.pointer < this.stack.length-1 - } - UndoStack.prototype.register = function(actionType){ - if (actionType.length) { - actionType.forEach(this.registerOne.bind(this)) - } - else { - this.registerOne(actionType) - } - } - UndoStack.prototype.registerOne = function(actionType){ - this.types[ actionType.type ] = actionType - } - if ('window' in this) { - window.UndoStack = new UndoStack - } - else { - module.exports = new UndoStack - } - -})() diff --git a/public/assets/javascripts/rectangles/util/undostack.js b/public/assets/javascripts/rectangles/util/undostack.js new file mode 100644 index 0000000..b93c79e --- /dev/null +++ b/public/assets/javascripts/rectangles/util/undostack.js @@ -0,0 +1,52 @@ +(function(){ + + var UndoStack = function(){ + this.debug = true + this.stack = [] + this.types = {} + this.pointer = -1 + } + UndoStack.prototype.push = function(action){ + this.pointer++ + this.stack[this.pointer] = action + this.purge() + } + UndoStack.prototype.purge = function(){ + if (this.stack.length-1 == this.pointer) return + this.stack.length = this.pointer+1 + } + UndoStack.prototype.undo = function(){ + if (this.pointer == -1) return false + var action = this.stack[this.pointer] + this.debug && console.log("undo", action.type) + this.types[ action.type ].undo(action.undo) + this.pointer-- + return this.pointer > -1 + } + UndoStack.prototype.redo = function(){ + if (this.pointer == this.stack.length-1) return false + this.pointer++ + var action = this.stack[this.pointer] + this.debug && console.log("redo", action.type) + this.types[ action.type ].redo(action.redo) + return this.pointer < this.stack.length-1 + } + UndoStack.prototype.register = function(actionType){ + if (actionType.length) { + actionType.forEach(this.registerOne.bind(this)) + } + else { + this.registerOne(actionType) + } + } + UndoStack.prototype.registerOne = function(actionType){ + this.types[ actionType.type ] = actionType + } + if ('window' in this) { + window.UndoStack = new UndoStack + } + else { + module.exports = new UndoStack + } + +})() diff --git a/public/assets/javascripts/ui/editor/MediaEditor.js b/public/assets/javascripts/ui/editor/MediaEditor.js index b9eb8fc..e3a8f2e 100644 --- a/public/assets/javascripts/ui/editor/MediaEditor.js +++ b/public/assets/javascripts/ui/editor/MediaEditor.js @@ -139,12 +139,14 @@ var MediaEditor = FormView.extend({ }, unbind: function(){ - this.scenery.mx.bound = false - this.scenery = null + if (this.scenery && this.scenery.mx) { + this.scenery.mx.bound = false + } + this.scenery = null }, destroy: function(){ - ConfirmModal.confirm("Are you sure you want to this media?", function(){ + ConfirmModal.confirm("Are you sure you want delete to this media?", function(){ var scenery = this.scenery this.hide() Scenery.remove(scenery.id) diff --git a/public/assets/javascripts/ui/lib/Parser.js b/public/assets/javascripts/ui/lib/Parser.js index 8867c0b..1cf0418 100644 --- a/public/assets/javascripts/ui/lib/Parser.js +++ b/public/assets/javascripts/ui/lib/Parser.js @@ -84,8 +84,6 @@ var Parser = { type: 'GET', url: 'http://vimeo.com/api/v2/video/' + id + '.json', success: function(result){ - console.log(result) - // embed_privacy: "nowhere" if (result.length == 0) { return done(id, "", 640, 360) } var res = result[0] if (res.embed_privacy != "anywhere") { diff --git a/test/09-test-undo.js b/test/09-test-undo.js index f774c04..dbca90e 100644 --- a/test/09-test-undo.js +++ b/test/09-test-undo.js @@ -34,22 +34,22 @@ describe('undo', function(){ UndoStack.push({ type: "demo", - prev: state, - next: "one" + undo: state, + redo: "one" }) state = "one" UndoStack.push({ type: "demo", - prev: state, - next: "two" + undo: state, + redo: "two" }) state = "two" UndoStack.push({ type: "demo", - prev: state, - next: "three" + undo: state, + redo: "three" }) state = "three" @@ -123,8 +123,8 @@ describe('undo', function(){ UndoStack.push({ type: "demo", - prev: state, - next: "four" + undo: state, + redo: "four" }) state = "four" diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index 087c0d7..dfb3a83 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -29,7 +29,7 @@ - + -- cgit v1.2.3-70-g09d2 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 --- .../assets/javascripts/rectangles/util/minotaur.js | 58 ++++++++++++++++++++++ public/assets/javascripts/ui/_router.js | 1 + 2 files changed, 59 insertions(+) create mode 100644 public/assets/javascripts/rectangles/util/minotaur.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/util/minotaur.js b/public/assets/javascripts/rectangles/util/minotaur.js new file mode 100644 index 0000000..b4c81f0 --- /dev/null +++ b/public/assets/javascripts/rectangles/util/minotaur.js @@ -0,0 +1,58 @@ +$(function(){ + + var Monitor = function () { + var base = this; + base.$el = $("#save"); + base.timeout = null; + base.delay = 500; + base.objects = {}; + + base.init = function () { + base.$el.addClass('saved').html('Save'); + 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.clear = function () { + if (base.timeout) clearTimeout(base.timeout); + base.timeout = false; + }; + + base.save = function () { + 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').html('Saved'); + saving = true; + }); + base.objects[type][id] = false; + } + } + + if (saving) { + base.$el.removeClass('unsaved saved').addClass('saving').html('Saving'); + } + else { + base.$el.removeClass('unsaved saving').addClass('saved').html('Saved'); + } + + base.objects = {}; + }; + + base.init(); + }; + + window.Minotaur = new Monitor (); +}); 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