VRFS-2830 : Merge / manual fix

This commit is contained in:
Steven Miers 2015-03-25 10:56:24 -05:00
commit 5f953d1b19
40 changed files with 1060 additions and 456 deletions

View File

@ -64,6 +64,18 @@ module JamRuby
accepts_nested_attributes_for :jam_track_tap_ins, allow_destroy: true
class << self
# @return array[artist_name(string)]
def all_artists
JamTrack.select("original_artist").
group("original_artist").
collect{|jam_track|jam_track.original_artist}
end
# @return array[JamTrack] for given artist_name
def tracks_for_artist(artist_name)
JamTrack.where("original_artist=?", artist_name).all
end
def index(options, user)
if options[:page]
page = options[:page].to_i
@ -99,6 +111,14 @@ module JamRuby
query = query.joins(:jam_track_rights)
query = query.where("jam_track_rights.user_id = ?", user.id)
end
if options[:artist].present?
query = query.where("original_artist=?", options[:artist])
end
if options[:group_artist]
query = query.group("original_artist")
end
query = query.where("jam_tracks.status = ?", 'Production') unless user.admin
query = query.where("jam_tracks.genre_id = '#{options[:genre]}'") unless options[:genre].blank?

View File

@ -368,6 +368,10 @@ module JamRuby
MusicSession.scheduled_rsvp(self, true).length
end
def purchased_jamtracks_count
self.purchased_jam_tracks.count
end
def joined_score
return nil unless has_attribute?(:score)
a = read_attribute(:score)

View File

@ -55,7 +55,30 @@ module JamRuby
account
end
def update_billing_info(current_user, billing_info)
def payment_history(current_user)
payments = []
account = get_account(current_user)
if(account.present?)
begin
account.transactions.find_each do |transaction|
if transaction.amount_in_cents > 0 # Account creation adds a transaction record
payments << {
:created_at => transaction.created_at,
:amount_in_cents => transaction.amount_in_cents,
:status => transaction.status,
:payment_method => transaction.payment_method,
:reference => transaction.reference
}
end
end
rescue Recurly::Error, NoMethodError => x
raise RecurlyClientError, x.to_s
end
end
payments
end
def update_billing_info(current_user, billing_info=nil)
account = get_account(current_user)
if (account.present?)
begin

View File

