A/B Test video tutorial styles

This commit is contained in:
Matt Lott 2014-12-17 23:55:11 -08:00
parent d494dc9c79
commit 9d4c3cc163
4 changed files with 65 additions and 31 deletions
app
locale
models
templates/play/menu
views/play/menu

View file

@ -313,6 +313,8 @@
save_load_tab: "Save/Load" save_load_tab: "Save/Load"
options_tab: "Options" options_tab: "Options"
guide_tab: "Guide" guide_tab: "Guide"
guide_video_tutorial: "Video Tutorial"
guide_tips: "Tips"
multiplayer_tab: "Multiplayer" multiplayer_tab: "Multiplayer"
auth_tab: "Sign Up" auth_tab: "Sign Up"
inventory_caption: "Equip your hero" inventory_caption: "Equip your hero"

View file

@ -139,6 +139,13 @@ module.exports = class User extends CocoModel
else else
@subscribeCopyGroup = 'original' @subscribeCopyGroup = 'original'
@subscribeCopyGroup @subscribeCopyGroup
getVideoTutorialStylesIndex: (numVideos=0)->
# A/B Testing video tutorial styles
# Not a constant number of videos available (e.g. could be 0, 1, 3, or 4 currently)
# TODO: Do we need to call identify() still? trackEvent will have a style property.
return 0 unless numVideos > 0
return me.get('testGroupNumber') % numVideos
isPremium: -> isPremium: ->
return false unless stripe = @get('stripe') return false unless stripe = @get('stripe')

View file

@ -1,8 +1,8 @@
if docs.length === 1 if docs.length === 1
if showVideo if showVideo
h3 Video Tutorial h3(id='help-video-heading', data-i18n="game_menu.guide_video_tutorial")
div(id="help-video-player") div(id="help-video-player")
h3 Tips h3(data-i18n="game_menu.guide_tips")
div div
!= docs[0].html != docs[0].html
else else

View file

