VRFS-3007 : Merge with latest develop
|
|
@ -1,20 +1,29 @@
|
|||
require 'jam_ruby/recurly_client'
|
||||
ActiveAdmin.register JamRuby::JamTrackRight, :as => 'JamTrackRights' do
|
||||
|
||||
menu :label => 'Purchased JamTracks', :parent => 'JamTracks'
|
||||
menu :label => 'Purchased JamTracks', :parent => 'Purchases'
|
||||
|
||||
config.sort_order = 'updated_at DESC'
|
||||
config.sort_order = 'created_at DESC'
|
||||
config.batch_actions = false
|
||||
|
||||
#form :partial => 'form'
|
||||
|
||||
filter :user_id
|
||||
|
||||
filter :user_id,
|
||||
:label => "USER ID", :required => false,
|
||||
:wrapper_html => { :style => "list-style: none" }
|
||||
|
||||
|
||||
filter :jam_track
|
||||
|
||||
index do
|
||||
default_actions
|
||||
|
||||
column "Order" do |right|
|
||||
link_to("Place", order_admin_jam_track_right_path(right)) + " | " +
|
||||
link_to("Refund", refund_admin_jam_track_right_path(right))
|
||||
end
|
||||
#column "Order" do |right|
|
||||
#link_to("Place", order_admin_jam_track_right_path(right)) + " | " +
|
||||
# link_to("Refund", refund_admin_jam_track_right_path(right))
|
||||
#end
|
||||
|
||||
column "Last Name" do |right|
|
||||
right.user.last_name
|
||||
|
|
@ -23,13 +32,15 @@ ActiveAdmin.register JamRuby::JamTrackRight, :as => 'JamTrackRights' do
|
|||
right.user.first_name
|
||||
end
|
||||
column "Jam Track" do |right|
|
||||
link_to(right.jam_track.name, admin_jam_track_right_path(right.jam_track))
|
||||
link_to(right.jam_track.name, admin_jam_track_path(right.jam_track))
|
||||
# right.jam_track
|
||||
end
|
||||
column "Plan Code" do |right|
|
||||
|
||||
right.jam_track.plan_code
|
||||
end
|
||||
column "Redeemed" do |right|
|
||||
right.redeemed ? 'Y' : 'N'
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -42,6 +53,9 @@ ActiveAdmin.register JamRuby::JamTrackRight, :as => 'JamTrackRights' do
|
|||
f.actions
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
|
||||
member_action :order, :method => :get do
|
||||
right = JamTrackRight.where("id=?",params[:id]).first
|
||||
user = right.user
|
||||
|
|
@ -84,4 +98,5 @@ ActiveAdmin.register JamRuby::JamTrackRight, :as => 'JamTrackRights' do
|
|||
redirect_to admin_jam_track_rights_path, notice: "Issued full refund on #{right.jam_track} for #{right.user.to_s}"
|
||||
end
|
||||
end
|
||||
=end
|
||||
end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
ActiveAdmin.register JamRuby::RecurlyTransactionWebHook, :as => 'RecurlyHooks' do
|
||||
|
||||
menu :label => 'Recurly Transaction Hooks', :parent => 'Purchases'
|
||||
|
||||
config.sort_order = 'created_at DESC'
|
||||
config.batch_actions = false
|
||||
|
||||
actions :all, :except => [:destroy]
|
||||
|
||||
#form :partial => 'form'
|
||||
|
||||
|
||||
filter :transaction_type, :as => :select, :collection => JamRuby::RecurlyTransactionWebHook::HOOK_TYPES
|
||||
filter :user_id,
|
||||
:label => "USER ID", :required => false,
|
||||
:wrapper_html => { :style => "list-style: none" }
|
||||
|
||||
filter :invoice_id
|
||||
|
||||
form :partial => 'form'
|
||||
|
||||
index do
|
||||
|
||||
default_actions
|
||||
|
||||
column :transaction_type
|
||||
column :transaction_at
|
||||
column :amount_in_cents
|
||||
column 'Transaction' do |hook| link_to('Go to Recurly', Rails.application.config.recurly_root_url + "/transactions/#{hook.recurly_transaction_id}") end
|
||||
column 'Invoice' do |hook| link_to(hook.invoice_number, Rails.application.config.recurly_root_url + "/invoices/#{hook.invoice_number}") end
|
||||
column :admin_description
|
||||
column 'User' do |hook| link_to("#{hook.user.email} (#{hook.user.name})", admin_user_path(hook.user.id)) end
|
||||
|
||||
#column "Order" do |right|
|
||||
#link_to("Place", order_admin_jam_track_right_path(right)) + " | " +
|
||||
# link_to("Refund", refund_admin_jam_track_right_path(right))
|
||||
#end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
= semantic_form_for([:admin, resource], :html => {:multipart => true}, :url => resource.new_record? ? admin_recurly_transaction_web_hooks_path : "#{ENV['RAILS_RELATIVE_URL_ROOT']}/admin/recurly_hooks/#{resource.id}") do |f|
|
||||
= f.semantic_errors *f.object.errors.keys
|
||||
= f.inputs name: 'Recurly Web Hook fields' do
|
||||
= f.input :admin_description, :input_html => { :rows=>1, :maxlength=>200, }, hint: "this will display on the user's payment history page"
|
||||
= f.input :jam_track, collection: JamRuby::JamTrack.all, include_blank: true, hint: "Please indicate which JamTrack this refund for, if not set"
|
||||
= f.actions
|
||||
|
|
@ -83,6 +83,7 @@ module JamAdmin
|
|||
config.external_port = ENV['EXTERNAL_PORT'] || 3000
|
||||
config.external_protocol = ENV['EXTERNAL_PROTOCOL'] || 'http://'
|
||||
config.external_root_url = "#{config.external_protocol}#{config.external_hostname}#{(config.external_port == 80 || config.external_port == 443) ? '' : ':' + config.external_port.to_s}"
|
||||
config.recurly_root_url = 'https://jamkazam-development.recurly.com'
|
||||
|
||||
# where is rabbitmq?
|
||||
config.rabbitmq_host = "localhost"
|
||||
|
|
@ -116,7 +117,7 @@ module JamAdmin
|
|||
config.email_smtp_domain = 'www.jamkazam.com'
|
||||
config.email_smtp_authentication = :plain
|
||||
config.email_smtp_user_name = 'jamkazam'
|
||||
config.email_smtp_password = 'jamjamblueberryjam'
|
||||
config.email_smtp_password = 'snorkeltoesniffyfarce1'
|
||||
config.email_smtp_starttls_auto = true
|
||||
|
||||
config.facebook_app_id = ENV['FACEBOOK_APP_ID'] || '468555793186398'
|
||||
|
|
|
|||
|
|
@ -43,4 +43,7 @@ JamAdmin::Application.configure do
|
|||
|
||||
# Show the logging configuration on STDOUT
|
||||
config.show_log_configuration = true
|
||||
|
||||
config.email_generic_from = 'nobody-dev@jamkazam.com'
|
||||
config.email_alerts_alias = 'alerts-dev@jamkazam.com'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -282,3 +282,7 @@ add_genre_type.sql
|
|||
add_description_to_perf_samples.sql
|
||||
alter_genre_player_unique_constraint.sql
|
||||
musician_search.sql
|
||||
signup_hints.sql
|
||||
packaging_notices.sql
|
||||
first_played_jamtrack_at.sql
|
||||
payment_history.sql
|
||||
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE users ADD COLUMN first_played_jamtrack_at TIMESTAMP;
|
||||
|
|
@ -1 +1,9 @@
|
|||
ALTER TABLE jam_tracks ADD COLUMN duration INTEGER;
|
||||
DO $$
|
||||
BEGIN
|
||||
BEGIN
|
||||
ALTER TABLE jam_tracks ADD COLUMN duration INTEGER;
|
||||
EXCEPTION
|
||||
WHEN duplicate_column THEN RAISE NOTICE 'column duration already exists in jam_tracks.';
|
||||
END;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE jam_track_rights ADD COLUMN packaging_steps INTEGER;
|
||||
ALTER TABLE jam_track_rights ADD COLUMN current_packaging_step INTEGER;
|
||||
ALTER TABLE jam_track_rights ADD COLUMN last_step_at TIMESTAMP;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
ALTER TABLE recurly_transaction_web_hooks ADD COLUMN admin_description VARCHAR;
|
||||
ALTER TABLE recurly_transaction_web_hooks ADD COLUMN jam_track_id VARCHAR(64) REFERENCES jam_tracks(id);
|
||||
|
||||
CREATE VIEW payment_histories AS
|
||||
SELECT id AS sale_id,
|
||||
CAST(NULL as VARCHAR) AS recurly_transaction_web_hook_id,
|
||||
user_id,
|
||||
created_at,
|
||||
'sale' AS transaction_type
|
||||
FROM sales s
|
||||
UNION ALL
|
||||
SELECT CAST(NULL as VARCHAR) AS sale_id,
|
||||
id AS recurly_transaction_web_hook_id,
|
||||
user_id,
|
||||
transaction_at AS created_at,
|
||||
transaction_type
|
||||
FROM recurly_transaction_web_hooks;
|
||||
|
|
@ -1,4 +1,11 @@
|
|||
ALTER TABLE jam_track_tracks ADD COLUMN preview_mp3_url VARCHAR;
|
||||
ALTER TABLE jam_track_tracks ADD COLUMN preview_mp3_md5 VARCHAR;
|
||||
ALTER TABLE jam_track_tracks ADD COLUMN preview_mp3_length BIGINT;
|
||||
UPDATE jam_track_tracks SET preview_url = NULL where track_type = 'Master';
|
||||
DO $$
|
||||
BEGIN
|
||||
BEGIN
|
||||
ALTER TABLE jam_track_tracks ADD COLUMN preview_mp3_url VARCHAR;
|
||||
ALTER TABLE jam_track_tracks ADD COLUMN preview_mp3_md5 VARCHAR;
|
||||
ALTER TABLE jam_track_tracks ADD COLUMN preview_mp3_length BIGINT;
|
||||
EXCEPTION
|
||||
WHEN duplicate_column THEN RAISE NOTICE 'preview mp3 columns already exist in jam_tracks';
|
||||
END;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
CREATE TABLE signup_hints (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
anonymous_user_id VARCHAR(64) UNIQUE,
|
||||
redirect_location VARCHAR,
|
||||
want_jamblaster BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
user_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE,
|
||||
expires_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE users ADD COLUMN want_jamblaster BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"container_file": "/var/folders/fk/0ckzmddd4tq28kxbb09vckbr0000gn/T/d20150428-83245-1alsyg1/jam-track-19.jkz", "version": "0", "coverart": null, "rsa_priv_file": "/var/folders/fk/0ckzmddd4tq28kxbb09vckbr0000gn/T/d20150428-83245-1alsyg1/skey.pem", "tracks": [{"name": "/var/folders/fk/0ckzmddd4tq28kxbb09vckbr0000gn/T/d20150428-83245-1alsyg1/9599b114-0f66-4140-ae3a-078a4e0c0767.ogg", "trackName": "track_00"}], "rsa_pub_file": "/var/folders/fk/0ckzmddd4tq28kxbb09vckbr0000gn/T/d20150428-83245-1alsyg1/pkey.pem", "jamktrack_info": "/var/folders/fk/0ckzmddd4tq28kxbb09vckbr0000gn/T/tmp9PHU_9"}
|
||||
|
|
@ -20,11 +20,12 @@ require 'resque_mailer'
|
|||
require 'rest-client'
|
||||
require 'zip'
|
||||
require 'csv'
|
||||
require 'tzinfo'
|
||||
|
||||
require "jam_ruby/constants/limits"
|
||||
require "jam_ruby/constants/notification_types"
|
||||
require "jam_ruby/constants/validation_messages"
|
||||
require "jam_ruby/errors/permission_error"
|
||||
require "jam_ruby/errors/jam_permission_error"
|
||||
require "jam_ruby/errors/state_error"
|
||||
require "jam_ruby/errors/jam_argument_error"
|
||||
require "jam_ruby/errors/conflict_error"
|
||||
|
|
@ -100,6 +101,7 @@ require "jam_ruby/models/genre_player"
|
|||
require "jam_ruby/models/genre"
|
||||
require "jam_ruby/models/user"
|
||||
require "jam_ruby/models/anonymous_user"
|
||||
require "jam_ruby/models/signup_hint"
|
||||
require "jam_ruby/models/rsvp_request"
|
||||
require "jam_ruby/models/rsvp_slot"
|
||||
require "jam_ruby/models/rsvp_request_rsvp_slot"
|
||||
|
|
@ -205,6 +207,7 @@ require "jam_ruby/models/generic_state"
|
|||
require "jam_ruby/models/score_history"
|
||||
require "jam_ruby/models/jam_company"
|
||||
require "jam_ruby/models/user_sync"
|
||||
require "jam_ruby/models/payment_history"
|
||||
require "jam_ruby/models/video_source"
|
||||
require "jam_ruby/models/text_message"
|
||||
require "jam_ruby/models/sale"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module JamRuby
|
||||
# sends out a boring ale
|
||||
class AdminMailer < ActionMailer::Base
|
||||
class AdminMailer < ActionMailer::Base
|
||||
include SendGrid
|
||||
|
||||
|
||||
|
|
@ -14,9 +14,24 @@ module JamRuby
|
|||
|
||||
def alerts(options)
|
||||
mail(to: APP_CONFIG.email_alerts_alias,
|
||||
from: APP_CONFIG.email_generic_from,
|
||||
body: options[:body],
|
||||
content_type: "text/plain",
|
||||
subject: options[:subject])
|
||||
end
|
||||
|
||||
def recurly_alerts(user, options)
|
||||
|
||||
body = options[:body]
|
||||
body << "\n\n"
|
||||
body << "User " << user.admin_url + "\n"
|
||||
body << "User's JamTracks " << user.jam_track_rights_admin_url + "\n"
|
||||
|
||||
mail(to: APP_CONFIG.email_recurly_notice,
|
||||
from: APP_CONFIG.email_generic_from,
|
||||
body: body,
|
||||
content_type: "text/plain",
|
||||
subject: options[:subject])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
<%= yield %>
|
||||
<% end %>
|
||||
|
||||
<% unless @suppress_user_has_account_footer == true %>
|
||||
This email was sent to you because you have an account at JamKazam / http://www.jamkazam.com. Visit your profile page to unsubscribe: http://www.jamkazam.com/unsubscribe/<%=@user.unsubscribe_token%>.
|
||||
<% unless @user.nil? || @suppress_user_has_account_footer == true %>
|
||||
This email was sent to you because you have an account at JamKazam / http://www.jamkazam.com. To unsubscribe: http://www.jamkazam.com/unsubscribe/<%=@user.unsubscribe_token%>.
|
||||
<% end %>
|
||||
|
||||
Copyright <%= Time.now.year %> JamKazam, Inc. All rights reserved.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
module JamRuby
|
||||
class JamPermissionError < Exception
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
module JamRuby
|
||||
class PermissionError < Exception
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -91,13 +91,15 @@ module JamRuby
|
|||
true
|
||||
end
|
||||
|
||||
def synchronize_metadata(jam_track, metadata, metalocation, original_artist, name)
|
||||
def synchronize_metadata(jam_track, metadata, metalocation, original_artist, name, options)
|
||||
|
||||
metadata ||= {}
|
||||
self.name = metadata["name"] || name
|
||||
|
||||
if jam_track.new_record?
|
||||
jam_track.id = "#{JamTrack.count + 1}" # default is UUID, but the initial import was based on auto-increment ID, so we'll maintain that
|
||||
latest_jamtrack = JamTrack.order('created_at desc').first
|
||||
id = latest_jamtrack.nil? ? 1 : latest_jamtrack.id.to_i + 1
|
||||
jam_track.id = "#{id}" # default is UUID, but the initial import was based on auto-increment ID, so we'll maintain that
|
||||
jam_track.status = 'Staging'
|
||||
jam_track.metalocation = metalocation
|
||||
jam_track.original_artist = metadata["original_artist"] || original_artist
|
||||
|
|
@ -107,13 +109,20 @@ module JamRuby
|
|||
jam_track.price = 1.99
|
||||
jam_track.reproduction_royalty_amount = 0
|
||||
jam_track.licensor_royalty_amount = 0
|
||||
jam_track.sales_region = 'United States'
|
||||
jam_track.sales_region = 'Worldwide'
|
||||
jam_track.recording_type = 'Cover'
|
||||
jam_track.description = "This is a JamTrack audio file for use exclusively with the JamKazam service. This JamTrack is a high quality cover of the #{jam_track.original_artist} song \"#{jam_track.name}\"."
|
||||
else
|
||||
#@@log.debug("#{self.name} skipped because it already exists in database")
|
||||
finish("jam_track_exists", "")
|
||||
return false
|
||||
if !options[:resync_audio]
|
||||
#@@log.debug("#{self.name} skipped because it already exists in database")
|
||||
finish("jam_track_exists", "")
|
||||
return false
|
||||
else
|
||||
# jamtrack exists, leave it be
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
saved = jam_track.save
|
||||
|
|
@ -318,24 +327,31 @@ module JamRuby
|
|||
|
||||
def set_custom_weight(track)
|
||||
weight = 5
|
||||
case track.instrument_id
|
||||
when 'electric guitar'
|
||||
weight = 1
|
||||
when 'acoustic guitar'
|
||||
weight = 2
|
||||
when 'drums'
|
||||
weight = 3
|
||||
when 'keys'
|
||||
weight = 4
|
||||
when 'computer'
|
||||
weight = 10
|
||||
else
|
||||
weight = 5
|
||||
end
|
||||
if track.track_type == 'Master'
|
||||
weight = 1000
|
||||
# if there are any persisted tracks, do not sort from scratch; just stick new stuff at the end
|
||||
|
||||
if track.persisted?
|
||||
weight = track.position
|
||||
else
|
||||
case track.instrument_id
|
||||
when 'electric guitar'
|
||||
weight = 100
|
||||
when 'acoustic guitar'
|
||||
weight = 200
|
||||
when 'drums'
|
||||
weight = 300
|
||||
when 'keys'
|
||||
weight = 400
|
||||
when 'computer'
|
||||
weight = 600
|
||||
else
|
||||
weight = 500
|
||||
end
|
||||
if track.track_type == 'Master'
|
||||
weight = 1000
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
weight
|
||||
end
|
||||
|
||||
|
|
@ -346,10 +362,19 @@ module JamRuby
|
|||
a_weight <=> b_weight
|
||||
end
|
||||
|
||||
# default to 1, but if there are any persisted tracks, this will get manipulated to be +1 the highest persisted track
|
||||
position = 1
|
||||
sorted_tracks.each do |track|
|
||||
track.position = position
|
||||
position = position + 1
|
||||
if track.persisted?
|
||||
# persisted tracks should be sorted at the beginning of the sorted_tracks,
|
||||
# so this just keeps moving the 'position builder' up to +1 of the last persisted track
|
||||
position = track.position + 1
|
||||
else
|
||||
track.position = position
|
||||
position = position + 1
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
sorted_tracks[sorted_tracks.length - 1].position = 1000
|
||||
|
|
@ -359,11 +384,40 @@ module JamRuby
|
|||
|
||||
def synchronize_audio(jam_track, metadata, s3_path, skip_audio_upload)
|
||||
|
||||
attempt_to_match_existing_tracks = true
|
||||
|
||||
# find all wav files in the JamTracks s3 bucket
|
||||
wav_files = fetch_wav_files(s3_path)
|
||||
|
||||
tracks = []
|
||||
|
||||
wav_files.each do |wav_file|
|
||||
|
||||
if attempt_to_match_existing_tracks
|
||||
# try to find a matching track from the JamTrack based on the name of the 44.1 path
|
||||
basename = File.basename(wav_file)
|
||||
ogg_44100_filename = File.basename(basename, ".wav") + "-44100.ogg"
|
||||
|
||||
found_track = nil
|
||||
jam_track.jam_track_tracks.each do |jam_track_track|
|
||||
|
||||
if jam_track_track["url_44"] && jam_track_track["url_44"].end_with?(ogg_44100_filename)
|
||||
# found a match!
|
||||
found_track = jam_track_track
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if found_track
|
||||
@@log.debug("found a existing track to reuse")
|
||||
found_track.original_audio_s3_path = wav_file
|
||||
tracks << found_track
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
@@log.debug("no existing track found; creating a new one")
|
||||
|
||||
track = JamTrackTrack.new
|
||||
track.original_audio_s3_path = wav_file
|
||||
|
||||
|
|
@ -388,6 +442,15 @@ module JamRuby
|
|||
tracks << track
|
||||
end
|
||||
|
||||
jam_track.jam_track_tracks.each do |jam_track_track|
|
||||
# delete all jam_track_tracks not in the tracks array
|
||||
unless tracks.include?(jam_track_track)
|
||||
@@log.info("destroying removed JamTrackTrack #{jam_track_track.inspect}")
|
||||
jam_track_track.destroy # should also delete s3 files associated with this jamtrack
|
||||
end
|
||||
end
|
||||
|
||||
@@log.info("sorting tracks")
|
||||
tracks = sort_tracks(tracks)
|
||||
|
||||
jam_track.jam_track_tracks = tracks
|
||||
|
|
@ -481,15 +544,16 @@ module JamRuby
|
|||
track["length_48"] = File.new(ogg_48000).size
|
||||
|
||||
synchronize_duration(jam_track, ogg_44100)
|
||||
jam_track.save!
|
||||
|
||||
# convert entire master ogg file to mp3, and push both to public destination
|
||||
preview_succeeded = synchronize_master_preview(track, tmp_dir, ogg_44100, ogg_44100_digest) if track.track_type == 'Master'
|
||||
if track.track_type == 'Master'
|
||||
preview_succeeded = synchronize_master_preview(track, tmp_dir, ogg_44100, ogg_44100_digest)
|
||||
|
||||
if !preview_succeeded
|
||||
return false
|
||||
if !preview_succeeded
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
track.save!
|
||||
|
|
@ -596,7 +660,7 @@ module JamRuby
|
|||
original_artist = parsed_metalocation[1]
|
||||
name = parsed_metalocation[2]
|
||||
|
||||
success = synchronize_metadata(jam_track, metadata, metalocation, original_artist, name)
|
||||
success = synchronize_metadata(jam_track, metadata, metalocation, original_artist, name, options)
|
||||
|
||||
return unless success
|
||||
|
||||
|
|
@ -614,8 +678,8 @@ module JamRuby
|
|||
def synchronize_recurly(jam_track)
|
||||
begin
|
||||
recurly = RecurlyClient.new
|
||||
# no longer create JamTrack plans: VRFS-3028
|
||||
# recurly.create_jam_track_plan(jam_track) unless recurly.find_jam_track_plan(jam_track)
|
||||
# no longer create JamTrack plans: VRFS-3028
|
||||
# recurly.create_jam_track_plan(jam_track) unless recurly.find_jam_track_plan(jam_track)
|
||||
rescue RecurlyClientError => x
|
||||
finish('recurly_create_plan', x.errors.to_s)
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -22,9 +22,21 @@ module JamRuby
|
|||
save_jam_track_right_jkz(jam_track_right, sample_rate)
|
||||
end
|
||||
|
||||
# increment the step, which causes a notification to be sent to the client so it can keep the UI fresh as the packaging step goes on
|
||||
def bump_step(jam_track_right, step)
|
||||
last_step_at = Time.now
|
||||
jam_track_right.current_packaging_step = step
|
||||
jam_track_right.last_step_at = Time.now
|
||||
JamTrackRight.where(:id => jam_track_right.id).update_all(last_step_at: last_step_at, current_packaging_step: step)
|
||||
SubscriptionMessage.jam_track_signing_job_change(jam_track_right)
|
||||
step = step + 1
|
||||
step
|
||||
end
|
||||
|
||||
def save_jam_track_right_jkz(jam_track_right, sample_rate=48)
|
||||
jam_track = jam_track_right.jam_track
|
||||
py_root = APP_CONFIG.jamtracks_dir
|
||||
step = 0
|
||||
Dir.mktmpdir do |tmp_dir|
|
||||
jam_file_opts=""
|
||||
jam_track.jam_track_tracks.each do |jam_track_track|
|
||||
|
|
@ -36,6 +48,9 @@ module JamRuby
|
|||
track_filename = File.join(tmp_dir, nm)
|
||||
track_url = jam_track_track.sign_url(120, sample_rate)
|
||||
@@log.info("downloading #{track_url} to #{track_filename}")
|
||||
|
||||
step = bump_step(jam_track_right, step)
|
||||
|
||||
copy_url_to_file(track_url, track_filename)
|
||||
jam_file_opts << " -i #{Shellwords.escape("#{track_filename}+#{jam_track_track.part}")}"
|
||||
end
|
||||
|
|
@ -48,6 +63,8 @@ module JamRuby
|
|||
version = jam_track.version
|
||||
@@log.info "Executing python source in #{py_file}, outputting to #{tmp_dir} (#{output_jkz})"
|
||||
|
||||
step = bump_step(jam_track_right, step)
|
||||
|
||||
# From http://stackoverflow.com/questions/690151/getting-output-of-system-calls-in-ruby/5970819#5970819:
|
||||
cli = "python #{py_file} -D -k #{sku} -p #{Shellwords.escape(tmp_dir)}/pkey.pem -s #{Shellwords.escape(tmp_dir)}/skey.pem #{jam_file_opts} -o #{Shellwords.escape(output_jkz)} -t #{Shellwords.escape(title)} -V #{Shellwords.escape(version)}"
|
||||
Open3.popen3(cli) do |stdin, stdout, stderr, wait_thr|
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
def self.jam_track_signing_job_change(jam_track_right)
|
||||
Notification.send_subscription_message('jam_track_right', jam_track_right.id.to_s, {signing_state: jam_track_right.signing_state}.to_json )
|
||||
Notification.send_subscription_message('jam_track_right', jam_track_right.id.to_s, {signing_state: jam_track_right.signing_state, current_packaging_step: jam_track_right.current_packaging_step, packaging_steps: jam_track_right.packaging_steps}.to_json )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module JamRuby
|
|||
|
||||
self.table_name = 'active_music_sessions'
|
||||
|
||||
attr_accessor :legal_terms, :max_score, :opening_jam_track, :opening_recording, :opening_backing_track, :opening_metronome
|
||||
attr_accessor :legal_terms, :max_score, :opening_jam_track, :opening_recording, :opening_backing_track, :opening_metronome, :jam_track_id
|
||||
|
||||
belongs_to :claimed_recording, :class_name => "JamRuby::ClaimedRecording", :foreign_key => "claimed_recording_id", :inverse_of => :playing_sessions
|
||||
belongs_to :claimed_recording_initiator, :class_name => "JamRuby::User", :inverse_of => :playing_claimed_recordings, :foreign_key => "claimed_recording_initiator_id"
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
module JamRuby
|
||||
class AfterSignupHint < ActiveRecord::Base
|
||||
|
||||
before_create :generate_lookup_id
|
||||
|
||||
def self.delete_old
|
||||
FacebookSignup.where("created_at < :week", {:week => 1.week.ago}).delete_all
|
||||
end
|
||||
|
||||
private
|
||||
def generate_lookup_id
|
||||
self.lookup_id = SecureRandom.urlsafe_base64
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -11,7 +11,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
def shopping_carts
|
||||
ShoppingCart.where(anonymous_user_id: @id)
|
||||
ShoppingCart.where(anonymous_user_id: @id).order('created_at DESC')
|
||||
end
|
||||
|
||||
def destroy_all_shopping_carts
|
||||
|
|
|
|||
|
|
@ -163,14 +163,14 @@ module JamRuby
|
|||
|
||||
# ensure person creating this Band is a Musician
|
||||
unless user.musician?
|
||||
raise PermissionError, "must be a musician"
|
||||
raise JamPermissionError, "must be a musician"
|
||||
end
|
||||
|
||||
band = id.blank? ? Band.new : Band.find(id)
|
||||
|
||||
# ensure user updating Band details is a Band member
|
||||
unless band.new_record? || band.users.exists?(user)
|
||||
raise PermissionError, ValidationMessages::USER_NOT_BAND_MEMBER_VALIDATION_ERROR
|
||||
raise JamPermissionError, ValidationMessages::USER_NOT_BAND_MEMBER_VALIDATION_ERROR
|
||||
end
|
||||
|
||||
band.name = params[:name] if params.has_key?(:name)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ module JamRuby
|
|||
# params is a hash, and everything is optional
|
||||
def update_fields(user, params)
|
||||
if user != self.user
|
||||
raise PermissionError, "user doesn't own claimed_recording"
|
||||
raise JamPermissionError, "user doesn't own claimed_recording"
|
||||
end
|
||||
|
||||
self.name = params[:name]
|
||||
|
|
@ -53,7 +53,7 @@ module JamRuby
|
|||
|
||||
def discard(user)
|
||||
if user != self.user
|
||||
raise PermissionError, "user doesn't own claimed_recording"
|
||||
raise JamPermissionError, "user doesn't own claimed_recording"
|
||||
end
|
||||
|
||||
ClaimedRecording.where(:id => id).update_all(:discarded => true )
|
||||
|
|
@ -96,11 +96,11 @@ module JamRuby
|
|||
|
||||
target_user = params[:user]
|
||||
|
||||
raise PermissionError, "must specify current user" unless user
|
||||
raise JamPermissionError, "must specify current user" unless user
|
||||
raise "user must be specified" unless target_user
|
||||
|
||||
if target_user != user.id
|
||||
raise PermissionError, "unable to view another user's favorites"
|
||||
raise JamPermissionError, "unable to view another user's favorites"
|
||||
end
|
||||
|
||||
query = ClaimedRecording.limit(limit).order('created_at DESC').offset(start)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,10 @@ module JamRuby
|
|||
# has_many :plays, :class_name => "JamRuby::PlayablePlay", :foreign_key => :jam_track_id, :dependent => :destroy
|
||||
# VRFS-2916 jam_tracks.id is varchar: ADD
|
||||
has_many :plays, :class_name => "JamRuby::PlayablePlay", :as => :playable, :dependent => :destroy
|
||||
|
||||
|
||||
# when we know what JamTrack this refund is related to, these are associated
|
||||
belongs_to :recurly_transactions, class_name: 'JamRuby::RecurlyTransactionWebHook'
|
||||
|
||||
accepts_nested_attributes_for :jam_track_tracks, allow_destroy: true
|
||||
accepts_nested_attributes_for :jam_track_tap_ins, allow_destroy: true
|
||||
|
||||
|
|
@ -161,21 +164,75 @@ module JamRuby
|
|||
query = query.where("original_artist=?", options[:artist])
|
||||
end
|
||||
|
||||
if options[:id].present?
|
||||
query = query.where("jam_tracks.id=?", options[:id])
|
||||
end
|
||||
|
||||
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.name')
|
||||
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.where("jam_tracks.sales_region = '#{options[:availability]}'") unless options[:availability].blank?
|
||||
|
||||
|
||||
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]
|
||||
|
|
@ -192,6 +249,10 @@ module JamRuby
|
|||
JamTrackTrack.where(jam_track_id: self.id).where(track_type: 'Master').first
|
||||
end
|
||||
|
||||
def stem_tracks
|
||||
JamTrackTrack.where(jam_track_id: self.id).where(track_type: 'Track')
|
||||
end
|
||||
|
||||
def can_download?(user)
|
||||
owners.include?(user)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ module JamRuby
|
|||
# try to catch major transitions:
|
||||
|
||||
# if just queue time changes, start time changes, or signed time changes, send out a notice
|
||||
if signing_queued_at_was != signing_queued_at || signing_started_at_was != signing_started_at || last_signed_at_was != last_signed_at
|
||||
if signing_queued_at_was != signing_queued_at || signing_started_at_was != signing_started_at || last_signed_at_was != last_signed_at || current_packaging_step != current_packaging_step_was || packaging_steps != packaging_steps_was
|
||||
SubscriptionMessage.jam_track_signing_job_change(self)
|
||||
end
|
||||
end
|
||||
|
|
@ -148,7 +148,11 @@ module JamRuby
|
|||
if signed
|
||||
state = 'SIGNED'
|
||||
elsif signing_started_at
|
||||
if Time.now - signing_started_at > APP_CONFIG.signing_job_run_max_time
|
||||
# the maximum amount of time the packaging job can take is 10 seconds * num steps. For a 10 track song, this will be 110 seconds. It's a bit long.
|
||||
signing_job_run_max_time = packaging_steps * 10
|
||||
if Time.now - signing_started_at > signing_job_run_max_time
|
||||
state = 'SIGNING_TIMEOUT'
|
||||
elsif Time.now - last_step_at > APP_CONFIG.signing_step_max_time
|
||||
state = 'SIGNING_TIMEOUT'
|
||||
else
|
||||
state = 'SIGNING'
|
||||
|
|
@ -169,6 +173,10 @@ module JamRuby
|
|||
def update_download_count(count=1)
|
||||
self.download_count = self.download_count + count
|
||||
self.last_downloaded_at = Time.now
|
||||
|
||||
if self.signed
|
||||
self.downloaded_since_sign = true
|
||||
end
|
||||
end
|
||||
|
||||
def self.list_keys(user, jamtracks)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ module JamRuby
|
|||
|
||||
@@log = Logging.logger[JamTrackTrack]
|
||||
|
||||
before_destroy :delete_s3_files
|
||||
|
||||
# Because JamTrackImporter imports audio files now, and because also the mere presence of this causes serious issues when updating the model (because reset of url_44 to something bogus), I've removed these
|
||||
#mount_uploader :url_48, JamTrackTrackUploader
|
||||
|
|
@ -20,6 +21,8 @@ module JamRuby
|
|||
|
||||
attr_accessor :original_audio_s3_path, :skip_uploader
|
||||
|
||||
before_destroy :delete_s3_files
|
||||
|
||||
validates :position, presence: true, numericality: {only_integer: true}, length: {in: 1..1000}
|
||||
validates :part, length: {maximum: 25}
|
||||
validates :track_type, inclusion: {in: TRACK_TYPE }
|
||||
|
|
@ -120,6 +123,13 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def delete_s3_files
|
||||
s3_manager.delete(self[:url_44]) if self[:url_44] && s3_manager.exists?(self[:url_44])
|
||||
s3_manager.delete(self[:url_48]) if self[:url_48] && s3_manager.exists?(self[:url_48])
|
||||
s3_public_manager.delete(self[:preview_url]) if self[:preview_url] && s3_public_manager.exists?(self[:preview_url])
|
||||
s3_public_manager.delete(self[:preview_mp3_url]) if self[:preview_mp3_url] && s3_public_manager.exists?(self[:preview_mp3_url])
|
||||
end
|
||||
|
||||
private
|
||||
def normalize_position
|
||||
parent = self.jam_track
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ module JamRuby
|
|||
|
||||
MAX_MIX_TIME = 7200 # 2 hours
|
||||
|
||||
@@log = Logging.logger[Mix]
|
||||
|
||||
before_destroy :delete_s3_files
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
|
@ -137,15 +139,67 @@ module JamRuby
|
|||
one_day = 60 * 60 * 24
|
||||
|
||||
jam_track_offset = 0
|
||||
jam_track_seek = 0
|
||||
|
||||
was_jamtrack_played = false
|
||||
|
||||
if recording.timeline
|
||||
recording_timeline_data = JSON.parse(recording.timeline)
|
||||
|
||||
# did the jam track play at all?
|
||||
jam_track_isplaying = recording_timeline_data["jam_track_isplaying"]
|
||||
recording_start_time = recording_timeline_data["recording_start_time"]
|
||||
jam_track_play_start_time = recording_timeline_data["jam_track_play_start_time"]
|
||||
jam_track_recording_start_play_offset = recording_timeline_data["jam_track_recording_start_play_offset"]
|
||||
|
||||
jam_track_offset = -jam_track_recording_start_play_offset
|
||||
if jam_track_play_start_time != 0
|
||||
was_jamtrack_played = true
|
||||
|
||||
# how long did the JamTrack play? not needed because we limit on the input tracks, which represents how long the recording is, too
|
||||
jam_track_play_time = recording_timeline_data["jam_track_play_time"]
|
||||
|
||||
|
||||
offset = jam_track_play_start_time - recording_start_time
|
||||
|
||||
@@log.debug("base offset = #{offset}")
|
||||
if offset >= 0
|
||||
# jamtrack started after recording, so buffer with silence as necessary\
|
||||
|
||||
if jam_track_recording_start_play_offset < 0
|
||||
@@log.info("prelude captured. offsetting further by #{-jam_track_recording_start_play_offset}")
|
||||
# a negative jam_track_recording_start_play_offset indicates prelude, i.e., silence
|
||||
# so add it to the offset to add more silence as necessary
|
||||
offset = offset + -jam_track_recording_start_play_offset
|
||||
jam_track_offset = offset
|
||||
else
|
||||
@@log.info("positive jamtrack offset; seeking into jamtrack by #{jam_track_recording_start_play_offset}")
|
||||
# a positive jam_track_recording_start_play_offset means we need to cut into the jamtrack
|
||||
jam_track_seek = jam_track_recording_start_play_offset
|
||||
jam_track_offset = offset
|
||||
end
|
||||
else
|
||||
# jamtrack started before recording, so we can seek into it to make up for the missing parts
|
||||
|
||||
if jam_track_recording_start_play_offset < 0
|
||||
@@log.info("partial prelude captured. offset becomes jamtrack offset#{-jam_track_recording_start_play_offset}")
|
||||
# a negative jam_track_recording_start_play_offset indicates prelude, i.e., silence
|
||||
# so add it to the offset to add more silence as necessary
|
||||
jam_track_offset = -jam_track_recording_start_play_offset
|
||||
else
|
||||
@@log.info("no prelude captured. offset becomes jamtrack offset=#{jam_track_recording_start_play_offset}")
|
||||
|
||||
jam_track_offset = 0
|
||||
jam_track_seek = jam_track_recording_start_play_offset
|
||||
end
|
||||
|
||||
|
||||
# also, ignore jam_track_recording_start_play_offset - it simply matches the offset in this case
|
||||
end
|
||||
|
||||
@@log.info("computed values. jam_track_offset=#{jam_track_offset} jam_track_seek=#{jam_track_seek}")
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
manifest = { "files" => [], "timeline" => [] }
|
||||
|
|
@ -154,7 +208,7 @@ module JamRuby
|
|||
|
||||
# this 'pick limiter' logic will ensure that we set a limiter on the 1st recorded_track we come across.
|
||||
pick_limiter = false
|
||||
if recording.is_jamtrack_recording?
|
||||
if was_jamtrack_played
|
||||
# we only use the limiter feature if this is a JamTrack recording
|
||||
# by setting this to true, the 1st recorded_track in the database will be the limiter
|
||||
pick_limiter = true
|
||||
|
|
@ -171,27 +225,29 @@ module JamRuby
|
|||
mix_params << { "level" => 1.0, "balance" => 0 }
|
||||
end
|
||||
|
||||
recording.recorded_jam_track_tracks.each do |recorded_jam_track_track|
|
||||
manifest["files"] << { "filename" => recorded_jam_track_track.jam_track_track.sign_url(one_day), "codec" => "vorbis", "offset" => jam_track_offset }
|
||||
# let's look for level info from the client
|
||||
level = 1.0 # default value - means no effect
|
||||
if recorded_jam_track_track.timeline
|
||||
if was_jamtrack_played
|
||||
recording.recorded_jam_track_tracks.each do |recorded_jam_track_track|
|
||||
manifest["files"] << { "filename" => recorded_jam_track_track.jam_track_track.sign_url(one_day, sample_rate=44), "codec" => "vorbis", "offset" => jam_track_offset, "seek" => jam_track_seek }
|
||||
# let's look for level info from the client
|
||||
level = 1.0 # default value - means no effect
|
||||
if recorded_jam_track_track.timeline
|
||||
|
||||
timeline_data = JSON.parse(recorded_jam_track_track.timeline)
|
||||
timeline_data = JSON.parse(recorded_jam_track_track.timeline)
|
||||
|
||||
# always take the 1st entry for now
|
||||
first = timeline_data[0]
|
||||
# always take the 1st entry for now
|
||||
first = timeline_data[0]
|
||||
|
||||
if first["mute"]
|
||||
# mute equates to no noise
|
||||
level = 0.0
|
||||
else
|
||||
# otherwise grab the left channel...
|
||||
level = first["vol_l"]
|
||||
if first["mute"]
|
||||
# mute equates to no noise
|
||||
level = 0.0
|
||||
else
|
||||
# otherwise grab the left channel...
|
||||
level = first["vol_l"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mix_params << { "level" => level, "balance" => 0 }
|
||||
mix_params << { "level" => level, "balance" => 0 }
|
||||
end
|
||||
end
|
||||
|
||||
manifest["timeline"] << { "timestamp" => 0, "mix" => mix_params }
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ module JamRuby
|
|||
return "New message about session."
|
||||
|
||||
when NotificationTypes::JAM_TRACK_SIGN_COMPLETE
|
||||
return "Jam Track is ready for download."
|
||||
return "JamTrack is ready for download."
|
||||
|
||||
# recording notifications
|
||||
when NotificationTypes::MUSICIAN_RECORDING_SAVED
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
module JamRuby
|
||||
class PaymentHistory < ActiveRecord::Base
|
||||
|
||||
self.table_name = 'payment_histories'
|
||||
|
||||
belongs_to :sale
|
||||
belongs_to :recurly_transaction_web_hook
|
||||
|
||||
|
||||
def self.index(user, params = {})
|
||||
|
||||
limit = params[:per_page]
|
||||
limit ||= 20
|
||||
limit = limit.to_i
|
||||
|
||||
query = PaymentHistory.limit(limit)
|
||||
.includes(sale: [:sale_line_items], recurly_transaction_web_hook:[])
|
||||
.where(user_id: user.id)
|
||||
.where("transaction_type = 'sale' OR transaction_type = 'refund' OR transaction_type = 'void'")
|
||||
.order('created_at DESC')
|
||||
|
||||
|
||||
current_page = params[:page].nil? ? 1 : params[:page].to_i
|
||||
next_page = current_page + 1
|
||||
|
||||
# will_paginate gem
|
||||
query = query.paginate(:page => current_page, :per_page => limit)
|
||||
|
||||
if query.length == 0 # no more results
|
||||
{ query: query, next_page: nil}
|
||||
elsif query.length < limit # no more results
|
||||
{ query: query, next_page: nil}
|
||||
else
|
||||
{ query: query, next_page: next_page }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3,7 +3,7 @@ module JamRuby
|
|||
|
||||
@@log = Logging.logger[Recording]
|
||||
|
||||
attr_accessible :owner, :owner_id, :band, :band_id, :recorded_tracks_attributes, :mixes_attributes, :claimed_recordings_attributes, :name, :description, :genre, :is_public, :duration, as: :admin
|
||||
attr_accessible :owner, :owner_id, :band, :band_id, :recorded_tracks_attributes, :mixes_attributes, :claimed_recordings_attributes, :name, :description, :genre, :is_public, :duration, :jam_track_id, as: :admin
|
||||
|
||||
has_many :users, :through => :recorded_tracks, :class_name => "JamRuby::User"
|
||||
has_many :claimed_recordings, :class_name => "JamRuby::ClaimedRecording", :inverse_of => :recording, :foreign_key => 'recording_id', :dependent => :destroy
|
||||
|
|
@ -21,6 +21,7 @@ module JamRuby
|
|||
belongs_to :owner, :class_name => "JamRuby::User", :inverse_of => :owned_recordings, :foreign_key => 'owner_id'
|
||||
belongs_to :band, :class_name => "JamRuby::Band", :inverse_of => :recordings
|
||||
belongs_to :music_session, :class_name => "JamRuby::ActiveMusicSession", :inverse_of => :recordings, foreign_key: :music_session_id
|
||||
belongs_to :non_active_music_session, :class_name => "JamRuby::MusicSession", foreign_key: :music_session_id
|
||||
belongs_to :jam_track, :class_name => "JamRuby::JamTrack", :inverse_of => :recordings, :foreign_key => 'jam_track_id'
|
||||
belongs_to :jam_track_initiator, :class_name => "JamRuby::User", :inverse_of => :initiated_jam_track_recordings, :foreign_key => 'jam_track_initiator_id'
|
||||
|
||||
|
|
@ -50,7 +51,11 @@ module JamRuby
|
|||
end
|
||||
|
||||
def is_jamtrack_recording?
|
||||
!jam_track_id.nil?
|
||||
!jam_track_id.nil? && parsed_timeline['jam_track_isplaying']
|
||||
end
|
||||
|
||||
def parsed_timeline
|
||||
timeline ? JSON.parse(timeline) : {}
|
||||
end
|
||||
|
||||
def high_quality_mix?
|
||||
|
|
@ -182,21 +187,21 @@ module JamRuby
|
|||
|
||||
def recorded_tracks_for_user(user)
|
||||
unless self.users.exists?(user)
|
||||
raise PermissionError, "user was not in this session"
|
||||
raise JamPermissionError, "user was not in this session"
|
||||
end
|
||||
recorded_tracks.where(:user_id => user.id)
|
||||
end
|
||||
|
||||
def recorded_backing_tracks_for_user(user)
|
||||
unless self.users.exists?(user)
|
||||
raise PermissionError, "user was not in this session"
|
||||
raise JamPermissionError, "user was not in this session"
|
||||
end
|
||||
recorded_backing_tracks.where(:user_id => user.id)
|
||||
end
|
||||
|
||||
|
||||
def has_access?(user)
|
||||
users.exists?(user)
|
||||
users.exists?(user) || plays.where("player_id=?", user).count != 0
|
||||
end
|
||||
|
||||
# Start recording a session.
|
||||
|
|
@ -264,7 +269,7 @@ module JamRuby
|
|||
def claim(user, name, description, genre, is_public, upload_to_youtube=false)
|
||||
upload_to_youtube = !!upload_to_youtube # Correct where nil is borking save
|
||||
unless self.users.exists?(user)
|
||||
raise PermissionError, "user was not in this session"
|
||||
raise JamPermissionError, "user was not in this session"
|
||||
end
|
||||
|
||||
claimed_recording = ClaimedRecording.new
|
||||
|
|
@ -710,23 +715,26 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def self.popular_recordings(limit = 100)
|
||||
Recording.select('recordings.id').joins('inner join claimed_recordings ON claimed_recordings.recording_id = recordings.id AND claimed_recordings.is_public = TRUE').where(all_discarded: false).where(is_done: true).where(deleted: false).order('play_count DESC').limit(limit).group('recordings.id')
|
||||
end
|
||||
|
||||
private
|
||||
def self.validate_user_is_band_member(user, band)
|
||||
unless band.users.exists? user
|
||||
raise PermissionError, ValidationMessages::USER_NOT_BAND_MEMBER_VALIDATION_ERROR
|
||||
raise JamPermissionError, ValidationMessages::USER_NOT_BAND_MEMBER_VALIDATION_ERROR
|
||||
end
|
||||
end
|
||||
|
||||
def self.validate_user_is_creator(user, creator)
|
||||
unless user.id == creator.id
|
||||
raise PermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
|
||||
raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
|
||||
end
|
||||
end
|
||||
|
||||
def self.validate_user_is_musician(user)
|
||||
unless user.musician?
|
||||
raise PermissionError, ValidationMessages::USER_NOT_MUSICIAN_VALIDATION_ERROR
|
||||
raise JamPermissionError, ValidationMessages::USER_NOT_MUSICIAN_VALIDATION_ERROR
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
module JamRuby
|
||||
class RecurlyTransactionWebHook < ActiveRecord::Base
|
||||
class RecurlyTransactionWebHook < ActiveRecord::Base
|
||||
|
||||
attr_accessible :admin_description, :jam_track_id, as: :admin
|
||||
|
||||
belongs_to :user, class_name: 'JamRuby::User'
|
||||
belongs_to :sale_line_item, class_name: 'JamRuby::SaleLineItem', foreign_key: 'subscription_id', primary_key: 'recurly_subscription_uuid', inverse_of: :recurly_transactions
|
||||
belongs_to :sale, class_name: 'JamRuby::Sale', foreign_key: 'invoice_id', primary_key: 'recurly_invoice_id', inverse_of: :recurly_transactions
|
||||
|
||||
# when we know what JamTrack this refund is related to, we set this value
|
||||
belongs_to :jam_track, class_name: 'JamRuby::JamTrack'
|
||||
|
||||
validates :recurly_transaction_id, presence: true
|
||||
validates :action, presence: true
|
||||
validates :status, presence: true
|
||||
|
|
@ -17,6 +22,9 @@ module JamRuby
|
|||
REFUND = 'refund'
|
||||
VOID = 'void'
|
||||
|
||||
|
||||
HOOK_TYPES = [SUCCESSFUL_PAYMENT, FAILED_PAYMENT, REFUND, VOID]
|
||||
|
||||
def is_credit_type?
|
||||
transaction_type == REFUND || transaction_type == VOID
|
||||
end
|
||||
|
|
@ -46,6 +54,10 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def admin_url
|
||||
APP_CONFIG.admin_root_url + "/admin/recurly_hooks/" + id
|
||||
end
|
||||
|
||||
# see spec for examples of XML
|
||||
def self.create_from_xml(document)
|
||||
|
||||
|
|
@ -81,6 +93,7 @@ module JamRuby
|
|||
|
||||
# now that we have the transaction saved, we also need to delete the jam_track_right if this is a refund, or voided
|
||||
|
||||
|
||||
if transaction.transaction_type == 'refund' || transaction.transaction_type == 'void'
|
||||
sale = Sale.find_by_recurly_invoice_id(transaction.invoice_id)
|
||||
|
||||
|
|
@ -91,33 +104,44 @@ module JamRuby
|
|||
jam_track_right = jam_track.right_for_user(transaction.user) if jam_track
|
||||
if jam_track_right
|
||||
jam_track_right.destroy
|
||||
AdminMailer.alerts({
|
||||
subject:"NOTICE: #{transaction.user.email} has had JamTrack: #{jam_track.name} revoked",
|
||||
body: "A void event came from Recurly for sale with Recurly invoice ID #{sale.recurly_invoice_id}. We deleted their right to the track in our own database as a result."
|
||||
}).deliver
|
||||
|
||||
# associate which JamTrack we assume this is related to in this one success case
|
||||
transaction.jam_track = jam_track
|
||||
transaction.save!
|
||||
|
||||
AdminMailer.recurly_alerts(transaction.user, {
|
||||
subject: "NOTICE: #{transaction.user.email} has had JamTrack: #{jam_track.name} revoked",
|
||||
body: "A #{transaction.transaction_type} event came from Recurly for sale with Recurly invoice ID #{sale.recurly_invoice_id}. We deleted their right to the track in our own database as a result."
|
||||
}).deliver
|
||||
else
|
||||
AdminMailer.alerts({
|
||||
subject:"NOTICE: #{transaction.user.email} got a refund, but unable to find JamTrackRight to delete",
|
||||
body: "This should just mean the user already has no rights to the JamTrackRight when the refund came in. Not a big deal, but sort of weird..."
|
||||
}).deliver
|
||||
AdminMailer.recurly_alerts(transaction.user, {
|
||||
subject: "NOTICE: #{transaction.user.email} got a refund, but unable to find JamTrackRight to delete",
|
||||
body: "This should just mean the user already has no rights to the JamTrackRight when the refund came in. Not a big deal, but sort of weird..."
|
||||
}).deliver
|
||||
end
|
||||
|
||||
else
|
||||
AdminMailer.alerts({
|
||||
subject:"ACTION REQUIRED: #{transaction.user.email} got a refund it was not for total value of a JamTrack sale",
|
||||
body: "We received a refund notice for an amount that was not the same as the original sale. So, no action was taken in the database. sale total: #{sale.recurly_total_in_cents}, refund amount: #{transaction.amount_in_cents}"
|
||||
}).deliver
|
||||
AdminMailer.recurly_alerts(transaction.user, {
|
||||
subject: "ACTION REQUIRED: #{transaction.user.email} got a refund it was not for total value of a JamTrack sale",
|
||||
body: "We received a #{transaction.transaction_type} notice for an amount that was not the same as the original sale. So, no action was taken in the database. sale total: #{sale.recurly_total_in_cents}, refund amount: #{transaction.amount_in_cents}"
|
||||
}).deliver
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
AdminMailer.alerts({
|
||||
subject: "ACTION REQUIRED: #{transaction.user.email} has refund on invoice with multiple JamTracks",
|
||||
body: "You will have to manually revoke any JamTrackRights in our database for the appropriate JamTracks"
|
||||
}).deliver
|
||||
AdminMailer.recurly_alerts(transaction.user, {
|
||||
subject: "ACTION REQUIRED: #{transaction.user.email} has refund on invoice with multiple JamTracks",
|
||||
body: "You will have to manually revoke any JamTrackRights in our database for the appropriate JamTracks"
|
||||
}).deliver
|
||||
end
|
||||
else
|
||||
AdminMailer.recurly_alerts(transaction.user, {
|
||||
subject: "ACTION REQUIRED: #{transaction.user.email} has refund with no correlator to sales",
|
||||
body: "You will have to manually revoke any JamTrackRights in our database for the appropriate JamTracks"
|
||||
}).deliver
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
transaction
|
||||
end
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ module JamRuby
|
|||
invitation = Invitation.where("music_session_id = ? AND receiver_id = ?", music_session.id, user.id)
|
||||
|
||||
if invitation.first.nil? && !music_session.open_rsvps && music_session.creator.id != user.id
|
||||
raise PermissionError, "Only a session invitee can create an RSVP for this session."
|
||||
raise JamPermissionError, "Only a session invitee can create an RSVP for this session."
|
||||
end
|
||||
|
||||
RsvpRequest.transaction do
|
||||
|
|
@ -154,7 +154,7 @@ module JamRuby
|
|||
|
||||
# authorize the user attempting to respond to the RSVP request
|
||||
if music_session.creator.id != user.id
|
||||
raise PermissionError, "Only the session organizer can accept or decline an RSVP request."
|
||||
raise JamPermissionError, "Only the session organizer can accept or decline an RSVP request."
|
||||
end
|
||||
|
||||
rsvp_request = RsvpRequest.find_by_id(rsvp_request_id)
|
||||
|
|
@ -249,7 +249,7 @@ module JamRuby
|
|||
rsvp_request = RsvpRequest.find(params[:id])
|
||||
|
||||
if music_session.creator.id != user.id && rsvp_request.user_id != user.id
|
||||
raise PermissionError, "Only the session organizer or RSVP creator can cancel the RSVP."
|
||||
raise JamPermissionError, "Only the session organizer or RSVP creator can cancel the RSVP."
|
||||
end
|
||||
|
||||
RsvpRequest.transaction do
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module JamRuby
|
|||
|
||||
attr_accessible :quantity, :cart_type, :product_info
|
||||
|
||||
validates_uniqueness_of :cart_id, scope: :cart_type
|
||||
validates_uniqueness_of :cart_id, scope: [:cart_type, :user_id, :anonymous_user_id]
|
||||
|
||||
belongs_to :user, :inverse_of => :shopping_carts, :class_name => "JamRuby::User", :foreign_key => "user_id"
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ module JamRuby
|
|||
|
||||
def product_info
|
||||
product = self.cart_product
|
||||
{name: product.name, price: product.price, product_id: cart_id, plan_code: product.plan_code, real_price: real_price(product), total_price: total_price(product), quantity: quantity, marked_for_redeem: marked_for_redeem} unless product.nil?
|
||||
{name: product.name, price: product.price, product_id: cart_id, plan_code: product.plan_code, real_price: real_price(product), total_price: total_price(product), quantity: quantity, marked_for_redeem: marked_for_redeem, free: free?, sales_region: product.sales_region} unless product.nil?
|
||||
end
|
||||
|
||||
# multiply quantity by price
|
||||
|
|
@ -111,6 +111,15 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def self.move_to_user(user, anonymous_user, shopping_carts)
|
||||
shopping_carts.each do |shopping_cart|
|
||||
mark_redeem = ShoppingCart.user_has_redeemable_jam_track?(user)
|
||||
cart = ShoppingCart.create(user, shopping_cart.cart_product, shopping_cart.quantity, mark_redeem)
|
||||
end
|
||||
|
||||
anonymous_user.destroy_all_shopping_carts
|
||||
end
|
||||
|
||||
def self.is_product_purchase?(adjustment)
|
||||
(adjustment[:accounting_code].include?(PURCHASE_FREE) || adjustment[:accounting_code].include?(PURCHASE_NORMAL)) && !adjustment[:accounting_code].include?(PURCHASE_FREE_CREDIT)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
module JamRuby
|
||||
|
||||
# some times someone comes to signup as a new user, but there is context to preserve.
|
||||
# the AnyUser cookie is one way that we can track the user from pre-signup to post-signup
|
||||
# anyway, once the signup is done, we check to see if there is a SignupHint, and if so,
|
||||
# we use it to figure out what to do with the user after they signup
|
||||
class SignupHint < ActiveRecord::Base
|
||||
|
||||
|
||||
belongs_to :user, class_name: 'JamRuby::User'
|
||||
|
||||
validates :redirect_location, length: {maximum: 1000}
|
||||
validates :want_jamblaster, inclusion: {in: [nil, true, false]}
|
||||
|
||||
def self.refresh_by_anoymous_user(anonymous_user, options = {})
|
||||
|
||||
hint = SignupHint.find_by_anonymous_user_id(anonymous_user.id)
|
||||
|
||||
unless hint
|
||||
hint = SignupHint.new
|
||||
end
|
||||
|
||||
hint.anonymous_user_id = anonymous_user.id
|
||||
hint.redirect_location = options[:redirect_location] if options.has_key?(:redirect_location)
|
||||
hint.want_jamblaster = options[:want_jamblaster] if options.has_key?(:want_jamblaster)
|
||||
hint.expires_at = 15.minutes.from_now
|
||||
hint.save
|
||||
hint
|
||||
end
|
||||
|
||||
def self.delete_old
|
||||
SignupHint.where("created_at < :week", {:week => 1.week.ago}).delete_all
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -113,6 +113,7 @@ module JamRuby
|
|||
result = {}
|
||||
|
||||
backing_tracks = [] unless backing_tracks
|
||||
tracks = [] unless tracks
|
||||
|
||||
Track.transaction do
|
||||
connection = Connection.find_by_client_id!(clientId)
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ module JamRuby
|
|||
scope :email_opt_in, where(:subscribe_email => true)
|
||||
|
||||
def user_progression_fields
|
||||
@user_progression_fields ||= Set.new ["first_downloaded_client_at", "first_ran_client_at", "first_music_session_at", "first_real_music_session_at", "first_good_music_session_at", "first_certified_gear_at", "first_invited_at", "first_friended_at", "first_recording_at", "first_social_promoted_at" ]
|
||||
@user_progression_fields ||= Set.new ["first_downloaded_client_at", "first_ran_client_at", "first_music_session_at", "first_real_music_session_at", "first_good_music_session_at", "first_certified_gear_at", "first_invited_at", "first_friended_at", "first_recording_at", "first_social_promoted_at", "first_played_jamtrack_at" ]
|
||||
end
|
||||
|
||||
def update_progression_field(field_name, time = DateTime.now)
|
||||
|
|
@ -812,7 +812,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
if user.id != updater_id
|
||||
raise PermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
|
||||
raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
|
||||
end
|
||||
|
||||
user.easy_save(first_name, last_name, email, password, password_confirmation, musician, gender,
|
||||
|
|
@ -1046,7 +1046,16 @@ module JamRuby
|
|||
user.photo_url = photo_url
|
||||
|
||||
# copy over the shopping cart to the new user, if a shopping cart is provided
|
||||
user.shopping_carts = any_user.shopping_carts if any_user
|
||||
if any_user
|
||||
user.shopping_carts = any_user.shopping_carts
|
||||
if user.shopping_carts
|
||||
user.shopping_carts.each do |shopping_cart|
|
||||
shopping_cart.anonymous_user_id = nil # nil out the anonymous user ID; required for uniqeness constraint on ShoppingCart
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
unless fb_signup.nil?
|
||||
user.update_fb_authorization(fb_signup)
|
||||
|
|
@ -1596,6 +1605,15 @@ module JamRuby
|
|||
verifier.generate(user.id)
|
||||
end
|
||||
|
||||
# URL to jam-admin
|
||||
def admin_url
|
||||
APP_CONFIG.admin_root_url + "/admin/users/" + id
|
||||
end
|
||||
|
||||
def jam_track_rights_admin_url
|
||||
APP_CONFIG.admin_root_url + "/admin/jam_track_rights?q[user_id_equals]=#{id}&commit=Filter&order=created_at DESC"
|
||||
end
|
||||
|
||||
private
|
||||
def create_remember_token
|
||||
self.remember_token = SecureRandom.urlsafe_base64
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class MQRouter
|
|||
end
|
||||
|
||||
if !music_session.access? user
|
||||
raise PermissionError, 'not allowed to join the specified session'
|
||||
raise JamPermissionError, 'not allowed to join the specified session'
|
||||
end
|
||||
|
||||
return music_session
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ module JamRuby
|
|||
@@log.debug("manifest")
|
||||
@@log.debug("--------")
|
||||
@@log.debug(JSON.pretty_generate(@manifest))
|
||||
@@log.debug("--------")
|
||||
|
||||
@manifest[:mix_id] = mix_id # slip in the mix_id so that the job can add it to the ogg comments
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,9 @@ module JamRuby
|
|||
el: 'data',
|
||||
ev: data.to_s
|
||||
}
|
||||
|
||||
RestClient.post(APP_CONFIG.ga_endpoint, params: params, timeout: 8, open_timeout: 8)
|
||||
|
||||
@@log.info("done (#{category}, #{action})")
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -34,8 +34,20 @@ module JamRuby
|
|||
return
|
||||
end
|
||||
|
||||
# compute the step count
|
||||
total_steps = @jam_track_right.jam_track.stem_tracks.count + 1 # the '1' represents the jkz.py invocation
|
||||
|
||||
# track that it's started ( and avoid db validations )
|
||||
JamTrackRight.where(:id => @jam_track_right.id).update_all(:signing_started_at => Time.now, :should_retry => false)
|
||||
signing_started_at = Time.now
|
||||
last_step_at = Time.now
|
||||
JamTrackRight.where(:id => @jam_track_right.id).update_all(:signing_started_at => signing_started_at, :should_retry => false, packaging_steps: total_steps, current_packaging_step: 0, last_step_at: last_step_at)
|
||||
# because we are skiping after_save, we have to keep the model current for the notification. A bit ugly...
|
||||
@jam_track_right.current_packaging_step = 0
|
||||
@jam_track_right.packaging_steps = total_steps
|
||||
@jam_track_right.signing_started_at = signing_started_at
|
||||
@jam_track_right.should_retry = false
|
||||
@jam_track_right.last_step_at = Time.now
|
||||
SubscriptionMessage.jam_track_signing_job_change(@jam_track_right)
|
||||
JamRuby::JamTracksManager.save_jam_track_right_jkz(@jam_track_right, self.bitrate)
|
||||
|
||||
# If bitrate is 48 (the default), use that URL. Otherwise, use 44kHz:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ module JamRuby
|
|||
@@log.debug("waking up")
|
||||
|
||||
FacebookSignup.delete_old
|
||||
SignupHint.delete_old
|
||||
|
||||
@@log.debug("done")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ describe JamTrackImporter do
|
|||
let(:options) {{ skip_audio_upload:true }}
|
||||
|
||||
it "bare minimum specification" do
|
||||
importer.synchronize_metadata(jam_track, minimum_meta, metalocation, 'Artist 1', 'Song 1')
|
||||
importer.synchronize_metadata(jam_track, minimum_meta, metalocation, 'Artist 1', 'Song 1', options)
|
||||
|
||||
jam_track.plan_code.should eq('jamtrack-artist1-song1')
|
||||
jam_track.name.should eq("Song 1")
|
||||
|
|
@ -57,7 +57,7 @@ describe JamTrackImporter do
|
|||
jam_track.original_artist.should eq('Artist 1')
|
||||
jam_track.songwriter.should be_nil
|
||||
jam_track.publisher.should be_nil
|
||||
jam_track.sales_region.should eq('United States')
|
||||
jam_track.sales_region.should eq('Worldwide')
|
||||
jam_track.price.should eq(1.99)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -134,12 +134,12 @@ describe JamTrackRight do
|
|||
end
|
||||
|
||||
it "signing" do
|
||||
right = FactoryGirl.create(:jam_track_right, signing_started_at: Time.now)
|
||||
right = FactoryGirl.create(:jam_track_right, signing_started_at: Time.now, packaging_steps: 3, current_packaging_step:0, last_step_at:Time.now)
|
||||
right.signing_state.should eq('SIGNING')
|
||||
end
|
||||
|
||||
it "signing timeout" do
|
||||
right = FactoryGirl.create(:jam_track_right, signing_started_at: Time.now - (APP_CONFIG.signing_job_run_max_time + 1))
|
||||
right = FactoryGirl.create(:jam_track_right, signing_started_at: Time.now - 100, packaging_steps: 3, current_packaging_step:0, last_step_at:Time.now)
|
||||
right.signing_state.should eq('SIGNING_TIMEOUT')
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,41 @@ describe JamTrack do
|
|||
end
|
||||
end
|
||||
|
||||
describe "artist_index" do
|
||||
before :each do
|
||||
JamTrack.delete_all
|
||||
end
|
||||
|
||||
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)
|
||||
|
|
@ -45,8 +80,8 @@ describe JamTrack do
|
|||
end
|
||||
|
||||
it "sorts by name" do
|
||||
jam_track1 = FactoryGirl.create(:jam_track_with_tracks, name: 'a')
|
||||
jam_track2 = FactoryGirl.create(:jam_track_with_tracks, name: 'b')
|
||||
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.index({}, user)
|
||||
query.size.should == 2
|
||||
|
|
@ -141,5 +176,4 @@ describe JamTrack do
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe PaymentHistory do
|
||||
|
||||
let(:user) {FactoryGirl.create(:user)}
|
||||
let(:user2) {FactoryGirl.create(:user)}
|
||||
let(:jam_track) {FactoryGirl.create(:jam_track)}
|
||||
|
||||
before(:each) do
|
||||
|
||||
end
|
||||
|
||||
describe "index" do
|
||||
it "empty" do
|
||||
result = PaymentHistory.index(user)
|
||||
result[:query].length.should eq(0)
|
||||
result[:next].should eq(nil)
|
||||
end
|
||||
|
||||
it "one" do
|
||||
sale = Sale.create_jam_track_sale(user)
|
||||
shopping_cart = ShoppingCart.create(user, jam_track)
|
||||
sale_line_item = SaleLineItem.create_from_shopping_cart(sale, shopping_cart, nil, 'some_adjustment_uuid', nil)
|
||||
|
||||
result = PaymentHistory.index(user)
|
||||
result[:query].length.should eq(1)
|
||||
result[:next].should eq(nil)
|
||||
end
|
||||
|
||||
it "user filtered correctly" do
|
||||
sale = Sale.create_jam_track_sale(user)
|
||||
shopping_cart = ShoppingCart.create(user, jam_track)
|
||||
sale_line_item = SaleLineItem.create_from_shopping_cart(sale, shopping_cart, nil, 'some_adjustment_uuid', nil)
|
||||
|
||||
result = PaymentHistory.index(user)
|
||||
result[:query].length.should eq(1)
|
||||
result[:next].should eq(nil)
|
||||
|
||||
sale2 = Sale.create_jam_track_sale(user2)
|
||||
shopping_cart = ShoppingCart.create(user2, jam_track)
|
||||
sale_line_item2 = SaleLineItem.create_from_shopping_cart(sale2, shopping_cart, nil, 'some_adjustment_uuid', nil)
|
||||
|
||||
result = PaymentHistory.index(user)
|
||||
result[:query].length.should eq(1)
|
||||
result[:next].should eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -15,6 +15,29 @@ describe Recording do
|
|||
@track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
|
||||
end
|
||||
|
||||
describe "popular_recordings" do
|
||||
it "empty" do
|
||||
Recording.popular_recordings.length.should eq(0)
|
||||
end
|
||||
|
||||
it "one public recording" do
|
||||
claim = FactoryGirl.create(:claimed_recording)
|
||||
|
||||
claim.recording.is_done = true
|
||||
claim.recording.save!
|
||||
recordings = Recording.popular_recordings
|
||||
recordings.length.should eq(1)
|
||||
recordings[0].id.should eq(claim.recording.id)
|
||||
end
|
||||
|
||||
it "one private recording" do
|
||||
claim = FactoryGirl.create(:claimed_recording, is_public: true)
|
||||
|
||||
recordings = Recording.popular_recordings
|
||||
recordings.length.should eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
describe "cleanup_excessive_storage" do
|
||||
|
||||
sample_audio='sample.file'
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ describe RsvpRequest do
|
|||
it "should not allow non-invitee to RSVP to session with closed RSVPs" do
|
||||
@music_session.open_rsvps = false
|
||||
@music_session.save!
|
||||
expect {RsvpRequest.create({:session_id => @music_session.id, :rsvp_slots => [@slot1.id, @slot2.id]}, @non_session_invitee)}.to raise_error(JamRuby::PermissionError)
|
||||
expect {RsvpRequest.create({:session_id => @music_session.id, :rsvp_slots => [@slot1.id, @slot2.id]}, @non_session_invitee)}.to raise_error(JamRuby::JamPermissionError)
|
||||
end
|
||||
|
||||
it "should allow RSVP creation with autoapprove option for open RSVP sessions" do
|
||||
|
|
@ -216,7 +216,7 @@ describe RsvpRequest do
|
|||
# attempt to approve with non-organizer
|
||||
rs1 = RsvpRequestRsvpSlot.find_by_rsvp_slot_id(@slot1.id)
|
||||
rs2 = RsvpRequestRsvpSlot.find_by_rsvp_slot_id(@slot2.id)
|
||||
expect {RsvpRequest.update({:id => rsvp.id, :session_id => @music_session.id, :rsvp_responses => [{:request_slot_id => rs1.id, :accept => true}, {:request_slot_id => rs2.id, :accept => true}]}, @session_invitee)}.to raise_error(PermissionError)
|
||||
expect {RsvpRequest.update({:id => rsvp.id, :session_id => @music_session.id, :rsvp_responses => [{:request_slot_id => rs1.id, :accept => true}, {:request_slot_id => rs2.id, :accept => true}]}, @session_invitee)}.to raise_error(JamPermissionError)
|
||||
|
||||
# approve with organizer
|
||||
rs1 = RsvpRequestRsvpSlot.find_by_rsvp_slot_id(@slot1.id)
|
||||
|
|
@ -402,7 +402,7 @@ describe RsvpRequest do
|
|||
comment.comment.should == "Let's Jam!"
|
||||
|
||||
# cancel
|
||||
expect {RsvpRequest.cancel({:id => rsvp.id, :session_id => @music_session.id, :cancelled => "all", :message => "I'm gonna cancel all your RSVPs"}, user)}.to raise_error(PermissionError)
|
||||
expect {RsvpRequest.cancel({:id => rsvp.id, :session_id => @music_session.id, :cancelled => "all", :message => "I'm gonna cancel all your RSVPs"}, user)}.to raise_error(JamPermissionError)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe SignupHint do
|
||||
|
||||
let(:user) {AnonymousUser.new(SecureRandom.uuid)}
|
||||
|
||||
describe "refresh_by_anoymous_user" do
|
||||
it "creates" do
|
||||
hint = SignupHint.refresh_by_anoymous_user(user, {redirect_location: 'abc'})
|
||||
hint.errors.any?.should be_false
|
||||
hint.redirect_location.should eq('abc')
|
||||
hint.want_jamblaster.should be_false
|
||||
end
|
||||
|
||||
it "updated" do
|
||||
SignupHint.refresh_by_anoymous_user(user, {redirect_location: 'abc'})
|
||||
|
||||
hint = SignupHint.refresh_by_anoymous_user(user, {redirect_location: nil, want_jamblaster: true})
|
||||
hint.errors.any?.should be_false
|
||||
hint.redirect_location.should be_nil
|
||||
hint.want_jamblaster.should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3,10 +3,18 @@ JAMKAZAM_TESTING_BUCKET = 'jamkazam-testing' # cuz i'm not comfortable using aws
|
|||
def app_config
|
||||
klass = Class.new do
|
||||
|
||||
def admin_root_url
|
||||
'http://localhost:3333'
|
||||
end
|
||||
|
||||
def email_alerts_alias
|
||||
'alerts@jamkazam.com'
|
||||
end
|
||||
|
||||
def email_recurly_notice
|
||||
'recurly-alerts@jamkazam.com'
|
||||
end
|
||||
|
||||
def email_generic_from
|
||||
'nobody@jamkazam.com'
|
||||
end
|
||||
|
|
@ -166,8 +174,8 @@ def app_config
|
|||
false
|
||||
end
|
||||
|
||||
def signing_job_run_max_time
|
||||
60 # 1 minute
|
||||
def signing_step_max_time
|
||||
40 # 40 seconds
|
||||
end
|
||||
|
||||
def signing_job_queue_max_time
|
||||
|
|
@ -182,6 +190,9 @@ def app_config
|
|||
'foobar'
|
||||
end
|
||||
|
||||
def unsubscribe_token
|
||||
'blah'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ doc/
|
|||
.idea
|
||||
*.iml
|
||||
|
||||
jt_metadata.json
|
||||
|
||||
artifacts
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ gem 'recurly'
|
|||
gem 'guard', '2.7.3'
|
||||
gem 'influxdb', '0.1.8'
|
||||
gem 'influxdb-rails', '0.1.10'
|
||||
gem 'sitemap_generator'
|
||||
|
||||
group :development, :test do
|
||||
gem 'rspec-rails', '2.14.2'
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#require 'resque/scheduler/tasks'
|
||||
require 'resque/tasks'
|
||||
require 'resque/scheduler/tasks'
|
||||
require 'sitemap_generator/tasks'
|
||||
require File.expand_path('../config/application', __FILE__)
|
||||
SampleApp::Application.load_tasks
|
||||
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 365 B |
|
After Width: | Height: | Size: 22 KiB |
|
|
@ -8,8 +8,10 @@
|
|||
var rest = context.JK.Rest();
|
||||
var userId;
|
||||
var user = {};
|
||||
|
||||
|
||||
function beforeShow(data) {
|
||||
console.log("beforeShow", data)
|
||||
userId = data.id;
|
||||
}
|
||||
|
||||
|
|
@ -43,6 +45,19 @@
|
|||
var invalidProfiles = prettyPrintAudioProfiles(context.JK.getBadConfigMap());
|
||||
var sessionSummary = summarizeSession(userDetail);
|
||||
|
||||
if(gon.global.video_available && gon.global.video_available!="none" ) {
|
||||
var webcamName;
|
||||
var webcam = context.jamClient.FTUECurrentSelectedVideoDevice()
|
||||
if (webcam == null || typeof(webcam) == "undefined" || Object.keys(webcam).length == 0) {
|
||||
webcamName = "None Configured"
|
||||
} else {
|
||||
webcamName = _.values(webcam)[0]
|
||||
}
|
||||
}
|
||||
else {
|
||||
webcamName = 'video unavailable'
|
||||
}
|
||||
|
||||
var $template = $(context._.template($('#template-account-main').html(), {
|
||||
email: userDetail.email,
|
||||
name: userDetail.name,
|
||||
|
|
@ -56,6 +71,7 @@
|
|||
invalidProfiles : invalidProfiles,
|
||||
isNativeClient: gon.isNativeClient,
|
||||
musician: context.JK.currentUserMusician,
|
||||
webcamName: webcamName,
|
||||
sales_count: userDetail.sales_count
|
||||
} , { variable: 'data' }));
|
||||
|
||||
|
|
@ -65,8 +81,9 @@
|
|||
$('#account-scheduled-sessions-link').show();
|
||||
} else {
|
||||
$('#account-scheduled-sessions-link').hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}// function
|
||||
|
||||
function prettyPrintAudioProfiles(profileMap) {
|
||||
var profiles = "";
|
||||
|
|
@ -110,6 +127,7 @@
|
|||
$('#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('click', '#account-edit-video-link', function(evt) { evt.stopPropagation(); navToEditVideo(); return false; } );
|
||||
$('#account-content-scroller').on('avatar_changed', '#profile-avatar', function(evt, newAvatarUrl) { evt.stopPropagation(); updateAvatar(newAvatarUrl); return false; })
|
||||
|
||||
// License dialog:
|
||||
|
|
@ -158,6 +176,11 @@
|
|||
window.location = "/client#/account/audio"
|
||||
}
|
||||
|
||||
function navToEditVideo() {
|
||||
resetForm()
|
||||
window.location = "/client#/account/video"
|
||||
}
|
||||
|
||||
function navToPaymentHistory() {
|
||||
window.location = '/client#/account/paymentHistory'
|
||||
}
|
||||
|
|
@ -178,6 +201,7 @@
|
|||
}
|
||||
|
||||
function initialize() {
|
||||
|
||||
var screenBindings = {
|
||||
'beforeShow': beforeShow,
|
||||
'afterShow': afterShow
|
||||
|
|
|
|||
|
|
@ -163,6 +163,13 @@
|
|||
|
||||
function handleConfigureAudioProfile(audioProfileId) {
|
||||
|
||||
if(!gearUtils.canBeConfigured(audioProfileId)) {
|
||||
|
||||
context.JK.Banner.showAlert("The System Default (Playback Only) profile can not currently be configured.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(audioProfileId == gearUtils.GearUtil)
|
||||
if(audioProfileId != context.jamClient.FTUEGetMusicProfileName()) {
|
||||
logger.debug("activating " + audioProfileId);
|
||||
var result = context.jamClient.FTUELoadAudioConfiguration(audioProfileId);
|
||||
|
|
|
|||
|
|
@ -51,41 +51,33 @@ context.JK.AccountPaymentHistoryScreen = class AccountPaymentHistoryScreen
|
|||
|
||||
renderPayments:(response) =>
|
||||
if response.entries? && response.entries.length > 0
|
||||
for sale in response.entries
|
||||
amt = sale.recurly_total_in_cents
|
||||
amt = 0 if !amt?
|
||||
|
||||
original_total = sale.state.original_total
|
||||
refund_total = sale.state.refund_total
|
||||
|
||||
refund_state = null
|
||||
if original_total != 0 # the enclosed logic does not work for free purchases
|
||||
if refund_total == original_total
|
||||
refund_state = 'refunded'
|
||||
else if refund_total != 0 and refund_total < original_total
|
||||
refund_state = 'partial refund'
|
||||
|
||||
|
||||
displayAmount = (amt/100).toFixed(2)
|
||||
status = 'paid'
|
||||
|
||||
if sale.state.voided
|
||||
status = 'voided'
|
||||
displayAmount = (0).toFixed(2)
|
||||
else if refund_state?
|
||||
status = refund_state
|
||||
displayAmount = (amt/100).toFixed(2) + " (refunded: #{(refund_total/100).toFixed(2)})"
|
||||
|
||||
description = []
|
||||
for line_item in sale.line_items
|
||||
description.push(line_item.product_info?.name)
|
||||
for paymentHistory in response.entries
|
||||
if paymentHistory.sale?
|
||||
# this is a sale
|
||||
sale = paymentHistory.sale
|
||||
amt = sale.recurly_total_in_cents
|
||||
status = 'paid'
|
||||
displayAmount = ' $' + (amt/100).toFixed(2)
|
||||
date = context.JK.formatDate(sale.created_at, true)
|
||||
items = []
|
||||
for line_item in sale.line_items
|
||||
items.push(line_item.product_info?.name)
|
||||
description = items.join(', ')
|
||||
else
|
||||
# this is a recurly webhook
|
||||
transaction = paymentHistory.transaction
|
||||
amt = transaction.amount_in_cents
|
||||
status = transaction.transaction_type
|
||||
displayAmount = '($' + (amt/100).toFixed(2) + ')'
|
||||
date = context.JK.formatDate(transaction.transaction_at, true)
|
||||
description = transaction.admin_description
|
||||
|
||||
payment = {
|
||||
date: context.JK.formatDate(sale.created_at, true)
|
||||
date: date
|
||||
amount: displayAmount
|
||||
status: status
|
||||
payment_method: 'Credit Card',
|
||||
description: description.join(', ')
|
||||
payment_method: 'Credit Card'
|
||||
description: description
|
||||
}
|
||||
|
||||
tr = $(context._.template(@rowTemplate, payment, { variable: 'data' }));
|
||||
|
|
@ -98,10 +90,9 @@ context.JK.AccountPaymentHistoryScreen = class AccountPaymentHistoryScreen
|
|||
|
||||
# Turn in to HTML rows and append:
|
||||
#@tbody.html("")
|
||||
console.log("response.next", response)
|
||||
@next = response.next_page
|
||||
@next = response.next
|
||||
@renderPayments(response)
|
||||
if response.next_page == null
|
||||
if response.next == null
|
||||
# if we less results than asked for, end searching
|
||||
@scroller.infinitescroll 'pause'
|
||||
@logger.debug("end of history")
|
||||
|
|
@ -147,7 +138,7 @@ context.JK.AccountPaymentHistoryScreen = class AccountPaymentHistoryScreen
|
|||
msg: $('<div class="infinite-scroll-loader">Loading ...</div>')
|
||||
img: '/assets/shared/spinner.gif'
|
||||
path: (page) =>
|
||||
'/api/sales?' + $.param(that.buildQuery())
|
||||
'/api/payment_histories?' + $.param(that.buildQuery())
|
||||
|
||||
}, (json, opts) =>
|
||||
this.salesHistoryDone(json)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
(function (context, $) {
|
||||
|
||||
"use strict";
|
||||
|
||||
context.JK = context.JK || {};
|
||||
context.JK.AccountVideoProfile = function (app) {
|
||||
var $webcamViewer = new context.JK.WebcamViewer()
|
||||
function initialize() {
|
||||
var screenBindings = {
|
||||
'beforeShow': beforeShow,
|
||||
'beforeHide':beforeHide
|
||||
};
|
||||
app.bindScreen('account/video', screenBindings);
|
||||
|
||||
$webcamViewer.init($(".webcam-container"))
|
||||
}
|
||||
|
||||
function beforeShow() {
|
||||
$webcamViewer.beforeShow()
|
||||
}
|
||||
|
||||
function beforeHide() {
|
||||
$webcamViewer.setVideoOff()
|
||||
}
|
||||
|
||||
this.beforeShow = beforeShow
|
||||
this.beforeHide = beforeHide
|
||||
this.initialize = initialize
|
||||
return this;
|
||||
};
|
||||
|
||||
})(window, jQuery);
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
//= require globals
|
||||
//= require AAB_message_factory
|
||||
//= require jam_rest
|
||||
//= require ga
|
||||
//= require utils
|
||||
//= require subscription_utils
|
||||
//= require custom_controls
|
||||
|
|
|
|||
|
|
@ -30,15 +30,16 @@
|
|||
var $orderPrompt = null;
|
||||
var $emptyCartPrompt = null;
|
||||
var $noAccountInfoPrompt = null;
|
||||
var $downloadApplicationLink = null;
|
||||
|
||||
|
||||
function beforeShow() {
|
||||
beforeShowOrder();
|
||||
|
||||
}
|
||||
|
||||
|
||||
function afterShow(data) {
|
||||
|
||||
beforeShowOrder();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -56,11 +57,13 @@
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
@ -225,6 +228,7 @@
|
|||
$orderPanel.addClass("hidden")
|
||||
$thanksPanel.removeClass("hidden")
|
||||
jamTrackUtils.checkShoppingCart()
|
||||
app.refreshUser()
|
||||
handleJamTracksPurchased(purchaseResponse.jam_tracks)
|
||||
}
|
||||
|
||||
|
|
@ -237,6 +241,11 @@
|
|||
}
|
||||
else {
|
||||
$jamTrackInBrowser.removeClass('hidden');
|
||||
app.user().done(function(user) {
|
||||
if(!user.first_downloaded_client_at) {
|
||||
$downloadApplicationLink.removeClass('hidden')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -297,7 +306,7 @@
|
|||
}
|
||||
else {
|
||||
logger.debug("done iterating over purchased JamTracks")
|
||||
$purchasedJamTrackHeader.text('All purchased JamTracks have been downloaded successfully! You can now play them in a session.')
|
||||
$purchasedJamTrackHeader.attr('status', 'done')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -349,6 +358,7 @@
|
|||
$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";
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
context.JK.CheckoutSignInScreen = function(app) {
|
||||
|
||||
var logger = context.JK.logger;
|
||||
var rest = context.JK.Rest();
|
||||
|
||||
var $screen = null;
|
||||
var $navigation = null;
|
||||
|
|
@ -17,6 +18,7 @@
|
|||
var $inputElements = null;
|
||||
var $contentHolder = null;
|
||||
var $btnNext = null;
|
||||
var $btnFacebook = null;
|
||||
|
||||
function beforeShow(data) {
|
||||
renderNavigation();
|
||||
|
|
@ -44,6 +46,7 @@
|
|||
$signinForm.on('submit', login);
|
||||
$signinBtn.on('click', login);
|
||||
$btnNext.on('click', moveNext);
|
||||
$btnFacebook.on('click', facebookSignup);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
|
|
@ -55,6 +58,31 @@
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
function facebookSignup() {
|
||||
|
||||
var $btn = $(this);
|
||||
|
||||
if($btn.is('.disabled')) {
|
||||
logger.debug("ignoring fast attempt at facebook signup")
|
||||
return false;
|
||||
}
|
||||
|
||||
$btn.addClass('disabled')
|
||||
|
||||
rest.createSignupHint({redirect_location: '/client#/checkoutPayment'})
|
||||
.done(function() {
|
||||
// send the user on to facebook signin
|
||||
window.location = $btn.attr('href');
|
||||
})
|
||||
.fail(function() {
|
||||
app.notify({text:"Facebook Signup is not working properly"});
|
||||
})
|
||||
.always(function() {
|
||||
$btn.removeClass('disabled')
|
||||
})
|
||||
return false;
|
||||
}
|
||||
function login() {
|
||||
if($signinBtn.is('.disabled')) {
|
||||
return false;
|
||||
|
|
@ -117,6 +145,7 @@
|
|||
$inputElements = $signinForm.find('.input-elements');
|
||||
$contentHolder = $screen.find('.content-holder');
|
||||
$btnNext = $screen.find('.btnNext');
|
||||
$btnFacebook = $screen.find('.signin-facebook')
|
||||
|
||||
if($screen.length == 0) throw "$screen must be specified";
|
||||
if($navigation.length == 0) throw "$navigation must be specified";
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class CheckoutUtils
|
|||
|
||||
setPreserveBillingInfo:() =>
|
||||
date = new Date();
|
||||
minutes = 1;
|
||||
minutes = 10;
|
||||
date.setTime(date.getTime() + (minutes * 60 * 1000))
|
||||
$.removeCookie(@cookie_name, { path: '/' })
|
||||
$.cookie(@cookie_name, "jam", { expires: date, path: '/' })
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
//= require globals
|
||||
//= require jamkazam
|
||||
//= require utils
|
||||
//= require ga
|
||||
//= require jam_rest
|
||||
//= require ga
|
||||
//= require corp/init
|
||||
//= require_directory ../corp
|
||||
|
|
@ -135,7 +135,11 @@
|
|||
if(!button.name) throw "button.name must be specified";
|
||||
if(!button.click) throw "button.click must be specified";
|
||||
|
||||
var buttonStyle = options.buttons.length == i + 1 ? 'button-orange' : 'button-grey';
|
||||
var buttonStyle = button.buttonStyle;
|
||||
if(!buttonStyle) {
|
||||
buttonStyle = options.buttons.length == i + 1 ? 'button-orange' : 'button-grey';
|
||||
}
|
||||
|
||||
|
||||
var $btn = $('<a class="' + buttonStyle + ' user-btn">' + button.name + '</a>');
|
||||
$btn.click(function() {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
var autostart = $autoStartField.find('.icheckbox_minimal').is('.checked');
|
||||
context.jamClient.SetAutoStart(autostart);
|
||||
app.layout.closeDialog('client-preferences-dialog')
|
||||
context.jamClient.SaveSettings();
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
|
@ -54,4 +55,4 @@
|
|||
this.initialize = initialize;
|
||||
|
||||
}
|
||||
})(window, jQuery);
|
||||
})(window, jQuery);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
$browserJamTrackBtn.click(function() {
|
||||
app.layout.closeDialog('getting-started')
|
||||
window.location = '/client#/jamtrack'
|
||||
window.location = '/client#/jamtrackBrowse'
|
||||
return false;
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@
|
|||
function getBackingTracks(page) {
|
||||
|
||||
var result = context.jamClient.getBackingTrackList();
|
||||
console.log("result", result)
|
||||
var backingTracks = result.backing_tracks;
|
||||
|
||||
if (!backingTracks || backingTracks.length == 0) {
|
||||
|
|
@ -89,8 +88,7 @@
|
|||
rest.openBackingTrack({id: context.JK.CurrentSessionModel.id(), backing_track_path: backingTrack.name})
|
||||
.done(function(response) {
|
||||
var result = context.jamClient.SessionOpenBackingTrackFile(backingTrack.name, false);
|
||||
console.log("BackingTrackPlay response: %o", result);
|
||||
|
||||
|
||||
// TODO: Possibly actually check the result. Investigate
|
||||
// what real client returns:
|
||||
// // if(result) {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@
|
|||
var $dialog = null;
|
||||
|
||||
function resetForm() {
|
||||
|
||||
// remove all display errors
|
||||
$('#recording-finished-dialog form .error-text').remove()
|
||||
$('#recording-finished-dialog form .error').removeClass("error")
|
||||
removeGoogleLoginErrors()
|
||||
}
|
||||
|
||||
function beforeShow() {
|
||||
|
|
@ -130,11 +130,47 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
function startGoogleLogin(e) {
|
||||
e.preventDefault()
|
||||
logger.debug("Starting google login")
|
||||
window._oauth_win = window.open("/auth/google_login", "Log In to Google", "height=500,width=500,menubar=no,resizable=no,status=no");
|
||||
|
||||
window._oauth_callback = function() {
|
||||
window._oauth_win.close()
|
||||
setGoogleAuthState()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function claimRecording(e) {
|
||||
|
||||
resetForm();
|
||||
registerClaimRecordingHandlers(false);
|
||||
registerClaimRecordingHandlers(false)
|
||||
|
||||
var upload_to_youtube = $('#recording-finished-dialog form input[name=upload_to_youtube]').is(':checked')
|
||||
|
||||
if (upload_to_youtube) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/auth/has_google_auth"
|
||||
}).success(function(data) {
|
||||
if(data.has_google_auth) {
|
||||
performClaim()
|
||||
} else {
|
||||
var error_ul = $('<ul class="error-text upload_to_youtube"><li>You must sign in to YouTube</li></ul>')
|
||||
$('#recording-finished-dialog form [purpose=upload_to_youtube]').addClass('error').append(error_ul)
|
||||
}
|
||||
}).always(function () {
|
||||
registerClaimRecordingHandlers(true);
|
||||
})
|
||||
} else {
|
||||
performClaim()
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function performClaim() {
|
||||
var name = $('#recording-finished-dialog form input[name=name]').val();
|
||||
var description = $('#recording-finished-dialog form textarea[name=description]').val();
|
||||
var genre = $('#recording-finished-dialog form select[name=genre]').val();
|
||||
|
|
@ -151,59 +187,53 @@
|
|||
save_video: save_video,
|
||||
upload_to_youtube: upload_to_youtube
|
||||
})
|
||||
.done(function () {
|
||||
$dialog.data('result', {keep:true});
|
||||
app.layout.closeDialog('recordingFinished');
|
||||
context.JK.GA.trackMakeRecording();
|
||||
})
|
||||
.fail(function (jqXHR) {
|
||||
if (jqXHR.status == 422) {
|
||||
var errors = JSON.parse(jqXHR.responseText);
|
||||
.done(function () {
|
||||
$dialog.data('result', {keep:true});
|
||||
app.layout.closeDialog('recordingFinished');
|
||||
context.JK.GA.trackMakeRecording();
|
||||
})
|
||||
.fail(function (jqXHR) {
|
||||
if (jqXHR.status == 422) {
|
||||
var errors = JSON.parse(jqXHR.responseText);
|
||||
|
||||
var $name_errors = context.JK.format_errors('name', errors);
|
||||
if ($name_errors) $('#recording-finished-dialog form input[name=name]').closest('div.field').addClass('error').end().after($name_errors);
|
||||
var $name_errors = context.JK.format_errors('name', errors);
|
||||
if ($name_errors) $('#recording-finished-dialog form input[name=name]').closest('div.field').addClass('error').end().after($name_errors);
|
||||
|
||||
var $description_errors = context.JK.format_errors('description', errors);
|
||||
if ($description_errors) $('#recording-finished-dialog form input[name=description]').closest('div.field').addClass('error').end().after($description_errors);
|
||||
var $description_errors = context.JK.format_errors('description', errors);
|
||||
if ($description_errors) $('#recording-finished-dialog form input[name=description]').closest('div.field').addClass('error').end().after($description_errors);
|
||||
|
||||
var $genre_errors = context.JK.format_errors('genre', errors);
|
||||
if ($genre_errors) $('#recording-finished-dialog form select[name=genre]').closest('div.field').addClass('error').end().after($genre_errors);
|
||||
var $genre_errors = context.JK.format_errors('genre', errors);
|
||||
if ($genre_errors) $('#recording-finished-dialog form select[name=genre]').closest('div.field').addClass('error').end().after($genre_errors);
|
||||
|
||||
var $is_public_errors = context.JK.format_errors('is_public', errors);
|
||||
if ($is_public_errors) $('#recording-finished-dialog form input[name=is_public]').closest('div.field').addClass('error').end().after($is_public_errors);
|
||||
var $is_public_errors = context.JK.format_errors('is_public', errors);
|
||||
if ($is_public_errors) $('#recording-finished-dialog form input[name=is_public]').closest('div.field').addClass('error').end().after($is_public_errors);
|
||||
|
||||
var $save_video_errors = context.JK.format_errors('save_video', errors);
|
||||
if ($save_video_errors) $('#recording-finished-dialog form input[name=save_video]').closest('div.field').addClass('error').end().after($save_video_errors);
|
||||
var $save_video_errors = context.JK.format_errors('save_video', errors);
|
||||
if ($save_video_errors) $('#recording-finished-dialog form input[name=save_video]').closest('div.field').addClass('error').end().after($save_video_errors);
|
||||
|
||||
var recording_error = context.JK.get_first_error('recording_id', errors);
|
||||
|
||||
var $upload_to_youtube_errors = context.JK.format_errors('upload_to_youtube', errors);
|
||||
if ($upload_to_youtube_errors) $('#recording-finished-dialog form input[name=upload_to_youtube]').closest('div.field').addClass('error').end().after($upload_to_youtube_errors);
|
||||
if (recording_error) context.JK.showErrorDialog(app, "Unable to claim recording.", recording_error);
|
||||
}
|
||||
else {
|
||||
logger.error("unable to claim recording %o", arguments);
|
||||
|
||||
var recording_error = context.JK.get_first_error('recording_id', errors);
|
||||
|
||||
if (recording_error) context.JK.showErrorDialog(app, "Unable to claim recording.", recording_error);
|
||||
}
|
||||
else {
|
||||
logger.error("unable to claim recording %o", arguments);
|
||||
|
||||
context.JK.showErrorDialog(app, "Unable to claim recording.", jqXHR.responseText);
|
||||
}
|
||||
})
|
||||
.always(function () {
|
||||
registerClaimRecordingHandlers(true);
|
||||
});
|
||||
return false;
|
||||
context.JK.showErrorDialog(app, "Unable to claim recording.", jqXHR.responseText);
|
||||
}
|
||||
})
|
||||
.always(function () {
|
||||
registerClaimRecordingHandlers(true);
|
||||
});
|
||||
}
|
||||
|
||||
function registerClaimRecordingHandlers(onOff) {
|
||||
$('#keep-session-recording').off('click', claimRecording)
|
||||
$('#recording-finished-dialog form').off('submit', claimRecording);
|
||||
|
||||
if (onOff) {
|
||||
$('#keep-session-recording').on('click', claimRecording);
|
||||
$('#recording-finished-dialog form').on('submit', claimRecording);
|
||||
}
|
||||
else {
|
||||
$('#keep-session-recording').off('click', claimRecording)
|
||||
$('#recording-finished-dialog form').off('submit', claimRecording);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function registerDiscardRecordingHandlers(onOff) {
|
||||
|
|
@ -216,6 +246,11 @@
|
|||
}
|
||||
|
||||
function onPause() {
|
||||
logger.debug("calling jamClient.SessionPausePlay");
|
||||
context.jamClient.SessionPausePlay();
|
||||
}
|
||||
|
||||
function onStop() {
|
||||
logger.debug("calling jamClient.SessionStopPlay");
|
||||
context.jamClient.SessionStopPlay();
|
||||
}
|
||||
|
|
@ -234,9 +269,39 @@
|
|||
registerClaimRecordingHandlers(true);
|
||||
registerDiscardRecordingHandlers(true);
|
||||
$(playbackControls)
|
||||
.on('stop', onStop)
|
||||
.on('pause', onPause)
|
||||
.on('play', onPlay)
|
||||
.on('change-position', onChangePlayPosition);
|
||||
$dialog.find(".google_login_button").on('click', startGoogleLogin);
|
||||
|
||||
// Check for google authorization using AJAX and show/hide the
|
||||
// google login button / "signed in" label as appropriate:
|
||||
$(window).on('focus', function() {
|
||||
setGoogleAuthState();
|
||||
});
|
||||
}
|
||||
|
||||
function setGoogleAuthState() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/auth/has_google_auth"
|
||||
}).success(function(data) {
|
||||
if(data.has_google_auth) {
|
||||
$("input.google_login_button").addClass("hidden")
|
||||
$("span.signed_in_to_google").removeClass("hidden")
|
||||
removeGoogleLoginErrors()
|
||||
} else {
|
||||
$("span.signed_in_to_google").addClass("hidden")
|
||||
$("input.google_login_button").removeClass("hidden")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function removeGoogleLoginErrors() {
|
||||
$("ul.error-text.upload_to_youtube").remove()
|
||||
$('#recording-finished-dialog form div[purpose=upload_to_youtube]').removeClass('error')
|
||||
}
|
||||
|
||||
function setRecording(recordingData) {
|
||||
|
|
@ -267,7 +332,6 @@
|
|||
playbackControls = new context.JK.PlaybackControls($('#recording-finished-dialog .recording-controls'));
|
||||
|
||||
registerStaticEvents();
|
||||
|
||||
initializeButtons();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ context.JK.SinglePlayerProfileGuardDialog = class SinglePlayerProfileGuardDialog
|
|||
|
||||
latency = '?'
|
||||
if canPlayWithOthers.audioLatency?
|
||||
latency = canPlayWithOthers.audioLatency
|
||||
latency = canPlayWithOthers.audioLatency.toFixed(2)
|
||||
|
||||
@audioLatency.text("#{latency} milliseconds.")
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
|
|||
@tracked = false
|
||||
@ajaxEnqueueAborted = false
|
||||
@ajaxGetJamTrackRightAborted = false
|
||||
@currentPackagingStep = null
|
||||
@totalSteps = null
|
||||
|
||||
throw "no JamTrack specified" unless @jamTrack?
|
||||
throw "invalid size" if @size != 'large' && @size != 'small'
|
||||
|
|
@ -174,6 +176,7 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
|
|||
if @state == @states.errored
|
||||
data.result = 'error'
|
||||
data.detail = @errorReason
|
||||
@rest.createAlert("JamTrack Sync failed for #{context.JK.currentUserName}", data)
|
||||
else
|
||||
data.result = 'success'
|
||||
|
||||
|
|
@ -187,7 +190,10 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
|
|||
showDownloading: () =>
|
||||
@logger.debug("showing #{@state.name}")
|
||||
# while downloading, we don't run the transition timer, because the download API is guaranteed to call success, or failure, eventually
|
||||
context.jamClient.JamTrackDownload(@jamTrack.id, this.makeDownloadSuccessCallback(), this.makeDownloadFailureCallback())
|
||||
context.jamClient.JamTrackDownload(@jamTrack.id, context.JK.currentUserId,
|
||||
this.makeDownloadProgressCallback(),
|
||||
this.makeDownloadSuccessCallback(),
|
||||
this.makeDownloadFailureCallback())
|
||||
|
||||
showKeying: () =>
|
||||
@logger.debug("showing #{@state.name}")
|
||||
|
|
@ -374,8 +380,22 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
|
|||
.done(this.processJamTrackRight)
|
||||
.fail(this.processJamTrackRightFail)
|
||||
|
||||
# update progress indicator for packaging step
|
||||
updateSteps: () =>
|
||||
if @currentPackagingStep? and @totalSteps?
|
||||
progress = "#{Math.round(@currentPackagingStep/@totalSteps * 100)}%"
|
||||
else
|
||||
progress = '...'
|
||||
|
||||
@root.find('.state-packaging .progress').text(progress)
|
||||
|
||||
processSigningState: (jamTrackRight) =>
|
||||
signingState = jamTrackRight.signing_state
|
||||
@totalSteps = jamTrackRight.packaging_steps
|
||||
@currentPackagingStep = jamTrackRight.current_packaging_step
|
||||
|
||||
@updateSteps()
|
||||
|
||||
processSigningState: (signingState) =>
|
||||
@logger.debug("DownloadJamTrack: processSigningState: " + signingState)
|
||||
|
||||
switch signingState
|
||||
|
|
@ -435,8 +455,9 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
|
|||
|
||||
|
||||
processJamTrackRight: (myJamTrack) =>
|
||||
@logger.debug("processJamTrackRight", myJamTrack)
|
||||
unless @ajaxGetJamTrackRightAborted
|
||||
this.processSigningState(myJamTrack.signing_state)
|
||||
this.processSigningState(myJamTrack)
|
||||
else
|
||||
@logger.debug("DownloadJamTrack: ignoring processJamTrackRight response")
|
||||
|
||||
|
|
@ -459,16 +480,26 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
|
|||
@logger.debug("DownloadJamTrack: ignoring processEnqueueJamTrackFail response")
|
||||
|
||||
onJamTrackRightEvent: (e, data) =>
|
||||
@logger.debug("DownloadJamTrack: subscription notification received: type:" + data.type)
|
||||
@logger.debug("DownloadJamTrack: subscription notification received: type:" + data.type, data)
|
||||
this.expectTransition()
|
||||
this.processSigningState(data.body.signing_state)
|
||||
this.processSigningState(data.body)
|
||||
|
||||
downloadProgressCallback: (bytesReceived, bytesTotal, downloadSpeedMegSec, timeRemaining) =>
|
||||
bytesReceived = Number(bytesReceived)
|
||||
bytesTotal = Number(bytesTotal)
|
||||
# bytesTotal from Qt is not trust worthy; trust server's answer instead
|
||||
#progressWidth = ((bytesReceived / updateSize) * 100).toString() + "%";
|
||||
# $('#progress-bar').width(progressWidth)
|
||||
updateDownloadProgress: () =>
|
||||
|
||||
if @bytesReceived? and @bytesTotal?
|
||||
progress = "#{Math.round(@bytesReceived/@bytesTotal * 100)}%"
|
||||
else
|
||||
progress = '0%'
|
||||
|
||||
@root.find('.state-downloading .progress').text(progress)
|
||||
|
||||
downloadProgressCallback: (bytesReceived, bytesTotal) =>
|
||||
@logger.debug("download #{bytesReceived}/#{bytesTotal}")
|
||||
|
||||
@bytesReceived = Number(bytesReceived)
|
||||
@bytesTotal = Number(bytesTotal)
|
||||
|
||||
setTimeout(this.updateDownloadProgress, 100)
|
||||
|
||||
downloadSuccessCallback: (updateLocation) =>
|
||||
# is the package loadable yet?
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
var stun = null;
|
||||
var rest = context.JK.Rest();
|
||||
|
||||
|
||||
$(document).on('JAMKAZAM_CONSTRUCTED', function(e, data) {
|
||||
|
||||
var app = data.app;
|
||||
|
|
@ -31,6 +32,8 @@
|
|||
updateScoringIntervals();
|
||||
|
||||
initializeInfluxDB();
|
||||
|
||||
trackNewUser();
|
||||
})
|
||||
|
||||
$(document).on('JAMKAZAM_READY', function() {
|
||||
|
|
@ -204,9 +207,9 @@
|
|||
var user = app.user()
|
||||
if(user) {
|
||||
user.done(function(userProfile) {
|
||||
if (userProfile.show_whats_next && userProfile.show_whats_next_count < 10 &&
|
||||
if (!userProfile.show_jamtrack_guide && userProfile.show_whats_next && userProfile.show_whats_next_count < 10 &&
|
||||
window.location.pathname.indexOf(gon.client_path) == 0 &&
|
||||
window.location.pathname.indexOf('/checkout') == -1 &&
|
||||
window.location.hash.indexOf('/checkout') == -1 &&
|
||||
!app.layout.isDialogShowing('getting-started'))
|
||||
{
|
||||
app.layout.showDialog('getting-started');
|
||||
|
|
@ -219,4 +222,26 @@
|
|||
context.JK.JamTrackUtils.checkShoppingCart();
|
||||
}
|
||||
|
||||
function trackNewUser() {
|
||||
var cookie = $.cookie('new_user')
|
||||
|
||||
if(cookie) {
|
||||
try {
|
||||
cookie = JSON.parse(cookie)
|
||||
|
||||
context.JK.signup = {}
|
||||
context.JK.signup = cookie
|
||||
|
||||
$(function() {
|
||||
// ga() object isn't ready until the page is loaded
|
||||
$.removeCookie('new_user')
|
||||
context.JK.GA.trackRegister(cookie.musician, cookie.registrationType);
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
logger.error("unable to deserialize new_user cookie")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})(window, jQuery);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
var frameSize = 2.5;
|
||||
var fakeJamClientRecordings = null;
|
||||
var p2pCallbacks = null;
|
||||
var videoShared = false;
|
||||
var metronomeActive=false;
|
||||
var metronomeBPM=false;
|
||||
var metronomeSound=false;
|
||||
|
|
@ -59,6 +60,45 @@
|
|||
function FTUESetMusicProfileName() {
|
||||
|
||||
}
|
||||
|
||||
function FTUESelectVideoCaptureDevice(device, settings) {
|
||||
|
||||
}
|
||||
function FTUESetVideoEncodeResolution(resolution) {
|
||||
|
||||
}
|
||||
function FTUEGetVideoCaptureDeviceNames() {
|
||||
return ["Built-in Webcam HD"]
|
||||
}
|
||||
function FTUECurrentSelectedVideoDevice() {
|
||||
return {"xy323ss": "Built-in Webcam HD"}
|
||||
}
|
||||
function FTUEGetAvailableEncodeVideoResolutions() {
|
||||
return {
|
||||
1: "1024x768",
|
||||
2: "800x600"
|
||||
}
|
||||
}
|
||||
|
||||
function FTUEGetVideoCaptureDeviceCapabilities() {
|
||||
return {}
|
||||
}
|
||||
|
||||
function isSessVideoShared() {
|
||||
return videoShared;
|
||||
}
|
||||
|
||||
function SessStopVideoSharing() {
|
||||
videoShared=false;
|
||||
}
|
||||
|
||||
function SessStartVideoSharing(bitrate) {
|
||||
if (!bitrate || typeof(bitrate)=="undefined") {
|
||||
bitrate = 0
|
||||
}
|
||||
videoShared=true;
|
||||
}
|
||||
|
||||
function FTUEGetInputLatency() {
|
||||
dbg("FTUEGetInputLatency");
|
||||
return 2;
|
||||
|
|
@ -403,6 +443,14 @@
|
|||
}
|
||||
|
||||
// Session Functions
|
||||
|
||||
function SessionCurrrentJamTrackPlayPosMs() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
function SessionGetJamTracksPlayDurationMs() {
|
||||
return 60000;
|
||||
}
|
||||
function SessionAddTrack() {}
|
||||
|
||||
function SessionAudioResync() {
|
||||
|
|
@ -931,6 +979,7 @@
|
|||
function LeaveSessionAndMinimize() {}
|
||||
function SetAutoStart() {}
|
||||
function GetAutoStart() { return true; }
|
||||
function SaveSettings() {}
|
||||
|
||||
// Javascript Bridge seems to camel-case
|
||||
// Set the instance functions:
|
||||
|
|
@ -1031,6 +1080,8 @@
|
|||
|
||||
// Session
|
||||
this.SessionAddTrack = SessionAddTrack;
|
||||
this.SessionCurrrentJamTrackPlayPosMs = SessionCurrrentJamTrackPlayPosMs;
|
||||
this.SessionGetJamTracksPlayDurationMs = SessionGetJamTracksPlayDurationMs;
|
||||
this.SessionGetControlState = SessionGetControlState;
|
||||
this.SessionGetAllControlState = SessionGetAllControlState;
|
||||
this.SessionSetUserName = SessionSetUserName;
|
||||
|
|
@ -1140,6 +1191,19 @@
|
|||
this.ClosePreviewRecording = ClosePreviewRecording;
|
||||
this.OnDownloadAvailable = OnDownloadAvailable;
|
||||
|
||||
// Video functionality:
|
||||
this.FTUESelectVideoCaptureDevice = FTUESelectVideoCaptureDevice
|
||||
this.FTUESetVideoEncodeResolution = FTUESetVideoEncodeResolution;
|
||||
this.FTUEGetVideoCaptureDeviceNames = FTUEGetVideoCaptureDeviceNames;
|
||||
this.FTUECurrentSelectedVideoDevice = FTUECurrentSelectedVideoDevice;
|
||||
this.FTUEGetAvailableEncodeVideoResolutions = FTUEGetAvailableEncodeVideoResolutions;
|
||||
this.FTUEGetVideoCaptureDeviceCapabilities = FTUEGetVideoCaptureDeviceCapabilities;
|
||||
|
||||
|
||||
this.isSessVideoShared = isSessVideoShared;
|
||||
this.SessStopVideoSharing = SessStopVideoSharing;
|
||||
this.SessStartVideoSharing = SessStartVideoSharing;
|
||||
|
||||
// Clipboard
|
||||
this.SaveToClipboard = SaveToClipboard;
|
||||
|
||||
|
|
@ -1169,4 +1233,4 @@
|
|||
this.clientID = "devtester";
|
||||
};
|
||||
|
||||
})(window,jQuery);
|
||||
})(window,jQuery);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
"use strict";
|
||||
|
||||
context.JK = context.JK || {};
|
||||
var rest = context.JK.Rest();
|
||||
var logger = context.JK.logger;
|
||||
|
||||
// types
|
||||
|
|
@ -130,6 +131,20 @@
|
|||
jkComment : 'jkComment'
|
||||
};
|
||||
|
||||
// JamTrack categories and actions:
|
||||
var jamTrackAvailabilityTypes = {
|
||||
worldwide: 'JamTrackGlobal',
|
||||
usa: 'JamTrackUSA'
|
||||
}
|
||||
var jamTrackActions = {
|
||||
isPublic: 'PublicPerformance',
|
||||
isPrivate: 'PrivateUse'
|
||||
}
|
||||
var jamTrackSessionLabels = {
|
||||
nonSession: 'NonSession',
|
||||
inSession: 'InSession'
|
||||
}
|
||||
|
||||
function translatePlatformForGA(platform) {
|
||||
assertOneOf(platform, context.JK.OS);
|
||||
|
||||
|
|
@ -239,6 +254,36 @@
|
|||
context.ga('send', 'event', categories.findSession, sessionCountRollup, numSessionsFound);
|
||||
}
|
||||
|
||||
function trackJamTrackPlaySession(sessionId, inSession) {
|
||||
rest.getSession(sessionId).done(function(session) {
|
||||
if (session && session.jam_track ) {
|
||||
rest.getJamTracks({id:session.jam_track.id}).done(function(response) {
|
||||
if (response.jamtracks && response.jamtracks.length!=0) {
|
||||
var jamtrack = response.jamtracks[0]
|
||||
trackJamTrackPlay(
|
||||
jamtrack.sales_region!=context.JK.AVAILABILITY_US,
|
||||
session.participants.length > 1,
|
||||
inSession);
|
||||
}// if
|
||||
})// rest.getJamTracks
|
||||
}// if
|
||||
})// rest.getSession
|
||||
}
|
||||
|
||||
function trackJamTrackPlay(isGlobal, isPublic, inSession) {
|
||||
assertBoolean(isGlobal)
|
||||
assertBoolean(isPublic)
|
||||
assertBoolean(inSession)
|
||||
context.ga(
|
||||
'send',
|
||||
'event',
|
||||
(isGlobal) ? jamTrackAvailabilityTypes.worldwide : jamTrackAvailabilityTypes.usa,
|
||||
(isPublic) ? jamTrackActions.isPublic : jamTrackActions.isPrivate,
|
||||
(inSession) ? jamTrackSessionLabels.inSession : jamTrackSessionLabels.nonSession
|
||||
)
|
||||
logger.debug("Tracked Jam Track Play")
|
||||
}
|
||||
|
||||
// if you want to pass in no title, either omit it from the arg list when u invoke virtualPageView, or pass in undefined, NOT null
|
||||
function virtualPageView(page, title) {
|
||||
|
||||
|
|
@ -271,7 +316,8 @@
|
|||
}
|
||||
|
||||
// when someone plays a recording
|
||||
function trackRecordingPlay(recordingAction) {
|
||||
function trackRecordingPlay(recording, recordingAction) {
|
||||
|
||||
if (!recordingAction) {
|
||||
recordingAction = _defaultPlayAction();
|
||||
}
|
||||
|
|
@ -279,10 +325,20 @@
|
|||
var label = JK.currentUserId ? userLabels.registeredUser : userLabels.visitor;
|
||||
|
||||
context.ga('send', 'event', categories.recordingPlay, recordingAction, label);
|
||||
|
||||
if (recording.jam_track) {
|
||||
rest.getJamTracks({id:recording.jam_track_id}).done(function(response) {
|
||||
if (response.jamtracks && response.jamtracks.length==1) {
|
||||
var jamtrack = response.jamtracks[0]
|
||||
trackJamTrackPlay(jamtrack.sales_region!=context.JK.AVAILABILITY_US, recording.fan_access, false);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// when someone plays a live session broadcast
|
||||
function trackSessionPlay(recordingAction) {
|
||||
function trackSessionPlay(session, recordingAction) {
|
||||
logger.debug("Tracking session play: ", session)
|
||||
if (!recordingAction) {
|
||||
recordingAction = _defaultPlayAction();
|
||||
}
|
||||
|
|
@ -379,7 +435,8 @@
|
|||
GA.trackSessionQuality = trackSessionQuality;
|
||||
GA.trackServiceInvitations = trackServiceInvitations;
|
||||
GA.trackFindSessions = trackFindSessions;
|
||||
GA.virtualPageView = virtualPageView;
|
||||
GA.trackJamTrackPlay = trackJamTrackPlay;
|
||||
GA.trackJamTrackPlaySession = trackJamTrackPlaySession;
|
||||
GA.trackFriendConnect = trackFriendConnect;
|
||||
GA.trackMakeRecording = trackMakeRecording;
|
||||
GA.trackShareRecording = trackShareRecording;
|
||||
|
|
@ -387,8 +444,8 @@
|
|||
GA.trackSessionPlay = trackSessionPlay;
|
||||
GA.trackBand = trackBand;
|
||||
GA.trackJKSocial = trackJKSocial;
|
||||
|
||||
|
||||
GA.virtualPageView = virtualPageView;
|
||||
|
||||
context.JK.GA = GA;
|
||||
|
||||
})(window,jQuery);
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
var rest = new context.JK.Rest();
|
||||
context.JK.HelpBubbleHelper = helpBubble;
|
||||
var logger = context.JK.logger;
|
||||
var jamTrackGuideTimeout = null;
|
||||
|
||||
var defaultScoreBreakDownOptions = {positions: ['right', 'top', 'bottom', 'left'], width:'600px', closeWhenOthersOpen: true };
|
||||
helpBubble.scoreBreakdown = function($element, isCurrentUser, full_score, myAudioLatency, otherAudioLatency, internetScore, options) {
|
||||
|
|
@ -26,4 +27,59 @@
|
|||
}
|
||||
}
|
||||
|
||||
function bigHelpOptions(options) {
|
||||
return {positions: options.positions, offsetParent: options.offsetParent,
|
||||
spikeGirth: 15,
|
||||
spikeLength: 20,
|
||||
fill: 'white',
|
||||
cornerRadius:8,
|
||||
strokeWidth: 2,
|
||||
cssStyles: {
|
||||
fontWeight:'bold',
|
||||
fontSize: '20px',
|
||||
backgroundColor:'transparent',
|
||||
color:'#ed3618'}}
|
||||
}
|
||||
|
||||
function clearJamTrackGuideTimeout() {
|
||||
if(jamTrackGuideTimeout) {
|
||||
clearTimeout(jamTrackGuideTimeout);
|
||||
jamTrackGuideTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
function jamTrackGuide(callback) {
|
||||
if(gon.isNativeClient) {
|
||||
context.JK.app.user().done(function(user) {
|
||||
if(user.show_jamtrack_guide) {
|
||||
clearJamTrackGuideTimeout();
|
||||
jamTrackGuideTimeout = setTimeout(function() {
|
||||
callback()
|
||||
}, 1000)
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
helpBubble.clearJamTrackGuide = clearJamTrackGuideTimeout;
|
||||
|
||||
helpBubble.jamtrackGuideTile = function ($element, $offsetParent) {
|
||||
jamTrackGuide(function() {
|
||||
context.JK.prodBubble($element, 'jamtrack-guide-tile', {}, bigHelpOptions({positions:['top'], offsetParent: $offsetParent}))
|
||||
})
|
||||
}
|
||||
|
||||
helpBubble.jamtrackGuidePrivate = function ($element, $offsetParent) {
|
||||
jamTrackGuide(function() {
|
||||
context.JK.prodBubble($element, 'jamtrack-guide-private', {}, bigHelpOptions({positions:['right'], offsetParent: $offsetParent}))
|
||||
})
|
||||
}
|
||||
|
||||
helpBubble.jamtrackGuideSession = function ($element, $offsetParent) {
|
||||
jamTrackGuide(function() {
|
||||
context.JK.prodBubble($element, 'jamtrack-guide-session', {}, bigHelpOptions({positions:['left'], offsetParent: $offsetParent}))
|
||||
})
|
||||
}
|
||||
|
||||
})(window, jQuery);
|
||||
|
|
@ -11,6 +11,14 @@
|
|||
function beforeShow(data) {
|
||||
}
|
||||
|
||||
function afterShow(data) {
|
||||
context.JK.HelpBubbleHelper.jamtrackGuideTile($('.homecard.createsession'), $screen.find('.createsession'));
|
||||
}
|
||||
|
||||
function beforeHide() {
|
||||
context.JK.HelpBubbleHelper.clearJamTrackGuide();
|
||||
}
|
||||
|
||||
function mouseenterTile() {
|
||||
$(this).addClass('hover');
|
||||
}
|
||||
|
|
@ -84,7 +92,7 @@
|
|||
}
|
||||
|
||||
this.initialize = function() {
|
||||
var screenBindings = { 'beforeShow': beforeShow };
|
||||
var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow, 'beforeHide' : beforeHide };
|
||||
app.bindScreen('home', screenBindings);
|
||||
events();
|
||||
$screen = $('.screen[layout-id="home"]')
|
||||
|
|
|
|||
|
|
@ -287,11 +287,6 @@
|
|||
}
|
||||
|
||||
function addPlayablePlay(playableId, playableType, claimedRecordingId, userId) {
|
||||
if (playableType == 'JamRuby::Recording') {
|
||||
context.JK.GA.trackRecordingPlay();
|
||||
} else if (playableType == 'JamRuby::MusicSession') {
|
||||
context.JK.GA.trackSessionPlay();
|
||||
}
|
||||
return $.ajax({
|
||||
url: '/api/users/' + playableId + "/plays",
|
||||
type: "POST",
|
||||
|
|
@ -1466,7 +1461,7 @@
|
|||
});
|
||||
}
|
||||
|
||||
function getJamtracks(options) {
|
||||
function getJamTracks(options) {
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
url: '/api/jamtracks?' + $.param(options),
|
||||
|
|
@ -1475,6 +1470,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'];
|
||||
|
||||
|
|
@ -1518,7 +1522,7 @@
|
|||
function getSalesHistory(options) {
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
url: '/api/sales?' + $.param(options),
|
||||
url: '/api/payment_histories?' + $.param(options),
|
||||
dataType: "json",
|
||||
contentType: 'application/json'
|
||||
});
|
||||
|
|
@ -1675,7 +1679,30 @@
|
|||
});
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
function createSignupHint(data) {
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
url: '/api/signup_hints',
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
function createAlert(subject, data) {
|
||||
var message = {subject:subject};
|
||||
$.extend(message, data);
|
||||
console.log("message", message)
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
url: '/api/alerts',
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(message),
|
||||
});
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
@ -1799,7 +1826,8 @@
|
|||
this.updateAudioLatency = updateAudioLatency;
|
||||
this.getJamTrack = getJamTrack;
|
||||
this.getJamTrackWithArtistInfo = getJamTrackWithArtistInfo;
|
||||
this.getJamtracks = getJamtracks;
|
||||
this.getJamTracks = getJamTracks;
|
||||
this.getJamTrackArtists = getJamTrackArtists;
|
||||
this.getPurchasedJamTracks = getPurchasedJamTracks;
|
||||
this.getPaymentHistory = getPaymentHistory;
|
||||
this.getSalesHistory = getSalesHistory;
|
||||
|
|
@ -1825,6 +1853,8 @@
|
|||
this.getMusicianSearchFilter = getMusicianSearchFilter;
|
||||
this.postMusicianSearchFilter = postMusicianSearchFilter;
|
||||
this.playJamTrack = playJamTrack;
|
||||
this.createSignupHint = createSignupHint;
|
||||
this.createAlert = createAlert;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ context.JK.JamTrackPreview = class JamTrackPreview
|
|||
@EVENTS = context.JK.EVENTS
|
||||
@rest = context.JK.Rest()
|
||||
@logger = context.JK.logger
|
||||
@options = options || {master_shows_duration: false}
|
||||
@options = options || {master_shows_duration: false, color:'gray'}
|
||||
@app = app
|
||||
@jamTrack = jamTrack
|
||||
@jamTrackTrack = jamTrackTrack
|
||||
|
|
@ -23,7 +23,7 @@ context.JK.JamTrackPreview = class JamTrackPreview
|
|||
template = $('#template-jam-track-preview')
|
||||
throw "no jam track preview template" if not template.exists()
|
||||
|
||||
@root.html($(template.html()))
|
||||
@root.html(context._.template(template.html(), @options, {variable:'data'}))
|
||||
@playButton = @root.find('.play-button')
|
||||
@stopButton = @root.find('.stop-button')
|
||||
@instrumentIcon = @root.find('.instrument-icon')
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ context.JK.JamTrackScreen=class JamTrackScreen
|
|||
@instrument.val(parms.instrument)
|
||||
if(parms.availability?)
|
||||
@availability.val(parms.availability)
|
||||
window.history.replaceState({}, "", "/client#/jamtrack")
|
||||
window.history.replaceState({}, "", "/client#/jamtrackBrowse")
|
||||
|
||||
getParams:() =>
|
||||
params = {}
|
||||
|
|
@ -63,16 +63,31 @@ context.JK.JamTrackScreen=class JamTrackScreen
|
|||
params[key] = decodeURIComponent(val)
|
||||
params
|
||||
|
||||
setFilterState: (state) =>
|
||||
if state
|
||||
@genre.easyDropDown('enable').removeAttr('disabled')
|
||||
@artist.easyDropDown('enable').removeAttr('disabled')
|
||||
@instrument.easyDropDown('enable').removeAttr('disabled')
|
||||
@availability.easyDropDown('enable').removeAttr('disabled')
|
||||
else
|
||||
@genre.easyDropDown('disable').attr('disabled', 'disabled')
|
||||
@artist.easyDropDown('disable').attr('disabled', 'disabled')
|
||||
@instrument.easyDropDown('disable').attr('disabled', 'disabled')
|
||||
@availability.easyDropDown('disable').attr('disabled', 'disabled')
|
||||
|
||||
refresh:() =>
|
||||
this.clearResults()
|
||||
@currentQuery = this.buildQuery()
|
||||
that = this
|
||||
rest.getJamtracks(@currentQuery).done((response) =>
|
||||
that.clearResults()
|
||||
this.setFilterState(false)
|
||||
rest.getJamTracks(@currentQuery).done((response) =>
|
||||
that.handleJamtrackResponse(response)
|
||||
).fail (jqXHR) =>
|
||||
).fail( (jqXHR) =>
|
||||
that.clearResults()
|
||||
that.noMoreJamtracks.show()
|
||||
that.app.notifyServerError jqXHR, 'Jamtrack Unavailable'
|
||||
that.app.notifyServerError jqXHR, 'Jamtrack Unavailable'
|
||||
).always () =>
|
||||
that.setFilterState(true)
|
||||
|
||||
search:() =>
|
||||
this.refresh()
|
||||
|
|
@ -117,7 +132,7 @@ context.JK.JamTrackScreen=class JamTrackScreen
|
|||
# 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\'>No JamTracks found.</div>'
|
||||
@content.append '<td colspan="3" class="no-jamtracks-msg\'>No JamTracks found.</div>'
|
||||
if @currentPage > 0
|
||||
@noMoreJamtracks.show()
|
||||
# there are bugs with infinitescroll not removing the 'loading'.
|
||||
|
|
@ -162,14 +177,39 @@ context.JK.JamTrackScreen=class JamTrackScreen
|
|||
|
||||
licenseUSWhy:(e) =>
|
||||
e.preventDefault()
|
||||
@app.layout.showDialog 'jamtrack-availability-dialog'
|
||||
@app.layout.showDialog 'jamtrack-availability-dialog'
|
||||
|
||||
registerEvents:() =>
|
||||
handleExpanded:(trackElement) =>
|
||||
jamTrack = trackElement.data('jamTrack')
|
||||
expanded = trackElement.data('expanded')
|
||||
expand = !expanded
|
||||
trackElement.data('expanded', expand)
|
||||
|
||||
detailArrow = trackElement.find('.jamtrack-detail-btn')
|
||||
|
||||
if expand
|
||||
trackElement.find('.extra').removeClass('hidden')
|
||||
detailArrow.html('hide tracks <a class="details-arrow arrow-up-orange"></a>')
|
||||
for track in jamTrack.tracks
|
||||
trackElement.find("[jamtrack-track-id='#{track.id}']").removeClass('hidden')
|
||||
else
|
||||
trackElement.find('.extra').addClass('hidden')
|
||||
detailArrow.html('preview all tracks <a class="details-arrow arrow-down-orange"></a>')
|
||||
count = 0
|
||||
for track in jamTrack.tracks
|
||||
if count < 2
|
||||
trackElement.find("[jamtrack-track-id='#{track.id}']").removeClass('hidden')
|
||||
else
|
||||
trackElement.find("[jamtrack-track-id='#{track.id}']").addClass('hidden')
|
||||
count++
|
||||
|
||||
|
||||
registerEvents:(parent) =>
|
||||
#@screen.find('.jamtrack-detail-btn').on 'click', this.showJamtrackDescription
|
||||
@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
|
||||
parent.find('.play-button').on 'click', this.playJamtrack
|
||||
parent.find('.jamtrack-add-cart').on 'click', this.addToCartJamtrack
|
||||
parent.find('.license-us-why').on 'click', this.licenseUSWhy
|
||||
parent.find('.jamtrack-detail-btn').on 'click', this.toggleExpanded
|
||||
# @screen.find('.jamtrack-preview').each (index, element) =>
|
||||
# new JK.JamTrackPreview(data.app, $element, jamTrack, track, {master_shows_duration: true})
|
||||
|
||||
|
|
@ -188,37 +228,41 @@ context.JK.JamTrackScreen=class JamTrackScreen
|
|||
trackRow.track_cnt = jamtrack.tracks.length
|
||||
trackRow.tracks = []
|
||||
for track in jamtrack.tracks
|
||||
if track.track_type != 'Master'
|
||||
trackRow.tracks.push(track)
|
||||
if track.track_type=='Master'
|
||||
track.instrument_desc = "Master"
|
||||
else
|
||||
inst = '../assets/content/icon_instrument_default24.png'
|
||||
if track.instrument?
|
||||
if track.instrument.id in instrument_logo_map
|
||||
inst = instrument_logo_map[track.instrument.id].asset
|
||||
track.instrument_desc = track.instrument.description
|
||||
track.instrument_url = inst
|
||||
|
||||
if track.part != ''
|
||||
track.instrument_desc += ' (' + track.part + ')'
|
||||
trackRow.tracks.push(track)
|
||||
if track.track_type=='Master'
|
||||
track.instrument_desc = "Master"
|
||||
else
|
||||
inst = '../assets/content/icon_instrument_default24.png'
|
||||
if track.instrument?
|
||||
if track.instrument.id in instrument_logo_map
|
||||
inst = instrument_logo_map[track.instrument.id].asset
|
||||
track.instrument_desc = track.instrument.description
|
||||
track.instrument_url = inst
|
||||
|
||||
if track.part != ''
|
||||
track.instrument_desc += ' (' + track.part + ')'
|
||||
|
||||
options =
|
||||
jamtrack: trackRow
|
||||
expanded: jamtrackExpanded
|
||||
expanded: false
|
||||
@jamtrackItem = $(context._.template($('#template-jamtrack').html(), options, variable: 'data'))
|
||||
that.renderJamtrack(@jamtrackItem, jamtrack)
|
||||
|
||||
this.registerEvents()
|
||||
that.registerEvents(@jamtrackItem)
|
||||
|
||||
|
||||
renderJamtrack:(jamtrackElement, jamTrack) =>
|
||||
jamtrackElement.data('jamTrack', jamTrack)
|
||||
jamtrackElement.data('expanded', true)
|
||||
|
||||
@content.append jamtrackElement
|
||||
|
||||
if this.expanded==jamTrack.id
|
||||
for track in jamTrack.tracks
|
||||
trackRow = jamtrackElement.find("[jamtrack-track-id='#{track.id}']")
|
||||
previewElement = trackRow.find(".jamtrack-preview")
|
||||
new JK.JamTrackPreview(@app, previewElement, jamTrack, track, {master_shows_duration: false})
|
||||
#if this.expanded==jamTrack.id
|
||||
for track in jamTrack.tracks
|
||||
trackRow = jamtrackElement.find("[jamtrack-track-id='#{track.id}']")
|
||||
previewElement = trackRow.find(".jamtrack-preview")
|
||||
new JK.JamTrackPreview(@app, previewElement, jamTrack, track, {master_shows_duration: true, color:'gray'})
|
||||
|
||||
this.handleExpanded(jamtrackElement, false)
|
||||
|
||||
showJamtrackDescription:(e) =>
|
||||
e.preventDefault()
|
||||
|
|
@ -232,17 +276,14 @@ context.JK.JamTrackScreen=class JamTrackScreen
|
|||
e.preventDefault()
|
||||
jamtrackRecord = $(e.target).parents('.jamtrack-record')
|
||||
jamTrackId = jamtrackRecord.attr("jamtrack-id")
|
||||
if this.expanded==jamTrackId
|
||||
this.expanded = null
|
||||
else
|
||||
this.expanded = jamTrackId
|
||||
this.rerenderJamtracks()
|
||||
|
||||
this.handleExpanded(jamtrackRecord)
|
||||
|
||||
initialize:() =>
|
||||
screenBindings =
|
||||
'beforeShow': this.beforeShow
|
||||
'afterShow': this.afterShow
|
||||
@app.bindScreen 'jamtrack', screenBindings
|
||||
@app.bindScreen 'jamtrackBrowse', screenBindings
|
||||
@screen = $('#jamtrack-find-form')
|
||||
@scroller = @screen.find('.content-body-scroller')
|
||||
@content = @screen.find('.jamtrack-content')
|
||||
|
|
|
|||
|
|
@ -344,6 +344,18 @@
|
|||
return userData;
|
||||
}
|
||||
|
||||
this.refreshUser = function() {
|
||||
userDeferred = rest.getUserDetail();
|
||||
if (userDeferred) {
|
||||
userDeferred.done(this.updateUserCache)
|
||||
}
|
||||
else {
|
||||
userDeferred = new $.Deferred();
|
||||
userDeferred.reject('not_logged_in');
|
||||
}
|
||||
return userDeferred;
|
||||
}
|
||||
|
||||
this.activeElementEvent = function(evtName, data) {
|
||||
return this.layout.activeElementEvent(evtName, data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,45 +8,70 @@ 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 = "<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>")
|
||||
for artist in artists
|
||||
artistLink = "<a href='client?artist=#{encodeURIComponent(artist.original_artist)}#/jamtrackBrowse' class='artist-link' artist='#{artist.original_artist}'>#{artist.original_artist} (#{artist.song_count})</a>"
|
||||
@bandList.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"
|
||||
@bandList.on "click", "a.artist-link", (event)->
|
||||
context.location="client#/jamtrackBrowse"
|
||||
window.history.replaceState({}, "", this.href)
|
||||
event.preventDefault()
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,10 @@
|
|||
audioDomElement.play();
|
||||
isPlaying = true;
|
||||
rest.addPlayablePlay(recordingId, 'JamRuby::Recording', claimedRecordingId, context.JK.currentUserId);
|
||||
rest.getRecording({id: recordingId})
|
||||
.done(function(recording) {
|
||||
context.JK.GA.trackRecordingPlay(recording);
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,8 @@
|
|||
waitForBufferingTimeout = setTimeout(noBuffer, WAIT_FOR_BUFFER_TIMEOUT);
|
||||
logger.debug("setting buffering timeout");
|
||||
rest.addPlayablePlay(musicSessionId, 'JamRuby::MusicSession', null, context.JK.currentUserId);
|
||||
|
||||
context.JK.GA.trackJamTrackPlaySession(musicSessionId, false)
|
||||
|
||||
if(needsCanPlayGuard()) {
|
||||
$audio.bind('canplay', function() {
|
||||
audioDomElement.play();
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
//= require jamkazam
|
||||
//= require utils
|
||||
//= require ui_helper
|
||||
//= require ga
|
||||
//= require jam_rest
|
||||
//= require ga
|
||||
//= require web/signup_helper
|
||||
//= require web/signin_helper
|
||||
//= require web/signin
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
var $playButton = $('.play-button img.playbutton', $parentElement);
|
||||
var $pauseButton = $('.play-button img.pausebutton', $parentElement);
|
||||
var $stopButton = $('.stop-button img.stopbutton', $parentElement);
|
||||
var $currentTime = $('.recording-current', $parentElement);
|
||||
var $duration = $('.duration-time', $parentElement);
|
||||
var $sliderBar = $('.recording-playback', $parentElement);
|
||||
|
|
@ -42,6 +43,7 @@
|
|||
var playbackDurationMs = 0;
|
||||
var playbackPositionMs = 0;
|
||||
var durationChanged = false;
|
||||
var seenActivity = false;
|
||||
|
||||
var endReached = false;
|
||||
var dragging = false;
|
||||
|
|
@ -53,16 +55,28 @@
|
|||
var playbackMonitorMode = PLAYBACK_MONITOR_MODE.MEDIA_FILE;
|
||||
|
||||
function startPlay() {
|
||||
seenActivity = false;
|
||||
updateIsPlaying(true);
|
||||
if(endReached) {
|
||||
update(0, playbackDurationMs, playbackPlaying);
|
||||
}
|
||||
$self.triggerHandler('play', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode});
|
||||
|
||||
|
||||
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK) {
|
||||
var sessionModel = context.JK.CurrentSessionModel || null;
|
||||
context.JK.GA.trackJamTrackPlaySession(sessionModel.id(), true)
|
||||
}
|
||||
}
|
||||
|
||||
function stopPlay(endReached) {
|
||||
updateIsPlaying(false);
|
||||
$self.triggerHandler('pause', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode, endReached : endReached});
|
||||
$self.triggerHandler('stop', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode, endReached : endReached});
|
||||
}
|
||||
|
||||
function pausePlay(endReached) {
|
||||
updateIsPlaying(false);
|
||||
$self.triggerHandler('pause', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode, endReached : endReached});
|
||||
}
|
||||
|
||||
function updateOffsetBasedOnPosition(offsetLeft) {
|
||||
|
|
@ -121,6 +135,17 @@
|
|||
// return false;
|
||||
//}
|
||||
|
||||
pausePlay();
|
||||
return false;
|
||||
});
|
||||
|
||||
$stopButton.on('click', function(e) {
|
||||
var sessionModel = context.JK.CurrentSessionModel || null;
|
||||
//if(sessionModel && sessionModel.areControlsLockedForJamTrackRecording() && $parentElement.closest('.session-track').data('track_data').type == 'jam_track') {
|
||||
// context.JK.prodBubble($pauseButton, 'jamtrack-controls-disabled', {}, {positions:['top'], offsetParent: $pauseButton})
|
||||
// return false;
|
||||
//}
|
||||
|
||||
stopPlay();
|
||||
return false;
|
||||
});
|
||||
|
|
@ -182,8 +207,7 @@
|
|||
var positionMs = context.jamClient.SessionCurrrentJamTrackPlayPosMs();
|
||||
var duration = context.jamClient.SessionGetJamTracksPlayDurationMs();
|
||||
var durationMs = duration.media_len;
|
||||
var start = duration.start; // needed to understand start offset, and prevent slider from moving in tapins
|
||||
//console.log("JamTrack start: " + start)
|
||||
var start = duration.start; // needed to understand start offset, and prevent slider from moving in tapins
|
||||
}
|
||||
else {
|
||||
var positionMs = context.jamClient.SessionCurrrentPlayPosMs();
|
||||
|
|
@ -197,18 +221,11 @@
|
|||
positionMs = 0;
|
||||
}
|
||||
|
||||
if(playbackMonitorMode = PLAYBACK_MONITOR_MODE.JAMTRACK) {
|
||||
|
||||
if(isPlaying) {
|
||||
$jamTrackGetReady.attr('data-current-time', positionMs)
|
||||
}
|
||||
else {
|
||||
// this is so the jamtrack 'Get Ready!' stays hidden when it's not playing
|
||||
$jamTrackGetReady.attr('data-current-time', -1)
|
||||
}
|
||||
|
||||
if(positionMs > 0) {
|
||||
seenActivity = true;
|
||||
}
|
||||
|
||||
|
||||
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.METRONOME) {
|
||||
updateIsPlaying(isPlaying);
|
||||
}
|
||||
|
|
@ -216,6 +233,17 @@
|
|||
update(positionMs, durationMs, isPlaying);
|
||||
}
|
||||
|
||||
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK) {
|
||||
|
||||
if(playbackPlaying) {
|
||||
$jamTrackGetReady.attr('data-current-time', positionMs)
|
||||
}
|
||||
else {
|
||||
// this is so the jamtrack 'Get Ready!' stays hidden when it's not playing
|
||||
$jamTrackGetReady.attr('data-current-time', -1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
monitorPlaybackTimeout = setTimeout(monitorRecordingPlayback, 500);
|
||||
}
|
||||
|
|
@ -227,9 +255,9 @@
|
|||
}
|
||||
|
||||
// at the end of the play, the duration sets to 0, as does currentTime. but isPlaying does not reset to
|
||||
logger.debug("currentTimeMs, durationTimeMs", currentTimeMs, durationTimeMs);
|
||||
if(currentTimeMs == 0 && durationTimeMs == 0) {
|
||||
if(isPlaying) {
|
||||
//logger.debug("currentTimeMs, durationTimeMs, mode", currentTimeMs, durationTimeMs, playbackMonitorMode);
|
||||
if(currentTimeMs == 0 && seenActivity) {
|
||||
if(playbackPlaying) {
|
||||
isPlaying = false;
|
||||
durationTimeMs = playbackDurationMs;
|
||||
currentTimeMs = playbackDurationMs;
|
||||
|
|
@ -293,6 +321,7 @@
|
|||
$pauseButton.hide();
|
||||
}
|
||||
|
||||
logger.debug("updating is playing: " + isPlaying)
|
||||
playbackPlaying = isPlaying;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -922,6 +922,19 @@
|
|||
if(!context.JK.guardAgainstBrowser(app)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_START %>') {
|
||||
// short-cut added for private sessions; just get it going
|
||||
beforeMoveStep1(); // this will populate the createSessionSettings structure
|
||||
startSessionClicked(); // and this will create the session
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(optionRequiresMultiplayerProfile()) {
|
||||
if(context.JK.guardAgainstSinglePlayerProfile(app).canPlay == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(optionRequiresMultiplayerProfile()) {
|
||||
|
|
@ -986,7 +999,11 @@
|
|||
}
|
||||
|
||||
function afterShow() {
|
||||
context.JK.HelpBubbleHelper.jamtrackGuidePrivate($screen.find('li[create-type="quick-start"] label'), $screen.find('.content-body-scroller'))
|
||||
}
|
||||
|
||||
function beforeHide() {
|
||||
context.JK.HelpBubbleHelper.clearJamTrackGuide();
|
||||
}
|
||||
|
||||
function toggleDate(dontRebuildDropdowns) {
|
||||
|
|
@ -1293,7 +1310,7 @@
|
|||
instrumentSelector = instrumentSelectorInstance;
|
||||
instrumentRSVP = instrumentRSVPSelectorInstance;
|
||||
|
||||
var screenBindings = {'beforeShow': beforeShow, 'afterShow': afterShow};
|
||||
var screenBindings = {'beforeShow': beforeShow, 'afterShow': afterShow, 'beforeHide' : beforeHide};
|
||||
app.bindScreen('createSession', screenBindings);
|
||||
|
||||
$wizardSteps = $screen.find('.create-session-wizard');
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
var modUtils = context.JK.ModUtils;
|
||||
var logger = context.JK.logger;
|
||||
var self = this;
|
||||
|
||||
var webcamViewer = new context.JK.WebcamViewer()
|
||||
|
||||
var defaultParticipant = {
|
||||
tracks: [{
|
||||
instrument_id: "unknown"
|
||||
|
|
@ -133,16 +134,19 @@
|
|||
var RENDER_SESSION_DELAY = 750; // When I need to render a session, I have to wait a bit for the mixers to be there.
|
||||
|
||||
function beforeShow(data) {
|
||||
sessionId = data.id;
|
||||
if(!sessionId) {
|
||||
window.location = '/client#/home';
|
||||
}
|
||||
promptLeave = true;
|
||||
$myTracksContainer.empty();
|
||||
displayDoneRecording(); // assumption is that you can't join a recording session, so this should be safe
|
||||
sessionId = data.id;
|
||||
if(!sessionId) {
|
||||
window.location = '/client#/home';
|
||||
}
|
||||
promptLeave = true;
|
||||
$myTracksContainer.empty();
|
||||
displayDoneRecording(); // assumption is that you can't join a recording session, so this should be safe
|
||||
|
||||
var shareDialog = new JK.ShareDialog(context.JK.app, sessionId, "session");
|
||||
shareDialog.initialize(context.JK.FacebookHelperInstance);
|
||||
var shareDialog = new JK.ShareDialog(context.JK.app, sessionId, "session");
|
||||
shareDialog.initialize(context.JK.FacebookHelperInstance);
|
||||
if(gon.global.video_available && gon.global.video_available!="none") {
|
||||
webcamViewer.beforeShow()
|
||||
}
|
||||
}
|
||||
|
||||
function beforeDisconnect() {
|
||||
|
|
@ -168,10 +172,13 @@
|
|||
}
|
||||
}
|
||||
checkForCurrentUser();
|
||||
|
||||
context.JK.HelpBubbleHelper.jamtrackGuideSession($screen.find('li.open-a-jamtrack'), $screen)
|
||||
}
|
||||
|
||||
function afterShow(data) {
|
||||
|
||||
$fluidTracks.addClass('showing');
|
||||
$openBackingTrack.removeClass('disabled');
|
||||
|
||||
if(!context.JK.JamServer.connected) {
|
||||
|
|
@ -207,7 +214,6 @@
|
|||
var singlePlayerCheckOK = true;
|
||||
// to know whether we are allowed to be in this session, we have to check if we are the creator when checking against single player functionality
|
||||
if(musicSession.user_id != context.JK.currentUserId) {
|
||||
|
||||
var canPlay = context.JK.guardAgainstSinglePlayerProfile(app, function () {
|
||||
promptLeave = false;
|
||||
});
|
||||
|
|
@ -413,7 +419,7 @@
|
|||
}
|
||||
else {
|
||||
displayDoneRecording();
|
||||
promptUserToSave(data.recordingId);
|
||||
promptUserToSave(data.recordingId, timeline);
|
||||
}
|
||||
|
||||
})
|
||||
|
|
@ -501,6 +507,13 @@
|
|||
|
||||
function beforeHide(data) {
|
||||
|
||||
context.JK.HelpBubbleHelper.clearJamTrackGuide();
|
||||
|
||||
if(gon.global.video_available && gon.global.video_available!="none") {
|
||||
webcamViewer.setVideoOff()
|
||||
}
|
||||
|
||||
$fluidTracks.removeClass('showing');
|
||||
if(screenActive) {
|
||||
// this path is possible if FTUE is invoked on session page, and they cancel
|
||||
sessionModel.leaveCurrentSession()
|
||||
|
|
@ -532,6 +545,7 @@
|
|||
var metronomeMasterMixers = getMetronomeMasterMixers();
|
||||
|
||||
if (metronomeMixer == null && metronomeMasterMixers.length > 0) {
|
||||
logger.debug("monitoring metronome")
|
||||
playbackControls.startMonitor(context.JK.PLAYBACK_MONITOR_MODE.METRONOME)
|
||||
}
|
||||
else if (metronomeMixer != null && metronomeMasterMixers.length == 0) {
|
||||
|
|
@ -542,10 +556,14 @@
|
|||
|
||||
function checkJamTrackTransition(currentSession) {
|
||||
// handle jam tracks
|
||||
if (jamTrack == null && (currentSession && currentSession.jam_track != null)) {
|
||||
|
||||
// if we have a recording open, then don't go into JamTrack monitor mode even if a JamTrack is open
|
||||
if (jamTrack == null && (currentSession && currentSession.jam_track != null && currentSession.claimed_recording == null)) {
|
||||
logger.debug("monitoring jamtrack")
|
||||
playbackControls.startMonitor(context.JK.PLAYBACK_MONITOR_MODE.JAMTRACK);
|
||||
}
|
||||
else if (jamTrack && (currentSession == null || currentSession.jam_track == null)) {
|
||||
else if (jamTrack && (currentSession == null || (currentSession.jam_track == null && currentSession.claimed_recording == null))) {
|
||||
logger.debug("stop monitoring jamtrack")
|
||||
playbackControls.stopMonitor();
|
||||
}
|
||||
jamTrack = currentSession == null ? null : currentSession.jam_track;
|
||||
|
|
@ -554,9 +572,11 @@
|
|||
function checkBackingTrackTransition(currentSession) {
|
||||
// handle backing tracks
|
||||
if (backing_track_path == null && (currentSession && currentSession.backing_track_path != null)) {
|
||||
logger.debug("monitoring backing track")
|
||||
playbackControls.startMonitor();
|
||||
}
|
||||
else if (backing_track_path && (currentSession == null || currentSession.backing_track_path == null)) {
|
||||
logger.debug("stop monitoring backing track")
|
||||
playbackControls.stopMonitor();
|
||||
}
|
||||
backing_track_path = currentSession == null ? null : currentSession.backing_track_path;
|
||||
|
|
@ -568,9 +588,11 @@
|
|||
if (claimedRecording == null && (currentSession && currentSession.claimed_recording != null)) {
|
||||
// this is a 'started with a claimed_recording' transition.
|
||||
// we need to start a timer to watch for the state of the play session
|
||||
logger.debug("monitoring recording")
|
||||
playbackControls.startMonitor();
|
||||
}
|
||||
else if (claimedRecording && (currentSession == null || currentSession.claimed_recording == null)) {
|
||||
logger.debug("stop monitoring recording")
|
||||
playbackControls.stopMonitor();
|
||||
}
|
||||
claimedRecording = currentSession == null ? null : currentSession.claimed_recording;
|
||||
|
|
@ -709,7 +731,7 @@
|
|||
|
||||
function _initDialogs() {
|
||||
configureTrackDialog.initialize();
|
||||
addNewGearDialog.initialize();
|
||||
addNewGearDialog.initialize();
|
||||
}
|
||||
|
||||
// Get the latest list of underlying audio mixer channels, and populates:
|
||||
|
|
@ -1278,13 +1300,15 @@
|
|||
$('.session-recording-name').text(jamTrackName);
|
||||
|
||||
var noCorrespondingTracks = false;
|
||||
$.each(jamTrackMixers, function(index, mixer) {
|
||||
$.each(jamTracks, function(index, jamTrack) {
|
||||
var mixer = null;
|
||||
var preMasteredClass = "";
|
||||
// find the track or tracks that correspond to the mixer
|
||||
var correspondingTracks = []
|
||||
$.each(jamTracks, function(i, jamTrack) {
|
||||
if(mixer.id == jamTrack.id) {
|
||||
$.each(jamTrackMixers, function(i, matchMixer) {
|
||||
if(matchMixer.id == jamTrack.id) {
|
||||
correspondingTracks.push(jamTrack);
|
||||
mixer = matchMixer;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -1692,9 +1716,11 @@
|
|||
// special case; if it's me and I have no tracks, show info about this sort of use of the app
|
||||
if (myTrack && participant.tracks.length == 0) {
|
||||
$tracksHolder.addClass('no-local-tracks')
|
||||
$liveTracksContainer.addClass('no-local-tracks')
|
||||
}
|
||||
else {
|
||||
$tracksHolder.removeClass('no-local-tracks')
|
||||
$liveTracksContainer.removeClass('no-local-tracks')
|
||||
}
|
||||
|
||||
// loop through all tracks for each participant
|
||||
|
|
@ -2003,16 +2029,13 @@
|
|||
var otherAudioWidthPct = Math.floor(100 * otherAudioWidth/totalWidth);
|
||||
var liveTrackWidthPct = Math.ceil(100 * liveTrackWidth/totalWidth);
|
||||
|
||||
logger.debug("resizeFluid: ", minimumLiveTrackWidth, otherAudioWidth, otherAudioWidthPct, liveTrackWidthPct, liveTrackWidthPct)
|
||||
|
||||
//logger.debug("resizeFluid: ", minimumLiveTrackWidth, otherAudioWidth, otherAudioWidthPct, liveTrackWidthPct, liveTrackWidthPct)
|
||||
$audioTracks.css('width', otherAudioWidthPct + '%');
|
||||
$liveTracks.css('width', liveTrackWidthPct + '%');
|
||||
}
|
||||
|
||||
function _addRecordingTrack(trackData, mixer, oppositeMixer) {
|
||||
|
||||
otherAudioFilled();
|
||||
|
||||
$('.session-recordings .recording-controls').show();
|
||||
|
||||
var parentSelector = '#session-recordedtracks-container';
|
||||
|
|
@ -2472,6 +2495,18 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
function sessionWebCam(e) {
|
||||
e.preventDefault();
|
||||
if(webcamViewer.isVideoShared()) {
|
||||
$('#session-webcam').removeClass("selected")
|
||||
} else {
|
||||
$('#session-webcam').addClass("selected")
|
||||
}
|
||||
|
||||
webcamViewer.toggleWebcam()
|
||||
return false;
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/2604450/how-to-create-a-jquery-clock-timer
|
||||
function updateRecordingTimer() {
|
||||
|
||||
|
|
@ -2511,11 +2546,12 @@
|
|||
}
|
||||
|
||||
function displayStartedRecording() {
|
||||
// the commented out code reflects dropping the counter as your recording to save space
|
||||
startTimeDate = new Date;
|
||||
$recordingTimer = $("<span id='recording-timer'>(0:00)</span>");
|
||||
var $recordingStatus = $('<span></span>').append("<span>Stop Recording</span>").append($recordingTimer);
|
||||
//$recordingTimer = $("<span id='recording-timer'>(0:00)</span>");
|
||||
var $recordingStatus = $('<span></span>').append("<span>Stop Recording</span>")//.append($recordingTimer);
|
||||
$('#recording-status').html( $recordingStatus );
|
||||
recordingTimerInterval = setInterval(updateRecordingTimer, 1000);
|
||||
//recordingTimerInterval = setInterval(updateRecordingTimer, 1000);
|
||||
}
|
||||
|
||||
function displayStoppingRecording(data) {
|
||||
|
|
@ -2542,7 +2578,7 @@
|
|||
$recordingTimer = null;
|
||||
|
||||
$('#recording-start-stop').removeClass('currently-recording');
|
||||
$('#recording-status').text("Make a Recording");
|
||||
$('#recording-status').text("Make Recording");
|
||||
}
|
||||
|
||||
function lockControlsforJamTrackRecording() {
|
||||
|
|
@ -2573,9 +2609,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
function promptUserToSave(recordingId) {
|
||||
function promptUserToSave(recordingId, timeline) {
|
||||
rest.getRecording( {id: recordingId} )
|
||||
.done(function(recording) {
|
||||
if(timeline) {
|
||||
recording.timeline = timeline.global
|
||||
}
|
||||
recordingFinishedDialog.setRecording(recording);
|
||||
app.layout.showDialog('recordingFinished').one(EVENTS.DIALOG_CLOSED, function(e, data) {
|
||||
if(data.result && data.result.keep){
|
||||
|
|
@ -2587,7 +2626,7 @@
|
|||
}
|
||||
|
||||
function checkPendingMetronome() {
|
||||
logger.debug("checkPendingMetronome", sessionModel.isMetronomeOpen(), getMetronomeMasterMixers().length)
|
||||
//logger.debug("checkPendingMetronome", sessionModel.isMetronomeOpen(), getMetronomeMasterMixers().length)
|
||||
if(sessionModel.isMetronomeOpen() && getMetronomeMasterMixers().length == 0) {
|
||||
var pendingMetronome = $($templatePendingMetronome.html())
|
||||
|
||||
|
|
@ -2695,7 +2734,7 @@
|
|||
text: "Unable to open your JamTrack. Please contact support@jamkazam.com"
|
||||
}, null, true);
|
||||
} else {
|
||||
rest.playJamTrack(jamTrack.id);
|
||||
playJamTrack(jamTrack.id);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -2714,8 +2753,21 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
function openBackingTrackFile(e) {
|
||||
function playJamTrack(jamTrackId) {
|
||||
var participantCnt=sessionModel.participants().length
|
||||
rest.playJamTrack(jamTrackId)
|
||||
.done(function() {
|
||||
app.refreshUser();
|
||||
})
|
||||
context.stats.write('web.jamtrack.open', {
|
||||
value: 1,
|
||||
session_size: participantCnt,
|
||||
user_id: context.JK.currentUserId,
|
||||
user_name: context.JK.currentUserName
|
||||
})
|
||||
}// function
|
||||
|
||||
function openBackingTrackFile(e) {
|
||||
// just ignore the click if they are currently recording for now
|
||||
if(sessionModel.recordingModel.isRecording()) {
|
||||
app.notify({
|
||||
|
|
@ -2726,6 +2778,12 @@
|
|||
return false;
|
||||
} else {
|
||||
context.jamClient.openBackingTrackFile(sessionModel.backing_track)
|
||||
context.stats.write('web.backingtrack.open', {
|
||||
value: 1,
|
||||
session_size: participantCnt,
|
||||
user_id: context.JK.currentUserId,
|
||||
user_name: context.JK.currentUserName
|
||||
})
|
||||
//context.JK.CurrentSessionModel.refreshCurrentSession(true);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -2852,6 +2910,12 @@
|
|||
}
|
||||
|
||||
function closeBackingTrack() {
|
||||
|
||||
if (sessionModel.recordingModel.isRecording()) {
|
||||
logger.debug("can't close backing track while recording")
|
||||
return false;
|
||||
}
|
||||
|
||||
rest.closeBackingTrack({id: sessionModel.id()})
|
||||
.done(function() {
|
||||
//sessionModel.refreshCurrentSession(true);
|
||||
|
|
@ -2872,9 +2936,13 @@
|
|||
}
|
||||
|
||||
function closeJamTrack() {
|
||||
|
||||
logger.debug("closing recording");
|
||||
|
||||
if (sessionModel.recordingModel.isRecording()) {
|
||||
logger.debug("can't close jamtrack while recording")
|
||||
return false;
|
||||
}
|
||||
|
||||
if(downloadJamTrack) {
|
||||
logger.debug("closing DownloadJamTrack widget")
|
||||
downloadJamTrack.root.remove();
|
||||
|
|
@ -2942,13 +3010,31 @@
|
|||
}
|
||||
|
||||
function onPause(e, data) {
|
||||
logger.debug("calling jamClient.SessionStopPlay. endReached:", data.endReached);
|
||||
logger.debug("calling jamClient.SessionPausePlay. endReached:", data.endReached);
|
||||
|
||||
// if a JamTrack is open, and the user hits 'pause' or 'stop', we need to automatically stop the recording
|
||||
if(sessionModel.jamTracks() && sessionModel.recordingModel.isRecording()) {
|
||||
startStopRecording();
|
||||
}
|
||||
|
||||
if(!data.endReached) {
|
||||
context.jamClient.SessionStopPlay();
|
||||
context.jamClient.SessionPausePlay();
|
||||
}
|
||||
}
|
||||
|
||||
function onStop(e, data) {
|
||||
logger.debug("calling jamClient.SessionStopPlay. endReached:", data.endReached);
|
||||
|
||||
// if a JamTrack is open, and the user hits 'pause' or 'stop', we need to automatically stop the recording
|
||||
if(sessionModel.jamTracks() && sessionModel.recordingModel.isRecording()) {
|
||||
startStopRecording();
|
||||
}
|
||||
|
||||
if(!data.endReached) {
|
||||
context.jamClient.SessionStopPlay();
|
||||
}
|
||||
}
|
||||
|
||||
function onPlay(e, data) {
|
||||
logger.debug("calling jamClient.SessionStartPlay");
|
||||
context.jamClient.SessionStartPlay(data.playbackMode);
|
||||
|
|
@ -3045,7 +3131,6 @@
|
|||
var mode = data.playbackMode; // will be either 'self' or 'cricket'
|
||||
|
||||
logger.debug("setting metronome playback mode: ", mode)
|
||||
|
||||
var isCricket = mode == 'cricket';
|
||||
context.jamClient.setMetronomeCricketTestState(isCricket);
|
||||
}
|
||||
|
|
@ -3078,6 +3163,7 @@
|
|||
function events() {
|
||||
$('#session-leave').on('click', sessionLeave);
|
||||
$('#session-resync').on('click', sessionResync);
|
||||
$('#session-webcam').on('click', sessionWebCam);
|
||||
$('#session-contents').on("click", '[action="delete"]', deleteSession);
|
||||
$tracksHolder.on('click', 'div[control="mute"]', toggleMute);
|
||||
$('#recording-start-stop').on('click', startStopRecording);
|
||||
|
|
@ -3109,6 +3195,7 @@
|
|||
$closePlaybackRecording.on('click', closeOpenMedia);
|
||||
$(playbackControls)
|
||||
.on('pause', onPause)
|
||||
.on('stop', onStop)
|
||||
.on('play', onPlay)
|
||||
.on('change-position', onChangePlayPosition);
|
||||
$(friendInput).focus(function() { $(this).val(''); })
|
||||
|
|
@ -3161,7 +3248,10 @@
|
|||
$fluidTracks = $screen.find('.session-fluidtracks');
|
||||
$voiceChat = $screen.find('#voice-chat');
|
||||
$tracksHolder = $screen.find('#tracks')
|
||||
|
||||
if(gon.global.video_available && gon.global.video_available!="none") {
|
||||
webcamViewer.init($(".webcam-container"))
|
||||
webcamViewer.setVideoOff()
|
||||
}
|
||||
events();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@
|
|||
// see if we already have tracks; if so, we need to run with these
|
||||
var inputTracks = context.JK.TrackHelpers.getUserTracks(context.jamClient);
|
||||
|
||||
logger.debug("isNoInputProfile", gearUtils.isNoInputProfile())
|
||||
if(inputTracks.length > 0 || gearUtils.isNoInputProfile() ) {
|
||||
logger.debug("on page enter, tracks are already available")
|
||||
sessionPageEnterDeferred.resolve(inputTracks);
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@
|
|||
var $content = null;
|
||||
|
||||
function beforeShow(data) {
|
||||
loadShoppingCarts();
|
||||
|
||||
}
|
||||
|
||||
function afterShow(data) {
|
||||
loadShoppingCarts();
|
||||
}
|
||||
|
||||
function afterHide() {
|
||||
|
|
@ -29,18 +30,22 @@
|
|||
function proceedCheckout(e) {
|
||||
e.preventDefault();
|
||||
|
||||
logger.debug("proceedCheckout")
|
||||
if (!context.JK.currentUserId) {
|
||||
logger.debug("proceeding to signin screen because there is no user")
|
||||
window.location = '/client#/checkoutSignin';
|
||||
}
|
||||
else {
|
||||
app.user().done(function(user) {
|
||||
if(user.has_recurly_account && user.reuse_card) {
|
||||
window.location = '/client#/checkoutOrder';
|
||||
}
|
||||
else {
|
||||
window.location = '/client#/checkoutPayment';
|
||||
}
|
||||
})
|
||||
var user = app.currentUser();
|
||||
|
||||
if(user.has_recurly_account && user.reuse_card) {
|
||||
logger.debug("proceeding to checkout order screen because we have card info already")
|
||||
window.location = '/client#/checkoutOrder';
|
||||
}
|
||||
else {
|
||||
logger.debug("proceeding to checkout payment screen because we do not have card info")
|
||||
window.location = '/client#/checkoutPayment';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -55,6 +60,7 @@
|
|||
.fail(app.ajaxError);
|
||||
}
|
||||
|
||||
|
||||
function clearContent() {
|
||||
$content.empty();
|
||||
}
|
||||
|
|
@ -69,11 +75,24 @@
|
|||
|
||||
function renderShoppingCarts(carts) {
|
||||
var data = {};
|
||||
var latest_cart = carts[carts.length - 1];
|
||||
|
||||
if(carts.length > 0) {
|
||||
var latest_cart = carts[0];
|
||||
}
|
||||
|
||||
var $latestCartHtml = "";
|
||||
|
||||
var any_in_us = false
|
||||
context._.each(carts, function(cart) {
|
||||
if(cart.product_info.sales_region == 'United States') {
|
||||
any_in_us = true
|
||||
}
|
||||
})
|
||||
|
||||
if (latest_cart) {
|
||||
|
||||
latest_cart.any_in_us = any_in_us
|
||||
|
||||
$latestCartHtml = $(
|
||||
context._.template(
|
||||
$('#template-shopping-cart-header').html(),
|
||||
|
|
@ -85,9 +104,9 @@
|
|||
|
||||
var sub_total = 0;
|
||||
$.each(carts, function(index, cart) {
|
||||
sub_total += parseFloat(cart.product_info.price) * parseFloat(cart.quantity);
|
||||
sub_total += parseFloat(cart.product_info.real_price);
|
||||
});
|
||||
data.sub_total = sub_total.toFixed(2);
|
||||
data.sub_total = sub_total;
|
||||
|
||||
data.carts = carts;
|
||||
var $cartsHtml = $(
|
||||
|
|
|
|||
|
|
@ -8,13 +8,6 @@
|
|||
if(musician) {
|
||||
context.JK.Downloads.listClients(true);
|
||||
}
|
||||
|
||||
if(registrationType) {
|
||||
$(function() {
|
||||
// ga() object isn't ready until the page is loaded
|
||||
context.JK.GA.trackRegister(musician, registrationType);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
context.congratulations = congratulations;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
else {
|
||||
$individualizedHeader.removeClass('hidden')
|
||||
$jamtrack_name.text(jam_track.name);
|
||||
$jamTracksButton.attr('href', '/client?artist=' + jam_track.original_artist + '#/jamtrack')
|
||||
$jamTracksButton.attr('href', '/client?artist=' + jam_track.original_artist + '#/jamtrackBrowse')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
$previews.append($element);
|
||||
|
||||
new context.JK.JamTrackPreview(app, $element, jam_track, track, {master_shows_duration: false})
|
||||
new context.JK.JamTrackPreview(app, $element, jam_track, track, {master_shows_duration: false, color:'black'})
|
||||
})
|
||||
|
||||
$previews.append('<br clear = "all" />')
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
logger.debug("jam_track", jam_track)
|
||||
|
||||
$jamTrackBandInfo.text(jam_track.band_jam_track_count + ' ' + jam_track.original_artist);
|
||||
$jamTracksButton.attr('href', '/client?artist=' + jam_track.original_artist + '#/jamtrack')
|
||||
$jamTracksButton.attr('href', '/client?artist=' + jam_track.original_artist + '#/jamtrackBrowse')
|
||||
|
||||
if(jam_track.band_jam_track_count == 1) {
|
||||
$jamTrackNoun.text('JamTrack')
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
$previews.append($element);
|
||||
|
||||
new context.JK.JamTrackPreview(app, $element, jam_track, track, {master_shows_duration: false})
|
||||
new context.JK.JamTrackPreview(app, $element, jam_track, track, {master_shows_duration: false, color:'black'})
|
||||
})
|
||||
|
||||
$previews.append('<br clear = "all" />')
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@
|
|||
//= require subscription_utils
|
||||
//= require ui_helper
|
||||
//= require custom_controls
|
||||
//= require ga
|
||||
//= require jam_rest
|
||||
//= require ga
|
||||
//= require session_utils
|
||||
//= require recording_utils
|
||||
//= require helpBubbleHelper
|
||||
|
|
|
|||