@ -88,6 +88,7 @@ describe RecurlyClient do
end
it "can place order" do
history_items = @client.payment_history(@user).length
@client.find_or_create_account(@user, @billing_info)
expect{@client.place_order(@user, @jamtrack, nil)}.not_to raise_error()
subs = @client.get_account(@user).subscriptions
@ -96,6 +97,7 @@ describe RecurlyClient do
@user.jam_track_rights.should_not be_nil
@user.jam_track_rights.should have(1).items
@user.jam_track_rights.last.jam_track.id.should eq(@jamtrack.id)
@client.payment_history(@user).should have(history_items+1).items
end
it "can refund subscription" do

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -33,6 +33,10 @@
}
}
function licenseDetail(userDetail) {
return (userDetail.purchased_jamtracks_count==0) ? "You don't currently own any JamTracks" : 'You currently own a license to use ' + userDetail.purchased_jamtracks_count + " JamTracks"
}
function populateAccount(userDetail) {
var validProfiles = prettyPrintAudioProfiles(context.JK.getGoodConfigMap());
@ -42,8 +46,10 @@
var $template = $(context._.template($('#template-account-main').html(), {
email: userDetail.email,
name: userDetail.name,
licenseDetail: licenseDetail(userDetail),
location : userDetail.location,
session : sessionSummary,
paymentMethod: "mastercard",
instruments : prettyPrintInstruments(userDetail.instruments),
photoUrl : context.JK.resolveAvatarUrl(userDetail.photo_url),
validProfiles : validProfiles,
@ -94,14 +100,20 @@
// events for main screen
function events() {
// wire up main panel clicks
// wire up main panel clicks:
$('#account-content-scroller').on('click', '#account-scheduled-sessions-link', function(evt) { evt.stopPropagation(); navToScheduledSessions(); return false; } );
$('#account-content-scroller').on('click', '#account-my-jamtracks-link', function(evt) { evt.stopPropagation(); navToMyJamTracks(); return false; } );
$('#account-content-scroller').on('click', '#account-edit-identity-link', function(evt) { evt.stopPropagation(); navToEditIdentity(); return false; } );
$('#account-content-scroller').on('click', '#account-edit-profile-link', function(evt) { evt.stopPropagation(); navToEditProfile(); return false; } );
$('#account-content-scroller').on('click', '#account-edit-subscriptions-link', function(evt) { evt.stopPropagation(); navToEditSubscriptions(); return false; } );
$('#account-content-scroller').on('click', '#account-edit-payments-link', function(evt) { evt.stopPropagation(); navToEditPayments(); return false; } );
$('#account-content-scroller').on('click', '#account-edit-audio-link', function(evt) { evt.stopPropagation(); navToEditAudio(); return false; } );
$('#account-content-scroller').on('avatar_changed', '#profile-avatar', function(evt, newAvatarUrl) { evt.stopPropagation(); updateAvatar(newAvatarUrl); return false; })
// License dialog:
$("#account-content-scroller").on('click', '#account-view-license-link', function(evt) {evt.stopPropagation(); app.layout.showDialog('jamtrack-license-dialog'); return false; } );
$("#account-content-scroller").on('click', '#account-payment-history-link', function(evt) {evt.stopPropagation(); app.layout.showDialog('jamtrack-payment-history-dialog'); return false; } );
}
function renderAccount() {
@ -117,6 +129,11 @@
window.location = '/client#/account/sessions'
}
function navToMyJamTracks() {
resetForm();
window.location = '/client#/account/jamtracks'
}
function navToEditIdentity() {
resetForm()
window.location = '/client#/account/identity'
@ -128,7 +145,7 @@
}
function navToEditSubscriptions() {
window.location = '/client#/account/profile'
}
function navToEditPayments() {

View File

@ -0,0 +1,103 @@
$ = jQuery
context = window
context.JK ||= {}
context.JK.AccountJamTracks = class AccountJamTracks
constructor: (@app) ->
@rest = context.JK.Rest()
@client = context.jamClient
@logger = context.JK.logger
@screen = null
@userId = context.JK.currentUserId;
initialize:() =>
screenBindings =
'beforeShow': @beforeShow
'afterShow': @afterShow
@app.bindScreen('account/jamtracks', screenBindings)
@screen = $('#account-jamtracks')
beforeShow:() =>
@logger.debug("beforeShow")
rest.getPurchasedJamTracks({})
.done(@populateJamTracks)
.fail(@app.ajaxError);
afterShow:() =>
@logger.debug("afterShow")
populateJamTracks:(data) =>
@logger.debug("populateJamTracks", data)
template = context._.template($('#template-account-jamtrack').html(), {jamtracks:data.jamtracks}, { variable: 'data' })
# template = context._.template($('#template-account-jamtrack').html(), {
# jamtracks: data.jamtracks
# current_user: @userId
# }, variable: 'data')
@logger.debug("TEMPLATE", template)
this.appendJamTracks template
@screen.find('.jamtrack-solo-session').on 'click', @soloSession
@screen.find('.jamtrack-group-session').on 'click', @groupSession
appendJamTracks:(template) =>
$('#account-my-jamtracks table tbody').replaceWith template
soloSession:(e) =>
#context.location="client#/createSession"
@logger.debug "BLEH", e
jamRow = $(e.target).parents("tr")
@logger.debug "BLEH2", e, jamRow.data()
@createSession(jamRow.data(), true)
#@logger.debug "BLEH", $(this), $(this).data()
groupSession:(e) =>
#context.location="client#/createSession"
jamRow = $(e.target).parents("tr")
@createSession(jamRow.data(), false)
createSession:(sessionData, solo) =>
tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient)
if (context.JK.guardAgainstBrowser(@app))
@logger.debug("CRATING SESSION", sessionData.genre, solo)
data = {}
data.client_id = @app.clientId
#data.description = $('#description').val()
data.description = "Jam Track Session"
data.as_musician = true
data.legal_terms = true
data.intellectual_property = true
data.approval_required = false
data.musician_access = !solo
data.fan_access = false
data.fan_chat = false
data.genre = [sessionData.genre]
data.genres = [sessionData.genre]
# data.genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre')
# data.musician_access = if $('#musician-access option:selected').val() == 'true' then true else false
# data.approval_required = if $('input[name=\'musician-access-option\']:checked').val() == 'true' then true else false
# data.fan_access = if $('#fan-access option:selected').val() == 'true' then true else false
# data.fan_chat = if $('input[name=\'fan-chat-option\']:checked').val() == 'true' then true else false
# if $('#band-list option:selected').val() != ''
# data.band = $('#band-list option:selected').val()
data.audio_latency = context.jamClient.FTUEGetExpectedLatency().latency
data.tracks = tracks
rest.legacyCreateSession(data).done((response) =>
newSessionId = response.id
context.location = '/client#/session/' + newSessionId
# Re-loading the session settings will cause the form to reset with the right stuff in it.
# This is an extra xhr call, but it keeps things to a single codepath
loadSessionSettings()
context.JK.GA.trackSessionCount data.musician_access, data.fan_access, invitationCount
context.JK.GA.trackSessionMusicians context.JK.GA.SessionCreationTypes.create
).fail (jqXHR) =>
handled = false
if jqXHR.status = 422
response = JSON.parse(jqXHR.responseText)
if response['errors'] and response['errors']['tracks'] and response['errors']['tracks'][0] == 'Please select at least one track'
@app.notifyAlert 'No Inputs Configured', $('<span>You will need to reconfigure your audio device.</span>')
handled = true
if !handled
@app.notifyServerError jqXHR, 'Unable to Create Session'

View File

@ -0,0 +1,46 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
context.JK.JamtrackLicenseDialog = function(app) {
var logger = context.JK.logger;
var $dialog = null;
var dialogId = 'jamtrack-license-dialog';
function beforeShow(data) {
}
function afterShow(data) {
}
function afterHide() {
}
function showDialog() {
return app.layout.showDialog(dialogId);
}
function events() {
}
function initialize() {
var dialogBindings = {
'beforeShow' : beforeShow,
'afterShow' : afterShow,
'afterHide': afterHide
};
app.bindDialog(dialogId, dialogBindings);
$dialog = $('[layout-id="' + dialogId + '"]');
events();
}
this.initialize = initialize;
this.showDialog = showDialog;
};
return this;
})(window,jQuery);

View File

@ -0,0 +1,61 @@
$ = jQuery
context = window
context.JK ||= {}
context.JK.JamtrackPaymentHistoryDialog = class JamtrackPaymentHistoryDialog
constructor: (@app) ->
@rest = context.JK.Rest()
@client = context.jamClient
@logger = context.JK.logger
@screen = null
@dialogId = 'jamtrack-payment-history-dialog';
@dialog = null;
initialize:() =>
dialogBindings = {
'beforeShow' : @beforeShow,
'afterShow' : @afterShow
}
@dialog = $('[layout-id="' + @dialogId + '"]');
@app.bindDialog(@dialogId, dialogBindings);
@tbody = @dialog.find("table.payment-table tbody")
@rowTemplate = $('#template-payment-history-row').html()
beforeShow:() =>
# Get payment history from jamrest
payments = [
{date: new Date(2013, 4, 5), amount: 372.33},
{date: new Date(2014, 5, 5), amount: 338.44}
]
@rest.getPaymentHistory()
.done(@showPaymentHistory)
.fail(@app.ajaxError)
showPaymentHistory:(data) =>
# Turn in to HTML rows and append:
@tbody.html("")
if data.payments? && data.payments.length > 0
for p in data.payments
amt = p.amount
amt = 0 if !amt?
payment = {
date: context.JK.formatDateYYYYMMDD(p.created_at)
amount: (amt * 100).toFixed(2)
status: p.status
payment_method: p.payment_method.replace("_", " ")
reference: p.reference
}
tr = $(context._.template(@rowTemplate, payment, { variable: 'data' }));
@tbody.append(tr);
else
tr = "<tr><td colspan='5'>No payments found</td></tr>"
@tbody.append(tr);
afterShow:() =>
showDialog:() =>
@app.layout.showDialog(@dialogId)

View File

@ -27,6 +27,8 @@
CHAT: "1"
};
context.JK.AVAILABILITY_US = "United States";
context.JK.EVENTS = {
DIALOG_CLOSED : 'dialog_closed',
SHOW_SIGNUP : 'show_signup',

View File

@ -1474,6 +1474,15 @@
});
}
function getPaymentHistory(options) {
return $.ajax({
type: "GET",
url: '/api/recurly/payment_history',
dataType: "json",
contentType: 'application/json'
});
}
function getBackingTracks(options) {
return $.ajax({
type: "GET",
@ -1735,6 +1744,7 @@
this.updateAudioLatency = updateAudioLatency;
this.getJamtracks = getJamtracks;
this.getPurchasedJamTracks = getPurchasedJamTracks;
this.getPaymentHistory = getPaymentHistory;
this.getJamTrackRight = getJamTrackRight;
this.enqueueJamTrack = enqueueJamTrack;
this.getBackingTracks = getBackingTracks;

View File

@ -0,0 +1,243 @@
$ = jQuery
context = window
context.JK ||= {}
context.JK.JamTrackScreen=class JamTrackScreen
LIMIT = 10
instrument_logo_map = context.JK.getInstrumentIconMap24()
constructor: (@app) ->
@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 = false
beforeShow:(data) =>
this.setFilterFromURL()
this.refresh()
afterShow:(data) =>
events:() =>
@genre.on 'change', this.search
@artist.on 'change', this.search
@instrument.on 'change', this.search
@availability.on 'change', this.search
clearResults:() =>
#$logger.debug("CLEARING CONTENT")
@currentPage = 0
@content.empty()
@noMoreJamtracks.hide()
@next = null
setFilterFromURL:() =>
# Grab parms from URL for artist, instrument, and availability
parms=this.getParams()
this.logger.debug("parms", parms)
if(parms.artist?)
@artist.val(parms.artist)
if(parms.instrument?)
@instrument.val(parms.instrument)
if(parms.availability?)
@availability.val(parms.availability)
window.history.replaceState({}, "", "/client#/jamtrack")
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
refresh:() =>
@currentQuery = this.buildQuery()
that = this
rest.getJamtracks(@currentQuery).done((response) ->
that.clearResults()
that.handleJamtrackResponse(response)
).fail (jqXHR) ->
that.clearResults()
that.noMoreJamtracks.show()
that.app.notifyServerError jqXHR, 'Jamtrack Unavailable'
search:() =>
this.refresh()
false
defaultQuery:() =>
query =
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) =>
#logger.debug("Handling response", JSON.stringify(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 '<div class=\'no-jamtracks-msg\'>There\'s no jamtracks.</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:() =>
@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(this.buildQuery())
}, (json, opts) ->
this.handleJamtrackResponse(json)
@scroller.infinitescroll 'resume'
playJamtrack:(e) =>
e.preventDefault()
addToCartJamtrack:(e) =>
e.preventDefault()
params = id: $(e.target).attr('data-jamtrack-id')
rest.addJamtrackToShoppingCart(params).done((response) ->
context.location = '/client#/shoppingCart'
).fail @app.ajaxError
licenseUSWhy:(e) =>
e.preventDefault()
@app.layout.showDialog 'jamtrack-availability-dialog'
registerEvents:() =>
@screen.find('.jamtrack-detail-btn').on 'click', this.showJamtrackDescription
@screen.find('.play-button').on 'click', this.playJamtrack
@screen.find('.jamtrack-add-cart').on 'click', this.addToCartJamtrack
@screen.find('.license-us-why').on 'click', this.licenseUSWhy
@screen.find('.jamtrack-detail-btn').on 'click', this.toggleExpanded
renderJamtracks:(data) =>
that = this
for jamtrack in data.jamtracks
for track in jamtrack.tracks
continue if track.track_type=='Master'
inst = '../assets/content/icon_instrument_default24.png'
if track.instrument.id in instrument_logo_map
inst = instrument_logo_map[track.instrument.id].asset
track.instrument_url = inst
track.instrument_desc = track.instrument.description
if track.part != ''
track.instrument_desc += ' (' + track.part + ')'
options =
jamtrack: jamtrack
expanded: that.expanded
@jamtrackItem = $(context._.template($('#template-jamtrack').html(), options, variable: 'data'))
that.renderJamtrack(@jamtrackItem)
this.registerEvents()
showJamtrackDescription:(e) =>
e.preventDefault()
@description = $(e.target).parent('.detail-arrow').next()
if @description.css('display') == 'none'
@description.show()
else
@description.hide()
toggleExpanded:() =>
this.expanded = !this.expanded
this.refresh()
renderJamtrack:(jamtrack) =>
@content.append jamtrack
initialize:() =>
screenBindings =
'beforeShow': this.beforeShow
'afterShow': this.afterShow
@app.bindScreen 'jamtrack', 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')
@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')
if @availability.length == 0
throw new Error('@availability must be specified')
this.events()

View File

@ -1,263 +0,0 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
context.JK.JamTrackScreen = function(app) {
var logger = context.JK.logger;
var $screen = null;
var $content = null;
var $scroller = null;
var $genre = null;
var $instrument = null;
var $availability = null;
var $nextPager = null;
var $noMoreJamtracks = null;
var currentQuery = defaultQuery();
var currentPage = 0;
var LIMIT = 10;
var next = null;
var instrument_logo_map = context.JK.getInstrumentIconMap24();
function beforeShow(data) {
refresh();
}
function afterShow(data) {
}
function events() {
$genre.on("change", search);
$instrument.on("change", search);
$availability.on("change", search);
}
function clearResults() {
//logger.debug("CLEARING CONTENT")
currentPage = 0;
$content.empty();
$noMoreJamtracks.hide();
next = null;
}
function refresh() {
currentQuery = buildQuery();
rest.getJamtracks(currentQuery)
.done(function(response) {
clearResults();
handleJamtrackResponse(response);
})
.fail(function(jqXHR) {
clearResults();
$noMoreJamtracks.show();
app.notifyServerError(jqXHR, 'Jamtrack Unavailable')
})
}
function search() {
logger.debug("Searching for jamtracks...");
refresh();
return false;
}
function defaultQuery() {
var query = { per_page:LIMIT, page:currentPage + 1};
if(next) {
query.since = next;
}
return query;
}
function buildQuery() {
currentQuery = defaultQuery();
// genre filter
var genres = $screen.find('#jamtrack_genre').val();
if (genres !== undefined) {
currentQuery.genre = genres;
}
// instrument filter
var instrument = $instrument.val();
if (instrument !== undefined) {
currentQuery.instrument = instrument;
}
// availability filter
var availability = $availability.val();
if (availability !== undefined) {
currentQuery.availability = availability;
}
return currentQuery;
}
function handleJamtrackResponse(response) {
//logger.debug("Handling response", JSON.stringify(response))
next = response.next;
renderJamtracks(response);
if(response.next == null) {
// if we less results than asked for, end searching
$scroller.infinitescroll('pause');
logger.debug("end of jamtracks");
if(currentPage == 0 && response.jamtracks.length == 0) {
$content.append("<div class='no-jamtracks-msg'>There's no jamtracks.</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++;
buildQuery();
registerInfiniteScroll();
}
}
function registerInfiniteScroll() {
$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: function(page) {
return '/api/jamtracks?' + $.param(buildQuery());
}
},function(json, opts) {
handleJamtrackResponse(json);
});
$scroller.infinitescroll('resume');
}
function playJamtrack(e) {
e.preventDefault();
}
function addToCartJamtrack(e) {
e.preventDefault();
var params = {id: $(e.target).attr("data-jamtrack-id")};
rest.addJamtrackToShoppingCart(params)
.done(function(response) {
context.location = "/client#/shoppingCart";
})
.fail(app.ajaxError);
}
function licenseUSWhy(e) {
e.preventDefault();
app.layout.showDialog('jamtrack-availability-dialog');
}
function registerEvents() {
$screen.find('.jamtrack-detail-btn').on("click", showJamtrackDescription);
$screen.find('.play-button').on('click', playJamtrack);
$screen.find('.jamtrack-add-cart').on('click', addToCartJamtrack);
$screen.find('.license-us-why').on('click', licenseUSWhy);
}
function renderJamtracks(data) {
$.each(data.jamtracks, function(i, jamtrack) {
$.each(jamtrack.tracks, function (index, track) {
if(track.track_type == 'Master') {
return; // continue
}
var inst = '../assets/content/icon_instrument_default24.png';
if (track.instrument.id in instrument_logo_map) {
inst = instrument_logo_map[track.instrument.id].asset;
}
track.instrument_url = inst;
track.instrument_desc = track.instrument.description;
if (track.part != "") {
track.instrument_desc += " ( " + track.part + " )";
}
});
var options = {
jamtrack: jamtrack
};
var $jamtrackItem = $(
context._.template(
$('#template-jamtrack').html(),
options,
{variable: 'data'}
)
);
renderJamtrack($jamtrackItem );
});
registerEvents();
}
function showJamtrackDescription(e) {
e.preventDefault();
var $description = $(e.target).parent(".detail-arrow").next();
if ($description.css("display") == "none") {
$description.show();
}
else {
$description.hide();
}
}
function renderJamtrack(jamtrack) {
$content.append(jamtrack);
}
function initialize() {
var screenBindings = {
'beforeShow': beforeShow,
'afterShow': afterShow
};
app.bindScreen('jamtrack', screenBindings);
$screen = $("#jamtrack-find-form");
$scroller = $screen.find('.content-body-scroller');
$content = $screen.find(".jamtrack-content");
$genre = $screen.find("#jamtrack_genre");
$instrument = $screen.find("#jamtrack_instrument");
$availability = $screen.find("#jamtrack_availability");
$nextPager = $screen.find("a.btn-next-pager");
$noMoreJamtracks = $screen.find("#end-of-jamtrack-list");
if($screen.length == 0) throw "$screen must be specified";
if($scroller.length == 0) throw "$scroller must be specified";
if($content.length == 0) throw "$content must be specified";
if($noMoreJamtracks.length == 0) throw "$noMoreJamtracks must be specified";
if($genre.length == 0) throw "$genre must be specified";
if($instrument.length == 0) throw "$instrument must be specified";
if($availability.length ==0) throw "$availability must be specified";
events();
}
this.initialize = initialize;
return this;
}
})(window,jQuery);

