diff options
28 files changed, 576 insertions, 277 deletions
diff --git a/public/assets/javascripts/rectangles/engine/map/draw.js b/public/assets/javascripts/rectangles/engine/map/draw.js index 3e185d2..7eb6e7c 100644 --- a/public/assets/javascripts/rectangles/engine/map/draw.js +++ b/public/assets/javascripts/rectangles/engine/map/draw.js @@ -10,7 +10,7 @@ Map.Draw = function(map, opt){ draw.animate = function(){ ctx.save() draw.clear() - // draw.ruler() + draw.fill("rgba(255,255,255,0.98)") if (opt.minimap) { ctx.translate( map.dimensions.a * 1/2, map.dimensions.b * 1/2) @@ -19,7 +19,7 @@ Map.Draw = function(map, opt){ ctx.scale( -1, 1 ) draw.coords() - draw.regions(Rooms.regions, [ "#fff" ]) + draw.regions(Rooms.regions, [ "#fff" ], "#000") draw.camera(scene.camera) } @@ -29,7 +29,7 @@ Map.Draw = function(map, opt){ ctx.translate( map.center.a, map.center.b ) ctx.scale( -1, 1 ) - draw.regions(Rooms.regions, [ "#f8f8f8" ]) + draw.regions(Rooms.regions, [ "#f8f8f8" ], "#000") draw.mouse(map.ui.mouse.cursor) draw.coords() scene && draw.camera(scene.camera) @@ -38,46 +38,81 @@ Map.Draw = function(map, opt){ ctx.restore() } + // changes the ctx temporarily draw.render = function(){ - ctx.save() + var thumbnail_width = 1000 + var thumbnail_height = 750 + + var extent = Rooms.extent() + var center = extent.center() + var extent_width = extent.width() + var extent_height = extent.height() + var zoom + if (extent_width > extent_height) { + zoom = thumbnail_width / extent.width() * 0.9 + } + else { + zoom = thumbnail_height / extent.height() * 0.9 + } + + var canvas = document.createElement("canvas") + ctx = canvas.getContext('2d') + canvas.width = thumbnail_width + canvas.height = thumbnail_height + draw.clear() - ctx.translate( map.dimensions.a * 1/2, map.dimensions.b * 1/2) - ctx.scale( map.zoom, map.zoom ) - ctx.translate( map.center.a, map.center.b ) + ctx.translate( thumbnail_width * 1/2, thumbnail_height * 1/2) + ctx.scale( zoom, zoom ) + ctx.translate( center.a, -center.b ) ctx.scale( -1, 1 ) - draw.regions(Rooms.regions, ["#fff"]) - draw.mouse(map.ui.mouse.cursor) - scene && draw.camera(scene.camera) - + draw.regions(Rooms.regions, ["#fff"], null) + ctx.restore() + + // invert opacity + var pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height) + var pixels = pixelData.data + for (var i = 0, k, _len = pixels.length; i < _len; i++) { + k = i*4 + if (pixels[k+3] == 0) { + pixels[k] = pixels[k+1] = pixels[k+2] = pixels[k+3] = 255 + } + else { + pixels[k] = pixels[k+1] = pixels[k+2] = 255 + pixels[k+3] = 0 + } + } + ctx.putImageData(pixelData, 0, 0) + + // reset the ctx + ctx = map.canvas.getContext("2d") + + return canvas } draw.clear = function(){ - ctx.fillStyle = "rgba(255,255,255,0.98)" ctx.clearRect(0, 0, map.dimensions.a, map.dimensions.b) - ctx.fillRect(0, 0, map.dimensions.a, map.dimensions.b) } - draw.ruler = function (){ - ctx.strokeStyle = "rgba(80,80,80,0.5)" - ctx.lineWidth = 1 - var len = 5 - for (var i = 0.5; i < map.dimensions.a; i += 10) { - line(i, 0, i, len) - line(0, i, len, i) - } + draw.fill = function(fillStyle){ + ctx.fillStyle = fillStyle + ctx.fillRect(0, 0, map.dimensions.a, map.dimensions.b) } - draw.regions = function(regions, colors){ + draw.regions = function(regions, colors, stroke){ + if (stroke) { + ctx.strokeStyle = "#000" + ctx.lineWidth = (1 / map.zoom) + } for (var i = 0; i < regions.length; i++) { if (regions[i].dupe) continue ctx.fillStyle = colors[i % colors.length] - ctx.strokeStyle = "#000" - ctx.lineWidth = (1 / map.zoom) fill_region(regions[i]) - stroke_sides(regions[i]) + if (stroke) { + stroke_sides(regions[i]) + } } } diff --git a/public/assets/javascripts/rectangles/engine/map/ui_editor.js b/public/assets/javascripts/rectangles/engine/map/ui_editor.js index f9334e6..02218ed 100644 --- a/public/assets/javascripts/rectangles/engine/map/ui_editor.js +++ b/public/assets/javascripts/rectangles/engine/map/ui_editor.js @@ -50,7 +50,7 @@ Map.UI.Editor = function(map){ return r.focused = r.rect.contains(cursor.x.a, cursor.y.a) }) - if (intersects.length && base.permissions.destroy) { + if (intersects.length && (base.permissions.destroy || e.altKey)) { base.mouse.down = false room = intersects[0] diff --git a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js index 6f96275..3603f0c 100644 --- a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js +++ b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js @@ -118,6 +118,14 @@ return data } + base.extent = function(){ + var extent = new Rect ( new vec2(Infinity, -Infinity), new vec2(Infinity, -Infinity) ) + base.forEach(function(room){ + extent.expand(room.rect) + }) + return extent + } + base.sorted_by_position = function(){ return sort.rooms_by_position( base.values() ) } diff --git a/public/assets/javascripts/rectangles/engine/rooms/_walls.js b/public/assets/javascripts/rectangles/engine/rooms/_walls.js index 5ff53fe..7ff472d 100644 --- a/public/assets/javascripts/rectangles/engine/rooms/_walls.js +++ b/public/assets/javascripts/rectangles/engine/rooms/_walls.js @@ -103,6 +103,10 @@ walls_data.forEach(function(wall_data){ if (! wall_data) { return } var wall = base.lookup[ wall_data.id ] + if (! wall) { + console.log(wall_data); + return + } wall.deserialize( wall_data ) }) }, @@ -133,7 +137,7 @@ $("#header").toggleClass("black", luminance < 128) $("body").css("background-color", rgbColor) - + Walls.colors.wall = rgb Walls.list.forEach(function(wall){ wall.outline(rgbaColor, null) diff --git a/public/assets/javascripts/rectangles/engine/rooms/mover.js b/public/assets/javascripts/rectangles/engine/rooms/mover.js index 5c7b4af..98f80c5 100644 --- a/public/assets/javascripts/rectangles/engine/rooms/mover.js +++ b/public/assets/javascripts/rectangles/engine/rooms/mover.js @@ -21,13 +21,6 @@ Rooms.mover = new function(){ base.update = function(pos){ var radius = scene.camera.radius - if (base.noclip) { - cam.x = pos.x - cam.y = pos.y - cam.z = pos.z - return - } - cam.y = pos.y // if we were in a room already.. @@ -42,14 +35,15 @@ Rooms.mover = new function(){ // check if we've breached one of the walls.. clamp position if so var collision = base.room.collidesDisc(pos.x, pos.z, radius) - if (collision) { + if (collision && ! base.noclip) { cam.x = (collision & LEFT_RIGHT) ? base.room.rect.x.clampDisc(pos.x, radius) : pos.x cam.z = (collision & FRONT_BACK) ? base.room.rect.y.clampDisc(pos.z, radius) : pos.z return } // in this case, we appear to have left the room.. - $(".face.active").removeClass("active") + // $(".face.active").removeClass("active") + $("body").css("background-color", "transparent") base.room = null } @@ -65,6 +59,7 @@ Rooms.mover = new function(){ // did we actually enter a room? if (intersects.length) { base.room = intersects[0] + $("body").css("background-color", rgb_string( Walls.colors.wall )) app.tube("change-room", { room: base.room }) } diff --git a/public/assets/javascripts/rectangles/models/rect.js b/public/assets/javascripts/rectangles/models/rect.js index a08176a..00f2c55 100644 --- a/public/assets/javascripts/rectangles/models/rect.js +++ b/public/assets/javascripts/rectangles/models/rect.js @@ -141,6 +141,29 @@ Rect.prototype.width = function(){ return this.x.length() } Rect.prototype.height = function(){ return this.y.length() } Rect.prototype.delta = function(){ return new vec2( this.x.magnitude(), this.y.magnitude() ) } + Rect.prototype.expand = function(rect){ + this.x.a = Math.min( this.x.a, rect.x.a ) + this.x.b = Math.max( this.x.b, rect.x.b ) + this.y.a = Math.min( this.y.a, rect.y.a ) + this.y.b = Math.max( this.y.b, rect.y.b ) + return this + } + Rect.prototype.square = function(){ + var width = this.x.length() + var height = this.y.length() + var diff + if (width < height) { + diff = (height - width) / 2 + this.x.a -= diff + this.x.b += diff + } + else { + diff = (width - height) / 2 + this.y.a -= diff + this.y.b += diff + } + return this + } Rect.prototype.toString = function(){ var sides = sidesToString(this.sides) var s = "[" + this.x.toString() + " " + this.y.toString() + "] " + sides diff --git a/public/assets/javascripts/rectangles/models/wall.js b/public/assets/javascripts/rectangles/models/wall.js index 8174de7..fcb2f5e 100644 --- a/public/assets/javascripts/rectangles/models/wall.js +++ b/public/assets/javascripts/rectangles/models/wall.js @@ -13,7 +13,7 @@ } var Wall = function(opt){ - this.id = [ opt.side, opt.edge, opt.vec.a ].join("_") + this.id = [ opt.side|0, opt.edge|0, opt.vec.a|0 ].join("_") this.vec = opt.vec this.edge = opt.edge this.side = opt.side diff --git a/public/assets/javascripts/ui/builder/BuilderSettings.js b/public/assets/javascripts/ui/builder/BuilderSettings.js index 94eed29..7ae6294 100644 --- a/public/assets/javascripts/ui/builder/BuilderSettings.js +++ b/public/assets/javascripts/ui/builder/BuilderSettings.js @@ -107,7 +107,7 @@ var BuilderSettings = FormView.extend({ }, serialize: function(){ - map.draw.render() + var thumbnail = map.draw.render() var fd = new FormData() fd.append( "_csrf", this.$csrf.val() ) fd.append( "_id", this.$id.val() ) @@ -115,7 +115,7 @@ var BuilderSettings = FormView.extend({ fd.append( "privacy", this.$privacy.filter(":checked").val() == "private" ) fd.append( "rooms", JSON.stringify( Rooms.serialize() ) ) fd.append( "startPosition", JSON.stringify( app.position(scene.camera) ) ) - fd.append( "thumbnail", dataUriToBlob(map.canvas.toDataURL()) ) + fd.append( "thumbnail", dataUriToBlob(thumbnail.toDataURL()) ) return fd }, diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js index fd251b7..0c08369 100644 --- a/public/assets/javascripts/ui/editor/EditorSettings.js +++ b/public/assets/javascripts/ui/editor/EditorSettings.js @@ -146,7 +146,6 @@ var EditorSettings = FormView.extend({ }, serialize: function(){ - map.draw.render() var fd = new FormData() fd.append( "_csrf", this.$csrf.val() ) fd.append( "_id", this.$id.val() ) @@ -160,7 +159,8 @@ var EditorSettings = FormView.extend({ fd.append( "startPosition", JSON.stringify( app.position(scene.camera) ) ) if (this.thumbnailIsStale()) { - fd.append( "thumbnail", dataUriToBlob(map.canvas.toDataURL()) ) + var thumbnail = map.draw.render() + fd.append( "thumbnail", dataUriToBlob(thumbnail.toDataURL()) ) } return fd }, diff --git a/public/assets/javascripts/ui/editor/MediaUpload.js b/public/assets/javascripts/ui/editor/MediaUpload.js index 971fb15..3f425c3 100644 --- a/public/assets/javascripts/ui/editor/MediaUpload.js +++ b/public/assets/javascripts/ui/editor/MediaUpload.js @@ -42,7 +42,6 @@ var MediaUpload = UploadView.extend({ } media._csrf = $("[name=_csrf]").val() - console.log(media) var request = $.ajax({ type: "post", @@ -55,7 +54,7 @@ var MediaUpload = UploadView.extend({ add: function(media){ console.log(media) - this.parent.mediaViewer.add(media) + this.parent.mediaViewer.add(media, this.parent.mediaViewer.$myMedia) this.parent.mediaViewer.$deleteMedia.show() }, diff --git a/public/assets/javascripts/ui/editor/MediaViewer.js b/public/assets/javascripts/ui/editor/MediaViewer.js index b51d8f2..1414e16 100644 --- a/public/assets/javascripts/ui/editor/MediaViewer.js +++ b/public/assets/javascripts/ui/editor/MediaViewer.js @@ -20,6 +20,7 @@ var MediaViewer = ModalView.extend({ this.$foundMedia = this.$(".foundMedia") this.$foundToggle = this.$(".foundToggle") this.$deleteMedia = this.$("#deleteMedia") + this.$noMedia = this.$(".noMedia") }, foundToggle: function(){ @@ -103,9 +104,11 @@ var MediaViewer = ModalView.extend({ data.forEach(function(media){ this.add(media, this.$myMedia) }.bind(this)) + this.$noMedia.hide() this.$deleteMedia.show() } else { + this.$noMedia.show() this.$deleteMedia.hide() } this.__super__.show.call(this) @@ -176,6 +179,7 @@ var MediaViewer = ModalView.extend({ if ($(".myMedia .mediaContainer").length == 0) { this.$deleteMedia.hide() + this.$noMedia.show() this.deleteArmed(false) } return diff --git a/public/assets/javascripts/ui/editor/WallpaperPicker.js b/public/assets/javascripts/ui/editor/WallpaperPicker.js index 140076d..6bf2542 100644 --- a/public/assets/javascripts/ui/editor/WallpaperPicker.js +++ b/public/assets/javascripts/ui/editor/WallpaperPicker.js @@ -133,7 +133,7 @@ var WallpaperPicker = UploadView.extend({ wall: null, pickWall: function(wall){ - if (wall.background.src == "none") { + if (! wall.background || wall.background.src == "none") { return; } this.wall = wall @@ -148,16 +148,16 @@ var WallpaperPicker = UploadView.extend({ initializePositionCursor: function(){ var base = this - var dx = 0, dy = 0, dragging = false + var dx = 0, dy = 0, dragging = false, delta var x = 0, y = 0, s = 1 var mymouse = new mouse({ el: this.$position[0], down: function(e, cursor){ if (! base.wall) return + dragging = true s = parseFloat( base.$scale.val() ) x = base.wall.background.x y = base.wall.background.y - dragging = true }, drag: function(e, cursor){ if (! dragging) return @@ -172,7 +172,6 @@ var WallpaperPicker = UploadView.extend({ }) }, up: function(e, cursor, new_cursor){ - delta.zero() dragging = false }, }) diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js index 1bfc6cb..99db2a3 100644 --- a/public/assets/javascripts/ui/site/LayoutsModal.js +++ b/public/assets/javascripts/ui/site/LayoutsModal.js @@ -3,6 +3,7 @@ var LayoutsIndex = View.extend({ initialize: function(){ this.$templates = this.$(".templates") + this.$templatesList = this.$(".templates-list") this.$noTemplates = this.$(".no-templates") this.$form = this.$("form") }, @@ -19,15 +20,21 @@ var LayoutsIndex = View.extend({ this.$form.hide() this.$noTemplates.show() } - this.$templates.empty() + this.$templatesList.empty() data.forEach(function(room){ var $span = $("<span>") - // $span.html(JSON.stringify(room)) $span.data("slug", room.slug) - $span.css("background-image", "url(" + room.photo + ")") - $span.attr("data-name", room.name) - this.$templates.append($span) + var $label = $("<label>") + $label.html( room.name ) + + var $image = $("<span>") + $image.addClass("image").css("background-image", "url(" + room.photo + ")") + + $span.append( $image ) + $span.append( $label ) + + this.$templatesList.append($span) }.bind(this)) this.show() } diff --git a/public/assets/javascripts/ui/site/ProjectList.js b/public/assets/javascripts/ui/site/ProjectList.js index 993d805..ebb0a96 100644 --- a/public/assets/javascripts/ui/site/ProjectList.js +++ b/public/assets/javascripts/ui/site/ProjectList.js @@ -1,16 +1,49 @@ - +var projectListTimeout = null var ProjectList = View.extend({ el: ".projectList", events: { - "mouseenter .room": 'spinOn', - "mouseleave .room": 'spinOff', + "mouseenter .room": 'enter', + "mouseleave .room": 'leave', }, initialize: function(){ + this.$(".images").each(function(){ + $divs = $(this).children("div") + $divs.hide() + $divs.first().show() + $(this).data("index", 0) + }) + }, + + timeout: null, + enter: function(e){ + clearTimeout(projectListTimeout) + this.advance(e.currentTarget) }, + leave: function(e){ + clearTimeout(projectListTimeout) + var $divs = $(e.currentTarget).find(".images div") + $divs.hide() + $divs.eq(0).show() + }, + + advance: function(el){ + projectListTimeout = setTimeout(function(){ + this.advance(el) + }.bind(this), 500) + var $images = $(el).find(".images") + var $divs = $images.children("div") + var index = $images.data("index") + var nextIndex = (index + 1) % $divs.length + $divs.eq(index).hide() + $divs.eq(nextIndex).show() + $images.data("index", nextIndex) + } + +/* spinOn: function(e){ var iframe = $(e.currentTarget).find("iframe").get('0') if (! iframe) return @@ -22,5 +55,6 @@ var ProjectList = View.extend({ if (! iframe) return iframe.contentWindow.postMessage("spin-off", window.location.origin) } +*/ }) diff --git a/public/assets/javascripts/ui/site/StaffView.js b/public/assets/javascripts/ui/site/StaffView.js index fdf39d2..0398f71 100644 --- a/public/assets/javascripts/ui/site/StaffView.js +++ b/public/assets/javascripts/ui/site/StaffView.js @@ -3,14 +3,19 @@ var StaffView = View.extend({ events: { "click #toggle-staff": "toggleStaff", + "click #toggle-featured": "toggleFeatured", }, initialize: function() { this.$toggleStaff = $("#toggle-staff") + this.$toggleFeatured = $("#toggle-featured") this.$mediaEmbed = $("#media-embed") if (this.$toggleStaff.length && this.$toggleStaff.data().isstaff) { this.$toggleStaff.html("Is Staff") } + if (this.$toggleFeatured.length && this.$toggleFeatured.data().featured) { + this.$toggleFeatured.html("Featured Project") + } if (this.$mediaEmbed.length) { var media = this.$mediaEmbed.data() this.$mediaEmbed.html( Parser.tag( media ) ) @@ -44,6 +49,24 @@ var StaffView = View.extend({ }.bind(this) }) }.bind(this)) + }, + + toggleFeatured: function(){ + var state = ! this.$toggleFeatured.data().featured + $.ajax({ + type: "put", + dataType: "json", + url: window.location.href + "/feature", + data: { + state: state, + _csrf: $("#_csrf").val(), + }, + success: function(data){ + this.$toggleFeatured.data("featured", data.state) + this.$toggleFeatured.html(data.state ? "Featured Project" : "Feature this project") + $("#isFeaturedProject").html(data.state ? "yes" : "no") + }.bind(this) + }) }, }) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 6e23962..a15ea39 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -10,7 +10,7 @@ body,textarea,input { font-family: 'Lato', sans-serif; } input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill { - background:white; + background:white!important; } *, *:before, *:after { moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; @@ -246,6 +246,11 @@ h5 { display: inline-block; } +.projectList { + border-top: 1px solid; +} + + .projectList.about { text-align: left; border-top: 1px solid; @@ -324,30 +329,42 @@ iframe.embed { z-index: -1; pointer-events: none; } -.projectList { - display: inline-block; - float: left; - width: 100%; -} + +.projectList a { + width: 32vw; + float:left; + clear: right; + padding-bottom: 2vw; +} .projectList .room { - width: 50%; - height:40vh; + width: 30vw; + height: 23vw; + margin: 1vw 1vw 0 1vw; display:table; position: relative; - float:left; - border-top:1px solid; + z-index: 1; } - -.projectList .room:nth-child(3n+2) { - border-right:1px solid black; +.projectList .holder { + position: absolute; + top: 50%; + z-index: 2; } -.projectList .room:nth-child(3n+1) { - width: 100%; - height: 50vh; +.room .mask { + position: absolute; + top: 0; left: 0; + z-index: 1; + width: 100%; + height: 100%; + text-align: center; + overflow: hidden; + background-color: #ddd; + background-size: cover; +} +.projectList a:hover .room .mask { + background-color: rgba(238,238,238,0.1); } - .room .images { position: absolute; top: 0; left: 0; @@ -357,16 +374,36 @@ iframe.embed { text-align: center; overflow: hidden; } -.room .images img { - max-height: 100%; - max-width: 100%; +.room .images div { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-size: cover; + background-position: center center; } +/* +.room .images[data-mediacount='1'] img:nth-child(1) { left: 20%; top: 20%; } + +.room .images[data-mediacount='2'] img:nth-child(1) { left: 51%; bottom: 0%; width: auto; height: 40%; } +.room .images[data-mediacount='2'] img:nth-child(2) { right: 51%; bottom: 50%; width: auto; height: 40%; } + +.room .images[data-mediacount='3'] img:nth-child(1) { right: 51%; bottom: 41%; } +.room .images[data-mediacount='3'] img:nth-child(2) { right: 51%; top: 61%; } +.room .images[data-mediacount='3'] img:nth-child(3) { left: 51%; bottom: 0%; width:auto; height:30%;} + +.room .images[data-mediacount='4'] img:nth-child(1) { right: 51%; bottom: 41%; } +.room .images[data-mediacount='4'] img:nth-child(2) { left: 51%; bottom: 61%; } +.room .images[data-mediacount='4'] img:nth-child(3) { right: 51%; top: 61%; } +.room .images[data-mediacount='4'] img:nth-child(4) { left: 51%; top: 41%; } +*/ + .page .btn { clear: both; padding: 30px 0; border: 0; - } .page .viewMore { @@ -385,18 +422,16 @@ iframe.embed { vertical-align: middle; } -.page .room .holder a { - font-weight: 300; - font-size: 20px; - letter-spacing: 1px; - color: black; - background: white; - border: 1px solid; - padding: 5px; - box-shadow: -3px 3px black; - text-decoration:none; - max-width: 180px; - display: inline-block; +.page .projectList label { + font-weight: 600; + font-size: 12px; + color: black; + text-decoration: none; + display: inline-block; + cursor: pointer; + border: 1px solid transparent; + line-height: 18px; + padding:0 5px; } .page .room .holder a:hover { @@ -404,6 +439,11 @@ iframe.embed { color:white; } +.projectList a:hover label { + background:black; + color:white; +} + .page .questions { background: #55efcb; @@ -437,11 +477,14 @@ iframe.embed { .page h1 { font-size: 80px; font-weight: 100; - padding: 60px 0 25px 0; + padding: 20px 0 25px 0; float: left; width: 100%; border-top: 1px solid; } +.page h1:nth-child(2) { + margin-top: 40px; +} .page p { margin: 20px; @@ -476,6 +519,8 @@ iframe.embed { width: 100%; padding: 80px 0; background: #f9f9f9; + float: left; + clear: both; } .footer a, .footer span{ @@ -499,6 +544,10 @@ iframe.embed { display:table; } +.noPic { + border-right: 1px solid; +} + .profilePic .ion-ios7-person-outline { font-size: 100px; } @@ -610,47 +659,86 @@ iframe.embed { .profilepage .bio span:last-of-type:after { display: none; } +.profilepage .about h2 { + text-align: center; + font-weight: 300; + font-size: 32px; +} +.profilepage .about h2:nth-child(2){ + margin:34px 0; +} +.about { + background-color: #ffffff;background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyODkuNScgaGVpZ2h0PScyODkuNScgdmlld0JveD0nMCAwIDI4OS41IDI4OS41Jz4KCTxkZWZzPgoJCTxwYXR0ZXJuIGlkPSdibHVlc3RyaXBlJyBwYXR0ZXJuVW5pdHM9J3VzZXJTcGFjZU9uVXNlJyB4PScwJyB5PScwJyB3aWR0aD0nNTcuOScgaGVpZ2h0PSc1Ny45JyB2aWV3Qm94PScwIDAgMTE1LjggMTE1LjgnID4KCQk8cmVjdCB3aWR0aD0nMTEwJScgaGVpZ2h0PScxMTAlJyBmaWxsPScjZmZmZmZmJy8+CgkJCTxwYXRoIGQ9J00xLDFoMTE1Ljh2MTE1LjhoLTExNS44di0xMTUuOCcgZmlsbC1vcGFjaXR5PScwJyBzdHJva2Utd2lkdGg9JzAuOCcgc3Ryb2tlLWRhc2hhcnJheT0nMCwxLDEnIHN0cm9rZT0nI2NjY2NjYycvPgoJCTwvcGF0dGVybj4gCgkJPGZpbHRlciBpZD0nZnV6eicgeD0nMCcgeT0nMCc+CgkJCTxmZVR1cmJ1bGVuY2UgdHlwZT0ndHVyYnVsZW5jZScgcmVzdWx0PSd0JyBiYXNlRnJlcXVlbmN5PScuMiAuMycgbnVtT2N0YXZlcz0nNScgc3RpdGNoVGlsZXM9J3N0aXRjaCcvPgoJCQk8ZmVDb2xvck1hdHJpeCB0eXBlPSdzYXR1cmF0ZScgaW49J3QnIHZhbHVlcz0nMCcvPgoJCTwvZmlsdGVyPgoJPC9kZWZzPgoJPHJlY3Qgd2lkdGg9JzEwMCUnIGhlaWdodD0nMTAwJScgZmlsbD0ndXJsKCNibHVlc3RyaXBlKScvPgo8cmVjdCB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJyBmaWx0ZXI9J3VybCgjZnV6eiknIG9wYWNpdHk9JzAnLz4KPC9zdmc+Cg=='); + background-attachment: fixed; + +} +.profilepage .about h2 .btn { + border: 1px solid; + font-weight: 500; + padding: 10px; + font-size: 18px; +} +.profilepage .about h2 .btn:hover { + background:black; + color:white; +} .templates { overflow: auto; - max-height: 80%; + max-height: 100%; width: 100%; + padding: 20px 0 40px 0; +} +.templates-list { + display: inline-block; + width: 100%; + margin-bottom: 40px; +} +.templates::-webkit-scrollbar { + width: 5px; + height: 5px; +} + +.templates::-webkit-scrollbar-thumb { +background-color: white; +border-left: 1px solid black; +} + +.templates::-webkit-scrollbar-track { + background-color: transparent; } + .no-templates { display: none; } -.templates span{ +.templates span { + display: block; + float: left; + margin: 1vw 0; + padding: 2vw; + cursor: pointer; +} +.templates span .image { background-position: center; - background-size: contain; - background-repeat: no-repeat; + background-size: cover; background-color: #fff; width: 20vw; - height: 20vh; - display: inline-block; - margin: 4vw; - border:1px solid black; - position: relative; + height: 15vw; + display: block; + background-color: #ddd; } -.templates span:after { - content: attr(data-name); - position: absolute; - top: 100%; +.templates span label { width: 100%; left: 0; - background: #fff; - padding: 5px; - border-top: 1px solid black; + display: block; font-weight: 300; } -.templates span:hover { - border:1px solid blue; - cursor:pointer; -} -.templates span:hover:after { - border-top: 1px solid blue; +.templates span:hover .image { + background-color: #f00; + cursor:pointer; } .templates h1 { @@ -1000,10 +1088,13 @@ iframe.embed { .mediaDrawer { -webkit-transform:translateY(-100%); transform:translateY(-100%); - background:rgba(255,255,255,0.9); + background:white; text-align:center; overflow-x: hidden; } +.editing .mediaDrawer { + background:rgba(255,255,255,0.95); +} .mediaDrawer.active { -webkit-transform:translateY(0%); transform:translateY(0%); @@ -1091,7 +1182,7 @@ iframe.embed { left: 50%; padding: 26px 20px; margin-left: -200px; - background: rgba(255,255,255,0.9); + background: rgba(255,255,255,0.99); z-index: 7; -webkit-transform: translateY(-1000%); -webkit-transition: -webkit-transform 0.6s ease-in-out; @@ -1123,7 +1214,7 @@ iframe.embed { border: 1px solid #ccc; font-size: 15px; padding: 5px; - width: 220px; + width: 290px; text-align: center; border-radius: 20px; } @@ -1215,8 +1306,6 @@ iframe.embed { color:white; } -.deleteArmed .mediaContainer { -} .deleteArmed .mediaContainer:hover { background:#FF3B30; @@ -1272,12 +1361,11 @@ iframe.embed { .mediaContainer { - border: 1px solid white; display: inline-block; width: 25%; margin: 4%; vertical-align: top; - border:1px solid white; + border:1px solid transparent; padding:2%; } .mediaContainer:hover { @@ -1589,6 +1677,7 @@ input[type="range"]::-webkit-slider-thumb { .settings.info { right: auto; left: 10px; + width: 230px; } .vvbox h4 { @@ -1669,6 +1758,7 @@ input[type="range"]::-webkit-slider-thumb { font-size: 12px; width: 100%; max-height: 200px; + max-width: 100%; } #textEditor.settings textarea { max-height: none; @@ -1895,6 +1985,8 @@ form div.hidden { } form h3.link { content:"?"; + margin-top: 0; + padding: 0 0 10px 0; } form h3.link:after { content:"?"; @@ -2256,6 +2348,7 @@ a[data-role="forgot-password"] { background-size: cover; display: inline-block; margin-right: 10px; + background-color: #ccc; } #collaborator-list .username { position: relative; @@ -2362,6 +2455,11 @@ a[data-role="forgot-password"] { width: 50%; height: 180px; } + .profilepage .about h2 { + text-align: center; + font-weight: 500; + font-size: 17px; + } .projectList.about { text-align: center; padding: 20px 0; diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css index aa21f9b..c75a9b1 100644 --- a/public/assets/stylesheets/staff.css +++ b/public/assets/stylesheets/staff.css @@ -28,15 +28,16 @@ nav { text-align: left; } nav a { - padding-left: 20px; + margin-left: 20px; } hr { border: 1px solid #bbb; - margin: 5px auto 10px; + margin: 10px auto 10px; + background: transparent; } .body { width: 80%; - margin: 0 auto; + margin: 40px auto; } .json { display: none; @@ -63,6 +64,8 @@ hr { .staff { font-size: 15px; } +.staff .body a { +} .staff .editLinks a { color: #00f; } diff --git a/public/favicon.ico b/public/favicon.ico Binary files differnew file mode 100644 index 0000000..19c9da3 --- /dev/null +++ b/public/favicon.ico diff --git a/server/lib/schemas/Project.js b/server/lib/schemas/Project.js index abf34fb..dd50da6 100644 --- a/server/lib/schemas/Project.js +++ b/server/lib/schemas/Project.js @@ -35,6 +35,7 @@ var ProjectSchema = new mongoose.Schema({ user_id: { type: mongoose.Schema.ObjectId, index: true }, created_at: { type: Date }, updated_at: { type: Date }, + featured: { type: Boolean, default: false }, }); module.exports = exports = mongoose.model('project', ProjectSchema); diff --git a/server/lib/views/index.js b/server/lib/views/index.js index ca48159..637b061 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -11,147 +11,164 @@ var User = require('../schemas/User'), moment = require('moment'); marked.setOptions({ - renderer: new marked.Renderer(), - gfm: true, - sanitize: true, - smartLists: true, - smartypants: true, + renderer: new marked.Renderer(), + gfm: true, + sanitize: true, + smartLists: true, + smartypants: true, }); -var views = {} +var views = module.exports = { -views.staff = require('./staff') + staff: require('./staff'), -views.editor_new = function (req, res) { - if (! req.user) { - res.redirect('/') - } - else { - res.locals.opt.editing = true - res.render('editor') - } -} + editor_new: function (req, res) { + if (! req.user) { + res.redirect('/') + } + else { + res.locals.opt.editing = true + res.render('editor') + } + }, -views.editor = function (req, res) { - if (! req.project) { - res.redirect('/') - } - else if (req.isOwner || req.isCollaborator || req.isStaff) { - res.locals.opt.editing = true - res.render('editor') - } - else { - views.reader(req, res) - } -} + editor: function (req, res) { + if (! req.project) { + res.redirect('/') + } + else if (req.isOwner || req.isCollaborator || req.isStaff) { + res.locals.opt.editing = true + res.render('editor') + } + else { + views.reader(req, res) + } + }, -views.reader = function (req, res) { - if (! req.project) { - res.redirect('/') - return - } - User.findOne({ _id: req.project.user_id }, function(err, user) { - if (err || ! user) { - console.error(err) + reader: function (req, res) { + if (! req.project) { res.redirect('/') return } - res.render('reader', { - name: util.sanitize(req.project.name), - description: util.sanitize(req.project.description), - date: moment(req.project.updated_at).format("M/DD/YYYY"), - author: user.displayName, - authorlink: "/profile/" + user.username, - canEdit: req.isOwner || req.isCollaborator, - editlink: "/project/" + req.project.slug + "/edit", - noui: !! (req.query.noui === '1'), + User.findOne({ _id: req.project.user_id }, function(err, user) { + if (err || ! user) { + console.error(err) + res.redirect('/') + return + } + res.render('reader', { + name: util.sanitize(req.project.name), + description: util.sanitize(req.project.description), + date: moment(req.project.updated_at).format("M/DD/YYYY"), + author: user.displayName, + authorlink: "/profile/" + user.username, + canEdit: req.isOwner || req.isCollaborator, + editlink: "/project/" + req.project.slug + "/edit", + noui: !! (req.query.noui === '1'), + }) }) - }) -} + }, -views.builder = function (req, res) { - res.render('builder') -} + builder: function (req, res) { + res.render('builder') + }, -views.modal = function (req, res) { - res.render('modal'); -}; + modal: function (req, res) { + res.render('modal'); + }, -views.home = function (req, res) { - if (req.user) { - Project.find({ privacy: false }) - .sort('-created_at') - .limit(20) - .exec(function(err, projects){ - res.render('home', { projects: projects || [] }) - }) - } - else { - res.send("<html></html>") - } -} + home: function (req, res) { + if (req.user) { + Project.find({ featured: true }) + .sort('-created_at') + .limit(6) + .exec(function(err, projects){ + projects = projects.map(function(project){ + project = project.toObject() + project.date = moment(project.updated_at).format("M/DD/YYYY") + if (! project.colors || project.colors.wall && project.colors.wall[0] == project.colors.wall[1] && project.colors.wall[1] == project.colors.wall[2] && project.colors.wall[2] > 238) { + project.color = [238,238,238] + } else { + project.color = project.colors.wall + } + return project + }) + res.render('home', { projects: projects || [] }) + }) + } + else { + res.send("<html></html>") + } + }, -views.docs = function (req, res){ - var name = req.params.name || "index" - - if (name === "new") { - res.render('docs', { - doc: { name: "new" }, - content: null, - isNew: true - }) - return - } - - Documentation.findOne({ name: name }, function(err, doc) { - if (err || ! doc) { - return res.render('docs', { - doc: { name: util.sanitize(name) }, + docs: function (req, res){ + var name = req.params.name || "index" + + if (name === "new") { + res.render('docs', { + doc: { name: "new" }, content: null, isNew: true }) + return } - res.render('docs', { - doc: doc, - content: marked(doc.body), - isNew: false - }) - }) -} -views.profile = function (req, res) { - var username = req.params.username || (req.user && req.user.username) - if (username) { - User.findOne({ username: username }, function (err, user) { - user ? next(user) : done(err, {}, []) + Documentation.findOne({ name: name }, function(err, doc) { + if (err || ! doc) { + return res.render('docs', { + doc: { name: util.sanitize(name) }, + content: null, + isNew: true + }) + } + res.render('docs', { + doc: doc, + content: marked(doc.body), + isNew: false + }) }) - } - else { - done() - } - - function next(user){ - var criteria = { user_id: user._id } - if ( ! (req.user && req.user._id && req.user._id == user._id) ) { - criteria.privacy = false + }, + + profile: function (req, res) { + var username = req.params.username || (req.user && req.user.username) + if (username) { + User.findOne({ username: username }, function (err, user) { + user ? next(user) : done(err, {}, []) + }) + } + else { + done() } - Project.find(criteria, function(err, projects){ - projects = projects.map(function(project){ - project = project.toObject() - project.date = moment(project.updated_at).format("M/DD/YYYY") - return project + + function next(user){ + var criteria = { user_id: user._id } + if ( ! (req.user && req.user._id && req.user._id == user._id) ) { + criteria.privacy = false + } + Project.find(criteria) + .sort('-created_at') + .exec(function(err, projects){ + projects = projects.map(function(project){ + project = project.toObject() + project.date = moment(project.updated_at).format("M/DD/YYYY") + if (! project.colors || project.colors.wall && project.colors.wall[0] == project.colors.wall[1] && project.colors.wall[1] == project.colors.wall[2] && project.colors.wall[2] > 238) { + project.color = [238,238,238] + } else { + project.color = project.colors.wall + } + return project + }) + done(err, user, projects) + }) + } + + function done(err, user, projects){ + if (! user) { return res.redirect('/') } + res.render('profile', { + profile: user, + projects: projects || [], }) - done(err, user, projects) - }) - } - - function done(err, user, projects){ - if (! user) { return res.redirect('/') } - res.render('profile', { - profile: user, - projects: projects || [], - }) + } } -} -module.exports = views +}
\ No newline at end of file diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index 41877c8..da09d83 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -389,6 +389,15 @@ var staff = module.exports = { staff.projects.show ); + app.put('/staff/projects/:slug/feature', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + middleware.ensureProject, + staff.middleware.ensureProject, + + staff.projects.feature + ); // // media @@ -505,6 +514,12 @@ var staff = module.exports = { res.render('staff/projects/show_404') } }, + feature: function(req, res){ + res.locals.project.featured = req.body.state == "true" + res.locals.project.save(function(err, project){ + res.json({ state: project.featured }) + }) + }, }, media: { diff --git a/views/controls/editor/media-drawer.ejs b/views/controls/editor/media-drawer.ejs index 10a160e..d800426 100644 --- a/views/controls/editor/media-drawer.ejs +++ b/views/controls/editor/media-drawer.ejs @@ -6,7 +6,7 @@ <input type="file" accept="image/*" class="file" multiple> </form> <small>~ or ~</small><br> - <input type="text" placeholder="Enter Vimeo or YouTube Link" class="url"> + <input type="text" placeholder="Enter Vimeo or YouTube or image link" class="url"> </span> <div class="ants"> @@ -20,6 +20,7 @@ <h3 class="editBtn warn" id="deleteMedia"></h3> <div class="myMedia"> + <div class="noMedia">You have no media yet. Upload some!</div> </div> <div class="foundMedia"> diff --git a/views/docs.ejs b/views/docs.ejs index 5662133..665190d 100644 --- a/views/docs.ejs +++ b/views/docs.ejs @@ -8,8 +8,6 @@ <div class="rapper page docs"> [[ include partials/header ]] - <br clear="all"> - [[ if (! isNew) { ]] <h1>[[- doc.displayName ]]</h1> diff --git a/views/home.ejs b/views/home.ejs index 51d5a92..16b00e7 100755 --- a/views/home.ejs +++ b/views/home.ejs @@ -10,7 +10,7 @@ </script> </head> <body class="loading"> - <div class="rapper page"> + <div class="rapper page home"> [[ include partials/header ]] <div class="hero" style="background-image:url(https://s3.amazonaws.com/luckyplop/6450f5b88c5c043a4551eff8902b1728f813bd66.jpg)"> @@ -23,7 +23,7 @@ </div> </div> - <h1>Whats VValls For?</h1> + <h1>What's VValls For?</h1> <div class="projectList about"> <div class="item wow bounceInLeft"> @@ -62,10 +62,9 @@ </div> <h1>Room Showcase</h1> - <img src="https://s3.amazonaws.com/uploads.hipchat.com/14935/55226/twq38ErgSnriaOq/vvalls-thumbnail-options2.gif" style="border-top:1px solid;width:100%"> - <!-- + [[ include projects/list-projects ]] - --> + <a href="#loadmore" class="viewMore btn">View More</a> [[ include partials/confirm-modal ]] diff --git a/views/profile.ejs b/views/profile.ejs index d977844..5ff2eb0 100644 --- a/views/profile.ejs +++ b/views/profile.ejs @@ -41,7 +41,7 @@ [[ } ]] </div> </div> - </div> + [[ if (projects.length) { ]] <h1>[[- profile.username ]] has [[- projects.length ]] project[[- projects.length != 1 ? "s" : "" ]]</h1> @@ -50,11 +50,23 @@ <a href="#" class="viewMore btn">view more</a> [[ } else { ]] + <h1>Welcome to VVALLS</h1> - <br><br> - You don't have any projects yet. To get started click "New Project" up at the top of the screen. + <div class="projectList about"> + <h2> + VValls lets you create awesome 3D rooms. + </h2> + + <h2> + You don't have any projects yet. + </h2> + <h2> + <a href="#"class="btn" data-role="new-project-modal">Create a New Project</a> + </h2> + + </div> [[ } ]] - + </div> [[ include partials/edit-profile ]] [[ include projects/layouts-modal ]] [[ include projects/edit-project ]] diff --git a/views/projects/layouts-modal.ejs b/views/projects/layouts-modal.ejs index 24a83b7..6f60d81 100644 --- a/views/projects/layouts-modal.ejs +++ b/views/projects/layouts-modal.ejs @@ -3,14 +3,17 @@ <div class="box"> <div class="templates"> - <h1>Edit Room Layouts</h1> + <h2>Edit Room Layouts</h2> + <div class="templates-list"> + </div> + <form> + <input data-role="create-new-layout" class="button_text" type="submit" value="New Layout"> + </form> </div> <div class="no-templates"> There are no room layouts available. Please <a href="/layout/new">create a new one.</a> </div> - <form> - <input data-role="create-new-layout" class="button_text" type="submit" value="New Layout"> - </form> + </div> </div> @@ -19,7 +22,9 @@ <div class="box"> <div class="templates"> - <h1>Your Projects</h1> + <h2>Your Projects</h2> + <div class="templates-list"> + </div> </div> <div class="no-templates"> </div> @@ -33,8 +38,14 @@ <span class="close">X</span> <div class="box"> - <h2>Choose Room Template</h2> <div class="templates"> + <h2>Select a Room Template</h2> + + <div class="templates-list"> + </div> + <form> + <input data-role="create-new-layout" class="button_text" type="submit" value="or make your own template"> + </form> </div> <div class="no-templates"> There are no room layouts available. Please <a href="/layout/new">create a new one.</a> diff --git a/views/projects/list-projects.ejs b/views/projects/list-projects.ejs index a12f237..c47dee0 100644 --- a/views/projects/list-projects.ejs +++ b/views/projects/list-projects.ejs @@ -4,31 +4,31 @@ [[ projects.forEach(function(project, i) { ]] - <span class="room"> - <span class="images"> - <img src="[[- project.photo ]]"> + [[ if (String(user._id) == String(project.user_id)) { ]] + <a href="/project/[[- project.slug ]]/edit"> + [[ } else { ]] + <a href="/project/[[- project.slug ]]" class="roomName"> + [[ } ]] + + <span class="room" style="background-color: rgb([[- project.color ]]);"> + <span class="mask" style="background-image: url([[- project.photo ]]);"> + </span> + <span class="images" data-mediaCount="[[- Math.min(project.media.length, 4) ]]"> [[ mediaCount = 0 ]] [[ project.media.some(function(media){ ]] [[ if (media.media.type != "image") { return false } ]] - [[ if (++mediaCount > 3) { return true } ]] - <img src="[[- media.media.url ]]"> + [[ if (++mediaCount > 4) { return true } ]] + <div style="background-image:url([[- media.media.url ]])"></div> [[ }) ]] </span> - - <div class="holder"> - [[ if (String(user._id) == String(project.user_id)) { ]] - <a href="/project/[[- project.slug ]]/edit"> - [[- project.name ]]<br> - [[- project.date ]] - </a> - [[ } else { ]] - <a href="/project/[[- project.slug ]]" class="roomName"> - [[- project.name ]]<br> - [[- project.date ]] - [[ } ]] - </div> </span> + <label> + [[- project.name ]]<br> + Created – [[- project.date ]] + </label> + + </a> [[ }) ]] </div> diff --git a/views/staff/projects/show.ejs b/views/staff/projects/show.ejs index 687f0c2..1034b31 100644 --- a/views/staff/projects/show.ejs +++ b/views/staff/projects/show.ejs @@ -41,8 +41,21 @@ "[[- project.description ]]" </td> </tr> + <tr> + <th> + featured? + </th> + <td id="isFeaturedProject"> + [[- project.featured ? "yes" : "no" ]] + </td> + </tr> </table> + <br><br> + <div id="actions"> + <button id="toggle-featured" data-featured="[[- !! project.featured ]]">Feature this Project</button> + </div> + <br> <br> <table id="iframe-embed" class="projectList"> |
