jam-cloud/web/app/assets/javascripts/jam_track_screen.js.coffee

484 lines
15 KiB
CoffeeScript
Raw Normal View History

$ = jQuery
context = window
context.JK ||= {}
context.JK.JamTrackScreen=class JamTrackScreen
LIMIT = 10
instrument_logo_map = context.JK.getInstrumentIconMap24()
constructor: (@app) ->
@EVENTS = context.JK.EVENTS
@logger = context.JK.logger
@screen = null
@content = null
@scroller = null
@genre = null
@artist = null
@instrument = null
@availability = null
@nextPager = null
@noMoreJamtracks = null
@currentPage = 0
@next = null
@currentQuery = this.defaultQuery()
@expanded = null
@shownHelperBubbles = false
beforeShow:(data) =>
this.setFilterFromURL()
if context.JK.currentUserId?
@app.user().done((user) =>
@user = user
this.refresh()
).fail((arg) =>
@logger.error("app.user.done failed: " + JSON.stringify(arg))
@logger.debug(arg.statusCode);
throw 'fail should not occur if user is available'
)
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:() =>
@genre.on 'change', this.search
@artist.on 'change', this.search
@instrument.on 'change', this.search
@availability.on 'change', this.search
clearResults:() =>
@currentPage = 0
@content.empty()
@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()
2015-03-27 14:54:01 +00:00
if(parms.artist?)
@artist.val(parms.artist)
else
@artist.val('')
if(parms.instrument?)
@instrument.val(parms.instrument)
else
@instrument.val('')
if(parms.availability?)
@availability.val(parms.availability)
else
@availability.val('')
if window.history.replaceState #ie9 proofing
window.history.replaceState({}, "", "/client#/jamtrackBrowse")
2015-03-27 14:54:01 +00:00
getParams:() =>
params = {}
q = window.location.href.split("?")[1]
if q?
q = q.split('#')[0]
raw_vars = q.split("&")
for v in raw_vars
[key, val] = v.split("=")
params[key] = decodeURIComponent(val)
params
2015-04-24 18:45:47 +00:00
setFilterState: (state) =>
if state
@genre.easyDropDown('enable').removeAttr('disabled')
@artist.easyDropDown('enable').removeAttr('disabled')
@instrument.easyDropDown('enable').removeAttr('disabled')
@availability.easyDropDown('enable').removeAttr('disabled')
else
@genre.easyDropDown('disable').attr('disabled', 'disabled')
@artist.easyDropDown('disable').attr('disabled', 'disabled')
@instrument.easyDropDown('disable').attr('disabled', 'disabled')
@availability.easyDropDown('disable').attr('disabled', 'disabled')
refresh:() =>
this.clearResults()
@currentQuery = this.buildQuery()
that = this
2015-04-24 18:45:47 +00:00
this.setFilterState(false)
rest.getJamTracks(@currentQuery).done((response) =>
that.handleJamtrackResponse(response)
2015-04-24 18:45:47 +00:00
).fail( (jqXHR) =>
that.clearResults()
2015-03-16 00:45:58 +00:00
that.noMoreJamtracks.show()
2015-04-24 18:45:47 +00:00
that.app.notifyServerError jqXHR, 'Jamtrack Unavailable'
).always () =>
that.setFilterState(true)
search:() =>
this.refresh()
false
defaultQuery:() =>
query =
2015-03-25 15:56:24 +00:00
per_page: LIMIT
page: @currentPage+1
if @next
query.since = @next
query
buildQuery:() =>
@currentQuery = this.defaultQuery()
# genre filter
# var genres = @screen.find('#jamtrack_genre').val()
# if (genres !== undefined) {
# @currentQuery.genre = genres
# }
# instrument filter
instrument = @instrument.val()
if instrument?
@currentQuery.instrument = instrument
# artist filter
art = @artist.val()
if art?
@currentQuery.artist = art
# availability filter
availability = @availability.val()
if availability?
@currentQuery.availability = availability
@currentQuery
handleJamtrackResponse:(response) =>
@next = response.next
this.renderJamtracks(response)
if response.next == null
# if we less results than asked for, end searching
@scroller.infinitescroll 'pause'
if @currentPage == 0 and response.jamtracks.length == 0
@content.append '<td colspan="3" class="no-jamtracks-msg\'>No JamTracks found.</div>'
if @currentPage > 0
@noMoreJamtracks.show()
# there are bugs with infinitescroll not removing the 'loading'.
# it's most noticeable at the end of the list, so whack all such entries
$('.infinite-scroll-loader').remove()
else
@currentPage++
this.buildQuery()
this.registerInfiniteScroll()
registerInfiniteScroll:() =>
that = this
@scroller.infinitescroll {
behavior: 'local'
navSelector: '#jamtrackScreen .btn-next-pager'
nextSelector: '#jamtrackScreen .btn-next-pager'
binder: @scroller
dataType: 'json'
appendCallback: false
prefill: false
bufferPx: 100
loading:
msg: $('<div class="infinite-scroll-loader">Loading ...</div>')
img: '/assets/shared/spinner.gif'
path: (page) =>
'/api/jamtracks?' + $.param(that.buildQuery())
}, (json, opts) =>
this.handleJamtrackResponse(json)
@scroller.infinitescroll 'resume'
playJamtrack:(e) =>
e.preventDefault()
addToCartJamtrack:(e) =>
e.preventDefault()
$target = $(e.target)
params = id: $target.attr('data-jamtrack-id')
isFree = $(e.target).is('.is_free')
rest.addJamtrackToShoppingCart(params).done((response) =>
if(isFree)
if context.JK.currentUserId?
context.JK.currentUserFreeJamTrack = true # make sure the user sees no more free notices
context.location = '/client#/redeemComplete'
else
# now make a rest call to buy it
context.location = '/client#/redeemSignup'
else
context.location = '/client#/shoppingCart'
).fail @app.ajaxError
licenseUSWhy:(e) =>
e.preventDefault()
@app.layout.showDialog 'jamtrack-availability-dialog'
handleExpanded:(trackElement) =>
jamTrack = trackElement.data('jamTrack')
expanded = trackElement.data('expanded')
expand = !expanded
trackElement.data('expanded', expand)
detailArrow = trackElement.find('.jamtrack-detail-btn')
if expand
trackElement.find('.extra').removeClass('hidden')
detailArrow.html('hide tracks <a class="details-arrow arrow-up"></a>')
for track in jamTrack.tracks
trackElement.find("[jamtrack-track-id='#{track.id}']").removeClass('hidden')
else
trackElement.find('.extra').addClass('hidden')
detailArrow.html('show all tracks <a class="details-arrow arrow-down"></a>')
count = 0
for track in jamTrack.tracks
if count < 6
trackElement.find("[jamtrack-track-id='#{track.id}']").removeClass('hidden')
else
trackElement.find("[jamtrack-track-id='#{track.id}']").addClass('hidden')
count++
registerEvents:(parent) =>
#@screen.find('.jamtrack-detail-btn').on 'click', this.showJamtrackDescription
parent.find('.play-button').on 'click', this.playJamtrack
parent.find('.jamtrack-add-cart').on 'click', this.addToCartJamtrack
parent.find('.license-us-why').on 'click', this.licenseUSWhy
parent.find('.jamtrack-detail-btn').on 'click', this.toggleExpanded
# @screen.find('.jamtrack-preview').each (index, element) =>
# new JK.JamTrackPreview(data.app, $element, jamTrack, track, {master_shows_duration: true})
rerenderJamtracks:() =>
if @currentData?
@clearResults()
@renderJamtracks(@currentData)
false
computeWeight: (jam_track_track, instrument) =>
weight = switch
when jam_track_track.track_type == 'Master' then 0
when jam_track_track.instrument?.id == instrument then 1 + jam_track_track.position
else 10000 + jam_track_track.position
renderJamtracks:(data) =>
@currentData = data
that = this
for jamtrack in data.jamtracks
jamtrackExpanded = this.expanded==jamtrack.id
2015-04-06 20:52:34 +00:00
trackRow = _.clone(jamtrack)
trackRow.track_cnt = jamtrack.tracks.length
trackRow.tracks = []
# if an instrument is selected by the user, then re-order any jam tracks with a matching instrument to the top
instrument = @instrument.val()
if instrument?
jamtrack.tracks.sort((a, b) =>
aWeight = @computeWeight(a, instrument)
bWeight = @computeWeight(b, instrument)
return aWeight - bWeight
)
for track in jamtrack.tracks
trackRow.tracks.push(track)
if track.track_type=='Master'
track.instrument_desc = "Master"
else
inst = '../assets/content/icon_instrument_default24.png'
if track.instrument?
if track.instrument.id in instrument_logo_map
inst = instrument_logo_map[track.instrument.id].asset
track.instrument_desc = track.instrument.description
track.instrument_url = inst
if track.part != ''
track.instrument_desc += ' (' + track.part + ')'
free_state = if context.JK.currentUserFreeJamTrack then 'free' else 'non-free'
is_free = free_state == 'free'
options =
jamtrack: trackRow
expanded: false
free_state: free_state,
is_free: is_free
@jamtrackItem = $(context._.template($('#template-jamtrack').html(), options, variable: 'data'))
that.renderJamtrack(@jamtrackItem, jamtrack)
that.registerEvents(@jamtrackItem)
renderJamtrack:(jamtrackElement, jamTrack) =>
jamtrackElement.data('jamTrack', jamTrack)
jamtrackElement.data('expanded', true)
@content.append jamtrackElement
#if this.expanded==jamTrack.id
for track in jamTrack.tracks
trackRow = jamtrackElement.find("[jamtrack-track-id='#{track.id}']")
previewElement = trackRow.find(".jamtrack-preview")
preview = new JK.JamTrackPreview(@app, previewElement, jamTrack, track, {master_shows_duration: true, color:'gray'})
$(preview).on(@EVENTS.PREVIEW_PLAYED, @previewPlayed)
this.handleExpanded(jamtrackElement, false)
showJamtrackDescription:(e) =>
e.preventDefault()
@description = $(e.target).parent('.detail-arrow').next()
if @description.css('display') == 'none'
@description.show()
else
@description.hide()
toggleExpanded:(e) =>
e.preventDefault()
jamtrackRecord = $(e.target).parents('.jamtrack-record')
jamTrackId = jamtrackRecord.attr("jamtrack-id")
this.handleExpanded(jamtrackRecord)
initialize:() =>
screenBindings =
'beforeShow': this.beforeShow
'afterShow': this.afterShow
'beforeHide' : this.beforeHide
@app.bindScreen 'jamtrackBrowse', screenBindings
@screen = $('#jamtrack-find-form')
@scroller = @screen.find('.content-body-scroller')
@content = @screen.find('.jamtrack-content')
@genre = @screen.find('#jamtrack_genre')
@artist = @screen.find('#jamtrack_artist')
@instrument = @screen.find('#jamtrack_instrument')
@availability = @screen.find('#jamtrack_availability')
@nextPager = @screen.find('a.btn-next-pager')
2015-03-16 00:45:58 +00:00
@noMoreJamtracks = @screen.find('.end-of-jamtrack-list')
if @screen.length == 0
throw new Error('@screen must be specified')
if @scroller.length == 0
throw new Error('@scroller must be specified')
if @content.length == 0
throw new Error('@content must be specified')
if @noMoreJamtracks.length == 0
throw new Error('@noMoreJamtracks must be specified')
#if(@genre.length == 0) throw new Error("@genre must be specified")
if @artist.length == 0
throw new Error('@artist must be specified')
if @instrument.length == 0
throw new Error('@instrument must be specified')
2015-05-04 23:01:03 +00:00
#if @availability.length == 0
# throw new Error('@availability must be specified')
this.events()