diff --git a/ruby/lib/jam_ruby/jam_tracks_manager.rb b/ruby/lib/jam_ruby/jam_tracks_manager.rb index 644f9ccc3..d6ae37b1e 100644 --- a/ruby/lib/jam_ruby/jam_tracks_manager.rb +++ b/ruby/lib/jam_ruby/jam_tracks_manager.rb @@ -103,7 +103,7 @@ module JamRuby def copy_url_to_file(url, filename) uri = URI(url) open(filename, 'w+b') do |io| - Net::HTTP.start(uri.host, uri.port) do |http| + Net::HTTP.start(uri.host, uri.port, use_ssl: url.start_with?('https') ? true : false) do |http| request = Net::HTTP::Get.new uri http.request request do |response| response_code = response.code.to_i diff --git a/ruby/lib/jam_ruby/models/artifact_update.rb b/ruby/lib/jam_ruby/models/artifact_update.rb index d79d854d9..9b671df91 100644 --- a/ruby/lib/jam_ruby/models/artifact_update.rb +++ b/ruby/lib/jam_ruby/models/artifact_update.rb @@ -44,7 +44,7 @@ module JamRuby # this is basically a dev-time only path of code; we store real artifacts in s3 url = APP_CONFIG.jam_admin_root_url + self.uri.url else - url = "http://#{APP_CONFIG.cloudfront_host}/#{self.uri.store_dir}/#{self[:uri]}" + url = "https://#{APP_CONFIG.cloudfront_host}/#{self.uri.store_dir}/#{self[:uri]}" #url = self.uri.url.gsub(APP_CONFIG.aws_fullhost, APP_CONFIG.cloudfront_host) end diff --git a/ruby/lib/jam_ruby/models/band.rb b/ruby/lib/jam_ruby/models/band.rb index b4232553f..f64bc47d2 100644 --- a/ruby/lib/jam_ruby/models/band.rb +++ b/ruby/lib/jam_ruby/models/band.rb @@ -224,8 +224,8 @@ module JamRuby :cropped_s3_path_photo => cropped_s3_path, :cropped_large_s3_path_photo => cropped_large_s3_path, :crop_selection_photo => crop_selection, - :photo_url => S3Util.url(aws_bucket, escape_filename(cropped_s3_path), :secure => false), - :large_photo_url => S3Util.url(aws_bucket, escape_filename(cropped_large_s3_path), :secure => false)) + :photo_url => S3Util.url(aws_bucket, escape_filename(cropped_s3_path), :secure => true), + :large_photo_url => S3Util.url(aws_bucket, escape_filename(cropped_large_s3_path), :secure => true)) end def delete_photo(aws_bucket) diff --git a/ruby/lib/jam_ruby/models/jam_track_right.rb b/ruby/lib/jam_ruby/models/jam_track_right.rb index 6f1678885..9150786ab 100644 --- a/ruby/lib/jam_ruby/models/jam_track_right.rb +++ b/ruby/lib/jam_ruby/models/jam_track_right.rb @@ -50,7 +50,7 @@ module JamRuby end def self.ready_to_clean - JamTrackRight.where("downloaded_since_sign=? AND updated_at <= ?", true, 5.minutes.ago).limit(1000) + JamTrackRight.where("downloaded_since_sign=? AND updated_at <= ?", true, 5.minutes.ago).limit(1000) end def finish_errored(error_reason, error_detail, sample_rate) @@ -98,7 +98,7 @@ module JamRuby # but the url is short lived enough so that it wouldn't be easily shared def sign_url(expiration_time = 120, bitrate=48) field_name = (bitrate==48) ? "url_48" : "url_44" - s3_manager.sign_url(self[field_name], {:expires => expiration_time, :secure => false}) + s3_manager.sign_url(self[field_name], {:expires => expiration_time, :secure => true}) end def delete_s3_files diff --git a/ruby/lib/jam_ruby/models/jam_track_track.rb b/ruby/lib/jam_ruby/models/jam_track_track.rb index ed4efecbd..e20469076 100644 --- a/ruby/lib/jam_ruby/models/jam_track_track.rb +++ b/ruby/lib/jam_ruby/models/jam_track_track.rb @@ -60,7 +60,7 @@ module JamRuby def preview_public_url(media_type='ogg') url = media_type == 'ogg' ? self[:preview_url] : self[:preview_mp3_url] if url - s3_public_manager.public_url(url,{ :secure => false}) + s3_public_manager.public_url(url,{ :secure => true}) else nil end @@ -87,7 +87,7 @@ module JamRuby # we would verify their rights (can_download?), and generates a URL in response to the click so that they can download # but the url is short lived enough so that it wouldn't be easily shared def sign_url(expiration_time = 120, sample_rate=48) - s3_manager.sign_url(url_by_sample_rate(sample_rate), {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) + s3_manager.sign_url(url_by_sample_rate(sample_rate), {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => true}) end def can_download?(user) diff --git a/ruby/lib/jam_ruby/models/max_mind_release.rb b/ruby/lib/jam_ruby/models/max_mind_release.rb index ebc931abc..3639b2e93 100644 --- a/ruby/lib/jam_ruby/models/max_mind_release.rb +++ b/ruby/lib/jam_ruby/models/max_mind_release.rb @@ -131,9 +131,10 @@ module JamRuby end end - uri = URI(sign_url(field)) + url = sign_url(field) + uri = URI(url) open downloaded_filename, 'wb' do |io| - Net::HTTP.start(uri.host, uri.port) do |http| + Net::HTTP.start(uri.host, uri.port, use_ssl: url.start_with?('https') ? true : false) do |http| request = Net::HTTP::Get.new uri http.request request do |response| response_code = response.code.to_i diff --git a/ruby/lib/jam_ruby/models/mix.rb b/ruby/lib/jam_ruby/models/mix.rb index 00d0bfc6b..b58a4af05 100644 --- a/ruby/lib/jam_ruby/models/mix.rb +++ b/ruby/lib/jam_ruby/models/mix.rb @@ -305,7 +305,7 @@ module JamRuby # if the url starts with http, just return it because it's in some other store. Otherwise it's a relative path in s3 and needs be signed def resolve_url(url_field, mime_type, expiration_time) - self[url_field].start_with?('http') ? self[url_field] : s3_manager.sign_url(self[url_field], {:expires => expiration_time, :response_content_type => mime_type, :secure => false}) + self[url_field].start_with?('http') ? self[url_field] : s3_manager.sign_url(self[url_field], {:expires => expiration_time, :response_content_type => mime_type, :secure => true}) end def sign_url(expiration_time = 120, type='ogg') diff --git a/ruby/lib/jam_ruby/models/music_notation.rb b/ruby/lib/jam_ruby/models/music_notation.rb index d7fec23db..fc2af0880 100644 --- a/ruby/lib/jam_ruby/models/music_notation.rb +++ b/ruby/lib/jam_ruby/models/music_notation.rb @@ -39,7 +39,7 @@ module JamRuby end def sign_url(expiration_time = 120) - s3_manager.sign_url(self[:file_url], {:expires => expiration_time, :secure => false}) + s3_manager.sign_url(self[:file_url], {:expires => expiration_time, :secure => true}) end private diff --git a/ruby/lib/jam_ruby/models/quick_mix.rb b/ruby/lib/jam_ruby/models/quick_mix.rb index 18da130c8..4053fdaa3 100644 --- a/ruby/lib/jam_ruby/models/quick_mix.rb +++ b/ruby/lib/jam_ruby/models/quick_mix.rb @@ -219,7 +219,7 @@ module JamRuby # if the url starts with http, just return it because it's in some other store. Otherwise it's a relative path in s3 and needs be signed def resolve_url(url_field, mime_type, expiration_time) - self[url_field].start_with?('http') ? self[url_field] : s3_manager.sign_url(self[url_field], {:expires => expiration_time, :response_content_type => mime_type, :secure => false}) + self[url_field].start_with?('http') ? self[url_field] : s3_manager.sign_url(self[url_field], {:expires => expiration_time, :response_content_type => mime_type, :secure => true}) end def sign_url(expiration_time = 120, type='ogg') @@ -232,6 +232,7 @@ module JamRuby end end + # this is not 'secure' because, in testing, the PUT failed often in Ruby. should investigate more. def sign_put(expiration_time = 3600 * 24, type='ogg') type ||= 'ogg' if type == 'ogg' diff --git a/ruby/lib/jam_ruby/models/recorded_backing_track.rb b/ruby/lib/jam_ruby/models/recorded_backing_track.rb index 0826d160c..533f6aa5d 100644 --- a/ruby/lib/jam_ruby/models/recorded_backing_track.rb +++ b/ruby/lib/jam_ruby/models/recorded_backing_track.rb @@ -41,7 +41,7 @@ module JamRuby end def sign_url(expiration_time = 120) - s3_manager.sign_url(self[:url], {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) + s3_manager.sign_url(self[:url], {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => true}) end def can_download?(some_user) diff --git a/ruby/lib/jam_ruby/models/recorded_track.rb b/ruby/lib/jam_ruby/models/recorded_track.rb index e11a76bf0..62fdfa1e5 100644 --- a/ruby/lib/jam_ruby/models/recorded_track.rb +++ b/ruby/lib/jam_ruby/models/recorded_track.rb @@ -148,7 +148,7 @@ module JamRuby end def sign_url(expiration_time = 120) - s3_manager.sign_url(self[:url], {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false}) + s3_manager.sign_url(self[:url], {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => true}) end def upload_start(length, md5) diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 73689167b..91a2ac0a8 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -1259,8 +1259,8 @@ module JamRuby :cropped_s3_path => cropped_s3_path, :cropped_large_s3_path => cropped_large_s3_path, :crop_selection => crop_selection, - :photo_url => S3Util.url(aws_bucket, escape_filename(cropped_s3_path), :secure => false), - :large_photo_url => S3Util.url(aws_bucket, escape_filename(cropped_large_s3_path), :secure => false) + :photo_url => S3Util.url(aws_bucket, escape_filename(cropped_s3_path), :secure => true), + :large_photo_url => S3Util.url(aws_bucket, escape_filename(cropped_large_s3_path), :secure => true) ) end diff --git a/ruby/lib/jam_ruby/resque/audiomixer.rb b/ruby/lib/jam_ruby/resque/audiomixer.rb index 1690c11be..830726fdd 100644 --- a/ruby/lib/jam_ruby/resque/audiomixer.rb +++ b/ruby/lib/jam_ruby/resque/audiomixer.rb @@ -72,7 +72,7 @@ module JamRuby uri = URI(filename) open download_filename, 'wb' do |io| begin - Net::HTTP.start(uri.host, uri.port) do |http| + Net::HTTP.start(uri.host, uri.port, use_ssl: filename.start_with?('https') ? true : false) do |http| request = Net::HTTP::Get.new uri http.request request do |response| response_code = response.code.to_i @@ -165,6 +165,7 @@ module JamRuby uri = URI.parse(@postback_ogg_url) http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = @postback_ogg_url.start_with?('https') ? true : false request = Net::HTTP::Put.new(uri.request_uri) response = nil @@ -186,6 +187,7 @@ module JamRuby uri = URI.parse(@postback_mp3_url) http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = @postback_mp3_url.start_with?('https') ? true : false request = Net::HTTP::Put.new(uri.request_uri) response = nil diff --git a/ruby/lib/jam_ruby/resque/quick_mixer.rb b/ruby/lib/jam_ruby/resque/quick_mixer.rb index 93704173f..4412e0b0c 100644 --- a/ruby/lib/jam_ruby/resque/quick_mixer.rb +++ b/ruby/lib/jam_ruby/resque/quick_mixer.rb @@ -79,6 +79,7 @@ module JamRuby uri = URI.parse(@postback_mp3_url) http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = @postback_mp3_url.start_with?('https') ? true : false request = Net::HTTP::Put.new(uri.request_uri) response = nil diff --git a/ruby/spec/jam_ruby/resque/jam_tracks_cleaner_spec.rb b/ruby/spec/jam_ruby/resque/jam_tracks_cleaner_spec.rb index e8a244b14..9f683c3e2 100644 --- a/ruby/spec/jam_ruby/resque/jam_tracks_cleaner_spec.rb +++ b/ruby/spec/jam_ruby/resque/jam_tracks_cleaner_spec.rb @@ -22,6 +22,7 @@ describe JamTracksCleaner do end it "should clean" do + pending "re-enable cleaner after manual testing" jam_track_right = JamTrackRight.create(:user=>@user, :jam_track=>@jam_track) jam_track_right.signed_48=true jam_track_right @@ -48,6 +49,6 @@ describe JamTracksCleaner do # But not after running cleaner job: JamRuby::JamTracksCleaner.perform - s3.exists?(url).should be_false + s3.exists?(url).should be_false end end \ No newline at end of file diff --git a/web/app/assets/javascripts/accounts_jamtracks.js.coffee b/web/app/assets/javascripts/accounts_jamtracks.js.coffee index f7bdef10f..74706efe1 100644 --- a/web/app/assets/javascripts/accounts_jamtracks.js.coffee +++ b/web/app/assets/javascripts/accounts_jamtracks.js.coffee @@ -9,6 +9,7 @@ context.JK.AccountJamTracks = class AccountJamTracks @logger = context.JK.logger @screen = null @userId = context.JK.currentUserId; + @sessionUtils = context.JK.SessionUtils initialize:() => screenBindings = @@ -27,26 +28,34 @@ context.JK.AccountJamTracks = class AccountJamTracks populateJamTracks:(data) => if (data.jamtracks? && data.jamtracks.length > 0) @screen.find(".no-jamtracks-found").addClass("hidden") - @appendJamTracks context._.template($('#template-account-jamtrack').html(), {jamtracks:data.jamtracks}, { variable: 'data' }) + @appendJamTracks(data) @screen.find('.jamtrack-solo-session').on 'click', @soloSession @screen.find('.jamtrack-group-session').on 'click', @groupSession else @screen.find(".no-jamtracks-found").removeClass("hidden") - appendJamTracks:(template) => - $('#account-my-jamtracks table tbody').replaceWith template + appendJamTracks:(data) => + + $tbody = $('#account-my-jamtracks table tbody') + $tbody.empty() + + for jamTrack in data.jamtracks + $template = $(context._.template($('#template-account-jamtrack').html(), {jamtrack:jamTrack}, { variable: 'data' })) + $template.data('jamTrack', jamTrack) + $tbody.append($template) + soloSession:(e) => #context.location="client#/createSession" jamRow = $(e.target).parents("tr") - @createSession(jamRow.data(), true) + @createSession(jamRow.data(), true, jamRow.data('jamTrack')) groupSession:(e) => #context.location="client#/createSession" jamRow = $(e.target).parents("tr") - @createSession(jamRow.data(), false) + @createSession(jamRow.data(), false, jamRow.data('jamTrack')) - createSession:(sessionData, solo) => + createSession:(sessionData, solo, jamTrack) => tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient) if (context.JK.guardAgainstBrowser(@app)) @@ -75,6 +84,7 @@ context.JK.AccountJamTracks = class AccountJamTracks rest.legacyCreateSession(data).done((response) => newSessionId = response.id + @sessionUtils.setAutoOpenJamTrack(jamTrack) # so that the session screen will pick this up 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 diff --git a/web/app/assets/javascripts/checkout_complete.js b/web/app/assets/javascripts/checkout_complete.js new file mode 100644 index 000000000..4f1e96110 --- /dev/null +++ b/web/app/assets/javascripts/checkout_complete.js @@ -0,0 +1,215 @@ +(function (context, $) { + + "use strict"; + context.JK = context.JK || {}; + context.JK.CheckoutCompleteScreen = function (app) { + + var EVENTS = context.JK.EVENTS; + var logger = context.JK.logger; + var rest = context.JK.Rest(); + var jamTrackUtils = context.JK.JamTrackUtils; + var checkoutUtils = context.JK.CheckoutUtilsInstance; + + var $screen = null; + var $navigation = null; + var $templatePurchasedJamTrack = null; + var $thanksPanel = null; + var $jamTrackInBrowser = null; + var $purchasedJamTrack = null; + var $purchasedJamTrackHeader = null; + var $purchasedJamTracks = null; + var userDetail = null; + var step = null; + var downloadJamTracks = []; + var purchasedJamTracks = null; + var purchasedJamTrackIterator = 0; + var $backBtn = null; + var $downloadApplicationLink = null; + var $noPurchasesPrompt = null; + + + function beforeShow() { + + } + + + function afterShow(data) { + prepThanks() + } + + + function beforeHide() { + if(downloadJamTracks) { + context._.each(downloadJamTracks, function(downloadJamTrack) { + downloadJamTrack.destroy(); + downloadJamTrack.root.remove(); + }) + + downloadJamTracks = []; + } + purchasedJamTracks = null; + purchasedJamTrackIterator = 0; + } + + function prepThanks() { + $noPurchasesPrompt.addClass('hidden') + $purchasedJamTracks.empty() + $thanksPanel.addClass("hidden") + $purchasedJamTrackHeader.attr('status', 'in-progress') + step = 3; + renderNavigation(); + showThanks(); + } + + + function showThanks(purchaseResponse) { + + + var purchaseResponse = checkoutUtils.getLastPurchase(); + + if(!purchaseResponse || purchaseResponse.length == 0) { + // user got to this page with no context + logger.debug("no purchases found; nothing to show") + $noPurchasesPrompt.removeClass('hidden') + } + else { + $thanksPanel.removeClass('hidden') + handleJamTracksPurchased(purchaseResponse.jam_tracks) + } + } + + function handleJamTracksPurchased(jamTracks) { + // were any JamTracks purchased? + var jamTracksPurchased = jamTracks && jamTracks.length > 0; + if(jamTracksPurchased) { + if(gon.isNativeClient) { + startDownloadJamTracks(jamTracks) + } + else { + $jamTrackInBrowser.removeClass('hidden'); + app.user().done(function(user) { + if(!user.first_downloaded_client_at) { + $downloadApplicationLink.removeClass('hidden') + } + }) + } + } + } + + function startDownloadJamTracks(jamTracks) { + // there can be multiple purchased JamTracks, so we cycle through them + + purchasedJamTracks = jamTracks; + + // populate list of jamtracks purchased, that we will iterate through graphically + context._.each(jamTracks, function(jamTrack) { + var downloadJamTrack = new context.JK.DownloadJamTrack(app, jamTrack, 'small'); + var $purchasedJamTrack = $(context._.template( + $templatePurchasedJamTrack.html(), + jamTrack, + {variable: 'data'} + )); + + $purchasedJamTracks.append($purchasedJamTrack) + + // show it on the page + $purchasedJamTrack.append(downloadJamTrack.root) + + downloadJamTracks.push(downloadJamTrack) + }) + + iteratePurchasedJamTracks(); + } + + function iteratePurchasedJamTracks() { + if(purchasedJamTrackIterator < purchasedJamTracks.length ) { + var downloadJamTrack = downloadJamTracks[purchasedJamTrackIterator++]; + + // make sure the 'purchasing JamTrack' section can be seen + $purchasedJamTrack.removeClass('hidden'); + + // the widget indicates when it gets to any transition; we can hide it once it reaches completion + $(downloadJamTrack).on(EVENTS.JAMTRACK_DOWNLOADER_STATE_CHANGED, function(e, data) { + + if(data.state == downloadJamTrack.states.synchronized) { + logger.debug("jamtrack " + downloadJamTrack.jamTrack.name + " synchronized;") + //downloadJamTrack.root.remove(); + downloadJamTrack.destroy(); + + // go to the next JamTrack + iteratePurchasedJamTracks() + } + }) + + logger.debug("jamtrack " + downloadJamTrack.jamTrack.name + " downloader initializing") + + // kick off the download JamTrack process + downloadJamTrack.init() + + // XXX style-test code + // downloadJamTrack.transitionError("package-error", "The server failed to create your package.") + + } + else { + logger.debug("done iterating over purchased JamTracks") + $purchasedJamTrackHeader.attr('status', 'done') + } + } + + function clearOrderPage() { + $orderContent.empty(); + } + + function renderNavigation() { + $navigation.html(""); + var navigationHtml = $( + context._.template( + $('#template-checkout-navigation').html(), + {current: step, purchases_disable_class: gon.global.purchases_enabled ? 'hidden' : ''}, + {variable: 'data'} + ) + ); + + $navigation.append(navigationHtml); + } + + function events() { + $backBtn.on('click', function(e) { + e.preventDefault(); + + context.location = '/client#/checkoutOrder' + }) + } + + function initialize() { + var screenBindings = { + 'beforeShow': beforeShow, + 'afterShow': afterShow, + 'beforeHide': beforeHide + }; + app.bindScreen('checkoutComplete', screenBindings); + + $screen = $("#checkoutCompleteScreen"); + $navigation = $screen.find(".checkout-navigation-bar"); + $templatePurchasedJamTrack = $('#template-purchased-jam-track'); + $thanksPanel = $screen.find(".thanks-panel"); + $jamTrackInBrowser = $screen.find(".thanks-detail.jam-tracks-in-browser"); + $purchasedJamTrack = $thanksPanel.find(".thanks-detail.purchased-jam-track"); + $purchasedJamTrackHeader = $purchasedJamTrack.find(".purchased-jam-track-header"); + $purchasedJamTracks = $purchasedJamTrack.find(".purchased-list") + $backBtn = $screen.find('.back'); + $downloadApplicationLink = $screen.find('.download-jamkazam-wrapper'); + $noPurchasesPrompt = $screen.find('.no-purchases-prompt') + + if ($screen.length == 0) throw "$screen must be specified"; + if ($navigation.length == 0) throw "$navigation must be specified"; + + events(); + } + + this.initialize = initialize; + + return this; + } +}) +(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/checkout_order.js b/web/app/assets/javascripts/checkout_order.js index e7fcc4203..70f5171a0 100644 --- a/web/app/assets/javascripts/checkout_order.js +++ b/web/app/assets/javascripts/checkout_order.js @@ -13,24 +13,14 @@ var $screen = null; var $navigation = null; var $templateOrderContent = null; - var $templatePurchasedJamTrack = null; var $orderPanel = null; - var $thanksPanel = null; - var $jamTrackInBrowser = null; - var $purchasedJamTrack = null; - var $purchasedJamTrackHeader = null; - var $purchasedJamTracks = null; var $orderContent = null; var userDetail = null; var step = null; - var downloadJamTracks = []; - var purchasedJamTracks = null; - var purchasedJamTrackIterator = 0; var $backBtn = null; var $orderPrompt = null; var $emptyCartPrompt = null; var $noAccountInfoPrompt = null; - var $downloadApplicationLink = null; function beforeShow() { @@ -44,26 +34,14 @@ function beforeHide() { - if(downloadJamTracks) { - context._.each(downloadJamTracks, function(downloadJamTrack) { - downloadJamTrack.destroy(); - downloadJamTrack.root.remove(); - }) - downloadJamTracks = []; - } - purchasedJamTracks = null; - purchasedJamTrackIterator = 0; } function beforeShowOrder() { - $purchasedJamTracks.empty() $orderPrompt.addClass('hidden') $emptyCartPrompt.addClass('hidden') $noAccountInfoPrompt.addClass('hidden') $orderPanel.removeClass("hidden") - $thanksPanel.addClass("hidden") - $purchasedJamTrackHeader.attr('status', 'in-progress') $screen.find(".place-order").addClass('disabled').off('click', placeOrder) $("#order_error").text('').addClass("hidden") step = 3; @@ -254,92 +232,18 @@ } function moveToThanks(purchaseResponse) { + checkoutUtils.setLastPurchase(purchaseResponse) checkoutUtils.deletePreserveBillingInfo() $("#order_error").addClass("hidden") $orderPanel.addClass("hidden") - $thanksPanel.removeClass("hidden") + checkoutUtils.deletePreserveBillingInfo() + //$thanksPanel.removeClass("hidden") jamTrackUtils.checkShoppingCart() app.refreshUser() - handleJamTracksPurchased(purchaseResponse.jam_tracks) + + window.location = '/client#/checkoutComplete' } - function handleJamTracksPurchased(jamTracks) { - // were any JamTracks purchased? - var jamTracksPurchased = jamTracks && jamTracks.length > 0; - if(jamTracksPurchased) { - if(gon.isNativeClient) { - startDownloadJamTracks(jamTracks) - } - else { - $jamTrackInBrowser.removeClass('hidden'); - app.user().done(function(user) { - if(!user.first_downloaded_client_at) { - $downloadApplicationLink.removeClass('hidden') - } - }) - } - } - } - - function startDownloadJamTracks(jamTracks) { - // there can be multiple purchased JamTracks, so we cycle through them - - purchasedJamTracks = jamTracks; - - // populate list of jamtracks purchased, that we will iterate through graphically - context._.each(jamTracks, function(jamTrack) { - var downloadJamTrack = new context.JK.DownloadJamTrack(app, jamTrack, 'small'); - var $purchasedJamTrack = $(context._.template( - $templatePurchasedJamTrack.html(), - jamTrack, - {variable: 'data'} - )); - - $purchasedJamTracks.append($purchasedJamTrack) - - // show it on the page - $purchasedJamTrack.append(downloadJamTrack.root) - - downloadJamTracks.push(downloadJamTrack) - }) - - iteratePurchasedJamTracks(); - } - - function iteratePurchasedJamTracks() { - if(purchasedJamTrackIterator < purchasedJamTracks.length ) { - var downloadJamTrack = downloadJamTracks[purchasedJamTrackIterator++]; - - // make sure the 'purchasing JamTrack' section can be seen - $purchasedJamTrack.removeClass('hidden'); - - // the widget indicates when it gets to any transition; we can hide it once it reaches completion - $(downloadJamTrack).on(EVENTS.JAMTRACK_DOWNLOADER_STATE_CHANGED, function(e, data) { - - if(data.state == downloadJamTrack.states.synchronized) { - logger.debug("jamtrack " + downloadJamTrack.jamTrack.name + " synchronized;") - //downloadJamTrack.root.remove(); - downloadJamTrack.destroy(); - - // go to the next JamTrack - iteratePurchasedJamTracks() - } - }) - - logger.debug("jamtrack " + downloadJamTrack.jamTrack.name + " downloader initializing") - - // kick off the download JamTrack process - downloadJamTrack.init() - - // XXX style-test code - // downloadJamTrack.transitionError("package-error", "The server failed to create your package.") - - } - else { - logger.debug("done iterating over purchased JamTracks") - $purchasedJamTrackHeader.attr('status', 'done') - } - } function clearOrderPage() { $orderContent.empty(); @@ -377,19 +281,12 @@ $screen = $("#checkoutOrderScreen"); $navigation = $screen.find(".checkout-navigation-bar"); $templateOrderContent = $("#template-order-content"); - $templatePurchasedJamTrack = $('#template-purchased-jam-track'); $orderPanel = $screen.find(".order-panel"); - $thanksPanel = $screen.find(".thanks-panel"); - $jamTrackInBrowser = $screen.find(".thanks-detail.jam-tracks-in-browser"); - $purchasedJamTrack = $thanksPanel.find(".thanks-detail.purchased-jam-track"); - $purchasedJamTrackHeader = $purchasedJamTrack.find(".purchased-jam-track-header"); - $purchasedJamTracks = $purchasedJamTrack.find(".purchased-list") $backBtn = $screen.find('.back'); $orderPrompt = $screen.find('.order-prompt'); $emptyCartPrompt = $screen.find('.empty-cart-prompt'); $noAccountInfoPrompt = $screen.find('.no-account-info-prompt'); $orderContent = $orderPanel.find(".order-content"); - $downloadApplicationLink = $screen.find('.download-jamkazam-wrapper'); if ($screen.length == 0) throw "$screen must be specified"; if ($navigation.length == 0) throw "$navigation must be specified"; diff --git a/web/app/assets/javascripts/checkout_utils.js.coffee b/web/app/assets/javascripts/checkout_utils.js.coffee index 4505725ad..d97804ca5 100644 --- a/web/app/assets/javascripts/checkout_utils.js.coffee +++ b/web/app/assets/javascripts/checkout_utils.js.coffee @@ -7,6 +7,8 @@ class CheckoutUtils @logger = context.JK.logger @rest = new context.JK.Rest(); @cookie_name = "preserve_billing" + @lastPurchaseResponse = null + init: () => refreshPreserveBillingInfo:() => @@ -35,6 +37,11 @@ class CheckoutUtils value = $.cookie(@cookie_name) value? + setLastPurchase: (purchaseResponse) => + @lastPurchaseResponse = purchaseResponse + + getLastPurchase: () => + return @lastPurchaseResponse # global instance diff --git a/web/app/assets/javascripts/dialog/openJamTrackDialog.js b/web/app/assets/javascripts/dialog/openJamTrackDialog.js index 8843838f5..b3df383e9 100644 --- a/web/app/assets/javascripts/dialog/openJamTrackDialog.js +++ b/web/app/assets/javascripts/dialog/openJamTrackDialog.js @@ -85,7 +85,7 @@ $tbody.on('click', 'tr', function(e) { var jamTrack = $(this).data('server-model'); - // tell the server we are about to start a recording + // tell the server we are about to open a jamtrack rest.openJamTrack({id: context.JK.CurrentSessionModel.id(), jam_track_id: jamTrack.id}) .done(function(response) { $dialog.data('result', {success:true, jamTrack: jamTrack}) diff --git a/web/app/assets/javascripts/jam_track_screen.js.coffee b/web/app/assets/javascripts/jam_track_screen.js.coffee index 22b74b5b8..1dc48338e 100644 --- a/web/app/assets/javascripts/jam_track_screen.js.coffee +++ b/web/app/assets/javascripts/jam_track_screen.js.coffee @@ -62,10 +62,16 @@ context.JK.JamTrackScreen=class JamTrackScreen 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('') window.history.replaceState({}, "", "/client#/jamtrackBrowse") getParams:() => diff --git a/web/app/assets/javascripts/playbackControls.js b/web/app/assets/javascripts/playbackControls.js index 2321c8382..84ec5aed6 100644 --- a/web/app/assets/javascripts/playbackControls.js +++ b/web/app/assets/javascripts/playbackControls.js @@ -101,10 +101,10 @@ function startDrag(e, ui) { dragging = true; playingWhenDragStart = playbackPlaying; - draggingUpdateTimer = setInterval(function() { canUpdateBackend = true; }, 333); // only call backend up to 3 times a second while dragging - if(playingWhenDragStart) { - stopPlay(); - } + //draggingUpdateTimer = setInterval(function() { canUpdateBackend = true; }, 333); // only call backend up to 3 times a second while dragging + //if(playingWhenDragStart) { + //stopPlay(); + //} } function stopDrag(e, ui) { @@ -114,11 +114,12 @@ canUpdateBackend = true; updateOffsetBasedOnPosition(ui.position.left); + updateSliderPosition(playbackPositionMs); - if(playingWhenDragStart) { - playingWhenDragStart = false; - startPlay(); - } + //if(playingWhenDragStart) { + // playingWhenDragStart = false; + // startPlay(); + //} } function onDrag(e, ui) { diff --git a/web/app/assets/javascripts/session.js b/web/app/assets/javascripts/session.js index 8999298eb..feaed19de 100644 --- a/web/app/assets/javascripts/session.js +++ b/web/app/assets/javascripts/session.js @@ -305,7 +305,8 @@ window.location="/client#/home" } }) - .done(function() {logger.debug("user has passed all session guards") + .done(function() { + logger.debug("user has passed all session guards") promptLeave = true; var sessionModel = context.JK.CurrentSessionModel; @@ -489,7 +490,25 @@ else { app.notifyServerError(xhr, 'Unable to Join Session'); } - }); + }) + .done(function() { + // check if this is a auto-load jamtrack situation (came from account jamtrack screen) + var jamTrack = sessionUtils.grabAutoOpenJamTrack(); + if(jamTrack) { + // give the session to settle just a little (call a timeout of 1 second) + setTimeout(function() { + // tell the server we are about to open a jamtrack + rest.openJamTrack({id: context.JK.CurrentSessionModel.id(), jam_track_id: jamTrack.id}) + .done(function(response) { + // now actually load the jamtrack + loadJamTrack(jamTrack); + }) + .fail(function(jqXHR) { + app.notifyServerError(jqXHR, "Unable to Open JamTrack For Playback"); + }) + }, 1000) + } + }) }) } @@ -1276,7 +1295,7 @@ } function renderJamTracks(jamTrackMixersOrig) { - logger.debug("rendering jam tracks") + logger.debug("rendering jam tracks", jamTrackMixersOrig); var jamTrackMixers = jamTrackMixersOrig.slice(); var jamTracks = [] @@ -2699,69 +2718,7 @@ // once the dialog is closed, see if the user has a jamtrack selected if(!data.canceled && data.result.jamTrack) { - - var jamTrack = data.result.jamTrack; - - $('.session-recording-name').text(''); - - // hide 'other audio' placeholder - otherAudioFilled(); - - if(downloadJamTrack) { - // if there was one showing before somehow, destroy it. - logger.warn("destroying existing JamTrack") - downloadJamTrack.root.remove(); - downloadJamTrack.destroy(); - downloadJamTrack = null - } - - downloadJamTrack = new context.JK.DownloadJamTrack(app, jamTrack, 'large'); - - // the widget indicates when it gets to any transition; we can hide it once it reaches completion - $(downloadJamTrack).on(EVENTS.JAMTRACK_DOWNLOADER_STATE_CHANGED, function(e, data) { - - if(data.state == downloadJamTrack.states.synchronized) { - logger.debug("jamtrack synchronized; hide widget and show tracks") - downloadJamTrack.root.remove(); - downloadJamTrack.destroy(); - downloadJamTrack = null; - - // XXX: test with this removed; it should be unnecessary - context.jamClient.JamTrackStopPlay(); - - var sampleRate = context.jamClient.GetSampleRate() - var sampleRateForFilename = sampleRate == 48 ? '48' : '44' - var fqId = jamTrack.id + '-' + sampleRateForFilename - - if(jamTrack.jmep) - { - logger.debug("setting jmep data") - - context.jamClient.JamTrackLoadJmep(fqId, jamTrack.jmep) - } - else { - logger.debug("no jmep data for jamtrack") - } - - // JamTrackPlay means 'load' - var result = context.jamClient.JamTrackPlay(fqId); - - if(!result) { - app.notify( - { title: "JamTrack Can Not Open", - text: "Unable to open your JamTrack. Please contact support@jamkazam.com" - }, null, true); - } else { - playJamTrack(jamTrack.id); - } - } - }) - - // show it on the page - $otherAudioContainer.append(downloadJamTrack.root) - - // kick off the download JamTrack process - downloadJamTrack.init() + loadJamTrack(data.result.jamTrack); } else { logger.debug("OpenJamTrack dialog closed with no selection; ignoring", data) @@ -2771,6 +2728,69 @@ return false; } + function loadJamTrack(jamTrack) { + + $('.session-recording-name').text(''); + + // hide 'other audio' placeholder + otherAudioFilled(); + + if(downloadJamTrack) { + // if there was one showing before somehow, destroy it. + logger.warn("destroying existing JamTrack") + downloadJamTrack.root.remove(); + downloadJamTrack.destroy(); + downloadJamTrack = null + } + + downloadJamTrack = new context.JK.DownloadJamTrack(app, jamTrack, 'large'); + + // the widget indicates when it gets to any transition; we can hide it once it reaches completion + $(downloadJamTrack).on(EVENTS.JAMTRACK_DOWNLOADER_STATE_CHANGED, function(e, data) { + + if(data.state == downloadJamTrack.states.synchronized) { + logger.debug("jamtrack synchronized; hide widget and show tracks") + downloadJamTrack.root.remove(); + downloadJamTrack.destroy(); + downloadJamTrack = null; + + // XXX: test with this removed; it should be unnecessary + context.jamClient.JamTrackStopPlay(); + + var sampleRate = context.jamClient.GetSampleRate() + var sampleRateForFilename = sampleRate == 48 ? '48' : '44' + var fqId = jamTrack.id + '-' + sampleRateForFilename + + if(jamTrack.jmep) + { + logger.debug("setting jmep data") + + context.jamClient.JamTrackLoadJmep(fqId, jamTrack.jmep) + } + else { + logger.debug("no jmep data for jamtrack") + } + + // JamTrackPlay means 'load' + var result = context.jamClient.JamTrackPlay(fqId); + + if(!result) { + app.notify( + { title: "JamTrack Can Not Open", + text: "Unable to open your JamTrack. Please contact support@jamkazam.com" + }, null, true); + } else { + playJamTrack(jamTrack.id); + } + } + }) + + // show it on the page + $otherAudioContainer.append(downloadJamTrack.root) + + // kick off the download JamTrack process + downloadJamTrack.init() + } function playJamTrack(jamTrackId) { var participantCnt=sessionModel.participants().length rest.playJamTrack(jamTrackId) @@ -3088,7 +3108,11 @@ logger.debug("calling jamClient.SessionTrackSeekMs(" + seek + ")"); if(data.playbackMonitorMode == context.JK.PLAYBACK_MONITOR_MODE.JAMTRACK) { + // this doesn't ever show anything, because of blocking nature of the seek call + //var $mediaSeeking = $screen.find('.media-seeking') + //$mediaSeeking.attr('data-mode', 'SEEKING') context.jamClient.SessionJamTrackSeekMs(seek); + //$mediaSeeking.attr('data-mode', '') } else { context.jamClient.SessionTrackSeekMs(seek); diff --git a/web/app/assets/javascripts/session_utils.js b/web/app/assets/javascripts/session_utils.js index a7eefa791..9d54f2493 100644 --- a/web/app/assets/javascripts/session_utils.js +++ b/web/app/assets/javascripts/session_utils.js @@ -10,6 +10,7 @@ var rest = new context.JK.Rest(); context.JK.SessionUtils = sessionUtils; var logger = context.JK.logger; + var autoOpenJamTrack = null; var LATENCY = sessionUtils.LATENCY = { ME : {description: "ME", style: "latency-me", min: -1, max: -1}, @@ -20,6 +21,18 @@ UNKNOWN: {description: "UNKNOWN", style: "latency-unknown", min: -2, max: -2} }; + sessionUtils.setAutoOpenJamTrack = function(jamTrack) { + logger.debug("setting auto-load jamtrack") + autoOpenJamTrack = jamTrack; + } + + // one shot! + sessionUtils.grabAutoOpenJamTrack = function() { + var jamTrack = autoOpenJamTrack; + autoOpenJamTrack = null; + return jamTrack; + } + sessionUtils.createOpenSlot = function($openSlotsTemplate, slot, openSlotCount, currentSlotIndex) { var inst = context.JK.getInstrumentIcon24(slot.instrument_id); diff --git a/web/app/assets/stylesheets/client/checkout.css.scss b/web/app/assets/stylesheets/client/checkout.css.scss index 8e9e40b9d..4244928ba 100644 --- a/web/app/assets/stylesheets/client/checkout.css.scss +++ b/web/app/assets/stylesheets/client/checkout.css.scss @@ -45,78 +45,3 @@ margin-left: 30px; } } - -.thanks-panel { - padding: 30px; - - span.notice { - font-style:italic; - font-size:12px; - } - - br.purchase-downloads { - clear:both; - margin-bottom:20px; - } - - .thanks-detail { - .download-jamkazam { - color:$ColorLink; - border-radius: 4px; - border-style:solid; - border-color:#AAA; - border-width:1px; - padding:10px; - margin-top:20px; - display:inline-block; - } - - .download-jamkazam-wrapper { - text-align:center; - display:block; - - &.hidden { - display:none; - } - } - } - .thanks-detail.purchased-jam-track { - - margin-top:20px; - - .purchased-jam-track-header { - font-size: 15px; - margin-bottom:10px; - - span { - display:none; - } - - &[status="in-progress"] { - span.in-progress-msg { - display:inline; - } - } - - &[status="done"] { - span.done-msg { - display:inline; - } - } - } - - ul.purchased-list { - float:left; - margin:20px 100px 0 20px; - - li { - margin:0; - } - } - - .download-jamtrack { - width:auto; - vertical-align: middle; // to make bullets mid-align when error shows - } - } -} diff --git a/web/app/assets/stylesheets/client/checkout_complete.css.scss b/web/app/assets/stylesheets/client/checkout_complete.css.scss new file mode 100644 index 000000000..45c9b3951 --- /dev/null +++ b/web/app/assets/stylesheets/client/checkout_complete.css.scss @@ -0,0 +1,116 @@ +@import "client/common.css.scss"; +#checkoutCompleteScreen { + + p { + font-size:14px; + margin:0; + } + + .order-prompt { + color:white; + line-height:125%; + } + + h2 { + color:white; + background-color:#4d4d4d; + font-weight:normal; + margin: 0 0 10px 0; + font-size:14px; + padding: 3px 0 3px 10px; + height: 14px; + line-height: 14px; + vertical-align: middle; + text-align:left; + } + + .action-bar { + margin-top:20px; + } + + #checkout-info-help { + margin-right:1px; + } + + .checkout-complete-wrapper { + padding:30px 30px; + } + + .no-purchases-prompt { + + } + .thanks-panel { + + + span.notice { + font-style:italic; + font-size:12px; + } + + br.purchase-downloads { + clear:both; + margin-bottom:20px; + } + + .thanks-detail { + .download-jamkazam { + color:$ColorLink; + border-radius: 4px; + border-style:solid; + border-color:#AAA; + border-width:1px; + padding:10px; + margin-top:20px; + display:inline-block; + } + + .download-jamkazam-wrapper { + text-align:center; + display:block; + + &.hidden { + display:none; + } + } + } + .thanks-detail.purchased-jam-track { + + margin-top:20px; + + .purchased-jam-track-header { + font-size: 15px; + margin-bottom:10px; + + span { + display:none; + } + + &[status="in-progress"] { + span.in-progress-msg { + display:inline; + } + } + + &[status="done"] { + span.done-msg { + display:inline; + } + } + } + + ul.purchased-list { + float:left; + margin:20px 100px 0 20px; + + li { + margin:0; + } + } + + .download-jamtrack { + width:auto; + vertical-align: middle; // to make bullets mid-align when error shows + } + } + } +} \ No newline at end of file diff --git a/web/app/assets/stylesheets/client/client.css b/web/app/assets/stylesheets/client/client.css index 9ade671f2..341aa8486 100644 --- a/web/app/assets/stylesheets/client/client.css +++ b/web/app/assets/stylesheets/client/client.css @@ -61,6 +61,8 @@ *= require ./checkout_signin *= require ./checkout_payment *= require ./checkout_order + *= require ./checkout_complete + *= require ./genreSelector *= require ./sessionList *= require ./searchResults *= require ./clientUpdate diff --git a/web/app/assets/stylesheets/client/session.css.scss b/web/app/assets/stylesheets/client/session.css.scss index 50be54daf..213a4d726 100644 --- a/web/app/assets/stylesheets/client/session.css.scss +++ b/web/app/assets/stylesheets/client/session.css.scss @@ -85,7 +85,7 @@ top:3px ! important; } - .jam-track-get-ready { + .jam-track-get-ready, .media-seeking { display:none; position:absolute; top:-29px; @@ -96,11 +96,6 @@ line-height:32px; left:50%; - &[data-mode="JAMTRACK"] { - &[data-current-time="0"] { - display:block; - } - } .spinner-small { vertical-align:middle; display:inline-block; @@ -110,6 +105,14 @@ vertical-align:middle; } } + + .jam-track-get-ready[data-mode="JAMTRACK"][data-current-time="0"] { + display:block; + } + + .media-seeking[data-mode="SEEKING"] { + display:block; + } } .playback-mode-buttons { diff --git a/web/app/controllers/application_controller.rb b/web/app/controllers/application_controller.rb index 4a2ae2397..844faf7ea 100644 --- a/web/app/controllers/application_controller.rb +++ b/web/app/controllers/application_controller.rb @@ -5,6 +5,8 @@ class ApplicationController < ActionController::Base include SessionsHelper include ClientHelper + force_ssl port: Rails.application.config.external_port_ssl if Rails.application.config.force_ssl + # inject username/email into bugsnag data before_bugsnag_notify :add_user_info_to_bugsnag diff --git a/web/app/views/clients/_account.html.erb b/web/app/views/clients/_account.html.erb index 12089c9f2..af5e85f10 100644 --- a/web/app/views/clients/_account.html.erb +++ b/web/app/views/clients/_account.html.erb @@ -124,7 +124,7 @@