From 598c4445ffc041de786bf8c1764d0371a59b5ccb Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Tue, 10 Sep 2013 18:06:16 -0400 Subject: [PATCH] [#1396] setup tour, using user.flags.showTour now instead of localStorage. double check with #1507 --- Gruntfile.js | 2 + archive/derby_controllers/browser.coffee | 57 -------------------- public/js/app.js | 2 +- public/js/controllers/notificationCtrl.js | 4 +- public/js/services/guideServices.js | 66 +++++++++++++++++++++++ src/models/user.js | 17 +++--- views/index.jade | 4 +- 7 files changed, 84 insertions(+), 68 deletions(-) create mode 100644 public/js/services/guideServices.js diff --git a/Gruntfile.js b/Gruntfile.js index 54dc3ab9ca..ce422bda48 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -40,6 +40,7 @@ module.exports = function(grunt) { 'public/js/services/userServices.js', 'public/js/services/groupServices.js', 'public/js/services/memberServices.js', + 'public/js/services/guideServices.js', 'public/js/filters/filters.js', @@ -103,6 +104,7 @@ module.exports = function(grunt) { 'build/bower_components/habitrpg-shared/dist/spritesheets.css': ['public/bower_components/habitrpg-shared/dist/spritesheets.css'], 'build/bower_components/bootstrap/docs/assets/css/bootstrap.css': ['public/bower_components/bootstrap/docs/assets/css/bootstrap.css'], 'build/bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css': ['public/bower_components/bootstrap/docs/assets/css/bootstrap-responsive.css'], + 'build/bower_components/bootstrap-tour/build/css/bootstrap-tour.min.css': ['public/bower_components/bootstrap-tour/build/css/bootstrap-tour.min.css'], 'build/bower_components/bootstrap/docs/assets/css/docs.css': ['public/bower_components/bootstrap/docs/assets/css/docs.css'] } } diff --git a/archive/derby_controllers/browser.coffee b/archive/derby_controllers/browser.coffee index ddee1cad13..5efa078558 100644 --- a/archive/derby_controllers/browser.coffee +++ b/archive/derby_controllers/browser.coffee @@ -16,7 +16,6 @@ loadJavaScripts = (model) -> ### require "../vendor/jquery.cookie.min.js" require "../vendor/bootstrap/js/bootstrap.min.js" - require "../vendor/jquery.bootstrap-growl.min.js" require "../vendor/datepicker/js/bootstrap-datepicker" require "../vendor/bootstrap-tour/bootstrap-tour" @@ -26,66 +25,11 @@ loadJavaScripts = (model) -> # note: external script loading is handled in app.on('render') near the bottom of this file (see https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/x8FwdTLEuXo) -setupTooltips = module.exports.setupTooltips = -> - $('.popover-auto-show').popover('show') - -setupTour = (model) -> - tourSteps = [ - { - element: ".main-herobox" - title: "Welcome to HabitRPG" - content: "Welcome to HabitRPG, a habit-tracker which treats your goals like a Role Playing Game." - } - { - element: "#bars" - title: "Achieve goals and level up" - content: "As you accomplish goals, you level up. If you fail your goals, you lose hit points. Lose all your HP and you die." - } - { - element: "ul.habits" - title: "Habits" - content: "Habits are goals that you constantly track." - placement: "bottom" - } - { - element: "ul.dailys" - title: "Dailies" - content: "Dailies are goals that you want to complete once a day." - placement: "bottom" - } - { - element: "ul.todos" - title: "Todos" - content: "Todos are one-off goals which need to be completed eventually." - placement: "bottom" - } - { - element: "ul.rewards" - title: "Rewards" - content: "As you complete goals, you earn gold to buy rewards. Buy them liberally - rewards are integral in forming good habits." - placement: "bottom" - } - { - element: "ul.habits li:first-child" - title: "Hover over comments" - content: "Different task-types have special properties. Hover over each task's comment for more information. When you're ready to get started, delete the existing tasks and add your own." - placement: "right" - } - ] - - $('.main-herobox').popover('destroy') #remove previous popovers - tour = new Tour() - tourSteps.forEach (step) -> tour.addStep _.defaults step, {html:true} - tour._current = 0 if isNaN(tour._current) #bootstrap-tour bug - tour.start() - - # jquery sticky header on scroll, no need for position fixed initStickyHeader = (model) -> $('.header-wrap').sticky({topSpacing:0}) - module.exports.app = (appExports, model, app) -> app.on 'render', (ctx) -> @@ -94,7 +38,6 @@ module.exports.app = (appExports, model, app) -> setupTooltips(model) initStickyHeader(model) setupSortable(model) - setupTour(model) $('.datepicker').datepicker({autoclose:true, todayBtn:true}) .on 'changeDate', (ev) -> diff --git a/public/js/app.js b/public/js/app.js index 8b2ceb2715..3ae6e6e098 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,7 +1,7 @@ "use strict"; window.habitrpg = angular.module('habitrpg', - ['ngRoute', 'ngResource', 'ngSanitize', 'userServices', 'groupServices', 'memberServices', 'sharedServices', 'authServices', 'notificationServices', 'ui.bootstrap', 'ui.keypress']) + ['ngRoute', 'ngResource', 'ngSanitize', 'userServices', 'groupServices', 'memberServices', 'sharedServices', 'authServices', 'notificationServices', 'guideServices', 'ui.bootstrap', 'ui.keypress']) .constant("API_URL", "") .constant("STORAGE_USER_ID", 'habitrpg-user') diff --git a/public/js/controllers/notificationCtrl.js b/public/js/controllers/notificationCtrl.js index 1026bbce91..d32d9db0bd 100644 --- a/public/js/controllers/notificationCtrl.js +++ b/public/js/controllers/notificationCtrl.js @@ -1,7 +1,9 @@ 'use strict'; habitrpg.controller('NotificationCtrl', - ['$scope', '$rootScope', 'User', function ($scope, $rootScope, User) { + ['$scope', '$rootScope', 'User', 'Guide', function ($scope, $rootScope, User, Guide) { + + Guide.initTour(); function growlNotification(html, type) { $.bootstrapGrowl(html, { diff --git a/public/js/services/guideServices.js b/public/js/services/guideServices.js new file mode 100644 index 0000000000..8852307b06 --- /dev/null +++ b/public/js/services/guideServices.js @@ -0,0 +1,66 @@ +'use strict'; + +/** + * Services for each tour step when you unlock features + */ + +angular.module('guideServices', []). + factory('Guide', ['User', function(User) { + + var initTour = function() { + if (User.user.flags.showTour === false) return; + var tourSteps = [ + { + element: ".main-herobox", + title: "Welcome to HabitRPG", + content: "Welcome to HabitRPG, a habit-tracker which treats your goals like a Role Playing Game." + }, { + element: "#bars", + title: "Achieve goals and level up", + content: "As you accomplish goals, you level up. If you fail your goals, you lose hit points. Lose all your HP and you die." + }, { + element: "ul.habits", + title: "Habits", + content: "Habits are goals that you constantly track.", + placement: "bottom" + }, { + element: "ul.dailys", + title: "Dailies", + content: "Dailies are goals that you want to complete once a day.", + placement: "bottom" + }, { + element: "ul.todos", + title: "Todos", + content: "Todos are one-off goals which need to be completed eventually.", + placement: "bottom" + }, { + element: "ul.rewards", + title: "Rewards", + content: "As you complete goals, you earn gold to buy rewards. Buy them liberally - rewards are integral in forming good habits.", + placement: "bottom" + }, { + element: "ul.habits li:first-child", + title: "Hover over comments", + content: "Different task-types have special properties. Hover over each task's comment for more information. When you're ready to get started, delete the existing tasks and add your own.", + placement: "right" + } + ]; + $('.main-herobox').popover('destroy'); + var tour = new Tour({ + onEnd: function(){ + User.log({op:'set',data:{'flags.showTour':false}}); + } + }); + tourSteps.forEach(function(step) { + tour.addStep(_.defaults(step, {html: true})); + }); + tour.restart(); // Tour doesn't quite mesh with our handling of flags.showTour, just restart it on page load + //tour.start(true); + }; + + return { + initTour: initTour + } + + } +]); diff --git a/src/models/user.js b/src/models/user.js index dac9b74747..7f32ba1f69 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -60,14 +60,15 @@ var UserSchema = new Schema({ filters: {type: Schema.Types.Mixed, 'default': {}}, flags: { - ads: String, - dropsEnabled: Boolean, - itemsEnabled: Boolean, - newStuff: String, //FIXME to boolean (currently show/hide) - rewrite: Boolean, - partyEnabled: Boolean, - petsEnabled: Boolean, - rest: Boolean // fixme - change to preferences.resting once we're off derby + showTour: {type: Boolean, 'default': true}, + ads: {type: String, 'default': 'show'}, // FIXME make this a boolean, run migration + dropsEnabled: {type: Boolean, 'default': false}, + itemsEnabled: {type: Boolean, 'default': false}, + newStuff: {type: String, 'default': 'hide'}, //FIXME to boolean (currently show/hide) + rewrite: {type: Boolean, 'default': true}, + partyEnabled: Boolean, // FIXME do we need this? + petsEnabled: {type: Boolean, 'default': false}, + rest: {type: Boolean, 'default': false} // fixme - change to preferences.resting once we're off derby }, history: { exp: [ diff --git a/views/index.jade b/views/index.jade index 33d3f8212a..7e7cc338a4 100644 --- a/views/index.jade +++ b/views/index.jade @@ -16,7 +16,7 @@ html // CSS Remember to update also in Grunfile.js cssmin task! link(rel='stylesheet', href='/#{env.getBuildUrl("bower_components/bootstrap/docs/assets/css/bootstrap.css")}') - + link(rel='stylesheet', href='/#{env.getBuildUrl("app.css")}') // HabitRPG Shared @@ -28,6 +28,7 @@ html // Remember to update the file list in Gruntfile.js! script(type='text/javascript', src='/bower_components/jquery/jquery.min.js') script(type='text/javascript', src='/bower_components/bootstrap-growl/jquery.bootstrap-growl.min.js') + script(type='text/javascript', src='/bower_components/bootstrap-tour/build/js/bootstrap-tour.min.js') script(type='text/javascript', src='/bower_components/angular/angular.min.js') script(type='text/javascript', src='/bower_components/angular-sanitize/angular-sanitize.min.js') @@ -56,6 +57,7 @@ html script(type='text/javascript', src='/js/services/userServices.js') script(type='text/javascript', src='/js/services/groupServices.js') script(type='text/javascript', src='/js/services/memberServices.js') + script(type='text/javascript', src='/js/services/guideServices.js') script(type='text/javascript', src='/js/filters/filters.js')