From c29af72938bf4c2bb6ddf6065aca0cd0cc340f75 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Mon, 20 Apr 2015 22:13:30 -0500 Subject: [PATCH] * fix jamtrack landing page formatting VRFS-3056 --- ruby/lib/jam_ruby/models/jam_track.rb | 55 +++++++++- ruby/spec/jam_ruby/models/jam_track_spec.rb | 31 ++++++ web/app/assets/javascripts/jam_rest.js | 10 ++ .../javascripts/jamtrack_landing.js.coffee | 57 +++++++--- web/app/assets/stylesheets/client/client.css | 1 + .../stylesheets/client/jamtrack.css.scss | 85 --------------- .../client/jamtrack_landing.css.scss | 101 ++++++++++++++++++ .../controllers/api_jam_tracks_controller.rb | 11 +- .../views/api_jam_tracks/artist_index.rabl | 7 ++ web/app/views/api_jam_tracks/show_artist.rabl | 3 + .../views/clients/_jamtrack_landing.html.slim | 55 +++++----- web/config/routes.rb | 1 + web/spec/features/jamtrack_landing_spec.rb | 71 ++++++++++++ 13 files changed, 357 insertions(+), 131 deletions(-) create mode 100644 web/app/assets/stylesheets/client/jamtrack_landing.css.scss create mode 100644 web/app/views/api_jam_tracks/artist_index.rabl create mode 100644 web/app/views/api_jam_tracks/show_artist.rabl create mode 100644 web/spec/features/jamtrack_landing_spec.rb diff --git a/ruby/lib/jam_ruby/models/jam_track.rb b/ruby/lib/jam_ruby/models/jam_track.rb index b936de8dd..0197a57ef 100644 --- a/ruby/lib/jam_ruby/models/jam_track.rb +++ b/ruby/lib/jam_ruby/models/jam_track.rb @@ -168,15 +168,68 @@ module JamRuby if options[:group_artist] query = query.select("original_artist, array_agg(jam_tracks.id) AS id, MIN(name) AS name, MIN(description) AS description, MIN(recording_type) AS recording_type, MIN(original_artist) AS original_artist, MIN(songwriter) AS songwriter, MIN(publisher) AS publisher, MIN(sales_region) AS sales_region, MIN(price) AS price, MIN(version) AS version, MIN(genre_id) AS genre_id") query = query.group("original_artist") + query = query.order('jam_tracks.original_artist') else query = query.group("jam_tracks.id") + query = query.order('jam_tracks.original_artist, jam_tracks.name') end query = query.where("jam_tracks.status = ?", 'Production') unless user.admin query = query.where("jam_tracks.genre_id = '#{options[:genre]}'") unless options[:genre].blank? query = query.where("jam_track_tracks.instrument_id = '#{options[:instrument]}'") unless options[:instrument].blank? query = query.where("jam_tracks.sales_region = '#{options[:availability]}'") unless options[:availability].blank? - query = query.order('jam_tracks.original_artist, jam_tracks.name') + + + if query.length == 0 + [query, nil] + elsif query.length < limit + [query, nil] + else + [query, start + limit] + end + end + + + # provides artist names and how many jamtracks are available for each + def artist_index(options, user) + if options[:page] + page = options[:page].to_i + per_page = options[:per_page].to_i + + if per_page == 0 + # try and see if limit was specified + limit = options[:limit] + limit ||= 100 + limit = limit.to_i + else + limit = per_page + end + + start = (page -1 )* per_page + limit = per_page + else + limit = options[:limit] + limit ||= 100 + limit = limit.to_i + + start = options[:start].presence + start = start.to_i || 0 + + page = 1 + start/limit + per_page = limit + end + + + query = JamTrack.paginate(page: page, per_page: per_page) + query = query.select("original_artist, count(original_artist) AS song_count") + query = query.group("original_artist") + query = query.order('jam_tracks.original_artist') + + query = query.where("jam_tracks.status = ?", 'Production') unless user.admin + query = query.where("jam_tracks.genre_id = '#{options[:genre]}'") unless options[:genre].blank? + query = query.where("jam_track_tracks.instrument_id = '#{options[:instrument]}'") unless options[:instrument].blank? + query = query.where("jam_tracks.sales_region = '#{options[:availability]}'") unless options[:availability].blank? + if query.length == 0 [query, nil] diff --git a/ruby/spec/jam_ruby/models/jam_track_spec.rb b/ruby/spec/jam_ruby/models/jam_track_spec.rb index ca894a2c7..beb6d0991 100644 --- a/ruby/spec/jam_ruby/models/jam_track_spec.rb +++ b/ruby/spec/jam_ruby/models/jam_track_spec.rb @@ -38,6 +38,37 @@ describe JamTrack do end end + describe "artist_index" do + it "empty query" do + query, pager = JamTrack.artist_index({}, user) + query.size.should == 0 + end + + it "groups" do + jam_track1 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'a') + jam_track2 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'b') + + query, pager = JamTrack.artist_index({}, user) + query.size.should == 1 + + query[0].original_artist.should eq('artist') + query[0]['song_count'].should eq('2') + end + + it "sorts by name" do + jam_track1 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'blartist', name: 'a') + jam_track2 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'artist', name: 'b') + + query, pager = JamTrack.artist_index({}, user) + query.size.should == 2 + + query[0].original_artist.should eq('artist') + query[0]['song_count'].should eq('1') + query[1].original_artist.should eq('blartist') + query[1]['song_count'].should eq('1') + end + end + describe "index" do it "empty query" do query, pager = JamTrack.index({}, user) diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js index 1b2ae2dba..8e8226643 100644 --- a/web/app/assets/javascripts/jam_rest.js +++ b/web/app/assets/javascripts/jam_rest.js @@ -1456,6 +1456,15 @@ }); } + function getJamTrackArtists(options) { + return $.ajax({ + type: "GET", + url: '/api/jamtracks/artists?' + $.param(options), + dataType: "json", + contentType: 'application/json' + }); + } + function getJamTrackRight(options) { var jamTrackId = options['id']; @@ -1777,6 +1786,7 @@ this.getJamTrack = getJamTrack; this.getJamTrackWithArtistInfo = getJamTrackWithArtistInfo; this.getJamTracks = getJamTracks; + this.getJamTrackArtists = getJamTrackArtists; this.getPurchasedJamTracks = getPurchasedJamTracks; this.getPaymentHistory = getPaymentHistory; this.getSalesHistory = getSalesHistory; diff --git a/web/app/assets/javascripts/jamtrack_landing.js.coffee b/web/app/assets/javascripts/jamtrack_landing.js.coffee index 57534d7f1..2fb470923 100644 --- a/web/app/assets/javascripts/jamtrack_landing.js.coffee +++ b/web/app/assets/javascripts/jamtrack_landing.js.coffee @@ -8,44 +8,69 @@ context.JK.JamTrackLanding = class JamTrackLanding @client = context.jamClient @logger = context.JK.logger @screen = null + @noFreeJamTrack = null + @freeJamTrack = null + @bandList = null + @noBandsFound = null initialize:() => screenBindings = 'beforeShow': @beforeShow 'afterShow': @afterShow @app.bindScreen('jamtrackLanding', screenBindings) - @screen = $('#jamtrackLanding') - + @screen = $('#jamtrackLanding') + @noFreeJamTrack = @screen.find('.no-free-jamtrack') + @freeJamTrack = @screen.find('.free-jamtrack') + @bandList = @screen.find('#band_list') + @noBandsFound = @screen.find('#no_bands_found') + beforeShow:() => + + @noFreeJamTrack.addClass('hidden') + @freeJamTrack.addClass('hidden') + + afterShow:() => + + if context.JK.currentUserId + @app.user().done(@onUser) + else + @onUser({free_jamtrack: gon.global.one_free_jamtrack_per_user}) + + onUser:(user) => + if user.free_jamtrack + @freeJamTrack.removeClass('hidden') + else + @noFreeJamTrack.removeClass('hidden') + # Get artist names and build links - @rest.getJamTracks({group_artist: true}) - .done(this.buildArtistLinks) - .fail(this.handleFailure) + @rest.getJamTrackArtists({group_artist: true, per_page:100}) + .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 + # Get artist names and build links + @logger.debug("buildArtest links response", response) + + artists = response.artists $("#band_list>li:not('#no_bands_found')").remove() - if jamtracks.length==0 - $("#no_bands_found").removeClass("hidden") + if artists.length==0 + @noBandsFound.removeClass("hidden") else - $("#no_bands_found").addClass("hidden") + @noBandsFound.addClass("hidden") # client#/jamtrack - for jamtrack in jamtracks - artistLink = "#{jamtrack.original_artist}" - $("#band_list").append("
  • #{artistLink}
  • ") + for artist in artists + artistLink = "#{artist.original_artist} (#{artist.song_count})" + @bandList.append("
  • #{artistLink}
  • ") # 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)-> + @bandList.on "click", "a.artist-link", (event)-> context.location="client#/jamtrackBrowse" window.history.replaceState({}, "", this.href) event.preventDefault() diff --git a/web/app/assets/stylesheets/client/client.css b/web/app/assets/stylesheets/client/client.css index 5bb85acaa..8df2f986e 100644 --- a/web/app/assets/stylesheets/client/client.css +++ b/web/app/assets/stylesheets/client/client.css @@ -52,6 +52,7 @@ *= require ./createSession *= require ./feed *= require ./jamtrack + *= require ./jamtrack_landing *= require ./shoppingCart *= require ./checkout *= require ./checkout_signin diff --git a/web/app/assets/stylesheets/client/jamtrack.css.scss b/web/app/assets/stylesheets/client/jamtrack.css.scss index 1ed39f671..1a512f0c8 100644 --- a/web/app/assets/stylesheets/client/jamtrack.css.scss +++ b/web/app/assets/stylesheets/client/jamtrack.css.scss @@ -1,90 +1,5 @@ @import 'common'; -#jamtrackLanding { - font-family: verdana; - .two-column-list-container { - -moz-column-count: 2; - -moz-column-gap: 20px; - -webkit-column-count: 2; - -webkit-column-gap: 20px; - column-count: 2; - column-gap: 20px; - margin-left: 0px; - ul { - list-style-type: none; - li { - margin: 1px 4px 1px 0px; - font-size:11px; - } - } - } - - ul { - li { - margin: 1px 4px 1px 4px; - font-size:11px; - } - } - - .browse-header { - padding: 4px 0 4px 0; - } - - .list-columns { - padding: 4px; - h2 { - font-size: 16pt; - font-weight:600; - 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; - color: white !important; - text-align: center; - vertical-align: center; - } - - .what, .howto { - margin-bottom: 2em; - * { - font-family: arial; - font-size: 11pt; - font-weight: 200; - line-height: 17px; - color: #cccccc; - } - } - - .details { - margin-bottom: 4px !important; - } - - .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; diff --git a/web/app/assets/stylesheets/client/jamtrack_landing.css.scss b/web/app/assets/stylesheets/client/jamtrack_landing.css.scss new file mode 100644 index 000000000..26821d7c8 --- /dev/null +++ b/web/app/assets/stylesheets/client/jamtrack_landing.css.scss @@ -0,0 +1,101 @@ +@import 'common'; + +#jamtrackLanding { + //font-family: verdana; + .two-column-list-container { + -moz-column-count: 2; + -moz-column-gap: 20px; + -webkit-column-count: 2; + -webkit-column-gap: 20px; + column-count: 2; + column-gap: 20px; + margin-left: 0; + ul { + list-style-type: none; + li { + margin: 1px 4px 1px 0; + font-size:12px; + line-height:14px; + } + } + } + + ul { + li { + margin: 1px 4px 1px 4px; + font-size:12px; + line-height:14px ; + } + } + + #band_list { + margin-top:10px; + margin-left:0; + + li { + font-size:12px; + } + } + .browse-header { + padding: 4px 0 4px 0; + color:#ccc; + } + + .list-columns { + h2 { + + font-size: 20px; + font-weight:700; + text-transform: lowercase; + margin-bottom: 10px !important; + } + + .free-jamtrack { + font-size: 11pt; + padding: 3px; + @include border-radius(7px); + background-color:$ColorScreenPrimary; + color: white !important; + text-align: center; + vertical-align: center; + } + + .what, .howto { + margin-bottom: 2em; + font-size: 14px; + line-height: 19px; + color: #cccccc; + } + + .what ul { + margin-top:20px; + } + + .details { + margin-bottom: 4px !important; + } + + .about { + @include border_box_sizing; + float: left; + width: 50%; + padding:20px 20px 0 20px; + > * { + margin: 4px; + } + } + .browse { + @include border_box_sizing; + float: left; + width: 50%; + padding:20px 20px 0 20px; + > * { + margin: 4px; + } + + h2.browse-jamtracks { + margin-top:30px; + } + } + } +} diff --git a/web/app/controllers/api_jam_tracks_controller.rb b/web/app/controllers/api_jam_tracks_controller.rb index eb6c0c4f1..f7dbc3b18 100644 --- a/web/app/controllers/api_jam_tracks_controller.rb +++ b/web/app/controllers/api_jam_tracks_controller.rb @@ -1,8 +1,8 @@ class ApiJamTracksController < ApiController # have to be signed in currently to see this screen - before_filter :api_signed_in_user, :except => [:index, :show, :show_with_artist_info] - before_filter :api_any_user, :only => [:index, :show, :show_with_artist_info] + before_filter :api_signed_in_user, :except => [:index, :show, :show_with_artist_info, :artist_index] + before_filter :api_any_user, :only => [:index, :show, :show_with_artist_info, :artist_index] before_filter :lookup_jam_track_right, :only => [:download,:enqueue, :show_jam_track_right] respond_to :json @@ -22,6 +22,13 @@ class ApiJamTracksController < ApiController render "api_jam_tracks/index", :layout => nil end + def artist_index + data = JamTrack.artist_index(params, any_user) + @artists, @next = data[0], data[1] + + render "api_jam_tracks/artist_index", :layout => nil + end + def played if params[:id].blank? render(:json => { :message => "JamTrack ID required" }, :status => 400) and return diff --git a/web/app/views/api_jam_tracks/artist_index.rabl b/web/app/views/api_jam_tracks/artist_index.rabl new file mode 100644 index 000000000..d994d6b82 --- /dev/null +++ b/web/app/views/api_jam_tracks/artist_index.rabl @@ -0,0 +1,7 @@ +node :next do |page| + @next +end + +node :artists do |page| + partial "api_jam_tracks/show_artist", object: @artists +end \ No newline at end of file diff --git a/web/app/views/api_jam_tracks/show_artist.rabl b/web/app/views/api_jam_tracks/show_artist.rabl new file mode 100644 index 000000000..68839c3f3 --- /dev/null +++ b/web/app/views/api_jam_tracks/show_artist.rabl @@ -0,0 +1,3 @@ +object @artist + +attributes :original_artist, :song_count \ No newline at end of file diff --git a/web/app/views/clients/_jamtrack_landing.html.slim b/web/app/views/clients/_jamtrack_landing.html.slim index 69e92422c..ed1bcb1d7 100644 --- a/web/app/views/clients/_jamtrack_landing.html.slim +++ b/web/app/views/clients/_jamtrack_landing.html.slim @@ -5,31 +5,32 @@ h1 jamtracks = render "screen_navigation" .content-body - .list-columns - .about - h2 what are jamtracks? - .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 - .howto - .details - span="To play with your JamTracks, open a JamTrack while in a session in the JamKazam app. Or " - a href="client#/jamtrackBrowse" visit the JamTracks Section of your account. - .free-jamtrack.orange-fill.details - | 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 - | browse by band    - a href="client#/jamtrackBrowse" or browse all jamtracks - .band-browse.two-column-list-container - ul#band_list - li#no_bands_found.hidden No bands found + .content-body-scroller + .list-columns + .about + h2 what are jamtracks? + .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 + .howto + .no-free-jamtrack.details.hidden + span="To play with your JamTracks, open a JamTrack while in a session in the JamKazam app. Or " + a href="client#/account/jamtracks" visit the JamTracks Section of your account. + .free-jamtrack.orange-fill.details.hidden + | 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 jamtracks + .browse-header + | browse by band     + a href="client#/jamtrackBrowse" or browse all jamtracks + .band-browse.two-column-list-container + ul#band_list + li#no_bands_found.hidden No bands found diff --git a/web/config/routes.rb b/web/config/routes.rb index 6836b0092..70d71e5da 100644 --- a/web/config/routes.rb +++ b/web/config/routes.rb @@ -215,6 +215,7 @@ SampleApp::Application.routes.draw do # Jamtracks match '/jamtracks/purchased' => 'api_jam_tracks#purchased', :via => :get, :as => 'api_jam_tracks_purchased' + match '/jamtracks/artists' => 'api_jam_tracks#artist_index', :via => :get, :as => 'api_jam_tracks_list_artists' match '/jamtracks/:plan_code' => 'api_jam_tracks#show', :via => :get, :as => 'api_jam_tracks_show' match '/jamtracks/band/:plan_code' => 'api_jam_tracks#show_with_artist_info', :via => :get, :as => 'api_jam_tracks_show_with_artist_info' match '/jamtracks' => 'api_jam_tracks#index', :via => :get, :as => 'api_jam_tracks_list' diff --git a/web/spec/features/jamtrack_landing_spec.rb b/web/spec/features/jamtrack_landing_spec.rb new file mode 100644 index 000000000..0cd33d0e8 --- /dev/null +++ b/web/spec/features/jamtrack_landing_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' + +describe "JamTrack Landing", :js => true, :type => :feature, :capybara_feature => true do + + let(:user) { FactoryGirl.create(:user, has_redeemable_jamtrack: 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 + Capybara.current_driver = Capybara.javascript_driver + Capybara.default_wait_time = 30 # these tests are SLOOOOOW + end + + + before(:each) do + ShoppingCart.delete_all + JamTrackRight.delete_all + JamTrack.delete_all + JamTrackTrack.delete_all + JamTrackLicensor.delete_all + + + stub_const("APP_CONFIG", web_config) + end + + it "not logged in" do + jt_us.touch + jt_ww.touch + + visit '/client#/jamtrackLanding' + + find('h2', text: 'what are jamtracks?') + if web_config.one_free_jamtrack_per_user + find('.free-jamtrack') + else + find('.no-free-jamtrack') + end + + find("a[artist='#{jt_us.original_artist}']", text: 'foobar (1)') + find("a[artist='#{jt_ww.original_artist}']", text: 'barfoo (1)') + end + + it "logged in and has redeemable track" do + jt_us.touch + jt_ww.touch + + fast_signin(user, '/client#/jamtrackLanding') + + find('h2', text: 'what are jamtracks?') + find('.free-jamtrack') + find("a[artist='#{jt_us.original_artist}']", text: 'foobar (1)') + find("a[artist='#{jt_ww.original_artist}']", text: 'barfoo (1)') + end + + it "logged in and does not have redeemable track" do + jt_us.touch + jt_ww.touch + user.has_redeemable_jamtrack = false + user.save! + + fast_signin(user, '/client#/jamtrackLanding') + + find('h2', text: 'what are jamtracks?') + find('.no-free-jamtrack') + find("a[artist='#{jt_us.original_artist}']", text: 'foobar (1)') + find("a[artist='#{jt_ww.original_artist}']", text: 'barfoo (1)') + end +end