From 29e0f23c5ade5072851aaa74314166b0c7281272 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 23 Jan 2015 19:28:53 -0500 Subject: stub subscription modal js --- .../javascripts/ui/site/EditSubscriptionModal.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 public/assets/javascripts/ui/site/EditSubscriptionModal.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js new file mode 100644 index 0000000..1b3b859 --- /dev/null +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -0,0 +1,21 @@ + +var EditSubscriptionModal = ModalFormView.extend({ + el: ".mediaDrawer.editSubscription", + action: "/api/subscription", + method: "put", + + fixedClose: true, + + events: { + "click [data-role='changePasswordToggle']": 'togglePasswordFields' + }, + + load: function(){ + this.reset() + $.get("/api/subscription", function(data){ + + this.show() + }.bind(this)) + }, + +}) -- cgit v1.2.3-70-g09d2 From 3059c3203d2cec4e2e745be8c21c6d3fbddb0c14 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Wed, 28 Jan 2015 01:39:28 -0500 Subject: rigging EditSubscriptionModal --- Gruntfile.js | 1 + config.json.example | 1 - public/assets/javascripts/ui/_router.js | 10 ++++++++++ server/index.js | 1 + server/lib/api/subscription.js | 19 ++++++++++++++++--- server/lib/webhook/webhook.js | 14 ++++++++++++++ views/about/brochure.ejs | 3 +++ views/partials/edit-subscription.ejs | 1 - views/partials/scripts.ejs | 1 + 9 files changed, 46 insertions(+), 5 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/Gruntfile.js b/Gruntfile.js index f62cc82..ed236c5 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -99,6 +99,7 @@ module.exports = function(grunt) { "public/assets/javascripts/ui/site/LayoutsModal.js", "public/assets/javascripts/ui/site/EditProjectModal.js", "public/assets/javascripts/ui/site/EditProfileModal.js", + "public/assets/javascripts/ui/site/EditSubscriptionModal.js", "public/assets/javascripts/ui/site/DocumentModal.js", "public/assets/javascripts/ui/site/HomeView.js", diff --git a/config.json.example b/config.json.example index b8c310c..dc79edd 100644 --- a/config.json.example +++ b/config.json.example @@ -5,6 +5,5 @@ "socketPort": 1337, "webhookPort": 5000, "databaseHost": "lvh.me", - "pageSize": 10, "env": { "development": 1 } } diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index 3532428..9e7ce75 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -9,6 +9,7 @@ var SiteRouter = Router.extend({ "click [data-role='new-project-modal']": 'newProject', "click [data-role='edit-project-modal']": 'editProject', "click [data-role='edit-profile-modal']": 'editProfile', + "click [data-role='edit-subscription-modal']": 'editSubscription', "click [data-role='new-document-modal']": 'newDocument', "click [data-role='edit-document-modal']": 'editDocument', "click [data-role='destroy-document-modal']": 'destroyDocument', @@ -29,6 +30,7 @@ var SiteRouter = Router.extend({ "/profile": 'profile', "/profile/edit": 'editProfile', + "/profile/billing": 'editSubscription', "/profile/:name": 'profile', "/about/:name/edit": 'editDocument', "/about/new": 'newDocument', @@ -56,6 +58,7 @@ var SiteRouter = Router.extend({ "/profile": 'profile', "/profile/edit": 'editProfile', + "/profile/billing": 'editSubscription', "/profile/:name": 'profile', "/project/:name": 'projectViewer', @@ -69,6 +72,7 @@ var SiteRouter = Router.extend({ this.newProjectModal = new NewProjectModal() this.editProjectModal = new EditProjectModal() this.editProfileModal = new EditProfileModal() + this.editSubscriptionModal = new EditSubscriptionModal() this.passwordForgotModal = new PasswordForgot() this.documentModal = new DocumentModal() this.profileView = new ProfileView() @@ -195,6 +199,12 @@ var SiteRouter = Router.extend({ this.editProfileModal.load() }, + editSubscription: function(e){ + e && e.preventDefault() + window.history.pushState(null, document.title, "/profile/billing") + + this.editSubscriptionModal.load() + }, newDocument: function(e){ diff --git a/server/index.js b/server/index.js index 02fea3c..475054d 100644 --- a/server/index.js +++ b/server/index.js @@ -102,6 +102,7 @@ site.route = function () { app.get('/profile', views.profile) app.get('/profile/edit', views.profile) + app.get('/profile/billing', views.profile) app.get('/profile/:username', views.profile) app.get('/about', views.docs); diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index bd19127..83644cf 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -18,16 +18,29 @@ var subscription = module.exports = { }) }, */ - show: function(req,res){ + middleware: { + fetchAccount: function(req, res, next){ + recurly.subscriptions.listByAccount(req.user._id, function(data){ + }) + }, + }, + + // synchronise an account with recurly.. + // useful when testing locally (if webhooks do not fire) + sync: function(req, res){ + // fetch req.user._id + }, + + show: function(req, res){ // fetch from recurly }, - update: function(req,res){ + update: function(req, res){ // update plan_type on recurly // update add_ons on recurly }, - destroy: function(req,res){ + destroy: function(req, res){ // destroy on recurly }, diff --git a/server/lib/webhook/webhook.js b/server/lib/webhook/webhook.js index e9a7925..4f23d0b 100644 --- a/server/lib/webhook/webhook.js +++ b/server/lib/webhook/webhook.js @@ -134,7 +134,21 @@ var subscribe = module.exports = { }); }, + list: function(req, res){ + recurly.subscriptions.listByAccount(req.params.id, function(data){ + if (data.data != 404) { + res.json(data) + return + } + else { + res.json(data) + return + } + }) + }, + route: function(app){ app.post('/subscribe/webhook', subscribe.handle); + app.get('/subscribe/list/:id', subscribe.list); }, } diff --git a/views/about/brochure.ejs b/views/about/brochure.ejs index 1c808f8..49b03db 100644 --- a/views/about/brochure.ejs +++ b/views/about/brochure.ejs @@ -123,6 +123,9 @@ text-align: center; margin-bottom: 10px; } +.about_plan ul { + margin-bottom: 60px; +} .planbox li { list-style-type: none; margin-bottom: 5px; diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 1f8db62..adc3f71 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -44,7 +44,6 @@ - [[ } ]] diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index fc94992..04bd945 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -95,6 +95,7 @@ + -- cgit v1.2.3-70-g09d2 From 1d88890a988b255c915d0472297b18a2635f6433 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 30 Jan 2015 01:26:46 -0500 Subject: ui boilerplate --- .../javascripts/ui/site/EditSubscriptionModal.js | 40 ++++++++++++++++++++-- views/partials/edit-subscription.ejs | 28 +++++++-------- 2 files changed, 52 insertions(+), 16 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 1b3b859..342e8be 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -7,15 +7,51 @@ var EditSubscriptionModal = ModalFormView.extend({ fixedClose: true, events: { - "click [data-role='changePasswordToggle']": 'togglePasswordFields' + "click [data-role='']": 'togglePasswordFields' + }, + + initialize: function(){ + this.$freePlan = this.$("#free_plan") + this.$paidPlan = this.$("#paid_plan") + this.$proLayoutRow = this.$("#proLayoutRow") + + this.$billingInterval = this.$("[data-role=billingInterval]") + + this.$planType = this.$("[data-role=planType]") + this.$planName = this.$("[data-role=planName]") + this.$planCost = this.$("[data-role=planCost]") + + this.$basicLayoutCost = this.$("[data-role=basicLayoutCost]") + this.$basicLayoutQuantity = this.$("[data-role=basicLayoutQuantity]") + + this.$proLayoutCost = this.$("[data-role=proLayoutCost]") + this.$proLayoutQuantity = this.$("[data-role=proLayoutQuantity]") + + this.$upgradeSubscription = this.$("[data-role=upgradeSubscription]") + this.$cancelSubscription = this.$("[data-role=cancelSubscription]") }, load: function(){ this.reset() $.get("/api/subscription", function(data){ - + if (data.error) { + this.$freePlan.show() + this.$paidPlan.hide() + this.show() + return + } + this.$freePlan.show() + this.$paidPlan.hide() + + var plan = data.plans[ data.subscription.plan_name ] + this.show() + + // layouts }.bind(this)) }, + + updateTotals: function(){ + }, }) diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index adc3f71..f49d791 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -13,37 +13,37 @@

View the Plans -

- Your current plan level is + -
-

[[- plans.free.name ]]

-
    -
  • [[- plans.free.stock_project_limit ]] exhibition with pre-designed template floor plan -
-
- -
-

[[- plans.basic.name ]]

-
    -
  • $[[- plans.basic.monthly_price ]]/mo or $[[- plans.basic.yearly_price ]]/year -
  • Comes with [[- plans.basic.basic_layout_limit ]] basic floor plan and [[- plans.basic.basic_project_limit ]] exhibitions -
  • Each new basic floor plan costs $[[- plans.basic.basic_layout_monthly_price ]]/mo - or $[[- plans.basic.basic_layout_yearly_price ]]/year, minimum 3 months -
  • Each new floor plan can have up to [[- plans.basic.basic_project_limit ]] exhibitions -
  • VValls logo appears when embedding an exhibition on a web page -
  • - [[ if (! logged_in) { ]] - - [[ } else if (! user.plan_level) { ]] - - [[ } else if (user.plan_level == plan.level) { ]] - Current Level - [[ } ]] -
-
- -
-

[[- plans.pro.name ]]

-
    -
  • $[[- plans.pro.monthly_price ]]/mo or $[[- plans.pro.yearly_price ]]/year -
  • Comes with [[- plans.pro.pro_layout_limit ]] pro floor plan and [[- plans.pro.pro_project_limit ]] exhibitions -
  • Each new pro floor plan costs $[[- plans.pro.pro_layout_monthly_price ]]/mo - or $[[- plans.pro.pro_layout_yearly_price ]]/year, minimum 3 months -
  • Each new pro floor plan can have up to [[- plans.pro.pro_project_limit ]] exhibitions -
  • Includes planning for 3D objects in the room -
  • No VValls logo on embed -
  • - [[ if (! logged_in) { ]] - - [[ } else if (! user.plan_level) { ]] - - [[ } else if (user.plan_level == plan.level) { ]] - Current Level - [[ } else if (user.plan_level < plan.level) { ]] - - [[ } ]] -
-
- -
-
    -
  • Buying any extra floor plan unlocks collaboration. Invite an artist or curator to work on the exhibition with you. -
  • Basic Floor plan: Rectangle-based design of any dimension. -
  • Pro Floor plan: Trace an arbitrary floor plan from image. -
-
- -
-

Want Something Custom?

-
  • We offer customized white-label options for business and educational uses. -
  • Contact us for more information. -
  • + [[ include _plans ]]
    - [[ include ../partials/confirm-modal ]] [[ include ../projects/layouts-modal ]] [[ include ../partials/sign-in ]] @@ -91,51 +28,3 @@ [[ include ../partials/scripts ]] - \ No newline at end of file diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index bb7cc27..2f6e4c1 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -7,15 +7,14 @@
  • Edit Subscription

  • -
    - You are currently using the free plan. For access to all of Vvalls features, +
  • + You are currently using the free version of Vvalls. For access to all of Vvalls features, consider upgrading to a paid plan. -

    - View the Plans -

  • - + +
    +

    [[- plans.basic.name ]]

    +
      +
    • $[[- plans.basic.monthly_price ]]/mo or $[[- plans.basic.yearly_price ]]/year +
    • Comes with [[- plans.basic.basic_layout_limit ]] basic floor plan and [[- plans.basic.basic_project_limit ]] exhibitions +
    • Each new basic floor plan costs $[[- plans.basic.basic_layout_monthly_price ]]/mo + or $[[- plans.basic.basic_layout_yearly_price ]]/year, minimum 3 months +
    • Each new floor plan can have up to [[- plans.basic.basic_project_limit ]] exhibitions +
    • VValls logo appears when embedding an exhibition on a web page +
    • + [[ if (! logged_in) { ]] + + [[ } else if (! user.plan_level) { ]] + + [[ } else if (user.plan_level == plan.level) { ]] + Current Level + [[ } ]] +
    +
    + +
    +

    [[- plans.pro.name ]]

    +
      +
    • $[[- plans.pro.monthly_price ]]/mo or $[[- plans.pro.yearly_price ]]/year +
    • Comes with [[- plans.pro.pro_layout_limit ]] pro floor plan and [[- plans.pro.pro_project_limit ]] exhibitions +
    • Each new pro floor plan costs $[[- plans.pro.pro_layout_monthly_price ]]/mo + or $[[- plans.pro.pro_layout_yearly_price ]]/year, minimum 3 months +
    • Each new pro floor plan can have up to [[- plans.pro.pro_project_limit ]] exhibitions +
    • Includes planning for 3D objects in the room +
    • No VValls logo on embed +
    • + [[ if (! logged_in) { ]] + + [[ } else if (! user.plan_level) { ]] + + [[ } else if (user.plan_level == plan.level) { ]] + Current Level + [[ } else if (user.plan_level < plan.level) { ]] + + [[ } ]] +
    +
    + +
    +
      +
    • Buying any extra floor plan unlocks collaboration.
      Invite an artist or curator to work on the exhibition with you. +
    • Basic Floor plan: Rectangle-based design of any dimension. +
    • Pro Floor plan: Trace an arbitrary floor plan from image. +
    +
    + +
    +

    Want Something Custom?

    +
  • We offer customized white-label options for business and educational uses. +
  • Contact us for more information. +
  • diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 2f6e4c1..cc296f6 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -1,19 +1,19 @@
    X
    -
    +
    • Edit Subscription

    • -
    • +
    • You are currently using the free version of Vvalls. For access to all of Vvalls features, consider upgrading to a paid plan.

      - +
    • -
    • Your current plan level is diff --git a/views/staff/_users.ejs b/views/staff/_users.ejs index 053e289..46811b6 100644 --- a/views/staff/_users.ejs +++ b/views/staff/_users.ejs @@ -12,7 +12,8 @@ - - @@ -44,7 +42,8 @@
      [[- user.last_seen ]] -- cgit v1.2.3-70-g09d2 From a3f3f4d370da5d38c039f6cdb36223b396eeeb77 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 30 Jan 2015 17:59:29 -0500 Subject: sync gear for test purposes --- .../javascripts/ui/site/EditSubscriptionModal.js | 20 +++++++++++++++----- public/assets/stylesheets/app.css | 14 ++++++++++++++ server/index.js | 2 +- server/lib/api/subscription.js | 4 +++- views/partials/edit-subscription.ejs | 2 ++ 5 files changed, 35 insertions(+), 7 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index e7e1fa5..1637e18 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -2,6 +2,7 @@ var EditSubscriptionModal = ModalFormView.extend({ el: ".mediaDrawer.editSubscription", action: "/api/subscription", + syncAction: "/api/subscription/sync", updateAction: "/api/subscription", destroyAction: "/api/subscription/destroy", @@ -11,6 +12,7 @@ var EditSubscriptionModal = ModalFormView.extend({ events: { "click [data-role='upgradeSubscription']": 'upgradeSubscription', "click [data-role='cancelSubscription']": 'cancelSubscription', + "click .gear": 'sync', }, initialize: function(){ @@ -41,6 +43,7 @@ var EditSubscriptionModal = ModalFormView.extend({ this.$upgradeSubscription = this.$("[data-role=upgradeSubscription]") this.$cancelSubscription = this.$("[data-role=cancelSubscription]") + this.$gear = this.$(".gear") }, plan_levels: { @@ -48,10 +51,6 @@ var EditSubscriptionModal = ModalFormView.extend({ basic: 1, pro: 2, }, - - sync: function(){ - $.put(this.syncAction, this.didLoad.bind(this)) - }, loaded: false, load: function(){ @@ -74,6 +73,7 @@ var EditSubscriptionModal = ModalFormView.extend({ show: function(){ + this.$gear.removeClass("turning") if (! this.subscriber) { this.$freePlan.show() this.$paidPlan.hide() @@ -88,7 +88,7 @@ var EditSubscriptionModal = ModalFormView.extend({ this.$paidPlan.show() this.updateTotals() - + this.__super__.show.call(this) }, @@ -127,6 +127,16 @@ var EditSubscriptionModal = ModalFormView.extend({ this.$planTotal.toDollars ( totals.plan_total ) }, + sync: function(){ + this.$gear.addClass("turning") + $.ajax({ + url: this.syncAction, + type: "put", + data: { _csrf: $("[name=_csrf]").val() }, + success: this.didLoad.bind(this) + }) + }, + update: function(){ $.ajax({ url: this.updateAction, diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 8184032..981869b 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -979,6 +979,20 @@ iframe.embed { .about_custom a { border-bottom: 1px solid; } +.editSubscription .gear { + position: absolute; + top: 10px; + left: 10px; + opacity: 0.1; + cursor: pointer; + transition: all 0.3s; +} +.editSubscription .gear.turning { + opacity: 0.3; + -webkit-transform: rotate(360deg); + transform: rotate(360deg); +} + /* LAYOUTS MODAL */ diff --git a/server/index.js b/server/index.js index fa7044b..5c14d9d 100644 --- a/server/index.js +++ b/server/index.js @@ -151,9 +151,9 @@ site.route = function () { app.post('/api/media/upload', middleware.ensureAuthenticated, api.media.upload) app.delete('/api/media/destroy', middleware.ensureAuthenticated, api.media.destroy) - app.get('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.sync) app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show) app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.update) + app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.sync) app.delete('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy) app.get('/partials/plans', views.partials.plans) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 9c77dfc..4ec7709 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -8,7 +8,9 @@ var _ = require('lodash'), Project = require('../schemas/Project'), Layout = require('../schemas/Layout'), Plan = require('../schemas/Plan'); - Subscription = require('../schemas/Subscription'); + Subscription = require('../schemas/Subscription'), + Recurly = require('node-recurly'), + recurly = new Recurly(require('../webhook/recurly-config')); var plan_levels = { free: 0, diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index cc296f6..cfd5728 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -12,6 +12,7 @@ consider upgrading to a paid plan.

      +


    • Your current plan level is @@ -43,6 +44,7 @@
    • +
      -- cgit v1.2.3-70-g09d2 From 682b96ebb7210858e26157d1367b75efde9119e2 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 30 Jan 2015 18:11:55 -0500 Subject: follow links in profile brochure --- public/assets/javascripts/ui/site/EditSubscriptionModal.js | 9 ++++++--- public/assets/stylesheets/app.css | 12 ++++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 1637e18..b38894d 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -1,5 +1,5 @@ -var EditSubscriptionModal = ModalFormView.extend({ +var EditSubscriptionModal = ModalView.extend({ el: ".mediaDrawer.editSubscription", action: "/api/subscription", syncAction: "/api/subscription/sync", @@ -13,6 +13,7 @@ var EditSubscriptionModal = ModalFormView.extend({ "click [data-role='upgradeSubscription']": 'upgradeSubscription', "click [data-role='cancelSubscription']": 'cancelSubscription', "click .gear": 'sync', + "click .planList button": 'followLink', }, initialize: function(){ @@ -54,7 +55,6 @@ var EditSubscriptionModal = ModalFormView.extend({ loaded: false, load: function(){ - this.reset() if (this.loaded) { return this.show() } $.get(this.action, this.didLoad.bind(this)) }, @@ -70,7 +70,10 @@ var EditSubscriptionModal = ModalFormView.extend({ } return this.show() }, - + followLink: function(e){ + e.preventDefault(); + window.location.href = $(e.target).closest("a").attr("href") + }, show: function(){ this.$gear.removeClass("turning") diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 981869b..4826aef 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -989,8 +989,16 @@ iframe.embed { } .editSubscription .gear.turning { opacity: 0.3; - -webkit-transform: rotate(360deg); - transform: rotate(360deg); + -webkit-animation: gear 1s; + animation: gear 1s; +} +@-webkit-keyframes gear { + from { transform: rotate(0deg); } + to { transform: rotate(720deg); } +} +@keyframes gear { + from { transform: rotate(0deg); } + to { transform: rotate(720deg); } } -- cgit v1.2.3-70-g09d2 From 9e8364dd574c02c8a5605c3b09c0230a5476f9b1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 30 Jan 2015 18:30:37 -0500 Subject: sync working --- public/assets/javascripts/ui/site/EditSubscriptionModal.js | 1 + server/index.js | 2 +- server/lib/api/subscription.js | 9 +++++---- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index b38894d..28d699c 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -60,6 +60,7 @@ var EditSubscriptionModal = ModalView.extend({ }, didLoad: function(data){ this.loaded = true + console.log("didLoad", data) this.plans = data.plans if (data.subscription) { this.subscriber = data.subscription diff --git a/server/index.js b/server/index.js index 5c14d9d..9f28f59 100644 --- a/server/index.js +++ b/server/index.js @@ -153,7 +153,7 @@ site.route = function () { app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show) app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.update) - app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.sync) + app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.sync) app.delete('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy) app.get('/partials/plans', views.partials.plans) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 4ec7709..0801204 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -41,8 +41,9 @@ var subscription = module.exports = { sync: function(req, res){ var subscriber = req.subscription || new Subscription () var user = req.user - recurly.subscriptions.listByAccount(req.user._id, function(data){ - if (data.description !== 200) { + recurly.subscriptions.listByAccount(req.user._id, function(recurlyRes){ + var data = recurlyRes.data + if (recurlyRes.description !== 200) { res.json({ error: "no account" }) return } @@ -87,8 +88,8 @@ var subscription = module.exports = { subscriber.save(function(){ user.save(function(){ - res.render({ - subscription: req.subscription, + res.json({ + subscription: subscriber, plans: res.locals.plans }) }) -- cgit v1.2.3-70-g09d2 From 18c81b8a5c8ac4b6d9cbc16e370fcc37e9138cd6 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 30 Jan 2015 19:04:31 -0500 Subject: styling form --- .../javascripts/ui/site/EditSubscriptionModal.js | 4 ++-- public/assets/stylesheets/app.css | 27 ++++++++++++++++++++++ views/partials/edit-subscription.ejs | 27 ++++++++++++---------- 3 files changed, 44 insertions(+), 14 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 28d699c..0d54d8f 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -30,7 +30,7 @@ var EditSubscriptionModal = ModalView.extend({ this.$billingInterval = this.$("[data-role=billingInterval]") - this.$planType = this.$("[data-role=planType]") + this.$planName = this.$("[data-role=planName]") this.$planCost = this.$("[data-role=planCost]") this.$planTotal = this.$("[data-role=planTotal]") @@ -114,7 +114,7 @@ var EditSubscriptionModal = ModalView.extend({ var plan = this.plans[ this.plan_levels[ subscriber.plan_type ] ] var totals = this.calculateTotals(subscriber, plan) - this.$planType.html ( plan.name ) + this.$planName.html ( plan.name ) this.$planCost.toDollars ( totals.plan_price ) this.$billingInterval.html ( totals.is_monthly ? "mo." : "yr." ) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 4826aef..bedf2c4 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1000,6 +1000,33 @@ iframe.embed { from { transform: rotate(0deg); } to { transform: rotate(720deg); } } +.paidPlan { + text-align: left; + font-size: 14px; +} +.planInfo { + margin: 10px 0; + width: 100%; + padding: 0; +} +.planInfo td, .planInfo th { + text-align: left; + padding: 10px 3px; + margin: 0; +} +.planInfo td:nth-child(2), +.planInfo th:nth-child(2), +.planInfo td:nth-child(3), +.planInfo td:nth-child(4), +.planInfo th:nth-child(3) { + text-align: right; +} +.planInfo [data-role="billingInterval"] { + font-size: 10px; +} +.totalRow td:nth-child(4) { + border-top: 1px solid; +} /* LAYOUTS MODAL */ diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index cfd5728..266d43b 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -16,29 +16,32 @@
    • Your current plan level is - +
      - + - + + - + - - + + - + - - + + + - - - + + + +
      @ $/$/
      Additional Basic layoutsAdditional Basic layouts @ $/$each $/$/ Buy more
      Additional Pro layoutsAdditional Pro layouts @ $/$@ $ ...$/Buy more
      Total$Total$/
      -- cgit v1.2.3-70-g09d2 From 6a9418a4256c04c327262947f0fee3b615c93029 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 30 Jan 2015 20:27:42 -0500 Subject: buttonz --- .../javascripts/ui/site/EditSubscriptionModal.js | 7 ++++--- public/assets/stylesheets/app.css | 23 ++++++++++++++++++++-- views/partials/edit-subscription.ejs | 5 ++--- 3 files changed, 27 insertions(+), 8 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 0d54d8f..6823740 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -10,7 +10,8 @@ var EditSubscriptionModal = ModalView.extend({ subscriber: null, events: { - "click [data-role='upgradeSubscription']": 'upgradeSubscription', + "click [data-role='addLayouts']": 'addLayouts', + "click [data-role='changePlan']": 'changePlan', "click [data-role='cancelSubscription']": 'cancelSubscription', "click .gear": 'sync', "click .planList button": 'followLink', @@ -141,11 +142,11 @@ var EditSubscriptionModal = ModalView.extend({ }) }, - update: function(){ + update: function(data){ $.ajax({ url: this.updateAction, type: "put", - data: { _csrf: this.$csrf.val() }, + data: { _csrf: $("[name=_csrf]").val() }, success: function(data){ } }) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index bedf2c4..2570bb2 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -985,12 +985,15 @@ iframe.embed { left: 10px; opacity: 0.1; cursor: pointer; + -webkit-transition: all 0.3s; + -webkit-transform-origin: 49% 53%; transition: all 0.3s; + transform-origin: 49% 53%; } .editSubscription .gear.turning { opacity: 0.3; - -webkit-animation: gear 1s; - animation: gear 1s; + -webkit-animation: gear 1s infinite linear; + animation: gear 1s infinite linear; } @-webkit-keyframes gear { from { transform: rotate(0deg); } @@ -1027,6 +1030,22 @@ iframe.embed { .totalRow td:nth-child(4) { border-top: 1px solid; } +.paidPlan button { + width: 200px; + float: none; + margin: 5px 7px; +} +.paidPlan [data-role="cancelSubscription"] { + color: red; + width: 200px; + float: none; +} +.paidPlan [data-role="cancelSubscription"]:hover { + color: white; + background: red; + border-color: red; +} + /* LAYOUTS MODAL */ diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 266d43b..8599fb5 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -28,14 +28,12 @@
    • each $/ $/Buy more
      Additional Pro layouts @ $ ... $/Buy more
      $/
      - + +
    • -- cgit v1.2.3-70-g09d2 From d08c86d68ceb22665b735054fc3bc316f85f84c1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 31 Jan 2015 08:51:55 -0500 Subject: billing link in footer --- public/assets/javascripts/ui/site/EditSubscriptionModal.js | 12 ++++++++++-- server/lib/auth/index.js | 4 ++-- views/partials/footer.ejs | 6 ++++++ 3 files changed, 18 insertions(+), 4 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 6823740..82f6903 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -12,7 +12,7 @@ var EditSubscriptionModal = ModalView.extend({ events: { "click [data-role='addLayouts']": 'addLayouts', "click [data-role='changePlan']": 'changePlan', - "click [data-role='cancelSubscription']": 'cancelSubscription', + "click [data-role='cancelSubscription']": 'destroy', "click .gear": 'sync', "click .planList button": 'followLink', }, @@ -132,6 +132,13 @@ var EditSubscriptionModal = ModalView.extend({ this.$planTotal.toDollars ( totals.plan_total ) }, + addLayouts: function(e){ + e.preventDefault() + }, + changePlan: function(e){ + e.preventDefault() + }, + sync: function(){ this.$gear.addClass("turning") $.ajax({ @@ -152,7 +159,8 @@ var EditSubscriptionModal = ModalView.extend({ }) }, - destroy: function(){ + destroy: function(e){ + e.preventDefault() var msg = "Are you sure you want to cancel your subscription?" ConfirmModal.confirm(msg, function(){ $.ajax({ diff --git a/server/lib/auth/index.js b/server/lib/auth/index.js index a9a2400..199377d 100644 --- a/server/lib/auth/index.js +++ b/server/lib/auth/index.js @@ -135,12 +135,12 @@ var auth = { deserializeUser: function (id, done) { try { var _id = mongoose.Types.ObjectId(id) - User.findOne({ _id: _id }, "_id displayName username photo isStaff", function (err, user) { + User.findOne({ _id: _id }, "_id displayName username photo isStaff plan_level", function (err, user) { done(err, user); }); } catch (e) { - User.findOne({ twitter_id: id }, "_id displayName username photo isStaff", function (err, user) { + User.findOne({ twitter_id: id }, "_id displayName username photo isStaff plan_level", function (err, user) { done(err, user); }); } diff --git a/views/partials/footer.ejs b/views/partials/footer.ejs index e3c572f..8a95fc4 100644 --- a/views/partials/footer.ejs +++ b/views/partials/footer.ejs @@ -15,6 +15,12 @@ About How To + + [[ if (logged_in && user.plan_level > 0) { ]] + Billing + [[ } else { ]] + Subscribe + [[ } ]] Terms Privacy Contact -- cgit v1.2.3-70-g09d2 From af230e59ec431c9b617b0caf94dc7c37bb5e81af Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 31 Jan 2015 09:16:27 -0500 Subject: handle cancelled subscription --- .../javascripts/ui/site/EditSubscriptionModal.js | 5 +- server/index.js | 2 +- server/lib/api/subscription.js | 78 +++++++++++++--------- server/lib/schemas/Subscription.js | 2 +- 4 files changed, 51 insertions(+), 36 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 82f6903..7dd527a 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -61,7 +61,6 @@ var EditSubscriptionModal = ModalView.extend({ }, didLoad: function(data){ this.loaded = true - console.log("didLoad", data) this.plans = data.plans if (data.subscription) { this.subscriber = data.subscription @@ -163,11 +162,13 @@ var EditSubscriptionModal = ModalView.extend({ e.preventDefault() var msg = "Are you sure you want to cancel your subscription?" ConfirmModal.confirm(msg, function(){ + this.__super__.show.call(this) $.ajax({ url: this.destroyAction, type: "delete", - data: { _csrf: this.$csrf.val() }, + data: { _csrf: $("[name=_csrf]").val() }, success: function(data){ + window.location.href = "/" } }) }.bind(this)) diff --git a/server/index.js b/server/index.js index 9f28f59..3572675 100644 --- a/server/index.js +++ b/server/index.js @@ -154,7 +154,7 @@ site.route = function () { app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show) app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.update) app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.sync) - app.delete('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy) + app.delete('/api/subscription/destroy', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy) app.get('/partials/plans', views.partials.plans) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 0801204..285ce8b 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -51,40 +51,51 @@ var subscription = module.exports = { res.json({ error: "account error" }) return } + if (subscriber.state != "active") { + user.plan_type = "free" + user.plan_level = plan_levels["free"] - var plan = data.subscriptions.subscription.plan.plan_code.split("-") - var plan_type = plan[0] - var plan_period = plan[1] - - user.plan_type = plan_type - user.plan_level = plan_levels[plan_type] + return subscriber.remove(function(){ + user.save(function(){ + res.json({ error: "account cancelled" }) + }) + }) + } + else { + var plan = data.subscriptions.subscription.plan.plan_code.split("-") + var plan_type = plan[0] + var plan_period = plan[1] + + user.plan_type = plan_type + user.plan_level = plan_levels[plan_type] - subscriber.uuid = data.subscriptions.subscription.uuid - subscriber.user_id = user._id - subscriber.plan_type = plan_type - subscriber.plan_period = plan_period - subscriber.plan_level = plan_levels[plan_type] - - var add_ons = data.subscriptions.subscription.subscription_add_ons.subscription_add_on - if (add_ons) { - if (add_ons.add_on_code) { - add_ons = [ add_ons ] - } - // TODO: handle multiple add-ons.. presumably this will work - add_ons.forEach(function(add_on){ - var add_on_type = add_on.add_on_code.split("-")[1] - if (add_on_type == "basic") { - subscriber.basic_layouts = parseInt( add_on.quantity._ ) - } - if (add_on_type == "pro") { - subscriber.pro_layouts = parseInt( add_on.quantity._ ) - } - }) - } - else { - subscriber.basic_layouts = 0 - subscriber.pro_layouts = 0 - } + subscriber.uuid = data.subscriptions.subscription.uuid + subscriber.user_id = user._id + subscriber.plan_type = plan_type + subscriber.plan_period = plan_period + subscriber.plan_level = plan_levels[plan_type] + + var add_ons = data.subscriptions.subscription.subscription_add_ons.subscription_add_on + if (add_ons) { + if (add_ons.add_on_code) { + add_ons = [ add_ons ] + } + // TODO: handle multiple add-ons.. presumably this will work + add_ons.forEach(function(add_on){ + var add_on_type = add_on.add_on_code.split("-")[1] + if (add_on_type == "basic") { + subscriber.basic_layouts = parseInt( add_on.quantity._ ) + } + if (add_on_type == "pro") { + subscriber.pro_layouts = parseInt( add_on.quantity._ ) + } + }) + } + else { + subscriber.basic_layouts = 0 + subscriber.pro_layouts = 0 + } + } subscriber.save(function(){ user.save(function(){ @@ -156,6 +167,9 @@ var subscription = module.exports = { subscriber.remove(function(){ req.user.plan_code = 0 req.user.plan_type = "free" + req.user.save(function(){ + res.json({ status: "OK" }) + }) }) }) }, diff --git a/server/lib/schemas/Subscription.js b/server/lib/schemas/Subscription.js index 44455a9..355bbe2 100644 --- a/server/lib/schemas/Subscription.js +++ b/server/lib/schemas/Subscription.js @@ -12,7 +12,7 @@ var SubscriptionSchema = new mongoose.Schema({ plan_type: { type: String, default: "free" }, plan_period: { type: String, default: "monthly" }, - subscription_uuid: { type: String }, + uuid: { type: String }, basic_layouts: { type: Number, default: 0 }, pro_layouts: { type: Number, default: 0 }, -- cgit v1.2.3-70-g09d2 From 85728db4898e88592d9e89510bf121de91e59a6f Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 31 Jan 2015 10:17:12 -0500 Subject: .. --- public/assets/javascripts/ui/site/EditSubscriptionModal.js | 5 ++--- server/lib/api/subscription.js | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 7dd527a..0f72995 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -162,14 +162,13 @@ var EditSubscriptionModal = ModalView.extend({ e.preventDefault() var msg = "Are you sure you want to cancel your subscription?" ConfirmModal.confirm(msg, function(){ - this.__super__.show.call(this) $.ajax({ url: this.destroyAction, type: "delete", data: { _csrf: $("[name=_csrf]").val() }, success: function(data){ - window.location.href = "/" - } + this.didLoad(data) + }.bind(this) }) }.bind(this)) }, diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index b8853e6..3a8403f 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -55,7 +55,6 @@ var subscription = module.exports = { } return false }) - console.log(data.subscriptions) if (! is_active) { set_cancelled() } -- cgit v1.2.3-70-g09d2 From ef52758ef0c27760a93ca861f1d17259dbc40fc4 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 31 Jan 2015 19:10:24 -0500 Subject: adding radio buttons etc --- .../javascripts/ui/site/EditSubscriptionModal.js | 31 +++++++++++++++++-- public/assets/stylesheets/app.css | 11 +++++-- server/index.js | 2 +- server/lib/api/subscription.js | 2 +- views/partials/edit-subscription.ejs | 35 +++++++++++++++++----- 5 files changed, 68 insertions(+), 13 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 0f72995..619bff8 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -35,6 +35,11 @@ var EditSubscriptionModal = ModalView.extend({ this.$planCost = this.$("[data-role=planCost]") this.$planTotal = this.$("[data-role=planTotal]") + this.$basicPlanName = this.$("[data-role=basicPlanName]") + this.$proPlanName = this.$("[data-role=proPlanName]") + this.$basicPlanCost = this.$("[data-role=basicPlanCost]") + this.$proPlanCost = this.$("[data-role=proPlanCost]") + this.$basicLayoutCost = this.$("[data-role=basicLayoutCost]") this.$basicLayoutQuantity = this.$("[data-role=basicLayoutQuantity]") this.$basicLayoutTotal = this.$("[data-role=basicLayoutTotal]") @@ -43,8 +48,24 @@ var EditSubscriptionModal = ModalView.extend({ this.$proLayoutQuantity = this.$("[data-role=proLayoutQuantity]") this.$proLayoutTotal = this.$("[data-role=proLayoutTotal]") + this.$showLayoutsMenu = this.$("[data-role=showLayoutsMenu]") + this.$showPlanMenu = this.$("[data-role=showPlanMenu]") + + this.$layoutsMenu = this.$("[data-role=layoutsMenu]") + this.$planMenu = this.$("[data-role=planMenu]") + this.$closeMenu = this.$("[data-role=closeMenu]") + + this.$buyLayouts = this.$("[data-role=buyLayouts]") + + this.$changePlan = this.$("[data-role=changePlan]") + + this.$basicLayoutInput = this.$("[data-role=basicLayoutInput]") + this.$proLayoutInput = this.$("[data-role=proLayoutInput]") + this.$planRadio = this.$("[name=planRadio]") + this.$upgradeSubscription = this.$("[data-role=upgradeSubscription]") this.$cancelSubscription = this.$("[data-role=cancelSubscription]") + this.$gear = this.$(".gear") }, @@ -100,7 +121,7 @@ var EditSubscriptionModal = ModalView.extend({ var t = {} t.is_pro = plan.name == "pro" t.is_monthly = subscriber.plan_period == "monthly" - t.plan_price = t.is_monthly ? plan.monthly_price : plan.yearly_price + t.plan_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.yearly_price t.basic_layout_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.basic_layout_yearly_price t.basic_layout_total = subscriber.basic_layouts * t.basic_layout_price t.pro_layout_price = t.is_monthly ? plan.pro_layout_monthly_price : plan.pro_layout_yearly_price @@ -113,12 +134,18 @@ var EditSubscriptionModal = ModalView.extend({ var subscriber = this.subscriber var plan = this.plans[ this.plan_levels[ subscriber.plan_type ] ] var totals = this.calculateTotals(subscriber, plan) + + this.$basicPlanName.html ( this.plans[1].name ) + this.$proPlanName.html ( this.plans[2].name ) + this.$basicPlanCost.toDollars ( totals.is_monthly ? this.plans[1].monthly_price : this.plans[2].yearly_price) + this.$proPlanCost.toDollars ( totals.is_monthly ? this.plans[2].monthly_price : this.plans[2].yearly_price) this.$planName.html ( plan.name ) this.$planCost.toDollars ( totals.plan_price ) this.$billingInterval.html ( totals.is_monthly ? "mo." : "yr." ) - this.$proLayoutRow.toggle ( totals.is_pro ) + this.$basicLayoutRow.toggle ( subscriber.basic_layouts > 0 ) + this.$proLayoutRow.toggle ( totals.is_pro && subscriber.pro_layouts > 0) this.$basicLayoutCost.toDollars ( totals.basic_layout_price ) this.$basicLayoutQuantity.html ( subscriber.basic_layouts ) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 082a2d4..4144b8b 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -987,6 +987,8 @@ iframe.embed { font-size: 1.9vw; padding: 0; } + +/* debug sync button */ .editSubscription .gear { position: absolute; top: 10px; @@ -1053,8 +1055,13 @@ iframe.embed { background: red; border-color: red; } - - +/* purchase mode */ +.paidPlan input[type=number] { display: none } +.paidPlan.editing input[type=number] { display: inline-block } +.paidPlan.editing input[type=number]+span { display: none } +form .paidPlan div { float: none; } +form .paidPlan label { float: none; font-size: 2vw; margin: 0 10px; } +.paidPlan .upgradeMenu div { padding: 5px 10px; } /* LAYOUTS MODAL */ diff --git a/server/index.js b/server/index.js index 3572675..8c8212f 100644 --- a/server/index.js +++ b/server/index.js @@ -72,7 +72,7 @@ site.setup = function(){ server = http.createServer(app) server.listen(app.get('port'), function () { - console.log('Vvalls server listening on port ' + app.get('port')); + console.log('VValls server listening on port ' + app.get('port')); }); // var io = websocket.listen(server) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 3a8403f..6f08e66 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -28,7 +28,7 @@ var subscription = module.exports = { }) }, ensurePlans: function(req, res, next){ - Plan.find({}).sort({ 'level': -1 }).exec(function (err, plans) { + Plan.find({}).sort({ 'level': 1 }).exec(function (err, plans) { res.locals.plans = (plans || []) next() }) diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 69ec88d..fcb4b94 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -8,13 +8,13 @@

      Edit Subscription

    • - You are currently using the free version of Vvalls. For access to all of Vvalls features, + You are currently using the free version of VValls. For access to all of VValls features, consider upgrading to a paid plan.




    • -
    • +
    • Your current plan level is @@ -25,13 +25,13 @@ - + - + @@ -42,9 +42,30 @@
      Additional Basic layouts each $/ $/
      Additional Pro layouts @ $ ... $/
      $/
      - - - +
      + + + +
      +
      + + +
      +
      +

      Select desired plan:

      +
      + + + $/ +
      +
      + + + $/ +
      + + +
    -- cgit v1.2.3-70-g09d2 From a7be7295ae568bee76f18e3cf1228168b265db76 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 14:32:25 -0500 Subject: setting up events --- .../javascripts/ui/site/EditSubscriptionModal.js | 44 ++++++++++++++++------ 1 file changed, 32 insertions(+), 12 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 619bff8..af3b99e 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -15,14 +15,30 @@ var EditSubscriptionModal = ModalView.extend({ "click [data-role='cancelSubscription']": 'destroy', "click .gear": 'sync', "click .planList button": 'followLink', + + "click [data-role=showLayoutsMenu]": "layoutsMode", + "click [data-role=showPlanMenu]": "planMode", + + "click [data-role=closeMenu]": "reset", + + "input [data-role=basicLayoutInput]": "updateQuantity", + "input [data-role=proLayoutInput]": "updateQuantity", + "click [data-role=buyLayouts]": "saveLayouts", + + "input [name=planRadio]": "updatePlan", + "click [data-role=changePlan]": "savePlan", }, initialize: function(){ // this.parent = opt.parent this.__super__.initialize.call(this) + // two sections this.$freePlan = this.$(".freePlan") this.$paidPlan = this.$(".paidPlan") + + // subscription table + this.$planInfo = this.$(".planInfo") this.$planRow = this.$(".planRow") this.$basicLayoutRow = this.$(".basicLayoutRow") this.$proLayoutRow = this.$(".proLayoutRow") @@ -31,15 +47,18 @@ var EditSubscriptionModal = ModalView.extend({ this.$billingInterval = this.$("[data-role=billingInterval]") + // plan stuff this.$planName = this.$("[data-role=planName]") this.$planCost = this.$("[data-role=planCost]") this.$planTotal = this.$("[data-role=planTotal]") this.$basicPlanName = this.$("[data-role=basicPlanName]") - this.$proPlanName = this.$("[data-role=proPlanName]") this.$basicPlanCost = this.$("[data-role=basicPlanCost]") + + this.$proPlanName = this.$("[data-role=proPlanName]") this.$proPlanCost = this.$("[data-role=proPlanCost]") + // basic + pro layout stuff this.$basicLayoutCost = this.$("[data-role=basicLayoutCost]") this.$basicLayoutQuantity = this.$("[data-role=basicLayoutQuantity]") this.$basicLayoutTotal = this.$("[data-role=basicLayoutTotal]") @@ -48,24 +67,24 @@ var EditSubscriptionModal = ModalView.extend({ this.$proLayoutQuantity = this.$("[data-role=proLayoutQuantity]") this.$proLayoutTotal = this.$("[data-role=proLayoutTotal]") + // menus.. main menu this.$showLayoutsMenu = this.$("[data-role=showLayoutsMenu]") this.$showPlanMenu = this.$("[data-role=showPlanMenu]") + this.$cancelSubscription = this.$("[data-role=cancelSubscription]") + // three submenus this.$layoutsMenu = this.$("[data-role=layoutsMenu]") this.$planMenu = this.$("[data-role=planMenu]") - this.$closeMenu = this.$("[data-role=closeMenu]") this.$buyLayouts = this.$("[data-role=buyLayouts]") - + this.$closeMenu = this.$("[data-role=closeMenu]") this.$changePlan = this.$("[data-role=changePlan]") + // input fields this.$basicLayoutInput = this.$("[data-role=basicLayoutInput]") this.$proLayoutInput = this.$("[data-role=proLayoutInput]") this.$planRadio = this.$("[name=planRadio]") - this.$upgradeSubscription = this.$("[data-role=upgradeSubscription]") - this.$cancelSubscription = this.$("[data-role=cancelSubscription]") - this.$gear = this.$(".gear") }, @@ -112,11 +131,15 @@ var EditSubscriptionModal = ModalView.extend({ this.$freePlan.hide() this.$paidPlan.show() - this.updateTotals() + this.reset() this.__super__.show.call(this) }, - + reset: function(){ + var subscriber = this.subscriber + var plan = this.plans[ this.plan_levels[ subscriber.plan_type ] ] + this.displayTotals(subscriber) + }, calculateTotals: function(subscriber, plan){ var t = {} t.is_pro = plan.name == "pro" @@ -129,10 +152,7 @@ var EditSubscriptionModal = ModalView.extend({ t.plan_total = t.plan_price + t.basic_layout_total + t.pro_layout_total return t }, - - updateTotals: function(){ - var subscriber = this.subscriber - var plan = this.plans[ this.plan_levels[ subscriber.plan_type ] ] + displayTotals: function(subscriber, plan){ var totals = this.calculateTotals(subscriber, plan) this.$basicPlanName.html ( this.plans[1].name ) -- cgit v1.2.3-70-g09d2 From 97e7312439b24bfdd255f6868e8b42c469b0b38e Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 14:49:10 -0500 Subject: basic ui --- .../javascripts/ui/site/EditSubscriptionModal.js | 60 ++++++++++++++++++++-- public/assets/stylesheets/app.css | 10 +++- views/partials/edit-subscription.ejs | 4 +- 3 files changed, 65 insertions(+), 9 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index af3b99e..539a8ae 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -8,6 +8,7 @@ var EditSubscriptionModal = ModalView.extend({ fixedClose: true, subscriber: null, + tempSubscriber: null, events: { "click [data-role='addLayouts']": 'addLayouts', @@ -19,16 +20,62 @@ var EditSubscriptionModal = ModalView.extend({ "click [data-role=showLayoutsMenu]": "layoutsMode", "click [data-role=showPlanMenu]": "planMode", - "click [data-role=closeMenu]": "reset", + "click [data-role=closeMenu]": "resetMode", "input [data-role=basicLayoutInput]": "updateQuantity", "input [data-role=proLayoutInput]": "updateQuantity", - "click [data-role=buyLayouts]": "saveLayouts", + "click [data-role=saveQuantity]": "saveQuantity", "input [name=planRadio]": "updatePlan", "click [data-role=changePlan]": "savePlan", }, - + + resetMode: function(e){ + e.preventDefault() + this.$paidPlan.removeClass("editLayouts editPlan") + this.reset() + }, + + layoutsMode: function(e){ + e.preventDefault() + this.$paidPlan.addClass("editLayouts") + this.tempSubscriber = defaults({}, this.subscriber) + this.$basicLayoutInput.val( this.subscriber.basic_layouts ) + this.$proLayoutInput.val( this.subscriber.pro_layouts ) + }, + updateQuantity: function(e){ + e.preventDefault() + this.tempSubscriber.basic_layouts = this.$proLayoutInput.int() + this.tempSubscriber.pro_layouts = this.$basicLayoutInput.int() + + var plan = this.getPlan( this.tempSubscriber.plan_type ) + this.displayTotals(this.tempSubscriber, plan) + }, + saveQuantity: function(e){ + e.preventDefault() + // blabla.. save + this.subscriber = this.tempSubscriber + this.resetMode() + }, + + planMode: function(e){ + e.preventDefault() + this.$paidPlan.addClass("editPlan") + this.$planRadio.val( this.subscriber.plan_type ) + this.tempSubscriber = defaults({}, this.subscriber) + }, + updatePlan: function(e){ + e.preventDefault() + var plan = this.getPlan( this.$("[name=planRadio]").val() ) + this.displayTotals(this.tempSubscriber, plan) + }, + savePlan: function(e){ + e.preventDefault() + this.subscriber.plan_type = this.$("[name=planRadio]").val() + this.subscriber = this.tempSubscriber + this.resetMode() + }, + initialize: function(){ // this.parent = opt.parent this.__super__.initialize.call(this) @@ -137,8 +184,11 @@ var EditSubscriptionModal = ModalView.extend({ }, reset: function(){ var subscriber = this.subscriber - var plan = this.plans[ this.plan_levels[ subscriber.plan_type ] ] - this.displayTotals(subscriber) + var plan = this.getPlan(subscriber.plan_type) + this.displayTotals(subscriber, plan) + }, + getPlan: function(plan_type){ + return this.plans[ this.plan_levels[ plan_type ] ] }, calculateTotals: function(subscriber, plan){ var t = {} diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 4144b8b..b3d380c 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1057,11 +1057,17 @@ iframe.embed { } /* purchase mode */ .paidPlan input[type=number] { display: none } -.paidPlan.editing input[type=number] { display: inline-block } -.paidPlan.editing input[type=number]+span { display: none } form .paidPlan div { float: none; } form .paidPlan label { float: none; font-size: 2vw; margin: 0 10px; } .paidPlan .upgradeMenu div { padding: 5px 10px; } +.paidPlan .layoutsMenu { display: none } +.paidPlan .planMenu { display: none } +.paidPlan.editLayouts .layoutsMenu { display: block } +.paidPlan.editLayouts .billingMenu { display: none } +.paidPlan.editLayouts input[type=number] { display: inline-block } +.paidPlan.editLayouts input[type=number]+span { display: none } +.paidPlan.editPlan .planMenu { display: block } +.paidPlan.editPlan .billingMenu { display: none } /* LAYOUTS MODAL */ diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index fcb4b94..086f513 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -48,7 +48,7 @@
    - +
    @@ -63,7 +63,7 @@ $/
    - +
    -- cgit v1.2.3-70-g09d2 From bc843c0c65d9ff98dac35a72821f7e312dc7e62b Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 15:31:44 -0500 Subject: let confirmModal take two callbacks --- public/assets/javascripts/ui/lib/ConfirmModal.js | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/lib/ConfirmModal.js b/public/assets/javascripts/ui/lib/ConfirmModal.js index a72b31e..7d9da67 100644 --- a/public/assets/javascripts/ui/lib/ConfirmModal.js +++ b/public/assets/javascripts/ui/lib/ConfirmModal.js @@ -4,21 +4,31 @@ var ConfirmModal = new( ModalFormView.extend({ el: ".mediaDrawer.confirm", events: { - "click .yes": "advance", - "click .no": "hide", + "click .yes": "agree", + "click .no": "cancel", }, - confirm: function(question, callback){ + confirm: function(question, agreeCallback, cancelCallback){ this.$(".question").empty().append(question) - this.callback = callback + this.agreeCallback = agreeCallback + this.cancelCallback = cancelCallback this.show() }, - advance: function(e){ + agree: function(e){ e && e.preventDefault() this.hide() - this.callback && this.callback() - this.callback = null + this.agreeCallback && this.agreeCallback() + this.agreeCallback = null + this.cancelCallback = null + }, + + cancel: function(e){ + e && e.preventDefault() + this.hide() + this.cancelCallback && this.cancelCallback() + this.agreeCallback = null + this.cancelCallback = null } }) ) \ No newline at end of file -- cgit v1.2.3-70-g09d2 From fbf637f2210d281c8c6f41b72cf50746939a8ece Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 15:32:01 -0500 Subject: edit layout counts --- .../javascripts/ui/site/EditSubscriptionModal.js | 24 +++++++++++++--------- public/assets/stylesheets/app.css | 13 ++++++++++-- views/partials/edit-subscription.ejs | 4 ++-- 3 files changed, 27 insertions(+), 14 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 539a8ae..fe93499 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -31,46 +31,50 @@ var EditSubscriptionModal = ModalView.extend({ }, resetMode: function(e){ - e.preventDefault() + e && e.preventDefault() this.$paidPlan.removeClass("editLayouts editPlan") this.reset() }, layoutsMode: function(e){ - e.preventDefault() + e && e.preventDefault() this.$paidPlan.addClass("editLayouts") this.tempSubscriber = defaults({}, this.subscriber) this.$basicLayoutInput.val( this.subscriber.basic_layouts ) this.$proLayoutInput.val( this.subscriber.pro_layouts ) + this.$basicLayoutRow.show() + this.$proLayoutRow.toggle(this.subscriber.plan_name == "pro") }, updateQuantity: function(e){ - e.preventDefault() - this.tempSubscriber.basic_layouts = this.$proLayoutInput.int() - this.tempSubscriber.pro_layouts = this.$basicLayoutInput.int() + e && e.preventDefault() + this.tempSubscriber.basic_layouts = this.$basicLayoutInput.int() + this.tempSubscriber.pro_layouts = this.$proLayoutInput.int() var plan = this.getPlan( this.tempSubscriber.plan_type ) this.displayTotals(this.tempSubscriber, plan) + this.$basicLayoutRow.show() + this.$proLayoutRow.toggle(plan.name == "pro") }, saveQuantity: function(e){ - e.preventDefault() + e && e.preventDefault() // blabla.. save this.subscriber = this.tempSubscriber this.resetMode() }, planMode: function(e){ - e.preventDefault() + e && e.preventDefault() this.$paidPlan.addClass("editPlan") this.$planRadio.val( this.subscriber.plan_type ) this.tempSubscriber = defaults({}, this.subscriber) }, updatePlan: function(e){ - e.preventDefault() + e && e.preventDefault() var plan = this.getPlan( this.$("[name=planRadio]").val() ) this.displayTotals(this.tempSubscriber, plan) }, savePlan: function(e){ - e.preventDefault() + e && e.preventDefault() this.subscriber.plan_type = this.$("[name=planRadio]").val() this.subscriber = this.tempSubscriber this.resetMode() @@ -178,7 +182,7 @@ var EditSubscriptionModal = ModalView.extend({ this.$freePlan.hide() this.$paidPlan.show() - this.reset() + this.resetMode() this.__super__.show.call(this) }, diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index b3d380c..b58bb01 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1027,6 +1027,10 @@ iframe.embed { padding: 10px 3px; margin: 0; } +.planInfo td { + height: 60px; + vertical-align: middle; +} .planInfo td:nth-child(2), .planInfo th:nth-child(2), .planInfo td:nth-child(3), @@ -1034,6 +1038,10 @@ iframe.embed { .planInfo th:nth-child(3) { text-align: right; } +.planInfo td:nth-child(4) { + width: 90px; +} + .planInfo [data-role="billingInterval"] { font-size: 10px; } @@ -1046,7 +1054,8 @@ iframe.embed { margin: 5px 7px; } .paidPlan [data-role="cancelSubscription"] { - color: red; + color: #800; + border-color: black; width: 200px; float: none; } @@ -1056,7 +1065,7 @@ iframe.embed { border-color: red; } /* purchase mode */ -.paidPlan input[type=number] { display: none } +.paidPlan input[type=number] { display: none; float: right; } form .paidPlan div { float: none; } form .paidPlan label { float: none; font-size: 2vw; margin: 0 10px; } .paidPlan .upgradeMenu div { padding: 5px 10px; } diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 086f513..19f6851 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -43,8 +43,8 @@
    - - +
    +
    -- cgit v1.2.3-70-g09d2 From 60aa806d65a90907c6a76cb017c167c8453260b3 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 16:58:58 -0500 Subject: plan val from radio button --- .../javascripts/ui/site/EditSubscriptionModal.js | 110 ++++++++++----------- views/partials/edit-subscription.ejs | 4 +- 2 files changed, 56 insertions(+), 58 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index fe93499..b9abd75 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -26,60 +26,10 @@ var EditSubscriptionModal = ModalView.extend({ "input [data-role=proLayoutInput]": "updateQuantity", "click [data-role=saveQuantity]": "saveQuantity", - "input [name=planRadio]": "updatePlan", + "change [name=planRadio]": "updatePlan", "click [data-role=changePlan]": "savePlan", }, - resetMode: function(e){ - e && e.preventDefault() - this.$paidPlan.removeClass("editLayouts editPlan") - this.reset() - }, - - layoutsMode: function(e){ - e && e.preventDefault() - this.$paidPlan.addClass("editLayouts") - this.tempSubscriber = defaults({}, this.subscriber) - this.$basicLayoutInput.val( this.subscriber.basic_layouts ) - this.$proLayoutInput.val( this.subscriber.pro_layouts ) - this.$basicLayoutRow.show() - this.$proLayoutRow.toggle(this.subscriber.plan_name == "pro") - }, - updateQuantity: function(e){ - e && e.preventDefault() - this.tempSubscriber.basic_layouts = this.$basicLayoutInput.int() - this.tempSubscriber.pro_layouts = this.$proLayoutInput.int() - - var plan = this.getPlan( this.tempSubscriber.plan_type ) - this.displayTotals(this.tempSubscriber, plan) - this.$basicLayoutRow.show() - this.$proLayoutRow.toggle(plan.name == "pro") - }, - saveQuantity: function(e){ - e && e.preventDefault() - // blabla.. save - this.subscriber = this.tempSubscriber - this.resetMode() - }, - - planMode: function(e){ - e && e.preventDefault() - this.$paidPlan.addClass("editPlan") - this.$planRadio.val( this.subscriber.plan_type ) - this.tempSubscriber = defaults({}, this.subscriber) - }, - updatePlan: function(e){ - e && e.preventDefault() - var plan = this.getPlan( this.$("[name=planRadio]").val() ) - this.displayTotals(this.tempSubscriber, plan) - }, - savePlan: function(e){ - e && e.preventDefault() - this.subscriber.plan_type = this.$("[name=planRadio]").val() - this.subscriber = this.tempSubscriber - this.resetMode() - }, - initialize: function(){ // this.parent = opt.parent this.__super__.initialize.call(this) @@ -135,6 +85,8 @@ var EditSubscriptionModal = ModalView.extend({ this.$basicLayoutInput = this.$("[data-role=basicLayoutInput]") this.$proLayoutInput = this.$("[data-role=proLayoutInput]") this.$planRadio = this.$("[name=planRadio]") + this.$basicPlanInput = this.$("[data-role=basicPlanInput]") + this.$proPlanInput = this.$("[data-role=proPlanInput]") this.$gear = this.$(".gear") }, @@ -198,7 +150,7 @@ var EditSubscriptionModal = ModalView.extend({ var t = {} t.is_pro = plan.name == "pro" t.is_monthly = subscriber.plan_period == "monthly" - t.plan_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.yearly_price + t.plan_price = t.is_monthly ? plan.monthly_price : plan.yearly_price t.basic_layout_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.basic_layout_yearly_price t.basic_layout_total = subscriber.basic_layouts * t.basic_layout_price t.pro_layout_price = t.is_monthly ? plan.pro_layout_monthly_price : plan.pro_layout_yearly_price @@ -232,13 +184,59 @@ var EditSubscriptionModal = ModalView.extend({ this.$planTotal.toDollars ( totals.plan_total ) }, - addLayouts: function(e){ - e.preventDefault() + resetMode: function(e){ + e && e.preventDefault() + this.$paidPlan.removeClass("editLayouts editPlan") + this.reset() }, - changePlan: function(e){ - e.preventDefault() + + layoutsMode: function(e){ + e && e.preventDefault() + this.$paidPlan.addClass("editLayouts") + this.tempSubscriber = defaults({}, this.subscriber) + this.$basicLayoutInput.val( this.subscriber.basic_layouts ) + this.$proLayoutInput.val( this.subscriber.pro_layouts ) + this.$basicLayoutRow.show() + this.$proLayoutRow.toggle(this.subscriber.plan_name == "pro") + }, + updateQuantity: function(e){ + e && e.preventDefault() + var plan = this.getPlan( this.tempSubscriber.plan_type ) + this.tempSubscriber.basic_layouts = this.$basicLayoutInput.int() + this.tempSubscriber.pro_layouts = this.$proLayoutInput.int() + this.displayTotals(this.tempSubscriber, plan) + this.$basicLayoutRow.show() + this.$proLayoutRow.toggle(plan.name == "pro") + }, + saveQuantity: function(e){ + e && e.preventDefault() + this.subscriber = this.tempSubscriber + this.resetMode() + // blabla.. save }, + planMode: function(e){ + e && e.preventDefault() + this.$paidPlan.addClass("editPlan") + switch (this.subscriber.plan_type) { + case 'basic': this.$basicPlanInput.prop('checked', true); break; + case 'pro': this.$proPlanInput.prop('checked', true); break; + } + this.tempSubscriber = defaults({}, this.subscriber) + }, + updatePlan: function(e){ + e && e.preventDefault() + var plan_type = this.$("[name=planRadio]:checked").val() + var plan = this.getPlan( plan_type ) + this.displayTotals(this.tempSubscriber, plan) + }, + savePlan: function(e){ + e && e.preventDefault() + this.subscriber.plan_type = this.$("[name=planRadio]:checked").val() + this.subscriber = this.tempSubscriber + this.resetMode() + // blabla.. save + }, sync: function(){ this.$gear.addClass("turning") $.ajax({ diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 19f6851..e651187 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -54,12 +54,12 @@

    Select desired plan:

    - + $/
    - + $/
    -- cgit v1.2.3-70-g09d2 From 003f59d687d8d3d5e4e9c4a2eeb1bb167753d0c9 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 18:22:28 -0500 Subject: check form input --- .../javascripts/ui/site/EditSubscriptionModal.js | 18 +++++++++++------- views/partials/edit-subscription.ejs | 6 +++--- 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index b9abd75..384460d 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -27,7 +27,9 @@ var EditSubscriptionModal = ModalView.extend({ "click [data-role=saveQuantity]": "saveQuantity", "change [name=planRadio]": "updatePlan", - "click [data-role=changePlan]": "savePlan", + "click [data-role=savePlan]": "savePlan", + + "submit form": "preventDefault", }, initialize: function(){ @@ -148,7 +150,7 @@ var EditSubscriptionModal = ModalView.extend({ }, calculateTotals: function(subscriber, plan){ var t = {} - t.is_pro = plan.name == "pro" + t.is_pro = subscriber.plan_type == "pro" t.is_monthly = subscriber.plan_period == "monthly" t.plan_price = t.is_monthly ? plan.monthly_price : plan.yearly_price t.basic_layout_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.basic_layout_yearly_price @@ -197,16 +199,19 @@ var EditSubscriptionModal = ModalView.extend({ this.$basicLayoutInput.val( this.subscriber.basic_layouts ) this.$proLayoutInput.val( this.subscriber.pro_layouts ) this.$basicLayoutRow.show() - this.$proLayoutRow.toggle(this.subscriber.plan_name == "pro") + this.$proLayoutRow.toggle(this.subscriber.plan_type == "pro") }, updateQuantity: function(e){ e && e.preventDefault() var plan = this.getPlan( this.tempSubscriber.plan_type ) - this.tempSubscriber.basic_layouts = this.$basicLayoutInput.int() - this.tempSubscriber.pro_layouts = this.$proLayoutInput.int() + this.tempSubscriber.basic_layouts = clamp( this.$basicLayoutInput.int() || 0, 0, 100) + this.tempSubscriber.pro_layouts = clamp( this.$proLayoutInput.int() || 0, 0, 100) + + this.$basicLayoutInput.val(this.tempSubscriber.basic_layouts) + this.$proLayoutInput.val(this.tempSubscriber.pro_layouts) this.displayTotals(this.tempSubscriber, plan) this.$basicLayoutRow.show() - this.$proLayoutRow.toggle(plan.name == "pro") + this.$proLayoutRow.toggle(this.tempSubscriber.plan_type == "pro") }, saveQuantity: function(e){ e && e.preventDefault() @@ -233,7 +238,6 @@ var EditSubscriptionModal = ModalView.extend({ savePlan: function(e){ e && e.preventDefault() this.subscriber.plan_type = this.$("[name=planRadio]:checked").val() - this.subscriber = this.tempSubscriber this.resetMode() // blabla.. save }, diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index e651187..1b0fc41 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -32,7 +32,7 @@ Additional Pro layouts - @ $ ... + each $/ $/ @@ -43,12 +43,12 @@
    -
    +

    - +
    -- cgit v1.2.3-70-g09d2 From 3f0ef2173b6d00ae8130b3125b63f3d9ad9e98de Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 18:48:08 -0500 Subject: make it 1 action --- .../javascripts/ui/site/EditSubscriptionModal.js | 57 ++++++++++------------ public/assets/stylesheets/app.css | 14 +++--- views/partials/edit-subscription.ejs | 43 ++++++++-------- 3 files changed, 56 insertions(+), 58 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 384460d..6e5dc9e 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -7,6 +7,7 @@ var EditSubscriptionModal = ModalView.extend({ destroyAction: "/api/subscription/destroy", fixedClose: true, + editing: false, subscriber: null, tempSubscriber: null, @@ -17,14 +18,13 @@ var EditSubscriptionModal = ModalView.extend({ "click .gear": 'sync', "click .planList button": 'followLink', - "click [data-role=showLayoutsMenu]": "layoutsMode", - "click [data-role=showPlanMenu]": "planMode", + "click [data-role=showEditMenu]": "editMode", "click [data-role=closeMenu]": "resetMode", "input [data-role=basicLayoutInput]": "updateQuantity", "input [data-role=proLayoutInput]": "updateQuantity", - "click [data-role=saveQuantity]": "saveQuantity", + "click [data-role=saveChanges]": "saveChanges", "change [name=planRadio]": "updatePlan", "click [data-role=savePlan]": "savePlan", @@ -186,21 +186,28 @@ var EditSubscriptionModal = ModalView.extend({ this.$planTotal.toDollars ( totals.plan_total ) }, - resetMode: function(e){ - e && e.preventDefault() - this.$paidPlan.removeClass("editLayouts editPlan") - this.reset() - }, - - layoutsMode: function(e){ + editMode: function(e){ e && e.preventDefault() - this.$paidPlan.addClass("editLayouts") + + this.editing = true + this.$el.addClass("editing") this.tempSubscriber = defaults({}, this.subscriber) this.$basicLayoutInput.val( this.subscriber.basic_layouts ) this.$proLayoutInput.val( this.subscriber.pro_layouts ) this.$basicLayoutRow.show() this.$proLayoutRow.toggle(this.subscriber.plan_type == "pro") + switch (this.subscriber.plan_type) { + case 'basic': this.$basicPlanInput.prop('checked', true); break; + case 'pro': this.$proPlanInput.prop('checked', true); break; + } }, + resetMode: function(e){ + e && e.preventDefault() + this.editing = false + this.$el.removeClass("editing") + this.reset() + }, + updateQuantity: function(e){ e && e.preventDefault() var plan = this.getPlan( this.tempSubscriber.plan_type ) @@ -213,34 +220,24 @@ var EditSubscriptionModal = ModalView.extend({ this.$basicLayoutRow.show() this.$proLayoutRow.toggle(this.tempSubscriber.plan_type == "pro") }, - saveQuantity: function(e){ + saveChanges: function(e){ e && e.preventDefault() + if (this.tempSubscriber.plan_type != this.subscriber.plan_type + || this.tempSubscriber.basic_layouts != this.subscriber.basic_layouts + || this.tempSubscriber.pro_layouts != this.subscriber.pro_layouts) { + // update plan_type + } this.subscriber = this.tempSubscriber this.resetMode() // blabla.. save }, - planMode: function(e){ - e && e.preventDefault() - this.$paidPlan.addClass("editPlan") - switch (this.subscriber.plan_type) { - case 'basic': this.$basicPlanInput.prop('checked', true); break; - case 'pro': this.$proPlanInput.prop('checked', true); break; - } - this.tempSubscriber = defaults({}, this.subscriber) - }, updatePlan: function(e){ e && e.preventDefault() - var plan_type = this.$("[name=planRadio]:checked").val() - var plan = this.getPlan( plan_type ) - this.displayTotals(this.tempSubscriber, plan) - }, - savePlan: function(e){ - e && e.preventDefault() - this.subscriber.plan_type = this.$("[name=planRadio]:checked").val() - this.resetMode() - // blabla.. save + this.tempSubscriber.plan_type = this.$("[name=planRadio]:checked").val() + this.updateQuantity() }, + sync: function(){ this.$gear.addClass("turning") $.ajax({ diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index b58bb01..ffb133d 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1071,12 +1071,14 @@ form .paidPlan label { float: none; font-size: 2vw; margin: 0 10px; } .paidPlan .upgradeMenu div { padding: 5px 10px; } .paidPlan .layoutsMenu { display: none } .paidPlan .planMenu { display: none } -.paidPlan.editLayouts .layoutsMenu { display: block } -.paidPlan.editLayouts .billingMenu { display: none } -.paidPlan.editLayouts input[type=number] { display: inline-block } -.paidPlan.editLayouts input[type=number]+span { display: none } -.paidPlan.editPlan .planMenu { display: block } -.paidPlan.editPlan .billingMenu { display: none } + +.editing .section_break { display: none } +.editing .paidPlan .currentPlanLevel { display: none } +.editing .paidPlan .billingMenu { display: none } +.editing .paidPlan .layoutsMenu { display: block } +.editing .paidPlan .planMenu { display: block } +.editing .paidPlan input[type=number] { display: inline-block } +.editing .paidPlan input[type=number]+span { display: none } /* LAYOUTS MODAL */ diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 1b0fc41..38c6dfc 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -14,8 +14,23 @@



    -
  • - Your current plan level is +
  • +
    + Your current plan level is +
    +
    +

    Select desired plan:

    +
    + + + $/ +
    +
    + + + $/ +
    +
    @@ -24,13 +39,13 @@ - + - + @@ -43,27 +58,11 @@
    $/
    Additional Basic layoutsBasic layouts each $/ $/
    Additional Pro layoutsPro layouts each $/ $/
    -
    -
    +
    - - -
    -
    -

    Select desired plan:

    -
    - - - $/ -
    -
    - - - $/ -
    - +
  • -- cgit v1.2.3-70-g09d2 From 9e40939c50cf098e88f7d66f85bd925fcc9d01e4 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 18:52:32 -0500 Subject: space for blabitybla text --- public/assets/javascripts/ui/site/EditSubscriptionModal.js | 8 +++++--- public/assets/stylesheets/app.css | 5 +++-- views/partials/edit-subscription.ejs | 7 ++++++- 3 files changed, 14 insertions(+), 6 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 6e5dc9e..cd3d1bb 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -71,12 +71,11 @@ var EditSubscriptionModal = ModalView.extend({ this.$proLayoutTotal = this.$("[data-role=proLayoutTotal]") // menus.. main menu - this.$showLayoutsMenu = this.$("[data-role=showLayoutsMenu]") - this.$showPlanMenu = this.$("[data-role=showPlanMenu]") + this.$showEditMenu = this.$("[data-role=showEditMenu]") this.$cancelSubscription = this.$("[data-role=cancelSubscription]") // three submenus - this.$layoutsMenu = this.$("[data-role=layoutsMenu]") + this.$editMenu = this.$("[data-role=editMenu]") this.$planMenu = this.$("[data-role=planMenu]") this.$buyLayouts = this.$("[data-role=buyLayouts]") @@ -270,6 +269,9 @@ var EditSubscriptionModal = ModalView.extend({ this.didLoad(data) }.bind(this) }) + }.bind(this), + function(){ + this.show() }.bind(this)) }, diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index ffb133d..7c49ed1 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1069,17 +1069,18 @@ iframe.embed { form .paidPlan div { float: none; } form .paidPlan label { float: none; font-size: 2vw; margin: 0 10px; } .paidPlan .upgradeMenu div { padding: 5px 10px; } -.paidPlan .layoutsMenu { display: none } +.paidPlan .editMenu { display: none } .paidPlan .planMenu { display: none } .editing .section_break { display: none } .editing .paidPlan .currentPlanLevel { display: none } .editing .paidPlan .billingMenu { display: none } -.editing .paidPlan .layoutsMenu { display: block } +.editing .paidPlan .editMenu { display: block } .editing .paidPlan .planMenu { display: block } .editing .paidPlan input[type=number] { display: inline-block } .editing .paidPlan input[type=number]+span { display: none } +.editMenu .fineprint { font-size: 12px; width: auto; text-align: justify; } /* LAYOUTS MODAL */ .templates { diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 38c6dfc..f3c3589 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -61,7 +61,12 @@
    -
    +
    +
    + Your credit card will be charged the difference of XXXX for this month. + Your subscription will renew at XXXX at the start of your next billing cycle. + We thank you for your support! +
    -- cgit v1.2.3-70-g09d2 From 7a23f57b1ef3e9ceca414d909aa15a7d5ea6d536 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 20:46:42 -0500 Subject: hitting update api --- .../javascripts/ui/site/EditSubscriptionModal.js | 25 ++++++++++++++++------ server/lib/api/subscription.js | 20 ++++++++--------- 2 files changed, 28 insertions(+), 17 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index cd3d1bb..3bc1a24 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -221,14 +221,21 @@ var EditSubscriptionModal = ModalView.extend({ }, saveChanges: function(e){ e && e.preventDefault() - if (this.tempSubscriber.plan_type != this.subscriber.plan_type - || this.tempSubscriber.basic_layouts != this.subscriber.basic_layouts - || this.tempSubscriber.pro_layouts != this.subscriber.pro_layouts) { - // update plan_type + var is_changed = false + var diff = {} + "plan_type basic_layouts pro_layouts".split(" ").forEach(function(field){ + if (this.tempSubscriber[field] != this.subscriber[field]) { + diff[field] = this.tempSubscriber[field] + is_changed = true + } + }.bind(this)) + + if (is_changed) { + diff.plan_type = this.tempSubscriber.plan_type + this.update(diff) } this.subscriber = this.tempSubscriber this.resetMode() - // blabla.. save }, updatePlan: function(e){ @@ -248,12 +255,16 @@ var EditSubscriptionModal = ModalView.extend({ }, update: function(data){ + data['_csrf'] = $("[name=_csrf]").val() + this.$gear.addClass("turning") $.ajax({ url: this.updateAction, type: "put", - data: { _csrf: $("[name=_csrf]").val() }, + data: data, success: function(data){ - } + console.log("SUCCESS") + this.$gear.removeClass("turning") + }.bind(this) }) }, diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 6f08e66..362d633 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -138,26 +138,26 @@ var subscription = module.exports = { } var subscriber = req.subscription - // change.. - // data.plan_code - // data.subscription_add_ons = [] - // add_on.add_on_code - // add_on.quantity - var basic_layouts = max(0, parseInt(req.body.basic_layouts)) - var pro_layouts = max(0, parseInt(req.body.pro_layouts)) + var plan_type = req.body.plan_type + var basic_layouts = Math.max(0, parseInt(req.body.basic_layouts, 10)) + var pro_layouts = Math.max(0, parseInt(req.body.pro_layouts, 10)) var data = {} - data.plan_code = req.body.plan_type + "_monthly" + data.plan_code = plan_type + "_monthly" data.subscription_add_ons = [] - if (plan_levels[req.body.plan_type]) { + if (plan_levels[plan_type] > 0) { data.subscription_add_ons.push({ add_on_code: "extra-basic-layout", quantity: basic_layouts }) } - if (req.body.plan_type == "pro") { + if (plan_type == "pro") { data.subscription_add_ons.push({ add_on_code: "extra-pro-layout", quantity: pro_layouts }) } + // data.plan_code + // data.subscription_add_ons = [] + // add_on.add_on_code + // add_on.quantity recurly.subscriptions.update(subscriber.uuid, data, function(){ return res.json(subscriber) }) -- cgit v1.2.3-70-g09d2 From a5c5fa85c85fc31bebae1917ceeac4f8e1e383d5 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sun, 1 Feb 2015 22:02:52 -0500 Subject: talking to recurly --- package.json | 2 +- .../javascripts/ui/site/EditSubscriptionModal.js | 1 - server/lib/api/subscription.js | 32 ++++++++++++++++++---- 3 files changed, 27 insertions(+), 8 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/package.json b/package.json index e89fcd9..56ffcdf 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "mongoose-unique-validator": "~0.3.0", "monk": "~0.7.1", "multer": "~0.1.0", - "node-recurly": "^2.1.0", + "node-recurly": "julescarbon/node-recurly", "node-restful": "~0.1.14", "passport": "~0.2.0", "passport-facebook": "~1.0.3", diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 3bc1a24..55ff3b5 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -262,7 +262,6 @@ var EditSubscriptionModal = ModalView.extend({ type: "put", data: data, success: function(data){ - console.log("SUCCESS") this.$gear.removeClass("turning") }.bind(this) }) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 362d633..7e9221a 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -137,13 +137,20 @@ var subscription = module.exports = { return res.json({ error: "bad input" }) } var subscriber = req.subscription + var user = req.user var plan_type = req.body.plan_type - var basic_layouts = Math.max(0, parseInt(req.body.basic_layouts, 10)) - var pro_layouts = Math.max(0, parseInt(req.body.pro_layouts, 10)) + var basic_layouts = Math.max(0, parseInt(req.body.basic_layouts || 0, 10)) + var pro_layouts = Math.max(0, parseInt(req.body.pro_layouts || 0, 10)) + + if (plan_type == subscription.plan_type + && basic_layouts == subscriber.basic_layouts + && pro_layouts == subscriber.pro_layouts) { + return res.json(subscriber) + } var data = {} - data.plan_code = plan_type + "_monthly" + data.plan_code = plan_type + "-monthly" data.subscription_add_ons = [] if (plan_levels[plan_type] > 0) { @@ -158,8 +165,21 @@ var subscription = module.exports = { // data.subscription_add_ons = [] // add_on.add_on_code // add_on.quantity - recurly.subscriptions.update(subscriber.uuid, data, function(){ - return res.json(subscriber) + recurly.subscriptions.update(subscriber.uuid, data, function(err, data){ + if (err) { + console.log("error updating recurly subscription", err) + return res.json({ error: err }) + } + subscriber.plan_type = plan_type + subscriber.basic_layouts = basic_layouts + subscriber.pro_layouts = pro_layouts + subscriber.save(function(){ + user.plan_level = plan_levels[plan_type] + user.plan_type = plan_type + user.save(function(){ + return res.json(subscriber) + }) + }) }) }, @@ -169,7 +189,7 @@ var subscription = module.exports = { } var subscriber = req.subscription - recurly.subscriptions.terminate(subscriber.uuid, "partial", function(){ + recurly.subscriptions.terminate(subscriber.uuid, "partial", function(err, data){ subscriber.remove(function(){ req.user.plan_code = 0 req.user.plan_type = "free" -- cgit v1.2.3-70-g09d2 From e7ecd5b141945a9c9ca7a57df643eaa3f3fdc3d6 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 2 Feb 2015 09:43:06 -0500 Subject: double checking all plan changes.. need to pass full plan info to update --- public/assets/javascripts/ui/site/EditSubscriptionModal.js | 3 +-- server/lib/api/subscription.js | 10 ++++++---- views/staff/_nav.ejs | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 55ff3b5..c276354 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -224,14 +224,13 @@ var EditSubscriptionModal = ModalView.extend({ var is_changed = false var diff = {} "plan_type basic_layouts pro_layouts".split(" ").forEach(function(field){ + diff[field] = this.tempSubscriber[field] if (this.tempSubscriber[field] != this.subscriber[field]) { - diff[field] = this.tempSubscriber[field] is_changed = true } }.bind(this)) if (is_changed) { - diff.plan_type = this.tempSubscriber.plan_type this.update(diff) } this.subscriber = this.tempSubscriber diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 7e9221a..9c2d6ef 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -142,6 +142,7 @@ var subscription = module.exports = { var plan_type = req.body.plan_type var basic_layouts = Math.max(0, parseInt(req.body.basic_layouts || 0, 10)) var pro_layouts = Math.max(0, parseInt(req.body.pro_layouts || 0, 10)) + if (plan_type != "pro") { pro_layouts = 0 } if (plan_type == subscription.plan_type && basic_layouts == subscriber.basic_layouts @@ -149,15 +150,14 @@ var subscription = module.exports = { return res.json(subscriber) } - var data = {} + var data = { subscription_add_ons: [] } data.plan_code = plan_type + "-monthly" - data.subscription_add_ons = [] - if (plan_levels[plan_type] > 0) { + if (plan_levels[plan_type] > 0 && basic_layouts > 0) { data.subscription_add_ons.push({ add_on_code: "extra-basic-layout", quantity: basic_layouts }) } - if (plan_type == "pro") { + if (plan_type == "pro" && pro_layouts > 0) { data.subscription_add_ons.push({ add_on_code: "extra-pro-layout", quantity: pro_layouts }) } @@ -165,7 +165,9 @@ var subscription = module.exports = { // data.subscription_add_ons = [] // add_on.add_on_code // add_on.quantity + console.log(data) recurly.subscriptions.update(subscriber.uuid, data, function(err, data){ + console.log("got response from RECURLY ...") if (err) { console.log("error updating recurly subscription", err) return res.json({ error: err }) diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs index e79ff69..a607638 100644 --- a/views/staff/_nav.ejs +++ b/views/staff/_nav.ejs @@ -4,5 +4,5 @@ projects media plans - subscriptions + \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 4b6ba728390f3c16c48392beef5cb0b58cbf1763 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 2 Feb 2015 13:57:13 -0500 Subject: null sub --- public/assets/javascripts/ui/site/EditSubscriptionModal.js | 1 + 1 file changed, 1 insertion(+) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index c276354..3a20234 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -275,6 +275,7 @@ var EditSubscriptionModal = ModalView.extend({ type: "delete", data: { _csrf: $("[name=_csrf]").val() }, success: function(data){ + this.subscriber = null this.didLoad(data) }.bind(this) }) -- cgit v1.2.3-70-g09d2 From 673cd38ccb8a9c6ba7ec0a879fc96dcc580b046c Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 3 Feb 2015 14:46:16 -0500 Subject: enable hidpi canvas in main app --- Gruntfile.js | 1 + bower.json | 2 +- .../javascripts/rectangles/engine/map/draw.js | 2 +- public/assets/javascripts/ui/lib/LabColorPicker.js | 26 ++++++++++++---------- public/assets/javascripts/ui/reader/Tracker.js | 14 +++++++----- public/assets/test/surface.html | 2 +- views/controls/editor/color-control.ejs | 2 +- views/partials/scripts.ejs | 1 + 8 files changed, 29 insertions(+), 21 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/Gruntfile.js b/Gruntfile.js index f7af106..70a8b13 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -13,6 +13,7 @@ module.exports = function(grunt) { "public/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js", "public/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js", "public/assets/javascripts/vendor/bower_components/marked/lib/marked.js", + "public/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js", "public/assets/javascripts/vendor/tube.js", "public/assets/javascripts/vendor/loader.js", "public/assets/javascripts/vendor/polyfill.js", diff --git a/bower.json b/bower.json index c78310d..e3e83ca 100644 --- a/bower.json +++ b/bower.json @@ -10,6 +10,6 @@ "jquery-jsonview": "1.2.0", "prefixfree": "", "marked": "0.3.2", - "hidpi-canvas": "~1.0.9" + "hidpi-canvas": "git://github.com/julescarbon/hidpi-canvas-polyfill.git#master" } } diff --git a/public/assets/javascripts/rectangles/engine/map/draw.js b/public/assets/javascripts/rectangles/engine/map/draw.js index eceda3c..5a9b592 100644 --- a/public/assets/javascripts/rectangles/engine/map/draw.js +++ b/public/assets/javascripts/rectangles/engine/map/draw.js @@ -56,9 +56,9 @@ Map.Draw = function(map, opt){ } var canvas = document.createElement("canvas") - ctx = canvas.getContext('2d') canvas.width = thumbnail_width canvas.height = thumbnail_height + ctx = canvas.getContext('2d') draw.clear() diff --git a/public/assets/javascripts/ui/lib/LabColorPicker.js b/public/assets/javascripts/ui/lib/LabColorPicker.js index 7ddcdd5..2c8fb90 100644 --- a/public/assets/javascripts/ui/lib/LabColorPicker.js +++ b/public/assets/javascripts/ui/lib/LabColorPicker.js @@ -1,9 +1,12 @@ 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 + canvas.width = w + canvas.height = h + var ctx = this.ctx = canvas.getContext('2d-lodpi') +// canvas.className = "colorPicker" +// var imageData = ctx.createImageData(w, h) +// var data = imageData.data var cursor = this.cursor = document.createElement("div") cursor.className = "colorPickerCursor" @@ -15,10 +18,6 @@ var LabColorPicker = function (parent, w, h) { brightnessControl.setAttribute("max", "110") brightnessControl.setAttribute("value", "0") - canvas.width = w - canvas.height = h - canvas.className = "colorPicker" - var ww = w-1 var hh = h-1 @@ -84,11 +83,14 @@ var LabColorPicker = function (parent, w, h) { } 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] ) + var imageData = ctx.createImageData(canvas.width, canvas.height) + var data = imageData.data + var x, y, t, cw = imageData.width, ch = imageData.height + var cww = cw-1, chh = ch-1 + for (var i = 0; i < cw; i++) { + for (var j = 0; j < ch; j++) { + x = mix( i/cww, a_range[0], a_range[1] ) + y = mix( j/chh, b_range[0], b_range[1] ) t = (j*w + i) * 4 rgb = xyz2rgb(hunterlab2xyz(val, x, y)) data[t] = Math.round( rgb[0] ) diff --git a/public/assets/javascripts/ui/reader/Tracker.js b/public/assets/javascripts/ui/reader/Tracker.js index ce32c59..d2dec39 100644 --- a/public/assets/javascripts/ui/reader/Tracker.js +++ b/public/assets/javascripts/ui/reader/Tracker.js @@ -1,8 +1,12 @@ -(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ -(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), -m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) -})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); - +if (window.location.host.indexOf("lvh.me") === -1) { + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); +} +else { + ga = function(){} +} ga('create', 'UA-56883705-1', 'auto'); ga('send', 'pageview'); diff --git a/public/assets/test/surface.html b/public/assets/test/surface.html index 02b473d..9e6abe8 100644 --- a/public/assets/test/surface.html +++ b/public/assets/test/surface.html @@ -2,7 +2,7 @@ - + diff --git a/views/controls/editor/color-control.ejs b/views/controls/editor/color-control.ejs index c035e24..bcc955d 100644 --- a/views/controls/editor/color-control.ejs +++ b/views/controls/editor/color-control.ejs @@ -1,4 +1,4 @@ -
    +

    Edit Room Colors

    diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index a58eca1..011644b 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -5,6 +5,7 @@ + -- cgit v1.2.3-70-g09d2 From c6eea0f4887ba14e5a6ecfff8c9e8480ae6421c1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 2 Apr 2015 17:05:31 -0400 Subject: placing objects on the floor --- .../rectangles/engine/sculpture/_sculpture.js | 24 +++-- .../rectangles/engine/sculpture/types/_object.js | 91 +++++++++++++++++ .../rectangles/engine/sculpture/types/image.js | 110 ++++++--------------- .../assets/javascripts/rectangles/models/floor.js | 7 +- .../assets/javascripts/rectangles/models/vec3.js | 9 ++ .../assets/javascripts/ui/editor/EditorSettings.js | 3 + server/lib/schemas/Project.js | 1 + views/partials/scripts.ejs | 1 + 8 files changed, 149 insertions(+), 97 deletions(-) create mode 100644 public/assets/javascripts/rectangles/engine/sculpture/types/_object.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js index eb64e92..c8c90d3 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js @@ -4,7 +4,6 @@ var Sculpture = new function(){ var base = this; base.list = {} - base.nextMedia = null base.mouse = new mouse ({ use_offset: false, mousedownUsesCapture: true }) @@ -12,29 +11,28 @@ var Sculpture = new function(){ } base.add = function(opt){ - var scene_media + var sculpture switch (opt.media.type) { case 'image': - scene_media = new Sculpture.types.image (opt) + sculpture = new Sculpture.types.image (opt) break } - base.list[scene_media.id] = scene_media - return scene_media + base.list[sculpture.id] = sculpture + return sculpture } - base.addNextToWall = function(opt){ + base.addNext = function(opt){ opt.newMedia = true - opt.media = base.nextMedia - opt.index = opt.index || 0 - var scene_media = base.add(opt) + opt.media = Scenery.nextMedia + var sculpture = base.add(opt) - // test if scenery was placed here - if (! scene_media) { + // test if sculpture was placed here + if (! sculpture) { return null } else { - base.nextMedia = null - return scene_media + Scenery.nextMedia = null + return sculpture } } diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js new file mode 100644 index 0000000..fa6b0b1 --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -0,0 +1,91 @@ +Sculpture.types.base = Fiber.extend(function(base){ + + var exports = { + + init: function(opt){ + this.id = opt.id || Sculpture.uid("sculpture") + // this.move = new Sculpture.move (this) + this.media = opt.media + this.naturalDimensions = new vec2(this.media.width, this.media.height) + + this.set_scale( opt.scale || this.media.scale || 1.0 ) + this.position = new vec2(0,0) + }, + + set_scale: function(scale){ + this.scale = scale || 1.0 + if (this.mx) { + this.mx.scale = this.mx.ops.scale = this.scale + } + this.dimensions = this.naturalDimensions.clone().mul(this.scale) + }, + + place: function(opt){ + if (opt.data) { + this.deserialize(opt.data) + } + else { + this.mx.move(opt.position) + } + }, + + bind: function(){ + // this.move.bind() + }, + + unbind: function(){ + // this.move.unbind() + }, + + remove: function(){ + if (this.removed) return + this.removed = true + + UndoStack.push({ + type: 'destroy-sculpture', + undo: this.serialize(), + redo: { id: this.id }, + }) + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) + + Sculpture.remove(this.id) + + // Sculpture.resize.hide() + if (app.controller.sculptureEditor) { + app.controller.sculptureEditor.tainted = false + app.controller.sculptureEditor.hide() + } + }, + + destroy: function(){ + this.unbind() + scene.remove(this.mx) + this.mx.media = null + this.mx.ops = null + this.mx = null + this.move = null + this.media = null + this.dimensions = null + this.naturalDimensions = null + this.wall = null + this.bounds = null + this.center = null + }, + + serialize: function(){ + var data = { + id: this.id, + dimensions: this.dimensions.serialize(), + position: app.position(this.mx), + scale: this.scale, + media: this.media, + } + return data + }, + } + + return exports + +}) diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/image.js b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js index af538f7..ae62133 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/image.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js @@ -1,98 +1,48 @@ -Scenery.types.base = Fiber.extend(function(base){ - var exports = { +Sculpture.types.image = Sculpture.types.base.extend(function(base){ + var exports = { + + type: 'image', + init: function(opt){ - _.bindAll(this, 'enter', 'leave') - this.id = opt.id || Scenery.uid("scenery") - this.move = new Scenery.move (this) - this.media = opt.media - this.naturalDimensions = new vec2(this.media.width, this.media.height) - - this.set_scale( opt.scale || this.media.scale || 1.0 ) - this.position = new vec2(0,0) - }, + opt.scale = opt.scale || (opt.data && opt.data.scale) || DEFAULT_PICTURE_WIDTH / max(DEFAULT_PICTURE_WIDTH, opt.media.width) - set_scale: function(scale){ - this.scale = scale || 1.0 - if (this.mx) { - this.mx.scale = this.mx.ops.scale = this.scale - } - this.dimensions = this.naturalDimensions.clone().mul(this.scale) - }, - - bind: function(){ - this.move.bind() -// $(this.mx.el).bind({ -// mouseenter: this.enter, -// mouseleave: this.leave, -// }) - }, - - unbind: function(){ - this.move.unbind() -// $(this.mx.el).unbind({ -// mouseenter: this.enter, -// mouseleave: this.leave, -// }) - }, - - remove: function(){ - if (this.removed) return - this.removed = true - - UndoStack.push({ - type: 'destroy-sculpture', - undo: this.serialize(), - redo: { id: this.id }, - }) + base.init.call(this, opt) - // TODO: watch individual scenery object here - Minotaur.watch( app.router.editorView.settings ) + this.build(opt) + this.bind() + this.place(opt) + }, - Scenery.remove(this.id) + build: function(opt){ + this.footprint = new MX.Object3D() + this.mx = new MX.Image({ + src: this.media.url, + scale: this.scale, + media: this.media, + backface: true, + }) - Scenery.resize.hide() - if (app.controller.mediaEditor) { - app.controller.mediaEditor.tainted = false - app.controller.mediaEditor.hide() - } - if (app.controller.textEditor) { - app.controller.textEditor.tainted = false - app.controller.textEditor.hide() - } - }, + opt.position.y = opt.position.y || this.scale * this.media.height/2, + opt.position.rotationY = opt.position.rotationY || scene.camera.rotationY, - destroy: function(){ - this.unbind() - scene.remove(this.mx) - this.mx.media = null - this.mx.ops = null - this.mx = null - this.move = null - this.media = null - this.dimensions = null - this.naturalDimensions = null - this.wall = null - this.bounds = null - this.center = null + scene.add( this.mx ) }, serialize: function(){ - var data = { - id: this.id, - wall_id: this.wall && this.wall.id, - side: this.wall && this.wall.side, - dimensions: this.dimensions.serialize(), - position: app.position(this.mx), - scale: this.scale, - media: this.media, - } + var data = base.serialize.call(this) return data }, + + deserialize: function(data){ + this.mx.move(data.position) + this.mx.ops.width = data.dimensions.a + this.mx.ops.height = data.dimensions.b + this.dimensions.deserialize(data.dimensions) + }, } return exports - }) diff --git a/public/assets/javascripts/rectangles/models/floor.js b/public/assets/javascripts/rectangles/models/floor.js index 7b020a9..530de2b 100644 --- a/public/assets/javascripts/rectangles/models/floor.js +++ b/public/assets/javascripts/rectangles/models/floor.js @@ -79,9 +79,8 @@ if (Scenery.nextMedia) { e.preventDefault() - var sculpture = Sculpture.addNextToWall({ - index: index, - position: pos, + var sculpture = Sculpture.addNext({ + position: { x: x, y: 0, z: z }, }) // scenery was not placed @@ -91,7 +90,7 @@ } app.controller.toolbar.resetPermissions() - Sculpture.resize.show(sculpture) + // Sculpture.resize.show(sculpture) Sculpture.hovering = true // app.controller.pick(sculpture) diff --git a/public/assets/javascripts/rectangles/models/vec3.js b/public/assets/javascripts/rectangles/models/vec3.js index c44dfe6..97329ed 100644 --- a/public/assets/javascripts/rectangles/models/vec3.js +++ b/public/assets/javascripts/rectangles/models/vec3.js @@ -32,3 +32,12 @@ vec3.prototype.apply_projection = function (m) { return this; } + +vec3.prototype.serialize = function(){ + return [ round(this.a), round(this.b), round(this.c) ] +} +vec3.prototype.deserialize = function(data){ + this.a = data[0] + this.b = data[1] + this.c = data[2] +} \ No newline at end of file diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js index b319404..460863e 100644 --- a/public/assets/javascripts/ui/editor/EditorSettings.js +++ b/public/assets/javascripts/ui/editor/EditorSettings.js @@ -77,6 +77,7 @@ var EditorSettings = FormView.extend({ data.privacy && this.$privacy.find("[value=" + data.privacy + "]").prop("checked", "checked") data.media && Scenery.deserialize(data.media) + data.sculpture && Sculpture.deserialize(data.sculpture) } }, @@ -112,6 +113,7 @@ var EditorSettings = FormView.extend({ clear: function(e){ e.preventDefault() Scenery.removeAll() + Sculpture.removeAll() }, destroy: function(){ @@ -191,6 +193,7 @@ var EditorSettings = FormView.extend({ fd.append( "walls", JSON.stringify( Walls.serialize() ) ) fd.append( "colors", JSON.stringify( Walls.colors ) ) fd.append( "media", JSON.stringify( Scenery.serialize() ) ) + fd.append( "sculpture", JSON.stringify( Sculpture.serialize() ) ) fd.append( "startPosition", JSON.stringify( this.startPosition || false ) ) fd.append( "lastPosition", JSON.stringify( app.position(scene.camera) ) ) diff --git a/server/lib/schemas/Project.js b/server/lib/schemas/Project.js index a923d85..e9501fc 100644 --- a/server/lib/schemas/Project.js +++ b/server/lib/schemas/Project.js @@ -30,6 +30,7 @@ var ProjectSchema = new mongoose.Schema({ rooms: [mongoose.Schema.Types.Mixed], walls: [mongoose.Schema.Types.Mixed], media: [mongoose.Schema.Types.Mixed], + sculpture: [mongoose.Schema.Types.Mixed], colors: mongoose.Schema.Types.Mixed, startPosition: mongoose.Schema.Types.Mixed, lastPosition: mongoose.Schema.Types.Mixed, diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index 6cc5315..ca6cc94 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -74,6 +74,7 @@ + -- cgit v1.2.3-70-g09d2 From 519ff21e00c5c48d06e1ddee0cdc1dc3d90a26f8 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 3 Apr 2015 18:40:04 -0400 Subject: pulling in move code / view code --- .../rectangles/engine/scenery/resize.js | 1 + .../rectangles/engine/sculpture/move.js | 158 ++++++++++++++++ .../rectangles/engine/sculpture/types/_object.js | 22 ++- .../rectangles/engine/sculpture/types/image.js | 18 -- public/assets/javascripts/ui/editor/EditorView.js | 10 +- .../javascripts/ui/editor/SculptureEditor.js | 200 +++++++++++++++++++++ views/partials/scripts.ejs | 2 + 7 files changed, 390 insertions(+), 21 deletions(-) create mode 100644 public/assets/javascripts/rectangles/engine/sculpture/move.js create mode 100644 public/assets/javascripts/ui/editor/SculptureEditor.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index 73fd82a..a5e255a 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -49,6 +49,7 @@ Scenery.resize = new function(){ // rotate the dots as appropriate base.rotate_dots = function(){ + console.trace() rotationY = obj.wall.rotationY dots.forEach(function(dot){ dot.rotationY = rotationY diff --git a/public/assets/javascripts/rectangles/engine/sculpture/move.js b/public/assets/javascripts/rectangles/engine/sculpture/move.js new file mode 100644 index 0000000..b5a4b40 --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/sculpture/move.js @@ -0,0 +1,158 @@ + +Sculpture.move = function(base){ + + var x, y, z, position, dimension, bounds + var dragging = false, moved = false + var oldState + + this.bind = function(){ + Sculpture.mouse.bind_el(base.mx.el) + Sculpture.mouse.on("down", down) + Sculpture.mouse.on("enter", switch_wall) + Sculpture.mouse.on("drag", drag) + Sculpture.mouse.on("up", up) + } + + this.unbind = function(){ + base.focused = false + Sculpture.mouse.unbind_el(base.mx.el) + Sculpture.mouse.off("down", down) + Sculpture.mouse.off("enter", switch_wall) + Sculpture.mouse.off("drag", drag) + Sculpture.mouse.off("up", up) + } + + function down (e, cursor){ + if (e.target != base.mx.el && (e.target != base.mx.overlay)) return; + if (editor.permissions.destroy) { + base.remove() + return + } + + // load the modal + app.controller.pick(base) + + if (! base.focused) { + e.clickAccepted = false + base.focused = true + return + } + if (! (editor.permissions.move || editor.permissions.resize) ) { + e.clickAccepted = false + return + } + dragging = true + moved = false + x = base.mx.x + y = base.mx.y + z = base.mx.z + + bounds = base.bounds + dimension = base.dimensions + position = base.wall.mxToPosition( base.mx, dimension ) + + oldState = base.serialize() + document.body.classList.add("dragging") + } + + function drag (e, cursor){ + if (! dragging) return + + moved = true + + var flipX = base.wall.side & (FRONT | RIGHT) + + var delta = cursor.delta() + delta.mul( cursor_amp ) // TODO: this should be proportional to your distance from the wall + if (flipX) { delta.a *= -1 } + delta.b *= -1 + + var new_bounds = base.wall.surface.translate( bounds, dimension, position, delta ) + if (new_bounds) bounds = new_bounds + if (flipX) { delta.a *= -1 } + + base.mx.y = position.b + delta.b + dimension.b / 2 + switch (base.wall.side) { + case FRONT: + case BACK: + base.mx.x = position.a + delta.a * cos(base.wall.rotationY) + dimension.a / 2 + break + case LEFT: + case RIGHT: + base.mx.z = position.a + delta.a * sin(base.wall.rotationY) + dimension.a / 2 + break + } + + if (editor.permissions.resize) { + Sculpture.resize.move_dots() + } + } + + function up (e, cursor){ + if (! dragging || ! oldState) return + + if (moved) { + UndoStack.push({ + type: 'update-sculpture', + undo: oldState, + redo: base.serialize(), + }) + + // TODO: watch individual sculpture object here + Minotaur.watch( app.router.editorView.settings ) + } + + dragging = moved = false + oldState = null + document.body.classList.remove("dragging") + } + + function switch_wall (e, target, cursor){ + if (! dragging) return + if (target.wall.id == base.wall.id) return + + var old_wall_side = base.wall.side + var wall_group = old_wall_side | target.wall.side + var new_bounds = target.wall.surface.bounds_at_index_with_dimensions(target.index || 0, dimension) + + if (! new_bounds) return + + base.wall = target.wall + base.bounds = bounds = new_bounds + + position.a = bounds.x.midpoint() - dimension.a / 2 + + if (old_wall_side !== target.wall.side && wall_group !== FRONT_BACK && wall_group !== LEFT_RIGHT) { + switch (old_wall_side) { + case FRONT: + position.a = bounds.x.a + dimension.a / 2 + break + case BACK: + position.a = bounds.x.b - dimension.a / 2 + break + case LEFT: + position.a = bounds.x.a + dimension.a / 2 + break + case RIGHT: + position.a = bounds.x.b - dimension.a / 2 + break + } + } + + var mx_delta = base.wall.positionToMx( position, dimension ) + base.mx.move(mx_delta) + + if (editor.permissions.resize) { + Sculpture.resize.rotate_dots() + Sculpture.resize.move_dots() + } + + cursor.x.a = cursor.x.b + //var delta = cursor.delta() + drag(e, cursor) + + } + + return this + +} \ No newline at end of file diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index fa6b0b1..6c93b41 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -8,8 +8,14 @@ Sculpture.types.base = Fiber.extend(function(base){ this.media = opt.media this.naturalDimensions = new vec2(this.media.width, this.media.height) + this.move = new Sculpture.move (this) + this.billboard = true + this.backface = true + this.set_scale( opt.scale || this.media.scale || 1.0 ) this.position = new vec2(0,0) + + this.isSculpture = true }, set_scale: function(scale){ @@ -30,11 +36,11 @@ Sculpture.types.base = Fiber.extend(function(base){ }, bind: function(){ - // this.move.bind() + this.move.bind() }, unbind: function(){ - // this.move.unbind() + this.move.unbind() }, remove: function(){ @@ -81,9 +87,21 @@ Sculpture.types.base = Fiber.extend(function(base){ position: app.position(this.mx), scale: this.scale, media: this.media, + billboard: this.billboard, + backface: this.backface, } return data }, + + deserialize: function(data){ + this.mx.move(data.position) + this.mx.ops.width = data.dimensions.a + this.mx.ops.height = data.dimensions.b + this.billboard = data.billboard + this.backface = data.backface + if (! this.backface) this.mx.el.classList.remove("backface-visible") + this.dimensions.deserialize(data.dimensions) + }, } return exports diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/image.js b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js index 9e8de58..3e5ab08 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/image.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js @@ -27,29 +27,11 @@ Sculpture.types.image = Sculpture.types.base.extend(function(base){ if (opt.position) { opt.position.y = opt.position.y || this.scale * this.media.height/2 + 3 opt.position.rotationY = opt.position.rotationY || scene.camera.rotationY - this.billboard = true - this.backface = true } scene.add( this.mx ) }, - serialize: function(){ - var data = base.serialize.call(this) - data.billboard = this.billboard - data.backface = this.backface - return data - }, - - deserialize: function(data){ - this.mx.move(data.position) - this.mx.ops.width = data.dimensions.a - this.mx.ops.height = data.dimensions.b - this.billboard = data.billboard - this.backface = data.backface - if (! this.backface) this.mx.el.classList.remove("backface-visible") - this.dimensions.deserialize(data.dimensions) - }, } return exports diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js index 50d3650..e5e2ca0 100644 --- a/public/assets/javascripts/ui/editor/EditorView.js +++ b/public/assets/javascripts/ui/editor/EditorView.js @@ -17,6 +17,7 @@ var EditorView = View.extend({ this.mediaUpload = new MediaUpload ({ parent: this }) this.mediaTumblr = new MediaTumblr ({ parent: this }) this.mediaEditor = new MediaEditor ({ parent: this }) + this.sculptureEditor = new SculptureEditor ({ parent: this }) this.wallpaperPicker = new WallpaperPicker ({ parent: this }) this.colorControl = new ColorControl ({ parent: this }) this.textEditor = new TextEditor ({ parent: this }) @@ -56,12 +57,19 @@ var EditorView = View.extend({ }, pick: function(scenery){ - if (scenery.type == "text") { + if (scenery.isSculpture) { this.mediaEditor.hide() + this.textEditor.hide() + this.sculptureEditor.pick(scenery) + } + else if (scenery.type == "text") { + this.mediaEditor.hide() + this.sculptureEditor.hide() this.textEditor.pick(scenery) } else { this.textEditor.hide() + this.sculptureEditor.hide() this.mediaEditor.pick(scenery) } }, diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js new file mode 100644 index 0000000..cce000e --- /dev/null +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -0,0 +1,200 @@ + +var SculptureEditor = FormView.extend({ + el: "#sculptureEditor", + + events: { + "keydown": 'taint', + "focus [name]": "clearMinotaur", + "click [data-role=play-media]": "togglePaused", + "mousedown [name=keyframe]": "stopPropagation", + "mousedown": "stopPropagation", + "change [name=keyframe]": "seek", + "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", + }, + + initialize: function(opt){ + this.parent = opt.parent + this.__super__.initialize.call(this) + + this.$name = this.$("[name=name]") + this.$description = this.$("[name=description]") + + // image fields + this.$width = this.$("[name=width]") + this.$height = this.$("[name=height]") + this.$units = this.$("[name=units]") + + // video fields + this.$playButton = this.$("[data-role=play-media]") + this.$autoplay = this.$("[name=autoplay]") + this.$loop = this.$("[name=loop]") + this.$mute = this.$("[name=mute]") + this.$keyframe = this.$("[name=keyframe]") + }, + + toggle: function(state) { + if (state) { + this.parent.settings.toggle() + } + this.$el.toggleClass("active", state); + }, + + togglePaused: function(state){ + var state = this.sculpture.toggle(state) + this.$playButton.toggleClass("paused", ! state) + }, + + pick: function(sculpture) { + if (this.sculpture && sculpture !== this.sculpture) { + this.unbind() + } + + this.bind(sculpture) + this.$el.addClass("active") + +// app.controller.toolbar.resetMode() + app.controller.toolbar.resetControls() + // Sculpture.resize.show(sculpture) + Sculpture.hovering = true + + var media = sculpture.media + + // console.log(media) + + this.$name.val(media.title) // || filenameFromUrl(media.url) ) + this.$description.val(media.description) + this.setDimensions() + this.$units.val( "ft" ) + + switch (media.type) { + case "image": + this.$(".video").hide() + this.$(".audio").hide() + this.$(".image").show() + break + + case "youtube": + case "vimeo": + case "video": + this.$(".image").hide() + this.$(".audio").hide() + this.$(".video").show() + + this.$playButton.toggleClass("paused", ! this.sculpture.paused()) + this.$autoplay.prop('checked', !! media.autoplay) + this.$loop.prop('checked', !! media.loop) + this.$mute.prop('checked', !! media.mute) + this.$keyframe.val( Number(media.keyframe || 0) ) + break + + case "soundcloud": + this.$(".image").hide() + this.$(".video").hide() + this.$(".audio").show() + this.$playButton.toggleClass("paused", ! this.sculpture.paused()) + this.$autoplay.prop('checked', !! media.autoplay) + this.$loop.prop('checked', !! media.loop) + break + } + }, + + hide: function(sculpture){ + if (this.sculpture) { + this.unbind() + } + this.toggle(false) + }, + + seek: function(){ + var n = parseFloat( this.$keyframe.val() ) + this.sculpture.seek(n) + this.tainted = true + + this.sculpture.media.keyframe = n + }, + setAutoplay: function(){ + var checked = this.$autoplay.prop('checked') + this.sculpture.media.autoplay = checked + this.tainted = true + if (checked && this.sculpture.paused()) { + this.togglePaused() + } + }, + setLoop: function(){ + var checked = this.$loop.prop('checked') + this.sculpture.setLoop(checked) + this.tainted = true + }, + setMute: function(){ + var checked = this.$mute.prop('checked') + this.sculpture.media.mute = checked + this.sculpture.mute(checked) + this.tainted = true + }, + + setDimensions: function(){ + if (! this.sculpture) return + this.$width.unitVal( Number(this.sculpture.naturalDimensions.a * this.sculpture.scale) || "" ) + this.$height.unitVal( Number(this.sculpture.naturalDimensions.b * this.sculpture.scale) || "" ) + this.tainted = true + }, + changeWidth: function(e){ + e.stopPropagation() + this.sculpture.set_scale( this.$width.unitVal() / this.sculpture.naturalDimensions.a ) + this.setDimensions() + }, + changeHeight: function(e){ + e.stopPropagation() + this.sculpture.set_scale( this.$height.unitVal() / this.sculpture.naturalDimensions.b ) + this.setDimensions() + }, + changeUnits: function(){ + app.units = this.$units.val() + this.$('.units').resetUnitVal() + }, + + taint: function(e){ + e.stopPropagation() + this.tainted = true + }, + + bind: function(sculpture){ + this.sculpture = sculpture + this.sculpture.mx.bound = true + this.sculpture.mx.el.classList.add("picked") + }, + + unbind: function(){ + if (this.sculpture) { + this.sculpture.focused = false + if (this.tainted && this.sculpture.media) { + this.sculpture.media.title = this.$name.val() + this.sculpture.media.description = this.$description.val() + Minotaur.watch( app.router.editorView.settings ) + } + if (this.sculpture.mx) { + this.sculpture.mx.bound = false + this.sculpture.mx.el.classList.remove("picked") + } + } + this.tainted = false + this.sculpture = null + }, + + destroy: function(){ + var sculpture = this.sculpture + this.hide() + + sculpture.remove() + + this.tainted = false + this.sculpture = null + }, + +}) diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index ca6cc94..1eda8bd 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -74,6 +74,7 @@ + @@ -124,6 +125,7 @@ + -- cgit v1.2.3-70-g09d2 From f68450b1c3ece018009df5542b7e73b2b74852e7 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 3 Apr 2015 20:39:44 -0400 Subject: sculpture on reader --- Gruntfile.js | 7 +++++++ public/assets/javascripts/ui/reader/ReaderView.js | 1 + 2 files changed, 8 insertions(+) (limited to 'public/assets/javascripts/ui') diff --git a/Gruntfile.js b/Gruntfile.js index 70a8b13..026ec6f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -32,6 +32,7 @@ module.exports = function(grunt) { "public/assets/javascripts/mx/primitives/mx.youtube.js", "public/assets/javascripts/mx/primitives/mx.vimeo.js", "public/assets/javascripts/mx/primitives/mx.soundcloud.js", + "public/assets/javascripts/mx/primitives/mx.grid.js", "public/assets/javascripts/rectangles/_env.js", @@ -76,6 +77,11 @@ module.exports = function(grunt) { "public/assets/javascripts/rectangles/engine/scenery/types/video.js", "public/assets/javascripts/rectangles/engine/scenery/types/audio.js", + "public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js", + "public/assets/javascripts/rectangles/engine/sculpture/move.js", + "public/assets/javascripts/rectangles/engine/sculpture/types/_object.js", + "public/assets/javascripts/rectangles/engine/sculpture/types/image.js", + "public/assets/javascripts/rectangles/engine/map/_map.js", "public/assets/javascripts/rectangles/engine/map/ui_editor.js", "public/assets/javascripts/rectangles/engine/map/ui_minimap.js", @@ -123,6 +129,7 @@ module.exports = function(grunt) { "public/assets/javascripts/ui/editor/MediaUpload.js", "public/assets/javascripts/ui/editor/MediaViewer.js", "public/assets/javascripts/ui/editor/Presets.js", + "public/assets/javascripts/ui/editor/SculptureEditor.js", "public/assets/javascripts/ui/editor/TextEditor.js", "public/assets/javascripts/ui/editor/WallpaperPicker.js", diff --git a/public/assets/javascripts/ui/reader/ReaderView.js b/public/assets/javascripts/ui/reader/ReaderView.js index 617a145..e3e27c3 100644 --- a/public/assets/javascripts/ui/reader/ReaderView.js +++ b/public/assets/javascripts/ui/reader/ReaderView.js @@ -74,6 +74,7 @@ var ReaderView = View.extend({ data.rooms && Rooms.deserialize(data.rooms) data.walls && Walls.deserialize(data.walls) data.media && Scenery.deserialize(data.media) + data.sculpture && Sculpture.deserialize(data.sculpture) data.startPosition && scene.camera.move(data.startPosition) cam.y = window.viewHeight = data.viewHeight || app.defaults.viewHeight -- cgit v1.2.3-70-g09d2 From 24543d0839ad51b2afa7195b16d29bc52b3f1a1b Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Apr 2015 13:15:19 -0400 Subject: remove sculpture --- .../javascripts/mx/extensions/mx.movements.js | 5 +++- .../rectangles/engine/sculpture/types/_object.js | 12 +++++++++ .../javascripts/ui/editor/SculptureEditor.js | 31 +++++++++++++++++++++- public/assets/stylesheets/app.css | 3 +++ views/controls/editor/sculpture.ejs | 10 +++---- 5 files changed, 54 insertions(+), 7 deletions(-) (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 bc71fc4..931caac 100644 --- a/public/assets/javascripts/mx/extensions/mx.movements.js +++ b/public/assets/javascripts/mx/extensions/mx.movements.js @@ -162,7 +162,10 @@ MX.Movements = function (cam) { case 8: // backspace e.preventDefault() - if (app.controller.mediaEditor.scenery) { + if (app.controller.sculptureEditor.sculpture) { + app.controller.sculptureEditor.sculpture.remove() + } + else if (app.controller.mediaEditor.scenery) { app.controller.mediaEditor.scenery.remove() } else if (app.controller.textEditor.scenery) { diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index 6c93b41..48fd96a 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -43,6 +43,18 @@ Sculpture.types.base = Fiber.extend(function(base){ this.move.unbind() }, + setOutline: function(val){ + this.outline = val + // show/hide outline + }, + setOutlineColor: function(val){ + this.outlineColor = val + // set outline color + }, + setBillboard: function(val){ + this.billboard = val + }, + remove: function(){ if (this.removed) return this.removed = true diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index cce000e..ab0ccd2 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -10,12 +10,15 @@ var SculptureEditor = FormView.extend({ "mousedown": "stopPropagation", "change [name=keyframe]": "seek", "change [name=autoplay]": "setAutoplay", + "change [name=billboard]": "setBillboard", + "change [name=outline]": "setOutline", + "change [name=outlineColor]": "setOutlineColor", "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", + "click [data-role=destroy-sculpture]": "destroy", }, initialize: function(opt){ @@ -25,6 +28,10 @@ var SculptureEditor = FormView.extend({ this.$name = this.$("[name=name]") this.$description = this.$("[name=description]") + this.$billboard = this.$("[name=billboard]") + this.$outline = this.$("[name=outline]") + this.$outlineColor = this.$("[name=outlineColor]") + // image fields this.$width = this.$("[name=width]") this.$height = this.$("[name=height]") @@ -71,6 +78,11 @@ var SculptureEditor = FormView.extend({ this.$description.val(media.description) this.setDimensions() this.$units.val( "ft" ) + + this.$outline.prop( 'checked', !! media.outline ) + this.$outlineColor.val( media.outlineColor ) + this.$billboard.prop( 'checked', !! media.billboard ) + switch (media.type) { case "image": @@ -138,6 +150,23 @@ var SculptureEditor = FormView.extend({ this.tainted = true }, + + setBillboard: function(){ + var checked = this.$billboard.prop('checked') + this.sculpture.setBillboard(checked) + this.tainted = true + }, + setOutline: function(){ + var checked = this.$outline.prop('checked') + this.sculpture.setOutline(checked) + this.tainted = true + }, + setOutlineColor: function(){ + var color = this.$outlineColor.val() + this.sculpture.setOutlineColor(color) + this.tainted = true + }, + setDimensions: function(){ if (! this.sculpture) return this.$width.unitVal( Number(this.sculpture.naturalDimensions.a * this.sculpture.scale) || "" ) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index b23b50b..6e97500 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -2455,6 +2455,9 @@ input[type="range"]::-webkit-slider-thumb { #mediaEditor .setting.number [type=text] { width: 140px; } +#sculptureEditor .setting.number input[type=text] { + width: 130px; +} .playButton,.muteButton { border-radius: 50%; diff --git a/views/controls/editor/sculpture.ejs b/views/controls/editor/sculpture.ejs index 21e5039..4b8535a 100644 --- a/views/controls/editor/sculpture.ejs +++ b/views/controls/editor/sculpture.ejs @@ -13,14 +13,14 @@
    - - - + + +
    - - + +
    -- cgit v1.2.3-70-g09d2 From 546fba7ee9dac48d2fb0015709247b1b2efca8bc Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Apr 2015 14:31:24 -0400 Subject: store billboard setting --- public/assets/javascripts/rectangles/engine/scenery/resize.js | 2 +- .../javascripts/rectangles/engine/sculpture/types/_object.js | 6 ++++++ public/assets/javascripts/ui/editor/EditorView.js | 1 + public/assets/javascripts/ui/editor/SculptureEditor.js | 7 +++---- 4 files changed, 11 insertions(+), 5 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index a5e255a..006ff2a 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -49,7 +49,7 @@ Scenery.resize = new function(){ // rotate the dots as appropriate base.rotate_dots = function(){ - console.trace() + // console.trace() rotationY = obj.wall.rotationY dots.forEach(function(dot){ dot.rotationY = rotationY diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index 489a6a1..b903c5b 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -54,9 +54,13 @@ Sculpture.types.base = Fiber.extend(function(base){ setBillboard: function(val){ this.billboard = val if (this.billboard) { + this.mx.el.classList.add("backface-visible") + this.mx.el.classList.remove("backface-hidden") this.mx.rotationY = cam.rotationY } else { + this.mx.el.classList.add("backface-hidden") + this.mx.el.classList.remove("backface-visible") this.mx.rotationY = PI/2 } }, @@ -106,6 +110,8 @@ Sculpture.types.base = Fiber.extend(function(base){ scale: this.scale, media: this.media, billboard: this.billboard, + outline: this.outline, + outlineColor: this.outlineColor, backface: this.backface, } return data diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js index e5e2ca0..a7b4f20 100644 --- a/public/assets/javascripts/ui/editor/EditorView.js +++ b/public/assets/javascripts/ui/editor/EditorView.js @@ -80,6 +80,7 @@ var EditorView = View.extend({ }, hideExtras: function(){ + this.sculptureEditor.hide() this.mediaEditor.hide() this.textEditor.hide() this.share.hide() diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index ab0ccd2..ff1e6b9 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -79,10 +79,9 @@ var SculptureEditor = FormView.extend({ this.setDimensions() this.$units.val( "ft" ) - this.$outline.prop( 'checked', !! media.outline ) - this.$outlineColor.val( media.outlineColor ) - this.$billboard.prop( 'checked', !! media.billboard ) - + this.$outline.prop( 'checked', !! sculpture.outline ) + this.$outlineColor.val( sculpture.outlineColor || "#000000" ) + this.$billboard.prop( 'checked', !! sculpture.billboard ) switch (media.type) { case "image": -- cgit v1.2.3-70-g09d2 From 0b8b54e26aa7a40065a0be6f7708b7021e4fec13 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Apr 2015 15:03:35 -0400 Subject: resize scenery --- Gruntfile.js | 1 + .../rectangles/engine/scenery/resize.js | 1 + .../rectangles/engine/sculpture/_sculpture.js | 4 + .../rectangles/engine/sculpture/move.js | 6 +- .../rectangles/engine/sculpture/resize.js | 207 +++++++++++++++++++++ .../rectangles/engine/sculpture/types/_object.js | 2 +- .../assets/javascripts/rectangles/models/floor.js | 2 +- public/assets/javascripts/ui/editor/EditorView.js | 1 + .../javascripts/ui/editor/SculptureEditor.js | 3 +- views/partials/scripts.ejs | 1 + 10 files changed, 221 insertions(+), 7 deletions(-) create mode 100644 public/assets/javascripts/rectangles/engine/sculpture/resize.js (limited to 'public/assets/javascripts/ui') diff --git a/Gruntfile.js b/Gruntfile.js index 026ec6f..789ce6f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -79,6 +79,7 @@ module.exports = function(grunt) { "public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js", "public/assets/javascripts/rectangles/engine/sculpture/move.js", + "public/assets/javascripts/rectangles/engine/sculpture/resize.js", "public/assets/javascripts/rectangles/engine/sculpture/types/_object.js", "public/assets/javascripts/rectangles/engine/sculpture/types/image.js", diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index 006ff2a..8dac140 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -8,6 +8,7 @@ Scenery.resize = new function(){ var dragging = false var naturalDimension, naturalDimensionCopy, dimension, position, scale var oldState + var rotationY var dots = [], dot, selected_dot diff --git a/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js index 1543def..888b925 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js @@ -9,6 +9,7 @@ var Sculpture = new function(){ base.init = function(){ app.on("move", base.updateBillboards) + base.resize.init() } base.updateBillboards = function(){ @@ -17,6 +18,9 @@ var Sculpture = new function(){ sculpture.mx.rotationY = cam.rotationY } }) + if (Sculpture.resize.obj && Sculpture.resize.obj.billboard) { + Sculpture.resize.move_dots() + } } base.add = function(opt){ diff --git a/public/assets/javascripts/rectangles/engine/sculpture/move.js b/public/assets/javascripts/rectangles/engine/sculpture/move.js index 28d707e..f968bcf 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/move.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/move.js @@ -66,9 +66,9 @@ Sculpture.move = function(base){ base.mx.x = x + delta.a * cos(cam.rotationY) - delta.b * sin(cam.rotationY) base.mx.z = z + delta.a * sin(cam.rotationY) + delta.b * cos(cam.rotationY) -// if (editor.permissions.resize) { -// Sculpture.resize.move_dots() -// } + if (editor.permissions.resize) { + Sculpture.resize.move_dots() + } } function up (e, cursor){ diff --git a/public/assets/javascripts/rectangles/engine/sculpture/resize.js b/public/assets/javascripts/rectangles/engine/sculpture/resize.js new file mode 100644 index 0000000..53b8b2d --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/sculpture/resize.js @@ -0,0 +1,207 @@ +Sculpture.resize = new function(){ + + var base = this + + var obj + var x, y, z, bounds + var dragging = false + var naturalDimension, naturalDimensionCopy, dimension, position, scale + var oldState + var rotationY + + var dots = [], dot, selected_dot + + base.init = function(){ + base.build() + base.bind() + } + + // create 9 dots at the corners of the div + base.build = function(){ + [ TOP, + TOP_RIGHT, + RIGHT, + BOTTOM_RIGHT, + BOTTOM, + BOTTOM_LEFT, + LEFT, + TOP_LEFT ].forEach(base.build_dot) + } + + // generate a dot element + base.build_dot = function(side) { + var dot = new MX.Object3D('.dot') + dot.width = dot.height = dot_side * 2 + dot.scale = 0.5 + dot.side = side + $(dot.el).on({ + mouseenter: function(){ base.hovering = true }, + mouseleave: function(){ base.hovering = false }, + }) + dots.push(dot) + } + + base.add_dots = function(){ + dots.forEach(function(dot){ + scene.add(dot) + }) + } + + // move all the dots to the object's current position + base.move_dots = function(){ + rotationY = obj.mx.rotationY + + var x = obj.mx.x + sin(rotationY) * dot_distance_from_picture + var y = obj.mx.y + var z = obj.mx.z - cos(rotationY) * dot_distance_from_picture + + dots.forEach(function(dot){ + base.move_dot(dot, { x: x, y: y, z: z, rotationY: rotationY }) + }) + } + + // move a dot .. to the initial position of the image + base.move_dot = function(dot, pos){ + if (dot.side & TOP) { + pos.y += obj.dimensions.b / 2 + } + if (dot.side & BOTTOM) { + pos.y -= obj.dimensions.b / 2 + } + if (dot.side & LEFT) { + pos.x -= cos(rotationY) * (obj.dimensions.a) / 2 + pos.z -= sin(rotationY) * (obj.dimensions.a) / 2 + } + if (dot.side & RIGHT) { + pos.x += cos(rotationY) * (obj.dimensions.a) / 2 + pos.z += sin(rotationY) * (obj.dimensions.a) / 2 + } + dot.move(pos) + } + + // pick a new object to focus on and show the dots + base.show = function(new_object) { + // if (obj === new_object) return + if (! new_object) return + base.obj = obj = new_object + base.add_dots() + base.move_dots() + } + + // dismiss the dots on blur + var dotsHideTimeout; + base.defer_hide = function(){ + clearTimeout(dotsHideTimeout) + + dotsHideTimeout = setTimeout(function(){ + if (Scenery.hovering || Scenery.resize.hovering || Scenery.mouse.down) return + Scenery.resize.hide() + }, dot_hide_delay) + } + + base.hide = function () { + if (! obj) return + base.obj = obj = null + dots.forEach(function(dot){ + scene.remove(dot) + }) + } + + base.bind = function(){ + dots.forEach(function(dot){ + Sculpture.mouse.bind_el(dot.el) + }) + Sculpture.mouse.on("down", down) + Sculpture.mouse.on("drag", drag) + Sculpture.mouse.on("up", up) + } + + base.unbind = function(){ + dots.forEach(function(dot){ + Sculpture.mouse.unbind_el(dot.el) + }) + Sculpture.mouse.off("down", down) + Sculpture.mouse.off("drag", drag) + Sculpture.mouse.off("up", up) + } + + function down (e, cursor){ + var selection = dots.filter(function(dot){return e.target == dot.el}) + if (! selection.length) return + + selected_dot = selection[0] + dragging = true + + naturalDimension = obj.naturalDimensions + dimension = obj.dimensions + position = new vec3(obj.mx.x, obj.mx.y, obj.mx.z) + oldState = obj.serialize() + + if (obj.type == "text") { + naturalDimensionCopy = naturalDimension.clone() + positionCopy = position.clone() + } + + document.body.classList.add("dragging") + } + + function drag (e, cursor){ + if (! dragging) return + + var x_sign = selected_dot.side & LEFT ? -1 : selected_dot.side & RIGHT ? 1 : 0 + var y_sign = selected_dot.side & TOP ? -1 : selected_dot.side & BOTTOM ? 1 : 0 + var width = cursor.x.magnitude() + var height = cursor.y.magnitude() + var mag = cursor.magnitude() + + if (abs(width) > abs(height)) { + mag = x_sign * mag * sign(width) + } + else { + mag = y_sign * mag * sign(height) + } + + if (obj.type == "text") { + obj.mx.width = obj.media.width = naturalDimension.a = naturalDimensionCopy.a + (mag * 2) + obj.mx.height = obj.media.height = naturalDimension.b = naturalDimensionCopy.b + (mag * 2) + dimension.a = naturalDimension.a * obj.scale + dimension.b = naturalDimension.b * obj.scale + } + else { + obj.set_scale( ( dimension.a + mag ) / naturalDimension.a ) + } + + if (selected_dot.side & LEFT_RIGHT) { + obj.mx.x = position.a + cos(rotationY) * mag/2 * (x_sign) + obj.mx.z = position.c + sin(rotationY) * mag/2 * (x_sign) + } + if (selected_dot.side & TOP_BOTTOM) { + obj.mx.y = position.b - mag/2 * y_sign + } + + base.move_dots() + + app.controller.sculptureEditor.setDimensions() + } + + function up (e, cursor){ + if (! dragging) return + dragging = false + if (! editor.permissions.resize) { return } + + obj.scale = obj.mx.ops.scale = obj.mx.scale + obj.dimensions.assign(obj.naturalDimensions).mul(obj.scale) + + UndoStack.push({ + type: 'update-sculpture', + undo: oldState, + redo: obj.serialize(), + }) + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) + + document.body.classList.remove("dragging") + selected_dot = null + } +} \ No newline at end of file diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index b903c5b..390c42e 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -80,7 +80,7 @@ Sculpture.types.base = Fiber.extend(function(base){ Sculpture.remove(this.id) - // Sculpture.resize.hide() + Sculpture.resize.hide() if (app.controller.sculptureEditor) { app.controller.sculptureEditor.tainted = false app.controller.sculptureEditor.hide() diff --git a/public/assets/javascripts/rectangles/models/floor.js b/public/assets/javascripts/rectangles/models/floor.js index 530de2b..799bdc7 100644 --- a/public/assets/javascripts/rectangles/models/floor.js +++ b/public/assets/javascripts/rectangles/models/floor.js @@ -90,7 +90,7 @@ } app.controller.toolbar.resetPermissions() - // Sculpture.resize.show(sculpture) + Sculpture.resize.show(sculpture) Sculpture.hovering = true // app.controller.pick(sculpture) diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js index a7b4f20..a2d84a6 100644 --- a/public/assets/javascripts/ui/editor/EditorView.js +++ b/public/assets/javascripts/ui/editor/EditorView.js @@ -84,6 +84,7 @@ var EditorView = View.extend({ this.mediaEditor.hide() this.textEditor.hide() this.share.hide() + Sculpture.resize.hide() Scenery.resize.hide() Scenery.hovering = false } diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index ff1e6b9..35abc00 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -67,7 +67,7 @@ var SculptureEditor = FormView.extend({ // app.controller.toolbar.resetMode() app.controller.toolbar.resetControls() - // Sculpture.resize.show(sculpture) + Sculpture.resize.show(sculpture) Sculpture.hovering = true var media = sculpture.media @@ -149,7 +149,6 @@ var SculptureEditor = FormView.extend({ this.tainted = true }, - setBillboard: function(){ var checked = this.$billboard.prop('checked') this.sculpture.setBillboard(checked) diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index 1eda8bd..6dfe912 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -75,6 +75,7 @@ + -- cgit v1.2.3-70-g09d2 From 7fd34f49fea785f11320eec412a95726cbcf7349 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Apr 2015 17:59:51 -0400 Subject: static build target --- .gitignore | 3 + Gruntfile.js | 130 +++++++++++++- public/assets/javascripts/ui/reader/MediaPlayer.js | 2 +- public/assets/javascripts/ui/reader/ReaderView.js | 12 +- public/assets/javascripts/ui/reader/_router.js | 16 ++ public/assets/test/static.html | 196 +++++++++++++++++++++ server/index.js | 4 + 7 files changed, 354 insertions(+), 9 deletions(-) create mode 100644 public/assets/javascripts/ui/reader/_router.js create mode 100644 public/assets/test/static.html (limited to 'public/assets/javascripts/ui') diff --git a/.gitignore b/.gitignore index 50f54f1..14d6d0f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ config.json app.concat.js app.min.js +reader.concat.js +reader.min.js + diff --git a/Gruntfile.js b/Gruntfile.js index 93f13fe..a3ef359 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -147,7 +147,110 @@ module.exports = function(grunt) { "public/assets/javascripts/defaults.js", ], dest: 'public/assets/javascripts/app.concat.js', + }, + + // this builds a static version of the vvalls code, suitable for embedding + // in another website. see assets/test/static.html + 'static': { + src: [ + "public/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js", + "public/assets/javascripts/vendor/bower_components/lodash/lodash.min.js", + "public/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js", + "public/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js", + "public/assets/javascripts/vendor/bower_components/marked/lib/marked.js", + "public/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js", + "public/assets/javascripts/vendor/tube.js", + "public/assets/javascripts/vendor/loader.js", + "public/assets/javascripts/vendor/polyfill.js", + "public/assets/javascripts/vendor/froogaloop.js", + "public/assets/javascripts/util.js", + + "public/assets/javascripts/mx/mx.js", + "public/assets/javascripts/mx/extensions/mx.scene.js", + "public/assets/javascripts/mx/extensions/mx.movements.js", + "public/assets/javascripts/mx/extensions/mx.movementsMobile.js", + "public/assets/javascripts/mx/primitives/mx.image.js", + "public/assets/javascripts/mx/primitives/mx.text.js", + "public/assets/javascripts/mx/primitives/mx.video.js", + "public/assets/javascripts/mx/primitives/mx.youtube.js", + "public/assets/javascripts/mx/primitives/mx.vimeo.js", + "public/assets/javascripts/mx/primitives/mx.soundcloud.js", + "public/assets/javascripts/mx/primitives/mx.grid.js", + + "public/assets/javascripts/rectangles/_env.js", + + "public/assets/javascripts/rectangles/util/constants.js", + "public/assets/javascripts/rectangles/util/colors.js", + "public/assets/javascripts/rectangles/util/coords.js", + "public/assets/javascripts/rectangles/util/debug.js", + "public/assets/javascripts/rectangles/util/keys.js", + "public/assets/javascripts/rectangles/util/measurement.js", + "public/assets/javascripts/rectangles/util/minotaur.js", + "public/assets/javascripts/rectangles/util/mouse.js", + "public/assets/javascripts/rectangles/util/permissions.js", + "public/assets/javascripts/rectangles/util/sort.js", + "public/assets/javascripts/rectangles/util/uid.js", + "public/assets/javascripts/rectangles/util/undostack.js", + "public/assets/javascripts/rectangles/util/wheel.js", + + "public/assets/javascripts/rectangles/models/vec2.js", + "public/assets/javascripts/rectangles/models/vec3.js", + "public/assets/javascripts/rectangles/models/rect.js", + "public/assets/javascripts/rectangles/models/surface.js", + "public/assets/javascripts/rectangles/models/tree.js", + "public/assets/javascripts/rectangles/models/room.js", + "public/assets/javascripts/rectangles/models/wall.js", + "public/assets/javascripts/rectangles/models/floor.js", + + "public/assets/javascripts/rectangles/engine/rooms/_rooms.js", + "public/assets/javascripts/rectangles/engine/rooms/_walls.js", + "public/assets/javascripts/rectangles/engine/rooms/builder.js", + "public/assets/javascripts/rectangles/engine/rooms/clipper.js", + "public/assets/javascripts/rectangles/engine/rooms/grouper.js", + "public/assets/javascripts/rectangles/engine/rooms/mover.js", + + "public/assets/javascripts/rectangles/engine/scenery/_scenery.js", + "public/assets/javascripts/rectangles/engine/scenery/move.js", + "public/assets/javascripts/rectangles/engine/scenery/resize.js", + "public/assets/javascripts/rectangles/engine/scenery/randomize.js", + "public/assets/javascripts/rectangles/engine/scenery/sound.js", + "public/assets/javascripts/rectangles/engine/scenery/undo.js", + "public/assets/javascripts/rectangles/engine/scenery/types/_object.js", + "public/assets/javascripts/rectangles/engine/scenery/types/image.js", + "public/assets/javascripts/rectangles/engine/scenery/types/text.js", + "public/assets/javascripts/rectangles/engine/scenery/types/video.js", + "public/assets/javascripts/rectangles/engine/scenery/types/audio.js", + + "public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js", + "public/assets/javascripts/rectangles/engine/sculpture/move.js", + "public/assets/javascripts/rectangles/engine/sculpture/resize.js", + "public/assets/javascripts/rectangles/engine/sculpture/types/_object.js", + "public/assets/javascripts/rectangles/engine/sculpture/types/image.js", + + "public/assets/javascripts/rectangles/engine/map/_map.js", + "public/assets/javascripts/rectangles/engine/map/ui_editor.js", + "public/assets/javascripts/rectangles/engine/map/ui_minimap.js", + "public/assets/javascripts/rectangles/engine/map/draw.js", + + "public/assets/javascripts/ui/lib/View.js", + "public/assets/javascripts/ui/lib/Router.js", + "public/assets/javascripts/ui/lib/ModalView.js", + + "public/assets/javascripts/ui/reader/ReaderView.js", + "public/assets/javascripts/ui/reader/ShareView.js", + "public/assets/javascripts/ui/reader/EmbedView.js", + "public/assets/javascripts/ui/reader/MediaPlayer.js", + "public/assets/javascripts/ui/reader/Tracker.js", + + "public/assets/javascripts/ui/reader/_router.js", + + "public/assets/javascripts/app.js", + "public/assets/javascripts/defaults.js", + ], + dest: 'public/assets/javascripts/reader.concat.js', } + + }, copy: { concat: { @@ -158,7 +261,15 @@ module.exports = function(grunt) { }, ] }, - }, + 'static': { + files: [ + { + src: 'public/assets/javascripts/static.concat.js', + dest: 'public/assets/javascripts/static.min.js', + }, + ] + }, + }, uglify: { options: { banner: '/* vvalls by okfocus 2015 */\n' @@ -166,10 +277,17 @@ module.exports = function(grunt) { js: { src: 'public/assets/javascripts/app.concat.js', dest: 'public/assets/javascripts/app.min.js', + }, + 'static': { + src: 'public/assets/javascripts/static.concat.js', + dest: 'public/assets/javascripts/static.min.js', } }, clean: { - release: ["public/assets/javascripts/app.concat.js"], + release: [ + "public/assets/javascripts/static.concat.js", + "public/assets/javascripts/app.concat.js", + ], } }); @@ -180,8 +298,10 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-clean'); // Default task(s). - grunt.registerTask('js', ['concat:js', 'uglify:js', 'clean:release']); - grunt.registerTask('merge', ['concat:js', 'copy:concat']); - grunt.registerTask('default', ['js']); + grunt.registerTask('js', ['concat:js', 'uglify:js', 'clean:release']); + grunt.registerTask('js-test', ['concat:js', 'copy:concat']); + grunt.registerTask('static', ['concat:static', 'uglify:static', 'clean:release']); + grunt.registerTask('static-test', ['concat:static', 'copy:static']); + grunt.registerTask('default', ['js']); }; diff --git a/public/assets/javascripts/ui/reader/MediaPlayer.js b/public/assets/javascripts/ui/reader/MediaPlayer.js index 8424d9c..8e65976 100644 --- a/public/assets/javascripts/ui/reader/MediaPlayer.js +++ b/public/assets/javascripts/ui/reader/MediaPlayer.js @@ -1,5 +1,5 @@ -var MediaPlayer = FormView.extend({ +var MediaPlayer = View.extend({ el: "#mediaPlayer", events: { diff --git a/public/assets/javascripts/ui/reader/ReaderView.js b/public/assets/javascripts/ui/reader/ReaderView.js index e3e27c3..55d2520 100644 --- a/public/assets/javascripts/ui/reader/ReaderView.js +++ b/public/assets/javascripts/ui/reader/ReaderView.js @@ -31,7 +31,12 @@ var ReaderView = View.extend({ this.tracker = new Tracker ({ mode: mode }) - $.get(this.projectAction + name, this.ready.bind(this)) + if ('vvalls_data' in window) { + this.ready(window.vvalls_data) + } + else { + $.get(this.projectAction + name, this.ready.bind(this)) + } }, getQS: function(){ @@ -85,9 +90,10 @@ var ReaderView = View.extend({ Walls.setColor[mode](colors[mode]) }) - editor.permissions.clear() + window.editor && editor.permissions.clear() - this.listen() + // disable until we start using spinning again + // this.listen() }, listen: function(){ diff --git a/public/assets/javascripts/ui/reader/_router.js b/public/assets/javascripts/ui/reader/_router.js new file mode 100644 index 0000000..a0e346a --- /dev/null +++ b/public/assets/javascripts/ui/reader/_router.js @@ -0,0 +1,16 @@ + +var SiteRouter = Router.extend({ + el: "body", + + initialize: function(){ + app.launch() + if (app.unsupported) return + + this.readerView = app.controller = new ReaderView() + this.readerView.load() + + $("body").removeClass("loading") + } + +}) + diff --git a/public/assets/test/static.html b/public/assets/test/static.html new file mode 100644 index 0000000..90871a5 --- /dev/null +++ b/public/assets/test/static.html @@ -0,0 +1,196 @@ + + + + VValls + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + +
    +
    +

    + Leaves and such +
    + +
    + + asdf +

    + + + Last modified 4/20/2015 + + + + + Edit Room + +
    + +
    + + + + + + + + + + + + + +
    +
    +
    + +
    + +
    + X + +
    +
    +
    +

    Embed VValls

    + +

    + This code generates an iframe which will embed this room in your website or blog. +

    + + + dimensions: x + + + + test +
    +
    +
    +
    + +
    + +
    + +
    +
    + + + + + + + + + + diff --git a/server/index.js b/server/index.js index 7bc3f7f..391385c 100644 --- a/server/index.js +++ b/server/index.js @@ -66,6 +66,10 @@ site.setup = function(){ app.set('env', config.env.production ? "production" : "development") app.get('env') === 'development' && app.use(express.errorHandler()); + if (config.env.production) { + app.set('json spaces', 0) + } + // Essential middleware // app.all('*', middleware.enableCORS); app.all('*', middleware.ensureLocals); -- cgit v1.2.3-70-g09d2 From ff0e7521982ecb38992c59656452dbcc15af64d5 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Apr 2015 19:33:33 -0400 Subject: editor ref --- public/assets/javascripts/ui/reader/_router.js | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/reader/_router.js b/public/assets/javascripts/ui/reader/_router.js index a0e346a..f3b121b 100644 --- a/public/assets/javascripts/ui/reader/_router.js +++ b/public/assets/javascripts/ui/reader/_router.js @@ -14,3 +14,11 @@ var SiteRouter = Router.extend({ }) +var editor = { + permissions: new Permissions({ + 'pick': true, + 'move': true, + 'resize': true, + 'destroy': false, + }) +} -- cgit v1.2.3-70-g09d2 From 90b0e89b4dabf67035ae4bccdb02c52da4e31ab1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 27 Apr 2015 19:49:27 -0400 Subject: infoboxes on sculpture --- public/assets/javascripts/ui/editor/SculptureEditor.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index 35abc00..52663e1 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -73,9 +73,8 @@ var SculptureEditor = FormView.extend({ var media = sculpture.media // console.log(media) - - this.$name.val(media.title) // || filenameFromUrl(media.url) ) - this.$description.val(media.description) + this.$name.val(media.title || "") // || filenameFromUrl(media.url) ) + this.$description.val(media.description || "") this.setDimensions() this.$units.val( "ft" ) -- cgit v1.2.3-70-g09d2 From 53695472cfb20b730d04b2d6a6a16c6d281e9180 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 27 Apr 2015 20:47:41 -0400 Subject: outline box --- .../rectangles/engine/sculpture/move.js | 1 + .../rectangles/engine/sculpture/resize.js | 3 +- .../rectangles/engine/sculpture/types/_object.js | 52 +++++++++++++++++++--- .../assets/javascripts/rectangles/models/vec3.js | 18 +++++++- .../javascripts/rectangles/util/measurement.js | 4 ++ .../javascripts/ui/editor/SculptureEditor.js | 11 +++++ public/assets/stylesheets/app.css | 7 +++ views/controls/editor/sculpture.ejs | 2 +- 8 files changed, 90 insertions(+), 8 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/engine/sculpture/move.js b/public/assets/javascripts/rectangles/engine/sculpture/move.js index e571c3b..0cbeccd 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/move.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/move.js @@ -83,6 +83,7 @@ Sculpture.move = function(base){ if (editor.permissions.resize) { Sculpture.resize.move_dots() + base.updateOutline() } } diff --git a/public/assets/javascripts/rectangles/engine/sculpture/resize.js b/public/assets/javascripts/rectangles/engine/sculpture/resize.js index 53b8b2d..5f21d66 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/resize.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/resize.js @@ -180,7 +180,8 @@ Sculpture.resize = new function(){ } base.move_dots() - + obj.updateOutline() + app.controller.sculptureEditor.setDimensions() } diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index 5dd0aae..2f24ae5 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -6,7 +6,8 @@ Sculpture.types.base = Fiber.extend(function(base){ this.id = opt.id || Sculpture.uid("sculpture") // this.move = new Sculpture.move (this) this.media = opt.media - this.naturalDimensions = new vec2(this.media.width, this.media.height) + this.naturalDimensions = new vec3(this.media.width, this.media.height, this.media.width) + this.dimensions = new vec3(this.media.width, this.media.height, this.media.width) this.move = new Sculpture.move (this) this.billboard = true @@ -14,7 +15,7 @@ Sculpture.types.base = Fiber.extend(function(base){ this.set_scale( opt.scale || this.media.scale || 1.0 ) this.position = new vec2(0,0) - + this.isSculpture = true }, @@ -25,6 +26,11 @@ Sculpture.types.base = Fiber.extend(function(base){ } this.dimensions = this.naturalDimensions.clone().mul(this.scale) }, + set_depth: function(depth){ + console.log(this.dimensions.c, this.naturalDimensions.c, depth) + this.dimensions.c = depth + this.naturalDimensions.c = depth / this.scale + }, place: function(opt){ if (opt.data) { @@ -45,11 +51,16 @@ Sculpture.types.base = Fiber.extend(function(base){ setOutline: function(val){ this.outline = val - // show/hide outline + if (val && ! this.outlineEl) { + this.buildOutline() + } + this.outlineEl.el.style.display = val ? "block" : "none" }, setOutlineColor: function(val){ this.outlineColor = val - // set outline color + if (this.outlineEl) { + this.outlineColor = this.outlineEl.el.style.borderColor = val + } }, setBillboard: function(val){ this.billboard = val @@ -65,6 +76,32 @@ Sculpture.types.base = Fiber.extend(function(base){ } Sculpture.resize.move_dots() }, + + buildOutline: function(){ + this.outlineEl = new MX.Object3D(".mx-outline") + this.outlineEl.width = this.naturalDimensions.a + this.outlineEl.height = this.naturalDimensions.c + this.outlineEl.scale = this.mx.scale + this.outlineEl.rotationX = -PI/2 + this.outlineEl.x = this.mx.x + this.outlineEl.y = sculpture_distance_from_floor + this.outlineEl.z = this.mx.z + this.outlineEl.el.style.borderColor = this.outlineColor || "#000000" + scene.add(this.outlineEl) + }, + updateOutline: function(){ + if (! this.outline) { return } + if (! this.outlineEl) { + this.buildOutline() + } + this.outlineEl.x = this.mx.x + this.outlineEl.y = sculpture_distance_from_floor + this.outlineEl.z = this.mx.z + this.outlineEl.width = this.naturalDimensions.a + this.outlineEl.height = this.naturalDimensions.c + + this.outlineEl.scale = this.mx.scale + }, remove: function(){ if (this.removed) return @@ -112,7 +149,7 @@ Sculpture.types.base = Fiber.extend(function(base){ media: this.media, billboard: this.billboard, outline: this.outline, - outlineColor: this.outlineColor, + outlineColor: this.outlineColor || "#000000", backface: this.backface, } return data @@ -123,9 +160,14 @@ Sculpture.types.base = Fiber.extend(function(base){ this.mx.ops.width = data.dimensions.a this.mx.ops.height = data.dimensions.b this.billboard = data.billboard + this.outline = data.outline + this.outlineColor = data.outlineColor || "#000000" this.backface = data.backface if (! this.backface) this.mx.el.classList.remove("backface-visible") this.dimensions.deserialize(data.dimensions) + if (this.outline) { + this.buildOutline() + } }, } diff --git a/public/assets/javascripts/rectangles/models/vec3.js b/public/assets/javascripts/rectangles/models/vec3.js index 97329ed..b3825a9 100644 --- a/public/assets/javascripts/rectangles/models/vec3.js +++ b/public/assets/javascripts/rectangles/models/vec3.js @@ -39,5 +39,21 @@ vec3.prototype.serialize = function(){ vec3.prototype.deserialize = function(data){ this.a = data[0] this.b = data[1] - this.c = data[2] + this.c = data[2] || data[0] + return this +} +vec3.prototype.clone = function(){ + return new vec3(this.a, this.b, this.c) +} +vec3.prototype.assign = function(v){ + this.a = v.a + this.b = v.b + this.c = v.c + return this +} +vec3.prototype.mul = function(n) { + this.a *= n + this.b *= n + this.c *= n + return this } \ No newline at end of file diff --git a/public/assets/javascripts/rectangles/util/measurement.js b/public/assets/javascripts/rectangles/util/measurement.js index d6a0b35..6346eac 100644 --- a/public/assets/javascripts/rectangles/util/measurement.js +++ b/public/assets/javascripts/rectangles/util/measurement.js @@ -28,6 +28,10 @@ function measurementToString( n ) { case 'ft': ft = floor(n / 36) inch = abs(round((n % 36) / 3)) + if (inch == 12) { + inch = 0 + ft += 1 + } s = ft + "'" if (inch > 0) { s += " " + inch + '"' diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index 52663e1..953260c 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -17,6 +17,7 @@ var SculptureEditor = FormView.extend({ "change [name=mute]": "setMute", "change [name=width]": 'changeWidth', "change [name=height]": 'changeHeight', + "change [name=depth]": 'changeDepth', "change [name=units]": 'changeUnits', "click [data-role=destroy-sculpture]": "destroy", }, @@ -35,6 +36,7 @@ var SculptureEditor = FormView.extend({ // image fields this.$width = this.$("[name=width]") this.$height = this.$("[name=height]") + this.$depth = this.$("[name=depth]") this.$units = this.$("[name=units]") // video fields @@ -168,17 +170,26 @@ var SculptureEditor = FormView.extend({ if (! this.sculpture) return this.$width.unitVal( Number(this.sculpture.naturalDimensions.a * this.sculpture.scale) || "" ) this.$height.unitVal( Number(this.sculpture.naturalDimensions.b * this.sculpture.scale) || "" ) + this.$depth.unitVal( Number(this.sculpture.naturalDimensions.c * this.sculpture.scale) || "" ) this.tainted = true }, changeWidth: function(e){ e.stopPropagation() this.sculpture.set_scale( this.$width.unitVal() / this.sculpture.naturalDimensions.a ) this.setDimensions() + this.sculpture.updateOutline() }, changeHeight: function(e){ e.stopPropagation() this.sculpture.set_scale( this.$height.unitVal() / this.sculpture.naturalDimensions.b ) this.setDimensions() + this.sculpture.updateOutline() + }, + changeDepth: function(e){ + e.stopPropagation() + this.sculpture.set_depth( this.$depth.unitVal() ) + this.$depth.unitVal( Number(this.sculpture.naturalDimensions.c * this.sculpture.scale) || "" ) + this.sculpture.updateOutline() }, changeUnits: function(){ app.units = this.$units.val() diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 6e97500..6adb2a0 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1205,6 +1205,13 @@ form .paidPlan label { float: none; font-size: 16px; margin: 0 10px; } -webkit-box-sizing: content-box; box-sizing: content-box; } +.mx-outline { + border-width: 2px; + border-style: dashed; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; +} .destroyActive .mx-scene, .destroyActive .mx-object3d.image { cursor:url(/assets/img/delete-cursor.png), auto; } diff --git a/views/controls/editor/sculpture.ejs b/views/controls/editor/sculpture.ejs index 4b8535a..dfe917f 100644 --- a/views/controls/editor/sculpture.ejs +++ b/views/controls/editor/sculpture.ejs @@ -33,7 +33,7 @@
    - +
    remove object -- cgit v1.2.3-70-g09d2 From c0e5a31151dcdbf2b08707fba9008d003d87cd4f Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 28 Apr 2015 19:09:09 -0400 Subject: upgrade ionicons --- public/assets/fonts/ionicons.eot | Bin 101984 -> 120724 bytes public/assets/fonts/ionicons.svg | 1725 +++++++++++++++---------- public/assets/fonts/ionicons.ttf | Bin 164548 -> 188508 bytes public/assets/fonts/ionicons.woff | Bin 57276 -> 67904 bytes public/assets/javascripts/ui/site/HomeView.js | 2 +- public/assets/stylesheets/app.css | 12 +- public/assets/stylesheets/ionicons.css | 884 ++++++++----- views/controls/builder/settings.ejs | 2 +- views/controls/builder/toolbar.ejs | 6 +- views/controls/editor/media-drawer.ejs | 2 +- views/controls/editor/media-editor.ejs | 4 +- views/controls/editor/settings.ejs | 6 +- views/controls/editor/toolbar.ejs | 14 +- views/controls/editor/wallpaper.ejs | 2 +- views/controls/reader/about-room.ejs | 2 +- views/home.ejs | 4 +- views/profile.ejs | 2 +- 17 files changed, 1627 insertions(+), 1040 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/fonts/ionicons.eot b/public/assets/fonts/ionicons.eot index 52b1e57..92a3f20 100755 Binary files a/public/assets/fonts/ionicons.eot and b/public/assets/fonts/ionicons.eot differ diff --git a/public/assets/fonts/ionicons.svg b/public/assets/fonts/ionicons.svg index 5c8c909..49fc8f3 100755 --- a/public/assets/fonts/ionicons.svg +++ b/public/assets/fonts/ionicons.svg @@ -1,11 +1,11 @@ -Created by FontForge 20120731 at Mon Jun 16 14:44:31 2014 +Created by FontForge 20120731 at Thu Dec 4 09:51:48 2014 By Adam Bradley Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net) @@ -19,189 +19,307 @@ Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net) panose-1="2 0 6 3 0 0 0 0 0 0" ascent="448" descent="-64" - bbox="-0.5 -64.0026 512.487 448" + bbox="-0.54049 -64 512.487 448" underline-thickness="25.6" underline-position="-51.2" - unicode-range="U+F100-F358" + unicode-range="U+F100-F4F7" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - +d="M160 128c-38 0 -69 31 -69 69v150c0 38 31 69 69 69s69 -31 69 -69v-150c0 -38 -31 -69 -69 -69zM281 203h39c0 -78 -62 -142 -137 -153v-82h-46v82c-75 10 -137 75 -137 153h39c0 -69 58 -116 121 -116s121 47 121 116z" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -276,10 +401,8 @@ d="M438 256c6 0 10 -4 10 -10v-108c0 -6 -4 -10 -10 -10h-37v-54c0 -6 -4 -10 -10 -1 +d="M80 256h240v-224c0 -9 -7 -16 -16 -16h-208c-9 0 -16 7 -16 16v224zM296 104v48c0 4 -4 8 -8 8s-8 -4 -8 -8v-48c0 -4 4 -8 8 -8s8 4 8 8zM288 176c4 0 8 4 8 8s-4 8 -8 8s-8 -4 -8 -8s4 -8 8 -8zM381 416c3 0 3 -2 3 -3s-2 -3 -3 -5s-13 -20 -13 -40v-336 +c0 -35 -29 -64 -64 -64h-208c-35 0 -64 29 -64 64v307c0 32 -2 33 -32 37c0 12 11 40 65 40h316zM336 368c0 5 0 16 1 16h-273c-1 0 -3 0 -4 -1c5 -7 4 -32 4 -44v-307c0 -18 14 -32 32 -32h210c17 0 30 14 30 32v336z" /> + @@ -324,8 +451,8 @@ h192v-16h-192zM64 96v16h96v-16h-96zM320 96v48h64v-48h-64z" /> d="M0 352h512v-256h-512v256zM193 128c-20 23 -33 58 -33 96s13 73 33 96h-97c0 -35 -29 -64 -64 -64v-80c27 0 48 -21 48 -48h113zM298 187c3 4 4 9 4 15c0 3 0 5 -1 8s-2 6 -4 8s-4 4 -7 6s-6 4 -10 5c-1 0 -4 1 -7 2s-5 0 -8 1v31c2 -1 5 -2 7 -3c4 -3 6 -7 7 -13h20 c0 5 -2 9 -4 13s-5 8 -9 11s-9 5 -14 6c-2 1 -5 2 -7 2v9h-18v-9c-2 0 -4 -1 -6 -2c-5 -1 -10 -2 -14 -5s-7 -6 -9 -10s-4 -9 -4 -14c0 -3 0 -5 1 -8s2 -5 4 -7s5 -5 8 -7s7 -4 12 -5c3 -1 6 0 8 -1v-35c-3 1 -6 2 -9 4s-5 4 -6 7s-2 6 -2 9h-20c0 -5 2 -11 4 -16 c3 -5 6 -8 10 -11s9 -6 15 -7c3 -1 5 -2 8 -2v-9h18v9c3 0 6 1 9 2c5 1 10 2 14 5s7 7 10 11zM480 176v80c-35 0 -64 29 -64 64h-97c20 -23 33 -58 33 -96s-13 -73 -33 -96h113c0 27 22 48 48 48zM64 224c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32z -M384 224c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32zM273 213c2 -1 4 -2 6 -4s3 -5 3 -9c0 -2 0 -4 -1 -6s-2 -4 -4 -5s-5 -3 -8 -4c-1 0 -2 -1 -4 -1v31c3 -1 6 -1 8 -2zM236 257c1 2 3 3 5 4s4 2 6 2v-26c-4 1 -7 3 -9 5s-4 4 -4 8c0 3 1 5 2 7zM0 64 -v16h512v-16h-512zM0 32v16h512v-16h-512z" /> +M384 224c0 21 11 32 32 32s32 -11 32 -32s-11 -32 -32 -32s-32 11 -32 32zM273 213c2 -1 4 -2 6 -4s3 -5 3 -9c0 -2 0 -4 -1 -6s-2 -4 -4 -5s-5 -3 -8 -4c-1 0 -2 -1 -4 -1v31c3 -1 6 -1 8 -2zM236 257c1 2 3 3 5 4s4 2 6 2v-26c-4 1 -7 3 -9 5s-4 4 -4 8c0 3 1 5 2 7zM0 32 +v32h512v-32h-512z" /> @@ -358,14 +485,13 @@ d="M170 192v0v0l-167 174c-4 4 -4 12 0 16l30 30c4 4 12 5 16 1l204 -213c2 -2 3 -5 +d="M80 288c2 20 10 35 28 40l1 1c12 3 21 7 21 20v21c0 26 21 46 46 46s46 -20 46 -46v-21c0 -13 9 -18 21 -21h2c18 -5 25 -20 27 -40h-192zM176 384c-8 0 -13 -6 -13 -14s5 -14 13 -14s14 6 14 14s-6 14 -14 14zM325 384c15 0 27 -12 27 -28v-360c0 -16 -12 -28 -27 -28 +h-149h-148c-15 0 -28 12 -28 28v360c0 16 13 28 28 28h73v-13c0 -11 -9 -19 -19 -19h-37c-7 0 -12 -6 -12 -13v-327c0 -6 5 -12 11 -12h265c6 0 11 6 11 12v327c0 7 -5 13 -12 13h-37c-10 0 -20 8 -20 19v13h74zM64 224v32h112v-32h-112zM64 32v32h160v-32h-160zM64 96v32 +h129v-32h-129zM64 160v32h208v-32h-208z" /> +d="M224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM360 56c10 10 19 21 26 33l-27 16l8 14l27 -16c13 25 21 52 22 81h-32v16h32c-1 29 -9 56 -22 81l-27 -16l-8 14l27 16c-7 12 -16 23 -26 33s-21 19 -33 26l-16 -27l-14 8 +l16 27c-25 13 -52 21 -81 22v-32h-16v32c-29 -1 -56 -9 -81 -22l16 -27l-14 -8l-16 27c-12 -7 -23 -16 -33 -26s-19 -21 -26 -33l27 -16l-8 -14l-27 16c-13 -25 -21 -52 -22 -81h32v-16h-32c1 -29 9 -56 22 -81l27 16l8 -14l-27 -16c7 -12 16 -23 26 -33s21 -19 33 -26 +l16 27l14 -8l-16 -27c25 -13 52 -21 81 -22v32h16v-32c29 1 56 9 81 22l-16 27l14 8l16 -27c12 7 23 16 33 26zM368 207v-32h-117c-6 -9 -16 -15 -27 -15c-18 0 -32 14 -32 32c0 12 6 22 16 28v68h32v-68c5 -3 9 -8 12 -13h116z" /> @@ -406,6 +532,8 @@ s9 5 9 10v150z" /> d="M0 32v64h64v-64h-64zM96 32v128h64v-128h-64zM192 32v224h64v-224h-64zM288 32v320h64v-320h-64z" /> + @@ -421,33 +549,36 @@ d="M287 279c1 -3 1 -5 1 -9v-244c0 -13 -9 -26 -21 -26h-243c-12 0 -24 13 -24 26v33 +d="M325 322c2 -4 7 -12 3 -15c-3 -2 -10 -2 -13 5s0 11 -5 9s-7 3 -6 4c1 2 3 3 5 4c0 2 -4 8 2 7c4 -1 12 -10 14 -14zM344 277v0v0zM403 251c0 0 -2 0 0 0v0zM224 416c124 0 224 -100 224 -224s-100 -224 -224 -224s-224 100 -224 224s100 224 224 224zM141 19l8 -4 +c3 -1 6 -2 10 -3c14 -5 28 -8 43 -10c28 -3 56 -1 83 8c15 5 30 11 43 20c6 4 6 16 10 24c8 16 -2 33 12 47c12 14 4 19 4 34c0 10 8 18 4 29c-1 4 -7 -3 -9 1c-5 7 -21 1 -28 2c-13 2 -24 14 -33 23c-5 5 0 20 1 26c4 15 0 33 19 38c5 1 5 9 10 11c5 1 10 3 15 4 +c9 1 17 -2 26 -2c10 0 14 -5 22 -11c7 -6 13 -3 22 -5c7 0 0 5 -2 8c-3 2 -6 2 -8 2c-16 4 -23 22 -36 30c-6 3 -9 2 -11 0c-1 -1 1 -12 1 -12c-1 -3 -10 -4 -13 -5c-9 -2 -29 17 -15 22c4 1 27 5 24 15c-3 6 2 13 -5 14c-8 1 -7 7 -15 8c-5 1 -5 11 -5 14c0 9 2 6 9 7 +c-17 11 -37 19 -57 24c-1 -3 -5 -12 -8 -12c-5 -1 -6 0 -9 -3c-9 -10 -16 -28 -25 -7c-4 11 5 19 2 28h-6h-3c6 -12 -5 -18 -8 -19c-8 0 -10 5 -17 4c-4 -1 -7 4 -11 2s-13 -8 -14 -12c-3 -12 6 -13 14 -6c6 6 17 12 25 6c6 -5 5 -9 5 -14s-1 -18 -9 -16c-4 1 -7 6 -11 3 +c-8 -7 -18 -6 -29 -9c-10 -2 -16 -6 -25 -9c-8 -3 -11 -4 -12 -12c0 -2 0 -14 -3 -15c-5 -2 -8 22 -22 20c-12 -1 -30 -13 -25 -28c2 -5 28 -3 10 -14c-2 -1 2 -17 2 -20c1 -8 13 -18 21 -10c6 6 6 5 14 2c15 -8 33 -15 45 -27c6 -6 9 -24 17 -28c9 -5 19 -5 26 -14 +c6 -7 -2 -19 -8 -23c-4 -2 -12 -24 -16 -29c-2 -4 -12 -6 -16 -7c-3 0 -7 -9 -9 -11c-7 -7 -8 -13 -17 -19c-18 -12 -22 -23 -18 -44c2 -8 5 -13 11 -16zM100 46l2 -2c7 -6 15 -11 23 -16c-21 21 -23 49 -21 78l3 24c1 3 -4 7 -4 11c0 10 0 5 -8 13c-4 4 -10 11 -12 17 +c-7 16 1 30 10 43c9 14 -7 20 -10 32c-1 6 -7 6 -6 12c1 7 -4 5 -9 9c-12 8 -1 20 -7 26c-43 -70 -36 -162 16 -224c1 -1 0 -1 1 -2h1c3 -4 6 -8 9 -11s7 -6 10 -9z" /> + +d="M381 259l-250 -251l-91 91l251 250zM440 360c12 -12 11 -32 -2 -45l-45 -45l-91 91l45 45c13 13 33 14 45 2zM32 85l85 -85l-117 -32z" /> + + + @@ -475,9 +606,6 @@ c0 -65 36 -121 90 -150c6 -3 13 -7 19 -9c2 -1 3 -1 5 -2c9 -3 19 -5 29 -7c9 -2 18 l53 -52l-36 -41zM178 58l38 113h-85l139 155l-38 -113h85z" /> - - - +d="M224 416c124 0 224 -36 224 -80c0 -8 -3 -15 -9 -22v0c-35 -43 -151 -179 -151 -218v-4v-83v0c0 -23 -29 -41 -64 -41s-64 18 -64 41v0v87c0 39 -117 177 -149 216v0c-7 8 -11 16 -11 24c0 44 100 80 224 80zM224 288c92 0 176 22 176 48s-83 48 -176 48 +s-176 -22 -176 -48s84 -48 176 -48z" /> - + - - @@ -565,463 +681,554 @@ d="M448 195c2 -124 -97 -225 -221 -227s-225 97 -227 221s97 225 221 227s225 -97 22 - - - - - - - + + - - - - - - - - - - - - - - - - - - - - + + + + - - + + - - + + - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - + + - - - - - - - - - - - - - - + + - - - - - - - - + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - + + + + - - - - - - - - - - - - + + + + + + - - + + - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + + + - - - - - - - + + - - - - + - - - - - - - - - - - - + - - - - + + - - - - - + + - - - - - - - + + - - - - - - - - - - - + + - - - - - - - - - - - - - - + + - - - - - - - - + + - - - - - + + + + + - - - + + + d="M84 341c-21 0 -37 17 -37 38s16 37 37 37s37 -16 37 -37s-16 -38 -37 -38zM121 333c28 0 47 -24 47 -48v-114c0 -22 -32 -22 -32 0v105h-5v-286c0 -28 -41 -31 -43 0v165h-1h-7v-165c-1 -29 -43 -30 -43 0v286h-6v-105c0 -22 -31 -22 -31 0v114c0 24 19 48 47 48h37h37z " /> +d="M441 311c4 -3 7 -8 7 -14v-281c0 -6 -2 -11 -7 -14c-2 -1 -5 -2 -7 -2c-3 0 -6 0 -8 2l-97 66l-97 -66c-5 -3 -10 -3 -15 0l-97 66l-97 -66c-5 -3 -10 -3 -15 0s-8 8 -8 14v281c0 6 3 11 7 14l105 71c5 3 10 3 15 0l97 -66l98 66c5 3 10 3 15 0zM103 95v242l-71 -50v-242 +zM135 95l73 -49v129l-4 -11c-7 2 -13 6 -20 10l8 13c5 -3 11 -6 16 -8v109l-73 49v-101c4 -2 9 -4 13 -7l-10 -13c-1 1 -2 1 -3 2v-123zM240 46l73 49v109c0 -1 -1 -1 -1 -2l-6 -6l-12 11l6 6c3 3 5 7 8 10l5 -5v119l-73 -49v-112h7l3 -15c-3 0 -6 -1 -9 -1h-1v-114zM416 46 +v242l-71 49v-88c3 1 5 1 8 2l4 -16c-4 -1 -8 -1 -12 -3v-137zM97 227c-3 -1 -11 -5 -14 -7l-11 12c4 3 8 6 12 8c3 2 6 3 9 4l5 -15c-2 -1 1 -1 -1 -2zM265 182c5 3 10 5 15 10l11 -12c-6 -6 -12 -10 -19 -13zM67 192v-1l-15 5v1c2 7 4 13 9 20l13 -9c-4 -5 -5 -10 -7 -16z +M166 210c3 -4 7 -8 11 -11l-11 -12c-4 4 -8 9 -12 13l-3 3l12 11c1 -1 2 -3 3 -4zM376 218l-11 12l10 10l-10 10l11 12l10 -11l11 11l11 -12l-10 -10l10 -10l-11 -12l-11 11z" /> @@ -1443,6 +1656,11 @@ c-12 0 -23 -3 -33 -9l-80 138c35 20 73 31 113 31s78 -10 113 -30l-81 -139c-10 6 -2 + + +d="M315 318c10 -4 12 -13 9 -20l-148 -330s-143 320 -148 331s2 16 9 19c39 18 90 28 139 28s96 -9 139 -28zM112 256c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM176 109c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM240 224 +c18 0 32 14 32 32s-14 32 -32 32s-32 -14 -32 -32s14 -32 32 -32zM342 382c6 -3 10 -6 10 -13c0 -1 0 -3 -1 -5l-8 -19c-3 -5 -8 -9 -14 -9c-1 0 -3 1 -6 2c-41 18 -95 30 -147 30s-102 -11 -147 -30c-3 -1 -4 -2 -6 -2c-6 0 -11 4 -14 9l-8 19s-1 2 -1 5c0 8 6 12 10 14 +c49 21 107 33 166 33s118 -13 166 -34z" /> @@ -1521,21 +1737,16 @@ d="M48 324v-68h-48v68c0 33 28 60 61 60h67v-48h-68c-7 0 -12 -5 -12 -12zM356 384c3 c0 -7 5 -12 12 -12z" /> - + - + - + + + + + + + + + @@ -1629,19 +1869,25 @@ d="M113 371l79 -66l-114 -71l-78 63zM27 295l52 -42l86 53l-53 46zM306 235l78 -63l- l-78 -63l-114 71l79 66zM219 305l86 -52l52 42l-85 56z" /> + + - - + + + + @@ -1685,12 +1935,32 @@ h48c9 0 16 7 16 16zM337 32c9 0 15 7 15 16v176h-52c3 -10 4 -21 4 -32c0 -30 -11 -5 d="M112 192c0 53 27 80 80 80s80 -27 80 -80s-27 -80 -80 -80s-80 27 -80 80zM113 271c-14 -14 -23 -29 -28 -47h-85v112c0 13 4 25 14 34s22 14 35 14h288c13 0 24 -5 33 -14s14 -21 14 -34v-112h-84c-5 18 -14 33 -28 47c-22 22 -49 33 -80 33s-57 -11 -79 -33zM352 300 v39c0 4 -2 7 -4 9s-5 4 -9 4h-38c-4 0 -7 -2 -9 -4s-4 -5 -4 -9v-39c0 -4 2 -7 4 -9s5 -3 9 -3h38c4 0 7 1 9 3s4 5 4 9zM272 113c22 22 32 48 32 79h80v-144c0 -13 -5 -24 -14 -34s-20 -14 -33 -14h-288c-13 0 -24 4 -34 14s-15 21 -15 34v144h81c0 -31 10 -57 32 -79 s48 -33 79 -33s58 11 80 33z" /> + + + + + + + + + - + + + + + + + + + - + + @@ -1845,11 +2171,16 @@ h-208c-15 0 -15 3 -17 15l-19 242c-1 12 0 15 17 15h246z" /> + + +d="M224 384l224 -111l-92 -60l-132 -85l-160 102v-198l-32 16v203l-32 21zM358 192l10 -82c-16 -12 -112 -78 -144 -110c-32 32 -128 98 -144 110l9 82l135 -88z" /> diff --git a/public/assets/fonts/ionicons.ttf b/public/assets/fonts/ionicons.ttf index cc67b2f..c4e4632 100755 Binary files a/public/assets/fonts/ionicons.ttf and b/public/assets/fonts/ionicons.ttf differ diff --git a/public/assets/fonts/ionicons.woff b/public/assets/fonts/ionicons.woff index 1d7b977..5f3a14e 100755 Binary files a/public/assets/fonts/ionicons.woff and b/public/assets/fonts/ionicons.woff differ diff --git a/public/assets/javascripts/ui/site/HomeView.js b/public/assets/javascripts/ui/site/HomeView.js index a04bac1..20452bd 100644 --- a/public/assets/javascripts/ui/site/HomeView.js +++ b/public/assets/javascripts/ui/site/HomeView.js @@ -22,7 +22,7 @@ var HomeView = View.extend({ player.api('play') }) - $('.videoModal .ion-ios7-close-empty').click( function(){ + $('.videoModal .ion-ios-close-empty').click( function(){ player.api('pause') hide() }) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 6adb2a0..f4182d1 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -139,7 +139,7 @@ a{ background: rgba(255,255,255,0.9); } -.videoModal .ion-ios7-close-empty { +.videoModal .ion-ios-close-empty { position: absolute; right: 50px; top: 10px; @@ -148,7 +148,7 @@ a{ color:#444; } -.desktop .videoModal .ion-ios7-close-empty:hover { +.desktop .videoModal .ion-ios-close-empty:hover { color:black; } @@ -703,7 +703,7 @@ iframe.embed { border-right: 1px solid; } -.profilePic .ion-ios7-person-outline { +.profilePic .ion-ios-person-outline { font-size: 100px; } @@ -1466,7 +1466,7 @@ form .paidPlan label { float: none; font-size: 16px; margin: 0 10px; } font-weight:600; } -.menu span.ion-ios7-sunny-outline:hover:after { +.menu span.ion-ios-sunny-outline:hover:after { width: 130px; } @@ -1634,7 +1634,7 @@ form .paidPlan label { float: none; font-size: 16px; margin: 0 10px; } transform: translateY(0%); } -.fileUpload .ion-ios7-upload-outline { +.fileUpload .ion-ios-upload-outline { font-size:40px; } .fileUpload .upload-icon.uploading { @@ -3374,7 +3374,7 @@ a[data-role="forgot-password"] { .footer { padding:50px 0 120px 0; } - .videoModal .ion-ios7-close-empty { + .videoModal .ion-ios-close-empty { right: 10px; top: 20px; } diff --git a/public/assets/stylesheets/ionicons.css b/public/assets/stylesheets/ionicons.css index 34c20e2..885aa6b 100755 --- a/public/assets/stylesheets/ionicons.css +++ b/public/assets/stylesheets/ionicons.css @@ -1,25 +1,17 @@ +@charset "UTF-8"; /*! - Ionicons, v1.5.2 + Ionicons, v2.0.0 Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ https://twitter.com/benjsperry https://twitter.com/ionicframework MIT License: https://github.com/driftyco/ionicons + + Android-style icons originally built by Google’s + Material Design Icons: https://github.com/google/material-design-icons + used under CC BY http://creativecommons.org/licenses/by/4.0/ + Modified icons to fit ionicon’s grid from original. */ -@font-face { font-family: "Ionicons"; src: url("../fonts/ionicons.eot?v=1.5.2"); src: url("../fonts/ionicons.eot?v=1.5.2#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=1.5.2") format("truetype"), url("../fonts/ionicons.woff?v=1.5.2") format("woff"), url("../fonts/ionicons.svg?v=1.5.2#Ionicons") format("svg"); font-weight: normal; font-style: normal; } -.ion, .ion-loading-a, .ion-loading-b, .ion-loading-c, .ion-loading-d, .ion-looping, .ion-refreshing, .ion-ios7-reloading, .ionicons, .ion-alert:before, .ion-alert-circled:before, .ion-android-add:before, .ion-android-add-contact:before, .ion-android-alarm:before, .ion-android-archive:before, .ion-android-arrow-back:before, .ion-android-arrow-down-left:before, .ion-android-arrow-down-right:before, .ion-android-arrow-forward:before, .ion-android-arrow-up-left:before, .ion-android-arrow-up-right:before, .ion-android-battery:before, .ion-android-book:before, .ion-android-calendar:before, .ion-android-call:before, .ion-android-camera:before, .ion-android-chat:before, .ion-android-checkmark:before, .ion-android-clock:before, .ion-android-close:before, .ion-android-contact:before, .ion-android-contacts:before, .ion-android-data:before, .ion-android-developer:before, .ion-android-display:before, .ion-android-download:before, .ion-android-drawer:before, .ion-android-dropdown:before, .ion-android-earth:before, .ion-android-folder:before, .ion-android-forums:before, .ion-android-friends:before, .ion-android-hand:before, .ion-android-image:before, .ion-android-inbox:before, .ion-android-information:before, .ion-android-keypad:before, .ion-android-lightbulb:before, .ion-android-locate:before, .ion-android-location:before, .ion-android-mail:before, .ion-android-microphone:before, .ion-android-mixer:before, .ion-android-more:before, .ion-android-note:before, .ion-android-playstore:before, .ion-android-printer:before, .ion-android-promotion:before, .ion-android-reminder:before, .ion-android-remove:before, .ion-android-search:before, .ion-android-send:before, .ion-android-settings:before, .ion-android-share:before, .ion-android-social:before, .ion-android-social-user:before, .ion-android-sort:before, .ion-android-stair-drawer:before, .ion-android-star:before, .ion-android-stopwatch:before, .ion-android-storage:before, .ion-android-system-back:before, .ion-android-system-home:before, .ion-android-system-windows:before, .ion-android-timer:before, .ion-android-trash:before, .ion-android-user-menu:before, .ion-android-volume:before, .ion-android-wifi:before, .ion-aperture:before, .ion-archive:before, .ion-arrow-down-a:before, .ion-arrow-down-b:before, .ion-arrow-down-c:before, .ion-arrow-expand:before, .ion-arrow-graph-down-left:before, .ion-arrow-graph-down-right:before, .ion-arrow-graph-up-left:before, .ion-arrow-graph-up-right:before, .ion-arrow-left-a:before, .ion-arrow-left-b:before, .ion-arrow-left-c:before, .ion-arrow-move:before, .ion-arrow-resize:before, .ion-arrow-return-left:before, .ion-arrow-return-right:before, .ion-arrow-right-a:before, .ion-arrow-right-b:before, .ion-arrow-right-c:before, .ion-arrow-shrink:before, .ion-arrow-swap:before, .ion-arrow-up-a:before, .ion-arrow-up-b:before, .ion-arrow-up-c:before, .ion-asterisk:before, .ion-at:before, .ion-bag:before, .ion-battery-charging:before, .ion-battery-empty:before, .ion-battery-full:before, .ion-battery-half:before, .ion-battery-low:before, .ion-beaker:before, .ion-beer:before, .ion-bluetooth:before, .ion-bonfire:before, .ion-bookmark:before, .ion-briefcase:before, .ion-bug:before, .ion-calculator:before, .ion-calendar:before, .ion-camera:before, .ion-card:before, .ion-cash:before, .ion-chatbox:before, .ion-chatbox-working:before, .ion-chatboxes:before, .ion-chatbubble:before, .ion-chatbubble-working:before, .ion-chatbubbles:before, .ion-checkmark:before, .ion-checkmark-circled:before, .ion-checkmark-round:before, .ion-chevron-down:before, .ion-chevron-left:before, .ion-chevron-right:before, .ion-chevron-up:before, .ion-clipboard:before, .ion-clock:before, .ion-close:before, .ion-close-circled:before, .ion-close-round:before, .ion-closed-captioning:before, .ion-cloud:before, .ion-code:before, .ion-code-download:before, .ion-code-working:before, .ion-coffee:before, .ion-compass:before, .ion-compose:before, .ion-connection-bars:before, .ion-contrast:before, .ion-cube:before, .ion-disc:before, .ion-document:before, .ion-document-text:before, .ion-drag:before, .ion-earth:before, .ion-edit:before, .ion-egg:before, .ion-eject:before, .ion-email:before, .ion-eye:before, .ion-eye-disabled:before, .ion-female:before, .ion-filing:before, .ion-film-marker:before, .ion-fireball:before, .ion-flag:before, .ion-flame:before, .ion-flash:before, .ion-flash-off:before, .ion-flask:before, .ion-folder:before, .ion-fork:before, .ion-fork-repo:before, .ion-forward:before, .ion-funnel:before, .ion-game-controller-a:before, .ion-game-controller-b:before, .ion-gear-a:before, .ion-gear-b:before, .ion-grid:before, .ion-hammer:before, .ion-happy:before, .ion-headphone:before, .ion-heart:before, .ion-heart-broken:before, .ion-help:before, .ion-help-buoy:before, .ion-help-circled:before, .ion-home:before, .ion-icecream:before, .ion-icon-social-google-plus:before, .ion-icon-social-google-plus-outline:before, .ion-image:before, .ion-images:before, .ion-information:before, .ion-information-circled:before, .ion-ionic:before, .ion-ios7-alarm:before, .ion-ios7-alarm-outline:before, .ion-ios7-albums:before, .ion-ios7-albums-outline:before, .ion-ios7-americanfootball:before, .ion-ios7-americanfootball-outline:before, .ion-ios7-analytics:before, .ion-ios7-analytics-outline:before, .ion-ios7-arrow-back:before, .ion-ios7-arrow-down:before, .ion-ios7-arrow-forward:before, .ion-ios7-arrow-left:before, .ion-ios7-arrow-right:before, .ion-ios7-arrow-thin-down:before, .ion-ios7-arrow-thin-left:before, .ion-ios7-arrow-thin-right:before, .ion-ios7-arrow-thin-up:before, .ion-ios7-arrow-up:before, .ion-ios7-at:before, .ion-ios7-at-outline:before, .ion-ios7-barcode:before, .ion-ios7-barcode-outline:before, .ion-ios7-baseball:before, .ion-ios7-baseball-outline:before, .ion-ios7-basketball:before, .ion-ios7-basketball-outline:before, .ion-ios7-bell:before, .ion-ios7-bell-outline:before, .ion-ios7-bolt:before, .ion-ios7-bolt-outline:before, .ion-ios7-bookmarks:before, .ion-ios7-bookmarks-outline:before, .ion-ios7-box:before, .ion-ios7-box-outline:before, .ion-ios7-briefcase:before, .ion-ios7-briefcase-outline:before, .ion-ios7-browsers:before, .ion-ios7-browsers-outline:before, .ion-ios7-calculator:before, .ion-ios7-calculator-outline:before, .ion-ios7-calendar:before, .ion-ios7-calendar-outline:before, .ion-ios7-camera:before, .ion-ios7-camera-outline:before, .ion-ios7-cart:before, .ion-ios7-cart-outline:before, .ion-ios7-chatboxes:before, .ion-ios7-chatboxes-outline:before, .ion-ios7-chatbubble:before, .ion-ios7-chatbubble-outline:before, .ion-ios7-checkmark:before, .ion-ios7-checkmark-empty:before, .ion-ios7-checkmark-outline:before, .ion-ios7-circle-filled:before, .ion-ios7-circle-outline:before, .ion-ios7-clock:before, .ion-ios7-clock-outline:before, .ion-ios7-close:before, .ion-ios7-close-empty:before, .ion-ios7-close-outline:before, .ion-ios7-cloud:before, .ion-ios7-cloud-download:before, .ion-ios7-cloud-download-outline:before, .ion-ios7-cloud-outline:before, .ion-ios7-cloud-upload:before, .ion-ios7-cloud-upload-outline:before, .ion-ios7-cloudy:before, .ion-ios7-cloudy-night:before, .ion-ios7-cloudy-night-outline:before, .ion-ios7-cloudy-outline:before, .ion-ios7-cog:before, .ion-ios7-cog-outline:before, .ion-ios7-compose:before, .ion-ios7-compose-outline:before, .ion-ios7-contact:before, .ion-ios7-contact-outline:before, .ion-ios7-copy:before, .ion-ios7-copy-outline:before, .ion-ios7-download:before, .ion-ios7-download-outline:before, .ion-ios7-drag:before, .ion-ios7-email:before, .ion-ios7-email-outline:before, .ion-ios7-expand:before, .ion-ios7-eye:before, .ion-ios7-eye-outline:before, .ion-ios7-fastforward:before, .ion-ios7-fastforward-outline:before, .ion-ios7-filing:before, .ion-ios7-filing-outline:before, .ion-ios7-film:before, .ion-ios7-film-outline:before, .ion-ios7-flag:before, .ion-ios7-flag-outline:before, .ion-ios7-folder:before, .ion-ios7-folder-outline:before, .ion-ios7-football:before, .ion-ios7-football-outline:before, .ion-ios7-gear:before, .ion-ios7-gear-outline:before, .ion-ios7-glasses:before, .ion-ios7-glasses-outline:before, .ion-ios7-heart:before, .ion-ios7-heart-outline:before, .ion-ios7-help:before, .ion-ios7-help-empty:before, .ion-ios7-help-outline:before, .ion-ios7-home:before, .ion-ios7-home-outline:before, .ion-ios7-infinite:before, .ion-ios7-infinite-outline:before, .ion-ios7-information:before, .ion-ios7-information-empty:before, .ion-ios7-information-outline:before, .ion-ios7-ionic-outline:before, .ion-ios7-keypad:before, .ion-ios7-keypad-outline:before, .ion-ios7-lightbulb:before, .ion-ios7-lightbulb-outline:before, .ion-ios7-location:before, .ion-ios7-location-outline:before, .ion-ios7-locked:before, .ion-ios7-locked-outline:before, .ion-ios7-loop:before, .ion-ios7-loop-strong:before, .ion-ios7-medkit:before, .ion-ios7-medkit-outline:before, .ion-ios7-mic:before, .ion-ios7-mic-off:before, .ion-ios7-mic-outline:before, .ion-ios7-minus:before, .ion-ios7-minus-empty:before, .ion-ios7-minus-outline:before, .ion-ios7-monitor:before, .ion-ios7-monitor-outline:before, .ion-ios7-moon:before, .ion-ios7-moon-outline:before, .ion-ios7-more:before, .ion-ios7-more-outline:before, .ion-ios7-musical-note:before, .ion-ios7-musical-notes:before, .ion-ios7-navigate:before, .ion-ios7-navigate-outline:before, .ion-ios7-paper:before, .ion-ios7-paper-outline:before, .ion-ios7-paperplane:before, .ion-ios7-paperplane-outline:before, .ion-ios7-partlysunny:before, .ion-ios7-partlysunny-outline:before, .ion-ios7-pause:before, .ion-ios7-pause-outline:before, .ion-ios7-paw:before, .ion-ios7-paw-outline:before, .ion-ios7-people:before, .ion-ios7-people-outline:before, .ion-ios7-person:before, .ion-ios7-person-outline:before, .ion-ios7-personadd:before, .ion-ios7-personadd-outline:before, .ion-ios7-photos:before, .ion-ios7-photos-outline:before, .ion-ios7-pie:before, .ion-ios7-pie-outline:before, .ion-ios7-play:before, .ion-ios7-play-outline:before, .ion-ios7-plus:before, .ion-ios7-plus-empty:before, .ion-ios7-plus-outline:before, .ion-ios7-pricetag:before, .ion-ios7-pricetag-outline:before, .ion-ios7-pricetags:before, .ion-ios7-pricetags-outline:before, .ion-ios7-printer:before, .ion-ios7-printer-outline:before, .ion-ios7-pulse:before, .ion-ios7-pulse-strong:before, .ion-ios7-rainy:before, .ion-ios7-rainy-outline:before, .ion-ios7-recording:before, .ion-ios7-recording-outline:before, .ion-ios7-redo:before, .ion-ios7-redo-outline:before, .ion-ios7-refresh:before, .ion-ios7-refresh-empty:before, .ion-ios7-refresh-outline:before, .ion-ios7-reload:before, .ion-ios7-reloading:before, .ion-ios7-reverse-camera:before, .ion-ios7-reverse-camera-outline:before, .ion-ios7-rewind:before, .ion-ios7-rewind-outline:before, .ion-ios7-search:before, .ion-ios7-search-strong:before, .ion-ios7-settings:before, .ion-ios7-settings-strong:before, .ion-ios7-shrink:before, .ion-ios7-skipbackward:before, .ion-ios7-skipbackward-outline:before, .ion-ios7-skipforward:before, .ion-ios7-skipforward-outline:before, .ion-ios7-snowy:before, .ion-ios7-speedometer:before, .ion-ios7-speedometer-outline:before, .ion-ios7-star:before, .ion-ios7-star-half:before, .ion-ios7-star-outline:before, .ion-ios7-stopwatch:before, .ion-ios7-stopwatch-outline:before, .ion-ios7-sunny:before, .ion-ios7-sunny-outline:before, .ion-ios7-telephone:before, .ion-ios7-telephone-outline:before, .ion-ios7-tennisball:before, .ion-ios7-tennisball-outline:before, .ion-ios7-thunderstorm:before, .ion-ios7-thunderstorm-outline:before, .ion-ios7-time:before, .ion-ios7-time-outline:before, .ion-ios7-timer:before, .ion-ios7-timer-outline:before, .ion-ios7-toggle:before, .ion-ios7-toggle-outline:before, .ion-ios7-trash:before, .ion-ios7-trash-outline:before, .ion-ios7-undo:before, .ion-ios7-undo-outline:before, .ion-ios7-unlocked:before, .ion-ios7-unlocked-outline:before, .ion-ios7-upload:before, .ion-ios7-upload-outline:before, .ion-ios7-videocam:before, .ion-ios7-videocam-outline:before, .ion-ios7-volume-high:before, .ion-ios7-volume-low:before, .ion-ios7-wineglass:before, .ion-ios7-wineglass-outline:before, .ion-ios7-world:before, .ion-ios7-world-outline:before, .ion-ipad:before, .ion-iphone:before, .ion-ipod:before, .ion-jet:before, .ion-key:before, .ion-knife:before, .ion-laptop:before, .ion-leaf:before, .ion-levels:before, .ion-lightbulb:before, .ion-link:before, .ion-load-a:before, .ion-loading-a:before, .ion-load-b:before, .ion-loading-b:before, .ion-load-c:before, .ion-loading-c:before, .ion-load-d:before, .ion-loading-d:before, .ion-location:before, .ion-locked:before, .ion-log-in:before, .ion-log-out:before, .ion-loop:before, .ion-looping:before, .ion-magnet:before, .ion-male:before, .ion-man:before, .ion-map:before, .ion-medkit:before, .ion-merge:before, .ion-mic-a:before, .ion-mic-b:before, .ion-mic-c:before, .ion-minus:before, .ion-minus-circled:before, .ion-minus-round:before, .ion-model-s:before, .ion-monitor:before, .ion-more:before, .ion-mouse:before, .ion-music-note:before, .ion-navicon:before, .ion-navicon-round:before, .ion-navigate:before, .ion-network:before, .ion-no-smoking:before, .ion-nuclear:before, .ion-outlet:before, .ion-paper-airplane:before, .ion-paperclip:before, .ion-pause:before, .ion-person:before, .ion-person-add:before, .ion-person-stalker:before, .ion-pie-graph:before, .ion-pin:before, .ion-pinpoint:before, .ion-pizza:before, .ion-plane:before, .ion-planet:before, .ion-play:before, .ion-playstation:before, .ion-plus:before, .ion-plus-circled:before, .ion-plus-round:before, .ion-podium:before, .ion-pound:before, .ion-power:before, .ion-pricetag:before, .ion-pricetags:before, .ion-printer:before, .ion-pull-request:before, .ion-qr-scanner:before, .ion-quote:before, .ion-radio-waves:before, .ion-record:before, .ion-refresh:before, .ion-refreshing:before, .ion-reply:before, .ion-reply-all:before, .ion-ribbon-a:before, .ion-ribbon-b:before, .ion-sad:before, .ion-scissors:before, .ion-search:before, .ion-settings:before, .ion-share:before, .ion-shuffle:before, .ion-skip-backward:before, .ion-skip-forward:before, .ion-social-android:before, .ion-social-android-outline:before, .ion-social-apple:before, .ion-social-apple-outline:before, .ion-social-bitcoin:before, .ion-social-bitcoin-outline:before, .ion-social-buffer:before, .ion-social-buffer-outline:before, .ion-social-designernews:before, .ion-social-designernews-outline:before, .ion-social-dribbble:before, .ion-social-dribbble-outline:before, .ion-social-dropbox:before, .ion-social-dropbox-outline:before, .ion-social-facebook:before, .ion-social-facebook-outline:before, .ion-social-foursquare:before, .ion-social-foursquare-outline:before, .ion-social-freebsd-devil:before, .ion-social-github:before, .ion-social-github-outline:before, .ion-social-google:before, .ion-social-google-outline:before, .ion-social-googleplus:before, .ion-social-googleplus-outline:before, .ion-social-hackernews:before, .ion-social-hackernews-outline:before, .ion-social-instagram:before, .ion-social-instagram-outline:before, .ion-social-linkedin:before, .ion-social-linkedin-outline:before, .ion-social-pinterest:before, .ion-social-pinterest-outline:before, .ion-social-reddit:before, .ion-social-reddit-outline:before, .ion-social-rss:before, .ion-social-rss-outline:before, .ion-social-skype:before, .ion-social-skype-outline:before, .ion-social-tumblr:before, .ion-social-tumblr-outline:before, .ion-social-tux:before, .ion-social-twitter:before, .ion-social-twitter-outline:before, .ion-social-usd:before, .ion-social-usd-outline:before, .ion-social-vimeo:before, .ion-social-vimeo-outline:before, .ion-social-windows:before, .ion-social-windows-outline:before, .ion-social-wordpress:before, .ion-social-wordpress-outline:before, .ion-social-yahoo:before, .ion-social-yahoo-outline:before, .ion-social-youtube:before, .ion-social-youtube-outline:before, .ion-speakerphone:before, .ion-speedometer:before, .ion-spoon:before, .ion-star:before, .ion-stats-bars:before, .ion-steam:before, .ion-stop:before, .ion-thermometer:before, .ion-thumbsdown:before, .ion-thumbsup:before, .ion-toggle:before, .ion-toggle-filled:before, .ion-trash-a:before, .ion-trash-b:before, .ion-trophy:before, .ion-umbrella:before, .ion-university:before, .ion-unlocked:before, .ion-upload:before, .ion-usb:before, .ion-videocamera:before, .ion-volume-high:before, .ion-volume-low:before, .ion-volume-medium:before, .ion-volume-mute:before, .ion-wand:before, .ion-waterdrop:before, .ion-wifi:before, .ion-wineglass:before, .ion-woman:before, .ion-wrench:before, .ion-xbox:before { display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } - -.ion-spin, .ion-loading-a, .ion-loading-b, .ion-loading-c, .ion-loading-d, .ion-looping, .ion-refreshing, .ion-ios7-reloading { -webkit-animation: spin 1s infinite linear; -moz-animation: spin 1s infinite linear; -o-animation: spin 1s infinite linear; animation: spin 1s infinite linear; } - -@-moz-keyframes spin { 0% { -moz-transform: rotate(0deg); } - 100% { -moz-transform: rotate(359deg); } } -@-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); } - 100% { -webkit-transform: rotate(359deg); } } -@-o-keyframes spin { 0% { -o-transform: rotate(0deg); } - 100% { -o-transform: rotate(359deg); } } -@-ms-keyframes spin { 0% { -ms-transform: rotate(0deg); } - 100% { -ms-transform: rotate(359deg); } } -@keyframes spin { 0% { transform: rotate(0deg); } - 100% { transform: rotate(359deg); } } -.ion-loading-a { -webkit-animation-timing-function: steps(8, start); -moz-animation-timing-function: steps(8, start); animation-timing-function: steps(8, start); } +@font-face { font-family: "Ionicons"; src: url("../fonts/ionicons.eot?v=2.0.0"); src: url("../fonts/ionicons.eot?v=2.0.0#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=2.0.0") format("truetype"), url("../fonts/ionicons.woff?v=2.0.0") format("woff"), url("../fonts/ionicons.svg?v=2.0.0#Ionicons") format("svg"); font-weight: normal; font-style: normal; } +.ion, .ionicons, .ion-alert:before, .ion-alert-circled:before, .ion-android-add:before, .ion-android-add-circle:before, .ion-android-alarm-clock:before, .ion-android-alert:before, .ion-android-apps:before, .ion-android-archive:before, .ion-android-arrow-back:before, .ion-android-arrow-down:before, .ion-android-arrow-dropdown:before, .ion-android-arrow-dropdown-circle:before, .ion-android-arrow-dropleft:before, .ion-android-arrow-dropleft-circle:before, .ion-android-arrow-dropright:before, .ion-android-arrow-dropright-circle:before, .ion-android-arrow-dropup:before, .ion-android-arrow-dropup-circle:before, .ion-android-arrow-forward:before, .ion-android-arrow-up:before, .ion-android-attach:before, .ion-android-bar:before, .ion-android-bicycle:before, .ion-android-boat:before, .ion-android-bookmark:before, .ion-android-bulb:before, .ion-android-bus:before, .ion-android-calendar:before, .ion-android-call:before, .ion-android-camera:before, .ion-android-cancel:before, .ion-android-car:before, .ion-android-cart:before, .ion-android-chat:before, .ion-android-checkbox:before, .ion-android-checkbox-blank:before, .ion-android-checkbox-outline:before, .ion-android-checkbox-outline-blank:before, .ion-android-checkmark-circle:before, .ion-android-clipboard:before, .ion-android-close:before, .ion-android-cloud:before, .ion-android-cloud-circle:before, .ion-android-cloud-done:before, .ion-android-cloud-outline:before, .ion-android-color-palette:before, .ion-android-compass:before, .ion-android-contact:before, .ion-android-contacts:before, .ion-android-contract:before, .ion-android-create:before, .ion-android-delete:before, .ion-android-desktop:before, .ion-android-document:before, .ion-android-done:before, .ion-android-done-all:before, .ion-android-download:before, .ion-android-drafts:before, .ion-android-exit:before, .ion-android-expand:before, .ion-android-favorite:before, .ion-android-favorite-outline:before, .ion-android-film:before, .ion-android-folder:before, .ion-android-folder-open:before, .ion-android-funnel:before, .ion-android-globe:before, .ion-android-hand:before, .ion-android-hangout:before, .ion-android-happy:before, .ion-android-home:before, .ion-android-image:before, .ion-android-laptop:before, .ion-android-list:before, .ion-android-locate:before, .ion-android-lock:before, .ion-android-mail:before, .ion-android-map:before, .ion-android-menu:before, .ion-android-microphone:before, .ion-android-microphone-off:before, .ion-android-more-horizontal:before, .ion-android-more-vertical:before, .ion-android-navigate:before, .ion-android-notifications:before, .ion-android-notifications-none:before, .ion-android-notifications-off:before, .ion-android-open:before, .ion-android-options:before, .ion-android-people:before, .ion-android-person:before, .ion-android-person-add:before, .ion-android-phone-landscape:before, .ion-android-phone-portrait:before, .ion-android-pin:before, .ion-android-plane:before, .ion-android-playstore:before, .ion-android-print:before, .ion-android-radio-button-off:before, .ion-android-radio-button-on:before, .ion-android-refresh:before, .ion-android-remove:before, .ion-android-remove-circle:before, .ion-android-restaurant:before, .ion-android-sad:before, .ion-android-search:before, .ion-android-send:before, .ion-android-settings:before, .ion-android-share:before, .ion-android-share-alt:before, .ion-android-star:before, .ion-android-star-half:before, .ion-android-star-outline:before, .ion-android-stopwatch:before, .ion-android-subway:before, .ion-android-sunny:before, .ion-android-sync:before, .ion-android-textsms:before, .ion-android-time:before, .ion-android-train:before, .ion-android-unlock:before, .ion-android-upload:before, .ion-android-volume-down:before, .ion-android-volume-mute:before, .ion-android-volume-off:before, .ion-android-volume-up:before, .ion-android-walk:before, .ion-android-warning:before, .ion-android-watch:before, .ion-android-wifi:before, .ion-aperture:before, .ion-archive:before, .ion-arrow-down-a:before, .ion-arrow-down-b:before, .ion-arrow-down-c:before, .ion-arrow-expand:before, .ion-arrow-graph-down-left:before, .ion-arrow-graph-down-right:before, .ion-arrow-graph-up-left:before, .ion-arrow-graph-up-right:before, .ion-arrow-left-a:before, .ion-arrow-left-b:before, .ion-arrow-left-c:before, .ion-arrow-move:before, .ion-arrow-resize:before, .ion-arrow-return-left:before, .ion-arrow-return-right:before, .ion-arrow-right-a:before, .ion-arrow-right-b:before, .ion-arrow-right-c:before, .ion-arrow-shrink:before, .ion-arrow-swap:before, .ion-arrow-up-a:before, .ion-arrow-up-b:before, .ion-arrow-up-c:before, .ion-asterisk:before, .ion-at:before, .ion-backspace:before, .ion-backspace-outline:before, .ion-bag:before, .ion-battery-charging:before, .ion-battery-empty:before, .ion-battery-full:before, .ion-battery-half:before, .ion-battery-low:before, .ion-beaker:before, .ion-beer:before, .ion-bluetooth:before, .ion-bonfire:before, .ion-bookmark:before, .ion-bowtie:before, .ion-briefcase:before, .ion-bug:before, .ion-calculator:before, .ion-calendar:before, .ion-camera:before, .ion-card:before, .ion-cash:before, .ion-chatbox:before, .ion-chatbox-working:before, .ion-chatboxes:before, .ion-chatbubble:before, .ion-chatbubble-working:before, .ion-chatbubbles:before, .ion-checkmark:before, .ion-checkmark-circled:before, .ion-checkmark-round:before, .ion-chevron-down:before, .ion-chevron-left:before, .ion-chevron-right:before, .ion-chevron-up:before, .ion-clipboard:before, .ion-clock:before, .ion-close:before, .ion-close-circled:before, .ion-close-round:before, .ion-closed-captioning:before, .ion-cloud:before, .ion-code:before, .ion-code-download:before, .ion-code-working:before, .ion-coffee:before, .ion-compass:before, .ion-compose:before, .ion-connection-bars:before, .ion-contrast:before, .ion-crop:before, .ion-cube:before, .ion-disc:before, .ion-document:before, .ion-document-text:before, .ion-drag:before, .ion-earth:before, .ion-easel:before, .ion-edit:before, .ion-egg:before, .ion-eject:before, .ion-email:before, .ion-email-unread:before, .ion-erlenmeyer-flask:before, .ion-erlenmeyer-flask-bubbles:before, .ion-eye:before, .ion-eye-disabled:before, .ion-female:before, .ion-filing:before, .ion-film-marker:before, .ion-fireball:before, .ion-flag:before, .ion-flame:before, .ion-flash:before, .ion-flash-off:before, .ion-folder:before, .ion-fork:before, .ion-fork-repo:before, .ion-forward:before, .ion-funnel:before, .ion-gear-a:before, .ion-gear-b:before, .ion-grid:before, .ion-hammer:before, .ion-happy:before, .ion-happy-outline:before, .ion-headphone:before, .ion-heart:before, .ion-heart-broken:before, .ion-help:before, .ion-help-buoy:before, .ion-help-circled:before, .ion-home:before, .ion-icecream:before, .ion-image:before, .ion-images:before, .ion-information:before, .ion-information-circled:before, .ion-ionic:before, .ion-ios-alarm:before, .ion-ios-alarm-outline:before, .ion-ios-albums:before, .ion-ios-albums-outline:before, .ion-ios-americanfootball:before, .ion-ios-americanfootball-outline:before, .ion-ios-analytics:before, .ion-ios-analytics-outline:before, .ion-ios-arrow-back:before, .ion-ios-arrow-down:before, .ion-ios-arrow-forward:before, .ion-ios-arrow-left:before, .ion-ios-arrow-right:before, .ion-ios-arrow-thin-down:before, .ion-ios-arrow-thin-left:before, .ion-ios-arrow-thin-right:before, .ion-ios-arrow-thin-up:before, .ion-ios-arrow-up:before, .ion-ios-at:before, .ion-ios-at-outline:before, .ion-ios-barcode:before, .ion-ios-barcode-outline:before, .ion-ios-baseball:before, .ion-ios-baseball-outline:before, .ion-ios-basketball:before, .ion-ios-basketball-outline:before, .ion-ios-bell:before, .ion-ios-bell-outline:before, .ion-ios-body:before, .ion-ios-body-outline:before, .ion-ios-bolt:before, .ion-ios-bolt-outline:before, .ion-ios-book:before, .ion-ios-book-outline:before, .ion-ios-bookmarks:before, .ion-ios-bookmarks-outline:before, .ion-ios-box:before, .ion-ios-box-outline:before, .ion-ios-briefcase:before, .ion-ios-briefcase-outline:before, .ion-ios-browsers:before, .ion-ios-browsers-outline:before, .ion-ios-calculator:before, .ion-ios-calculator-outline:before, .ion-ios-calendar:before, .ion-ios-calendar-outline:before, .ion-ios-camera:before, .ion-ios-camera-outline:before, .ion-ios-cart:before, .ion-ios-cart-outline:before, .ion-ios-chatboxes:before, .ion-ios-chatboxes-outline:before, .ion-ios-chatbubble:before, .ion-ios-chatbubble-outline:before, .ion-ios-checkmark:before, .ion-ios-checkmark-empty:before, .ion-ios-checkmark-outline:before, .ion-ios-circle-filled:before, .ion-ios-circle-outline:before, .ion-ios-clock:before, .ion-ios-clock-outline:before, .ion-ios-close:before, .ion-ios-close-empty:before, .ion-ios-close-outline:before, .ion-ios-cloud:before, .ion-ios-cloud-download:before, .ion-ios-cloud-download-outline:before, .ion-ios-cloud-outline:before, .ion-ios-cloud-upload:before, .ion-ios-cloud-upload-outline:before, .ion-ios-cloudy:before, .ion-ios-cloudy-night:before, .ion-ios-cloudy-night-outline:before, .ion-ios-cloudy-outline:before, .ion-ios-cog:before, .ion-ios-cog-outline:before, .ion-ios-color-filter:before, .ion-ios-color-filter-outline:before, .ion-ios-color-wand:before, .ion-ios-color-wand-outline:before, .ion-ios-compose:before, .ion-ios-compose-outline:before, .ion-ios-contact:before, .ion-ios-contact-outline:before, .ion-ios-copy:before, .ion-ios-copy-outline:before, .ion-ios-crop:before, .ion-ios-crop-strong:before, .ion-ios-download:before, .ion-ios-download-outline:before, .ion-ios-drag:before, .ion-ios-email:before, .ion-ios-email-outline:before, .ion-ios-eye:before, .ion-ios-eye-outline:before, .ion-ios-fastforward:before, .ion-ios-fastforward-outline:before, .ion-ios-filing:before, .ion-ios-filing-outline:before, .ion-ios-film:before, .ion-ios-film-outline:before, .ion-ios-flag:before, .ion-ios-flag-outline:before, .ion-ios-flame:before, .ion-ios-flame-outline:before, .ion-ios-flask:before, .ion-ios-flask-outline:before, .ion-ios-flower:before, .ion-ios-flower-outline:before, .ion-ios-folder:before, .ion-ios-folder-outline:before, .ion-ios-football:before, .ion-ios-football-outline:before, .ion-ios-game-controller-a:before, .ion-ios-game-controller-a-outline:before, .ion-ios-game-controller-b:before, .ion-ios-game-controller-b-outline:before, .ion-ios-gear:before, .ion-ios-gear-outline:before, .ion-ios-glasses:before, .ion-ios-glasses-outline:before, .ion-ios-grid-view:before, .ion-ios-grid-view-outline:before, .ion-ios-heart:before, .ion-ios-heart-outline:before, .ion-ios-help:before, .ion-ios-help-empty:before, .ion-ios-help-outline:before, .ion-ios-home:before, .ion-ios-home-outline:before, .ion-ios-infinite:before, .ion-ios-infinite-outline:before, .ion-ios-information:before, .ion-ios-information-empty:before, .ion-ios-information-outline:before, .ion-ios-ionic-outline:before, .ion-ios-keypad:before, .ion-ios-keypad-outline:before, .ion-ios-lightbulb:before, .ion-ios-lightbulb-outline:before, .ion-ios-list:before, .ion-ios-list-outline:before, .ion-ios-location:before, .ion-ios-location-outline:before, .ion-ios-locked:before, .ion-ios-locked-outline:before, .ion-ios-loop:before, .ion-ios-loop-strong:before, .ion-ios-medical:before, .ion-ios-medical-outline:before, .ion-ios-medkit:before, .ion-ios-medkit-outline:before, .ion-ios-mic:before, .ion-ios-mic-off:before, .ion-ios-mic-outline:before, .ion-ios-minus:before, .ion-ios-minus-empty:before, .ion-ios-minus-outline:before, .ion-ios-monitor:before, .ion-ios-monitor-outline:before, .ion-ios-moon:before, .ion-ios-moon-outline:before, .ion-ios-more:before, .ion-ios-more-outline:before, .ion-ios-musical-note:before, .ion-ios-musical-notes:before, .ion-ios-navigate:before, .ion-ios-navigate-outline:before, .ion-ios-nutrition:before, .ion-ios-nutrition-outline:before, .ion-ios-paper:before, .ion-ios-paper-outline:before, .ion-ios-paperplane:before, .ion-ios-paperplane-outline:before, .ion-ios-partlysunny:before, .ion-ios-partlysunny-outline:before, .ion-ios-pause:before, .ion-ios-pause-outline:before, .ion-ios-paw:before, .ion-ios-paw-outline:before, .ion-ios-people:before, .ion-ios-people-outline:before, .ion-ios-person:before, .ion-ios-person-outline:before, .ion-ios-personadd:before, .ion-ios-personadd-outline:before, .ion-ios-photos:before, .ion-ios-photos-outline:before, .ion-ios-pie:before, .ion-ios-pie-outline:before, .ion-ios-pint:before, .ion-ios-pint-outline:before, .ion-ios-play:before, .ion-ios-play-outline:before, .ion-ios-plus:before, .ion-ios-plus-empty:before, .ion-ios-plus-outline:before, .ion-ios-pricetag:before, .ion-ios-pricetag-outline:before, .ion-ios-pricetags:before, .ion-ios-pricetags-outline:before, .ion-ios-printer:before, .ion-ios-printer-outline:before, .ion-ios-pulse:before, .ion-ios-pulse-strong:before, .ion-ios-rainy:before, .ion-ios-rainy-outline:before, .ion-ios-recording:before, .ion-ios-recording-outline:before, .ion-ios-redo:before, .ion-ios-redo-outline:before, .ion-ios-refresh:before, .ion-ios-refresh-empty:before, .ion-ios-refresh-outline:before, .ion-ios-reload:before, .ion-ios-reverse-camera:before, .ion-ios-reverse-camera-outline:before, .ion-ios-rewind:before, .ion-ios-rewind-outline:before, .ion-ios-rose:before, .ion-ios-rose-outline:before, .ion-ios-search:before, .ion-ios-search-strong:before, .ion-ios-settings:before, .ion-ios-settings-strong:before, .ion-ios-shuffle:before, .ion-ios-shuffle-strong:before, .ion-ios-skipbackward:before, .ion-ios-skipbackward-outline:before, .ion-ios-skipforward:before, .ion-ios-skipforward-outline:before, .ion-ios-snowy:before, .ion-ios-speedometer:before, .ion-ios-speedometer-outline:before, .ion-ios-star:before, .ion-ios-star-half:before, .ion-ios-star-outline:before, .ion-ios-stopwatch:before, .ion-ios-stopwatch-outline:before, .ion-ios-sunny:before, .ion-ios-sunny-outline:before, .ion-ios-telephone:before, .ion-ios-telephone-outline:before, .ion-ios-tennisball:before, .ion-ios-tennisball-outline:before, .ion-ios-thunderstorm:before, .ion-ios-thunderstorm-outline:before, .ion-ios-time:before, .ion-ios-time-outline:before, .ion-ios-timer:before, .ion-ios-timer-outline:before, .ion-ios-toggle:before, .ion-ios-toggle-outline:before, .ion-ios-trash:before, .ion-ios-trash-outline:before, .ion-ios-undo:before, .ion-ios-undo-outline:before, .ion-ios-unlocked:before, .ion-ios-unlocked-outline:before, .ion-ios-upload:before, .ion-ios-upload-outline:before, .ion-ios-videocam:before, .ion-ios-videocam-outline:before, .ion-ios-volume-high:before, .ion-ios-volume-low:before, .ion-ios-wineglass:before, .ion-ios-wineglass-outline:before, .ion-ios-world:before, .ion-ios-world-outline:before, .ion-ipad:before, .ion-iphone:before, .ion-ipod:before, .ion-jet:before, .ion-key:before, .ion-knife:before, .ion-laptop:before, .ion-leaf:before, .ion-levels:before, .ion-lightbulb:before, .ion-link:before, .ion-load-a:before, .ion-load-b:before, .ion-load-c:before, .ion-load-d:before, .ion-location:before, .ion-lock-combination:before, .ion-locked:before, .ion-log-in:before, .ion-log-out:before, .ion-loop:before, .ion-magnet:before, .ion-male:before, .ion-man:before, .ion-map:before, .ion-medkit:before, .ion-merge:before, .ion-mic-a:before, .ion-mic-b:before, .ion-mic-c:before, .ion-minus:before, .ion-minus-circled:before, .ion-minus-round:before, .ion-model-s:before, .ion-monitor:before, .ion-more:before, .ion-mouse:before, .ion-music-note:before, .ion-navicon:before, .ion-navicon-round:before, .ion-navigate:before, .ion-network:before, .ion-no-smoking:before, .ion-nuclear:before, .ion-outlet:before, .ion-paintbrush:before, .ion-paintbucket:before, .ion-paper-airplane:before, .ion-paperclip:before, .ion-pause:before, .ion-person:before, .ion-person-add:before, .ion-person-stalker:before, .ion-pie-graph:before, .ion-pin:before, .ion-pinpoint:before, .ion-pizza:before, .ion-plane:before, .ion-planet:before, .ion-play:before, .ion-playstation:before, .ion-plus:before, .ion-plus-circled:before, .ion-plus-round:before, .ion-podium:before, .ion-pound:before, .ion-power:before, .ion-pricetag:before, .ion-pricetags:before, .ion-printer:before, .ion-pull-request:before, .ion-qr-scanner:before, .ion-quote:before, .ion-radio-waves:before, .ion-record:before, .ion-refresh:before, .ion-reply:before, .ion-reply-all:before, .ion-ribbon-a:before, .ion-ribbon-b:before, .ion-sad:before, .ion-sad-outline:before, .ion-scissors:before, .ion-search:before, .ion-settings:before, .ion-share:before, .ion-shuffle:before, .ion-skip-backward:before, .ion-skip-forward:before, .ion-social-android:before, .ion-social-android-outline:before, .ion-social-angular:before, .ion-social-angular-outline:before, .ion-social-apple:before, .ion-social-apple-outline:before, .ion-social-bitcoin:before, .ion-social-bitcoin-outline:before, .ion-social-buffer:before, .ion-social-buffer-outline:before, .ion-social-chrome:before, .ion-social-chrome-outline:before, .ion-social-codepen:before, .ion-social-codepen-outline:before, .ion-social-css3:before, .ion-social-css3-outline:before, .ion-social-designernews:before, .ion-social-designernews-outline:before, .ion-social-dribbble:before, .ion-social-dribbble-outline:before, .ion-social-dropbox:before, .ion-social-dropbox-outline:before, .ion-social-euro:before, .ion-social-euro-outline:before, .ion-social-facebook:before, .ion-social-facebook-outline:before, .ion-social-foursquare:before, .ion-social-foursquare-outline:before, .ion-social-freebsd-devil:before, .ion-social-github:before, .ion-social-github-outline:before, .ion-social-google:before, .ion-social-google-outline:before, .ion-social-googleplus:before, .ion-social-googleplus-outline:before, .ion-social-hackernews:before, .ion-social-hackernews-outline:before, .ion-social-html5:before, .ion-social-html5-outline:before, .ion-social-instagram:before, .ion-social-instagram-outline:before, .ion-social-javascript:before, .ion-social-javascript-outline:before, .ion-social-linkedin:before, .ion-social-linkedin-outline:before, .ion-social-markdown:before, .ion-social-nodejs:before, .ion-social-octocat:before, .ion-social-pinterest:before, .ion-social-pinterest-outline:before, .ion-social-python:before, .ion-social-reddit:before, .ion-social-reddit-outline:before, .ion-social-rss:before, .ion-social-rss-outline:before, .ion-social-sass:before, .ion-social-skype:before, .ion-social-skype-outline:before, .ion-social-snapchat:before, .ion-social-snapchat-outline:before, .ion-social-tumblr:before, .ion-social-tumblr-outline:before, .ion-social-tux:before, .ion-social-twitch:before, .ion-social-twitch-outline:before, .ion-social-twitter:before, .ion-social-twitter-outline:before, .ion-social-usd:before, .ion-social-usd-outline:before, .ion-social-vimeo:before, .ion-social-vimeo-outline:before, .ion-social-whatsapp:before, .ion-social-whatsapp-outline:before, .ion-social-windows:before, .ion-social-windows-outline:before, .ion-social-wordpress:before, .ion-social-wordpress-outline:before, .ion-social-yahoo:before, .ion-social-yahoo-outline:before, .ion-social-yen:before, .ion-social-yen-outline:before, .ion-social-youtube:before, .ion-social-youtube-outline:before, .ion-soup-can:before, .ion-soup-can-outline:before, .ion-speakerphone:before, .ion-speedometer:before, .ion-spoon:before, .ion-star:before, .ion-stats-bars:before, .ion-steam:before, .ion-stop:before, .ion-thermometer:before, .ion-thumbsdown:before, .ion-thumbsup:before, .ion-toggle:before, .ion-toggle-filled:before, .ion-transgender:before, .ion-trash-a:before, .ion-trash-b:before, .ion-trophy:before, .ion-tshirt:before, .ion-tshirt-outline:before, .ion-umbrella:before, .ion-university:before, .ion-unlocked:before, .ion-upload:before, .ion-usb:before, .ion-videocamera:before, .ion-volume-high:before, .ion-volume-low:before, .ion-volume-medium:before, .ion-volume-mute:before, .ion-wand:before, .ion-waterdrop:before, .ion-wifi:before, .ion-wineglass:before, .ion-woman:before, .ion-wrench:before, .ion-xbox:before { display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .ion-alert:before { content: "\f101"; } @@ -27,27 +19,53 @@ .ion-android-add:before { content: "\f2c7"; } -.ion-android-add-contact:before { content: "\f2c6"; } +.ion-android-add-circle:before { content: "\f359"; } + +.ion-android-alarm-clock:before { content: "\f35a"; } + +.ion-android-alert:before { content: "\f35b"; } -.ion-android-alarm:before { content: "\f2c8"; } +.ion-android-apps:before { content: "\f35c"; } .ion-android-archive:before { content: "\f2c9"; } .ion-android-arrow-back:before { content: "\f2ca"; } -.ion-android-arrow-down-left:before { content: "\f2cb"; } +.ion-android-arrow-down:before { content: "\f35d"; } + +.ion-android-arrow-dropdown:before { content: "\f35f"; } + +.ion-android-arrow-dropdown-circle:before { content: "\f35e"; } + +.ion-android-arrow-dropleft:before { content: "\f361"; } + +.ion-android-arrow-dropleft-circle:before { content: "\f360"; } + +.ion-android-arrow-dropright:before { content: "\f363"; } + +.ion-android-arrow-dropright-circle:before { content: "\f362"; } + +.ion-android-arrow-dropup:before { content: "\f365"; } -.ion-android-arrow-down-right:before { content: "\f2cc"; } +.ion-android-arrow-dropup-circle:before { content: "\f364"; } .ion-android-arrow-forward:before { content: "\f30f"; } -.ion-android-arrow-up-left:before { content: "\f2cd"; } +.ion-android-arrow-up:before { content: "\f366"; } -.ion-android-arrow-up-right:before { content: "\f2ce"; } +.ion-android-attach:before { content: "\f367"; } -.ion-android-battery:before { content: "\f2cf"; } +.ion-android-bar:before { content: "\f368"; } -.ion-android-book:before { content: "\f2d0"; } +.ion-android-bicycle:before { content: "\f369"; } + +.ion-android-boat:before { content: "\f36a"; } + +.ion-android-bookmark:before { content: "\f36b"; } + +.ion-android-bulb:before { content: "\f36c"; } + +.ion-android-bus:before { content: "\f36d"; } .ion-android-calendar:before { content: "\f2d1"; } @@ -55,74 +73,156 @@ .ion-android-camera:before { content: "\f2d3"; } +.ion-android-cancel:before { content: "\f36e"; } + +.ion-android-car:before { content: "\f36f"; } + +.ion-android-cart:before { content: "\f370"; } + .ion-android-chat:before { content: "\f2d4"; } -.ion-android-checkmark:before { content: "\f2d5"; } +.ion-android-checkbox:before { content: "\f374"; } + +.ion-android-checkbox-blank:before { content: "\f371"; } + +.ion-android-checkbox-outline:before { content: "\f373"; } -.ion-android-clock:before { content: "\f2d6"; } +.ion-android-checkbox-outline-blank:before { content: "\f372"; } + +.ion-android-checkmark-circle:before { content: "\f375"; } + +.ion-android-clipboard:before { content: "\f376"; } .ion-android-close:before { content: "\f2d7"; } +.ion-android-cloud:before { content: "\f37a"; } + +.ion-android-cloud-circle:before { content: "\f377"; } + +.ion-android-cloud-done:before { content: "\f378"; } + +.ion-android-cloud-outline:before { content: "\f379"; } + +.ion-android-color-palette:before { content: "\f37b"; } + +.ion-android-compass:before { content: "\f37c"; } + .ion-android-contact:before { content: "\f2d8"; } .ion-android-contacts:before { content: "\f2d9"; } -.ion-android-data:before { content: "\f2da"; } +.ion-android-contract:before { content: "\f37d"; } + +.ion-android-create:before { content: "\f37e"; } + +.ion-android-delete:before { content: "\f37f"; } -.ion-android-developer:before { content: "\f2db"; } +.ion-android-desktop:before { content: "\f380"; } -.ion-android-display:before { content: "\f2dc"; } +.ion-android-document:before { content: "\f381"; } + +.ion-android-done:before { content: "\f383"; } + +.ion-android-done-all:before { content: "\f382"; } .ion-android-download:before { content: "\f2dd"; } -.ion-android-drawer:before { content: "\f310"; } +.ion-android-drafts:before { content: "\f384"; } + +.ion-android-exit:before { content: "\f385"; } + +.ion-android-expand:before { content: "\f386"; } + +.ion-android-favorite:before { content: "\f388"; } -.ion-android-dropdown:before { content: "\f2de"; } +.ion-android-favorite-outline:before { content: "\f387"; } -.ion-android-earth:before { content: "\f2df"; } +.ion-android-film:before { content: "\f389"; } .ion-android-folder:before { content: "\f2e0"; } -.ion-android-forums:before { content: "\f2e1"; } +.ion-android-folder-open:before { content: "\f38a"; } -.ion-android-friends:before { content: "\f2e2"; } +.ion-android-funnel:before { content: "\f38b"; } + +.ion-android-globe:before { content: "\f38c"; } .ion-android-hand:before { content: "\f2e3"; } -.ion-android-image:before { content: "\f2e4"; } +.ion-android-hangout:before { content: "\f38d"; } -.ion-android-inbox:before { content: "\f2e5"; } +.ion-android-happy:before { content: "\f38e"; } -.ion-android-information:before { content: "\f2e6"; } +.ion-android-home:before { content: "\f38f"; } + +.ion-android-image:before { content: "\f2e4"; } -.ion-android-keypad:before { content: "\f2e7"; } +.ion-android-laptop:before { content: "\f390"; } -.ion-android-lightbulb:before { content: "\f2e8"; } +.ion-android-list:before { content: "\f391"; } .ion-android-locate:before { content: "\f2e9"; } -.ion-android-location:before { content: "\f2ea"; } +.ion-android-lock:before { content: "\f392"; } .ion-android-mail:before { content: "\f2eb"; } +.ion-android-map:before { content: "\f393"; } + +.ion-android-menu:before { content: "\f394"; } + .ion-android-microphone:before { content: "\f2ec"; } -.ion-android-mixer:before { content: "\f2ed"; } +.ion-android-microphone-off:before { content: "\f395"; } + +.ion-android-more-horizontal:before { content: "\f396"; } + +.ion-android-more-vertical:before { content: "\f397"; } + +.ion-android-navigate:before { content: "\f398"; } + +.ion-android-notifications:before { content: "\f39b"; } + +.ion-android-notifications-none:before { content: "\f399"; } + +.ion-android-notifications-off:before { content: "\f39a"; } + +.ion-android-open:before { content: "\f39c"; } + +.ion-android-options:before { content: "\f39d"; } -.ion-android-more:before { content: "\f2ee"; } +.ion-android-people:before { content: "\f39e"; } -.ion-android-note:before { content: "\f2ef"; } +.ion-android-person:before { content: "\f3a0"; } + +.ion-android-person-add:before { content: "\f39f"; } + +.ion-android-phone-landscape:before { content: "\f3a1"; } + +.ion-android-phone-portrait:before { content: "\f3a2"; } + +.ion-android-pin:before { content: "\f3a3"; } + +.ion-android-plane:before { content: "\f3a4"; } .ion-android-playstore:before { content: "\f2f0"; } -.ion-android-printer:before { content: "\f2f1"; } +.ion-android-print:before { content: "\f3a5"; } -.ion-android-promotion:before { content: "\f2f2"; } +.ion-android-radio-button-off:before { content: "\f3a6"; } -.ion-android-reminder:before { content: "\f2f3"; } +.ion-android-radio-button-on:before { content: "\f3a7"; } + +.ion-android-refresh:before { content: "\f3a8"; } .ion-android-remove:before { content: "\f2f4"; } +.ion-android-remove-circle:before { content: "\f3a9"; } + +.ion-android-restaurant:before { content: "\f3aa"; } + +.ion-android-sad:before { content: "\f3ab"; } + .ion-android-search:before { content: "\f2f5"; } .ion-android-send:before { content: "\f2f6"; } @@ -131,33 +231,45 @@ .ion-android-share:before { content: "\f2f8"; } -.ion-android-social:before { content: "\f2fa"; } +.ion-android-share-alt:before { content: "\f3ac"; } -.ion-android-social-user:before { content: "\f2f9"; } - -.ion-android-sort:before { content: "\f2fb"; } +.ion-android-star:before { content: "\f2fc"; } -.ion-android-stair-drawer:before { content: "\f311"; } +.ion-android-star-half:before { content: "\f3ad"; } -.ion-android-star:before { content: "\f2fc"; } +.ion-android-star-outline:before { content: "\f3ae"; } .ion-android-stopwatch:before { content: "\f2fd"; } -.ion-android-storage:before { content: "\f2fe"; } +.ion-android-subway:before { content: "\f3af"; } + +.ion-android-sunny:before { content: "\f3b0"; } + +.ion-android-sync:before { content: "\f3b1"; } + +.ion-android-textsms:before { content: "\f3b2"; } + +.ion-android-time:before { content: "\f3b3"; } + +.ion-android-train:before { content: "\f3b4"; } + +.ion-android-unlock:before { content: "\f3b5"; } -.ion-android-system-back:before { content: "\f2ff"; } +.ion-android-upload:before { content: "\f3b6"; } -.ion-android-system-home:before { content: "\f300"; } +.ion-android-volume-down:before { content: "\f3b7"; } -.ion-android-system-windows:before { content: "\f301"; } +.ion-android-volume-mute:before { content: "\f3b8"; } -.ion-android-timer:before { content: "\f302"; } +.ion-android-volume-off:before { content: "\f3b9"; } -.ion-android-trash:before { content: "\f303"; } +.ion-android-volume-up:before { content: "\f3ba"; } -.ion-android-user-menu:before { content: "\f312"; } +.ion-android-walk:before { content: "\f3bb"; } -.ion-android-volume:before { content: "\f304"; } +.ion-android-warning:before { content: "\f3bc"; } + +.ion-android-watch:before { content: "\f3bd"; } .ion-android-wifi:before { content: "\f305"; } @@ -215,6 +327,10 @@ .ion-at:before { content: "\f10f"; } +.ion-backspace:before { content: "\f3bf"; } + +.ion-backspace-outline:before { content: "\f3be"; } + .ion-bag:before { content: "\f110"; } .ion-battery-charging:before { content: "\f111"; } @@ -237,6 +353,8 @@ .ion-bookmark:before { content: "\f26b"; } +.ion-bowtie:before { content: "\f3c0"; } + .ion-briefcase:before { content: "\f26c"; } .ion-bug:before { content: "\f2be"; } @@ -307,6 +425,8 @@ .ion-contrast:before { content: "\f275"; } +.ion-crop:before { content: "\f3c1"; } + .ion-cube:before { content: "\f318"; } .ion-disc:before { content: "\f12d"; } @@ -319,6 +439,8 @@ .ion-earth:before { content: "\f276"; } +.ion-easel:before { content: "\f3c2"; } + .ion-edit:before { content: "\f2bf"; } .ion-egg:before { content: "\f277"; } @@ -327,6 +449,12 @@ .ion-email:before { content: "\f132"; } +.ion-email-unread:before { content: "\f3c3"; } + +.ion-erlenmeyer-flask:before { content: "\f3c5"; } + +.ion-erlenmeyer-flask-bubbles:before { content: "\f3c4"; } + .ion-eye:before { content: "\f133"; } .ion-eye-disabled:before { content: "\f306"; } @@ -347,8 +475,6 @@ .ion-flash-off:before { content: "\f136"; } -.ion-flask:before { content: "\f138"; } - .ion-folder:before { content: "\f139"; } .ion-fork:before { content: "\f27a"; } @@ -359,10 +485,6 @@ .ion-funnel:before { content: "\f31b"; } -.ion-game-controller-a:before { content: "\f13b"; } - -.ion-game-controller-b:before { content: "\f13c"; } - .ion-gear-a:before { content: "\f13d"; } .ion-gear-b:before { content: "\f13e"; } @@ -373,6 +495,8 @@ .ion-happy:before { content: "\f31c"; } +.ion-happy-outline:before { content: "\f3c6"; } + .ion-headphone:before { content: "\f140"; } .ion-heart:before { content: "\f141"; } @@ -389,10 +513,6 @@ .ion-icecream:before { content: "\f27d"; } -.ion-icon-social-google-plus:before { content: "\f146"; } - -.ion-icon-social-google-plus-outline:before { content: "\f145"; } - .ion-image:before { content: "\f147"; } .ion-images:before { content: "\f148"; } @@ -403,479 +523,543 @@ .ion-ionic:before { content: "\f14b"; } -.ion-ios7-alarm:before { content: "\f14d"; } +.ion-ios-alarm:before { content: "\f3c8"; } + +.ion-ios-alarm-outline:before { content: "\f3c7"; } + +.ion-ios-albums:before { content: "\f3ca"; } + +.ion-ios-albums-outline:before { content: "\f3c9"; } + +.ion-ios-americanfootball:before { content: "\f3cc"; } + +.ion-ios-americanfootball-outline:before { content: "\f3cb"; } + +.ion-ios-analytics:before { content: "\f3ce"; } + +.ion-ios-analytics-outline:before { content: "\f3cd"; } + +.ion-ios-arrow-back:before { content: "\f3cf"; } + +.ion-ios-arrow-down:before { content: "\f3d0"; } + +.ion-ios-arrow-forward:before { content: "\f3d1"; } + +.ion-ios-arrow-left:before { content: "\f3d2"; } + +.ion-ios-arrow-right:before { content: "\f3d3"; } + +.ion-ios-arrow-thin-down:before { content: "\f3d4"; } + +.ion-ios-arrow-thin-left:before { content: "\f3d5"; } + +.ion-ios-arrow-thin-right:before { content: "\f3d6"; } + +.ion-ios-arrow-thin-up:before { content: "\f3d7"; } + +.ion-ios-arrow-up:before { content: "\f3d8"; } + +.ion-ios-at:before { content: "\f3da"; } + +.ion-ios-at-outline:before { content: "\f3d9"; } + +.ion-ios-barcode:before { content: "\f3dc"; } + +.ion-ios-barcode-outline:before { content: "\f3db"; } + +.ion-ios-baseball:before { content: "\f3de"; } + +.ion-ios-baseball-outline:before { content: "\f3dd"; } + +.ion-ios-basketball:before { content: "\f3e0"; } + +.ion-ios-basketball-outline:before { content: "\f3df"; } + +.ion-ios-bell:before { content: "\f3e2"; } + +.ion-ios-bell-outline:before { content: "\f3e1"; } + +.ion-ios-body:before { content: "\f3e4"; } + +.ion-ios-body-outline:before { content: "\f3e3"; } + +.ion-ios-bolt:before { content: "\f3e6"; } + +.ion-ios-bolt-outline:before { content: "\f3e5"; } -.ion-ios7-alarm-outline:before { content: "\f14c"; } +.ion-ios-book:before { content: "\f3e8"; } -.ion-ios7-albums:before { content: "\f14f"; } +.ion-ios-book-outline:before { content: "\f3e7"; } -.ion-ios7-albums-outline:before { content: "\f14e"; } +.ion-ios-bookmarks:before { content: "\f3ea"; } -.ion-ios7-americanfootball:before { content: "\f31f"; } +.ion-ios-bookmarks-outline:before { content: "\f3e9"; } -.ion-ios7-americanfootball-outline:before { content: "\f31e"; } +.ion-ios-box:before { content: "\f3ec"; } -.ion-ios7-analytics:before { content: "\f321"; } +.ion-ios-box-outline:before { content: "\f3eb"; } -.ion-ios7-analytics-outline:before { content: "\f320"; } +.ion-ios-briefcase:before { content: "\f3ee"; } -.ion-ios7-arrow-back:before { content: "\f150"; } +.ion-ios-briefcase-outline:before { content: "\f3ed"; } -.ion-ios7-arrow-down:before { content: "\f151"; } +.ion-ios-browsers:before { content: "\f3f0"; } -.ion-ios7-arrow-forward:before { content: "\f152"; } +.ion-ios-browsers-outline:before { content: "\f3ef"; } -.ion-ios7-arrow-left:before { content: "\f153"; } +.ion-ios-calculator:before { content: "\f3f2"; } -.ion-ios7-arrow-right:before { content: "\f154"; } +.ion-ios-calculator-outline:before { content: "\f3f1"; } -.ion-ios7-arrow-thin-down:before { content: "\f27e"; } +.ion-ios-calendar:before { content: "\f3f4"; } -.ion-ios7-arrow-thin-left:before { content: "\f27f"; } +.ion-ios-calendar-outline:before { content: "\f3f3"; } -.ion-ios7-arrow-thin-right:before { content: "\f280"; } +.ion-ios-camera:before { content: "\f3f6"; } -.ion-ios7-arrow-thin-up:before { content: "\f281"; } +.ion-ios-camera-outline:before { content: "\f3f5"; } -.ion-ios7-arrow-up:before { content: "\f155"; } +.ion-ios-cart:before { content: "\f3f8"; } -.ion-ios7-at:before { content: "\f157"; } +.ion-ios-cart-outline:before { content: "\f3f7"; } -.ion-ios7-at-outline:before { content: "\f156"; } +.ion-ios-chatboxes:before { content: "\f3fa"; } -.ion-ios7-barcode:before { content: "\f323"; } +.ion-ios-chatboxes-outline:before { content: "\f3f9"; } -.ion-ios7-barcode-outline:before { content: "\f322"; } +.ion-ios-chatbubble:before { content: "\f3fc"; } -.ion-ios7-baseball:before { content: "\f325"; } +.ion-ios-chatbubble-outline:before { content: "\f3fb"; } -.ion-ios7-baseball-outline:before { content: "\f324"; } +.ion-ios-checkmark:before { content: "\f3ff"; } -.ion-ios7-basketball:before { content: "\f327"; } +.ion-ios-checkmark-empty:before { content: "\f3fd"; } -.ion-ios7-basketball-outline:before { content: "\f326"; } +.ion-ios-checkmark-outline:before { content: "\f3fe"; } -.ion-ios7-bell:before { content: "\f159"; } +.ion-ios-circle-filled:before { content: "\f400"; } -.ion-ios7-bell-outline:before { content: "\f158"; } +.ion-ios-circle-outline:before { content: "\f401"; } -.ion-ios7-bolt:before { content: "\f15b"; } +.ion-ios-clock:before { content: "\f403"; } -.ion-ios7-bolt-outline:before { content: "\f15a"; } +.ion-ios-clock-outline:before { content: "\f402"; } -.ion-ios7-bookmarks:before { content: "\f15d"; } +.ion-ios-close:before { content: "\f406"; } -.ion-ios7-bookmarks-outline:before { content: "\f15c"; } +.ion-ios-close-empty:before { content: "\f404"; } -.ion-ios7-box:before { content: "\f15f"; } +.ion-ios-close-outline:before { content: "\f405"; } -.ion-ios7-box-outline:before { content: "\f15e"; } +.ion-ios-cloud:before { content: "\f40c"; } -.ion-ios7-briefcase:before { content: "\f283"; } +.ion-ios-cloud-download:before { content: "\f408"; } -.ion-ios7-briefcase-outline:before { content: "\f282"; } +.ion-ios-cloud-download-outline:before { content: "\f407"; } -.ion-ios7-browsers:before { content: "\f161"; } +.ion-ios-cloud-outline:before { content: "\f409"; } -.ion-ios7-browsers-outline:before { content: "\f160"; } +.ion-ios-cloud-upload:before { content: "\f40b"; } -.ion-ios7-calculator:before { content: "\f285"; } +.ion-ios-cloud-upload-outline:before { content: "\f40a"; } -.ion-ios7-calculator-outline:before { content: "\f284"; } +.ion-ios-cloudy:before { content: "\f410"; } -.ion-ios7-calendar:before { content: "\f163"; } +.ion-ios-cloudy-night:before { content: "\f40e"; } -.ion-ios7-calendar-outline:before { content: "\f162"; } +.ion-ios-cloudy-night-outline:before { content: "\f40d"; } -.ion-ios7-camera:before { content: "\f165"; } +.ion-ios-cloudy-outline:before { content: "\f40f"; } -.ion-ios7-camera-outline:before { content: "\f164"; } +.ion-ios-cog:before { content: "\f412"; } -.ion-ios7-cart:before { content: "\f167"; } +.ion-ios-cog-outline:before { content: "\f411"; } -.ion-ios7-cart-outline:before { content: "\f166"; } +.ion-ios-color-filter:before { content: "\f414"; } -.ion-ios7-chatboxes:before { content: "\f169"; } +.ion-ios-color-filter-outline:before { content: "\f413"; } -.ion-ios7-chatboxes-outline:before { content: "\f168"; } +.ion-ios-color-wand:before { content: "\f416"; } -.ion-ios7-chatbubble:before { content: "\f16b"; } +.ion-ios-color-wand-outline:before { content: "\f415"; } -.ion-ios7-chatbubble-outline:before { content: "\f16a"; } +.ion-ios-compose:before { content: "\f418"; } -.ion-ios7-checkmark:before { content: "\f16e"; } +.ion-ios-compose-outline:before { content: "\f417"; } -.ion-ios7-checkmark-empty:before { content: "\f16c"; } +.ion-ios-contact:before { content: "\f41a"; } -.ion-ios7-checkmark-outline:before { content: "\f16d"; } +.ion-ios-contact-outline:before { content: "\f419"; } -.ion-ios7-circle-filled:before { content: "\f16f"; } +.ion-ios-copy:before { content: "\f41c"; } -.ion-ios7-circle-outline:before { content: "\f170"; } +.ion-ios-copy-outline:before { content: "\f41b"; } -.ion-ios7-clock:before { content: "\f172"; } +.ion-ios-crop:before { content: "\f41e"; } -.ion-ios7-clock-outline:before { content: "\f171"; } +.ion-ios-crop-strong:before { content: "\f41d"; } -.ion-ios7-close:before { content: "\f2bc"; } +.ion-ios-download:before { content: "\f420"; } -.ion-ios7-close-empty:before { content: "\f2bd"; } +.ion-ios-download-outline:before { content: "\f41f"; } -.ion-ios7-close-outline:before { content: "\f2bb"; } +.ion-ios-drag:before { content: "\f421"; } -.ion-ios7-cloud:before { content: "\f178"; } +.ion-ios-email:before { content: "\f423"; } -.ion-ios7-cloud-download:before { content: "\f174"; } +.ion-ios-email-outline:before { content: "\f422"; } -.ion-ios7-cloud-download-outline:before { content: "\f173"; } +.ion-ios-eye:before { content: "\f425"; } -.ion-ios7-cloud-outline:before { content: "\f175"; } +.ion-ios-eye-outline:before { content: "\f424"; } -.ion-ios7-cloud-upload:before { content: "\f177"; } +.ion-ios-fastforward:before { content: "\f427"; } -.ion-ios7-cloud-upload-outline:before { content: "\f176"; } +.ion-ios-fastforward-outline:before { content: "\f426"; } -.ion-ios7-cloudy:before { content: "\f17a"; } +.ion-ios-filing:before { content: "\f429"; } -.ion-ios7-cloudy-night:before { content: "\f308"; } +.ion-ios-filing-outline:before { content: "\f428"; } -.ion-ios7-cloudy-night-outline:before { content: "\f307"; } +.ion-ios-film:before { content: "\f42b"; } -.ion-ios7-cloudy-outline:before { content: "\f179"; } +.ion-ios-film-outline:before { content: "\f42a"; } -.ion-ios7-cog:before { content: "\f17c"; } +.ion-ios-flag:before { content: "\f42d"; } -.ion-ios7-cog-outline:before { content: "\f17b"; } +.ion-ios-flag-outline:before { content: "\f42c"; } -.ion-ios7-compose:before { content: "\f17e"; } +.ion-ios-flame:before { content: "\f42f"; } -.ion-ios7-compose-outline:before { content: "\f17d"; } +.ion-ios-flame-outline:before { content: "\f42e"; } -.ion-ios7-contact:before { content: "\f180"; } +.ion-ios-flask:before { content: "\f431"; } -.ion-ios7-contact-outline:before { content: "\f17f"; } +.ion-ios-flask-outline:before { content: "\f430"; } -.ion-ios7-copy:before { content: "\f182"; } +.ion-ios-flower:before { content: "\f433"; } -.ion-ios7-copy-outline:before { content: "\f181"; } +.ion-ios-flower-outline:before { content: "\f432"; } -.ion-ios7-download:before { content: "\f184"; } +.ion-ios-folder:before { content: "\f435"; } -.ion-ios7-download-outline:before { content: "\f183"; } +.ion-ios-folder-outline:before { content: "\f434"; } -.ion-ios7-drag:before { content: "\f185"; } +.ion-ios-football:before { content: "\f437"; } -.ion-ios7-email:before { content: "\f187"; } +.ion-ios-football-outline:before { content: "\f436"; } -.ion-ios7-email-outline:before { content: "\f186"; } +.ion-ios-game-controller-a:before { content: "\f439"; } -.ion-ios7-expand:before { content: "\f30d"; } +.ion-ios-game-controller-a-outline:before { content: "\f438"; } -.ion-ios7-eye:before { content: "\f189"; } +.ion-ios-game-controller-b:before { content: "\f43b"; } -.ion-ios7-eye-outline:before { content: "\f188"; } +.ion-ios-game-controller-b-outline:before { content: "\f43a"; } -.ion-ios7-fastforward:before { content: "\f18b"; } +.ion-ios-gear:before { content: "\f43d"; } -.ion-ios7-fastforward-outline:before { content: "\f18a"; } +.ion-ios-gear-outline:before { content: "\f43c"; } -.ion-ios7-filing:before { content: "\f18d"; } +.ion-ios-glasses:before { content: "\f43f"; } -.ion-ios7-filing-outline:before { content: "\f18c"; } +.ion-ios-glasses-outline:before { content: "\f43e"; } -.ion-ios7-film:before { content: "\f18f"; } +.ion-ios-grid-view:before { content: "\f441"; } -.ion-ios7-film-outline:before { content: "\f18e"; } +.ion-ios-grid-view-outline:before { content: "\f440"; } -.ion-ios7-flag:before { content: "\f191"; } +.ion-ios-heart:before { content: "\f443"; } -.ion-ios7-flag-outline:before { content: "\f190"; } +.ion-ios-heart-outline:before { content: "\f442"; } -.ion-ios7-folder:before { content: "\f193"; } +.ion-ios-help:before { content: "\f446"; } -.ion-ios7-folder-outline:before { content: "\f192"; } +.ion-ios-help-empty:before { content: "\f444"; } -.ion-ios7-football:before { content: "\f329"; } +.ion-ios-help-outline:before { content: "\f445"; } -.ion-ios7-football-outline:before { content: "\f328"; } +.ion-ios-home:before { content: "\f448"; } -.ion-ios7-gear:before { content: "\f195"; } +.ion-ios-home-outline:before { content: "\f447"; } -.ion-ios7-gear-outline:before { content: "\f194"; } +.ion-ios-infinite:before { content: "\f44a"; } -.ion-ios7-glasses:before { content: "\f197"; } +.ion-ios-infinite-outline:before { content: "\f449"; } -.ion-ios7-glasses-outline:before { content: "\f196"; } +.ion-ios-information:before { content: "\f44d"; } -.ion-ios7-heart:before { content: "\f199"; } +.ion-ios-information-empty:before { content: "\f44b"; } -.ion-ios7-heart-outline:before { content: "\f198"; } +.ion-ios-information-outline:before { content: "\f44c"; } -.ion-ios7-help:before { content: "\f19c"; } +.ion-ios-ionic-outline:before { content: "\f44e"; } -.ion-ios7-help-empty:before { content: "\f19a"; } +.ion-ios-keypad:before { content: "\f450"; } -.ion-ios7-help-outline:before { content: "\f19b"; } +.ion-ios-keypad-outline:before { content: "\f44f"; } -.ion-ios7-home:before { content: "\f32b"; } +.ion-ios-lightbulb:before { content: "\f452"; } -.ion-ios7-home-outline:before { content: "\f32a"; } +.ion-ios-lightbulb-outline:before { content: "\f451"; } -.ion-ios7-infinite:before { content: "\f19e"; } +.ion-ios-list:before { content: "\f454"; } -.ion-ios7-infinite-outline:before { content: "\f19d"; } +.ion-ios-list-outline:before { content: "\f453"; } -.ion-ios7-information:before { content: "\f1a1"; } +.ion-ios-location:before { content: "\f456"; } -.ion-ios7-information-empty:before { content: "\f19f"; } +.ion-ios-location-outline:before { content: "\f455"; } -.ion-ios7-information-outline:before { content: "\f1a0"; } +.ion-ios-locked:before { content: "\f458"; } -.ion-ios7-ionic-outline:before { content: "\f1a2"; } +.ion-ios-locked-outline:before { content: "\f457"; } -.ion-ios7-keypad:before { content: "\f1a4"; } +.ion-ios-loop:before { content: "\f45a"; } -.ion-ios7-keypad-outline:before { content: "\f1a3"; } +.ion-ios-loop-strong:before { content: "\f459"; } -.ion-ios7-lightbulb:before { content: "\f287"; } +.ion-ios-medical:before { content: "\f45c"; } -.ion-ios7-lightbulb-outline:before { content: "\f286"; } +.ion-ios-medical-outline:before { content: "\f45b"; } -.ion-ios7-location:before { content: "\f1a6"; } +.ion-ios-medkit:before { content: "\f45e"; } -.ion-ios7-location-outline:before { content: "\f1a5"; } +.ion-ios-medkit-outline:before { content: "\f45d"; } -.ion-ios7-locked:before { content: "\f1a8"; } +.ion-ios-mic:before { content: "\f461"; } -.ion-ios7-locked-outline:before { content: "\f1a7"; } +.ion-ios-mic-off:before { content: "\f45f"; } -.ion-ios7-loop:before { content: "\f32d"; } +.ion-ios-mic-outline:before { content: "\f460"; } -.ion-ios7-loop-strong:before { content: "\f32c"; } +.ion-ios-minus:before { content: "\f464"; } -.ion-ios7-medkit:before { content: "\f289"; } +.ion-ios-minus-empty:before { content: "\f462"; } -.ion-ios7-medkit-outline:before { content: "\f288"; } +.ion-ios-minus-outline:before { content: "\f463"; } -.ion-ios7-mic:before { content: "\f1ab"; } +.ion-ios-monitor:before { content: "\f466"; } -.ion-ios7-mic-off:before { content: "\f1a9"; } +.ion-ios-monitor-outline:before { content: "\f465"; } -.ion-ios7-mic-outline:before { content: "\f1aa"; } +.ion-ios-moon:before { content: "\f468"; } -.ion-ios7-minus:before { content: "\f1ae"; } +.ion-ios-moon-outline:before { content: "\f467"; } -.ion-ios7-minus-empty:before { content: "\f1ac"; } +.ion-ios-more:before { content: "\f46a"; } -.ion-ios7-minus-outline:before { content: "\f1ad"; } +.ion-ios-more-outline:before { content: "\f469"; } -.ion-ios7-monitor:before { content: "\f1b0"; } +.ion-ios-musical-note:before { content: "\f46b"; } -.ion-ios7-monitor-outline:before { content: "\f1af"; } +.ion-ios-musical-notes:before { content: "\f46c"; } -.ion-ios7-moon:before { content: "\f1b2"; } +.ion-ios-navigate:before { content: "\f46e"; } -.ion-ios7-moon-outline:before { content: "\f1b1"; } +.ion-ios-navigate-outline:before { content: "\f46d"; } -.ion-ios7-more:before { content: "\f1b4"; } +.ion-ios-nutrition:before { content: "\f470"; } -.ion-ios7-more-outline:before { content: "\f1b3"; } +.ion-ios-nutrition-outline:before { content: "\f46f"; } -.ion-ios7-musical-note:before { content: "\f1b5"; } +.ion-ios-paper:before { content: "\f472"; } -.ion-ios7-musical-notes:before { content: "\f1b6"; } +.ion-ios-paper-outline:before { content: "\f471"; } -.ion-ios7-navigate:before { content: "\f1b8"; } +.ion-ios-paperplane:before { content: "\f474"; } -.ion-ios7-navigate-outline:before { content: "\f1b7"; } +.ion-ios-paperplane-outline:before { content: "\f473"; } -.ion-ios7-paper:before { content: "\f32f"; } +.ion-ios-partlysunny:before { content: "\f476"; } -.ion-ios7-paper-outline:before { content: "\f32e"; } +.ion-ios-partlysunny-outline:before { content: "\f475"; } -.ion-ios7-paperplane:before { content: "\f1ba"; } +.ion-ios-pause:before { content: "\f478"; } -.ion-ios7-paperplane-outline:before { content: "\f1b9"; } +.ion-ios-pause-outline:before { content: "\f477"; } -.ion-ios7-partlysunny:before { content: "\f1bc"; } +.ion-ios-paw:before { content: "\f47a"; } -.ion-ios7-partlysunny-outline:before { content: "\f1bb"; } +.ion-ios-paw-outline:before { content: "\f479"; } -.ion-ios7-pause:before { content: "\f1be"; } +.ion-ios-people:before { content: "\f47c"; } -.ion-ios7-pause-outline:before { content: "\f1bd"; } +.ion-ios-people-outline:before { content: "\f47b"; } -.ion-ios7-paw:before { content: "\f331"; } +.ion-ios-person:before { content: "\f47e"; } -.ion-ios7-paw-outline:before { content: "\f330"; } +.ion-ios-person-outline:before { content: "\f47d"; } -.ion-ios7-people:before { content: "\f1c0"; } +.ion-ios-personadd:before { content: "\f480"; } -.ion-ios7-people-outline:before { content: "\f1bf"; } +.ion-ios-personadd-outline:before { content: "\f47f"; } -.ion-ios7-person:before { content: "\f1c2"; } +.ion-ios-photos:before { content: "\f482"; } -.ion-ios7-person-outline:before { content: "\f1c1"; } +.ion-ios-photos-outline:before { content: "\f481"; } -.ion-ios7-personadd:before { content: "\f1c4"; } +.ion-ios-pie:before { content: "\f484"; } -.ion-ios7-personadd-outline:before { content: "\f1c3"; } +.ion-ios-pie-outline:before { content: "\f483"; } -.ion-ios7-photos:before { content: "\f1c6"; } +.ion-ios-pint:before { content: "\f486"; } -.ion-ios7-photos-outline:before { content: "\f1c5"; } +.ion-ios-pint-outline:before { content: "\f485"; } -.ion-ios7-pie:before { content: "\f28b"; } +.ion-ios-play:before { content: "\f488"; } -.ion-ios7-pie-outline:before { content: "\f28a"; } +.ion-ios-play-outline:before { content: "\f487"; } -.ion-ios7-play:before { content: "\f1c8"; } +.ion-ios-plus:before { content: "\f48b"; } -.ion-ios7-play-outline:before { content: "\f1c7"; } +.ion-ios-plus-empty:before { content: "\f489"; } -.ion-ios7-plus:before { content: "\f1cb"; } +.ion-ios-plus-outline:before { content: "\f48a"; } -.ion-ios7-plus-empty:before { content: "\f1c9"; } +.ion-ios-pricetag:before { content: "\f48d"; } -.ion-ios7-plus-outline:before { content: "\f1ca"; } +.ion-ios-pricetag-outline:before { content: "\f48c"; } -.ion-ios7-pricetag:before { content: "\f28d"; } +.ion-ios-pricetags:before { content: "\f48f"; } -.ion-ios7-pricetag-outline:before { content: "\f28c"; } +.ion-ios-pricetags-outline:before { content: "\f48e"; } -.ion-ios7-pricetags:before { content: "\f333"; } +.ion-ios-printer:before { content: "\f491"; } -.ion-ios7-pricetags-outline:before { content: "\f332"; } +.ion-ios-printer-outline:before { content: "\f490"; } -.ion-ios7-printer:before { content: "\f1cd"; } +.ion-ios-pulse:before { content: "\f493"; } -.ion-ios7-printer-outline:before { content: "\f1cc"; } +.ion-ios-pulse-strong:before { content: "\f492"; } -.ion-ios7-pulse:before { content: "\f335"; } +.ion-ios-rainy:before { content: "\f495"; } -.ion-ios7-pulse-strong:before { content: "\f334"; } +.ion-ios-rainy-outline:before { content: "\f494"; } -.ion-ios7-rainy:before { content: "\f1cf"; } +.ion-ios-recording:before { content: "\f497"; } -.ion-ios7-rainy-outline:before { content: "\f1ce"; } +.ion-ios-recording-outline:before { content: "\f496"; } -.ion-ios7-recording:before { content: "\f1d1"; } +.ion-ios-redo:before { content: "\f499"; } -.ion-ios7-recording-outline:before { content: "\f1d0"; } +.ion-ios-redo-outline:before { content: "\f498"; } -.ion-ios7-redo:before { content: "\f1d3"; } +.ion-ios-refresh:before { content: "\f49c"; } -.ion-ios7-redo-outline:before { content: "\f1d2"; } +.ion-ios-refresh-empty:before { content: "\f49a"; } -.ion-ios7-refresh:before { content: "\f1d6"; } +.ion-ios-refresh-outline:before { content: "\f49b"; } -.ion-ios7-refresh-empty:before { content: "\f1d4"; } +.ion-ios-reload:before { content: "\f49d"; } -.ion-ios7-refresh-outline:before { content: "\f1d5"; } +.ion-ios-reverse-camera:before { content: "\f49f"; } -.ion-ios7-reload:before, .ion-ios7-reloading:before { content: "\f28e"; } +.ion-ios-reverse-camera-outline:before { content: "\f49e"; } -.ion-ios7-reverse-camera:before { content: "\f337"; } +.ion-ios-rewind:before { content: "\f4a1"; } -.ion-ios7-reverse-camera-outline:before { content: "\f336"; } +.ion-ios-rewind-outline:before { content: "\f4a0"; } -.ion-ios7-rewind:before { content: "\f1d8"; } +.ion-ios-rose:before { content: "\f4a3"; } -.ion-ios7-rewind-outline:before { content: "\f1d7"; } +.ion-ios-rose-outline:before { content: "\f4a2"; } -.ion-ios7-search:before { content: "\f1da"; } +.ion-ios-search:before { content: "\f4a5"; } -.ion-ios7-search-strong:before { content: "\f1d9"; } +.ion-ios-search-strong:before { content: "\f4a4"; } -.ion-ios7-settings:before { content: "\f339"; } +.ion-ios-settings:before { content: "\f4a7"; } -.ion-ios7-settings-strong:before { content: "\f338"; } +.ion-ios-settings-strong:before { content: "\f4a6"; } -.ion-ios7-shrink:before { content: "\f30e"; } +.ion-ios-shuffle:before { content: "\f4a9"; } -.ion-ios7-skipbackward:before { content: "\f1dc"; } +.ion-ios-shuffle-strong:before { content: "\f4a8"; } -.ion-ios7-skipbackward-outline:before { content: "\f1db"; } +.ion-ios-skipbackward:before { content: "\f4ab"; } -.ion-ios7-skipforward:before { content: "\f1de"; } +.ion-ios-skipbackward-outline:before { content: "\f4aa"; } -.ion-ios7-skipforward-outline:before { content: "\f1dd"; } +.ion-ios-skipforward:before { content: "\f4ad"; } -.ion-ios7-snowy:before { content: "\f309"; } +.ion-ios-skipforward-outline:before { content: "\f4ac"; } -.ion-ios7-speedometer:before { content: "\f290"; } +.ion-ios-snowy:before { content: "\f4ae"; } -.ion-ios7-speedometer-outline:before { content: "\f28f"; } +.ion-ios-speedometer:before { content: "\f4b0"; } -.ion-ios7-star:before { content: "\f1e0"; } +.ion-ios-speedometer-outline:before { content: "\f4af"; } -.ion-ios7-star-half:before { content: "\f33a"; } +.ion-ios-star:before { content: "\f4b3"; } -.ion-ios7-star-outline:before { content: "\f1df"; } +.ion-ios-star-half:before { content: "\f4b1"; } -.ion-ios7-stopwatch:before { content: "\f1e2"; } +.ion-ios-star-outline:before { content: "\f4b2"; } -.ion-ios7-stopwatch-outline:before { content: "\f1e1"; } +.ion-ios-stopwatch:before { content: "\f4b5"; } -.ion-ios7-sunny:before { content: "\f1e4"; } +.ion-ios-stopwatch-outline:before { content: "\f4b4"; } -.ion-ios7-sunny-outline:before { content: "\f1e3"; } +.ion-ios-sunny:before { content: "\f4b7"; } -.ion-ios7-telephone:before { content: "\f1e6"; } +.ion-ios-sunny-outline:before { content: "\f4b6"; } -.ion-ios7-telephone-outline:before { content: "\f1e5"; } +.ion-ios-telephone:before { content: "\f4b9"; } -.ion-ios7-tennisball:before { content: "\f33c"; } +.ion-ios-telephone-outline:before { content: "\f4b8"; } -.ion-ios7-tennisball-outline:before { content: "\f33b"; } +.ion-ios-tennisball:before { content: "\f4bb"; } -.ion-ios7-thunderstorm:before { content: "\f1e8"; } +.ion-ios-tennisball-outline:before { content: "\f4ba"; } -.ion-ios7-thunderstorm-outline:before { content: "\f1e7"; } +.ion-ios-thunderstorm:before { content: "\f4bd"; } -.ion-ios7-time:before { content: "\f292"; } +.ion-ios-thunderstorm-outline:before { content: "\f4bc"; } -.ion-ios7-time-outline:before { content: "\f291"; } +.ion-ios-time:before { content: "\f4bf"; } -.ion-ios7-timer:before { content: "\f1ea"; } +.ion-ios-time-outline:before { content: "\f4be"; } -.ion-ios7-timer-outline:before { content: "\f1e9"; } +.ion-ios-timer:before { content: "\f4c1"; } -.ion-ios7-toggle:before { content: "\f33e"; } +.ion-ios-timer-outline:before { content: "\f4c0"; } -.ion-ios7-toggle-outline:before { content: "\f33d"; } +.ion-ios-toggle:before { content: "\f4c3"; } -.ion-ios7-trash:before { content: "\f1ec"; } +.ion-ios-toggle-outline:before { content: "\f4c2"; } -.ion-ios7-trash-outline:before { content: "\f1eb"; } +.ion-ios-trash:before { content: "\f4c5"; } -.ion-ios7-undo:before { content: "\f1ee"; } +.ion-ios-trash-outline:before { content: "\f4c4"; } -.ion-ios7-undo-outline:before { content: "\f1ed"; } +.ion-ios-undo:before { content: "\f4c7"; } -.ion-ios7-unlocked:before { content: "\f1f0"; } +.ion-ios-undo-outline:before { content: "\f4c6"; } -.ion-ios7-unlocked-outline:before { content: "\f1ef"; } +.ion-ios-unlocked:before { content: "\f4c9"; } -.ion-ios7-upload:before { content: "\f1f2"; } +.ion-ios-unlocked-outline:before { content: "\f4c8"; } -.ion-ios7-upload-outline:before { content: "\f1f1"; } +.ion-ios-upload:before { content: "\f4cb"; } -.ion-ios7-videocam:before { content: "\f1f4"; } +.ion-ios-upload-outline:before { content: "\f4ca"; } -.ion-ios7-videocam-outline:before { content: "\f1f3"; } +.ion-ios-videocam:before { content: "\f4cd"; } -.ion-ios7-volume-high:before { content: "\f1f5"; } +.ion-ios-videocam-outline:before { content: "\f4cc"; } -.ion-ios7-volume-low:before { content: "\f1f6"; } +.ion-ios-volume-high:before { content: "\f4ce"; } -.ion-ios7-wineglass:before { content: "\f294"; } +.ion-ios-volume-low:before { content: "\f4cf"; } -.ion-ios7-wineglass-outline:before { content: "\f293"; } +.ion-ios-wineglass:before { content: "\f4d1"; } -.ion-ios7-world:before { content: "\f1f8"; } +.ion-ios-wineglass-outline:before { content: "\f4d0"; } -.ion-ios7-world-outline:before { content: "\f1f7"; } +.ion-ios-world:before { content: "\f4d3"; } + +.ion-ios-world-outline:before { content: "\f4d2"; } .ion-ipad:before { content: "\f1f9"; } @@ -899,23 +1083,25 @@ .ion-link:before { content: "\f1fe"; } -.ion-load-a:before, .ion-loading-a:before { content: "\f29a"; } +.ion-load-a:before { content: "\f29a"; } -.ion-load-b:before, .ion-loading-b:before { content: "\f29b"; } +.ion-load-b:before { content: "\f29b"; } -.ion-load-c:before, .ion-loading-c:before { content: "\f29c"; } +.ion-load-c:before { content: "\f29c"; } -.ion-load-d:before, .ion-loading-d:before { content: "\f29d"; } +.ion-load-d:before { content: "\f29d"; } .ion-location:before { content: "\f1ff"; } +.ion-lock-combination:before { content: "\f4d4"; } + .ion-locked:before { content: "\f200"; } .ion-log-in:before { content: "\f29e"; } .ion-log-out:before { content: "\f29f"; } -.ion-loop:before, .ion-looping:before { content: "\f201"; } +.ion-loop:before { content: "\f201"; } .ion-magnet:before { content: "\f2a0"; } @@ -965,6 +1151,10 @@ .ion-outlet:before { content: "\f342"; } +.ion-paintbrush:before { content: "\f4d5"; } + +.ion-paintbucket:before { content: "\f4d6"; } + .ion-paper-airplane:before { content: "\f2c3"; } .ion-paperclip:before { content: "\f20f"; } @@ -1021,7 +1211,7 @@ .ion-record:before { content: "\f21b"; } -.ion-refresh:before, .ion-refreshing:before { content: "\f21c"; } +.ion-refresh:before { content: "\f21c"; } .ion-reply:before { content: "\f21e"; } @@ -1033,6 +1223,8 @@ .ion-sad:before { content: "\f34a"; } +.ion-sad-outline:before { content: "\f4d7"; } + .ion-scissors:before { content: "\f34b"; } .ion-search:before { content: "\f21f"; } @@ -1051,6 +1243,10 @@ .ion-social-android-outline:before { content: "\f224"; } +.ion-social-angular:before { content: "\f4d9"; } + +.ion-social-angular-outline:before { content: "\f4d8"; } + .ion-social-apple:before { content: "\f227"; } .ion-social-apple-outline:before { content: "\f226"; } @@ -1063,6 +1259,18 @@ .ion-social-buffer-outline:before { content: "\f228"; } +.ion-social-chrome:before { content: "\f4db"; } + +.ion-social-chrome-outline:before { content: "\f4da"; } + +.ion-social-codepen:before { content: "\f4dd"; } + +.ion-social-codepen-outline:before { content: "\f4dc"; } + +.ion-social-css3:before { content: "\f4df"; } + +.ion-social-css3-outline:before { content: "\f4de"; } + .ion-social-designernews:before { content: "\f22b"; } .ion-social-designernews-outline:before { content: "\f22a"; } @@ -1075,6 +1283,10 @@ .ion-social-dropbox-outline:before { content: "\f22e"; } +.ion-social-euro:before { content: "\f4e1"; } + +.ion-social-euro-outline:before { content: "\f4e0"; } + .ion-social-facebook:before { content: "\f231"; } .ion-social-facebook-outline:before { content: "\f230"; } @@ -1101,18 +1313,34 @@ .ion-social-hackernews-outline:before { content: "\f236"; } +.ion-social-html5:before { content: "\f4e3"; } + +.ion-social-html5-outline:before { content: "\f4e2"; } + .ion-social-instagram:before { content: "\f351"; } .ion-social-instagram-outline:before { content: "\f350"; } +.ion-social-javascript:before { content: "\f4e5"; } + +.ion-social-javascript-outline:before { content: "\f4e4"; } + .ion-social-linkedin:before { content: "\f239"; } .ion-social-linkedin-outline:before { content: "\f238"; } +.ion-social-markdown:before { content: "\f4e6"; } + +.ion-social-nodejs:before { content: "\f4e7"; } + +.ion-social-octocat:before { content: "\f4e8"; } + .ion-social-pinterest:before { content: "\f2b1"; } .ion-social-pinterest-outline:before { content: "\f2b0"; } +.ion-social-python:before { content: "\f4e9"; } + .ion-social-reddit:before { content: "\f23b"; } .ion-social-reddit-outline:before { content: "\f23a"; } @@ -1121,16 +1349,26 @@ .ion-social-rss-outline:before { content: "\f23c"; } +.ion-social-sass:before { content: "\f4ea"; } + .ion-social-skype:before { content: "\f23f"; } .ion-social-skype-outline:before { content: "\f23e"; } +.ion-social-snapchat:before { content: "\f4ec"; } + +.ion-social-snapchat-outline:before { content: "\f4eb"; } + .ion-social-tumblr:before { content: "\f241"; } .ion-social-tumblr-outline:before { content: "\f240"; } .ion-social-tux:before { content: "\f2c5"; } +.ion-social-twitch:before { content: "\f4ee"; } + +.ion-social-twitch-outline:before { content: "\f4ed"; } + .ion-social-twitter:before { content: "\f243"; } .ion-social-twitter-outline:before { content: "\f242"; } @@ -1143,6 +1381,10 @@ .ion-social-vimeo-outline:before { content: "\f244"; } +.ion-social-whatsapp:before { content: "\f4f0"; } + +.ion-social-whatsapp-outline:before { content: "\f4ef"; } + .ion-social-windows:before { content: "\f247"; } .ion-social-windows-outline:before { content: "\f246"; } @@ -1155,10 +1397,18 @@ .ion-social-yahoo-outline:before { content: "\f24a"; } +.ion-social-yen:before { content: "\f4f2"; } + +.ion-social-yen-outline:before { content: "\f4f1"; } + .ion-social-youtube:before { content: "\f24d"; } .ion-social-youtube-outline:before { content: "\f24c"; } +.ion-soup-can:before { content: "\f4f4"; } + +.ion-soup-can-outline:before { content: "\f4f3"; } + .ion-speakerphone:before { content: "\f2b2"; } .ion-speedometer:before { content: "\f2b3"; } @@ -1183,12 +1433,18 @@ .ion-toggle-filled:before { content: "\f354"; } +.ion-transgender:before { content: "\f4f5"; } + .ion-trash-a:before { content: "\f252"; } .ion-trash-b:before { content: "\f253"; } .ion-trophy:before { content: "\f356"; } +.ion-tshirt:before { content: "\f4f7"; } + +.ion-tshirt-outline:before { content: "\f4f6"; } + .ion-umbrella:before { content: "\f2b7"; } .ion-university:before { content: "\f357"; } diff --git a/views/controls/builder/settings.ejs b/views/controls/builder/settings.ejs index aae67d0..f7642ae 100644 --- a/views/controls/builder/settings.ejs +++ b/views/controls/builder/settings.ejs @@ -4,7 +4,7 @@ diff --git a/views/controls/builder/toolbar.ejs b/views/controls/builder/toolbar.ejs index 8b2e9b8..ad51f0e 100644 --- a/views/controls/builder/toolbar.ejs +++ b/views/controls/builder/toolbar.ejs @@ -2,7 +2,7 @@ + class="ion-ios-photos-outline"> + class="ion-ios-keypad-outline"> + class="ion-ios-sunny-outline"> + class="ion-ios-compose-outline">
    - +
    diff --git a/views/controls/reader/about-room.ejs b/views/controls/reader/about-room.ejs index 974fe0f..a9ef738 100644 --- a/views/controls/reader/about-room.ejs +++ b/views/controls/reader/about-room.ejs @@ -5,7 +5,7 @@ [[ if (authorpic) { ]]
    [[ } else { ]] - + [[ } ]] [[- author ]] diff --git a/views/home.ejs b/views/home.ejs index 20723a5..b83e3e9 100755 --- a/views/home.ejs +++ b/views/home.ejs @@ -12,7 +12,7 @@
    Create 3D Rooms
    -
    +
    Watch video.
    @@ -78,7 +78,7 @@
    - +
    diff --git a/views/profile.ejs b/views/profile.ejs index e149847..63a07f5 100644 --- a/views/profile.ejs +++ b/views/profile.ejs @@ -15,7 +15,7 @@ [[ } else { ]]
    - + [[ if (isOwnProfile) { ]]
    click to add profile pic
    -- cgit v1.2.3-70-g09d2 From 94ba321f96638906e41eda7abf371066011c8508 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 29 Apr 2015 18:46:21 -0400 Subject: misc edits --- public/assets/javascripts/mx/extensions/mx.movements.js | 2 +- public/assets/javascripts/mx/primitives/mx.video.js | 3 +++ public/assets/javascripts/mx/primitives/mx.vimeo.js | 16 ++++++++++++---- public/assets/javascripts/mx/primitives/mx.youtube.js | 3 +++ .../javascripts/rectangles/engine/scenery/_scenery.js | 17 +++++++++++++++-- .../javascripts/rectangles/engine/scenery/sound.js | 2 +- .../rectangles/engine/scenery/types/video.js | 7 ++++++- public/assets/javascripts/ui/reader/ReaderView.js | 2 ++ 8 files changed, 43 insertions(+), 9 deletions(-) (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 931caac..fa59908 100644 --- a/public/assets/javascripts/mx/extensions/mx.movements.js +++ b/public/assets/javascripts/mx/extensions/mx.movements.js @@ -20,7 +20,7 @@ MX.Movements = function (cam) { rotationX_max = PI/6 var v = 12, - vr = Math.PI * 0.012, + vr = Math.PI * 0.018, jumpV = 23, vx = vy = vz = 0, creepFactor = 0.3 diff --git a/public/assets/javascripts/mx/primitives/mx.video.js b/public/assets/javascripts/mx/primitives/mx.video.js index 43c392a..53ccf2e 100644 --- a/public/assets/javascripts/mx/primitives/mx.video.js +++ b/public/assets/javascripts/mx/primitives/mx.video.js @@ -21,6 +21,7 @@ MX.Video = MX.Object3D.extend({ this.el.classList.add("video") this.el.classList.add("mx-scenery") this.paused = !! this.media.autoplay + this.playing = false this.muted = app.muted || !! this.media.mute }, @@ -60,11 +61,13 @@ MX.Video = MX.Object3D.extend({ play: function(){ this.paused = false + this.playing = true this.player.play() }, pause: function(){ this.paused = true + this.playing = false this.player.pause() }, diff --git a/public/assets/javascripts/mx/primitives/mx.vimeo.js b/public/assets/javascripts/mx/primitives/mx.vimeo.js index e1a3b84..af138ae 100644 --- a/public/assets/javascripts/mx/primitives/mx.vimeo.js +++ b/public/assets/javascripts/mx/primitives/mx.vimeo.js @@ -20,6 +20,7 @@ MX.Vimeo = MX.Object3D.extend({ this.backface && this.el.classList.add("backface-visible") this.el.classList.add("video") this.el.classList.add("mx-scenery") + this.playing = false this.paused = !! this.media.autoplay this.muted = app.muted || !! this.media.mute this.started = false @@ -145,19 +146,26 @@ MX.Vimeo = MX.Object3D.extend({ if (this.paused) { this.pause() } + else { + this.playing = true + } }, onPause: function(){ if (! this.paused) { this.play() } + else { + this.playing = false + } }, finished: function(){ -// if (this.media.loop) { -// this.seek(0) -// this.play() -// } + console.log("vimeo finished") + if (this.media.loop) { + this.seek(0) + this.play() + } // else if (this.bound) { if (! this.media.loop && this.bound) { $(".playButton").removeClass('playing') diff --git a/public/assets/javascripts/mx/primitives/mx.youtube.js b/public/assets/javascripts/mx/primitives/mx.youtube.js index e4e73d6..8cd9f59 100644 --- a/public/assets/javascripts/mx/primitives/mx.youtube.js +++ b/public/assets/javascripts/mx/primitives/mx.youtube.js @@ -21,6 +21,7 @@ MX.Youtube = MX.Object3D.extend({ this.el.classList.add("video") this.el.classList.add("mx-scenery") this.paused = !! this.media.autoplay + this.playing = false this.muted = app.muted || !! this.media.mute }, @@ -143,11 +144,13 @@ MX.Youtube = MX.Object3D.extend({ play: function(){ this.paused = false + this.playing = true this.player.playVideo() }, pause: function(){ this.paused = true + this.playing = false this.player.pauseVideo() }, diff --git a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js index e9be663..6203c20 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js +++ b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js @@ -121,7 +121,10 @@ var Scenery = new function(){ } base.playAll = function(){ base.forEach(function(scenery){ - if (scenery.type == "video") scenery.play() + if (scenery.type == "video") { + scenery.unmute() + scenery.play() + } }) } base.pauseAll = function(){ @@ -129,7 +132,17 @@ var Scenery = new function(){ if (scenery.type == "video") scenery.pause() }) } - + base.muteAll = function(){ + base.forEach(function(scenery){ + if (scenery.type == "video") scenery.mx.mute() + }) + } + base.unmuteAll = function(){ + base.forEach(function(scenery){ + if (scenery.type == "video") scenery.mx.unmute() + }) + } + return base } diff --git a/public/assets/javascripts/rectangles/engine/scenery/sound.js b/public/assets/javascripts/rectangles/engine/scenery/sound.js index 37bdee0..d63d8c4 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/sound.js +++ b/public/assets/javascripts/rectangles/engine/scenery/sound.js @@ -5,7 +5,7 @@ Scenery.sound.init = function(){ app.tube.on("move", Scenery.sound.move) } Scenery.sound.move = function(){ - var vals = Scenery.map(function(scenery){ + Scenery.forEach(function(scenery){ if ((scenery.type == "video" || scenery.type == "audio") && ! scenery.muted()) { var distance = dist(cam.x, cam.z, scenery.mx.x, scenery.mx.z) diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/video.js b/public/assets/javascripts/rectangles/engine/scenery/types/video.js index fb1a868..163e19e 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/video.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/video.js @@ -38,7 +38,8 @@ Scenery.types.video = Scenery.types.base.extend(function(base){ backface: false, }) scene.add(this.mx) - this.mx.load() + + this.mx.load() }, play: function(){ @@ -90,6 +91,10 @@ Scenery.types.video = Scenery.types.base.extend(function(base){ } }, + unmute: function(){ + this.mx.unmute() + }, + setVolume: function(n){ this.mx.setVolume(n) }, diff --git a/public/assets/javascripts/ui/reader/ReaderView.js b/public/assets/javascripts/ui/reader/ReaderView.js index 55d2520..1ba97cf 100644 --- a/public/assets/javascripts/ui/reader/ReaderView.js +++ b/public/assets/javascripts/ui/reader/ReaderView.js @@ -94,6 +94,8 @@ var ReaderView = View.extend({ // disable until we start using spinning again // this.listen() + + app.tube("site-ready") }, listen: function(){ -- cgit v1.2.3-70-g09d2 From 15692020fbc7bdfa66f9ecae0eaf844054c59e4a Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 6 Aug 2015 19:11:23 -0400 Subject: plan restriction business logic --- public/assets/javascripts/ui/site/LayoutsModal.js | 14 ++++++++++++-- server/index.js | 2 +- server/lib/api/layouts.js | 11 ++++++++++- server/lib/middleware.js | 16 +++++++++++++++- 4 files changed, 38 insertions(+), 5 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js index 5974fc3..639d55c 100644 --- a/public/assets/javascripts/ui/site/LayoutsModal.js +++ b/public/assets/javascripts/ui/site/LayoutsModal.js @@ -15,13 +15,23 @@ var LayoutsIndex = View.extend({ }, populate: function(data){ - if (! data.length) { +/* + if (data.layoutCount > data.plan.basic_layout_limit) { + } + if (data.projectCount > data.plan.stock_project_limit) { + } + if (data.projectCount > data.plan.basic_project_limit) { + } + if (data.projectCount > data.plan.pro_project_limit) { + } +*/ + if (! data.layouts.length) { this.$templates.hide() this.$form.hide() this.$noTemplates.show() } this.$templatesList.empty() - data.forEach(function(room){ + data.layouts.forEach(function(room){ var $span = $("") $span.data("slug", room.slug) diff --git a/server/index.js b/server/index.js index 30cf69a..db9b051 100644 --- a/server/index.js +++ b/server/index.js @@ -139,7 +139,7 @@ site.route = function () { app.get('/project/:slug/view', middleware.ensureProject, middleware.ensureIsCollaborator, views.reader) app.get('/project/:slug/edit', middleware.ensureProject, middleware.ensureIsCollaborator, views.editor) - app.get('/api/layout', middleware.ensureAuthenticated, api.layouts.index) + app.get('/api/layout', middleware.ensureAuthenticated, middleware.ensureUserProjectsCount, middleware.ensureUserLayoutsCount, api.layouts.index) app.get('/api/layout/:slug', middleware.ensureAuthenticated, api.layouts.show) app.post('/api/layout/new', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.create) app.post('/api/layout/edit', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.update) diff --git a/server/lib/api/layouts.js b/server/lib/api/layouts.js index 641e9e2..7e7976c 100644 --- a/server/lib/api/layouts.js +++ b/server/lib/api/layouts.js @@ -3,13 +3,22 @@ var _ = require('lodash'), util = require('../util'), upload = require('../upload'), + middleware = require('../middleware'), config = require('../../../config.json'), Layout = require('../schemas/Layout'); var layouts = { index: function(req, res){ + // free layouts + // user layouts Layout.find({}, function(err, docs){ - res.json(docs) + res.json({ + layouts: docs, + plan: middleware.plans[ res.locals.user.plan_level || 0 ], + user: res.locals.user, + layoutCount: res.locals.layoutCount, + projectCount: res.locals.projectCount, + }) }) }, diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 35c520c..9d09a10 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -7,6 +7,7 @@ var passport = require('passport'), User = require('./schemas/User'), Collaborator = require('./schemas/Collaborator'), Project = require('./schemas/Project'), + Layout = require('./schemas/Layout'), Plan = require('./schemas/Plan'); @@ -63,7 +64,20 @@ var middleware = { res.locals.opt = {} next() }, - + + ensureUserProjectsCount: function(req, res, next){ + Project.count({ user_id: req.user.id }, function(err, count){ + res.locals.projectCount = count || 0 + next() + }) + }, + ensureUserLayoutsCount: function(req, res, next){ + Layout.count({ user_id: req.user.id }, function(err, count){ + res.locals.layoutCount = count || 0 + next() + }) + }, + ensureProject: function (req, res, next) { if (req.params.slug) { Project.findOne({ slug: req.params.slug }, function(err, project){ -- cgit v1.2.3-70-g09d2 From 33e5644226649d277c6b84dc37fccdd5b7c6e86c Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 7 Aug 2015 12:23:35 -0400 Subject: more accurate counts --- public/assets/javascripts/ui/site/LayoutsModal.js | 10 ++-- server/lib/api/layouts.js | 4 +- server/lib/middleware.js | 60 +++++++++++++++++++++-- server/lib/schemas/Plan.js | 2 +- server/lib/schemas/Project.js | 1 + server/lib/views/staff.js | 45 ++++++++++++++++- views/staff/_nav.ejs | 1 + views/staff/plans/_form.ejs | 6 +-- views/staff/projects/index.ejs | 2 +- 9 files changed, 113 insertions(+), 18 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js index 639d55c..f69b38f 100644 --- a/public/assets/javascripts/ui/site/LayoutsModal.js +++ b/public/assets/javascripts/ui/site/LayoutsModal.js @@ -16,13 +16,15 @@ var LayoutsIndex = View.extend({ populate: function(data){ /* - if (data.layoutCount > data.plan.basic_layout_limit) { + if (data.layoutCounts.basic > data.plan.basic_layout_limit) { } - if (data.projectCount > data.plan.stock_project_limit) { + if (data.layoutCounts.pro > data.plan.pro_layout_limit) { } - if (data.projectCount > data.plan.basic_project_limit) { + if (data.projectCounts.stock > data.plan.stock_project_limit) { } - if (data.projectCount > data.plan.pro_project_limit) { + if (data.projectCounts.basic > data.plan.basic_project_limit) { + } + if (data.projectCounts.pro > data.plan.pro_project_limit) { } */ if (! data.layouts.length) { diff --git a/server/lib/api/layouts.js b/server/lib/api/layouts.js index 7e7976c..1c87fae 100644 --- a/server/lib/api/layouts.js +++ b/server/lib/api/layouts.js @@ -16,8 +16,8 @@ var layouts = { layouts: docs, plan: middleware.plans[ res.locals.user.plan_level || 0 ], user: res.locals.user, - layoutCount: res.locals.layoutCount, - projectCount: res.locals.projectCount, + layoutCounts: res.locals.layoutCounts, + projectCounts: res.locals.projectCounts, }) }) }, diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 9d09a10..fe4dc49 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -60,20 +60,48 @@ var middleware = { res.locals.ogUrl = "http://vvalls.com/" res.locals.ogDescription = "3D gallery space, fully customizable" res.locals.ogAuthor = "VValls" - res.locals.plans = plans + res.locals.plans = middleware.plans res.locals.opt = {} next() }, ensureUserProjectsCount: function(req, res, next){ - Project.count({ user_id: req.user.id }, function(err, count){ - res.locals.projectCount = count || 0 + var counts = { stock: 0, basic: 0, pro: 0 } + res.locals.projectCounts = counts + Project.count({ user_id: req.user.id, layout_type: 0 }, function(err, count){ + res.locals.projectCounts.stock = count || 0 + if (req.user.plan_level > 0) { return middleware.ensureBasicProjectsCount(req, res, next) } + else next() + }) + }, + ensureBasicProjectsCount: function(req, res, next){ + Project.count({ user_id: req.user.id, layout_type: 1 }, function(err, count){ + res.locals.projectCounts.basic = count || 0 + if (req.user.plan_level > 1) { return middleware.ensureProProjectsCount(req, res, next) } + else next() + }) + }, + ensureProProjectsCount: function(req, res, next){ + Project.count({ user_id: req.user.id, layout_type: 2 }, function(err, count){ + res.locals.projectCounts.pro = count || 0 next() }) }, + ensureUserLayoutsCount: function(req, res, next){ - Layout.count({ user_id: req.user.id }, function(err, count){ - res.locals.layoutCount = count || 0 + var counts = { basic: 0, pro: 0 } + res.locals.layoutCounts = counts + if (req.user.plan_level == 0) { return next() } + + Layout.count({ user_id: req.user.id, layout_type: 1 }, function(err, count){ + res.locals.layoutCounts.basic = count || 0 + if (req.user.plan_level > 1) { return middleware.ensureProLayoutsCount(req, res, next) } + else next() + }) + }, + ensureProLayoutsCount: function(req, res, next){ + Project.count({ user_id: req.user.id, layout_type: 2 }, function(err, count){ + res.locals.layoutCounts.pro = count || 0 next() }) }, @@ -100,6 +128,28 @@ var middleware = { } }, + ensureLayout: function (req, res, next) { + if (req.params.slug) { + Layout.findOne({ slug: req.params.slug }, function(err, layout){ + if (err) { + console.error(err) + req.layout = null + } + else if (! project) { + req.layout = null + } + else { + req.layout = layout + } + next() + }) + } + else { + req.layout = null + next() + } + }, + ensureIsCollaborator: function(req, res, next) { req.isCollaborator = false req.isOwner = false diff --git a/server/lib/schemas/Plan.js b/server/lib/schemas/Plan.js index 8a19b99..388ce69 100644 --- a/server/lib/schemas/Plan.js +++ b/server/lib/schemas/Plan.js @@ -31,7 +31,7 @@ var PlanSchema = new mongoose.Schema({ permissions: { basic_editor: { type: Boolean, default: false }, pro_editor: { type: Boolean, default: false }, - solids: { type: Boolean, default: false }, + sculpture: { type: Boolean, default: false }, collaborators: { type: Boolean, default: false }, no_logo: { type: Boolean, default: false }, }, diff --git a/server/lib/schemas/Project.js b/server/lib/schemas/Project.js index e9501fc..855d95a 100644 --- a/server/lib/schemas/Project.js +++ b/server/lib/schemas/Project.js @@ -39,6 +39,7 @@ var ProjectSchema = new mongoose.Schema({ created_at: { type: Date }, updated_at: { type: Date }, featured: { type: Boolean, default: false }, + layout_type: { type: Number, default: 0 }, }); module.exports = exports = mongoose.model('project', ProjectSchema); diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index 19b361d..6c97bbd 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -21,7 +21,7 @@ var staff = module.exports = { plans: "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price " + "pro_layout_monthly_price pro_layout_yearly_price " + "basic_layout_limit pro_layout_limit stock_project_limit basic_project_limit pro_project_limit", - plans_permissions: "basic_editor pro_editor solids collaborators no_logo", + plans_permissions: "basic_editor pro_editor sculpture collaborators no_logo", }, defaults: { @@ -401,6 +401,13 @@ var staff = module.exports = { return project }, + layout: function(layout){ + layout = layout.toObject() + layout.date = moment( layout.updated_at || layout.created_at ).format("M/DD/YYYY hh:mm a") + layout.user = {} + return layout + }, + media: function(media){ media = media.toObject() media.date = moment( media.updated_at || media.created_at ).format("M/DD/YYYY hh:mm a") @@ -520,7 +527,41 @@ var staff = module.exports = { staff.projects.feature ); - + + // + // layouts + + app.get('/staff/layouts', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + staff.middleware.ensureLayoutsCount, + + staff.middleware.ensureLayouts, + staff.middleware.ensureLayoutsUsers, + + staff.layouts.index + ); + app.get('/staff/layouts/:slug', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + middleware.ensureLayout, + staff.middleware.ensureLayout, + staff.middleware.ensureLayoutUser, + + staff.layouts.show + ); + app.put('/staff/layouts/:slug/feature', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + middleware.ensureLayout, + staff.middleware.ensureLayout, + + staff.layouts.make_stock + ); + // // media diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs index a607638..3bb3b08 100644 --- a/views/staff/_nav.ejs +++ b/views/staff/_nav.ejs @@ -2,6 +2,7 @@ home users projects + layouts media plans diff --git a/views/staff/plans/_form.ejs b/views/staff/plans/_form.ejs index 61be7e8..85375fa 100644 --- a/views/staff/plans/_form.ejs +++ b/views/staff/plans/_form.ejs @@ -124,9 +124,9 @@
  • - - - + + +
  • diff --git a/views/staff/projects/index.ejs b/views/staff/projects/index.ejs index e4ba469..1d309ce 100644 --- a/views/staff/projects/index.ejs +++ b/views/staff/projects/index.ejs @@ -7,7 +7,7 @@
    [[ include ../_pagination ]] -[[ include ../_projects ]] +[[ include ../_layouts ]] [[ include ../_pagination ]] [[ include ../_footer ]] -- cgit v1.2.3-70-g09d2 From e0aebb7ef327f29c0ab8f5b75a24c5d823dfd90f Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 7 Aug 2015 18:30:51 -0400 Subject: lockout --- public/assets/javascripts/ui/site/LayoutsModal.js | 11 ++--------- server/lib/api/layouts.js | 3 --- 2 files changed, 2 insertions(+), 12 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js index f69b38f..b620b58 100644 --- a/public/assets/javascripts/ui/site/LayoutsModal.js +++ b/public/assets/javascripts/ui/site/LayoutsModal.js @@ -16,15 +16,8 @@ var LayoutsIndex = View.extend({ populate: function(data){ /* - if (data.layoutCounts.basic > data.plan.basic_layout_limit) { - } - if (data.layoutCounts.pro > data.plan.pro_layout_limit) { - } - if (data.projectCounts.stock > data.plan.stock_project_limit) { - } - if (data.projectCounts.basic > data.plan.basic_project_limit) { - } - if (data.projectCounts.pro > data.plan.pro_project_limit) { + if (data.user.plan_level < 1 && data.projectCounts.free == 1) { + // show lockout message } */ if (! data.layouts.length) { diff --git a/server/lib/api/layouts.js b/server/lib/api/layouts.js index 1c87fae..a3edc38 100644 --- a/server/lib/api/layouts.js +++ b/server/lib/api/layouts.js @@ -9,12 +9,9 @@ var _ = require('lodash'), var layouts = { index: function(req, res){ - // free layouts - // user layouts Layout.find({}, function(err, docs){ res.json({ layouts: docs, - plan: middleware.plans[ res.locals.user.plan_level || 0 ], user: res.locals.user, layoutCounts: res.locals.layoutCounts, projectCounts: res.locals.projectCounts, -- cgit v1.2.3-70-g09d2 From 18e8ca03b90f124968400ccc742744c3ed01547a Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 7 Aug 2015 18:36:25 -0400 Subject: cleanup --- public/assets/javascripts/ui/site/LayoutsModal.js | 2 +- server/lib/api/layouts.js | 17 +++++++------ server/lib/middleware.js | 29 ++++------------------- 3 files changed, 15 insertions(+), 33 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js index b620b58..87251af 100644 --- a/public/assets/javascripts/ui/site/LayoutsModal.js +++ b/public/assets/javascripts/ui/site/LayoutsModal.js @@ -16,7 +16,7 @@ var LayoutsIndex = View.extend({ populate: function(data){ /* - if (data.user.plan_level < 1 && data.projectCounts.free == 1) { + if (data.user.plan_level < 1 && data.projectCount == 1) { // show lockout message } */ diff --git a/server/lib/api/layouts.js b/server/lib/api/layouts.js index a3edc38..f1db121 100644 --- a/server/lib/api/layouts.js +++ b/server/lib/api/layouts.js @@ -9,13 +9,16 @@ var _ = require('lodash'), var layouts = { index: function(req, res){ - Layout.find({}, function(err, docs){ - res.json({ - layouts: docs, - user: res.locals.user, - layoutCounts: res.locals.layoutCounts, - projectCounts: res.locals.projectCounts, - }) + Layout.find({ is_stock: true }, function(err, stock_layouts){ + Layout.find({ user_id: req.user._id }, function(err, user_layouts){ + res.json({ + layouts: stock_layouts, + user_layouts: user_layouts, + user: res.locals.user, + layoutCount: res.locals.layoutCount, + projectCount: res.locals.projectCount, + }) + }) }) }, diff --git a/server/lib/middleware.js b/server/lib/middleware.js index fe4dc49..94c4acd 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -68,22 +68,8 @@ var middleware = { ensureUserProjectsCount: function(req, res, next){ var counts = { stock: 0, basic: 0, pro: 0 } res.locals.projectCounts = counts - Project.count({ user_id: req.user.id, layout_type: 0 }, function(err, count){ - res.locals.projectCounts.stock = count || 0 - if (req.user.plan_level > 0) { return middleware.ensureBasicProjectsCount(req, res, next) } - else next() - }) - }, - ensureBasicProjectsCount: function(req, res, next){ - Project.count({ user_id: req.user.id, layout_type: 1 }, function(err, count){ - res.locals.projectCounts.basic = count || 0 - if (req.user.plan_level > 1) { return middleware.ensureProProjectsCount(req, res, next) } - else next() - }) - }, - ensureProProjectsCount: function(req, res, next){ - Project.count({ user_id: req.user.id, layout_type: 2 }, function(err, count){ - res.locals.projectCounts.pro = count || 0 + Project.count({ user_id: req.user._id }, function(err, count){ + res.locals.projectCount = count || 0 next() }) }, @@ -93,15 +79,8 @@ var middleware = { res.locals.layoutCounts = counts if (req.user.plan_level == 0) { return next() } - Layout.count({ user_id: req.user.id, layout_type: 1 }, function(err, count){ - res.locals.layoutCounts.basic = count || 0 - if (req.user.plan_level > 1) { return middleware.ensureProLayoutsCount(req, res, next) } - else next() - }) - }, - ensureProLayoutsCount: function(req, res, next){ - Project.count({ user_id: req.user.id, layout_type: 2 }, function(err, count){ - res.locals.layoutCounts.pro = count || 0 + Layout.count({ user_id: req.user._id }, function(err, count){ + res.locals.layoutCount = count || 0 next() }) }, -- cgit v1.2.3-70-g09d2 From 71c3a4a02c7c46533aec836ef30a0d0ffa96399b Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 10 Aug 2015 18:20:22 -0400 Subject: layout stuff --- .../javascripts/mx/extensions/mx.movements.js | 6 +- .../assets/javascripts/mx/primitives/mx.image.js | 3 +- .../rectangles/engine/map/tools/ortho.js | 26 +- .../rectangles/engine/map/tools/polyline.js | 24 +- .../rectangles/engine/shapes/shapelist.js | 1 + public/assets/javascripts/ui/lib/Toolbar.js | 22 ++ public/assets/javascripts/ui/site/StaffView.js | 26 +- public/assets/test/ortho3.html | 38 +-- public/assets/test/ortho4.html | 261 +++++++++++++++++++++ server/lib/middleware.js | 2 +- server/lib/schemas/Media.js | 1 + server/lib/views/staff.js | 3 +- views/staff/_layouts.ejs | 2 +- views/staff/layouts/show.ejs | 4 +- 14 files changed, 352 insertions(+), 67 deletions(-) create mode 100644 public/assets/javascripts/ui/lib/Toolbar.js create mode 100644 public/assets/test/ortho4.html (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 fa59908..9ed8790 100644 --- a/public/assets/javascripts/mx/extensions/mx.movements.js +++ b/public/assets/javascripts/mx/extensions/mx.movements.js @@ -162,13 +162,13 @@ MX.Movements = function (cam) { case 8: // backspace e.preventDefault() - if (app.controller.sculptureEditor.sculpture) { + if (app.controller.sculptureEditor && app.controller.sculptureEditor.sculpture) { app.controller.sculptureEditor.sculpture.remove() } - else if (app.controller.mediaEditor.scenery) { + else if (app.controller.mediaEditor && app.controller.mediaEditor.scenery) { app.controller.mediaEditor.scenery.remove() } - else if (app.controller.textEditor.scenery) { + else if (app.controller.textEditor && app.controller.textEditor.scenery) { app.controller.textEditor.scenery.remove() } } diff --git a/public/assets/javascripts/mx/primitives/mx.image.js b/public/assets/javascripts/mx/primitives/mx.image.js index 64de4b2..f9de141 100644 --- a/public/assets/javascripts/mx/primitives/mx.image.js +++ b/public/assets/javascripts/mx/primitives/mx.image.js @@ -17,7 +17,7 @@ MX.Image = MX.Object3D.extend({ this.el.style.backgroundRepeat = 'no-repeat' - this.load(ops) + ops.src && this.load(ops) }, load: function(ops){ @@ -64,7 +64,6 @@ MX.Image = MX.Object3D.extend({ if (recenter) { ctx.restore() } - }, }) diff --git a/public/assets/javascripts/rectangles/engine/map/tools/ortho.js b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js index be3d707..ef41096 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/ortho.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js @@ -12,11 +12,11 @@ var OrthoPolylineTool = MapTool.extend(function (base) { if (map.ui.placing) { // close polyline or cancel map.ui.placing = false - if (line.points.length > 2) { - line.build() + if (shapes.workline.points.length > 2) { + shapes.workline.build() } else { - line.reset() + shapes.workline.reset() } return } @@ -29,24 +29,24 @@ var OrthoPolylineTool = MapTool.extend(function (base) { // compare to initial point var p = last_point.clone() if (map.ui.placing) { - if (line.lastPoint().eq(p)) { + if (shapes.workline.lastPoint().eq(p)) { return } - else if (line.canCloseWith(p)) { - line.close() - line.build() + else if (shapes.workline.canCloseWith(p)) { + shapes.workline.close() + shapes.workline.build() map.ui.placing = false } else { - line.add(p) + shapes.workline.add(p) prev_point = p horizontal = ! horizontal } } else { map.ui.placing = true - line = new Polyline () - line.add(p) + shapes.workline = new Polyline () + shapes.workline.add(p) first_point = prev_point = p horizontal = false } @@ -55,7 +55,7 @@ var OrthoPolylineTool = MapTool.extend(function (base) { last_point.a = cursor.x.a last_point.b = cursor.y.a if (map.ui.placing) { - if (line.points.length == 1) { + if (shapes.workline.points.length == 1) { var x = abs(prev_point.a - last_point.a) var y = abs(prev_point.b - last_point.b) if (x > y) { @@ -86,7 +86,7 @@ var OrthoPolylineTool = MapTool.extend(function (base) { } } - if (line.canCloseWith(last_point)) { + if (shapes.workline.canCloseWith(last_point)) { document.body.style.cursor = "pointer" last_point.assign(first_point) cursor.x.a = cursor.x.b = last_point.a @@ -107,7 +107,7 @@ var OrthoPolylineTool = MapTool.extend(function (base) { } } exports.cancel = function(){ - if (map.ui.placing) { line.reset() } + if (map.ui.placing) { shapes.workline.reset() } first_point = null map.ui.placing = false } diff --git a/public/assets/javascripts/rectangles/engine/map/tools/polyline.js b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js index 559aea8..1ab86f6 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/polyline.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js @@ -9,11 +9,11 @@ var PolylineTool = MapTool.extend(function (base) { if (map.ui.placing) { // close polyline or cancel map.ui.placing = false - if (line.points.length > 2) { - line.build() + if (shapes.workline.points.length > 2) { + shapes.workline.build() } else { - line.reset() + shapes.workline.reset() } return } @@ -24,27 +24,27 @@ var PolylineTool = MapTool.extend(function (base) { // compare to initial point var p = last_point.clone() if (map.ui.placing) { - if (line.canCloseWith(p)) { - line.close() - line.build() + if (shapes.workline.canCloseWith(p)) { + shapes.workline.close() + shapes.workline.build() map.ui.placing = false } else { - line.add(p) + shapes.workline.add(p) } } else { map.ui.placing = true - line = new Polyline () - line.add(p) + shapes.workline = new Polyline () + shapes.workline.add(p) } } exports.move = function(e, cursor){ last_point.a = cursor.x.a last_point.b = cursor.y.a - if (map.ui.placing && line.canCloseWith(last_point)) { + if (map.ui.placing && shapes.workline.canCloseWith(last_point)) { document.body.style.cursor = "pointer" - last_point.assign(line.points[0]) + last_point.assign(shapes.workline.points[0]) cursor.x.a = cursor.x.b = last_point.a cursor.y.a = cursor.y.b = last_point.b return @@ -62,7 +62,7 @@ var PolylineTool = MapTool.extend(function (base) { } } exports.cancel = function(){ - if (map.ui.placing) { line.reset() } + if (map.ui.placing) { shapes.workline.reset() } map.ui.placing = false } return exports diff --git a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js index 00e1a4e..932ce36 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js +++ b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js @@ -2,6 +2,7 @@ var ShapeList = Fiber.extend(function(base){ var exports = {} exports.init = function(){ this.shapes = [] + this.workline = null } exports.add = function(shape){ this.shapes.push(shape) diff --git a/public/assets/javascripts/ui/lib/Toolbar.js b/public/assets/javascripts/ui/lib/Toolbar.js new file mode 100644 index 0000000..a9ce51c --- /dev/null +++ b/public/assets/javascripts/ui/lib/Toolbar.js @@ -0,0 +1,22 @@ +var Toolbar = Fiber.extend(function(base){ + var exports = {} + exports.init = function(rapper){ + this.rapper = (typeof rapper == "string") ? $(rapper)[0] : rapper + this.tools = {} + this.els = {} + } + exports.add = function(role, fn){ + var self = this + this.tools[role] = fn + this.els[role] = $("[data-role=" + role + "]", self.rapper) + this.els[role].click(function(){ + $(".active", self.rapper).removeClass('active') + $(this).addClass('active') + fn() + }) + } + exports.pick = function(role){ + this.els[role].trigger("click") + } + return exports +}) \ No newline at end of file diff --git a/public/assets/javascripts/ui/site/StaffView.js b/public/assets/javascripts/ui/site/StaffView.js index 0398f71..59649e3 100644 --- a/public/assets/javascripts/ui/site/StaffView.js +++ b/public/assets/javascripts/ui/site/StaffView.js @@ -4,11 +4,13 @@ var StaffView = View.extend({ events: { "click #toggle-staff": "toggleStaff", "click #toggle-featured": "toggleFeatured", + "click #toggle-stock": "toggleStock", }, initialize: function() { this.$toggleStaff = $("#toggle-staff") this.$toggleFeatured = $("#toggle-featured") + this.$toggleStock = $("#toggle-stock") this.$mediaEmbed = $("#media-embed") if (this.$toggleStaff.length && this.$toggleStaff.data().isstaff) { this.$toggleStaff.html("Is Staff") @@ -16,6 +18,9 @@ var StaffView = View.extend({ if (this.$toggleFeatured.length && this.$toggleFeatured.data().featured) { this.$toggleFeatured.html("Featured Project") } + if (this.$toggleStock.length && this.$toggleStock.data().stock) { + this.$toggleStock.html("Layout is Stock") + } if (this.$mediaEmbed.length) { var media = this.$mediaEmbed.data() this.$mediaEmbed.html( Parser.tag( media ) ) @@ -67,6 +72,25 @@ var StaffView = View.extend({ $("#isFeaturedProject").html(data.state ? "yes" : "no") }.bind(this) }) - }, + }, + + toggleStock: function(){ + console.log("stock") + var state = ! this.$toggleStock.data().stock + $.ajax({ + type: "put", + dataType: "json", + url: window.location.href + "/stock", + data: { + state: state, + _csrf: $("#_csrf").val(), + }, + success: function(data){ + this.$toggleStock.data("stock", data.state) + this.$toggleStock.html(data.state ? "Stock Layout" : "Make this layout Stock") + $("#isStockLayout").html(data.state ? "yes" : "no") + }.bind(this) + }) + }, }) diff --git a/public/assets/test/ortho3.html b/public/assets/test/ortho3.html index ef5732c..f41a0ba 100644 --- a/public/assets/test/ortho3.html +++ b/public/assets/test/ortho3.html @@ -80,6 +80,7 @@ body { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 94c4acd..04cb330 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -114,7 +114,7 @@ var middleware = { console.error(err) req.layout = null } - else if (! project) { + else if (! layout) { req.layout = null } else { diff --git a/server/lib/schemas/Media.js b/server/lib/schemas/Media.js index 8247467..f37fb12 100644 --- a/server/lib/schemas/Media.js +++ b/server/lib/schemas/Media.js @@ -42,6 +42,7 @@ var MediaSchema = new mongoose.Schema({ mute: { type: Boolean, default: false }, keyframe: { type: Number, default: 0.0 }, tag: { type: String, default: "" }, + scale: { type: Number, default: 1.0 }, widthDimension: { type: Number }, heightDimension: { type: Number }, diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index a3d5bea..43330e2 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -6,6 +6,7 @@ var User = require('../schemas/User'), Collaborator = require('../schemas/Collaborator'), Plan = require('../schemas/Plan'), Subscription = require('../schemas/Subscription'), + Layout = require('../schemas/Layout'), config = require('../../../config'), middleware = require('../middleware'), util = require('../util'), @@ -821,7 +822,7 @@ var staff = module.exports = { make_stock: function(req, res){ res.locals.layout.is_stock = req.body.state == "true" res.locals.layout.save(function(err, layout){ - res.json({ state: layout.featured }) + res.json({ state: layout.is_stock }) }) }, }, diff --git a/views/staff/_layouts.ejs b/views/staff/_layouts.ejs index 3f3e6b2..d97883b 100644 --- a/views/staff/_layouts.ejs +++ b/views/staff/_layouts.ejs @@ -1,5 +1,5 @@ -[[ layouts.forEach(function(project){ ]] +[[ layouts.forEach(function(layout){ ]]
    [[- layout.name ]] diff --git a/views/staff/layouts/show.ejs b/views/staff/layouts/show.ejs index 0a2014b..b66449f 100644 --- a/views/staff/layouts/show.ejs +++ b/views/staff/layouts/show.ejs @@ -45,14 +45,14 @@ featured? - [[- layout.plan_type == 0 ? "yes" : "no" ]] + [[- layout.is_stock ? "yes" : "no" ]]


    - +

    -- cgit v1.2.3-70-g09d2 From e61e94f5d2f570f0cba3a3f7d91a18d8db524d79 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 10 Aug 2015 20:42:19 -0400 Subject: blueprint upload stuff --- .../javascripts/rectangles/engine/map/_map.js | 2 +- .../javascripts/ui/builder/BlueprintUpload.js | 120 +++++++++++++++++++++ public/assets/stylesheets/app.css | 3 +- public/assets/test/ortho4.html | 43 +++++++- 4 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 public/assets/javascripts/ui/builder/BlueprintUpload.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/engine/map/_map.js b/public/assets/javascripts/rectangles/engine/map/_map.js index bf646bb..e3d7621 100644 --- a/public/assets/javascripts/rectangles/engine/map/_map.js +++ b/public/assets/javascripts/rectangles/engine/map/_map.js @@ -44,7 +44,7 @@ var Map = function(opt){ var canvas = base.canvas = document.createElement("canvas") canvas.width = base.dimensions.a canvas.height = base.dimensions.b - + base.el.appendChild(canvas) switch (opt.type) { diff --git a/public/assets/javascripts/ui/builder/BlueprintUpload.js b/public/assets/javascripts/ui/builder/BlueprintUpload.js new file mode 100644 index 0000000..dbc6f12 --- /dev/null +++ b/public/assets/javascripts/ui/builder/BlueprintUpload.js @@ -0,0 +1,120 @@ + +var BlueprintUpload = UploadView.extend({ + el: ".blueprintUpload", + + mediaTag: "blueprint", + createAction: "/api/media/new", + uploadAction: "/api/media/upload", + listAction: "/api/media/user", + destroyAction: "/api/media/destroy", + + events: { + "mousedown": 'stopPropagation', + "change .url": "enterUrl", + "keydown .url": "enterSetUrl", + + "click .blueprint": "choose", + "change [name=blueprint-dimensions]": "changeDimensions", + "change [name=blueprint-units]": "changeUnits", + "click #saveBlueprint": "save", + }, + + initialize: function(opt){ + this.parent = opt.parent + this.__super__.initialize.call(this) + + this.$url = this.$(".url") + + this.$blueprintMap = this.$("#blueprintMap") + this.$blueprintDimensionsRapper = this.$("#blueprintDimensions") + this.$dimensions = this.$("[name=blueprint-dimensions]") + this.$units = this.$("[name=blueprint-units]") + this.$save = this.$("#saveBlueprint") + + this.map = new Map ({ type: ortho }) + + this.load() + }, + + loaded: false, + load: function(){ + $.get(this.listAction, { tag: this.mediaTag }, this.populate.bind(this)) + }, + + populate: function(data){ + this.loaded = true + if (data && data.length) { + data.forEach(this.append.bind(this)) + this.$(".txt").hide() + } + else { + this.$(".txt").show() + } + }, + + append: function(media){ + var $el = $("
    ") + $el.data("id", media._id) + $el.addClass("blueprint") + this.$blueprints.append($el) + }, + + pick: function(e){ + var $el = $(e.currentTarget) + // load map with it + }, + + destroy: function(_id, cb){ + $.ajax({ + type: "delete", + url: this.destroyAction, + data: { _id: _id, _csrf: $("[name=_csrf]").val() } + }).complete(cb || function(){}) + }, + + show: function(){ + this.toggle(true) + }, + hide: function(){ + this.toggle(false) + }, + toggle: function (state) { + this.$el.toggleClass("active", state) + }, + + addUrl: function (url){ + Parser.loadImage(url, function(media){ + if (! media) return + media._csrf = $("[name=_csrf]").val() + media.tag = this.mediaTag + + var request = $.ajax({ + type: "post", + url: this.createAction, + data: media, + }) + request.done(this.add.bind(this)) + + }.bind(this)) + }, + enterUrl: function(){ + var url = this.$url.sanitize() + this.addUrl(url) + this.$url.val("") + }, + enterSetUrl: function (e) { + e.stopPropagation() + if (e.keyCode == 13) { + setTimeout(this.enterUrl.bind(this), 100) + } + }, + + add: function(media){ + this.append(media) + }, + changeDimensions: function(){ + }, + changeUnits: function(){ + }, + +}) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 56c65fe..bb32500 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1597,7 +1597,8 @@ form .paidPlan label { float: none; font-size: 16px; margin: 0 10px; } .mediaDrawer.signin, .mediaDrawer.signup, .mediaDrawer.alert, .mediaDrawer.confirm, .mediaDrawer.passwordForgot, .mediaDrawer.passwordReset, .mediaDrawer.usernameTaken, -.mediaDrawer.layouts, .mediaDrawer.projects, .mediaDrawer.newProject { +.mediaDrawer.layouts, .mediaDrawer.projects, .mediaDrawer.newProject, +.mediaDrawer.blueprintUpload { display:table; } .confirm button { diff --git a/public/assets/test/ortho4.html b/public/assets/test/ortho4.html index b434efb..12b6ab2 100644 --- a/public/assets/test/ortho4.html +++ b/public/assets/test/ortho4.html @@ -1,15 +1,19 @@ +
    @@ -47,11 +55,38 @@ body {
    -
    +
    X

    Upload A Room Image

    + +
    +
    +
    + + + +
    +
    + +
    + + Please tell us the scale of your map. + Click both corners of a wall, and then enter how long the wall is. + +
    +
    + +
    + + + + +
    -- cgit v1.2.3-70-g09d2 From 8d749201d661f62766b4e3a84735c3307ff7ab5e Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 11 Aug 2015 13:22:02 -0400 Subject: refactor environment loading --- public/assets/javascripts/app.js | 30 +----- public/assets/javascripts/rectangles/_env.js | 34 +++++- public/assets/javascripts/ui/_router.js | 11 ++ .../javascripts/ui/builder/BlueprintUpload.js | 120 --------------------- public/assets/test/ortho4.html | 9 +- views/modal.ejs | 3 +- views/partials/scripts.ejs | 17 ++- 7 files changed, 68 insertions(+), 156 deletions(-) delete mode 100644 public/assets/javascripts/ui/builder/BlueprintUpload.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/app.js b/public/assets/javascripts/app.js index 6ebcda5..3cafeca 100644 --- a/public/assets/javascripts/app.js +++ b/public/assets/javascripts/app.js @@ -21,40 +21,12 @@ app.init = function () { app.launch = function () { if ($.browser.msie || ! has3d()) { return app.fallback() } - scene = new MX.Scene().addTo('#scene') - scene.width = window.innerWidth - scene.height = window.innerHeight - scene.perspective = window.innerHeight - - window.onresize = function () { - scene.width = window.innerWidth - scene.height = window.innerHeight - scene.perspective = window.innerHeight - scene.update() - } - - cam = scene.camera - cam.y = viewHeight - - if (MX.Map) map = app.map = new MX.Map() - - if (is_mobile) { - app.movements = new MX.MobileMovements(cam, viewHeight) - } - else { - app.movements = new MX.Movements(cam, viewHeight) - } - app.movements.init() - var last_t = 0 function animate (t) { var dt = t - last_t last_t = t requestAnimationFrame(animate) - environment.update(t) - window.path && path.update(t) - app.movements.update(dt || 0) - scene.update() + environment.update(t, dt) } var loader = new Loader(function(){ diff --git a/public/assets/javascripts/rectangles/_env.js b/public/assets/javascripts/rectangles/_env.js index 14f73e3..b3c7d66 100644 --- a/public/assets/javascripts/rectangles/_env.js +++ b/public/assets/javascripts/rectangles/_env.js @@ -1,6 +1,22 @@ var environment = new function(){} environment.init = function(){ + scene = new MX.Scene().addTo('#scene') + scene.width = window.innerWidth + scene.height = window.innerHeight + scene.perspective = window.innerHeight + + cam = scene.camera + cam.y = viewHeight + + if (is_mobile) { + app.movements = new MX.MobileMovements(cam, viewHeight) + } + else { + app.movements = new MX.Movements(cam, viewHeight) + } + app.movements.init() + map = new Map () if (window.scene) { @@ -16,7 +32,14 @@ environment.init = function(){ scene.camera.radius = 20 } - + + window.onresize = function () { + scene.width = window.innerWidth + scene.height = window.innerHeight + scene.perspective = window.innerHeight + scene.update() + } + Rooms.init() Walls.init() Scenery.init() @@ -52,8 +75,13 @@ environment.init = function(){ } }) } -environment.update = function(t){ +environment.minimal = function(){ + environment.update = function(t){} +} +environment.update = function(t, dt){ + app.movements.update(dt || 0) + scene.update() map.update() - window.minimap && window.minimap.update && minimap.update() + window.minimap && minimap.update && minimap.update() z = false } diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index 1bdce19..857377c 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -44,6 +44,8 @@ var SiteRouter = Router.extend({ "/project/:name": 'projectViewer', "/project/:name/edit": 'projectEditor', "/project/:name/view": 'projectViewer', + + "/test/blueprint": 'blueprintEditor', }, mobileRoutes: { @@ -157,6 +159,15 @@ var SiteRouter = Router.extend({ this.readerView = app.controller = new ReaderView() this.readerView.load(name) }, + + blueprintEditor: function(e){ + environment.init = environment.minimal + app.launch() + if (app.unsupported) return + + this.blueprintView = app.controller = new BlueprintView () + this.blueprintView.load() + }, signup: function(e){ e && e.preventDefault() diff --git a/public/assets/javascripts/ui/builder/BlueprintUpload.js b/public/assets/javascripts/ui/builder/BlueprintUpload.js deleted file mode 100644 index dbc6f12..0000000 --- a/public/assets/javascripts/ui/builder/BlueprintUpload.js +++ /dev/null @@ -1,120 +0,0 @@ - -var BlueprintUpload = UploadView.extend({ - el: ".blueprintUpload", - - mediaTag: "blueprint", - createAction: "/api/media/new", - uploadAction: "/api/media/upload", - listAction: "/api/media/user", - destroyAction: "/api/media/destroy", - - events: { - "mousedown": 'stopPropagation', - "change .url": "enterUrl", - "keydown .url": "enterSetUrl", - - "click .blueprint": "choose", - "change [name=blueprint-dimensions]": "changeDimensions", - "change [name=blueprint-units]": "changeUnits", - "click #saveBlueprint": "save", - }, - - initialize: function(opt){ - this.parent = opt.parent - this.__super__.initialize.call(this) - - this.$url = this.$(".url") - - this.$blueprintMap = this.$("#blueprintMap") - this.$blueprintDimensionsRapper = this.$("#blueprintDimensions") - this.$dimensions = this.$("[name=blueprint-dimensions]") - this.$units = this.$("[name=blueprint-units]") - this.$save = this.$("#saveBlueprint") - - this.map = new Map ({ type: ortho }) - - this.load() - }, - - loaded: false, - load: function(){ - $.get(this.listAction, { tag: this.mediaTag }, this.populate.bind(this)) - }, - - populate: function(data){ - this.loaded = true - if (data && data.length) { - data.forEach(this.append.bind(this)) - this.$(".txt").hide() - } - else { - this.$(".txt").show() - } - }, - - append: function(media){ - var $el = $("
    ") - $el.data("id", media._id) - $el.addClass("blueprint") - this.$blueprints.append($el) - }, - - pick: function(e){ - var $el = $(e.currentTarget) - // load map with it - }, - - destroy: function(_id, cb){ - $.ajax({ - type: "delete", - url: this.destroyAction, - data: { _id: _id, _csrf: $("[name=_csrf]").val() } - }).complete(cb || function(){}) - }, - - show: function(){ - this.toggle(true) - }, - hide: function(){ - this.toggle(false) - }, - toggle: function (state) { - this.$el.toggleClass("active", state) - }, - - addUrl: function (url){ - Parser.loadImage(url, function(media){ - if (! media) return - media._csrf = $("[name=_csrf]").val() - media.tag = this.mediaTag - - var request = $.ajax({ - type: "post", - url: this.createAction, - data: media, - }) - request.done(this.add.bind(this)) - - }.bind(this)) - }, - enterUrl: function(){ - var url = this.$url.sanitize() - this.addUrl(url) - this.$url.val("") - }, - enterSetUrl: function (e) { - e.stopPropagation() - if (e.keyCode == 13) { - setTimeout(this.enterUrl.bind(this), 100) - } - }, - - add: function(media){ - this.append(media) - }, - changeDimensions: function(){ - }, - changeUnits: function(){ - }, - -}) diff --git a/public/assets/test/ortho4.html b/public/assets/test/ortho4.html index 12b6ab2..1c1adef 100644 --- a/public/assets/test/ortho4.html +++ b/public/assets/test/ortho4.html @@ -91,14 +91,16 @@ body {
    - - + + + + @@ -126,8 +128,10 @@ body { + + + + @@ -79,10 +81,20 @@ + + + + - + + + + + + + @@ -115,6 +127,9 @@ + + + -- cgit v1.2.3-70-g09d2 From b5d2503ec4e5844ab3793c9e48020bcbaef3112b Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 11 Aug 2015 13:22:31 -0400 Subject: blueprint integration into views --- .../javascripts/ui/blueprint/BlueprintScale.js | 0 .../javascripts/ui/blueprint/BlueprintUpload.js | 122 +++++++++++++++++++++ .../javascripts/ui/blueprint/BlueprintView.js | 39 +++++++ views/controls/builder/blueprint.ejs | 92 ++++++++++++++++ 4 files changed, 253 insertions(+) create mode 100644 public/assets/javascripts/ui/blueprint/BlueprintScale.js create mode 100644 public/assets/javascripts/ui/blueprint/BlueprintUpload.js create mode 100644 public/assets/javascripts/ui/blueprint/BlueprintView.js create mode 100644 views/controls/builder/blueprint.ejs (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScale.js b/public/assets/javascripts/ui/blueprint/BlueprintScale.js new file mode 100644 index 0000000..e69de29 diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUpload.js b/public/assets/javascripts/ui/blueprint/BlueprintUpload.js new file mode 100644 index 0000000..fd3a659 --- /dev/null +++ b/public/assets/javascripts/ui/blueprint/BlueprintUpload.js @@ -0,0 +1,122 @@ + +var BlueprintUploadView = UploadView.extend({ + el: ".blueprintUpload", + + mediaTag: "blueprint", + createAction: "/api/media/new", + uploadAction: "/api/media/upload", + listAction: "/api/media/user", + destroyAction: "/api/media/destroy", + + events: { + "mousedown": 'stopPropagation', + "change .url": "enterUrl", + "keydown .url": "enterSetUrl", + + "click .blueprint": "choose", + "change [name=blueprint-dimensions]": "changeDimensions", + "change [name=blueprint-units]": "changeUnits", + "click #saveBlueprint": "save", + }, + + initialize: function(opt){ + this.parent = opt.parent + this.__super__.initialize.call(this) + + this.$url = this.$(".url") + + this.$blueprintMap = this.$("#blueprintMap") + this.$blueprintDimensionsRapper = this.$("#blueprintDimensions") + this.$dimensions = this.$("[name=blueprint-dimensions]") + this.$units = this.$("[name=blueprint-units]") + this.$save = this.$("#saveBlueprint") + + this.map = new Map ({ type: 'ortho' }) + + this.load() + }, + + loaded: false, + load: function(){ + $.get(this.listAction, { tag: this.mediaTag }, this.populate.bind(this)) + }, + + populate: function(data){ + this.loaded = true + if (data && data.length) { + data.forEach(this.append.bind(this)) + this.$(".txt").hide() + } + else { + this.$(".txt").show() + } + }, + + append: function(media){ + var $el = $("
    ") + $el.data("id", media._id) + $el.addClass("blueprint") + this.$blueprints.append($el) + }, + + pick: function(e){ + var $el = $(e.currentTarget) + // load map with it + }, + + destroy: function(_id, cb){ + $.ajax({ + type: "delete", + url: this.destroyAction, + data: { _id: _id, _csrf: $("[name=_csrf]").val() } + }).complete(cb || function(){}) + }, + + show: function(){ + this.toggle(true) + }, + hide: function(){ + this.toggle(false) + }, + toggle: function (state) { + this.$el.toggleClass("active", state) + }, + + addUrl: function (url){ + Parser.loadImage(url, function(media){ + if (! media) return + media._csrf = $("[name=_csrf]").val() + media.tag = this.mediaTag + + var request = $.ajax({ + type: "post", + url: this.createAction, + data: media, + }) + request.done(this.add.bind(this)) + + }.bind(this)) + }, + enterUrl: function(){ + var url = this.$url.sanitize() + this.addUrl(url) + this.$url.val("") + }, + enterSetUrl: function (e) { + e.stopPropagation() + if (e.keyCode == 13) { + setTimeout(this.enterUrl.bind(this), 100) + } + }, + + add: function(media){ + this.append(media) + }, + changeDimensions: function(){ + }, + changeUnits: function(){ + }, + save: function(){ + }, + +}) diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js new file mode 100644 index 0000000..f7ee13e --- /dev/null +++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js @@ -0,0 +1,39 @@ + +var BlueprintView = View.extend({ + el: "#blueprintView", + + events: { + }, + + initialize: function(){ +// this.info = new BuilderInfo ({ parent: this }) +// this.toolbar = new BuilderToolbar ({ parent: this }) +// this.settings = new BuilderSettings ({ parent: this }) +// this.colorControl = new ColorControl ({ parent: this }) +// this.cursor = new HelpCursor({ parent: this }) + this.blueprintUpload = new BlueprintUploadView ({ parent: this }) + }, + + load: function(name){ +// if (! name || name == "new") { +// this.ready({ isNew: true, _id: "new", name: "" }) +// return +// } +// +// name = sanitize(name) +// +// $.get(this.action + name, this.ready.bind(this)) + }, + + ready: function(data){ +// this.settings.load(data) +// this.info.load(data) + }, + + hideExtras: function(){ + }, + + pickWall: function(wall, pos){ + }, + +}) diff --git a/views/controls/builder/blueprint.ejs b/views/controls/builder/blueprint.ejs new file mode 100644 index 0000000..e5f3257 --- /dev/null +++ b/views/controls/builder/blueprint.ejs @@ -0,0 +1,92 @@ + + +
    +
    +
    + +
    + + + +
    + +
    + + + + +
    + +
    + X +
    + +

    Upload A Room Image

    + +
    +
    +
    + + + +
    +
    + +
    + + Please tell us the scale of your map. + Click both corners of a wall, and then enter how long the wall is. + +
    +
    + +
    + + + + +
    + +
    +
    +
    \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 4024085b09261c23cd89227e340037e0238072c7 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 11 Aug 2015 14:15:31 -0400 Subject: uploader functioning --- .../javascripts/ui/blueprint/BlueprintEditor.js | 30 ++++++ .../javascripts/ui/blueprint/BlueprintScale.js | 0 .../javascripts/ui/blueprint/BlueprintUpload.js | 35 ++----- .../javascripts/ui/blueprint/BlueprintView.js | 3 +- public/assets/stylesheets/app.css | 2 +- views/controls/blueprint/editor.ejs | 104 +++++++++++++++++++++ views/controls/builder/blueprint.ejs | 92 ------------------ views/modal.ejs | 2 +- views/partials/scripts.ejs | 1 + 9 files changed, 149 insertions(+), 120 deletions(-) create mode 100644 public/assets/javascripts/ui/blueprint/BlueprintEditor.js delete mode 100644 public/assets/javascripts/ui/blueprint/BlueprintScale.js create mode 100644 views/controls/blueprint/editor.ejs delete mode 100644 views/controls/builder/blueprint.ejs (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js new file mode 100644 index 0000000..227c1c8 --- /dev/null +++ b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js @@ -0,0 +1,30 @@ + +var BlueprintEditor = ModalView.extend({ + el: ".blueprintEditor", + + events: { + "change [name=blueprint-dimensions]": "changeDimensions", + "change [name=blueprint-units]": "changeUnits", + "click #saveBlueprint": "save", + }, + + initialize: function(){ + this.$blueprintMap = this.$("#blueprintMap") + this.$blueprintDimensionsRapper = this.$("#blueprintDimensions") + this.$dimensions = this.$("[name=blueprint-dimensions]") + this.$units = this.$("[name=blueprint-units]") + this.$save = this.$("#saveBlueprint") + + this.map = new Map ({ type: 'ortho' }) + + this.$blueprintMap.append(this.map.el) + }, + + changeDimensions: function(){ + }, + changeUnits: function(){ + }, + save: function(){ + }, + +}) diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScale.js b/public/assets/javascripts/ui/blueprint/BlueprintScale.js deleted file mode 100644 index e69de29..0000000 diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUpload.js b/public/assets/javascripts/ui/blueprint/BlueprintUpload.js index fd3a659..9467715 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintUpload.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintUpload.js @@ -1,5 +1,5 @@ -var BlueprintUploadView = UploadView.extend({ +var BlueprintUpload = UploadView.extend({ el: ".blueprintUpload", mediaTag: "blueprint", @@ -14,9 +14,6 @@ var BlueprintUploadView = UploadView.extend({ "keydown .url": "enterSetUrl", "click .blueprint": "choose", - "change [name=blueprint-dimensions]": "changeDimensions", - "change [name=blueprint-units]": "changeUnits", - "click #saveBlueprint": "save", }, initialize: function(opt){ @@ -24,15 +21,8 @@ var BlueprintUploadView = UploadView.extend({ this.__super__.initialize.call(this) this.$url = this.$(".url") + this.$blueprints = this.$(".blueprints") - this.$blueprintMap = this.$("#blueprintMap") - this.$blueprintDimensionsRapper = this.$("#blueprintDimensions") - this.$dimensions = this.$("[name=blueprint-dimensions]") - this.$units = this.$("[name=blueprint-units]") - this.$save = this.$("#saveBlueprint") - - this.map = new Map ({ type: 'ortho' }) - this.load() }, @@ -52,13 +42,6 @@ var BlueprintUploadView = UploadView.extend({ } }, - append: function(media){ - var $el = $("
    ") - $el.data("id", media._id) - $el.addClass("blueprint") - this.$blueprints.append($el) - }, - pick: function(e){ var $el = $(e.currentTarget) // load map with it @@ -112,11 +95,13 @@ var BlueprintUploadView = UploadView.extend({ add: function(media){ this.append(media) }, - changeDimensions: function(){ - }, - changeUnits: function(){ - }, - save: function(){ - }, + append: function(media){ + var $el = $("") + $el.attr("src", media.url) + $el.data("id", media._id) + $el.addClass("blueprint") + this.$blueprints.append($el) + }, + }) diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js index f7ee13e..40c61d7 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintView.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js @@ -11,7 +11,8 @@ var BlueprintView = View.extend({ // this.settings = new BuilderSettings ({ parent: this }) // this.colorControl = new ColorControl ({ parent: this }) // this.cursor = new HelpCursor({ parent: this }) - this.blueprintUpload = new BlueprintUploadView ({ parent: this }) + this.blueprintUpload = new BlueprintUpload ({ parent: this }) + this.blueprintEditor = new BlueprintEditor ({ parent: this }) }, load: function(name){ diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index bb32500..0f89242 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1598,7 +1598,7 @@ form .paidPlan label { float: none; font-size: 16px; margin: 0 10px; } .mediaDrawer.alert, .mediaDrawer.confirm, .mediaDrawer.passwordForgot, .mediaDrawer.passwordReset, .mediaDrawer.usernameTaken, .mediaDrawer.layouts, .mediaDrawer.projects, .mediaDrawer.newProject, -.mediaDrawer.blueprintUpload { +.mediaDrawer.blueprintEditor { display:table; } .confirm button { diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs new file mode 100644 index 0000000..6b80287 --- /dev/null +++ b/views/controls/blueprint/editor.ejs @@ -0,0 +1,104 @@ + + +
    +
    +
    + +
    + + + +
    + +
    + + + + +
    +
    + +
    + X +
    + +

    Upload your Blueprint

    + +
    + +
    +
    + + + +
    +
    + +
    +
    Your uploaded blueprints
    +
    +
    + + Please tell us the scale of your blueprint. + Click both corners of a wall, and then enter how long the wall is. + https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg + +
    +
    + +
    + + + + +
    + +
    +
    diff --git a/views/controls/builder/blueprint.ejs b/views/controls/builder/blueprint.ejs deleted file mode 100644 index e5f3257..0000000 --- a/views/controls/builder/blueprint.ejs +++ /dev/null @@ -1,92 +0,0 @@ - - -
    -
    -
    - -
    - - - -
    - -
    - - - - -
    - -
    - X -
    - -

    Upload A Room Image

    - -
    -
    -
    - - - -
    -
    - -
    - - Please tell us the scale of your map. - Click both corners of a wall, and then enter how long the wall is. - -
    -
    - -
    - - - - -
    - -
    -
    -
    \ No newline at end of file diff --git a/views/modal.ejs b/views/modal.ejs index 433861e..775ba88 100644 --- a/views/modal.ejs +++ b/views/modal.ejs @@ -10,7 +10,7 @@
    - [[ include controls/builder/blueprint ]] + [[ include controls/blueprint/editor ]] [[ include partials/confirm-modal ]] [[ include partials/sign-in ]] [[ include projects/layouts-modal ]] diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index 64ac135..2a93e9b 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -128,6 +128,7 @@ + -- cgit v1.2.3-70-g09d2 From d84c89a8dd770ea174a7d2ac90927046a5f4b5f6 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 11 Aug 2015 16:50:31 -0400 Subject: blueprint upload styling --- .../javascripts/rectangles/engine/map/ui/ortho.js | 4 +- .../javascripts/ui/blueprint/BlueprintEditor.js | 30 ----- .../javascripts/ui/blueprint/BlueprintScaler.js | 43 ++++++++ .../javascripts/ui/blueprint/BlueprintUpload.js | 36 ++++-- .../javascripts/ui/blueprint/BlueprintView.js | 2 +- views/controls/blueprint/editor.ejs | 122 +++++++++++++++++---- views/partials/scripts.ejs | 2 +- 7 files changed, 178 insertions(+), 61 deletions(-) delete mode 100644 public/assets/javascripts/ui/blueprint/BlueprintEditor.js create mode 100644 public/assets/javascripts/ui/blueprint/BlueprintScaler.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/engine/map/ui/ortho.js b/public/assets/javascripts/rectangles/engine/map/ui/ortho.js index 52f7339..5be7446 100644 --- a/public/assets/javascripts/rectangles/engine/map/ui/ortho.js +++ b/public/assets/javascripts/rectangles/engine/map/ui/ortho.js @@ -81,7 +81,9 @@ Map.UI.Ortho = function(map){ } base.set_tool = function(s){ console.log("set tool to", s) - base.tools[currentTool].cancel() + if (base.tools[currentTool]) { + base.tools[currentTool].cancel() + } currentTool = s tool = base.tools[currentTool] } diff --git a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js deleted file mode 100644 index 227c1c8..0000000 --- a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js +++ /dev/null @@ -1,30 +0,0 @@ - -var BlueprintEditor = ModalView.extend({ - el: ".blueprintEditor", - - events: { - "change [name=blueprint-dimensions]": "changeDimensions", - "change [name=blueprint-units]": "changeUnits", - "click #saveBlueprint": "save", - }, - - initialize: function(){ - this.$blueprintMap = this.$("#blueprintMap") - this.$blueprintDimensionsRapper = this.$("#blueprintDimensions") - this.$dimensions = this.$("[name=blueprint-dimensions]") - this.$units = this.$("[name=blueprint-units]") - this.$save = this.$("#saveBlueprint") - - this.map = new Map ({ type: 'ortho' }) - - this.$blueprintMap.append(this.map.el) - }, - - changeDimensions: function(){ - }, - changeUnits: function(){ - }, - save: function(){ - }, - -}) diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js new file mode 100644 index 0000000..e11b61e --- /dev/null +++ b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js @@ -0,0 +1,43 @@ + +var BlueprintScaler = ModalView.extend({ + el: ".blueprintScaler", + + events: { + "change [name=blueprint-dimensions]": "changeDimensions", + "change [name=blueprint-units]": "changeUnits", + "click #saveBlueprint": "save", + }, + + initialize: function(){ + this.$blueprintMap = this.$("#blueprintMap") + this.$blueprintDimensionsRapper = this.$("#blueprintDimensions") + this.$dimensions = this.$("[name=blueprint-dimensions]") + this.$units = this.$("[name=blueprint-units]") + this.$save = this.$("#saveBlueprint") + + this.map = map = new Map ({ + type: "ortho", + el: this.$blueprintMap.get(0), + width: window.innerWidth/2, + height: window.innerHeight, + zoom: -2, + zoom_min: -6.2, + zoom_max: 1, + }) + map.ui.add_tool("arrow", new ArrowTool) + map.ui.add_tool("position", new PositionTool) + map.ui.set_tool("position") + }, + + pick: function(){ + + }, + + changeDimensions: function(){ + }, + changeUnits: function(){ + }, + save: function(){ + }, + +}) diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUpload.js b/public/assets/javascripts/ui/blueprint/BlueprintUpload.js index 9467715..deb1075 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintUpload.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintUpload.js @@ -13,7 +13,8 @@ var BlueprintUpload = UploadView.extend({ "change .url": "enterUrl", "keydown .url": "enterSetUrl", - "click .blueprint": "choose", + "click .blueprint": "pick", + "click .remove": "destroy", }, initialize: function(opt){ @@ -34,25 +35,33 @@ var BlueprintUpload = UploadView.extend({ populate: function(data){ this.loaded = true if (data && data.length) { + this.$blueprints.show() data.forEach(this.append.bind(this)) - this.$(".txt").hide() + this.show() } else { - this.$(".txt").show() + this.show() } }, pick: function(e){ var $el = $(e.currentTarget) - // load map with it + var media = $el.data("media") + this.hide() + this.parent.blueprintScaler.pick(media) }, - destroy: function(_id, cb){ + destroy: function(e){ + e.stopPropagation() + var $el = $(e.currentTarget) + var _id = $el.closest(".blueprint").data("id") + $el.remove() $.ajax({ type: "delete", url: this.destroyAction, data: { _id: _id, _csrf: $("[name=_csrf]").val() } - }).complete(cb || function(){}) + }).complete(function(){ + }) }, show: function(){ @@ -93,13 +102,24 @@ var BlueprintUpload = UploadView.extend({ }, add: function(media){ + this.$blueprints.show() this.append(media) + this.hide() + this.parent.blueprintScaler.pick(media) }, append: function(media){ - var $el = $("") - $el.attr("src", media.url) + var $el = $("") + var img = new Image () + img.src = media.url + var remove = document.createElement("span") + remove.className = "remove" + remove.innerHTML = "x" + $el.data("id", media._id) + $el.data("media", media) + $el.append(img) + $el.append(remove) $el.addClass("blueprint") this.$blueprints.append($el) }, diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js index 40c61d7..a803f12 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintView.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js @@ -12,7 +12,7 @@ var BlueprintView = View.extend({ // this.colorControl = new ColorControl ({ parent: this }) // this.cursor = new HelpCursor({ parent: this }) this.blueprintUpload = new BlueprintUpload ({ parent: this }) - this.blueprintEditor = new BlueprintEditor ({ parent: this }) + this.blueprintScaler = new BlueprintScaler ({ parent: this }) }, load: function(name){ diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs index 6b80287..aec5e25 100644 --- a/views/controls/blueprint/editor.ejs +++ b/views/controls/blueprint/editor.ejs @@ -33,13 +33,88 @@ body { .hud span.active { color: #000; } .blueprintUpload { - width: 240px; + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + width: 340px; + position: absolute; + top: 50%; left: 50%; + background: white; + padding: 10px; + border: 1px solid black; + box-shadow: -3px 3px #000; + -webkit-transform: translate3D(0%,-200%,0); + transform: translate3D(0%,-200%,0); + margin-left: -175px; + margin-top: -200px; + opacity: 0; +} +.blueprintUpload.active { + -webkit-transform: translate3D(0,0,0); + transform: translate3D(0,0,0); + opacity: 1; +} +.blueprintUpload .toolButton { + float: none; + width: 108px; + display: inline-block; +} +.blueprintUpload .url { + font-size: 15px; + border: 1px solid #888; + padding: 2px; + font-weight: 300; + position: relative; + top: 3px; + margin-right: 10px; + width: 190px; +} +.blueprintUpload p { + font-weight: 300; + font-size: 13px; +} +.blueprintUpload .blueprints { + display: none; +} +.blueprintUpload .blueprints h5 { + width: 250px; + margin: 10px auto; + padding-top: 9px; } .blueprints .blueprint { border: 1px solid black; - padding: 5px; + background: white; + padding: 0px; + position: relative; + display: inline-block; +} +.blueprints .blueprint img { height: 100px; max-width: 200px; + display: block; + cursor: pointer; +} +.blueprints .blueprint .remove { + box-shadow: 0 1px 2px #888; + cursor: pointer; + position: absolute; + color: red; + top: 7px; + right: 7px; + width: 20px; height: 20px; + text-align: center; + background: #fff; + border-radius: 50%; +} +.blueprints .blueprint .remove span { + position: relative; + top: -2px; +} +.blueprintUpload .wallpaperUpload .upload-icon { + margin: 0 4px; +} +.uploadNewBlueprint { + color: #333; + border-bottom: 1px solid; cursor: pointer; } @@ -63,42 +138,49 @@ body {
    - X
    -

    Upload your Blueprint

    -
    +

    Upload your Blueprint

    +

    + Upload an image which you will trace to make a floor plan. + Images should be at least 1000x1000. +

    +
    - +
    -
    Your uploaded blueprints
    - Please tell us the scale of your blueprint. - Click both corners of a wall, and then enter how long the wall is. - https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg +
    +
    + Please tell us the scale of your blueprint. + Click both corners of a wall, and then enter how long the wall is. +

    + Do you want to upload a blueprint? +
    -
    -
    +
    +
    -
    - - +
    + + - + +
    - +
    diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index 2a93e9b..136bd4d 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -128,7 +128,7 @@ - + -- cgit v1.2.3-70-g09d2 From 554463ca8e8492bfd5f0f496e3a2291bfb495f80 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 11 Aug 2015 18:49:29 -0400 Subject: blueprint scaler stuff --- .../assets/javascripts/mx/primitives/mx.image.js | 17 ++- .../javascripts/ui/blueprint/BlueprintScaler.js | 34 +++++- .../javascripts/ui/blueprint/BlueprintUpload.js | 5 +- public/assets/stylesheets/app.css | 89 +++++++++++++++ public/assets/test/ortho4.html | 2 + views/controls/blueprint/editor.ejs | 120 +++++---------------- 6 files changed, 163 insertions(+), 104 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/mx/primitives/mx.image.js b/public/assets/javascripts/mx/primitives/mx.image.js index f9de141..33b1373 100644 --- a/public/assets/javascripts/mx/primitives/mx.image.js +++ b/public/assets/javascripts/mx/primitives/mx.image.js @@ -1,5 +1,7 @@ MX.Image = MX.Object3D.extend({ init: function (ops) { + ops = ops || {} + this.type = "Image" this.media = ops.media this.width = 0 @@ -41,15 +43,20 @@ MX.Image = MX.Object3D.extend({ layer.dirty = true layer.update() layer.ops.onload + + if (ops.keepImage) { + layer.image = image + } } - image.src = ops.src; - - if (ops.keepImage) { - this.image = image - } + + if (ops.src) image.src = ops.src + else if (ops.media) image.src = ops.media.url + else if (ops.url) image.src = ops.url }, draw: function(ctx, recenter){ + if (! this.image) { return } + if (recenter) { ctx.save() ctx.scale(-1, 1) diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js index e11b61e..a81c89b 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js @@ -18,7 +18,7 @@ var BlueprintScaler = ModalView.extend({ this.map = map = new Map ({ type: "ortho", el: this.$blueprintMap.get(0), - width: window.innerWidth/2, + width: window.innerWidth, height: window.innerHeight, zoom: -2, zoom_min: -6.2, @@ -27,10 +27,38 @@ var BlueprintScaler = ModalView.extend({ map.ui.add_tool("arrow", new ArrowTool) map.ui.add_tool("position", new PositionTool) map.ui.set_tool("position") + + scene = scene || { camera: { x: 0, y: 0, z: 0 } } + + this.floorplan = new MX.Image () + + this.animate() }, - pick: function(){ - + pick: function(media){ + this.floorplan.load({ media: media, keepImage: true }) + }, + + animate: function(t){ + requestAnimationFrame(this.animate.bind(this)) + + var dt = t - this.last_t + this.last_t = t + + if (! t) return + + this.map.update(t) + + this.map.draw.ctx.save() + this.map.draw.translate() + + this.floorplan.draw(this.map.draw.ctx, true) + + this.map.draw.coords() + + this.map.draw.mouse(this.map.ui.mouse.cursor) + + this.map.draw.ctx.restore() }, changeDimensions: function(){ diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUpload.js b/public/assets/javascripts/ui/blueprint/BlueprintUpload.js index deb1075..498575a 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintUpload.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintUpload.js @@ -36,8 +36,9 @@ var BlueprintUpload = UploadView.extend({ this.loaded = true if (data && data.length) { this.$blueprints.show() - data.forEach(this.append.bind(this)) - this.show() + data.forEach(this.append.bind(this)) + this.hide() + this.parent.blueprintScaler.pick(data[0]) } else { this.show() diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 0f89242..6507cc1 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -3253,6 +3253,95 @@ a[data-role="forgot-password"] { } +/* blueprint upload box */ + +.blueprintUpload { + -webkit-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + width: 340px; + position: absolute; + top: 50%; left: 50%; + background: white; + padding: 10px; + border: 1px solid black; + box-shadow: -3px 3px #000; + -webkit-transform: translate3D(0%,-200%,0); + transform: translate3D(0%,-200%,0); + margin-left: -175px; + margin-top: -200px; + opacity: 0; +} +.blueprintUpload.active { + -webkit-transform: translate3D(0,0,0); + transform: translate3D(0,0,0); + opacity: 1; +} +.blueprintUpload .toolButton { + float: none; + width: 108px; + display: inline-block; +} +.blueprintUpload .url { + font-size: 15px; + border: 1px solid #888; + padding: 2px; + font-weight: 300; + position: relative; + top: 3px; + margin-right: 10px; + width: 190px; +} +.blueprintUpload p { + font-weight: 300; + font-size: 13px; +} +.blueprintUpload .blueprints { + display: none; +} +.blueprintUpload .blueprints h5 { + width: 250px; + margin: 10px auto; + padding-top: 9px; +} +.blueprints .blueprint { + border: 2px solid black; + background: white; + padding: 0px; + position: relative; + display: inline-block; +} +.blueprints .blueprint img { + height: 100px; + max-width: 200px; + display: block; + cursor: pointer; +} +.blueprints .blueprint .remove { + box-shadow: -2px 2px #000; + cursor: pointer; + position: absolute; + color: red; + top: 7px; + right: 7px; + width: 20px; height: 20px; + text-align: center; + background: #fff; + border: 1px solid black; +} +.blueprints .blueprint .remove span { + position: relative; + top: -2px; +} +.blueprintUpload .wallpaperUpload .upload-icon { + margin: 0 4px; +} +.uploadNewBlueprint { + color: #333; + border-bottom: 1px solid; + cursor: pointer; +} + + /* KEYBOARD SHORTCUTS */ .keyboard { float: left; width: 50%; margin-top: 50px; } diff --git a/public/assets/test/ortho4.html b/public/assets/test/ortho4.html index 1c1adef..d704e0e 100644 --- a/public/assets/test/ortho4.html +++ b/public/assets/test/ortho4.html @@ -160,7 +160,9 @@ map.ui.placing = false $(window).resize(function(){ scene.width = window.innerWidth/2 + scene.height = window.innerHeight map.canvas.width = map.dimensions.a = window.innerWidth/2 + map.canvas.height = map.dimensions.b = window.innerHeight/2 }) var wall_height = 180 diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs index aec5e25..308b4c8 100644 --- a/views/controls/blueprint/editor.ejs +++ b/views/controls/blueprint/editor.ejs @@ -32,90 +32,20 @@ body { .hud span { color: #888; cursor: pointer; } .hud span.active { color: #000; } -.blueprintUpload { - -webkit-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - width: 340px; - position: absolute; - top: 50%; left: 50%; - background: white; - padding: 10px; - border: 1px solid black; - box-shadow: -3px 3px #000; - -webkit-transform: translate3D(0%,-200%,0); - transform: translate3D(0%,-200%,0); - margin-left: -175px; - margin-top: -200px; - opacity: 0; -} -.blueprintUpload.active { - -webkit-transform: translate3D(0,0,0); - transform: translate3D(0,0,0); - opacity: 1; -} -.blueprintUpload .toolButton { - float: none; - width: 108px; - display: inline-block; -} -.blueprintUpload .url { - font-size: 15px; - border: 1px solid #888; - padding: 2px; - font-weight: 300; - position: relative; - top: 3px; - margin-right: 10px; - width: 190px; -} -.blueprintUpload p { - font-weight: 300; +.blueprintInfo { + bottom: 14px; + left: 10px; + width: 270px; font-size: 13px; + font-weight: 300; + padding: 10px; } -.blueprintUpload .blueprints { - display: none; -} -.blueprintUpload .blueprints h5 { - width: 250px; - margin: 10px auto; - padding-top: 9px; -} -.blueprints .blueprint { - border: 1px solid black; - background: white; - padding: 0px; - position: relative; - display: inline-block; -} -.blueprints .blueprint img { - height: 100px; - max-width: 200px; - display: block; - cursor: pointer; -} -.blueprints .blueprint .remove { - box-shadow: 0 1px 2px #888; - cursor: pointer; - position: absolute; - color: red; - top: 7px; - right: 7px; - width: 20px; height: 20px; - text-align: center; - background: #fff; - border-radius: 50%; -} -.blueprints .blueprint .remove span { - position: relative; - top: -2px; -} -.blueprintUpload .wallpaperUpload .upload-icon { - margin: 0 4px; +.blueprintInfo .setting { + margin-bottom: 20px; } -.uploadNewBlueprint { - color: #333; - border-bottom: 1px solid; - cursor: pointer; +.blueprintInfo .setting.number input[type=text] { + width: 100px; + font-size: 16px; } @@ -139,7 +69,7 @@ body {
    - +

    Upload your Blueprint

    @@ -161,25 +91,27 @@ body {

    -
    +
    Please tell us the scale of your blueprint. - Click both corners of a wall, and then enter how long the wall is. + Click two corners of a wall, and then enter how long the wall is.

    - Do you want to upload a blueprint? + You can also upload another blueprint. +

    + +
    + + + +
    +
    -
    - - - - -
    -- cgit v1.2.3-70-g09d2 From dd4f0178c7bcb5d14e1308e3877c5ab02eddf000 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 12 Aug 2015 12:37:49 -0400 Subject: modify webhook to support custom plans --- .../javascripts/ui/site/EditSubscriptionModal.js | 1 + server/lib/api/subscription.js | 1 + server/lib/schemas/Subscription.js | 1 + server/lib/schemas/User.js | 1 + server/lib/views/staff/middleware.js | 2 +- server/lib/webhook/webhook.js | 24 ++++++++++++++++------ views/staff/subscriptions/index.ejs | 3 +++ 7 files changed, 26 insertions(+), 7 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 3a20234..1033114 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -96,6 +96,7 @@ var EditSubscriptionModal = ModalView.extend({ free: 0, basic: 1, pro: 2, + custom: 3, }, loaded: false, diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 9c2d6ef..c2fff4c 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -16,6 +16,7 @@ var plan_levels = { free: 0, basic: 1, pro: 2, + custom: 3, } var subscription = module.exports = { diff --git a/server/lib/schemas/Subscription.js b/server/lib/schemas/Subscription.js index 355bbe2..bf43e8b 100644 --- a/server/lib/schemas/Subscription.js +++ b/server/lib/schemas/Subscription.js @@ -9,6 +9,7 @@ var mongoose = require('mongoose'), var SubscriptionSchema = new mongoose.Schema({ user_id: { type: mongoose.Schema.ObjectId, index: true }, + plan_code: { type: String, default: "" }, plan_type: { type: String, default: "free" }, plan_period: { type: String, default: "monthly" }, diff --git a/server/lib/schemas/User.js b/server/lib/schemas/User.js index 4b6ff39..e6e7f03 100644 --- a/server/lib/schemas/User.js +++ b/server/lib/schemas/User.js @@ -55,6 +55,7 @@ var UserSchema = new mongoose.Schema({ default: "", }, + plan_code: { type: String, default: "" }, plan_level: { type: Number, default: 0 }, plan_type: { type: String, default: "free" }, last_charged: { type: Date, default: null }, diff --git a/server/lib/views/staff/middleware.js b/server/lib/views/staff/middleware.js index 5c74d0b..1ea98e9 100644 --- a/server/lib/views/staff/middleware.js +++ b/server/lib/views/staff/middleware.js @@ -40,7 +40,7 @@ var middleware = module.exports = { } if (initial) { if (initial == "?") { - criteria.username = new RegExp('^[$a-zA-Z]', "i") + criteria.username = new RegExp('^[^a-zA-Z]', "i") } else { criteria.username = new RegExp('^' + initial, "i") diff --git a/server/lib/webhook/webhook.js b/server/lib/webhook/webhook.js index 58a13ca..bd51dac 100644 --- a/server/lib/webhook/webhook.js +++ b/server/lib/webhook/webhook.js @@ -26,10 +26,11 @@ var xml_bodyparser = require('express-xml-bodyparser'); var parser = new xml2js.Parser(); var subscribe = module.exports = { - plan_level: { + plan_levels: { free: 0, basic: 1, pro: 2, + custom: 3, }, callbacks: { @@ -62,19 +63,30 @@ var subscribe = module.exports = { Subscription.findOne({ "uuid": uuid }, function(err, old_subscriber){ // if (err) return; - var plan = subscrip.plan[0].plan_code[0].split("-") - var plan_type = plan[0] - var plan_period = plan[1] + var plan, plan_type, plan_code + var plan_code = subscrip.plan[0].plan_code[0] + if (plan_code.indexOf("-") !== -1) { + plan = plan_code.split("-") + plan_type = plan[0] + plan_period = plan[1] + } + else { + plan_type = "custom" + plan_period = "monthly" + } + + user.plan_code = plan_code user.plan_type = plan_type - user.plan_level = subscribe.plan_level[plan_type] + user.plan_level = subscribe.plan_levels[plan_type] var subscriber = old_subscriber || new Subscription () subscriber.uuid = uuid subscriber.user_id = user._id + subscriber.plan_code = plan_code subscriber.plan_type = plan_type subscriber.plan_period = plan_period - subscriber.plan_level = subscribe.plan_level[plan_type] + subscriber.plan_level = subscribe.plan_levels[plan_type] subscriber.add_ons = [] var add_ons = subscrip.subscription_add_ons[0].subscription_add_on if (add_ons) { diff --git a/views/staff/subscriptions/index.ejs b/views/staff/subscriptions/index.ejs index 3efffb5..adf148c 100644 --- a/views/staff/subscriptions/index.ejs +++ b/views/staff/subscriptions/index.ejs @@ -26,6 +26,9 @@ [[- subscription.user.last_seen ]] + + [[- subscription.plan_code ]] + [[ }) ]] -- cgit v1.2.3-70-g09d2 From cc3d0bf036dc934494bf517ebae88bd8544b9b06 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 12 Aug 2015 13:27:07 -0400 Subject: add artist privilege --- .../javascripts/ui/site/EditSubscriptionModal.js | 1 + public/assets/javascripts/ui/site/StaffView.js | 23 +++++++++++++++++++++- server/lib/schemas/User.js | 1 + server/lib/views/staff/index.js | 16 ++++++++++++++- server/lib/webhook/webhook.js | 1 + views/staff/users/show.ejs | 11 ++++++++++- 6 files changed, 50 insertions(+), 3 deletions(-) (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 1033114..c1dc9f8 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -97,6 +97,7 @@ var EditSubscriptionModal = ModalView.extend({ basic: 1, pro: 2, custom: 3, + artist: 4, }, loaded: false, diff --git a/public/assets/javascripts/ui/site/StaffView.js b/public/assets/javascripts/ui/site/StaffView.js index 59649e3..97f86c2 100644 --- a/public/assets/javascripts/ui/site/StaffView.js +++ b/public/assets/javascripts/ui/site/StaffView.js @@ -5,12 +5,14 @@ var StaffView = View.extend({ "click #toggle-staff": "toggleStaff", "click #toggle-featured": "toggleFeatured", "click #toggle-stock": "toggleStock", + "click #toggle-artist": "toggleArtist", }, initialize: function() { this.$toggleStaff = $("#toggle-staff") this.$toggleFeatured = $("#toggle-featured") this.$toggleStock = $("#toggle-stock") + this.$toggleArtist = $("#toggle-artist") this.$mediaEmbed = $("#media-embed") if (this.$toggleStaff.length && this.$toggleStaff.data().isstaff) { this.$toggleStaff.html("Is Staff") @@ -21,6 +23,9 @@ var StaffView = View.extend({ if (this.$toggleStock.length && this.$toggleStock.data().stock) { this.$toggleStock.html("Layout is Stock") } + if (this.$toggleArtist.length && this.$toggleArtist.data().isartist) { + this.$toggleArtist.html("Is Artist") + } if (this.$mediaEmbed.length) { var media = this.$mediaEmbed.data() this.$mediaEmbed.html( Parser.tag( media ) ) @@ -75,7 +80,6 @@ var StaffView = View.extend({ }, toggleStock: function(){ - console.log("stock") var state = ! this.$toggleStock.data().stock $.ajax({ type: "put", @@ -93,4 +97,21 @@ var StaffView = View.extend({ }) }, + toggleArtist: function(){ + var state = ! this.$toggleArtist.data().isartist + $.ajax({ + type: "put", + dataType: "json", + url: window.location.href + "/artist", + data: { + state: state, + _csrf: $("#_csrf").val(), + }, + success: function(data){ + this.$toggleArtist.data("stock", data.state) + this.$toggleArtist.html(data.state ? "Is Artist" : "Make Artist") + $("#isArtist").html(data.state ? "yes" : "no") + }.bind(this) + }) + }, }) diff --git a/server/lib/schemas/User.js b/server/lib/schemas/User.js index e6e7f03..829b360 100644 --- a/server/lib/schemas/User.js +++ b/server/lib/schemas/User.js @@ -67,6 +67,7 @@ var UserSchema = new mongoose.Schema({ twitterName: { type: String, default: "" }, facebookUrl: { type: String, default: "" }, isStaff: { type: Boolean, default: false }, + isArtist: { type: Boolean, default: false }, subscription_id: { type: mongoose.Schema.ObjectId }, created_at: { type: Date }, updated_at: { type: Date }, diff --git a/server/lib/views/staff/index.js b/server/lib/views/staff/index.js index 6a56238..033fc88 100644 --- a/server/lib/views/staff/index.js +++ b/server/lib/views/staff/index.js @@ -75,7 +75,15 @@ var staff = module.exports = { staff.users.bless ); - + app.put('/staff/users/:username/artist', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + staff.middleware.ensureProfile, + + staff.users.make_artist + ); + if (app.get('env') === 'development') { app.get('/staff/authorize', middleware.ensureAuthenticated, @@ -304,6 +312,12 @@ var staff = module.exports = { res.json({ state: user.isStaff }) }) }, + make_artist: function(req, res){ + res.locals.profile.isArtist = req.body.state == "true" + res.locals.profile.save(function(err, user){ + res.json({ state: user.isArtist }) + }) + }, }, // /staff/projects/ diff --git a/server/lib/webhook/webhook.js b/server/lib/webhook/webhook.js index bd51dac..896d836 100644 --- a/server/lib/webhook/webhook.js +++ b/server/lib/webhook/webhook.js @@ -31,6 +31,7 @@ var subscribe = module.exports = { basic: 1, pro: 2, custom: 3, + artist: 4, }, callbacks: { diff --git a/views/staff/users/show.ejs b/views/staff/users/show.ejs index e441109..a434b57 100644 --- a/views/staff/users/show.ejs +++ b/views/staff/users/show.ejs @@ -35,7 +35,7 @@ plan - [[- profile.plan_type ]] + [[- profile.plan_code ]] @@ -101,12 +101,21 @@ [[- profile.isStaff ? "yes" : "no" ]] + + + is artist? + + + [[- profile.isArtist ? "yes" : "no" ]] + +

    [[ if (String(user._id) != String(profile._id)) { ]] + [[ } ]]
    -- cgit v1.2.3-70-g09d2 From 9ba29a587bf0722db82e5caf1b1cf4e5596003b6 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 12 Aug 2015 18:38:12 -0400 Subject: functioning blueprint scaler --- .../javascripts/rectangles/engine/map/draw.js | 2 +- .../rectangles/engine/map/tools/line.js | 49 ++++++++++++ .../assets/javascripts/rectangles/models/rect.js | 6 ++ .../javascripts/ui/blueprint/BlueprintScaler.js | 91 ++++++++++++++++++++-- .../javascripts/ui/blueprint/BlueprintView.js | 3 + server/lib/schemas/Layout.js | 1 + views/controls/blueprint/editor.ejs | 4 +- views/partials/scripts.ejs | 1 + 8 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 public/assets/javascripts/rectangles/engine/map/tools/line.js (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/rectangles/engine/map/draw.js b/public/assets/javascripts/rectangles/engine/map/draw.js index 11ba3f8..cc2f4d8 100644 --- a/public/assets/javascripts/rectangles/engine/map/draw.js +++ b/public/assets/javascripts/rectangles/engine/map/draw.js @@ -198,7 +198,7 @@ Map.Draw = function(map, opt){ // - function line (x,y,a,b,translation){ + var line = draw.line = function (x,y,a,b,translation){ if (translation) { x += translation.a a += translation.a diff --git a/public/assets/javascripts/rectangles/engine/map/tools/line.js b/public/assets/javascripts/rectangles/engine/map/tools/line.js new file mode 100644 index 0000000..8f409a8 --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/map/tools/line.js @@ -0,0 +1,49 @@ +var LineTool = MapTool.extend(function(base){ + var exports = {} + + var selected_point = null + + var line = exports.line = [] + + var can_drag, dragging + + exports.down = function(e, cursor){ + this.cursor = cursor + switch (line.length) { + case 0: + line[0] = cursor.x_component() + can_drag = true + break + case 1: + line[1] = cursor.x_component() + can_drag = false + break + case 2: + line[0] = cursor.x_component() + line.pop() + can_drag = true + break + } + } + + exports.move = function(e, cursor){ + this.cursor = cursor + } + + exports.drag = function(e, cursor){ + if (dragging) { + line[1].a = cursor.x.b + line[1].b = cursor.y.b + } + else if (can_drag && cursor.magnitude() > 10/map.zoom) { + line[1] = cursor.y_component() + dragging = true + } + } + + exports.up = function(e, cursor){ + can_drag = dragging = false + } + + return exports +}) \ No newline at end of file diff --git a/public/assets/javascripts/rectangles/models/rect.js b/public/assets/javascripts/rectangles/models/rect.js index c667cf5..92c8c9e 100644 --- a/public/assets/javascripts/rectangles/models/rect.js +++ b/public/assets/javascripts/rectangles/models/rect.js @@ -39,6 +39,12 @@ Rect.prototype.clone = function(){ return new Rect( this.x.clone(), this.y.clone() ) } + Rect.prototype.x_component = function(){ + return new vec2( this.x.a, this.y.a ) + } + Rect.prototype.y_component = function(){ + return new vec2( this.x.b, this.y.b ) + } Rect.prototype.assign = function(r) { this.x.assign(r.x) this.y.assign(r.y) diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js index a81c89b..addf9a9 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js @@ -1,10 +1,13 @@ -var BlueprintScaler = ModalView.extend({ +var BlueprintScaler = ModalFormView.extend({ el: ".blueprintScaler", + method: "/api/media/scale", + events: { "change [name=blueprint-dimensions]": "changeDimensions", "change [name=blueprint-units]": "changeUnits", + "click .uploadNewBlueprint": "showBlueprintUpload", "click #saveBlueprint": "save", }, @@ -12,6 +15,7 @@ var BlueprintScaler = ModalView.extend({ this.$blueprintMap = this.$("#blueprintMap") this.$blueprintDimensionsRapper = this.$("#blueprintDimensions") this.$dimensions = this.$("[name=blueprint-dimensions]") + this.$pixels = this.$("[name=blueprint-pixels]") this.$units = this.$("[name=blueprint-units]") this.$save = this.$("#saveBlueprint") @@ -24,23 +28,40 @@ var BlueprintScaler = ModalView.extend({ zoom_min: -6.2, zoom_max: 1, }) - map.ui.add_tool("arrow", new ArrowTool) - map.ui.add_tool("position", new PositionTool) - map.ui.set_tool("position") + this.lineTool = new LineTool + map.ui.add_tool("line", this.lineTool) + map.ui.set_tool("line") scene = scene || { camera: { x: 0, y: 0, z: 0 } } this.floorplan = new MX.Image () - this.animate() + this.animating = false + }, + + showBlueprintUpload: function(){ + this.parent.blueprintUpload.show() }, pick: function(media){ + this.media = media + + if (!! media.scale) { + this.parent.useFloorplan(media) + } + this.floorplan.load({ media: media, keepImage: true }) + + if (! this.animating) { + this.animating = true + this.animate() + } }, animate: function(t){ requestAnimationFrame(this.animate.bind(this)) + + if (! this.animating) return var dt = t - this.last_t this.last_t = t @@ -53,6 +74,27 @@ var BlueprintScaler = ModalView.extend({ this.map.draw.translate() this.floorplan.draw(this.map.draw.ctx, true) + + this.map.draw.ctx.strokeStyle = "#f00" + this.map.draw.ctx.lineWidth = 2/map.zoom + switch (this.lineTool.line.length) { + case 1: + this.map.draw.line( + this.lineTool.line[0].a, + this.lineTool.line[0].b, + this.lineTool.cursor.x.a, + this.lineTool.cursor.y.a + ) + break + case 2: + this.map.draw.line( + this.lineTool.line[0].a, + this.lineTool.line[0].b, + this.lineTool.line[1].a, + this.lineTool.line[1].b + ) + break + } this.map.draw.coords() @@ -62,10 +104,47 @@ var BlueprintScaler = ModalView.extend({ }, changeDimensions: function(){ + app.units = this.$units.val() + this.$dimensions.unitVal() }, changeUnits: function(){ + app.units = this.$units.val() + this.$dimensions.resetUnitVal() + }, + lineLength: function(){ + if (this.lineTool.line.length !== 2) return 0 + var line = this.lineTool.line + return dist( line[0].a, line[0].b, line[1].a, line[1].b ) + } + + validate: function(){ + var val = this.$dimensions.unitVal() + var errors = [] + if (! this.lineLength()) { + errors.push("no line") + alert("Please click two corners of a wall and then specify how long it is in feet or meters.") + } + else if (val == 0) { + errors.push("no measurement") + alert("Please tell us how long the wall is in feet or meters.") + } + return errors }, - save: function(){ + + showErrors: function(){}, + + serialize: function(){ + var fd = new FormData() + fd.append( "_id", this.media._id) + fd.append( "units", this.$units.val() ) + fd.append( "scale", this.$dimensions.unitVal() / this.lineLength() ) + fd.append( "_csrf", $("[name=_csrf]").val()) + return fd + }, + + success: function(){ + this.animating = false + this.parent.useFloorplan(media) }, }) diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js index a803f12..6b204e5 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintView.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js @@ -33,6 +33,9 @@ var BlueprintView = View.extend({ hideExtras: function(){ }, + + useFloorplan: function(media){ + }, pickWall: function(wall, pos){ }, diff --git a/server/lib/schemas/Layout.js b/server/lib/schemas/Layout.js index cff1d78..e15e188 100644 --- a/server/lib/schemas/Layout.js +++ b/server/lib/schemas/Layout.js @@ -23,6 +23,7 @@ var LayoutSchema = new mongoose.Schema({ photo: { type: String, }, + media: mongoose.Schema.Types.Mixed, rooms: [mongoose.Schema.Types.Mixed], startPosition: mongoose.Schema.Types.Mixed, viewHeight: { type: Number }, diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs index 308b4c8..3e0c097 100644 --- a/views/controls/blueprint/editor.ejs +++ b/views/controls/blueprint/editor.ejs @@ -99,8 +99,8 @@ body {

    - - + + - -
    - +
    +
    + + + +
    + +
    -- cgit v1.2.3-70-g09d2 From 6b3d07293bf674703b286cb396049fb8e83b86b7 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 14 Aug 2015 16:37:39 -0400 Subject: AnimatedView --- .../javascripts/ui/blueprint/BlueprintScaler.js | 29 ++++----------- public/assets/javascripts/ui/lib/AnimatedView.js | 31 ++++++++++++++++ views/blueprint.ejs | 33 +++++++++++++++++ views/builder.ejs | 16 -------- views/controls/blueprint/editor.ejs | 43 ++++++++++------------ views/modal.ejs | 1 - views/partials/scripts.ejs | 1 + 7 files changed, 93 insertions(+), 61 deletions(-) create mode 100644 public/assets/javascripts/ui/lib/AnimatedView.js create mode 100644 views/blueprint.ejs (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js index c393cfb..741f4fb 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js @@ -1,5 +1,5 @@ -var BlueprintScaler = ModalFormView.extend({ +var BlueprintScaler = ModalFormView.extend(AnimatedView.prototype).extend({ el: ".blueprintScaler", action: "/api/media/scale", @@ -20,7 +20,7 @@ var BlueprintScaler = ModalFormView.extend({ this.$units = this.$("[name=blueprint-units]") this.$save = this.$("#saveBlueprint") - this.map = map = new Map ({ + this.map = new Map ({ type: "ortho", el: this.$blueprintMap.get(0), width: window.innerWidth, @@ -30,14 +30,12 @@ var BlueprintScaler = ModalFormView.extend({ zoom_max: 1, }) this.lineTool = new LineTool - map.ui.add_tool("line", this.lineTool) - map.ui.set_tool("line") + this.map.ui.add_tool("line", this.lineTool) + this.map.ui.set_tool("line") scene = scene || { camera: { x: 0, y: 0, z: 0 } } this.floorplan = new MX.Image () - - this.animating = false }, showBlueprintUpload: function(){ @@ -50,27 +48,16 @@ var BlueprintScaler = ModalFormView.extend({ if (!! media.units) { this.parent.useFloorplan(media) this.hide() + this.stopAnimating() return } this.floorplan.load({ media: media, keepImage: true }) - if (! this.animating) { - this.animating = true - this.animate() - } + this.startAnimating() }, - animate: function(t){ - requestAnimationFrame(this.animate.bind(this)) - - if (! this.animating) return - - var dt = t - this.last_t - this.last_t = t - - if (! t) return - + animate: function(t, dt){ this.map.update(t) this.map.draw.ctx.save() @@ -147,7 +134,7 @@ var BlueprintScaler = ModalFormView.extend({ }, success: function(){ - this.animating = false + this.stopAnimating() this.parent.useFloorplan(this.media) this.hide() }, diff --git a/public/assets/javascripts/ui/lib/AnimatedView.js b/public/assets/javascripts/ui/lib/AnimatedView.js new file mode 100644 index 0000000..3c50b0a --- /dev/null +++ b/public/assets/javascripts/ui/lib/AnimatedView.js @@ -0,0 +1,31 @@ +var AnimatedView = View.extend({ + + _animating: false, + last_t: 0, + + startAnimating: function(){ + if (this._animating) return + this._animating = true + this._animate() + }, + + stopAnimating: function(){ + this._animating = false + }, + + _animate: function(t){ + if (! this._animating) return + + requestAnimationFrame(this._animate.bind(this)) + + var dt = t - this.last_t + this.last_t = t + + if (! t) return + + this.animate(t, dt) + }, + + animate: function(t, dt){}, + +}) \ No newline at end of file diff --git a/views/blueprint.ejs b/views/blueprint.ejs new file mode 100644 index 0000000..371d66f --- /dev/null +++ b/views/blueprint.ejs @@ -0,0 +1,33 @@ + + + + VValls + [[ include partials/meta ]] + + + +
    + +
    + [[ include partials/header ]] + +
    + [[ include controls/builder/info ]] + [[ include controls/builder/toolbar ]] + [[ include controls/builder/settings ]] + [[ include controls/blueprint/editor ]] +
    + +
    +
    +
    +
    +
    + + [[ include partials/confirm-modal ]] + [[ include projects/layouts-modal ]] + [[ include partials/sign-in ]] + + +[[ include partials/scripts ]] + diff --git a/views/builder.ejs b/views/builder.ejs index 0ba4238..6a31e22 100644 --- a/views/builder.ejs +++ b/views/builder.ejs @@ -17,22 +17,6 @@ [[ include controls/builder/settings ]]
    - -
    diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs index 77c958a..e18f501 100644 --- a/views/controls/blueprint/editor.ejs +++ b/views/controls/blueprint/editor.ejs @@ -67,7 +67,7 @@ body {
    -
    +
    @@ -90,30 +90,27 @@ body {
    -
    -
    - Please tell us the scale of your blueprint. - Click two corners of a wall, and then enter how long the wall is. -

    - You can also upload another blueprint. -

    +
    + Please tell us the scale of your blueprint. + Click two corners of a wall, and then enter how long the wall is. +

    + You can also upload another blueprint. +

    -
    -
    - - - -
    - -
    -
    +
    +
    + + + +
    + +
    +
    -
    -
    - +
    diff --git a/views/modal.ejs b/views/modal.ejs index 775ba88..dfc5573 100644 --- a/views/modal.ejs +++ b/views/modal.ejs @@ -10,7 +10,6 @@
    - [[ include controls/blueprint/editor ]] [[ include partials/confirm-modal ]] [[ include partials/sign-in ]] [[ include projects/layouts-modal ]] diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index a0222b5..e0024a4 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -102,6 +102,7 @@ + -- cgit v1.2.3-70-g09d2 From 599b43df07f092b35d25e7adac11db3c3b3d9c76 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 17 Aug 2015 12:23:39 -0400 Subject: BlueprintEditor --- public/assets/javascripts/ui/_router.js | 7 +- .../javascripts/ui/blueprint/BlueprintEditor.js | 155 +++++++++++++++++++++ .../javascripts/ui/blueprint/BlueprintView.js | 18 +-- server/index.js | 3 + server/lib/views/index.js | 4 + views/blueprint.ejs | 1 + views/controls/blueprint/editor.ejs | 53 ------- views/controls/blueprint/scaler.ejs | 48 +++++++ views/partials/scripts.ejs | 1 + 9 files changed, 227 insertions(+), 63 deletions(-) create mode 100644 public/assets/javascripts/ui/blueprint/BlueprintEditor.js create mode 100644 views/controls/blueprint/scaler.ejs (limited to 'public/assets/javascripts/ui') diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index 857377c..177e86f 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -38,6 +38,9 @@ var SiteRouter = Router.extend({ "/layout": 'layoutPicker', "/layout/:name": 'layoutEditor', + "/blueprint": 'blueprintEditor', + "/blueprint/:name": 'blueprintEditor', + "/project": 'projectPicker', "/project/new": 'newProject', "/project/new/:layout": 'projectNewWithLayout', @@ -160,13 +163,13 @@ var SiteRouter = Router.extend({ this.readerView.load(name) }, - blueprintEditor: function(e){ + blueprintEditor: function(e, name){ environment.init = environment.minimal app.launch() if (app.unsupported) return this.blueprintView = app.controller = new BlueprintView () - this.blueprintView.load() + this.blueprintView.load(name) }, signup: function(e){ diff --git a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js new file mode 100644 index 0000000..c781495 --- /dev/null +++ b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js @@ -0,0 +1,155 @@ + +var wall_height = 180 +var shapes = new ShapeList +var last_point = new vec2 (0,0) + +var BlueprintEditor = View.extend(AnimatedView.prototype).extend({ + + initialize: function(opt){ + this.parent = opt.parent + + map = new Map ({ + type: "ortho", + el: document.querySelector("#orthographic"), + width: window.innerWidth/2, + height: window.innerHeight, + zoom: -2, + zoom_min: -6.2, + zoom_max: 1, + }) + map.ui.add_tool("arrow", new ArrowTool) + map.ui.add_tool("polyline", new PolylineTool) + map.ui.add_tool("ortho-polyline", new OrthoPolylineTool) + map.ui.add_tool("eraser", new EraserTool) + map.ui.add_tool("position", new PositionTool) + map.ui.placing = false + +/* + $(window).resize(function(){ + scene.width = window.innerWidth/2 + scene.height = window.innerHeight + map.canvas.width = map.dimensions.a = window.innerWidth/2 + map.canvas.height = map.dimensions.b = window.innerHeight/2 + }) +*/ + + var PerspectiveToolbar = new Toolbar (".persp-hud") + PerspectiveToolbar.add("orbit-mode", function(){ + controls.toggle(true) + movements.lock() + }) + PerspectiveToolbar.add("keyboard-mode", function(){ + controls.toggle(false) + movements.unlock() + movements.gravity(true) + cam.rotationX = 0 + cam.rotationY = -cam.rotationY + cam.x = 0 + cam.y = viewHeight + 100 + cam.z = 0 + }) + + var OrthographicToolbar = new Toolbar (".ortho-hud") + OrthographicToolbar.add("arrow-mode", function(){ + map.ui.set_tool("arrow") + }) + OrthographicToolbar.add("polyline-mode", function(){ + map.ui.set_tool("polyline") + }) + OrthographicToolbar.add("ortho-polyline-mode", function(){ + map.ui.set_tool("ortho-polyline") + }) + OrthographicToolbar.add("eraser-mode", function(){ + map.ui.set_tool("eraser") + }) + OrthographicToolbar.pick("ortho-polyline-mode") + }, + + animate: function(t, dt){ + map.update(t) + + movements.update(dt) + controls.update() + scene.update() + + map.draw.ctx.save() + map.draw.translate() + + floorplan.draw(map.draw.ctx, true) + + map.draw.coords() + + if (shapes.workline) { + shapes.workline.draw(map.draw.ctx) + if (map.ui.placing && last_point) { + shapes.workline.draw_line( map.draw.ctx, last_point ) + } + } + + shapes.forEach(function(shape){ + shape.draw(map.draw.ctx) + }) + + map.draw.ctx.strokeStyle = "#f00"; + map.draw.x_at(0,0) + map.draw.mouse(map.ui.mouse.cursor) + map.draw.camera(scene.camera) + + map.draw.ctx.restore() + }, + +}) + +function build () { + scene = new MX.Scene().addTo("#perspective") + scene.camera.radius = 20 + + viewHeight = 100 + + scene.width = window.innerWidth/2 + scene.height = window.innerHeight + scene.perspective = window.innerHeight + + cam = scene.camera + movements = new MX.Movements(cam, viewHeight) + movements.init() + movements.lock() + movements.velocity(8) + app.on("move", function(pos){ + cam.x = pos.x + cam.y = pos.y + cam.z = pos.z + }) + + floorplan = new MX.Image({ + src: "https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg", + keepImage: true, + rotationX: -PI/2, + rotationY: PI, + }) + scene.add(floorplan) + + // recenter perspective view by rightclicking map + floorplan.el.addEventListener("contextmenu", function(e){ + e.preventDefault() + var offset = offsetFromPoint(e, this) + var x = (offset.left - 0.5) * floorplan.width * floorplan.scale + var z = (offset.top - 0.5) * floorplan.height * floorplan.scale + controls.opt.center.x = -x + controls.opt.center.y = 0 + controls.opt.center.z = -z + }, true) + + scene.update() + + controls = new MX.OrbitCamera({ + el: scene.el, + radius: 3000, + radiusRange: [ 10, 10000 ], + rotationX: PI/4, + rotationY: PI/2, + }) + controls.init() + + animate(0) +} diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js index 6b204e5..0a06fda 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintView.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js @@ -1,7 +1,9 @@ var BlueprintView = View.extend({ el: "#blueprintView", - + + action: "/api/layout/", + events: { }, @@ -16,14 +18,14 @@ var BlueprintView = View.extend({ }, load: function(name){ -// if (! name || name == "new") { + if (! name || name == "new") { // this.ready({ isNew: true, _id: "new", name: "" }) -// return -// } -// -// name = sanitize(name) -// -// $.get(this.action + name, this.ready.bind(this)) + return + } + + name = sanitize(name) + + $.get(this.action + name, this.ready.bind(this)) }, ready: function(data){ diff --git a/server/index.js b/server/index.js index 0028888..078db8e 100644 --- a/server/index.js +++ b/server/index.js @@ -127,6 +127,9 @@ site.route = function () { app.get('/layout', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.modal) app.get('/layout/:name', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.builder) + app.get('/blueprint', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.blueprint) + app.get('/blueprint/:name', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.blueprint) + app.get('/join/:nonce', middleware.ensureAuthenticated, api.collaborator.join) app.get('/api/collaborator/:slug/index', middleware.ensureAuthenticated, middleware.ensureProject, api.collaborator.index) app.post('/api/collaborator/:slug/create', middleware.ensureAuthenticated, middleware.ensureProject, api.collaborator.create) diff --git a/server/lib/views/index.js b/server/lib/views/index.js index 5241ddb..523f628 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -84,6 +84,10 @@ var views = module.exports = { res.render('builder') }, + blueprint: function (req, res) { + res.render('blueprint') + }, + modal: function (req, res) { res.render('modal'); }, diff --git a/views/blueprint.ejs b/views/blueprint.ejs index 371d66f..7e13318 100644 --- a/views/blueprint.ejs +++ b/views/blueprint.ejs @@ -16,6 +16,7 @@ [[ include controls/builder/toolbar ]] [[ include controls/builder/settings ]] [[ include controls/blueprint/editor ]] + [[ include controls/blueprint/scaler ]]
    diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs index e18f501..5334f85 100644 --- a/views/controls/blueprint/editor.ejs +++ b/views/controls/blueprint/editor.ejs @@ -1,8 +1,4 @@