diff --git a/ruby/lib/jam_ruby/models/affiliate_partner.rb b/ruby/lib/jam_ruby/models/affiliate_partner.rb
index 58c4a1b8b..4408ffa42 100644
--- a/ruby/lib/jam_ruby/models/affiliate_partner.rb
+++ b/ruby/lib/jam_ruby/models/affiliate_partner.rb
@@ -418,12 +418,13 @@ class JamRuby::AffiliatePartner < ActiveRecord::Base
elsif quarter == 2
[Date.new(year, 7, 1), Date.new(year, 9, 30)]
elsif quarter == 3
- [Date.new(year, 7, 1), Date.new(year, 9, 30)]
+ [Date.new(year, 10, 1), Date.new(year, 12, 31)]
else
raise "invalid quarter #{quarter}"
end
end
+ # 1-based month
def self.boundary_dates_for_month(year, month)
[Date.new(year, month, 1), Date.civil(year, month, -1)]
end
diff --git a/ruby/spec/jam_ruby/models/affiliate_partner_spec.rb b/ruby/spec/jam_ruby/models/affiliate_partner_spec.rb
index 26c660daf..822a1f527 100644
--- a/ruby/spec/jam_ruby/models/affiliate_partner_spec.rb
+++ b/ruby/spec/jam_ruby/models/affiliate_partner_spec.rb
@@ -722,6 +722,116 @@ describe AffiliatePartner do
traffic_total_day2.signups.should eq(1)
end
end
+
+ describe "boundary_dates" do
+ it "1st quarter" do
+ start_date, end_date = AffiliatePartner.boundary_dates(2015, 0)
+ start_date.should eq(Date.new(2015, 1, 1))
+ end_date.should eq(Date.new(2015, 3, 31))
+ end
+
+ it "2nd quarter" do
+ start_date, end_date = AffiliatePartner.boundary_dates(2015, 1)
+ start_date.should eq(Date.new(2015, 4, 1))
+ end_date.should eq(Date.new(2015, 6, 30))
+ end
+
+ it "3rd quarter" do
+ start_date, end_date = AffiliatePartner.boundary_dates(2015, 2)
+ start_date.should eq(Date.new(2015, 7, 1))
+ end_date.should eq(Date.new(2015, 9, 30))
+ end
+
+ it "4th quarter" do
+ start_date, end_date = AffiliatePartner.boundary_dates(2015, 3)
+ start_date.should eq(Date.new(2015, 10, 1))
+ end_date.should eq(Date.new(2015, 12, 31))
+ end
+ end
+
+ describe "boundary_dates_for_month" do
+ it "invalid month" do
+ expect{AffiliatePartner.boundary_dates_for_month(2015, 0)}.to raise_error
+ end
+
+ it "January" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 1)
+ start_date.should eq(Date.new(2015, 1, 1))
+ end_date.should eq(Date.new(2015, 1, 31))
+ end
+
+ it "February" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 2)
+ start_date.should eq(Date.new(2015, 2, 1))
+ end_date.should eq(Date.new(2015, 2, 28))
+ end
+
+ it "March" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 3)
+ start_date.should eq(Date.new(2015, 3, 1))
+ end_date.should eq(Date.new(2015, 3, 31))
+ end
+
+ it "April" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 4)
+ start_date.should eq(Date.new(2015, 4, 1))
+ end_date.should eq(Date.new(2015, 4, 30))
+ end
+
+ it "May" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 5)
+ start_date.should eq(Date.new(2015, 5, 1))
+ end_date.should eq(Date.new(2015, 5, 31))
+ end
+
+ it "June" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 6)
+ start_date.should eq(Date.new(2015, 6, 1))
+ end_date.should eq(Date.new(2015, 6, 30))
+ end
+
+ it "July" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 7)
+ start_date.should eq(Date.new(2015, 7, 1))
+ end_date.should eq(Date.new(2015, 7, 31))
+ end
+
+ it "August" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 8)
+ start_date.should eq(Date.new(2015, 8, 1))
+ end_date.should eq(Date.new(2015, 8, 31))
+ end
+
+ it "September" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 9)
+ start_date.should eq(Date.new(2015, 9, 1))
+ end_date.should eq(Date.new(2015, 9, 30))
+ end
+
+ it "October" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 10)
+ start_date.should eq(Date.new(2015, 10, 1))
+ end_date.should eq(Date.new(2015, 10, 31))
+ end
+
+ it "November" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 11)
+ start_date.should eq(Date.new(2015, 11, 1))
+ end_date.should eq(Date.new(2015, 11, 30))
+ end
+
+ it "December" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2015, 12)
+ start_date.should eq(Date.new(2015, 12, 1))
+ end_date.should eq(Date.new(2015, 12, 31))
+ end
+
+ it "February in a leap year" do
+ start_date, end_date = AffiliatePartner.boundary_dates_for_month(2016, 2)
+ start_date.should eq(Date.new(2016, 2, 1))
+ end_date.should eq(Date.new(2016, 2, 29))
+ end
+ end
end
end
diff --git a/web/app/assets/javascripts/application.js b/web/app/assets/javascripts/application.js
index 474503da2..03ccbd2a7 100644
--- a/web/app/assets/javascripts/application.js
+++ b/web/app/assets/javascripts/application.js
@@ -36,6 +36,7 @@
//= require jquery.custom-protocol
//= require jquery.exists
//= require jquery.payment
+//= require jquery.visible
//= require howler.core.js
//= require jstz
//= require class
diff --git a/web/app/assets/javascripts/globals.js b/web/app/assets/javascripts/globals.js
index 175a96fd6..85ebcc250 100644
--- a/web/app/assets/javascripts/globals.js
+++ b/web/app/assets/javascripts/globals.js
@@ -52,7 +52,8 @@
JAMTRACK_DOWNLOADER_STATE_CHANGED: 'jamtrack_downloader_state',
METRONOME_PLAYBACK_MODE_SELECTED: 'metronome_playback_mode_selected',
CHECKOUT_SIGNED_IN: 'checkout_signed_in',
- CHECKOUT_SKIP_SIGN_IN: 'checkout_skip_sign_in'
+ CHECKOUT_SKIP_SIGN_IN: 'checkout_skip_sign_in',
+ PREVIEW_PLAYED: 'preview_played'
};
context.JK.PLAYBACK_MONITOR_MODE = {
diff --git a/web/app/assets/javascripts/helpBubbleHelper.js b/web/app/assets/javascripts/helpBubbleHelper.js
index eb68a4a6c..c8ccdc4cf 100644
--- a/web/app/assets/javascripts/helpBubbleHelper.js
+++ b/web/app/assets/javascripts/helpBubbleHelper.js
@@ -62,6 +62,24 @@
}
}
+ helpBubble.rotateJamTrackLandingBubbles = function($preview, $video, $ctaButton, $alternativeCta) {
+ $(window).on('load', function() {
+ setTimeout(function() {
+ helpBubble.jamtrackLandingPreview($preview, $preview.offsetParent())
+
+ setTimeout(function() {
+ helpBubble.jamtrackLandingVideo($video, $video.offsetParent())
+
+ setTimeout(function() {
+ helpBubble.jamtrackLandingCta($ctaButton, $alternativeCta)
+ }, 11000); // 5 seconds on top of 6 second show time of bubbles
+ }, 11000); // 5 seconds on top of 6 second show time of bubbles
+ }, 1500)
+
+
+ })
+ }
+
helpBubble.clearJamTrackGuide = clearJamTrackGuideTimeout;
helpBubble.jamtrackGuideTile = function ($element, $offsetParent) {
@@ -82,4 +100,33 @@
})
}
+ helpBubble.jamtrackLandingPreview = function($element, $offsetParent) {
+ context.JK.prodBubble($element, 'jamtrack-landing-preview', {}, bigHelpOptions({positions:['right'], offsetParent: $offsetParent}))
+ }
+
+ helpBubble.jamtrackLandingVideo = function($element, $offsetParent) {
+ context.JK.prodBubble($element, 'jamtrack-landing-video', {}, bigHelpOptions({positions:['left'], offsetParent: $offsetParent}))
+ }
+
+ helpBubble.jamtrackLandingCta = function($element, $alternativeElement) {
+ if ($element.visible()) {
+ context.JK.prodBubble($element, 'jamtrack-landing-cta', {}, bigHelpOptions({positions:['left']}))
+ }
+ else {
+ context.JK.prodBubble($alternativeElement, 'jamtrack-landing-cta', {}, bigHelpOptions({positions:['right']}))
+ }
+ }
+
+ helpBubble.jamtrackBrowseBand = function($element, $offsetParent) {
+ return context.JK.prodBubble($element, 'jamtrack-browse-band', {}, bigHelpOptions({positions:['top'], offsetParent: $offsetParent}))
+ }
+
+ helpBubble.jamtrackBrowseMasterMix = function($element, $offsetParent) {
+ return context.JK.prodBubble($element, 'jamtrack-browse-master-mix', {}, bigHelpOptions({positions:['top'], offsetParent: $offsetParent}))
+ }
+
+ helpBubble.jamtrackBrowseCta = function($element, $offsetParent) {
+ return context.JK.prodBubble($element, 'jamtrack-browse-cta', {}, bigHelpOptions({positions:['top'], offsetParent: $offsetParent}))
+ }
+
})(window, jQuery);
\ No newline at end of file
diff --git a/web/app/assets/javascripts/jam_track_preview.js.coffee b/web/app/assets/javascripts/jam_track_preview.js.coffee
index 585b500dd..f78a25d05 100644
--- a/web/app/assets/javascripts/jam_track_preview.js.coffee
+++ b/web/app/assets/javascripts/jam_track_preview.js.coffee
@@ -129,6 +129,8 @@ context.JK.JamTrackPreview = class JamTrackPreview
if e?
e.stopPropagation()
+ $(this).triggerHandler(@EVENTS.PREVIEW_PLAYED)
+
if @no_audio
context.JK.prodBubble(@playButton, 'There is no preview available for this track.', {}, {duration:2000})
else
diff --git a/web/app/assets/javascripts/jam_track_screen.js.coffee b/web/app/assets/javascripts/jam_track_screen.js.coffee
index 43411b93b..ac25cc4c8 100644
--- a/web/app/assets/javascripts/jam_track_screen.js.coffee
+++ b/web/app/assets/javascripts/jam_track_screen.js.coffee
@@ -6,7 +6,8 @@ context.JK.JamTrackScreen=class JamTrackScreen
LIMIT = 10
instrument_logo_map = context.JK.getInstrumentIconMap24()
- constructor: (@app) ->
+ constructor: (@app) ->
+ @EVENTS = context.JK.EVENTS
@logger = context.JK.logger
@screen = null
@content = null
@@ -21,6 +22,7 @@ context.JK.JamTrackScreen=class JamTrackScreen
@next = null
@currentQuery = this.defaultQuery()
@expanded = null
+ @shownHelperBubbles = false
beforeShow:(data) =>
this.setFilterFromURL()
@@ -38,11 +40,17 @@ context.JK.JamTrackScreen=class JamTrackScreen
)
else
this.refresh()
+ unless @shownHelperBubbles
+ @shownHelperBubbles = true
+ @startHelperBubbles()
afterShow:(data) =>
context.JK.Tracking.jamtrackBrowseTrack(@app)
beforeHide: () =>
+ this.clearCtaHelpTimeout()
+ this.clearBandFilterHelpTimeout()
+ this.clearMasterHelpTimeout()
this.clearResults();
events:() =>
@@ -57,6 +65,104 @@ context.JK.JamTrackScreen=class JamTrackScreen
@noMoreJamtracks.hide()
@next = null
+ startHelperBubbles: () =>
+ @showBandFilterHelpTimeout = setTimeout(@showBandFilterHelp, 3500)
+
+ showBandFilterHelp: () =>
+ context.JK.HelpBubbleHelper.jamtrackBrowseBand(@artist.closest('.easydropdown-wrapper'), $('body'))
+
+ @showMasterHelpDueTime = new Date().getTime() + 11000 # 6000 ms for band tooltip to display, and 5 seconds of quiet time
+ @scroller.on('scroll', @masterHelpScrollWatch)
+ @scroller.on('scroll', @clearBubbles)
+ @showMasterHelpTimeout = setTimeout(@showMasterHelp, @masterHelpDueTime())
+
+ clearBubbles: () =>
+ if @helpBubble?
+ @helpBubble.btOff()
+ @helpBubble = null
+
+ # computes when we should show the master help bubble
+ masterHelpDueTime: () =>
+ dueTime = @showMasterHelpDueTime - new Date().getTime()
+ if dueTime <= 0
+ dueTime = 2000
+ dueTime
+
+
+ # computes when we should show the master help bubble
+ ctaHelpDueTime: () =>
+ dueTime = @showCtaHelpDueTime - new Date().getTime()
+ if dueTime <= 0
+ dueTime = 2000
+ dueTime
+
+ # if the user scrolls, reset the master help due time
+ masterHelpScrollWatch: () =>
+ @clearMasterHelpTimeout()
+ @showMasterHelpTimeout = setTimeout(@showMasterHelp, @masterHelpDueTime() + 2000)
+
+ # if the user scrolls, reset the master help due time
+ ctaHelpScrollWatch: () =>
+ @clearCtaHelpTimeout()
+ @showCtaHelpTimeout = setTimeout(@showCtaHelp, @ctaHelpDueTime() + 2000)
+
+
+ showCtaHelp: () =>
+ @scroller.off('scroll', @ctaHelpScrollWatch)
+ @clearCtaHelpTimeout()
+
+ cutoff = @scroller.offset().top;
+
+ @screen.find('.jamtrack-actions').each((i, element) =>
+ $element = $(element)
+
+ if ($element.offset().top >= cutoff)
+ @helpBubble = context.JK.HelpBubbleHelper.jamtrackBrowseCta($element, $('body'))
+ return false
+ else
+ return true
+ )
+
+ showMasterHelp: () =>
+ @scroller.off('scroll', @masterHelpScrollWatch)
+ @clearMasterHelpTimeout()
+
+ # don't show the help if the user has already clicked a preview
+ unless @userPreviewed
+ cutoff = @scroller.offset().top;
+
+ @screen.find('.jamtrack-preview[data-track-type="Master"]').each((i, element) =>
+ $element = $(element)
+
+ if ($element.offset().top >= cutoff)
+ @helpBubble = context.JK.HelpBubbleHelper.jamtrackBrowseMasterMix($element.find('.play-button'), $('body'))
+ return false
+ else
+ return true
+ )
+
+ @showCtaHelpDueTime = new Date().getTime() + 11000
+ @scroller.on('scroll', @ctaHelpScrollWatch)
+ @showCtaHelpTimeout = setTimeout(@showCtaHelp, @ctaHelpDueTime()) # 6000 ms for bubble show time, and 5000ms for delay
+
+ previewPlayed: () =>
+ @userPreviewed = true
+
+ clearCtaHelpTimeout:() =>
+ if @showCtaHelpTimeout?
+ clearTimeout(@showCtaHelpTimeout)
+ @showCtaHelpTimeout = null
+
+ clearBandFilterHelpTimeout: () =>
+ if @showBandFilterHelpTimeout?
+ clearTimeout(@showBandFilterHelpTimeout)
+ @showBandFilterHelpTimeout = null
+
+ clearMasterHelpTimeout: () =>
+ if @showMasterHelpTimeout?
+ clearTimeout(@showMasterHelpTimeout)
+ @showMasterHelpTimeout = null
+
setFilterFromURL:() =>
# Grab parms from URL for artist, instrument, and availability
parms=this.getParams()
@@ -73,7 +179,9 @@ context.JK.JamTrackScreen=class JamTrackScreen
@availability.val(parms.availability)
else
@availability.val('')
- window.history.replaceState({}, "", "/client#/jamtrackBrowse")
+
+ if window.history.replaceState #ie9 proofing
+ window.history.replaceState({}, "", "/client#/jamtrackBrowse")
getParams:() =>
params = {}
@@ -320,7 +428,8 @@ context.JK.JamTrackScreen=class JamTrackScreen
for track in jamTrack.tracks
trackRow = jamtrackElement.find("[jamtrack-track-id='#{track.id}']")
previewElement = trackRow.find(".jamtrack-preview")
- new JK.JamTrackPreview(@app, previewElement, jamTrack, track, {master_shows_duration: true, color:'gray'})
+ preview = new JK.JamTrackPreview(@app, previewElement, jamTrack, track, {master_shows_duration: true, color:'gray'})
+ $(preview).on(@EVENTS.PREVIEW_PLAYED, @previewPlayed)
this.handleExpanded(jamtrackElement, false)
diff --git a/web/app/assets/javascripts/jamtrack_landing.js.coffee b/web/app/assets/javascripts/jamtrack_landing.js.coffee
index 2fb470923..5198a1f64 100644
--- a/web/app/assets/javascripts/jamtrack_landing.js.coffee
+++ b/web/app/assets/javascripts/jamtrack_landing.js.coffee
@@ -72,7 +72,8 @@ context.JK.JamTrackLanding = class JamTrackLanding
that=this
@bandList.on "click", "a.artist-link", (event)->
context.location="client#/jamtrackBrowse"
- window.history.replaceState({}, "", this.href)
+ if window.history.replaceState # ie9 proofing
+ window.history.replaceState({}, "", this.href)
event.preventDefault()
handleFailure:(error) =>
diff --git a/web/app/assets/javascripts/web/individual_jamtrack.js b/web/app/assets/javascripts/web/individual_jamtrack.js
index 82863ad74..ebb720f2c 100644
--- a/web/app/assets/javascripts/web/individual_jamtrack.js
+++ b/web/app/assets/javascripts/web/individual_jamtrack.js
@@ -45,11 +45,13 @@
$previews.append($element);
new context.JK.JamTrackPreview(app, $element, jam_track, track, {master_shows_duration: false, color:'black', master_adds_line_break: true, preload_master:true})
+
+ if(track.track_type =='Master') {
+ context.JK.HelpBubbleHelper.rotateJamTrackLandingBubbles($element.find('.jam-track-preview'), $page.find('.video-wrapper'), $page.find('.cta-free-jamtrack a'), $page.find('a.browse-jamtracks'));
+ }
})
$previews.append('
')
-
-
})
.fail(function () {
app.notify({title: 'Unable to fetch JamTrack', text: "Please refresh the page or try again later."})
diff --git a/web/app/assets/javascripts/web/individual_jamtrack_band.js b/web/app/assets/javascripts/web/individual_jamtrack_band.js
index aaac3ca8c..22ceb52a3 100644
--- a/web/app/assets/javascripts/web/individual_jamtrack_band.js
+++ b/web/app/assets/javascripts/web/individual_jamtrack_band.js
@@ -35,6 +35,10 @@
$previews.append($element);
new context.JK.JamTrackPreview(app, $element, jam_track, track, {master_shows_duration: false, color:'black', master_adds_line_break:true, preload_master:true})
+
+ if(track.track_type =='Master') {
+ context.JK.HelpBubbleHelper.rotateJamTrackLandingBubbles($element.find('.jam-track-preview'), $page.find('.video-wrapper'), $page.find('.cta-free-jamtrack a'), $page.find('a.browse-jamtracks'));
+ }
})
$previews.append('
')
diff --git a/web/app/assets/javascripts/web/web.js b/web/app/assets/javascripts/web/web.js
index 99dc9de2d..a2a2c58d2 100644
--- a/web/app/assets/javascripts/web/web.js
+++ b/web/app/assets/javascripts/web/web.js
@@ -20,6 +20,7 @@
//= require jquery.icheck
//= require jquery.bt
//= require jquery.exists
+//= require jquery.visible
//= require howler.core.js
//= require AAA_Log
//= require AAC_underscore
diff --git a/web/app/assets/stylesheets/client/help.css.scss b/web/app/assets/stylesheets/client/help.css.scss
index b5c3cf17b..1bd085fa4 100644
--- a/web/app/assets/stylesheets/client/help.css.scss
+++ b/web/app/assets/stylesheets/client/help.css.scss
@@ -50,6 +50,8 @@ body.jam, body.web, .dialog{
.big-help {
font-size:20px;
+ color: #ed3618;
+ p {color:#ed3618}
}
.help-hover-recorded-tracks, .help-hover-stream-mix, .help-hover-recorded-backing-tracks {
diff --git a/web/app/assets/stylesheets/client/jamtrack.css.scss b/web/app/assets/stylesheets/client/jamtrack.css.scss
index 238465fdd..7b3a27aaf 100644
--- a/web/app/assets/stylesheets/client/jamtrack.css.scss
+++ b/web/app/assets/stylesheets/client/jamtrack.css.scss
@@ -209,14 +209,10 @@
@include border_box_sizing;
width: 20%;
text-align: center;
+ vertical-align: middle;
.jamtrack-action-container {
- display: flex;
- align-items: center;
- justify-content: center;
- position:absolute;
- height:100%;
- width:100%;
+ display:inline-block;
}
.play-button {
diff --git a/web/app/views/clients/_help.html.slim b/web/app/views/clients/_help.html.slim
index 2ec8bf719..9af12062e 100644
--- a/web/app/views/clients/_help.html.slim
+++ b/web/app/views/clients/_help.html.slim
@@ -261,4 +261,28 @@ script type="text/template" id="template-help-jamtrack-guide-private"
script type="text/template" id="template-help-jamtrack-guide-session"
.jamtrack-guide-open.big-help
- p To try out your JamTrack, click here to open it.
\ No newline at end of file
+ p To try out your JamTrack, click here to open it.
+
+script type="text/template" id="template-help-jamtrack-landing-preview"
+ .jamtrack-landing-preview.big-help
+ p click a play button to preview the master mix and individual tracks of the JamTrack
+
+script type="text/template" id="template-help-jamtrack-landing-video"
+ .jamtrack-landing-video.big-help
+ p click to watch JamTracks video
+
+script type="text/template" id="template-help-jamtrack-landing-cta"
+ .jamtrack-landing-cta.big-help
+ p click to browse through our JamTracks collection and get your first one free!
+
+script type="text/template" id="template-help-jamtrack-browse-band"
+ .jamtrack-browse-band.big-help
+ p List JamTracks of a specified band
+
+script type="text/template" id="template-help-jamtrack-browse-master-mix"
+ .jamtrack-browse-master-mix.big-help
+ p Listen to master mix and individual tracks
+
+script type="text/template" id="template-help-jamtrack-browse-cta"
+ .jamtrack-browse-cta.big-help
+ p Click to select your first free JamTrack!
\ No newline at end of file
diff --git a/web/app/views/landings/individual_jamtrack.html.slim b/web/app/views/landings/individual_jamtrack.html.slim
index c3b6e9daa..cb1cfc771 100644
--- a/web/app/views/landings/individual_jamtrack.html.slim
+++ b/web/app/views/landings/individual_jamtrack.html.slim
@@ -1,5 +1,6 @@
- provide(:page_name, 'landing_page full landing_jamtrack individual_jamtrack')
- provide(:description, @jam_track.nil? ? nil : "Preview multi-track JamTrack recording: #{@jam_track.name} by #{@jam_track.original_artist}. Way better than a backing track.")
+- provide(:title, @jam_track.nil? ? nil : "Preview JamTrack: #{@jam_track.name} by #{@jam_track.original_artist}")
.one_by_two
.row
diff --git a/web/app/views/landings/individual_jamtrack_band.html.slim b/web/app/views/landings/individual_jamtrack_band.html.slim
index 88237cd56..9b2b72b19 100644
--- a/web/app/views/landings/individual_jamtrack_band.html.slim
+++ b/web/app/views/landings/individual_jamtrack_band.html.slim
@@ -1,5 +1,6 @@
- provide(:page_name, 'landing_page full landing_jamtrack individual_jamtrack_band')
- provide(:description, @jam_track.nil? ? nil : "Preview multi-track JamTrack recording: #{@jam_track.name} by #{@jam_track.original_artist}. Way better than a backing track.")
+- provide(:title, @jam_track.nil? ? nil : "Preview JamTrack: #{@jam_track.name} by #{@jam_track.original_artist}")
.one_by_two
.row
diff --git a/web/config/application.rb b/web/config/application.rb
index 60c645415..1e61dc1ab 100644
--- a/web/config/application.rb
+++ b/web/config/application.rb
@@ -346,5 +346,7 @@ if defined?(Bundler)
config.expire_fingerprint_days = 14
config.found_conflict_count = 1
config.web_performance_timing_enabled = true
+ config.jamtrack_landing_bubbles_enabled = true
+ config.jamtrack_browser_bubbles_enabled = true
end
end
diff --git a/web/config/environments/test.rb b/web/config/environments/test.rb
index b20761c29..a5b075118 100644
--- a/web/config/environments/test.rb
+++ b/web/config/environments/test.rb
@@ -108,6 +108,6 @@ SampleApp::Application.configure do
config.jam_tracks_available = true
config.video_available = "full"
config.guard_against_fraud = true
- config.error_on_fraud = true
+ config.error_on_fraud = false
end
diff --git a/web/config/initializers/gon.rb b/web/config/initializers/gon.rb
index 71c0a7493..f82a4a1d7 100644
--- a/web/config/initializers/gon.rb
+++ b/web/config/initializers/gon.rb
@@ -17,4 +17,6 @@ Gon.global.gear_check_ignore_high_latency = Rails.application.config.gear_check_
Gon.global.purchases_enabled = Rails.application.config.purchases_enabled
Gon.global.estimate_taxes = Rails.application.config.estimate_taxes
Gon.global.web_performance_timing_enabled = Rails.application.config.web_performance_timing_enabled
+Gon.global.jamtrack_landing_bubbles_enabled = Rails.application.config.jamtrack_landing_bubbles_enabled
+Gon.global.jamtrack_browser_bubbles_enabled = Rails.application.config.jamtrack_browser_bubbles_enabled
Gon.global.env = Rails.env
diff --git a/web/vendor/assets/javascripts/jquery.visible.js b/web/vendor/assets/javascripts/jquery.visible.js
new file mode 100644
index 000000000..1e340099b
--- /dev/null
+++ b/web/vendor/assets/javascripts/jquery.visible.js
@@ -0,0 +1,68 @@
+(function($){
+
+ /**
+ * Copyright 2012, Digital Fusion
+ * Licensed under the MIT license.
+ * http://teamdf.com/jquery-plugins/license/
+ *
+ * @author Sam Sehnert
+ * @desc A small plugin that checks whether elements are within
+ * the user visible viewport of a web browser.
+ * only accounts for vertical position, not horizontal.
+ */
+ var $w = $(window);
+ $.fn.visible = function(partial,hidden,direction){
+
+ if (this.length < 1)
+ return;
+
+ var $t = this.length > 1 ? this.eq(0) : this,
+ t = $t.get(0),
+ vpWidth = $w.width(),
+ vpHeight = $w.height(),
+ direction = (direction) ? direction : 'both',
+ clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;
+
+ if (typeof t.getBoundingClientRect === 'function'){
+
+ // Use this native browser method, if available.
+ var rec = t.getBoundingClientRect(),
+ tViz = rec.top >= 0 && rec.top < vpHeight,
+ bViz = rec.bottom > 0 && rec.bottom <= vpHeight,
+ lViz = rec.left >= 0 && rec.left < vpWidth,
+ rViz = rec.right > 0 && rec.right <= vpWidth,
+ vVisible = partial ? tViz || bViz : tViz && bViz,
+ hVisible = partial ? lViz || rViz : lViz && rViz;
+
+ if(direction === 'both')
+ return clientSize && vVisible && hVisible;
+ else if(direction === 'vertical')
+ return clientSize && vVisible;
+ else if(direction === 'horizontal')
+ return clientSize && hVisible;
+ } else {
+
+ var viewTop = $w.scrollTop(),
+ viewBottom = viewTop + vpHeight,
+ viewLeft = $w.scrollLeft(),
+ viewRight = viewLeft + vpWidth,
+ offset = $t.offset(),
+ _top = offset.top,
+ _bottom = _top + $t.height(),
+ _left = offset.left,
+ _right = _left + $t.width(),
+ compareTop = partial === true ? _bottom : _top,
+ compareBottom = partial === true ? _top : _bottom,
+ compareLeft = partial === true ? _right : _left,
+ compareRight = partial === true ? _left : _right;
+
+ if(direction === 'both')
+ return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
+ else if(direction === 'vertical')
+ return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
+ else if(direction === 'horizontal')
+ return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
+ }
+ };
+
+})(jQuery);
\ No newline at end of file