View File

@ -0,0 +1,53 @@
$ = jQuery
context = window
context.JK ||= {}
context.JK.JamTrackLanding = class JamTrackLanding
constructor: (@app) ->
@rest = context.JK.Rest()
@client = context.jamClient
@logger = context.JK.logger
@screen = null
initialize:() =>
screenBindings =
'beforeShow': @beforeShow
'afterShow': @afterShow
@app.bindScreen('jamtrackLanding', screenBindings)
@screen = $('#jamtrackLanding')
beforeShow:() =>
# Get artist names and build links
@rest.getJamtracks({group_artist: true})
.done(this.buildArtistLinks)
.fail(this.handleFailure)
# Bind links to action that will open the jam_tracks list view filtered to given artist_name:
# artist_name
this.bindArtistLinks()
afterShow:() =>
buildArtistLinks:(response) =>
# Get artist names and build links
jamtracks = response.jamtracks
$("#band_list>li:not('#no_bands_found')").remove()
if jamtracks.length==0
$("#no_bands_found").removeClass("hidden")
else
$("#no_bands_found").addClass("hidden")
# client#/jamtrack
for jamtrack in jamtracks
artistLink = "<a href='client?artist=#{encodeURIComponent(jamtrack.original_artist)}#/jamtrack' class='artist-link' artist='#{jamtrack.original_artist}'>#{jamtrack.original_artist}</a>"
$("#band_list").append("<li>#{artistLink}</li>")
# We don't want to do a full page load if this is clicked on here:
bindArtistLinks:() =>
band_list=$("ul#band_list")
that=this
band_list.on "click", "a.artist-link", (event)->
context.location="client#/jamtrack"
window.history.replaceState({}, "", this.href)
event.preventDefault()
handleFailure:(error) =>