@ -17,6 +17,10 @@ module.exports = class LevelGuideView extends CocoView
@levelID = options.level.get('slug') @levelID = options.level.get('slug')
@helpVideos = LevelOptions[@levelID]?.helpVideos ? [] @helpVideos = LevelOptions[@levelID]?.helpVideos ? []
@trackedHelpVideoStart = @trackedHelpVideoFinish = false @trackedHelpVideoStart = @trackedHelpVideoFinish = false
# A/B Testing video tutorial styles
@helpVideosIndex = me.getVideoTutorialStylesIndex(@helpVideos.length)
@firstOnly = options.firstOnly @firstOnly = options.firstOnly
@docs = options?.docs ? options.level.get('documentation') ? {} @docs = options?.docs ? options.level.get('documentation') ? {}
general = @docs.generalArticles or [] general = @docs.generalArticles or []
@ -36,6 +40,16 @@ module.exports = class LevelGuideView extends CocoView
doc.slug = _.string.slugify(doc.name) for doc in @docs doc.slug = _.string.slugify(doc.name) for doc in @docs
super() super()
destroy: ->
if @vimeoListenerAttached
if window.addEventListener
window.removeEventListener('message', @onMessageReceived, false)
else
window.detachEvent('onmessage', @onMessageReceived, false)
if window.onYouTubeIframeAPIReady
window.onYouTubeIframeAPIReady = null
super()
getRenderData: -> getRenderData: ->
c = super() c = super()
c.docs = @docs c.docs = @docs
@ -70,12 +84,22 @@ module.exports = class LevelGuideView extends CocoView
@volume ?= me.get('volume') ? 1.0 @volume ?= me.get('volume') ? 1.0
createjs?.Sound?.setVolume(0.0) createjs?.Sound?.setVolume(0.0)
onStartHelpVideo: ->
unless @trackedHelpVideoStart
window.tracker?.trackEvent 'Start help video', level: @levelID, style: @helpVideos[@helpVideosIndex].style
@trackedHelpVideoStart = true
onFinishHelpVideo: ->
unless @trackedHelpVideoFinish
window.tracker?.trackEvent 'Finish help video', level: @levelID, style: @helpVideos[@helpVideosIndex].style
@trackedHelpVideoFinish = true
setupVideoPlayer: () -> setupVideoPlayer: () ->
return unless @helpVideos.length > 0 return unless @helpVideos.length > 0
# TODO: run A/B test for different video styles # TODO: run A/B test for different video styles
helpVideoURL = @helpVideos[0].URL helpVideoURL = @helpVideos[@helpVideosIndex].URL
if helpVideoURL.toLowerCase().indexOf('youtube') >= 0 if helpVideoURL.toLowerCase().indexOf('youtube') >= 0
@setupYouTubeVideoPlayer helpVideoURL @setupYouTubeVideoPlayer helpVideoURL
else if helpVideoURL.toLowerCase().indexOf('vimeo') >= 0 else if helpVideoURL.toLowerCase().indexOf('vimeo') >= 0
@ -84,16 +108,24 @@ module.exports = class LevelGuideView extends CocoView
setupYouTubeVideoPlayer: (helpVideoURL) -> setupYouTubeVideoPlayer: (helpVideoURL) ->
# Setup YouTube iframe player # Setup YouTube iframe player
# https://developers.google.com/youtube/iframe_api_reference # https://developers.google.com/youtube/iframe_api_reference
# TODO: Can't load a YouTube video twice in one level
# TODO: window.onYouTubeIframeAPIReady is only called once
onPlayerStateChange = (e) => onPlayerStateChange = (e) =>
if e.data is 1 if e.data is 1
unless @trackedHelpVideoStart @onStartHelpVideo()
window.tracker?.trackEvent 'Start help video', level: @levelID
@trackedHelpVideoStart = true
else if e.data is 0 else if e.data is 0
unless @trackedHelpVideoFinish @onFinishHelpVideo()
window.tracker?.trackEvent 'Finish help video', level: @levelID
@trackedHelpVideoFinish = true createPlayer = =>
new YT.Player 'help-video-player', {
height: @helpVideoHeight,
width: @helpVideoWidth,
videoId: videoID,
events: {
'onStateChange': onPlayerStateChange
}
}
if matchVideoID = helpVideoURL.match /www\.youtube\.com\/embed\/(bHaeKdMPZrA)/ if matchVideoID = helpVideoURL.match /www\.youtube\.com\/embed\/(bHaeKdMPZrA)/
videoID = matchVideoID[1] videoID = matchVideoID[1]
@ -104,19 +136,15 @@ module.exports = class LevelGuideView extends CocoView
# Add method that will be called by YouTube iframe player when ready # Add method that will be called by YouTube iframe player when ready
window.onYouTubeIframeAPIReady = => window.onYouTubeIframeAPIReady = =>
new YT.Player 'help-video-player', { createPlayer()
height: @helpVideoHeight,
width: @helpVideoWidth,
videoId: videoID,
events: {
'onStateChange': onPlayerStateChange
}
}
# Add YouTube video player # Add YouTube video player iframe script if necessary
tag = document.createElement('script') if YT?.Player?
tag.src = "https://www.youtube.com/iframe_api" createPlayer()
@$el.find('#help-video-player').before(tag) else
tag = document.createElement('script')
tag.src = "https://www.youtube.com/iframe_api"
@$el.find('#help-video-heading').after(tag)
setupVimeoVideoPlayer: (helpVideoURL) -> setupVimeoVideoPlayer: (helpVideoURL) ->
# Setup Vimeo player # Setup Vimeo player
@ -131,7 +159,7 @@ module.exports = class LevelGuideView extends CocoView
tag.frameborder = '0' tag.frameborder = '0'
@$el.find('#help-video-player').replaceWith(tag) @$el.find('#help-video-player').replaceWith(tag)
onMessageReceived = (e) => @onMessageReceived = (e) =>
data = JSON.parse(e.data) data = JSON.parse(e.data)
if data.event is 'ready' if data.event is 'ready'
# Vimeo player is ready, can now hook up other events # Vimeo player is ready, can now hook up other events
@ -141,16 +169,13 @@ module.exports = class LevelGuideView extends CocoView
player.contentWindow.postMessage JSON.stringify(method: 'addEventListener', value: 'play'), helpVideoURL player.contentWindow.postMessage JSON.stringify(method: 'addEventListener', value: 'play'), helpVideoURL
player.contentWindow.postMessage JSON.stringify(method: 'addEventListener', value: 'finish'), helpVideoURL player.contentWindow.postMessage JSON.stringify(method: 'addEventListener', value: 'finish'), helpVideoURL
else if data.event is 'play' else if data.event is 'play'
unless @trackedHelpVideoStart @onStartHelpVideo?()
window.tracker?.trackEvent 'Start help video', level: @levelID
@trackedHelpVideoStart = true
else if data.event is 'finish' else if data.event is 'finish'
unless @trackedHelpVideoFinish @onFinishHelpVideo?()
window.tracker?.trackEvent 'Finish help video', level: @levelID
@trackedHelpVideoFinish = true
# Listen for Vimeo player 'ready' # Listen for Vimeo player 'ready'
if window.addEventListener if window.addEventListener
window.addEventListener('message', onMessageReceived, false) window.addEventListener('message', @onMessageReceived, false)
else else
window.attachEvent('onmessage', onMessageReceived, false) window.attachEvent('onmessage', @onMessageReceived, false)
@vimeoListenerAttached = true