FeedBunch-app/app/assets/javascripts/ng-services/ng-TourSvc.js.coffee.erb
########################################################
# AngularJS service to show application tours
########################################################
angular.module('feedbunch').service 'tourSvc',
['$rootScope', '$timeout', 'csrfTokenSvc', 'timerFlagSvc',
($rootScope, $timeout, csrfTokenSvc, timerFlagSvc)->
#--------------------------------------------
# Media query to show the main app tour only in screens bigger than a smartphone
#--------------------------------------------
sm_min_media_query = 'screen and (min-width: 768px)'
#--------------------------------------------
# Media query to show the mobile app tour only in smartphone-sized screens
#--------------------------------------------
xs_max_media_query = 'screen and (max-width: 768px)'
# Constants for the different tour URL fragments
TOURS = {main_tour: 'main', mobile_tour: 'mobile', feed_tour: 'feed', entry_tour: 'entry', kb_shortcuts_tour: 'kb_shortcuts'}
# Constants for the different operations the web worker can perform
LOAD_TOUR = 'load_tour'
HIDE_TOUR = 'hide_tour'
RESET_TOURS = 'reset_tours'
# CSRF token
token = csrfTokenSvc.get_token()
# Web worker to load or hide tours
worker = new Worker '<%= asset_path 'workers/tours_worker' %>'
worker.onmessage = (e) ->
if e.data.status == 200 || e.data.status == 304
if e.data.operation == LOAD_TOUR
tour_loaded e.data.response
else if e.data.operation == RESET_TOURS
timerFlagSvc.start 'success_reset_tours'
else if e.data.status == 401 || e.data.status == 422
$window.location.href = '/login'
else
if e.data.operation == LOAD_TOUR
timerFlagSvc.start 'error_loading_tour'
else if e.data.operation == HIDE_TOUR
timerFlagSvc.start 'error_changing_show_tour'
else if e.data.operation == RESET_TOURS
timerFlagSvc.start 'error_changing_show_tour'
$rootScope.$digest()
#--------------------------------------------
# PRIVATE FUNCTION: Operations after a tour has been loaded
#--------------------------------------------
tour_loaded = (response)->
if response.tour == TOURS.main_tour
delay = 0
tour =
id: 'main-tour',
onEnd: main_tour_end,
onClose: main_tour_end
else if response.tour == TOURS.mobile_tour
delay = 0
tour =
id: 'mobile-tour',
onEnd: hide_mobile_tour,
onClose: hide_mobile_tour
else if response.tour == TOURS.feed_tour
delay = 0
tour =
id: 'feed-tour',
onEnd: hide_feed_tour,
onClose: hide_feed_tour
else if response.tour == TOURS.entry_tour
# Show entry tour after a 600ms delay, to give entry open/autoscroll
# animation time to finish.
delay = 600
tour =
id: 'entry-tour',
onEnd: hide_entry_tour,
onClose: hide_entry_tour
else if response.tour == TOURS.kb_shortcuts_tour
delay = 0
tour =
id: 'kb_shortcuts-tour',
onEnd: hide_kb_shortcuts_tour,
onClose: hide_kb_shortcuts_tour
tour.showCloseButton = true
tour.showPrevButton = false
tour.showNextButton = true
tour.i18n = response.i18n
tour.steps = response.steps
$timeout ->
hopscotch.startTour tour
, delay
#--------------------------------------------
# PRIVATE FUNCTION: set to false the show_main_tour flag for the current user.
#--------------------------------------------
hide_main_tour = ->
$rootScope.show_main_tour = false
worker.postMessage {operation: HIDE_TOUR, token: token, show_main_tour: 'false'}
#--------------------------------------------
# PRIVATE FUNCTION: set to false the show_mobile_tour flag for the current user.
#--------------------------------------------
hide_mobile_tour = ->
$rootScope.show_mobile_tour = false
worker.postMessage {operation: HIDE_TOUR, token: token, show_mobile_tour: 'false'}
#--------------------------------------------
# PRIVATE FUNCTION: set to false the show_feed_tour flag for the current user.
#--------------------------------------------
hide_feed_tour = ->
$rootScope.show_feed_tour = false
worker.postMessage {operation: HIDE_TOUR, token: token, show_feed_tour: 'false'}
#--------------------------------------------
# PRIVATE FUNCTION: set to false the show_entry_tour flag for the current user.
#--------------------------------------------
hide_entry_tour = ->
$rootScope.show_entry_tour = false
worker.postMessage {operation: HIDE_TOUR, token: token, show_entry_tour: 'false'}
#--------------------------------------------
# PRIVATE FUNCTION: set to false the show_kb_shortcuts_tour flag for the current user.
#--------------------------------------------
hide_kb_shortcuts_tour = ->
$rootScope.show_kb_shortcuts_tour = false
worker.postMessage {operation: HIDE_TOUR, token: token, show_kb_shortcuts_tour: 'false'}
#---------------------------------------------
# PRIVATE FUNCTION: show the main application tour.
#---------------------------------------------
show_main_tour = ->
# Show the main application tour, if the show_main_tour flag is true
if $rootScope.show_main_tour
# The main tour is only shown in screens bigger than a smartphone
enquire.register sm_min_media_query, ->
worker.postMessage {operation: LOAD_TOUR, token: token, tour: TOURS.main_tour}
#---------------------------------------------
# PRIVATE FUNCTION: show the keyboard shortcuts application tour.
#---------------------------------------------
show_kb_shortcuts_tour = ->
# If main tour is completed, kb shortcuts tour is shown as soon as page is loaded (unless already completed too)
if !$rootScope.show_main_tour && $rootScope.show_kb_shortcuts_tour
# The keyboards shortcuts tour is only shown in screens bigger than a smartphone
enquire.register sm_min_media_query, ->
worker.postMessage {operation: LOAD_TOUR, token: token, tour: TOURS.kb_shortcuts_tour}
#---------------------------------------------
# PRIVATE FUNCTION: show the mobile application tour.
#---------------------------------------------
show_mobile_tour = ->
if $rootScope.show_mobile_tour
# The mobile tour is only shown in smartphone-sized screens
enquire.register xs_max_media_query, ->
worker.postMessage {operation: LOAD_TOUR, token: token, tour: TOURS.mobile_tour}
#--------------------------------------------
# PRIVATE FUNCTION: at the end of main tour, mark show_main_tour flag to false so it's not shown again; and if the
# show_kb_shortcuts_flag is set to true, show the keyboard shortcuts tour
#--------------------------------------------
main_tour_end = ->
hide_main_tour()
show_kb_shortcuts_tour() if $rootScope.show_kb_shortcuts_tour
service =
#---------------------------------------------
# Show tours if the appropiate user config flags are set to true, when the page finishes loading:
# - main tour (only for screens bigger than smartphones)
# - keyboard shortcuts tour (only for screens bigger than smartphones, and only if the main tour is already completed)
# - mobile tour (only for smartphone-sized screens)
#---------------------------------------------
start: ->
show_main_tour()
show_kb_shortcuts_tour()
show_mobile_tour()
#---------------------------------------------
# Show the main application tour.
#---------------------------------------------
show_main_tour: show_main_tour
#---------------------------------------------
# Show the keyboard shortcuts application tour.
#---------------------------------------------
show_kb_shortcuts_tour: show_kb_shortcuts_tour
#---------------------------------------------
# Show the mobile application tour.
#---------------------------------------------
show_mobile_tour: show_mobile_tour
#---------------------------------------------
# Show the feed application tour.
#---------------------------------------------
show_feed_tour: ->
if $rootScope.show_feed_tour
# The feed tour is only shown in screens bigger than a smartphone
enquire.register sm_min_media_query, ->
worker.postMessage {operation: LOAD_TOUR, token: token, tour: TOURS.feed_tour}
#---------------------------------------------
# Show the entry application tour.
#---------------------------------------------
show_entry_tour: ->
if $rootScope.show_entry_tour
worker.postMessage {operation: LOAD_TOUR, token: token, tour: TOURS.entry_tour}
#---------------------------------------------
# Reset all application tours, so that they are shown again from the beginning.
#---------------------------------------------
reset_tours: ->
$rootScope.show_main_tour = true
$rootScope.show_mobile_tour = true
$rootScope.show_feed_tour = true
$rootScope.show_entry_tour = true
$rootScope.show_kb_shortcuts_tour = true
worker.postMessage {operation: RESET_TOURS, token: token}
return service
]