View File

@ -42,6 +42,7 @@
step = 2;
renderNavigation();
renderAccountInfo();
$("#order_error").addClass("hidden")
}
function resetJamTrackDownloadInfo() {

View File

@ -474,8 +474,8 @@
}
/** account sessions */
.account-sessions {
div#account-scheduled-sessions {
.account-sessions, .account-jamtracks {
div#account-scheduled-sessions, #account-my-jamtracks {
position: relative;
display: block;
overflow: auto;

View File

@ -387,6 +387,10 @@ a.arrow-down {
select {
font-size:11px;
margin-top:4px;
}
.dropdown-wrapper {
margin-right: 4px;
}
}

View File

@ -1,4 +1,74 @@
@import 'common';
#jamtrackLanding {
ul {
li {
margin: 1px 4px 1px 4em;
font-size:9px;
}
}
.list-columns {
h2 {
font-size: 16pt;
font-weight:300;
font-style: bolder;
font-family: verdana;
text-transform: lowercase;
margin-bottom: 2em;
}
.free-jamtrack {
font-size: 11pt;
padding: 3px;
@include border-radius(7px);
background-color:$ColorScreenPrimary;
text-align: center;
vertical-align: center;
}
.what, .howto {
margin-bottom: 2em;
}
p {
font-size: 12pt !important;
font-weight: normal;
line-height: 16px;
color: #dddddd;
* {
font-size: 10pt !important;
font-weight: normal;
line-height: 16px;
}
}
.about {
@include border_box_sizing;
float: left;
width: 50%;
> * {
margin: 4px;
}
}
.browse {
@include border_box_sizing;
float: left;
width: 50%;
> * {
margin: 4px;
}
}
}
}
#jamtrackScreen {
.jamtrack-header {
background-color: #4c4c4c;
font-weight: bold;
text-transform: uppercase;
height: 2em;
padding: 4px;
}
a.jamtrack_help {
color: #fff;
text-decoration: none;
@ -11,6 +81,8 @@
.jamtrack-content {
text-align: center;
border: 1px solid #222222;
padding: 2px
}
.no-jamtracks-msg {
@ -23,14 +95,16 @@
}
.jamtrack-detail {
@include border_box_sizing;
float: left;
width: 50%;
width: 30%;
padding: 10px 0px;
.detail-label {
width: 40%;
float: left;
margin-top: 5px;
font-weight: 400;
font-size: 11pt;
}
.detail-value {
@ -56,15 +130,17 @@
.jamtrack-detail-btn {
cursor: pointer;
margin-top: 5px;
margin-top: 7px;
margin-right: 5px;
padding-top: 5px;
vertical-align: bottom;
}
}
.jamtrack-tracks {
@include border_box_sizing;
float: left;
width: 25%;
width: 50%;
padding: 10px 0px;
.tracks-caption {
@ -78,6 +154,7 @@
.instrument-image {
float: left;
margin-right: 2px;
}
.instrument-desc {
@ -88,8 +165,9 @@
}
.jamtrack-action {
@include border_box_sizing;
float: left;
width: 25%;
width: 20%;
padding: 10px 0px;
text-align: center;
@ -113,4 +191,30 @@
width: 60%;
}
}
}
#jamtrack-license-dialog {
.dialog-inner {
height: auto;
.content-body {
max-height: auto;
.content-body-scroller {
height: 350px;
.paragraph {
margin-bottom: 1em;
}
overflow: hidden;
}
border: 1px solid #222;
margin: 4px 4px 8px 4px;
}
}
}
.jamtrack_buttons {
margin: 8px 4px 12px 4px;
}
.capitalize {
text-transform: capitalize
}

View File

@ -1,7 +1,7 @@
@import "client/common";
table.findsession-table, table.local-recordings, table.open-jam-tracks, table.open-backing-tracks, #account-session-detail {
table.findsession-table, table.local-recordings, table.open-jam-tracks, table.open-backing-tracks, table.cart-items, #account-session-detail, table.payment-table {
.latency-unacceptable {
width: 50px;
@ -64,7 +64,7 @@ table.findsession-table, table.local-recordings, table.open-jam-tracks, table.op
text-align:center;
}
}
table.findsession-table, table.local-recordings, table.open-jam-tracks, table.open-backing-tracks {
table.findsession-table, table.local-recordings, table.open-jam-tracks, table.open-backing-tracks, table.cart-items, table.payment-table {
width:98%;
height:10%;
font-size:11px;

View File

@ -29,9 +29,7 @@
}
.cart-item-caption {
width: 50%;
text-align: left;
float: left;
text-align: left;
}
.cart-item-caption#header {
@ -39,21 +37,15 @@
}
.cart-item-price {
width: 15%;
text-align: right;
float: left;
text-align: right;
}
.cart-item-quantity {
width: 15%;
text-align: right;
float: left;
text-align: right;
}
.cart-item-actions {
width: 20%;
text-align: center;
float: left;
//text-align: center;
}
.cart-items {

View File

@ -83,6 +83,14 @@ class ApiRecurlyController < ApiController
render json: { message: x.inspect, errors: x.errors}, :status => 404
end
# get Recurly payment history
def payment_history
@payments=@client.payment_history(current_user)
render :json=>{payments: @payments}
rescue RecurlyClientError => x
render json: { message: x.inspect, errors: x.errors}, :status => 404
end
# update Recurly account
def update_account
@account=@client.update_account(current_user, params[:billing_info])

View File

@ -26,7 +26,7 @@ class ApiUsersController < ApiController
@user = User.includes([{musician_instruments: :instrument},
{band_musicians: :user},
{genre_players: :genre},
:bands, :instruments, :genres])
:bands, :instruments, :genres, :jam_track_rights])
.find(params[:id])
respond_with @user, responder: ApiResponder, :status => 200

View File

@ -10,6 +10,10 @@ node :added_cart do |item|
any_user.shopping_carts.where("cart_id='?'",item.id).count != 0
end
node :purchased do |item|
!!item.right_for_user(current_user)
end
child(:jam_track_tracks => :tracks) {
attributes :id, :part, :instrument, :track_type
}

View File

@ -1,6 +1,10 @@
object @jam_track
attributes :id, :name, :description, :initial_play_silence, :original_artist, :version
attributes :id, :name, :description, :initial_play_silence, :original_artist, :version, :genre
node :genre do |jam_track|
jam_track.genre.present? ? jam_track.genre.id : nil
end
node :jmep do |jam_track|
jam_track.jmep_json ? JSON.parse(jam_track.jmep_json) : nil

View File

@ -1,6 +1,6 @@
object @user
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :follower_count, :following_count, :recording_count, :session_count, :biography, :favorite_count, :audio_latency, :upcoming_session_count, :reuse_card
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :follower_count, :following_count, :recording_count, :session_count, :biography, :favorite_count, :audio_latency, :upcoming_session_count, :reuse_card, :purchased_jamtracks_count
if @user.musician?
node :location do @user.location end

View File

