summaryrefslogtreecommitdiff
path: root/public/assets/javascripts/ui
diff options
context:
space:
mode:
Diffstat (limited to 'public/assets/javascripts/ui')
-rw-r--r--public/assets/javascripts/ui/builder/BuilderSettings.js2
-rw-r--r--public/assets/javascripts/ui/builder/BuilderView.js1
-rw-r--r--public/assets/javascripts/ui/editor/Collaborators.js128
-rw-r--r--public/assets/javascripts/ui/editor/EditorSettings.js25
-rw-r--r--public/assets/javascripts/ui/editor/EditorToolbar.js5
-rw-r--r--public/assets/javascripts/ui/editor/EditorView.js3
-rw-r--r--public/assets/javascripts/ui/editor/LightControl.js299
-rw-r--r--public/assets/javascripts/ui/editor/MediaEditor.js11
-rw-r--r--public/assets/javascripts/ui/editor/MediaUpload.js73
-rw-r--r--public/assets/javascripts/ui/editor/MediaViewer.js1
-rw-r--r--public/assets/javascripts/ui/editor/WallpaperPicker.js164
-rw-r--r--public/assets/javascripts/ui/lib/FormView.js12
-rw-r--r--public/assets/javascripts/ui/lib/ModalView.js9
-rw-r--r--public/assets/javascripts/ui/lib/UploadView.js90
-rw-r--r--public/assets/javascripts/ui/site/SignUpModal.js1
15 files changed, 599 insertions, 225 deletions
diff --git a/public/assets/javascripts/ui/builder/BuilderSettings.js b/public/assets/javascripts/ui/builder/BuilderSettings.js
index 0091454..796c398 100644
--- a/public/assets/javascripts/ui/builder/BuilderSettings.js
+++ b/public/assets/javascripts/ui/builder/BuilderSettings.js
@@ -29,6 +29,8 @@ var BuilderSettings = FormView.extend({
this.$id.val(data._id)
this.$name.val(data.name)
+ this.parent.lightControl.loadDefaults()
+
data.rooms && Rooms.deserialize(data.rooms)
data.startPosition && scene.camera.move(data.startPosition)
data.privacy && this.$privacy.find("[value=" + data.privacy + "]").prop('checked', "checked")
diff --git a/public/assets/javascripts/ui/builder/BuilderView.js b/public/assets/javascripts/ui/builder/BuilderView.js
index 555cd58..a89111f 100644
--- a/public/assets/javascripts/ui/builder/BuilderView.js
+++ b/public/assets/javascripts/ui/builder/BuilderView.js
@@ -11,6 +11,7 @@ var BuilderView = View.extend({
this.info = new BuilderInfo ({ parent: this })
this.toolbar = new BuilderToolbar ({ parent: this })
this.settings = new BuilderSettings ({ parent: this })
+ this.lightControl = new LightControl ({ parent: this })
},
load: function(name){
diff --git a/public/assets/javascripts/ui/editor/Collaborators.js b/public/assets/javascripts/ui/editor/Collaborators.js
new file mode 100644
index 0000000..452ad15
--- /dev/null
+++ b/public/assets/javascripts/ui/editor/Collaborators.js
@@ -0,0 +1,128 @@
+
+var Collaborators = ModalFormView.extend({
+ el: ".mediaDrawer.collaborators",
+
+ template: $("#collaborator-template").html(),
+
+ indexAction: function(){ return "/api/collaborator/" + this.parent.data.slug + "/index" },
+ createAction: function(){ return "/api/collaborator/" + this.parent.data.slug + "/create" },
+ destroyAction: function(){ return "/api/collaborator/" + this.parent.data.slug + "/destroy" },
+
+ events: {
+ "keydown [name=email]": "enterSubmit",
+ "click [data-role=destroy-collaborator]": "destroy",
+ },
+
+ show: function(){
+ this.action = this.createAction
+ this.$("#collaborator-url-rapper").hide()
+
+ if (! this.loaded) {
+ this.load()
+ }
+ else {
+ this.__super__.show.call(this)
+ }
+ },
+
+ load: function(){
+ $.get(this.indexAction(), this.populate.bind(this))
+ },
+
+ populate: function(collaborators){
+ this.loaded = true
+ collaborators.forEach(function(collab){
+ var $el = $( this.template )
+ $el.data("collaborator-id", collab._id)
+
+ if (collab.user) {
+ $el.find(".email").remove()
+
+ $el.find(".user")
+ .attr("href", "/profile/" + collab.user.username)
+
+ $el.find(".avatar")
+ .css("background-image", "url(" + collab.user.photo + ")")
+
+ $el.find(".username")
+ .html( collab.user.displayName )
+
+ if (collab.owner) {
+ $el.find("button").remove()
+ }
+ else {
+ $el.find(".role").remove()
+ }
+ }
+ else {
+ $el.find(".user").remove()
+ $el.find(".role").remove()
+ $el.find(".email").html( collab.email )
+ }
+
+ $("#collaborator-list").append($el)
+ }.bind(this))
+
+ this.__super__.show.call(this)
+ },
+
+ enterSubmit: function (e) {
+ e.stopPropagation()
+ var base = this
+ if (e.keyCode == 13) {
+ setTimeout(function(){
+ base.save(e)
+ base.reset()
+ }, 100)
+ }
+ },
+
+ validate: function(){
+ var errors = []
+
+ var email = this.$("[name=email]").val()
+ if (! email.length) {
+ errors.push("Please enter an email address");
+ }
+ else if (email.indexOf("@") === -1) {
+ errors.push("Please enter a valid email address");
+ }
+
+ return errors
+ },
+
+ success: function(data){
+ this.reset()
+ this.populate([data])
+ // weird! this.$("#collaborator-url") not working here, but works without this
+ setTimeout(function(){
+ $("#collaborator-url").val("http://vvalls.com/join/" + data.nonce)
+ }, 100)
+ this.$("#collaborator-dummy-email").html(data.email)
+ this.$("#collaborator-url-rapper").slideDown(300)
+ },
+
+ destroy: function(e){
+ var base = this
+ var $el = $(e.currentTarget).closest("li")
+
+ if ($el.find(".user").length) {
+ var name = $el.find(".username").html()
+ ConfirmModal.confirm("Are you sure you want to remove " + name + " from this project?", _destroy)
+ }
+ else {
+ _destroy()
+ }
+
+ function _destroy () {
+ var _id = $el.data("collaborator-id")
+ $el.remove()
+ $.ajax({
+ type: "DELETE",
+ url: base.destroyAction(),
+ data: { _id: _id, _csrf: $("[name=_csrf]").val() },
+ })
+ }
+ },
+
+})
diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js
index e9239e4..2a3929a 100644
--- a/public/assets/javascripts/ui/editor/EditorSettings.js
+++ b/public/assets/javascripts/ui/editor/EditorSettings.js
@@ -9,6 +9,7 @@ var EditorSettings = FormView.extend({
events: {
"keydown": 'stopPropagation',
"keydown [name=name]": 'enterSubmit',
+ "click [data-role='show-collaborators']": 'showCollaborators',
"click [data-role='save-project']": 'save',
"click [data-role='clone-project']": 'clone',
"click [data-role='clear-project']": 'clear',
@@ -28,15 +29,23 @@ var EditorSettings = FormView.extend({
load: function(data){
this.action = data.isNew ? this.createAction : this.updateAction
-
+ this.parent.data = data
+
data.rooms && Rooms.deserialize(data.rooms)
+ data.walls && Walls.deserialize(data.walls)
data.startPosition && scene.camera.move(data.startPosition)
-
+
+ if (data.colors && data.colors.wall) {
+ this.parent.lightControl.load(data.colors)
+ }
+ else {
+ this.parent.lightControl.loadDefaults()
+ }
+
if (data.isNew) {
this.$name.val( "Room " + moment().format("DD/MM/YYYY ha") )
}
else {
- // console.log(data)
this.thumbnailIsStale()
this.$id.val( data._id )
@@ -48,6 +57,11 @@ var EditorSettings = FormView.extend({
}
},
+ showCollaborators: function(e){
+ e && e.preventDefault()
+ this.parent.collaborators.show()
+ },
+
clone: function(){
var names = this.$name.val().split(" ")
if ( ! isNaN(Number( names[names.length-1] )) ) {
@@ -122,7 +136,8 @@ var EditorSettings = FormView.extend({
fd.append( "description", this.$description.val() )
fd.append( "privacy", this.$privacy.filter(":checked").val() == "private" )
fd.append( "rooms", JSON.stringify( Rooms.serialize() ) )
- fd.append( "walls", JSON.stringify( Rooms.serializeWalls() ) )
+ fd.append( "walls", JSON.stringify( Walls.serialize() ) )
+ fd.append( "colors", JSON.stringify( Walls.colors ) )
fd.append( "media", JSON.stringify( Scenery.serialize() ) )
fd.append( "startPosition", JSON.stringify( app.position(scene.camera) ) )
@@ -152,6 +167,8 @@ var EditorSettings = FormView.extend({
Minotaur.hide()
window.history.pushState(null, document.title, "/project/" + data.slug + "/edit")
+
+ this.parent.data = data
},
})
diff --git a/public/assets/javascripts/ui/editor/EditorToolbar.js b/public/assets/javascripts/ui/editor/EditorToolbar.js
index 5e0da7e..c631317 100644
--- a/public/assets/javascripts/ui/editor/EditorToolbar.js
+++ b/public/assets/javascripts/ui/editor/EditorToolbar.js
@@ -56,6 +56,11 @@ var EditorToolbar = View.extend({
$(".inuse").removeClass("inuse")
$("[data-role='resize-media']").toggleClass("inuse", state)
if (state) {
+ if (this.parent.mediaEditor.scenery) {
+ Scenery.resize.show( this.parent.mediaEditor.scenery )
+ }
+ }
+ else {
Scenery.resize.hide()
}
},
diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js
index 4067c4d..e11f189 100644
--- a/public/assets/javascripts/ui/editor/EditorView.js
+++ b/public/assets/javascripts/ui/editor/EditorView.js
@@ -16,6 +16,7 @@ var EditorView = View.extend({
this.mediaEditor = new MediaEditor ({ parent: this })
this.wallpaperPicker = new WallpaperPicker ({ parent: this })
this.lightControl = new LightControl ({ parent: this })
+ this.collaborators = new Collaborators ({ parent: this })
},
load: function(name){
@@ -30,7 +31,7 @@ var EditorView = View.extend({
ready: function(data){
$("#map").hide()
-
+
this.settings.load(data)
},
diff --git a/public/assets/javascripts/ui/editor/LightControl.js b/public/assets/javascripts/ui/editor/LightControl.js
index c3e80c2..bd09dc2 100644
--- a/public/assets/javascripts/ui/editor/LightControl.js
+++ b/public/assets/javascripts/ui/editor/LightControl.js
@@ -1,43 +1,272 @@
var LightControl = View.extend({
- el: ".lightcontrol",
-
- events: {
- "mousedown": "stopPropagation",
- },
+ el: ".lightcontrol",
+
+ events: {
+ "mousedown": "stopPropagation",
+ "click .swatch": "clickSwatch",
+ "click label": "clickLabel",
+ "input #shadow-control": "updateShadow",
+ "mousedown #brightness-control": "beginBrightness",
+ "input #brightness-control": "updateBrightness",
+ "input #outline-hue": "updateShadow",
+ "input #wall-hue": "updateShadow",
+ },
+
+ initialize: function(){
+ this.colorPicker = new LabColorPicker(this, 180, 180)
+ this.$el.prepend( this.colorPicker.canvas )
+
+ this.$swatches = this.$(".swatch")
+ this.$labels = this.$(".swatch + label")
+ this.$swatch = {
+ wall: this.$("#wall-color"),
+ outline: this.$("#outline-color"),
+ floor: this.$("#floor-color"),
+ ceiling: this.$("#ceiling-color"),
+ }
+ this.$brightnessControl = this.$("#brightness-control")
+ },
- toggle: function(state){
+ modes: [ "wall", "outline", "floor", "ceiling" ],
+
+ load: function(data){
+ this.modes.forEach(function(mode){
+ Walls.setColor[mode](data[mode])
+ this.$swatch[ mode ].css("background-color", rgb_string(data[mode]))
+ }.bind(this))
+ this.setMode("wall")
+ },
+
+ loadDefaults: function(){
+ var colors = {
+ wall: app.defaults.wallColor.slice(),
+ outline: app.defaults.outlineColor.slice(),
+ floor: app.defaults.floorColor.slice(),
+ ceiling: app.defaults.ceilingColor.slice(),
+ }
+ this.load(colors)
+ },
+
+ toggle: function(state){
this.$el.toggleClass("active", state);
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+
+ hide: function(){
+ this.toggle(false)
+ },
+
+ pick: function(rgb, Lab){
+ this.labColor = Lab
+ this.setSwatchColor(this.mode, rgb)
+ Walls.setColor[ this.mode ](rgb)
+ },
+
+ setSwatchColor: function(mode, rgb) {
+ this.$swatch[ mode ].css("background-color", rgb_string(rgb))
+ },
+
+ initialState: null,
+
+ begin: function(){
+ this.initialState = this.serialize()
+ },
+
+ serialize: function(){
+ return {
+ mode: this.mode,
+ rgb: Walls.colors[ this.mode ]
+ }
+ },
+
+ finalize: function(){
+ if (! this.initialState) { return }
+ UndoStack.push({
+ type: 'update-colors',
+ undo: this.initialState,
+ redo: this.serialize(),
+ })
+ this.initialState = null
+ },
+
+ setMode: function (mode) {
+ var color, brightness
+ this.mode = mode
+ this.$swatches.removeClass("selected")
+ this.$labels.removeClass("selected")
+ this.$swatch[ mode ].addClass("selected")
+ color = Walls.colors[ mode ]
+
+ this.$(".swatch.selected").next("label").addClass("selected")
+ this.labColor = this.colorPicker.load(color)
+ this.$brightnessControl.val( this.labColor[0] )
+ },
+
+ clickLabel: function(e){
+ $(e.currentTarget).prev(".swatch").trigger("click")
+ },
+ clickSwatch: function(e){
+ var mode = $(e.currentTarget).data('mode')
+ this.setMode(mode)
+ },
+
+ beginBrightness: function(){
+ this.begin()
+ $(window).one("mouseup", this.finalize.bind(this))
+ },
+
+ updateBrightness: function(){
+ this.labColor[0] = parseFloat( this.$brightnessControl.val() )
+ var rgb = this.colorPicker.setLab( this.labColor )
+ this.pick(rgb, this.labColor)
+ },
- // toggle the class that makes the cursor a paintbucket
- // $("body").removeClass("pastePaper");
- },
- show: function(){
- this.toggle(true)
- },
- hide: function(){
- this.toggle(false)
- },
+})
-/*
- $("#shadow-control").on({
- mousedown: function(){ app.dragging = true },
- change: function(){
- var hex = (~~($(this).int() / 100 * 0xff)).toString(10)
- if (hex.length == 1) hex = "0" + hex;
- var color = "rgba(" + [hex, hex, hex, "1.0"] + ")"
- $(".face").css("border-color", color)
- }
- })
+var LabColorPicker = function (parent, w, h) {
+ var base = this
+ var canvas = this.canvas = document.createElement('canvas')
+ var ctx = this.ctx = canvas.getContext('2d')
+ var imageData = ctx.createImageData(w,h)
+ var data = imageData.data
- $("#brightness-control").on({
- mousedown: function(){ app.dragging = true },
- change: function(){
- var hex = (~~($(this).int() / 100 * 0xff)).toString(10)
- var color = "rgba(" + [hex, hex, hex, "0.9"] + ")"
- $("body,.face").css("background-color", color)
- }
- })
-*/
+// var cursor = this.cursor = document.createElement("div")
+// cursor.className = "colorPickerCursor"
-})
+ canvas.width = w
+ canvas.height = h
+ canvas.className = "colorPicker"
+
+ var ww = w-1
+ var hh = h-1
+
+ var L_range = [0, 110]
+ var a_range = [-86.185, 98.254]
+ var b_range = [-107.863, 94.482]
+
+ var rgb = [0,0,0]
+
+ var val = 80
+
+ this.mouse = new mouse({
+ el: canvas,
+ down: function(e, cursor){
+ parent.begin()
+ cursor.x.a = -cursor.x.a
+ base.pick(cursor.x.a, cursor.y.a)
+ },
+ drag: function(e, cursor){
+ cursor.x.b = -cursor.x.b
+ base.pick(cursor.x.b, cursor.y.b)
+ },
+ up: function(){
+ parent.finalize()
+ }
+ })
+
+ this.setLab = function(Lab) {
+ val = Lab[0]
+ this.paint()
+ var rgb = xyz2rgb(hunterlab2xyz(Lab[0], Lab[1], Lab[2])).map(Math.round)
+ return rgb
+ }
+ this.pick = function(i, j){
+ var x = mix( i/ww, a_range[0], a_range[1] )
+ var y = mix( j/hh, b_range[0], b_range[1] )
+ var rgb = xyz2rgb(hunterlab2xyz(val, x, y)).map(Math.round)
+ parent.pick( rgb, [val,x,y] )
+ }
+ this.load = function(rgba){
+ var Lab = xyz2hunterlab(rgb2xyz(rgba))
+ var val = clamp( Lab[0], L_range[0], L_range[1] )
+ var x = mix( norm(Lab[1], a_range[0], a_range[1]), 0, ww )
+ var y = mix( norm(Lab[2], b_range[0], b_range[1]), 0, hh )
+ // move the cursor
+ this.setLab(Lab)
+ return Lab
+ }
+ this.paint = function() {
+ val = clamp(val, L_range[0], L_range[1])
+ var x, y, t
+ for (var i = 0; i < w; i++) {
+ for (var j = 0; j < h; j++) {
+ x = mix( i/ww, a_range[0], a_range[1] )
+ y = mix( j/hh, b_range[0], b_range[1] )
+ t = (j*w + i) * 4
+ rgb = xyz2rgb(hunterlab2xyz(val, x, y))
+ data[t] = Math.round( rgb[0] )
+ data[t+1] = Math.round( rgb[1] )
+ data[t+2] = Math.round( rgb[2] )
+ data[t+3] = 255
+ }
+ }
+ ctx.putImageData(imageData,0,0)
+ }
+
+ function hunterlab2xyz (L,a,b) {
+ var_Y = L / 10
+ var_X = a / 17.5 * L / 10
+ var_Z = b / 7 * L / 10
+
+ Y = Math.pow(var_Y, 2)
+ X = ( var_X + Y ) / 1.02
+ Z = -( var_Z - Y ) / 0.847
+ xyz = [X,Y,Z]
+ }
+ function xyz2rgb(){
+ var var_X = xyz[0] / 100 //X from 0 to 95.047 (Observer = 2°, Illuminant = D65)
+ var var_Y = xyz[1] / 100 //Y from 0 to 100.000
+ var var_Z = xyz[2] / 100 //Z from 0 to 108.883
+
+ var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986
+ var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415
+ var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570
+
+ if ( var_R > 0.0031308 ) var_R = 1.055 * Math.pow( var_R, 1 / 2.4 ) - 0.055
+ else var_R = 12.92 * var_R
+ if ( var_G > 0.0031308 ) var_G = 1.055 * Math.pow( var_G, 1 / 2.4 ) - 0.055
+ else var_G = 12.92 * var_G
+ if ( var_B > 0.0031308 ) var_B = 1.055 * Math.pow( var_B, 1 / 2.4 ) - 0.055
+ else var_B = 12.92 * var_B
+
+ rgb[0] = clamp(var_R * 255, 0, 255)
+ rgb[1] = clamp(var_G * 255, 0, 255)
+ rgb[2] = clamp(var_B * 255, 0, 255)
+ return rgb
+ }
+ function rgb2xyz(RGB){
+ var var_R = ( RGB[0] / 255 ) // R from 0 to 255
+ var var_G = ( RGB[1] / 255 ) // G from 0 to 255
+ var var_B = ( RGB[2] / 255 ) // B from 0 to 255
+
+ if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4
+ else var_R = var_R / 12.92
+ if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4
+ else var_G = var_G / 12.92
+ if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4
+ else var_B = var_B / 12.92
+
+ var_R = var_R * 100
+ var_G = var_G * 100
+ var_B = var_B * 100
+
+ //Observer. = 2°, Illuminant = D65
+ var x = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
+ var y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
+ var z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
+ return [x,y,z]
+ }
+ function xyz2hunterlab (XYZ) {
+ var X = XYZ[0]
+ var Y = XYZ[1] || 1e-6 // otherwise divide-by-zero error when converting rgb(0,0,0)
+ var Z = XYZ[2]
+ var L = 10 * sqrt( Y )
+ var a = 17.5 * ( ( ( 1.02 * X ) - Y ) / sqrt( Y ) )
+ var b = 7 * ( ( Y - ( 0.847 * Z ) ) / sqrt( Y ) )
+ return [L,a,b]
+ }
+}
diff --git a/public/assets/javascripts/ui/editor/MediaEditor.js b/public/assets/javascripts/ui/editor/MediaEditor.js
index cc924da..750cf41 100644
--- a/public/assets/javascripts/ui/editor/MediaEditor.js
+++ b/public/assets/javascripts/ui/editor/MediaEditor.js
@@ -116,17 +116,18 @@ var MediaEditor = FormView.extend({
},
setDimensions: function(){
- this.$width.unitVal( Number(this.scenery.dimensions.a * this.scenery.scale) || "" )
- this.$height.unitVal( Number(this.scenery.dimensions.b * this.scenery.scale) || "" )
+ if (! this.scenery) return
+ this.$width.unitVal( Number(this.scenery.naturalDimensions.a * this.scenery.scale) || "" )
+ this.$height.unitVal( Number(this.scenery.naturalDimensions.b * this.scenery.scale) || "" )
},
changeWidth: function(e){
e.stopPropagation()
- this.scenery.set_scale( this.$width.unitVal() / this.scenery.dimensions.a )
+ this.scenery.set_scale( this.$width.unitVal() / this.scenery.naturalDimensions.a )
this.setDimensions()
},
changeHeight: function(e){
e.stopPropagation()
- this.scenery.set_scale( this.$height.unitVal() / this.scenery.dimensions.b )
+ this.scenery.set_scale( this.$height.unitVal() / this.scenery.naturalDimensions.b )
this.setDimensions()
},
changeUnits: function(){
@@ -137,11 +138,13 @@ var MediaEditor = FormView.extend({
bind: function(scenery){
this.scenery = scenery
this.scenery.mx.bound = true
+ this.scenery.mx.el.classList.add("picked")
},
unbind: function(){
if (this.scenery && this.scenery.mx) {
this.scenery.mx.bound = false
+ this.scenery.mx.el.classList.remove("picked")
}
this.scenery = null
},
diff --git a/public/assets/javascripts/ui/editor/MediaUpload.js b/public/assets/javascripts/ui/editor/MediaUpload.js
index 86bf767..92cf2bd 100644
--- a/public/assets/javascripts/ui/editor/MediaUpload.js
+++ b/public/assets/javascripts/ui/editor/MediaUpload.js
@@ -1,5 +1,5 @@
-var MediaUpload = View.extend({
+var MediaUpload = UploadView.extend({
el: ".fileUpload",
createAction: "/api/media/new",
@@ -7,16 +7,12 @@ var MediaUpload = View.extend({
events: {
"keydown .url": "enterSubmit",
- "change .file": "handleFileSelect",
- "submit form": "preventDefault",
},
initialize: function(opt){
+ this.__super__.initialize.call(this)
this.parent = opt.parent
- this.$csrf = this.$("[name=_csrf]")
this.$url = this.$(".url")
- this.$file = this.$(".file")
- this.$upload = this.$(".upload-icon")
},
show: function(){
@@ -45,7 +41,7 @@ var MediaUpload = View.extend({
return
}
- media._csrf = this.$csrf.val()
+ media._csrf = $("[name=_csrf]").val()
console.log(media)
var request = $.ajax({
@@ -57,68 +53,13 @@ var MediaUpload = View.extend({
}.bind(this))
},
- handleFileSelect: function(e) {
- e.stopPropagation();
- e.preventDefault();
-
- this.parent.mediaViewer.deleteArmed(false)
-
- var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
-
- for (var i = 0, f; f = files[i]; i++) {
- if ( ! f.type.match('image.*')) {
- continue;
- }
-
- this.getImageDimensions(f)
- }
- },
-
- getImageDimensions: function(f){
- var base = this
-
- this.$upload.addClass('uploading')
-
- var reader = new FileReader();
-
- reader.onload = function(e) {
- var image = new Image()
- image.onload = function(){
- var width = image.naturalWidth,
- height = image.naturalHeight
- base.upload(f, width, height)
- }
- image.src = e.target.result
- }
-
- reader.readAsDataURL(f);
- },
-
- upload: function(f, width, height){
- var fd = new FormData()
- fd.append('image', f)
- fd.append('width', width)
- fd.append('height', height)
- fd.append('_csrf', this.$csrf.val())
-
- var request = $.ajax({
- url: this.uploadAction,
- type: "post",
- data: fd,
- dataType: "json",
- processData: false,
- contentType: false,
- })
- request.done(this.add.bind(this))
- },
-
add: function(media){
console.log(media)
- if (media.error) {
- return
- }
- this.$upload.removeClass('uploading')
this.parent.mediaViewer.add(media)
+ },
+
+ beforeUpload: function(){
+ this.parent.mediaViewer.deleteArmed(false)
}
})
diff --git a/public/assets/javascripts/ui/editor/MediaViewer.js b/public/assets/javascripts/ui/editor/MediaViewer.js
index 40bfe80..7cfa863 100644
--- a/public/assets/javascripts/ui/editor/MediaViewer.js
+++ b/public/assets/javascripts/ui/editor/MediaViewer.js
@@ -2,6 +2,7 @@
var MediaViewer = ModalView.extend({
el: ".mediaDrawer.mediaViewer",
destroyAction: "/api/media/destroy",
+ usesFileUpload: true,
events: {
'click .foundToggle': "foundToggle",
diff --git a/public/assets/javascripts/ui/editor/WallpaperPicker.js b/public/assets/javascripts/ui/editor/WallpaperPicker.js
index 9ee441b..61ecb78 100644
--- a/public/assets/javascripts/ui/editor/WallpaperPicker.js
+++ b/public/assets/javascripts/ui/editor/WallpaperPicker.js
@@ -1,40 +1,70 @@
-var WallpaperPicker = View.extend({
+var WallpaperPicker = UploadView.extend({
el: ".wallpaper",
+ mediaTag: "wallpaper",
+ uploadAction: "/api/media/upload",
+
events: {
"click .swatch": 'pick',
- },
+ },
initialize: function(){
- var wm = new WallpaperManager()
- app.on('wallpaper-ready', function(){
- var black = [0,0,0,1.0]
- var white = [255,255,255,1.0]
- var swatches = wm.buildSwatches(black, white, 2)
- swatches.forEach(function(swatch){
- var dataUrl = swatch.toDataURL()
- var span = document.createElement('span')
- span.style.backgroundImage = "url(" + dataUrl + ")"
- span.className = "swatch"
- this.$el.append(span)
- }.bind(this))
- }.bind(this))
- wm.init()
+ this.__super__.initialize.call(this)
+ this.$swatches = this.$(".swatches")
+ },
+
+ loaded: false,
+ show: function(){
+ if (! this.loaded) {
+ this.load()
+ }
+ else {
+ this.toggle(true)
+ }
+ },
+
+ hide: function(){
+ this.__super__.hide.call(this)
},
- toggle: function(state){
- this.$el.toggleClass("active", state);
- // toggle the class that makes the cursor a paintbucket
- // $("body").removeClass("pastePaper");
+ load: function(){
+ $.get("/api/media/user", { tag: this.mediaTag }, this.populate.bind(this))
},
- show: function(){
- this.toggle(true)
+
+ populate: function(data){
+ console.log(data)
+ this.loaded = true
+ data && data.forEach(this.add.bind(this))
+ this.toggle(true)
+ },
+
+ add: function (media) {
+ if (media.type !== "image") { return }
+ var swatch = document.createElement("div")
+ swatch.className = "swatch"
+ swatch.style.backgroundImage = "url(" + media.url + ")"
+ this.$swatches.append(swatch)
+ },
+
+ toggle: function (state) {
+ if (state && ! this.loaded) {
+ this.show()
+ }
+ else {
+ this.$el.toggleClass("active", state)
+ }
+ // toggle the class that makes the cursor a paintbucket
+ // $("body").removeClass("pastePaper")
},
+
hide: function(){
this.toggle(false)
},
+ beforeUpload: function(){
+ },
+
pick: function(e){
var $swatch = $(e.currentTarget)
var $floatingSwatch = $(".floatingSwatch")
@@ -58,94 +88,6 @@ var WallpaperPicker = View.extend({
$floatingSwatch.show()
_followCursor(e);
})
- }
+ },
})
-
-// pattern
-// scale
-// foreground
-// background
-
-var WallpaperManager = function () {
-
- var image = new Image ()
- var imageData
- var w, h
-
- this.masks = []
-
- this.init = function(){
- this.load()
- }
-
- this.load = function(){
- image.onload = function(){
- this.loadImageData()
- this.buildMasks()
- app.tube('wallpaper-ready')
- }.bind(this)
-
- image.src = "/assets/img/palette.gif"
- }
-
- this.loadImageData = function(){
- var canvas = document.createElement('canvas')
- var ctx = canvas.getContext('2d')
- w = canvas.width = image.naturalWidth
- h = canvas.height = image.naturalHeight
- ctx.drawImage(image, 0,0)
- imageData = ctx.getImageData(0,0,image.naturalWidth,image.naturalHeight).data
- }
-
- this.buildMasks = function(){
- var mask
- for (var y = 0; y < 6; y++) {
- for (var x = 0; x < 16; x++) {
- mask = this.buildMask(x,y)
- this.masks.push(mask)
- }
- }
- }
-
- this.buildMask = function(x,y){
- // add the offset of the top-left swatch
- x = (x * 18) + 15
- y = (y * 16) + 5
-
- var mask = new Array(64)
- var t = 0
- for (var i = 0; i < 8; i++) {
- for (var j = 0; j < 8; j++) {
- t = ( w*(y+j) + x+i ) * 4
- mask[j*8+i] = imageData[t] === 0
- }
- }
- return mask
- }
-
- this.buildSwatches = function(black, white, scale) {
- var swatches = this.masks.map(function(mask){
- return this.buildSwatch(mask,black,white,scale)
- }.bind(this))
-
- return swatches
- }
-
- this.buildSwatch = function(mask,black,white,scale){
- black = 'rgba(' + black.join(',') + ')'
- white = 'rgba(' + white.join(',') + ')'
- var canvas = document.createElement("canvas")
- canvas.width = 8*scale
- canvas.height = 8*scale
- var ctx = canvas.getContext('2d')
- for (var i = 0; i < 8; i++) {
- for (var j = 0; j < 8; j++) {
- ctx.fillStyle = mask[j*8+i] ? black : white
- ctx.fillRect(i*scale, j*scale, scale, scale)
- }
- }
- return canvas
- }
-
-} \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/FormView.js b/public/assets/javascripts/ui/lib/FormView.js
index ab33bc0..17b748a 100644
--- a/public/assets/javascripts/ui/lib/FormView.js
+++ b/public/assets/javascripts/ui/lib/FormView.js
@@ -33,7 +33,7 @@ var FormView = View.extend({
},
serialize: function(){
- var fd = new FormData()
+ var fd = new FormData(), hasCSRF = false
this.$("input[name], select[name], textarea[name]").each( function(){
if (this.type == "file") {
@@ -48,9 +48,14 @@ var FormView = View.extend({
}
else {
fd.append(this.name, this.value);
+ hasCSRF = hasCSRF || this.name == "_csrf"
}
});
+ if (! hasCSRF) {
+ fd.append("_csrf", $("[name=_csrf]").val())
+ }
+
return fd
},
@@ -71,9 +76,12 @@ var FormView = View.extend({
return
}
}
+
+ var action = typeof this.action == "function" ? this.action() : this.action
+ if (! action) return
var request = $.ajax({
- url: this.action,
+ url: action,
type: this.method,
data: this.serialize(),
dataType: "json",
diff --git a/public/assets/javascripts/ui/lib/ModalView.js b/public/assets/javascripts/ui/lib/ModalView.js
index 937c1e9..d9b518a 100644
--- a/public/assets/javascripts/ui/lib/ModalView.js
+++ b/public/assets/javascripts/ui/lib/ModalView.js
@@ -10,9 +10,15 @@ var ModalView = View.extend({
}
},
+ usesFileUpload: false,
+
show: function(){
$(".mediaDrawer").removeClass("active")
- $(".fileUpload").removeClass("active")
+
+ if (! this.usesFileUpload) {
+ $(".fileUpload").removeClass("active")
+ }
+
this.$el.addClass("active")
$("body").addClass("noOverflow")
},
@@ -32,4 +38,5 @@ var ModalView = View.extend({
this.hide()
}
}
+
})
diff --git a/public/assets/javascripts/ui/lib/UploadView.js b/public/assets/javascripts/ui/lib/UploadView.js
new file mode 100644
index 0000000..efaa8c9
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/UploadView.js
@@ -0,0 +1,90 @@
+
+var UploadView = View.extend({
+
+ // define uploadAction
+
+ events: {
+ "change .file": "handleFileSelect",
+ "submit form": "preventDefault",
+ },
+
+ initialize: function(){
+ this.$file = this.$(".file")
+ this.$upload = this.$(".upload-icon")
+ },
+
+ beforeUpload: function(){
+ },
+
+ handleFileSelect: function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+
+ this.beforeUpload()
+
+ var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
+
+ for (var i = 0, f; f = files[i]; i++) {
+ if ( ! f.type.match('image.*')) {
+ continue;
+ }
+
+ this.getImageDimensions(f)
+ }
+ },
+
+ getImageDimensions: function(f){
+ var base = this
+
+ this.$upload.addClass('uploading')
+
+ var reader = new FileReader();
+
+ reader.onload = function(e) {
+ var image = new Image()
+ image.onload = function(){
+ var width = image.naturalWidth,
+ height = image.naturalHeight
+ base.upload(f, width, height)
+ }
+ image.src = e.target.result
+ }
+
+ reader.readAsDataURL(f);
+ },
+
+ upload: function(f, width, height){
+ var fd = new FormData()
+ fd.append('image', f)
+ fd.append('width', width)
+ fd.append('height', height)
+ fd.append('_csrf', $("[name=_csrf]").val())
+
+ if (this.mediaTag) {
+ fd.append('tag', this.mediaTag)
+ }
+
+ var request = $.ajax({
+ url: this.uploadAction,
+ type: "post",
+ data: fd,
+ dataType: "json",
+ processData: false,
+ contentType: false,
+ })
+ request.done(this.success.bind(this))
+ },
+
+ success: function(media){
+ if (media.error) {
+ return
+ }
+ this.$upload.removeClass('uploading')
+ this.add(media)
+ },
+
+ add: function(media){
+ console.log(media)
+ },
+
+})
diff --git a/public/assets/javascripts/ui/site/SignUpModal.js b/public/assets/javascripts/ui/site/SignUpModal.js
index 5c651ee..a452023 100644
--- a/public/assets/javascripts/ui/site/SignUpModal.js
+++ b/public/assets/javascripts/ui/site/SignUpModal.js
@@ -34,4 +34,3 @@ var SignUpModal = ModalFormView.extend({
}
})
-