summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2014-08-14 15:24:34 -0400
committerJules Laplace <jules@okfoc.us>2014-08-14 15:24:34 -0400
commit31907c69cc192a23bb409adf5c438ed708db0842 (patch)
tree516a88386f96606b1890c83e5083fdb943582a68
parentc4c45b64c2c0fc109f4c21effe7f73f5c46a1ae9 (diff)
parent63da3ba331aa3d9714151ba5f502e6e1851d75bb (diff)
merge
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/move.js8
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/resize.js3
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/undo.js18
-rw-r--r--public/assets/javascripts/rectangles/models/wall.js3
-rw-r--r--public/assets/javascripts/rectangles/util/minotaur.js64
-rw-r--r--public/assets/javascripts/ui/_router.js1
-rw-r--r--public/assets/javascripts/ui/builder/BuilderSettings.js3
-rw-r--r--public/assets/javascripts/ui/editor/EditorSettings.js29
-rw-r--r--public/assets/javascripts/ui/editor/MediaEditor.js1
-rw-r--r--public/assets/javascripts/ui/lib/FormView.js28
-rw-r--r--public/assets/javascripts/ui/lib/View.js17
-rwxr-xr-xpublic/assets/stylesheets/app.css19
-rw-r--r--server/lib/api/projects.js23
-rw-r--r--views/partials/header.ejs4
-rw-r--r--views/partials/scripts.ejs1
15 files changed, 193 insertions, 29 deletions
diff --git a/public/assets/javascripts/rectangles/engine/scenery/move.js b/public/assets/javascripts/rectangles/engine/scenery/move.js
index fa247e1..f2d37d8 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 f015a44..b66d5f5 100644
--- a/public/assets/javascripts/rectangles/models/wall.js
+++ b/public/assets/javascripts/rectangles/models/wall.js
@@ -59,6 +59,9 @@
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
new file mode 100644
index 0000000..039a053
--- /dev/null
+++ b/public/assets/javascripts/rectangles/util/minotaur.js
@@ -0,0 +1,64 @@
+(function(){
+
+ var Monitor = function () {
+ var base = this
+ base.$el = $("#minotaur")
+ base.timeout = null
+ base.delay = 500
+ base.objects = {}
+
+ base.init = function () {
+ 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.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
+ }
+
+ base.save = function () {
+ var saving = false
+ base.clear()
+
+ for (var type in base.objects) {
+ for (var id in base.objects[type]) {
+ var obj = base.objects[type][id]
+ if (obj) {
+ obj.save(null, function(){ base.hide() }, function(){})
+ }
+ delete base.objects[type][id]
+ saving = true
+ }
+ }
+
+ saving ? base.show() : base.hide()
+ }
+
+ base.show = function () {
+ base.$el.removeClass().addClass('saving')
+ }
+
+ base.hide = function () {
+ base.$el.removeClass()
+ }
+
+ 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',
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..e9239e4 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,13 +32,17 @@ 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.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)
}
@@ -121,15 +125,32 @@ 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)
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/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css
index 7cc41f5..1c48eee 100755
--- a/public/assets/stylesheets/app.css
+++ b/public/assets/stylesheets/app.css
@@ -629,7 +629,24 @@ iframe.embed {
background-size: 100% 100%;
}
-
+#minotaur {
+ position: absolute;
+ top: 26px;
+ right: 260px;
+ opacity: 0;
+}
+#minotaur .label:after {
+ padding: 6px;
+ font-size: 13px;
+ font-weight: 300;
+}
+#minotaur.saving {
+ background: #8fd;
+ opacity: 1;
+}
+#minotaur.saving .label:after {
+ content: 'SAVING';
+}
.rapper {
position:relative;
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){
diff --git a/views/partials/header.ejs b/views/partials/header.ejs
index e83f42a..6697aff 100644
--- a/views/partials/header.ejs
+++ b/views/partials/header.ejs
@@ -1,5 +1,9 @@
<a href="/" class="logo"><img src="/assets/img/logo4.svg"></a>
+<div id="minotaur">
+ <span class="label"></span>
+</div>
+
<span class="topLinks">
[[ if (logged_in) { ]]
diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs
index d0454d6..6d85699 100644
--- a/views/partials/scripts.ejs
+++ b/views/partials/scripts.ejs
@@ -30,6 +30,7 @@
<script type="text/javascript" src="/assets/javascripts/rectangles/util/mouse.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/util/keys.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/util/undostack.js"></script>
+<script type="text/javascript" src="/assets/javascripts/rectangles/util/minotaur.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/models/vec2.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/models/vec3.js"></script>
<script type="text/javascript" src="/assets/javascripts/rectangles/models/mat4.js"></script>