@ -94,18 +94,19 @@
<hr />
<div class="account-left">
<h2>subscriptions:</h2>
<h2>jamtracks:</h2>
</div>
<div class="account-mid subscriptions">
<!--<strong>Studio:</strong> Gold ($49.99/year)<br />
<strong>NaaS:</strong> Yes ($29.99/year)-->
<strong>N/A</strong><br />
<strong>This feature not yet implemented</strong>
<strong class="jamtrack-license-detail">
{{data.licenseDetail}}
</strong>
<br clear="all" />
<a href="#" class="view-license" id="account-view-license-link">JamTracks License</a>
</div>
<div class="right">
<!--<a id="account-edit-subscriptions-link" href="#" class="button-orange">UPDATE</a>-->
<a id="account-my-jamtracks-link" href="#" class="button-orange">UPDATE</a>
</div>
<br clear="all" />
@ -117,14 +118,11 @@
</div>
<div class="account-mid payments">
<!--<strong>Method:</strong> MasterCard &bull;&bull;&bull;&bull; &bull;&bull;&bull;&bull; &bull;&bull;&bull;&bull; 1234<br />
<a href="#">View Payment History</a>&nbsp;&nbsp;<a href="#">Cancel Subscription</a> -->
<strong>N/A</strong></br />
<strong>This feature not yet implemented</strong>
<a id="account-payment-history-link" href="#">View Payment History</a>
</div>
<div class="right">
<!--<a id="account-edit-payments-link" href="#" class="button-orange">UPDATE</a>-->
<a id="account-payment-history-link" href="#" class="button-orange">VIEW</a>
</div>
<br clear="all" />

View File

@ -0,0 +1,39 @@
/! Account jamtracks Dialog
#account-jamtracks.screen.secondary layout='screen' layout-id='account/jamtracks'
.content-head
.content-icon
= image_tag "content/icon_account.png", :width => 27, :height => 20
h1 my account
= render "screen_navigation"
/! jamtracks scrolling area
.content-body
.content-body-scroller.account-content-scroller#account-jamtracks-content-scroller
.content-wrapper.account-jamtracks
.jamtracks-header
.left.jamtracks-caption
h2 my jamtracks:
.clearall
#account-my-jamtracks
table.generaltable
thead
th TITLE
th ORIGINAL ARTIST
th ACTIONS
tbody
.right
a.button-grey href="javascript:history.go(-1)" BACK
script#template-account-jamtrack type='text/template'
tbody
= "{% _.each(data.jamtracks, function(jamtrack) { %}"
tr data-id="{{jamtrack.id}}" data-genre="{{jamtrack.genre}}"
td
| {{jamtrack.name}}
td
| {{jamtrack.original_artist}}
td
.table-link: a.jamtrack-solo-session href= '#' jamtrack-id="{{jamtrack.id}}" Get into solo session
.table-link: a.jamtrack-group-session href= '#' jamtrack-id="{{jamtrack.id}}" Get into session others can join
= "{% }); %}"

View File

@ -67,7 +67,7 @@
.homebox-info
-if jamtracks
/! 1 session invitation, 19 public sessions active
.homecard.jamtrack layout-grid-columns=small_tile_size layout-grid-position=column_positions[2] layout-grid-rows="1" layout-link="jamtrack"
.homecard.jamtrack layout-grid-columns=small_tile_size layout-grid-position=column_positions[2] layout-grid-rows="1" layout-link="jamtrackLanding"
h2 jamtracks
.homebox-info
/! 5 followers, 3 following

View File

@ -1,83 +0,0 @@
%div{ layout: 'screen', :'layout-id' => 'jamtrack', id: 'jamtrackScreen', :class => 'screen secondary no-login-required'}
.content
.content-head
.content-icon= image_tag("content/icon_jamtracks.png", {:height => 19, :width => 19})
%h1 jamtracks
%a{href: "#", class: "jamtrack_help"} What is a JamTrack?
= render "screen_navigation"
.content-body
= form_tag('', {:id => 'jamtrack-find-form', :class => 'inner-content'}) do
= render(:partial => "web_filter", :locals => {:search_type => Search::PARAM_JAMTRACK})
.filter-body
.content-body-scroller
.profile-wrapper
.jamtrack-content
%a{href: "/api/jamtracks?page=1", class: "btn-next-pager"}= 'Next'
%div{id: 'end-of-jamtrack-list', class: 'end-of-list'}= 'No more Jamtracks'
%script{type: 'text/template', id: 'template-jamtrack'}
.jamtrack-record{"jamtrack-id" => "{{data.jamtrack.id}}"}
.jamtrack-detail
.detail-label
Name:
.detail-value
{{data.jamtrack.name}}
.clearall.detail-label
Type:
.detail-value
{{data.jamtrack.recording_type}}
.clearall.detail-label
Original Artist:
.detail-value
{{data.jamtrack.original_artist}}
.clearall.detail-label
Genre:
.detail-value
{{data.jamtrack.genres[0]}}
.clearall.detail-label
Writer/Composer:
.detail-value
{{[data.jamtrack.songwriter, data.jamtrack.publisher].join(", ")}}
.clearall.detail-label
Copyright:
.copyright-value
= "{% if (data.jamtrack.licensor != null) { %}"
{{data.jamtrack.licensor.name}}
="{% }; %}"
.detail-arrow
= image_tag 'down_arrow.png', class: 'jamtrack-detail-btn'
.clearall.jamtrack-description
.detail-label
Description
.detail-value
{{data.jamtrack.description}}
.clearall
.jamtrack-tracks
.tracks-caption
Tracks in This Recording:
= "{% _.each(data.jamtrack.tracks, function(track) { %}"
= "{% if(track.track_type == 'Master') return; %}"
.track-instrument
.instrument-image
%img{src: "{{track.instrument_url}}", width: 24, height: 24}
.instrument-desc
{{track.instrument_desc}}
.clearall
= "{% }); %}"
.jamtrack-action
%a{href: "#", class: 'play-button', "data-jamtrack-id" => "{{data.jamtrack.id}}"}
= image_tag 'shared/play_button.png'
.jamtrack-price
{{"$ " + data.jamtrack.price}}
= "{% if (data.jamtrack.added_cart) { %}"
%a.jamtrack-add-cart-disabled.button-grey.button-disabled{href: "javascript:void(0)"} Purchased
= "{% } else { %}"
%a.jamtrack-add-cart.button-orange{href: "#", "data-jamtrack-id" => "{{data.jamtrack.id}}"} Add to Cart
= "{% }; %}"
= "{% if (data.jamtrack.sales_region == 'United States') { %}"
.jamtrack-license
This JamTrack available only to US customers.
%a{href: "#", class: 'license-us-why'} why?
= "{% }; %}"
.clearall

View File

@ -0,0 +1,114 @@
#jamtrackScreen.screen.secondary.no-login-required layout='screen' layout-id='jamtrack'
.content
.content-head
.content-icon=image_tag("content/icon_jamtracks.png", height:19, width:19 )
h1 jamtracks
=render "screen_navigation"
.content-body
=form_tag('', {:id => 'jamtrack-find-form', :class => 'inner-content'}) do
=render(:partial => "web_filter", :locals => {:search_type => Search::PARAM_JAMTRACK})
.filter-body
.content-body-scroller
.profile-wrapper
.jamtrack-content
a.btn-next-pager href="/api/jamtracks?page=1" Next
.end-of-jamtrack-list.end-of-list="No more Jamtracks"
script type='text/template' id='template-jamtrack'
.jamtrack-record jamtrack-id="{{data.jamtrack.id}}"
.top_bar
.jamtrack-detail.jamtrack-header JAMTRACK
.jamtrack-tracks.jamtrack-header TRACKS INCLUDED/PREVIEW
.jamtrack-action.jamtrack-header SHOP
.jamtrack-detail
.detail-label
| Title:
.detail-value
| {{data.jamtrack.name}}
/ .clearall.detail-label
/ | Type:
/ .detail-value
/ | {{data.jamtrack.recording_type}}
/ .clearall.detail-label
/ | Original Artist:
/ .detail-value
/ | {{data.jamtrack.original_artist}}
.clearall.detail-label
| Original Artist:
.detail-value
| {{data.jamtrack.original_artist}}
.clearall.detail-label
| Genre:
.detail-value
| {{data.jamtrack.genres[0]}}
="{% if (data.expanded) { %}"
.clearall.detail-label
| Writer(s):
.detail-value
| {{data.jamtrack.songwriter}}
.clearall.detail-label
| Publisher:
.detail-value
| {{data.jamtrack.publisher}}
.clearall.detail-label
| Description:
.detail-value
| {{data.jamtrack.description}}
="{% } %}"
/ / / .clearall.detail-label
/ | Copyright:
/ .copyright-value
/ ="{% if (data.jamtrack.licensor !=null) { %}"
/ | {{data.jamtrack.licensor.name}}
/ ="{% }; %}"
/ .clearall.jamtrack-description
/ .detail-label
/ | Description
/ .detail-value
/ | {{data.jamtrack.description}}
/ .clearall
.jamtrack-tracks
/ .tracks-caption
/ | Tracks in This Recording:
="{% counter = 0 %}"
="{% _.each(data.jamtrack.tracks, function(track) { %}"
="{% if(track.track_type == 'Master') return; %}"
.track-instrument href="{{track.url_44}}"
.instrument-image
img src="/assets/shared/play_button.png" width=24 height=24
.instrument-image
img src="{{track.instrument_url}}" width=24 height=24
.instrument-desc
| {{track.instrument_desc}}
.clearall
="{% }); %}"
.detail-arrow
.jamtrack-detail-btn
="{% if (data.expanded) { %}"
| hide tracks
=image_tag("up_arrow.png")
="{% } else { %}"
| preview all tracks
=image_tag("down_arrow.png")
="{% } %}"
.jamtrack-action
/ a.play-button href="#" data-jamtrack-id="{{data.jamtrack.id}}"
/ =image_tag "shared/play_button.png"
.jamtrack-price
| {{"$ " + data.jamtrack.price}}
="{% if (data.jamtrack.purchased) { %}"
a.jamtrack-add-cart-disabled.button-grey.button-disabled href="javascript:void(0)" Purchased
="{% } else if (data.jamtrack.added_cart) { %}"
a.jamtrack-add-cart-disabled.button-grey.button-disabled href="client#/shoppingCart" Already In Cart
="{% } else { %}"
a.jamtrack-add-cart.button-orange href="#" data-jamtrack-id="{{data.jamtrack.id}}" Add to Cart
="{% }; %}"
="{% if (data.jamtrack.sales_region==JK.AVAILABILITY_US) { %}"
.jamtrack-license
| This JamTrack available only to US customers.
a.license-us-why href="#", why?
="{% }; %}"
.clearall

View File

@ -0,0 +1,35 @@
#jamtrackLanding.screen.secondary layout='screen' layout-id='jamtrackLanding'
.content
.content-head
.content-icon=image_tag("content/icon_jamtracks.png", height:19, width:19)
h1 jamtracks
= render "screen_navigation"
.content-body
.list-columns
.about
h2 what are jamtracks?
p.what
.details JamTracks are the best way to play along with your favorite music! Unlike traditional backing tracks, JamTracks are professionally mastered, complete multitrack recordings, with fully isolated tracks for each and every part of the master mix. Used with the free JamKazam app & Internet service, you can:
ul
li Solo just the part you want to play in order to hear and learn it
li Mute just the part you want to play and play along with the rest
li Make audio recordings and share them via Facebook or URL
li Make video recordings and share them via YouTube
li And even go online to play with others in real time -- for example, you can play the electric guitar lead, while someone else plays the bass, and all other parts play from the recorded tracks in your session
/ TODO: put in video thumbnail when available:
.browse
h2 my jamtracks
p.howto
.details
span="To play with your JamTracks, open a JamTrack while in a session in the JamKazam app. Or "
a href="client#/jamtrack" visit the JamTracks Section of your account.
.free-jamtrack.orange-fill
| For a limited time, get one JamTrack free. Browse JamTracks below, add one to your shopping cart, and we'll make it free during the checkout process.
h2 browse jamtracks
.browse-header
span="browse by band "
a href="client#/jamtrack" or browse all jamtracks
.band-browse
ul#band_list
li#no_bands_found.hidden No bands found

View File

@ -19,35 +19,37 @@
.clearall
%script{type: 'text/template', id: 'template-shopping-cart-body'}
.cart-items
.cart-item-caption#header
Your shopping cart now contains:
.cart-item-price
%span{style: "text-decoration: underline;"} Price
.cart-item-quantity
%span{style: "text-decoration: underline;"} Quantity
.clearall
%table.cart-items
%tr
%th.cart-item-caption
YOUR SHOPPING CART NOW CONTAINS:
%th.cart-item-price
Price
%th.cart-item-quantity
Quantity
%th
= "{% if (data.carts.length == 0) { %}"
.no-cart-items Nothing in cart
%tr
%td.no-cart-items colspan=4 Nothing in cart
= "{% } %}"
= "{% _.each(data.carts, function(cart) { %}"
.cart-item{"cart-id" => "{{cart.id}}"}
.cart-item-caption
%tr.cart-item{"cart-id" => "{{cart.id}}"}
%td.cart-item-caption
{{cart.cart_type}}: {{cart.product_info.name}}
.cart-item-price
%td.cart-item-price
$ {{cart.product_info.price}}
.cart-item-quantity
%td.cart-item-quantity
{{cart.quantity}}
.cart-item-actions
%a.button-grey.remove-cart{href: "#", "cart-id" => "{{cart.id}}"} DELETE
.clearall
%td.cart-item-actions
%a.button-grey.remove-cart{href: "#", "cart-id" => "{{cart.id}}"}
DELETE
= "{% }); %}"
.shopping-sub-total
Subtotal: $ {{data.sub_total}}
.clearall
.left
%a.button-grey{href: "#"} HELP
.right
%a.button-grey{href: "#"} HELP
%a.button-orange{href: "/client#/jamtrack"} CONTINUE SHOPPING
%a.button-orange.proceed-checkout{href: "#"} PROCEED TO CHECKOUT
.clearall

View File

@ -11,41 +11,31 @@
=content_tag(:div, :id => defined?(id) ? id : 'session-controls', :class => "#{filter_label}-filter filter-head") do
=content_tag(:div, :class => "filter-element wrapper") do
-if :feed==filter_label
/ @begin sort filter
=content_tag(:div, 'Sort Feed by:', :class => 'filter-element desc')
=select_tag("#{filter_label}_order_by", options_for_select(Search::F_SORT_OPTS), {:class => "#{filter_label}-order-by easydropdown" } )
/ @end sort filter
=select_tag("#{filter_label}_order_by", options_for_select(Search::F_SORT_OPTS), {:class => "#{filter_label}-order-by easydropdown" } )
-elsif :jamtrack !=filter_label
/ @begin order by filter
=content_tag(:div, 'Order By:', :class => 'filter-element desc')
=select_tag("#{filter_label}_order_by", options_for_select(Search::M_ORDERINGS), {:class => "#{filter_label}-order-by easydropdown"} )
/ @end order by filter
=select_tag("#{filter_label}_order_by", options_for_select(Search::M_ORDERINGS), {:class => "#{filter_label}-order-by easydropdown"} )
=content_tag(:div, :class => 'filter-element wrapper') do
/ -if (:band==filter_label || :jamtrack==filter_label)
/ =content_tag(:div, 'Genre:', :class => 'filter-element desc')
/ =select_tag("#{filter_label}_genre", |
/ options_for_select([['Any', '']].concat(JamRuby::Genre.all.collect { |ii| [ii.description, ii.id] })), {:class => 'easydropdown'}) |
-if :jamtrack==filter_label
=content_tag(:div, 'Filter JamTracks:', :class => 'filter-element desc')
=select_tag("#{filter_label}_artist", options_for_select([['Any Band', '']].concat(JamTrack.all_artists.collect { |ii| [ii, ii] })), {:class => 'easydropdown'})
=content_tag(:div, :class => 'filter-element wrapper') do
-if :band==filter_label || :jamtrack==filter_label
/ @begin genre filter
=content_tag(:div, 'Genre:', :class => 'filter-element desc')
=select_tag("#{filter_label}_genre", |
options_for_select([['Any', '']].concat(JamRuby::Genre.all.collect { |ii| [ii.description, ii.id] })), {:class => 'easydropdown'}) |
/ @end genre filter
-if :musician==filter_label || :jamtrack==filter_label
/ @begin instrument filter
=content_tag(:div, 'Instrument:', :class => 'filter-element desc instrument-selector')
=select_tag("#{filter_label}_instrument", |
options_for_select([['Any', '']].concat(JamRuby::Instrument.all.collect { |ii| [ii.description, ii.id] })), {:class=> "easydropdown"}) |
/ @end instrument filter
/ =content_tag(:div, 'Instrument:', :class => 'filter-element desc instrument-selector')
=select_tag("#{filter_label}_instrument", options_for_select([['Any Instrument', '']].concat(JamRuby::Instrument.all.collect { |ii| [ii.description, ii.id] })), {:class=> "easydropdown"}) |
-if :feed==filter_label
/ @begin date filter
=content_tag(:div, 'Include Dates:', :class => 'filter-element desc')
=select_tag("#{filter_label}_date", options_for_select(Search::DATE_OPTS), {:class => "easydropdown"})
/ @end date filter
/ =content_tag(:div, 'Include Dates:', :class => 'filter-element desc')
=select_tag("#{filter_label}_date", options_for_select(Search::DATE_OPTS), {:class => "easydropdown"})
=content_tag(:div, :class => 'filter-element wrapper') do
-if :feed==filter_label
/ @begin show filter
=content_tag(:div, 'Show:', :class => 'filter-element desc')
=select_tag("#{filter_label}_show", options_for_select(Search::SHOW_OPTS), {:class => "easydropdown"})
/ @end show filter
=select_tag("#{filter_label}_show", options_for_select(Search::SHOW_OPTS), {:class => "easydropdown"})
-elsif :musician==filter_label
/ @begin score filter
=content_tag(:div, 'Latency:', :class => 'filter-element desc latency-or-distance')
=content_tag(:div, :class => 'query-distance-params') do
=select_tag("musician_query_score", options_for_select(Search::M_SCORE_OPTS, Search::M_SCORE_DEFAULT), {:class => 'easydropdown'})
@ -53,26 +43,20 @@
#musician-search-city.filter-element.desc
to
%a#musician-change-filter-city{:href => "#"}
%span#musician-filter-city
/ @end score filter
%span#musician-filter-city
-elsif :jamtrack==filter_label
/ @begin availability filter
=content_tag(:div, 'Availability:', :class => 'filter-element desc')
=select_tag("#{filter_label}_availability", options_for_select([['Any', '']].concat(JamRuby::JamTrack::SALES_REGION), 'United States'), {:class => "easydropdown"})
/ @end availability filter
/ =content_tag(:div, 'Availability:', :class => 'filter-element desc')
=select_tag("#{filter_label}_availability", options_for_select([['Any Availability', '']].concat(JamRuby::JamTrack::SALES_REGION), 'United States'), {:class => "easydropdown"})
-else
/ @begin distance filter
=content_tag(:div, 'Within', :class => 'filter-element desc')
=content_tag(:div, :class => 'query-distance-params') do
-default_distance =:musician==filter_label ? Search::M_MILES_DEFAULT : Search::B_MILES_DEFAULT
=select_tag("#{filter_label}_query_distance", options_for_select(Search::DISTANCE_OPTS, default_distance), {:class => 'easydropdown'})
=content_tag(:div, :class => 'filter-element desc') do
miles of #{content_tag(:span, current_user ? current_user.current_city(request.remote_ip) : '', :id => "#{filter_label}-filter-city")}
/ @end distance filter
miles of #{content_tag(:span, current_user ? current_user.current_city(request.remote_ip) : '', :id => "#{filter_label}-filter-city")}
-if :feed==filter_label
.btn-refresh-holder
%a.button-grey.btn-refresh-entries{:href => "/client#/feed"} REFRESH
-elsif :musician==filter_label
.btn-refresh-holder
%a.button-grey.btn-refresh-entries{:href => "/client#/musicians"} REFRESH
/ @end web_filter
%a.button-grey.btn-refresh-entries{:href => "/client#/musicians"} REFRESH

View File

@ -38,6 +38,7 @@
<%= render "users/feed_music_session_ajax" %>
<%= render "users/feed_recording_ajax" %>
<%= render "jamtrack" %>
<%= render "jamtrack_landing" %>
<%= render "shopping_cart" %>
<%= render "checkout_signin" %>
<%= render "checkout_payment" %>
@ -54,6 +55,7 @@
<%= render "account_profile_avatar" %>
<%= render "account_audio_profile" %>
<%= render "account_sessions" %>
<%= render "account_jamtracks" %>
<%= render "account_session_detail" %>
<%= render "account_session_properties" %>
<%= render "inviteMusicians" %>
@ -157,6 +159,14 @@
var jamtrackAvailabilityDialog = new JK.JamtrackAvailabilityDialog(JK.app);
jamtrackAvailabilityDialog.initialize();
var jamtrackLicenseDialog = new JK.JamtrackLicenseDialog(JK.app);
jamtrackLicenseDialog.initialize();
var jamtrackPaymentHistoryDialog = new JK.JamtrackPaymentHistoryDialog(JK.app);
jamtrackPaymentHistoryDialog.initialize();
var audioProfileInvalidDialog = new JK.AudioProfileInvalidDialog(JK.app);
audioProfileInvalidDialog.initialize();
@ -182,6 +192,9 @@
var accountSessionsScreen = new JK.AccountSessions(JK.app);
accountSessionsScreen.initialize();
var accountJamTracksScreen = new JK.AccountJamTracks(JK.app);
accountJamTracksScreen.initialize();
var accountSessionDetailScreen = new JK.AccountSessionDetail(JK.app);
accountSessionDetailScreen.initialize(JK.InvitationDialogInstance);
@ -235,6 +248,11 @@
var jamtrackScreen = new JK.JamTrackScreen(JK.app);
jamtrackScreen.initialize();
var jamtrackLanding = new JK.JamTrackLanding(JK.app);
jamtrackLanding.initialize();
var shoppingCartScreen = new JK.ShoppingCartScreen(JK.app);
shoppingCartScreen.initialize();

View File

@ -25,6 +25,7 @@
= render 'dialogs/videoDialog'
= render 'dialogs/friendSelectorDialog'
= render 'dialogs/jamtrackAvailabilityDialog'
= render 'dialogs/jamtrackLicenseDialog'
= render 'dialogs/clientPreferencesDialog'
= render 'dialogs/audioProfileInvalidDialog'
= render 'dialogs/gettingStartedDialog'
@ -35,3 +36,4 @@
= render 'dialogs/openJamTrackDialog'
= render 'dialogs/openBackingTrackDialog'
= render 'dialogs/loginRequiredDialog'
= render 'dialogs/jamtrackPaymentHistoryDialog'

View File

@ -0,0 +1,18 @@
#jamtrack-license-dialog.dialog.dialog-overlay-sm layout='dialog' layout-id = 'jamtrack-license-dialog'
.content-head
h1 JamTrack License:
.dialog-inner
.content-body
.content-body-scroller
.paragraph
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam dignissim ut nunc at hendrerit. Vestibulum semper risus a libero fermentum, molestie convallis risus faucibus. Ut molestie hendrerit orci, id laoreet turpis malesuada nec. Cras sem urna, commodo finibus sodales eu, scelerisque et ligula. Vivamus congue urna lobortis, volutpat ex non, facilisis ante. Maecenas laoreet lacus sit amet justo tempus sagittis. Proin eget libero est. Nullam vulputate finibus nibh nec malesuada. Proin at odio dui. Cras venenatis pharetra ipsum sit amet mollis. Vivamus enim lectus, venenatis sit amet velit at, condimentum euismod dolor. Sed ut tellus in lacus finibus maximus quis ac tortor. Nullam ac purus tincidunt, vestibulum magna vel, hendrerit nunc. Nam tincidunt velit ut est congue ultrices. Integer id magna vulputate, consequat ante et, gravida nibh.
.paragraph
| Etiam ac neque vel ex sagittis cursus ut a nulla. Praesent id pretium metus. Duis rhoncus egestas magna ut fringilla. Aenean et lobortis sem. Duis at turpis luctus, auctor lectus vitae, consectetur ante. Donec feugiat ullamcorper lacus eu ultricies. Sed vitae turpis arcu. Nam faucibus facilisis sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque vel felis rutrum, elementum lacus euismod, ultricies leo.
.paragraph
| Etiam ac neque vel ex sagittis cursus ut a nulla. Praesent id pretium metus. Duis rhoncus egestas magna ut fringilla. Aenean et lobortis sem. Duis at turpis luctus, auctor lectus vitae, consectetur ante. Donec feugiat ullamcorper lacus eu ultricies. Sed vitae turpis arcu. Nam faucibus facilisis sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque vel felis rutrum, elementum lacus euismod, ultricies leo.
.paragraph
| Etiam non nisi magna. Sed diam sem, vulputate sit amet odio quis, vulputate pharetra nunc. Morbi commodo lacus in leo semper semper. Sed nulla felis, consequat dignissim dictum eu, elementum eget massa. Nulla luctus condimentum magna. Vestibulum in interdum erat. In porttitor fermentum mi, ac tincidunt nisi interdum vulputate.
.jamtrack_buttons
.right
a.button-grey class='btnCancel' layout-action='cancel' OK

View File

@ -0,0 +1,33 @@
#jamtrack-payment-history-dialog.dialog.dialog-overlay-sm layout='dialog' layout-id = 'jamtrack-payment-history-dialog'
.content-head
h1 Payment History:
.dialog-inner
.content-body
.content-body-scroller
table.payment-table
thead
tr
th DATE
th AMOUNT
th STATUS
th PAYMENT_METHOD
th REFERENCE
tbody
tr: td colspan="5" Loading payment history...
.jamtrack_buttons
.right
a.button-orange class='btnCancel' layout-action='cancel' OK
script#template-payment-history-row type="text/template"
tr
td
| {{data.date}}
td
| ${{data.amount}}
td.capitalize
| {{data.status}}
td.capitalize
| {{data.payment_method}}
td
| {{data.reference}}

View File

@ -259,6 +259,7 @@ SampleApp::Application.routes.draw do
match '/recurly/create_account' => 'api_recurly#create_account', :via => :post
match '/recurly/delete_account' => 'api_recurly#delete_account', :via => :delete
match '/recurly/get_account' => 'api_recurly#get_account', :via => :get
match '/recurly/payment_history' => 'api_recurly#payment_history', :via => :get
#match '/recurly/get_subscription' => 'api_recurly#get_subscription', :via => :get
match '/recurly/update_account' => 'api_recurly#update_account', :via => :put
match '/recurly/billing_info' => 'api_recurly#billing_info', :via => :get

View File

@ -3,10 +3,10 @@ require 'spec_helper'
describe "JamTrack Shopping", :js => true, :type => :feature, :capybara_feature => true do
let(:user) { FactoryGirl.create(:user) }
let(:jt_us) { FactoryGirl.create(:jam_track, :name=>'jt_us', sales_region: 'United States', make_track: true) }
let(:jt_ww) { FactoryGirl.create(:jam_track, :name=>'jt_ww', sales_region: 'Worldwide', make_track: true) }
let(:jt_rock) { FactoryGirl.create(:jam_track, :name=>'jt_rock', genre: JamRuby::Genre.find('rock'), make_track: true) }
let(:jt_blues) { FactoryGirl.create(:jam_track, :name=>'jt_blues', genre: JamRuby::Genre.find('blues'), make_track: true) }
let(:jt_us) { FactoryGirl.create(:jam_track, :name=>'jt_us', sales_region: 'United States', make_track: true, original_artist: "foobar") }
let(:jt_ww) { FactoryGirl.create(:jam_track, :name=>'jt_ww', sales_region: 'Worldwide', make_track: true, original_artist: "barfoo") }
let(:jt_rock) { FactoryGirl.create(:jam_track, :name=>'jt_rock', genre: JamRuby::Genre.find('rock'), make_track: true, original_artist: "badfood") }
let(:jt_blues) { FactoryGirl.create(:jam_track, :name=>'jt_blues', genre: JamRuby::Genre.find('blues'), make_track: true, original_artist: "foodbart") }
before(:all) do
Capybara.javascript_driver = :poltergeist
@ -35,11 +35,11 @@ describe "JamTrack Shopping", :js => true, :type => :feature, :capybara_feature
def find_jamtrack jamtrack, options = {}
jamtrack_record = find(".jamtrack-record[jamtrack-id=\"#{jamtrack.id}\"]")
jamtrack_record.find('.detail-value', text: jamtrack.name)
jamtrack_record.find('.detail-value', text: jamtrack.recording_type)
#jamtrack_record.find('.detail-value', text: jamtrack.recording_type)
jamtrack_record.find('.detail-value', text: jamtrack.original_artist)
jamtrack_record.find('.detail-value', text: jamtrack.genre.description)
jamtrack_record.find('.detail-value', text: [jamtrack.songwriter, jamtrack.publisher].join(', '))
jamtrack_record.find('.copyright-value', text: jamtrack.licensor.name)
# jamtrack_record.find('.detail-value', text: jamtrack.genre.description)
# jamtrack_record.find('.detail-value', text: [jamtrack.songwriter, jamtrack.publisher].join(', '))
# jamtrack_record.find('.copyright-value', text: jamtrack.licensor.name)
jamtrack_record.find('.jamtrack-price', text: "$ #{jamtrack.price}")
if jamtrack.sales_region == 'United States'
@ -53,7 +53,7 @@ describe "JamTrack Shopping", :js => true, :type => :feature, :capybara_feature
end
if options[:added_cart]
jamtrack_record.find('a.jamtrack-add-cart-disabled', text: 'Purchased')
jamtrack_record.find('a.jamtrack-add-cart-disabled', text: 'Already In Cart')
else
jamtrack_record.find('a.jamtrack-add-cart.button-orange', text: 'Add to Cart')
end
@ -67,8 +67,7 @@ describe "JamTrack Shopping", :js => true, :type => :feature, :capybara_feature
before(:each) do
visit "/client#/jamtrack"
find('h1', text: 'jamtracks')
find('a', text: 'What is a JamTrack?')
find('h1', text: 'jamtracks')
jk_select('Any', '#jamtrack-find-form #jamtrack_availability')
end
@ -86,11 +85,11 @@ describe "JamTrack Shopping", :js => true, :type => :feature, :capybara_feature
not_find_jamtrack jt_rock
end
it "filters with genre" do
jk_select('Blues', '#jamtrack-find-form #jamtrack_genre')
find_jamtrack jt_blues
it "filters with artist" do
jk_select("foobar", '#jamtrack-find-form #jamtrack_artist')
find_jamtrack jt_us
not_find_jamtrack jt_blues
not_find_jamtrack jt_rock
not_find_jamtrack jt_us
not_find_jamtrack jt_ww
end
@ -103,12 +102,18 @@ describe "JamTrack Shopping", :js => true, :type => :feature, :capybara_feature
end
it "sets artist filter" do
pending "The item is clearly present, so not currently sure why capybar can't find it"
visit "/client?artist=foobar#/jamtrack"
art = find('#jamtrack_artist')
puts "art: #{art}"
end
describe "Shopping Carts" do
before(:each) do
visit "/client#/jamtrack"
find('h1', text: 'jamtracks')
find('a', text: 'What is a JamTrack?')
find('h1', text: 'jamtracks')
jk_select('Any', '#jamtrack-find-form #jamtrack_availability')
end