merge conflict from feature/new_session (VRFS-3283)
|
|
@ -58,7 +58,7 @@ gem 'resque'
|
||||||
gem 'resque-retry'
|
gem 'resque-retry'
|
||||||
gem 'resque-failed-job-mailer'
|
gem 'resque-failed-job-mailer'
|
||||||
gem 'resque-lonely_job', '~> 1.0.0'
|
gem 'resque-lonely_job', '~> 1.0.0'
|
||||||
gem 'eventmachine', '1.0.3'
|
gem 'eventmachine', '1.0.4'
|
||||||
gem 'amqp', '0.9.8'
|
gem 'amqp', '0.9.8'
|
||||||
gem 'logging-rails', :require => 'logging/rails'
|
gem 'logging-rails', :require => 'logging/rails'
|
||||||
gem 'pg_migrate'
|
gem 'pg_migrate'
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ EOF
|
||||||
#bundle install --path vendor/bundle --local
|
#bundle install --path vendor/bundle --local
|
||||||
# prepare production acssets
|
# prepare production acssets
|
||||||
rm -rf $DIR/public/assets
|
rm -rf $DIR/public/assets
|
||||||
bundle exec rake assets:precompile RAILS_ENV=production
|
#bundle exec rake assets:precompile RAILS_ENV=production
|
||||||
|
|
||||||
# create debian using fpm
|
# create debian using fpm
|
||||||
bundle exec fpm -s dir -t deb -p target/deb/jam-admin_0.1.${BUILD_NUMBER}_${ARCH}.deb -n "jam-admin" -v "0.1.$BUILD_NUMBER" --prefix /var/lib/jam-admin --after-install $DIR/script/package/post-install.sh --before-install $DIR/script/package/pre-install.sh --before-remove $DIR/script/package/pre-uninstall.sh --after-remove $DIR/script/package/post-uninstall.sh Gemfile .bundle config Rakefile script config.ru lib public vendor app BUILD_NUMBER
|
bundle exec fpm -s dir -t deb -p target/deb/jam-admin_0.1.${BUILD_NUMBER}_${ARCH}.deb -n "jam-admin" -v "0.1.$BUILD_NUMBER" --prefix /var/lib/jam-admin --after-install $DIR/script/package/post-install.sh --before-install $DIR/script/package/pre-install.sh --before-remove $DIR/script/package/pre-uninstall.sh --after-remove $DIR/script/package/post-uninstall.sh Gemfile .bundle config Rakefile script config.ru lib public vendor app BUILD_NUMBER
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
ActionMailer::Base.raise_delivery_errors = true
|
ActionMailer::Base.raise_delivery_errors = true
|
||||||
ActionMailer::Base.delivery_method = Rails.env == "test" ? :test : :smtp
|
begin
|
||||||
|
ActionMailer::Base.delivery_method = Rails.env == "test" ? :test : :smtp
|
||||||
|
rescue
|
||||||
|
# this can happen on the build server when it's compiling assets and doesn't have the 'jam' database
|
||||||
|
ActionMailer::Base.delivery_method = :test
|
||||||
|
end
|
||||||
ActionMailer::Base.smtp_settings = {
|
ActionMailer::Base.smtp_settings = {
|
||||||
:address => Rails.application.config.email_smtp_address,
|
:address => Rails.application.config.email_smtp_address,
|
||||||
:port => Rails.application.config.email_smtp_port,
|
:port => Rails.application.config.email_smtp_port,
|
||||||
|
|
|
||||||
5
build
|
|
@ -62,8 +62,9 @@ popd > /dev/null
|
||||||
|
|
||||||
if [ ! -z "$PACKAGE" ]; then
|
if [ ! -z "$PACKAGE" ]; then
|
||||||
|
|
||||||
DEB_SERVER=http://localhost:9010/apt-`uname -p`
|
source /etc/lsb-release
|
||||||
GEM_SERVER=http://localhost:9000/gems
|
DEB_SERVER=https://int.jamkazam.com:9010/apt-`uname -p`/$DISTRIB_CODENAME
|
||||||
|
GEM_SERVER=http://localhost:9000/gems
|
||||||
|
|
||||||
# if still going, then push all debs up
|
# if still going, then push all debs up
|
||||||
if [[ "$GIT_BRANCH" == *develop* || "$GIT_BRANCH" == *master* || "$GIT_BRANCH" == *release* || "$GIT_BRANCH" == *feature* || "$GIT_BRANCH" == *hotfix* ]]; then
|
if [[ "$GIT_BRANCH" == *develop* || "$GIT_BRANCH" == *master* || "$GIT_BRANCH" == *release* || "$GIT_BRANCH" == *feature* || "$GIT_BRANCH" == *hotfix* ]]; then
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
GEM_SERVER=http://localhost:9000/gems
|
GEM_SERVER=https://int.jamkazam.com:9000/gems
|
||||||
DEB_SERVER=http://localhost:9010/apt-`uname -p`
|
DEB_SERVER=https://int.jamkazam.com:9010/apt-`uname -p`
|
||||||
|
|
||||||
echo "starting build..."
|
echo "starting build..."
|
||||||
./build
|
./build
|
||||||
|
|
|
||||||
15
db/manifest
|
|
@ -276,12 +276,6 @@ jam_track_duration.sql
|
||||||
sales.sql
|
sales.sql
|
||||||
show_whats_next_count.sql
|
show_whats_next_count.sql
|
||||||
recurly_adjustments.sql
|
recurly_adjustments.sql
|
||||||
alter_type_columns.sql
|
|
||||||
user_presences_rename.sql
|
|
||||||
add_genre_type.sql
|
|
||||||
add_description_to_perf_samples.sql
|
|
||||||
alter_genre_player_unique_constraint.sql
|
|
||||||
musician_search.sql
|
|
||||||
signup_hints.sql
|
signup_hints.sql
|
||||||
packaging_notices.sql
|
packaging_notices.sql
|
||||||
first_played_jamtrack_at.sql
|
first_played_jamtrack_at.sql
|
||||||
|
|
@ -292,7 +286,14 @@ signing.sql
|
||||||
optimized_redeemption.sql
|
optimized_redeemption.sql
|
||||||
optimized_redemption_warn_mode.sql
|
optimized_redemption_warn_mode.sql
|
||||||
affiliate_partners2.sql
|
affiliate_partners2.sql
|
||||||
enhance_band_profile.sql
|
|
||||||
broadcast_notifications.sql
|
broadcast_notifications.sql
|
||||||
broadcast_notifications_fk.sql
|
broadcast_notifications_fk.sql
|
||||||
calendar.sql
|
calendar.sql
|
||||||
|
alter_type_columns.sql
|
||||||
|
user_presences_rename.sql
|
||||||
|
add_genre_type.sql
|
||||||
|
add_description_to_perf_samples.sql
|
||||||
|
alter_genre_player_unique_constraint.sql
|
||||||
|
musician_search.sql
|
||||||
|
enhance_band_profile.sql
|
||||||
|
alter_band_profile_rate_defaults.sql
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE bands ALTER COLUMN hourly_rate SET DEFAULT NULL;
|
||||||
|
ALTER TABLE bands ALTER COLUMN gig_minimum SET DEFAULT NULL;
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE users ALTER paid_sessions_hourly_rate TYPE integer;
|
||||||
|
ALTER TABLE users ALTER paid_sessions_daily_rate TYPE integer;
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
GEM_SERVER=http://localhost:9000/gems
|
GEM_SERVER=https://int.jamkazam.com:9000/gems
|
||||||
|
|
||||||
echo "starting build..."
|
echo "starting build..."
|
||||||
./build
|
./build
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ gem "activerecord-import", "~> 0.4.1"
|
||||||
gem 'uuidtools', '2.1.2'
|
gem 'uuidtools', '2.1.2'
|
||||||
gem 'bcrypt-ruby', '3.0.1'
|
gem 'bcrypt-ruby', '3.0.1'
|
||||||
gem 'ruby-protocol-buffers', '1.2.2'
|
gem 'ruby-protocol-buffers', '1.2.2'
|
||||||
gem 'eventmachine', '1.0.3'
|
gem 'eventmachine', '1.0.4'
|
||||||
gem 'amqp', '1.0.2'
|
gem 'amqp', '1.0.2'
|
||||||
gem 'will_paginate'
|
gem 'will_paginate'
|
||||||
gem 'actionmailer', '3.2.13'
|
gem 'actionmailer', '3.2.13'
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
GEM_SERVER=http://localhost:9000/gems
|
GEM_SERVER=https://int.jamkazam.com:9000/gems
|
||||||
|
|
||||||
echo "starting build..."
|
echo "starting build..."
|
||||||
./build
|
./build
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ module JamRuby
|
||||||
validate :validate_photo_info
|
validate :validate_photo_info
|
||||||
validate :require_at_least_one_genre, :unless => :skip_genre_validation
|
validate :require_at_least_one_genre, :unless => :skip_genre_validation
|
||||||
validate :limit_max_genres
|
validate :limit_max_genres
|
||||||
|
validates_numericality_of :hourly_rate, greater_than:0, less_than:100000, :allow_nil => true
|
||||||
|
validates_numericality_of :gig_minimum, greater_than:0, less_than:200000, :allow_nil => true
|
||||||
|
|
||||||
before_save :check_lat_lng
|
before_save :check_lat_lng
|
||||||
before_save :check_website_url
|
before_save :check_website_url
|
||||||
|
|
@ -192,6 +194,17 @@ module JamRuby
|
||||||
band.photo_url = params[:photo_url] if params.has_key?(:photo_url)
|
band.photo_url = params[:photo_url] if params.has_key?(:photo_url)
|
||||||
band.logo_url = params[:logo_url] if params.has_key?(:logo_url)
|
band.logo_url = params[:logo_url] if params.has_key?(:logo_url)
|
||||||
|
|
||||||
|
band.paid_gigs = params[:paid_gigs] if params.has_key?(:paid_gigs)
|
||||||
|
band.free_gigs = params[:free_gigs] if params.has_key?(:free_gigs)
|
||||||
|
band.hourly_rate = (params.has_key?(:hourly_rate) && params[:hourly_rate].to_i > 0) ? params[:hourly_rate] : nil
|
||||||
|
band.gig_minimum = (params.has_key?(:gig_minimum) && params[:hourly_rate].to_i > 0) ? params[:gig_minimum] : nil
|
||||||
|
band.add_new_members = params[:add_new_members] if params.has_key?(:add_new_members)
|
||||||
|
band.touring_option = params[:touring_option] if params.has_key?(:touring_option)
|
||||||
|
band.band_type = params[:band_type] if params.has_key?(:band_type)
|
||||||
|
band.band_status = params[:band_status] if params.has_key?(:band_status)
|
||||||
|
band.concert_count = params[:concert_count] if params.has_key?(:concert_count)
|
||||||
|
band.play_commitment = params[:play_commitment] if params.has_key?(:play_commitment)
|
||||||
|
|
||||||
if params.has_key?(:genres) && params[:genres]
|
if params.has_key?(:genres) && params[:genres]
|
||||||
# loop through each genre in the array and save to the db
|
# loop through each genre in the array and save to the db
|
||||||
genres = []
|
genres = []
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ module JamRuby
|
||||||
ms
|
ms
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# XXX SQL INJECTION
|
||||||
def _genres(rel)
|
def _genres(rel)
|
||||||
gids = json[KEY_GENRES]
|
gids = json[KEY_GENRES]
|
||||||
unless gids.blank?
|
unless gids.blank?
|
||||||
|
|
@ -135,11 +136,12 @@ module JamRuby
|
||||||
rel
|
rel
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# XXX SQL INJECTION
|
||||||
def _instruments(rel)
|
def _instruments(rel)
|
||||||
unless (instruments = json['instruments']).blank?
|
unless (instruments = json['instruments']).blank?
|
||||||
instsql = "SELECT player_id FROM musicians_instruments WHERE (("
|
instsql = "SELECT player_id FROM musicians_instruments WHERE (("
|
||||||
instsql += instruments.collect do |inst|
|
instsql += instruments.collect do |inst|
|
||||||
"instrument_id = '#{inst['instrument_id']}' AND proficiency_level = #{inst['proficiency_level']}"
|
"instrument_id = '#{inst['id']}' AND proficiency_level = #{inst['level']}"
|
||||||
end.join(") OR (")
|
end.join(") OR (")
|
||||||
instsql += "))"
|
instsql += "))"
|
||||||
rel = rel.where("users.id IN (#{instsql})")
|
rel = rel.where("users.id IN (#{instsql})")
|
||||||
|
|
@ -357,47 +359,54 @@ module JamRuby
|
||||||
return 'Click search button to look for musicians with similar interests, skill levels, etc.'
|
return 'Click search button to look for musicians with similar interests, skill levels, etc.'
|
||||||
end
|
end
|
||||||
jj = self.json
|
jj = self.json
|
||||||
str = 'Current Search: '
|
str = ''
|
||||||
str += "Sort = #{SORT_ORDERS[json_value(MusicianSearch::KEY_SORT_ORDER)]}"
|
if 0 < (val = jj[KEY_INSTRUMENTS]).length
|
||||||
|
str += ", Instruments = "
|
||||||
|
instr_ids = val.collect { |stored_instrument| stored_instrument['id'] }
|
||||||
|
instrs = Instrument.where(["id IN (?)", instr_ids]).order(:description)
|
||||||
|
instrs.each_with_index do |ii, idx|
|
||||||
|
proficiency = val.detect { |stored_instrument| stored_instrument['id'] == ii.id }['level']
|
||||||
|
str += "#{ii.description} / #{INSTRUMENT_PROFICIENCY[proficiency.to_i]}"
|
||||||
|
str += ', ' unless idx==(instrs.length-1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if (val = jj[KEY_INTERESTS]) != INTEREST_VALS[0]
|
if (val = jj[KEY_INTERESTS]) != INTEREST_VALS[0]
|
||||||
str += "; Interest = #{INTERESTS[val]}"
|
str += ", Interest = #{INTERESTS[val]}"
|
||||||
end
|
end
|
||||||
if (val = jj[KEY_SKILL].to_i) != SKILL_VALS[0]
|
if (val = jj[KEY_SKILL].to_i) != SKILL_VALS[0]
|
||||||
str += "; Skill = #{SKILL_LEVELS[val]}"
|
str += ", Skill = #{SKILL_LEVELS[val]}"
|
||||||
end
|
end
|
||||||
if (val = jj[KEY_STUDIOS].to_i) != STUDIO_COUNTS[0]
|
if (val = jj[KEY_STUDIOS].to_i) != STUDIO_COUNTS[0]
|
||||||
str += "; Studio Sessions = #{STUDIOS_LABELS[val]}"
|
str += ", Studio Sessions = #{STUDIOS_LABELS[val]}"
|
||||||
end
|
end
|
||||||
if (val = jj[KEY_GIGS].to_i) != GIG_COUNTS[0]
|
if (val = jj[KEY_GIGS].to_i) != GIG_COUNTS[0]
|
||||||
str += "; Concert Gigs = #{GIG_LABELS[val]}"
|
str += ", Concert Gigs = #{GIG_LABELS[val]}"
|
||||||
end
|
end
|
||||||
val = jj[KEY_AGES].map(&:to_i)
|
val = jj[KEY_AGES].map(&:to_i)
|
||||||
val.sort!
|
val.sort!
|
||||||
if !val.blank?
|
if !val.blank?
|
||||||
str += "; Ages = "
|
str += ", Ages = "
|
||||||
val.each_with_index do |vv, idx|
|
val.each_with_index do |vv, idx|
|
||||||
str += "#{AGES[vv]}"
|
str += "#{AGES[vv]}"
|
||||||
str += ', ' unless idx==(val.length-1)
|
str += ', ' unless idx==(val.length-1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if 0 < (val = jj[KEY_GENRES]).length
|
if 0 < (val = jj[KEY_GENRES]).length
|
||||||
str += "; Genres = "
|
str += ", Genres = "
|
||||||
genres = Genre.where(["id IN (?)", val]).order('description').pluck(:description)
|
genres = Genre.where(["id IN (?)", val]).order('description').pluck(:description)
|
||||||
genres.each_with_index do |gg, idx|
|
genres.each_with_index do |gg, idx|
|
||||||
str += "#{gg}"
|
str += "#{gg}"
|
||||||
str += ', ' unless idx==(genres.length-1)
|
str += ', ' unless idx==(genres.length-1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if 0 < (val = jj[KEY_INSTRUMENTS]).length
|
str += ", Sort = #{SORT_ORDERS[json_value(MusicianSearch::KEY_SORT_ORDER)]}"
|
||||||
str += "; Instruments = "
|
|
||||||
instr_ids = val.collect { |vv| vv['instrument_id'] }
|
if str.start_with?(', ')
|
||||||
instrs = Instrument.where(["id IN (?)", instr_ids]).order(:description)
|
# trim off any leading ,
|
||||||
instrs.each_with_index do |ii, idx|
|
str = str[2..-1]
|
||||||
proficiency = val.detect { |vv| vv['instrument_id'] == ii.id }['proficiency_level']
|
|
||||||
str += "#{ii.description} (#{INSTRUMENT_PROFICIENCY[proficiency.to_i]})"
|
|
||||||
str += ', ' unless idx==(instrs.length-1)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
str = 'Current Search: ' + str
|
||||||
str
|
str
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,11 @@ module JamRuby
|
||||||
validates_numericality_of :last_jam_audio_latency, greater_than:MINIMUM_AUDIO_LATENCY, less_than:MAXIMUM_AUDIO_LATENCY, :allow_nil => true
|
validates_numericality_of :last_jam_audio_latency, greater_than:MINIMUM_AUDIO_LATENCY, less_than:MAXIMUM_AUDIO_LATENCY, :allow_nil => true
|
||||||
validates :last_jam_updated_reason, :inclusion => {:in => [nil, JAM_REASON_REGISTRATION, JAM_REASON_NETWORK_TEST, JAM_REASON_FTUE, JAM_REASON_JOIN, JAM_REASON_IMPORT, JAM_REASON_LOGIN] }
|
validates :last_jam_updated_reason, :inclusion => {:in => [nil, JAM_REASON_REGISTRATION, JAM_REASON_NETWORK_TEST, JAM_REASON_FTUE, JAM_REASON_JOIN, JAM_REASON_IMPORT, JAM_REASON_LOGIN] }
|
||||||
|
|
||||||
|
# stored in cents
|
||||||
|
validates_numericality_of :paid_sessions_hourly_rate, greater_than:0, less_than:200000, :allow_nil => true
|
||||||
|
# stored in cents
|
||||||
|
validates_numericality_of :paid_sessions_daily_rate, greater_than:0, less_than:5000000, :allow_nil => true
|
||||||
|
|
||||||
# custom validators
|
# custom validators
|
||||||
validate :validate_musician_instruments
|
validate :validate_musician_instruments
|
||||||
validate :validate_current_password
|
validate :validate_current_password
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,40 @@ describe Band do
|
||||||
band.country.should == band_params[:country]
|
band.country.should == band_params[:country]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "saves current interests" do
|
||||||
|
parms = band_params
|
||||||
|
parms[:paid_gigs]=true
|
||||||
|
parms[:free_gigs]=false
|
||||||
|
parms[:hourly_rate]=5000
|
||||||
|
parms[:gig_minimum]=30000
|
||||||
|
parms[:add_new_members]=true
|
||||||
|
parms[:touring_option]=false
|
||||||
|
parms[:band_type]="virtual"
|
||||||
|
parms[:band_status]="amateur"
|
||||||
|
parms[:concert_count]=3
|
||||||
|
|
||||||
|
band = Band.save(user, parms)
|
||||||
|
band.errors.any?.should be_false
|
||||||
|
|
||||||
|
band.paid_gigs.should == true
|
||||||
|
band.free_gigs.should == false
|
||||||
|
band.hourly_rate.should == 5000
|
||||||
|
parms[:gig_minimum]=30000
|
||||||
|
band.add_new_members.should == true
|
||||||
|
band.touring_option.should == false
|
||||||
|
band.band_type.should == "virtual"
|
||||||
|
band.band_status.should == "amateur"
|
||||||
|
band.concert_count.should == 3
|
||||||
|
|
||||||
|
parms[:hourly_rate]="foobar"
|
||||||
|
parms[:gig_minimum]="barfoo"
|
||||||
|
band=Band.save(user, parms)
|
||||||
|
band.errors.any?.should be_true
|
||||||
|
band.errors[:hourly_rate].should == ["is not a number"]
|
||||||
|
band.errors[:gig_minimum].should == ["is not a number"]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
it "ensures user is a musician" do
|
it "ensures user is a musician" do
|
||||||
expect{ Band.save(fan, band_params) }.to raise_error("must be a musician")
|
expect{ Band.save(fan, band_params) }.to raise_error("must be a musician")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,10 @@ def app_config
|
||||||
1
|
1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def google_public_server_key
|
||||||
|
"AIzaSyCPTPq5PEcl4XWcm7NZ2IGClZlbsiE8JNo"
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def audiomixer_workspace_path
|
def audiomixer_workspace_path
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ gem 'pg', '0.17.1'
|
||||||
gem 'compass-rails', '1.1.3' # 1.1.4 throws an exception on startup about !initialize on nil
|
gem 'compass-rails', '1.1.3' # 1.1.4 throws an exception on startup about !initialize on nil
|
||||||
gem 'rabl', '0.11.0' # for JSON API development
|
gem 'rabl', '0.11.0' # for JSON API development
|
||||||
gem 'gon', '~>4.1.0' # for passthrough of Ruby variables to Javascript variables
|
gem 'gon', '~>4.1.0' # for passthrough of Ruby variables to Javascript variables
|
||||||
gem 'eventmachine', '1.0.3'
|
gem 'eventmachine', '1.0.4'
|
||||||
gem 'faraday', '~>0.9.0'
|
gem 'faraday', '~>0.9.0'
|
||||||
gem 'amqp', '0.9.8'
|
gem 'amqp', '0.9.8'
|
||||||
gem 'logging-rails', :require => 'logging/rails'
|
gem 'logging-rails', :require => 'logging/rails'
|
||||||
|
|
@ -95,6 +95,7 @@ gem 'react-rails', '~> 1.0'
|
||||||
|
|
||||||
source 'https://rails-assets.org' do
|
source 'https://rails-assets.org' do
|
||||||
gem 'rails-assets-reflux'
|
gem 'rails-assets-reflux'
|
||||||
|
gem 'rails-assets-classnames'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 296 B |
|
After Width: | Height: | Size: 1010 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1021 B |
|
Before Width: | Height: | Size: 320 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1018 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
|
@ -198,6 +198,11 @@
|
||||||
|
|
||||||
function loggedIn(header, payload) {
|
function loggedIn(header, payload) {
|
||||||
|
|
||||||
|
// reason for setTimeout:
|
||||||
|
// loggedIn causes an absolute ton of initialization to happen, and errors sometimes happen
|
||||||
|
// but because loggedIn(header,payload) is a callback from a websocket, the browser doesn't show a stack trace...
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
server.signedIn = true;
|
server.signedIn = true;
|
||||||
server.clientID = payload.client_id;
|
server.clientID = payload.client_id;
|
||||||
server.publicIP = payload.public_ip;
|
server.publicIP = payload.public_ip;
|
||||||
|
|
@ -213,7 +218,7 @@
|
||||||
|
|
||||||
app.clientId = payload.client_id;
|
app.clientId = payload.client_id;
|
||||||
|
|
||||||
if(isClientMode()) {
|
if (isClientMode()) {
|
||||||
// tell the backend that we have logged in
|
// tell the backend that we have logged in
|
||||||
context.jamClient.OnLoggedIn(payload.user_id, payload.token); // ACTS AS CONTINUATION
|
context.jamClient.OnLoggedIn(payload.user_id, payload.token); // ACTS AS CONTINUATION
|
||||||
$.cookie('client_id', payload.client_id);
|
$.cookie('client_id', payload.client_id);
|
||||||
|
|
@ -239,9 +244,10 @@
|
||||||
|
|
||||||
activeElementEvent('afterConnect', payload);
|
activeElementEvent('afterConnect', payload);
|
||||||
|
|
||||||
if(payload.client_update && context.JK.ClientUpdateInstance) {
|
if (payload.client_update && context.JK.ClientUpdateInstance) {
|
||||||
context.JK.ClientUpdateInstance.runCheck(payload.client_update.product, payload.client_update.version, payload.client_update.uri, payload.client_update.size)
|
context.JK.ClientUpdateInstance.runCheck(payload.client_update.product, payload.client_update.version, payload.client_update.uri, payload.client_update.size)
|
||||||
}
|
}
|
||||||
|
}, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
function heartbeatAck(header, payload) {
|
function heartbeatAck(header, payload) {
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@
|
||||||
$('#account-content-scroller').on('click', '#account-my-jamtracks-link', function(evt) { evt.stopPropagation(); navToMyJamTracks(); return false; } );
|
$('#account-content-scroller').on('click', '#account-my-jamtracks-link', function(evt) { evt.stopPropagation(); navToMyJamTracks(); return false; } );
|
||||||
|
|
||||||
$('#account-content-scroller').on('click', '#account-edit-identity-link', function(evt) { evt.stopPropagation(); navToEditIdentity(); return false; } );
|
$('#account-content-scroller').on('click', '#account-edit-identity-link', function(evt) { evt.stopPropagation(); navToEditIdentity(); return false; } );
|
||||||
$('#account-content-scroller').on('click', '#account-edit-profile-link', function(evt) { evt.stopPropagation(); navToEditProfile(); return false; } );
|
$('#account-content-scroller').on('click', '.account-edit-profile-link', function(evt) { evt.stopPropagation(); navToEditProfile(); return false; } );
|
||||||
$('#account-content-scroller').on('click', '#account-edit-subscriptions-link', function(evt) { evt.stopPropagation(); navToEditSubscriptions(); return false; } );
|
$('#account-content-scroller').on('click', '#account-edit-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-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-audio-link', function(evt) { evt.stopPropagation(); navToEditAudio(); return false; } );
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@
|
||||||
rest.getLinks(type)
|
rest.getLinks(type)
|
||||||
.done(populateLinkTable)
|
.done(populateLinkTable)
|
||||||
.fail(function() {
|
.fail(function() {
|
||||||
app.notify({message: 'Unable to fetch links. Please try again later.' })
|
app.notify({text: 'Unable to fetch links. Please try again later.' })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,8 +145,9 @@
|
||||||
$traditionalTouringOption.val(userDetail.traditional_band_touring ? '1' : '0')
|
$traditionalTouringOption.val(userDetail.traditional_band_touring ? '1' : '0')
|
||||||
context.JK.dropdown($traditionalTouringOption)
|
context.JK.dropdown($traditionalTouringOption)
|
||||||
|
|
||||||
$hourlyRate.val(userDetail.paid_sessions_hourly_rate)
|
// convert the value to cents
|
||||||
$dailyRate.val(userDetail.paid_sessions_daily_rate)
|
$hourlyRate.val(profileUtils.normalizeMoneyForDisplay(userDetail.paid_sessions_hourly_rate));
|
||||||
|
$dailyRate.val(profileUtils.normalizeMoneyForDisplay(userDetail.paid_sessions_daily_rate));
|
||||||
|
|
||||||
$cowritingPurpose.val(userDetail.cowriting_purpose)
|
$cowritingPurpose.val(userDetail.cowriting_purpose)
|
||||||
context.JK.dropdown($cowritingPurpose)
|
context.JK.dropdown($cowritingPurpose)
|
||||||
|
|
@ -238,11 +239,11 @@
|
||||||
|
|
||||||
paid_sessions: $screen.find('input[name=paid_sessions]:checked').val(),
|
paid_sessions: $screen.find('input[name=paid_sessions]:checked').val(),
|
||||||
paid_session_genres: $paidSessionsGenreList.html() === NONE_SPECIFIED ? [] : $paidSessionsGenreList.html().split(GENRE_LIST_DELIMITER),
|
paid_session_genres: $paidSessionsGenreList.html() === NONE_SPECIFIED ? [] : $paidSessionsGenreList.html().split(GENRE_LIST_DELIMITER),
|
||||||
paid_sessions_hourly_rate: $hourlyRate.val(),
|
paid_sessions_hourly_rate: profileUtils.normalizeMoneyForSubmit($hourlyRate.val()),
|
||||||
paid_sessions_daily_rate: $dailyRate.val(),
|
paid_sessions_daily_rate: profileUtils.normalizeMoneyForSubmit($dailyRate.val()),
|
||||||
|
|
||||||
free_sessions: $screen.find('input[name=free_sessions]:checked').val(),
|
free_sessions: $screen.find('input[name=free_sessions]:checked').val(),
|
||||||
free_session_genre: $freeSessionsGenreList.html() === NONE_SPECIFIED ? [] : $freeSessionsGenreList.html().split(GENRE_LIST_DELIMITER),
|
free_session_genres: $freeSessionsGenreList.html() === NONE_SPECIFIED ? [] : $freeSessionsGenreList.html().split(GENRE_LIST_DELIMITER),
|
||||||
|
|
||||||
cowriting: $screen.find('input[name=cowriting]:checked').val(),
|
cowriting: $screen.find('input[name=cowriting]:checked').val(),
|
||||||
cowriting_genres: $cowritingGenreList.html() === NONE_SPECIFIED ? [] : $cowritingGenreList.html().split(GENRE_LIST_DELIMITER),
|
cowriting_genres: $cowritingGenreList.html() === NONE_SPECIFIED ? [] : $cowritingGenreList.html().split(GENRE_LIST_DELIMITER),
|
||||||
|
|
@ -263,7 +264,12 @@
|
||||||
var errors = JSON.parse(xhr.responseText)
|
var errors = JSON.parse(xhr.responseText)
|
||||||
|
|
||||||
if(xhr.status == 422) {
|
if(xhr.status == 422) {
|
||||||
|
context.JK.append_errors($hourlyRate, 'paid_sessions_hourly_rate', errors)
|
||||||
|
context.JK.append_errors($dailyRate, 'paid_sessions_daily_rate', errors)
|
||||||
|
|
||||||
|
if(errors.errors.length > 0) {
|
||||||
|
app.notifyServerError(xhr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
app.ajaxError(xhr, textStatus, errorMessage)
|
app.ajaxError(xhr, textStatus, errorMessage)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@
|
||||||
var ui = new context.JK.UIHelper(JK.app);
|
var ui = new context.JK.UIHelper(JK.app);
|
||||||
var target = {};
|
var target = {};
|
||||||
var profileUtils = context.JK.ProfileUtils;
|
var profileUtils = context.JK.ProfileUtils;
|
||||||
|
parent
|
||||||
|
var parent = $(".account-profile-samples")
|
||||||
|
|
||||||
var $screen = $('.profile-online-sample-controls', parent);
|
var $screen = $('.profile-online-sample-controls', parent);
|
||||||
// online presences
|
// online presences
|
||||||
var $website = $screen.find('.website');
|
var $website = $screen.find('.website');
|
||||||
|
|
@ -60,6 +63,7 @@
|
||||||
function afterShow(data) {
|
function afterShow(data) {
|
||||||
$.when(loadFn())
|
$.when(loadFn())
|
||||||
.done(function(targetPlayer) {
|
.done(function(targetPlayer) {
|
||||||
|
console.log("TARGET PLAYER", targetPlayer)
|
||||||
if (targetPlayer && targetPlayer.keys && targetPlayer.keys.length > 0) {
|
if (targetPlayer && targetPlayer.keys && targetPlayer.keys.length > 0) {
|
||||||
renderPlayer(targetPlayer)
|
renderPlayer(targetPlayer)
|
||||||
}
|
}
|
||||||
|
|
@ -147,22 +151,27 @@
|
||||||
if (samples && samples.length > 0) {
|
if (samples && samples.length > 0) {
|
||||||
$.each(samples, function(index, val) {
|
$.each(samples, function(index, val) {
|
||||||
|
|
||||||
recordingSources.push({
|
var source = {
|
||||||
'url': val.url,
|
'url': val.url,
|
||||||
'recording_id': val.service_id,
|
'recording_id': val.service_id,
|
||||||
'recording_title': val.description
|
'recording_title': val.description
|
||||||
|
}
|
||||||
|
recordingSources.push(source);
|
||||||
|
buildNonJamKazamEntry($sampleList, type, source);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildNonJamKazamEntry($sampleList, type, source) {
|
||||||
// TODO: this code is repeated in HTML file
|
// TODO: this code is repeated in HTML file
|
||||||
var recordingIdAttr = ' data-recording-id="' + val.service_id + '" ';
|
var recordingIdAttr = ' data-recording-id="' + source.recording_id + '" ';
|
||||||
var recordingUrlAttr = ' data-recording-url="' + val.url + '" ';
|
var recordingUrlAttr = ' data-recording-url="' + source.url + '" ';
|
||||||
var recordingTitleAttr = ' data-recording-title="' + val.description + '"';
|
var recordingTitleAttr = ' data-recording-title="' + source.recording_title + '"';
|
||||||
var title = formatTitle(val.description);
|
var title = formatTitle(source.recording_title);
|
||||||
|
$sampleList.find(".empty").addClass("hidden")
|
||||||
$sampleList.append('<div class="clearall recording-row left entry"' + recordingIdAttr + recordingUrlAttr + recordingTitleAttr + '>' + title + '</div>');
|
$sampleList.append('<div class="clearall recording-row left entry"' + recordingIdAttr + recordingUrlAttr + recordingTitleAttr + '>' + title + '</div>');
|
||||||
$sampleList.append('<div class="right close-button" data-recording-type="' + type + '"' + recordingIdAttr + '>X</div>');
|
$sampleList.append('<div class="right close-button" data-recording-type="' + type + '"' + recordingIdAttr + '>X</div>');
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildJamkazamEntry(recordingId, recordingName) {
|
function buildJamkazamEntry(recordingId, recordingName) {
|
||||||
|
|
@ -179,10 +188,7 @@
|
||||||
$btnAddJkRecording.click(function(evt) {
|
$btnAddJkRecording.click(function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
// retrieve recordings and pass to modal dialog
|
ui.launchRecordingSelectorDialog(jamkazamRecordingSources, function(selectedRecordings) {
|
||||||
api.getClaimedRecordings()
|
|
||||||
.done(function(response) {
|
|
||||||
ui.launchRecordingSelectorDialog(response, jamkazamRecordingSources, function(selectedRecordings) {
|
|
||||||
$jamkazamSampleList.empty();
|
$jamkazamSampleList.empty();
|
||||||
|
|
||||||
jamkazamRecordingSources = [];
|
jamkazamRecordingSources = [];
|
||||||
|
|
@ -197,7 +203,7 @@
|
||||||
buildJamkazamEntry(val.id, val.name);
|
buildJamkazamEntry(val.id, val.name);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
@ -287,6 +293,7 @@
|
||||||
disableSubmits()
|
disableSubmits()
|
||||||
|
|
||||||
var player = buildPlayer()
|
var player = buildPlayer()
|
||||||
|
|
||||||
updateFn({
|
updateFn({
|
||||||
website: player.website,
|
website: player.website,
|
||||||
online_presences: player.online_presences,
|
online_presences: player.online_presences,
|
||||||
|
|
@ -316,8 +323,13 @@
|
||||||
addPerformanceSamples(ps, $soundCloudSampleList, performanceSampleTypes.SOUNDCLOUD.description);
|
addPerformanceSamples(ps, $soundCloudSampleList, performanceSampleTypes.SOUNDCLOUD.description);
|
||||||
addPerformanceSamples(ps, $youTubeSampleList, performanceSampleTypes.YOUTUBE.description);
|
addPerformanceSamples(ps, $youTubeSampleList, performanceSampleTypes.YOUTUBE.description);
|
||||||
|
|
||||||
|
var website = $website.val()
|
||||||
|
if (website == '') {
|
||||||
|
website = null;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
website: $website.val(),
|
website: website,
|
||||||
online_presences: op,
|
online_presences: op,
|
||||||
performance_samples: ps
|
performance_samples: ps
|
||||||
}
|
}
|
||||||
|
|
@ -428,8 +440,8 @@
|
||||||
siteSuccessCallback($inputDiv, youTubeRecordingValidator, $youTubeSampleList, 'youtube');
|
siteSuccessCallback($inputDiv, youTubeRecordingValidator, $youTubeSampleList, 'youtube');
|
||||||
}
|
}
|
||||||
|
|
||||||
function siteSuccessCallback($inputDiv, recordingSiteValidator, sampleList, type) {
|
function siteSuccessCallback($inputDiv, recordingSiteValidator, $sampleList, type) {
|
||||||
sampleList.find(".empty").addClass("hidden")
|
$sampleList.find(".empty").addClass("hidden")
|
||||||
$inputDiv.removeClass('error');
|
$inputDiv.removeClass('error');
|
||||||
$inputDiv.find('.error-text').remove();
|
$inputDiv.find('.error-text').remove();
|
||||||
|
|
||||||
|
|
@ -437,13 +449,7 @@
|
||||||
if (recordingSources && recordingSources.length > 0) {
|
if (recordingSources && recordingSources.length > 0) {
|
||||||
var addedRecording = recordingSources[recordingSources.length-1];
|
var addedRecording = recordingSources[recordingSources.length-1];
|
||||||
|
|
||||||
// TODO: this code is repeated in elsewhere in this JS file:
|
buildNonJamKazamEntry($sampleList, type, addedRecording);
|
||||||
var recordingIdAttr = ' data-recording-id="' + addedRecording.recording_id + '" ';
|
|
||||||
var recordingUrlAttr = ' data-recording-url="' + addedRecording.url + '" ';
|
|
||||||
var recordingTitleAttr = ' data-recording-title="' + addedRecording.recording_title + '"';
|
|
||||||
var title = formatTitle(addedRecording.recording_title);
|
|
||||||
sampleList.append('<div class="clearall recording-row left entry"' + recordingIdAttr + recordingUrlAttr + recordingTitleAttr + '>' + title + '</div>');
|
|
||||||
sampleList.append('<div class="right close-button" data-recording-type="' + type + '"' + recordingIdAttr + '>X</div>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$inputDiv.find('input').val('');
|
$inputDiv.find('input').val('');
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,16 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
context.JK = context.JK || {};
|
context.JK = context.JK || {};
|
||||||
context.JK.AddNewGearDialog = function(app, sessionScreen) {
|
context.JK.AddNewGearDialog = function(app) {
|
||||||
var logger = context.JK.logger;
|
var logger = context.JK.logger;
|
||||||
|
|
||||||
function events() {
|
function events() {
|
||||||
$('#btn-leave-session-test').click(function() {
|
$('#btn-leave-session-test').click(function() {
|
||||||
|
|
||||||
sessionScreen.setPromptLeave(false);
|
context.SessionActions.leaveSession.trigger({location: '/client#/home'})
|
||||||
|
|
||||||
app.layout.closeDialog('configure-tracks');
|
app.layout.closeDialog('configure-tracks');
|
||||||
|
|
||||||
context.location = "/client#/home";
|
|
||||||
|
|
||||||
app.layout.startNewFtue();
|
app.layout.startNewFtue();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
var inputTracks = context.JK.TrackHelpers.getTracks(context.jamClient, 2);
|
var inputTracks = context.JK.TrackHelpers.getTracks(context.jamClient, 4);
|
||||||
|
|
||||||
// this is some ugly logic coming up, here's why:
|
// this is some ugly logic coming up, here's why:
|
||||||
// we need the id (guid) that the backend generated for the new track we just added
|
// we need the id (guid) that the backend generated for the new track we just added
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
//= require jquery.exists
|
//= require jquery.exists
|
||||||
//= require jquery.payment
|
//= require jquery.payment
|
||||||
//= require jquery.visible
|
//= require jquery.visible
|
||||||
|
//= require classnames
|
||||||
//= require reflux
|
//= require reflux
|
||||||
//= require howler.core.js
|
//= require howler.core.js
|
||||||
//= require jstz
|
//= require jstz
|
||||||
|
|
@ -54,11 +55,12 @@
|
||||||
//= require react
|
//= require react
|
||||||
//= require react_ujs
|
//= require react_ujs
|
||||||
//= require react-init
|
//= require react-init
|
||||||
//= require react-components
|
|
||||||
//= require web/signup_helper
|
//= require web/signup_helper
|
||||||
//= require web/signin_helper
|
//= require web/signin_helper
|
||||||
//= require web/signin
|
//= require web/signin
|
||||||
//= require web/tracking
|
//= require web/tracking
|
||||||
|
//= require webcam_viewer
|
||||||
|
//= require react-components
|
||||||
//= require_directory .
|
//= require_directory .
|
||||||
//= require_directory ./dialog
|
//= require_directory ./dialog
|
||||||
//= require_directory ./wizard
|
//= require_directory ./wizard
|
||||||
|
|
|
||||||
|
|
@ -37,20 +37,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onGenericEvent(type, text) {
|
function onGenericEvent(type, text) {
|
||||||
context.setTimeout(function() {
|
|
||||||
var alert = ALERT_TYPES[type];
|
var alert = ALERT_TYPES[type];
|
||||||
|
|
||||||
if(alert && alert.title) {
|
if(alert && alert.title) {
|
||||||
app.notify({
|
context.NotificationActions.backendNotification({msg: alert.title, detail: alert.message, backend_detail:text, help: alert.help})
|
||||||
"title": ALERT_TYPES[type].title,
|
|
||||||
"text": text,
|
|
||||||
"icon_url": "/assets/content/icon_alert_big.png"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.debug("Unhandled Backend Event type %o, data %o", type, text)
|
logger.debug("Unhandled Backend Event type %o, data %o", type, text)
|
||||||
}
|
}
|
||||||
}, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function alertCallback(type, text) {
|
function alertCallback(type, text) {
|
||||||
|
|
@ -77,8 +73,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 2) { // BACKEND_MIXER_CHANGE
|
if (type === 2) { // BACKEND_MIXER_CHANGE
|
||||||
if(context.JK.CurrentSessionModel)
|
|
||||||
context.JK.CurrentSessionModel.onBackendMixerChanged(type, text)
|
context.MixerActions.mixersChanged(type, text)
|
||||||
|
|
||||||
|
//if(context.JK.CurrentSessionModel)
|
||||||
|
// context.JK.CurrentSessionModel.onBackendMixerChanged(type, text)
|
||||||
}
|
}
|
||||||
else if (type === ALERT_NAMES.NO_VALID_AUDIO_CONFIG) { // NO_VALID_AUDIO_CONFIG
|
else if (type === ALERT_NAMES.NO_VALID_AUDIO_CONFIG) { // NO_VALID_AUDIO_CONFIG
|
||||||
if(context.JK.GearUtilsInstance && context.JK.GearUtilsInstance.isRestartingAudio()) {
|
if(context.JK.GearUtilsInstance && context.JK.GearUtilsInstance.isRestartingAudio()) {
|
||||||
|
|
@ -101,28 +100,36 @@
|
||||||
onStunEvent();
|
onStunEvent();
|
||||||
}
|
}
|
||||||
else if (type === 26) { // DEAD_USER_REMOVE_EVENT
|
else if (type === 26) { // DEAD_USER_REMOVE_EVENT
|
||||||
if(context.JK.CurrentSessionModel)
|
MixerActions.deadUserRemove(text);
|
||||||
context.JK.CurrentSessionModel.onDeadUserRemove(type, text);
|
//if(context.JK.CurrentSessionModel)
|
||||||
|
// context.JK.CurrentSessionModel.onDeadUserRemove(type, text);
|
||||||
}
|
}
|
||||||
else if (type === 27) { // WINDOW_CLOSE_BACKGROUND_MODE
|
else if (type === 27) { // WINDOW_CLOSE_BACKGROUND_MODE
|
||||||
if(context.JK.CurrentSessionModel)
|
|
||||||
context.JK.CurrentSessionModel.onWindowBackgrounded(type, text);
|
SessionActions.windowBackgrounded()
|
||||||
|
|
||||||
|
//if(context.JK.CurrentSessionModel)
|
||||||
|
// context.JK.CurrentSessionModel.onWindowBackgrounded(type, text);
|
||||||
}
|
}
|
||||||
else if(type === ALERT_NAMES.SESSION_LIVEBROADCAST_FAIL) {
|
else if(type === ALERT_NAMES.SESSION_LIVEBROADCAST_FAIL) {
|
||||||
if(context.JK.CurrentSessionModel)
|
SessionActions.broadcastFailure(text)
|
||||||
context.JK.CurrentSessionModel.onBroadcastFailure(type, text);
|
//if(context.JK.CurrentSessionModel)
|
||||||
|
// context.JK.CurrentSessionModel.onBroadcastFailure(type, text);
|
||||||
}
|
}
|
||||||
else if(type === ALERT_NAMES.SESSION_LIVEBROADCAST_ACTIVE) {
|
else if(type === ALERT_NAMES.SESSION_LIVEBROADCAST_ACTIVE) {
|
||||||
if(context.JK.CurrentSessionModel)
|
SessionActions.broadcastSuccess(text)
|
||||||
context.JK.CurrentSessionModel.onBroadcastSuccess(type, text);
|
//if(context.JK.CurrentSessionModel)
|
||||||
|
// context.JK.CurrentSessionModel.onBroadcastSuccess(type, text);
|
||||||
}
|
}
|
||||||
else if(type === ALERT_NAMES.SESSION_LIVEBROADCAST_STOPPED) {
|
else if(type === ALERT_NAMES.SESSION_LIVEBROADCAST_STOPPED) {
|
||||||
if(context.JK.CurrentSessionModel)
|
SessionActions.broadcastStopped(text)
|
||||||
context.JK.CurrentSessionModel.onBroadcastStopped(type, text);
|
//if(context.JK.CurrentSessionModel)
|
||||||
|
//context.JK.CurrentSessionModel.onBroadcastStopped(type, text);
|
||||||
}
|
}
|
||||||
else if(type === ALERT_NAMES.RECORD_PLAYBACK_STATE) {
|
else if(type === ALERT_NAMES.RECORD_PLAYBACK_STATE) {
|
||||||
if(context.JK.CurrentSessionModel)
|
//if(context.JK.CurrentSessionModel)
|
||||||
context.JK.CurrentSessionModel.onPlaybackStateChange(type, text);
|
// context.JK.CurrentSessionModel.onPlaybackStateChange(type, text);
|
||||||
|
context.MediaPlaybackActions.playbackStateChange(text);
|
||||||
}
|
}
|
||||||
else if((!context.JK.CurrentSessionModel || !context.JK.CurrentSessionModel.inSession()) &&
|
else if((!context.JK.CurrentSessionModel || !context.JK.CurrentSessionModel.inSession()) &&
|
||||||
(ALERT_NAMES.INPUT_IO_RATE == type || ALERT_NAMES.INPUT_IO_JTR == type || ALERT_NAMES.OUTPUT_IO_RATE == type || ALERT_NAMES.OUTPUT_IO_JTR== type)) {
|
(ALERT_NAMES.INPUT_IO_RATE == type || ALERT_NAMES.INPUT_IO_JTR == type || ALERT_NAMES.OUTPUT_IO_RATE == type || ALERT_NAMES.OUTPUT_IO_JTR== type)) {
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,8 @@
|
||||||
|
|
||||||
|
|
||||||
$("#play-commitment").val('1')
|
$("#play-commitment").val('1')
|
||||||
$("#hourly-rate").val("0.0")
|
$screen.find("#hourly-rate").val("0")
|
||||||
$("#gig-minimum").val("0.0")
|
$screen.find("#gig-minimum").val("0")
|
||||||
resetGenres();
|
resetGenres();
|
||||||
renderDesiredExperienceLabel([])
|
renderDesiredExperienceLabel([])
|
||||||
|
|
||||||
|
|
@ -225,9 +225,14 @@
|
||||||
band.free_gigs=$('input[name="free_gigs"]:checked').val()=="yes"
|
band.free_gigs=$('input[name="free_gigs"]:checked').val()=="yes"
|
||||||
band.touring_option=$('#touring-option').val()=="yes"
|
band.touring_option=$('#touring-option').val()=="yes"
|
||||||
|
|
||||||
band.play_commitment=$("#play-commitment").val()
|
|
||||||
band.hourly_rate=$("#hourly-rate").val()
|
if ($screen.find("#play-commitment").length == 0) {
|
||||||
band.gig_minimum=$("#gig-minimum").val()
|
logger.error("MISSING PLAY MOTIMMENT")
|
||||||
|
}
|
||||||
|
|
||||||
|
band.play_commitment = $screen.find("#play-commitment").val()
|
||||||
|
band.hourly_rate = profileUtils.normalizeMoneyForSubmit($screen.find("#hourly-rate").val())
|
||||||
|
band.gig_minimum = profileUtils.normalizeMoneyForSubmit($("#gig-minimum").val())
|
||||||
|
|
||||||
if (currentStep==GENRE_STEP) {
|
if (currentStep==GENRE_STEP) {
|
||||||
band.genres = getSelectedGenres();
|
band.genres = getSelectedGenres();
|
||||||
|
|
@ -424,8 +429,8 @@
|
||||||
|
|
||||||
$('#touring-option').val(band.touring_option ? 'yes' : 'no')
|
$('#touring-option').val(band.touring_option ? 'yes' : 'no')
|
||||||
$("#play-commitment").val(band.play_commitment)
|
$("#play-commitment").val(band.play_commitment)
|
||||||
$("#hourly-rate").val(band.hourly_rate)
|
$("#hourly-rate").val(profileUtils.normalizeMoneyForDisplay(band.hourly_rate))
|
||||||
$("#gig-minimum").val(band.gig_minimum)
|
$("#gig-minimum").val(profileUtils.normalizeMoneyForDisplay(band.gig_minimum))
|
||||||
|
|
||||||
// Initialize avatar
|
// Initialize avatar
|
||||||
if (band.photo_url) {
|
if (band.photo_url) {
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@
|
||||||
updateUri = uri;
|
updateUri = uri;
|
||||||
updateSize = size;
|
updateSize = size;
|
||||||
|
|
||||||
if(context.JK.CurrentSessionModel && context.JK.CurrentSessionModel.inSession()) {
|
if(context.SessionStore.inSession()) {
|
||||||
logger.debug("deferring client update because in session")
|
logger.debug("deferring client update because in session")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
$ = jQuery
|
$ = jQuery
|
||||||
context = window
|
context = window
|
||||||
context.JK ||= {};
|
context.JK ||= {};
|
||||||
broadcastActions = context.JK.Actions.Broadcast
|
broadcastActions = @BroadcastActions
|
||||||
|
|
||||||
context.JK.ClientInit = class ClientInit
|
context.JK.ClientInit = class ClientInit
|
||||||
constructor: () ->
|
constructor: () ->
|
||||||
|
|
@ -21,7 +21,10 @@ context.JK.ClientInit = class ClientInit
|
||||||
this.watchBroadcast()
|
this.watchBroadcast()
|
||||||
|
|
||||||
checkBroadcast: () =>
|
checkBroadcast: () =>
|
||||||
broadcastActions.load.triggerPromise()
|
broadcastActions.load.triggerPromise().catch(() ->
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
watchBroadcast: () =>
|
watchBroadcast: () =>
|
||||||
if context.JK.currentUserId
|
if context.JK.currentUserId
|
||||||
|
|
|
||||||
|
|
@ -112,10 +112,14 @@
|
||||||
$voiceChatTabSelector.click(function () {
|
$voiceChatTabSelector.click(function () {
|
||||||
// validate audio settings
|
// validate audio settings
|
||||||
if (validateAudioSettings()) {
|
if (validateAudioSettings()) {
|
||||||
|
logger.debug("initializing voice chat helper")
|
||||||
configureTracksHelper.reset();
|
configureTracksHelper.reset();
|
||||||
voiceChatHelper.reset();
|
voiceChatHelper.reset();
|
||||||
showVoiceChatPanel();
|
showVoiceChatPanel();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
logger.debug("invalid audio settings; ignoring")
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$btnCancel.click(function() {
|
$btnCancel.click(function() {
|
||||||
|
|
|
||||||
|
|
@ -120,11 +120,11 @@
|
||||||
openingRecording = true;
|
openingRecording = true;
|
||||||
|
|
||||||
// tell the server we are about to start a recording
|
// tell the server we are about to start a recording
|
||||||
rest.startPlayClaimedRecording({id: context.JK.CurrentSessionModel.id(), claimed_recording_id: claimedRecording.id})
|
rest.startPlayClaimedRecording({id: context.SessionStore.id(), claimed_recording_id: claimedRecording.id})
|
||||||
.done(function(response) {
|
.done(function(response) {
|
||||||
|
|
||||||
// update session info
|
// update session info
|
||||||
context.JK.CurrentSessionModel.updateSession(response);
|
context.SessionActions.updateSession.trigger(response);
|
||||||
|
|
||||||
var recordingId = $(this).attr('data-recording-id');
|
var recordingId = $(this).attr('data-recording-id');
|
||||||
var openRecordingResult = context.jamClient.OpenRecording(claimedRecording.recording);
|
var openRecordingResult = context.jamClient.OpenRecording(claimedRecording.recording);
|
||||||
|
|
@ -138,7 +138,7 @@
|
||||||
"icon_url": "/assets/content/icon_alert_big.png"
|
"icon_url": "/assets/content/icon_alert_big.png"
|
||||||
});
|
});
|
||||||
|
|
||||||
rest.stopPlayClaimedRecording({id: context.JK.CurrentSessionModel.id(), claimed_recording_id: claimedRecording.id})
|
rest.stopPlayClaimedRecording({id: context.SessionStore.id(), claimed_recording_id: claimedRecording.id})
|
||||||
.fail(function(jqXHR) {
|
.fail(function(jqXHR) {
|
||||||
app.notify({
|
app.notify({
|
||||||
"title": "Couldn't Stop Recording Playback",
|
"title": "Couldn't Stop Recording Playback",
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
var backingTrack = $(this).data('server-model');
|
var backingTrack = $(this).data('server-model');
|
||||||
|
|
||||||
// tell the server we are about to open a backing track:
|
// tell the server we are about to open a backing track:
|
||||||
rest.openBackingTrack({id: context.JK.CurrentSessionModel.id(), backing_track_path: backingTrack.name})
|
rest.openBackingTrack({id: context.SessionStore.id(), backing_track_path: backingTrack.name})
|
||||||
.done(function(response) {
|
.done(function(response) {
|
||||||
var result = context.jamClient.SessionOpenBackingTrackFile(backingTrack.name, false);
|
var result = context.jamClient.SessionOpenBackingTrackFile(backingTrack.name, false);
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
// else {
|
// else {
|
||||||
// logger.error("unable to open backing track")
|
// logger.error("unable to open backing track")
|
||||||
// }
|
// }
|
||||||
context.JK.CurrentSessionModel.refreshCurrentSession(true);
|
context.SessionActions.syncWithServer()
|
||||||
|
|
||||||
})
|
})
|
||||||
.fail(function(jqXHR) {
|
.fail(function(jqXHR) {
|
||||||
|
|
|
||||||
|
|
@ -86,10 +86,10 @@
|
||||||
var jamTrack = $(this).data('server-model');
|
var jamTrack = $(this).data('server-model');
|
||||||
|
|
||||||
// tell the server we are about to open a jamtrack
|
// tell the server we are about to open a jamtrack
|
||||||
rest.openJamTrack({id: context.JK.CurrentSessionModel.id(), jam_track_id: jamTrack.id})
|
rest.openJamTrack({id: context.SessionStore.id(), jam_track_id: jamTrack.id})
|
||||||
.done(function(response) {
|
.done(function(response) {
|
||||||
$dialog.data('result', {success:true, jamTrack: jamTrack})
|
$dialog.data('result', {success:true, jamTrack: jamTrack})
|
||||||
context.JK.CurrentSessionModel.updateSession(response);
|
context.SessionActions.updateSession.trigger(response);
|
||||||
app.layout.closeDialog('open-jam-track-dialog');
|
app.layout.closeDialog('open-jam-track-dialog');
|
||||||
})
|
})
|
||||||
.fail(function(jqXHR) {
|
.fail(function(jqXHR) {
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
function events() {
|
function events() {
|
||||||
$('#btn-rate-session-cancel', $scopeSelector).click(function(evt) {
|
$('#btn-rate-session-cancel', $scopeSelector).click(function(evt) {
|
||||||
closeDialog();
|
closeDialog();
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
$('#btn-rate-session-up', $scopeSelector).click(function(evt) {
|
$('#btn-rate-session-up', $scopeSelector).click(function(evt) {
|
||||||
if ($(this).hasClass('selected')) {
|
if ($(this).hasClass('selected')) {
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (localResult.aggregate_state == 'PARTIALLY_MISSING') {
|
else if (localResult.aggregate_state == 'PARTIALLY_MISSING') {
|
||||||
logger.error("unable to open recording due to some missing tracks: %o", localResults);
|
logger.error("unable to open recording due to some missing tracks: %o", recording, localResults);
|
||||||
app.notify({
|
app.notify({
|
||||||
title: "Unable to Open Recording for Playback",
|
title: "Unable to Open Recording for Playback",
|
||||||
text: "Some of your tracks associated with the recording are missing. This is a bug in the application.",
|
text: "Some of your tracks associated with the recording are missing. This is a bug in the application.",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
context.JK = context.JK || {};
|
context.JK = context.JK || {};
|
||||||
context.JK.RecordingSelectorDialog = function(app, recordings, selectedRecordings, selectCallback) {
|
context.JK.RecordingSelectorDialog = function(app, selectedRecordings, selectCallback) {
|
||||||
var logger = context.JK.logger;
|
var logger = context.JK.logger;
|
||||||
var rest = context.JK.Rest();
|
var rest = context.JK.Rest();
|
||||||
var recordingUtils = context.JK.RecordingUtils;
|
var recordingUtils = context.JK.RecordingUtils;
|
||||||
|
|
@ -10,173 +10,26 @@
|
||||||
var dialogId = 'recording-selector-dialog';
|
var dialogId = 'recording-selector-dialog';
|
||||||
var $screen = $('#' + dialogId);
|
var $screen = $('#' + dialogId);
|
||||||
var $btnSelect = $screen.find(".btn-select-recordings");
|
var $btnSelect = $screen.find(".btn-select-recordings");
|
||||||
var $instructions = $screen.find('#instructions');
|
|
||||||
var $recordings = $screen.find('.recordings');
|
var $recordings = $screen.find('.recordings');
|
||||||
|
var $paginatorHolder = null;
|
||||||
var feedHelper = new context.JK.Feed(app);
|
var feedHelper = new context.JK.Feed(app);
|
||||||
|
var $scroller = $recordings;
|
||||||
|
var $content = $recordings;
|
||||||
|
var $noMoreFeeds = $screen.find('.end-of-list');
|
||||||
|
var $empty = $();
|
||||||
|
feedHelper.initialize($screen, $scroller, $content, $noMoreFeeds, $empty, $empty, $empty, $empty, {sort: 'date', time_range: 'all', type: 'recording', show_checkbox: true, hide_avatar: true});
|
||||||
|
|
||||||
function beforeShow(data) {
|
function beforeShow(data) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterShow(data) {
|
function afterShow(data) {
|
||||||
|
|
||||||
$recordings.empty();
|
feedHelper.setUser(context.JK.currentUserId)
|
||||||
|
feedHelper.refresh()
|
||||||
$.each(recordings, function(index, val) {
|
|
||||||
bindRecordingItem(val);
|
|
||||||
});
|
|
||||||
|
|
||||||
// hide the avatars
|
// hide the avatars
|
||||||
$screen.find('.avatar-small.ib').hide();
|
//$screen.find('.avatar-small.ib').hide();
|
||||||
}
|
|
||||||
|
|
||||||
/********* THE FOLLOWING BLOCK IS REPEATED IN feedHelper.js **********/
|
|
||||||
function startRecordingPlay($feedItem) {
|
|
||||||
var img = $('.play-icon', $feedItem);
|
|
||||||
var $controls = $feedItem.find('.recording-controls');
|
|
||||||
img.attr('src', '/assets/content/icon_pausebutton.png');
|
|
||||||
$controls.trigger('play.listenRecording');
|
|
||||||
$feedItem.data('playing', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopRecordingPlay($feedItem) {
|
|
||||||
var img = $('.play-icon', $feedItem);
|
|
||||||
var $controls = $feedItem.find('.recording-controls');
|
|
||||||
img.attr('src', '/assets/content/icon_playbutton.png');
|
|
||||||
$controls.trigger('pause.listenRecording');
|
|
||||||
$feedItem.data('playing', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleRecordingPlay() {
|
|
||||||
|
|
||||||
var $playLink = $(this);
|
|
||||||
var $feedItem = $playLink.closest('.feed-entry');
|
|
||||||
var playing = $feedItem.data('playing');
|
|
||||||
|
|
||||||
if(playing) {
|
|
||||||
stopRecordingPlay($feedItem);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
startRecordingPlay($feedItem);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleRecordingDetails() {
|
|
||||||
var $detailsLink = $(this);
|
|
||||||
var $feedItem = $detailsLink.closest('.feed-entry');
|
|
||||||
var $musicians = $feedItem.find('.musician-detail');
|
|
||||||
var $description = $feedItem.find('.description');
|
|
||||||
var $name = $feedItem.find('.name');
|
|
||||||
var toggledOpen = $detailsLink.data('toggledOpen');
|
|
||||||
|
|
||||||
if(toggledOpen) {
|
|
||||||
toggleClose($feedItem, $name, $description, $musicians)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
toggleOpen($feedItem, $name, $description, $musicians)
|
|
||||||
}
|
|
||||||
|
|
||||||
toggledOpen = !toggledOpen;
|
|
||||||
$detailsLink.data('toggledOpen', toggledOpen);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function stateChangeRecording(e, data) {
|
|
||||||
var $controls = data.element;
|
|
||||||
var $feedItem = $controls.closest('.feed-entry');
|
|
||||||
|
|
||||||
var $sliderBar = $('.recording-position', $feedItem);
|
|
||||||
var $statusBar = $('.recording-status', $feedItem);
|
|
||||||
var $currentTime = $('.recording-current', $feedItem);
|
|
||||||
var $status = $('.status-text', $feedItem);
|
|
||||||
var $playButton = $('.play-button', $feedItem);
|
|
||||||
|
|
||||||
if(data.isEnd) stopRecordingPlay($feedItem);
|
|
||||||
if(data.isError) {
|
|
||||||
$sliderBar.hide();
|
|
||||||
$playButton.hide();
|
|
||||||
$currentTime.hide();
|
|
||||||
$statusBar.show();
|
|
||||||
$status.text(data.displayText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleOpen($feedItem, $name, $description, $musicians) {
|
|
||||||
$description.trigger('destroy.dot');
|
|
||||||
$description.data('original-height', $description.css('height')).css('height', 'auto');
|
|
||||||
$name.trigger('destroy.dot');
|
|
||||||
$name.data('original-height', $name.css('height')).css('height', 'auto');
|
|
||||||
$musicians.show();
|
|
||||||
$feedItem.animate({'max-height': '1000px'});
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleClose($feedItem, $name, $description, $musicians, immediate) {
|
|
||||||
$feedItem.css('height', $feedItem.height() + 'px')
|
|
||||||
$feedItem.animate({'height': $feedItem.data('original-max-height')}, immediate ? 0 : 400).promise().done(function() {
|
|
||||||
$feedItem.css('height', 'auto').css('max-height', $feedItem.data('original-max-height'));
|
|
||||||
|
|
||||||
$musicians.hide();
|
|
||||||
$description.css('height', $description.data('original-height'));
|
|
||||||
$description.dotdotdot();
|
|
||||||
$name.css('height', $name.data('original-height'));
|
|
||||||
$name.dotdotdot();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**********************************************************/
|
|
||||||
|
|
||||||
function bindRecordingItem(claimedRecording) {
|
|
||||||
claimedRecording.recording.mix_info = recordingUtils.createMixInfo({state: claimedRecording.recording.mix_state});
|
|
||||||
var options = {
|
|
||||||
feed_item: claimedRecording.recording,
|
|
||||||
candidate_claimed_recording: claimedRecording,
|
|
||||||
mix_class: claimedRecording['has_mix?'] ? 'has-mix' : 'no-mix',
|
|
||||||
};
|
|
||||||
|
|
||||||
var $feedItem = $(context._.template($('#template-feed-recording').html(), options, {variable: 'data'}));
|
|
||||||
var $controls = $feedItem.find('.recording-controls');
|
|
||||||
|
|
||||||
var $titleText = $feedItem.find('.title .title-text');
|
|
||||||
|
|
||||||
// if this item will be discarded, tack on a * to the RECORDING NAME
|
|
||||||
var discardTime = claimedRecording.recording['when_will_be_discarded?'];
|
|
||||||
if(discardTime) {
|
|
||||||
context.JK.helpBubble($titleText, 'recording-discarded-soon', {discardTime: discardTime}, {});
|
|
||||||
$titleText.text($titleText.text() + '*');
|
|
||||||
}
|
|
||||||
|
|
||||||
$controls.data('mix-state', claimedRecording.recording.mix_info); // for recordingUtils helper methods
|
|
||||||
$controls.data('server-info', claimedRecording.recording.mix); // for recordingUtils helper methods
|
|
||||||
$controls.data('view-context', 'feed');
|
|
||||||
|
|
||||||
$('.timeago', $feedItem).timeago();
|
|
||||||
context.JK.prettyPrintElements($('.duration', $feedItem));
|
|
||||||
context.JK.setInstrumentAssetPath($('.instrument-icon', $feedItem));
|
|
||||||
$('.details', $feedItem).click(toggleRecordingDetails);
|
|
||||||
$('.details-arrow', $feedItem).click(toggleRecordingDetails);
|
|
||||||
$('.play-button', $feedItem).click(toggleRecordingPlay);
|
|
||||||
|
|
||||||
var checked = '';
|
|
||||||
|
|
||||||
var match = $.grep(selectedRecordings, function(obj, index) {
|
|
||||||
return obj.claimed_recording_id === claimedRecording.id;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (match && match.length > 0) {
|
|
||||||
checked = 'checked';
|
|
||||||
}
|
|
||||||
|
|
||||||
// put the item on the page
|
|
||||||
$recordings.append("<div class='left'><input type='checkbox' " + checked + " data-recording-id='" + claimedRecording.id + "' data-recording-title='" + claimedRecording.name + "' />");
|
|
||||||
$recordings.append($feedItem);
|
|
||||||
|
|
||||||
// these routines need the item to have height to work (must be after renderFeed)
|
|
||||||
$controls.listenRecording({recordingId: claimedRecording.recording.id, claimedRecordingId: options.candidate_claimed_recording.id, sliderSelector:'.recording-slider', sliderBarSelector: '.recording-playback', currentTimeSelector:'.recording-current'});
|
|
||||||
$controls.bind('statechange.listenRecording', stateChangeRecording);
|
|
||||||
$('.dotdotdot', $feedItem).dotdotdot();
|
|
||||||
$feedItem.data('original-max-height', $feedItem.css('height'));
|
|
||||||
context.JK.bindHoverEvents($feedItem);
|
|
||||||
context.JK.bindProfileClickEvents($feedItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function afterHide() {
|
function afterHide() {
|
||||||
|
|
@ -187,10 +40,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function events() {
|
function events() {
|
||||||
$btnSelect.click(function(evt) {
|
$btnSelect.off('click').on('click', function(evt) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
var preSelectedRecordings = [];
|
var preSelectedRecordings = [];
|
||||||
$recordings.find('input[type=checkbox]:checked').each(function(index) {
|
$recordings.find('.select-box input[type=checkbox]:checked').each(function(index) {
|
||||||
preSelectedRecordings.push({
|
preSelectedRecordings.push({
|
||||||
"id": $(this).attr('data-recording-id'),
|
"id": $(this).attr('data-recording-id'),
|
||||||
"name": $(this).attr('data-recording-title')
|
"name": $(this).attr('data-recording-title')
|
||||||
|
|
@ -198,6 +51,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
if (selectCallback) {
|
if (selectCallback) {
|
||||||
|
console.log("calling selectCallback", preSelectedRecordings)
|
||||||
selectCallback(preSelectedRecordings);
|
selectCallback(preSelectedRecordings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,8 +71,6 @@
|
||||||
|
|
||||||
app.bindDialog(dialogId, dialogBindings);
|
app.bindDialog(dialogId, dialogBindings);
|
||||||
|
|
||||||
$instructions.html('Select one or more recordings and click ADD to add JamKazam recordings to your performance samples.');
|
|
||||||
|
|
||||||
events();
|
events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
$ = jQuery
|
||||||
|
context = window
|
||||||
|
context.JK ||= {}
|
||||||
|
MIX_MODES = context.JK.MIX_MODES
|
||||||
|
|
||||||
|
context.JK.SessionMasterMixDialog = class SessionMasterMixDialog
|
||||||
|
constructor: (@app) ->
|
||||||
|
@rest = context.JK.Rest()
|
||||||
|
@logger = context.JK.logger
|
||||||
|
@screen = null
|
||||||
|
@dialogId = 'session-master-mix-dialog'
|
||||||
|
@dialog = null
|
||||||
|
@closeBtn = null
|
||||||
|
|
||||||
|
initialize:() =>
|
||||||
|
dialogBindings =
|
||||||
|
'beforeShow' : @beforeShow
|
||||||
|
'afterShow' : @afterShow
|
||||||
|
'afterHide' : @afterHide
|
||||||
|
|
||||||
|
|
||||||
|
@dialog = $('[layout-id="' + @dialogId + '"]')
|
||||||
|
@app.bindDialog(@dialogId, dialogBindings)
|
||||||
|
@content = @dialog.find(".dialog-inner")
|
||||||
|
|
||||||
|
beforeShow:() =>
|
||||||
|
@logger.debug("session-master-mix-dlg: beforeShow")
|
||||||
|
context.jamClient.SetMixerMode(MIX_MODES.MASTER)
|
||||||
|
|
||||||
|
afterShow:() =>
|
||||||
|
@logger.debug("session-master-mix-dlg: afterShow")
|
||||||
|
|
||||||
|
afterHide:() =>
|
||||||
|
context.jamClient.SetMixerMode(MIX_MODES.PERSONAL)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
(function(context,$) {
|
(function(context,$) {
|
||||||
|
|
||||||
context.JK = context.JK || {};
|
context.JK = context.JK || {};
|
||||||
context.JK.SessionSettingsDialog = function(app, sessionScreen) {
|
context.JK.SessionSettingsDialog = function(app) {
|
||||||
var logger = context.JK.logger;
|
var logger = context.JK.logger;
|
||||||
var gearUtils = context.JK.GearUtilsInstance;
|
var gearUtils = context.JK.GearUtilsInstance;
|
||||||
var $dialog;
|
var $dialog;
|
||||||
var $screen = $('#session-settings');
|
var $screen = $('#session-settings');
|
||||||
var $selectedFilenames = $screen.find('#selected-filenames');
|
//var $selectedFilenames = $screen.find('#selected-filenames');
|
||||||
var $uploadSpinner = $screen.find('.upload-spinner');
|
var $uploadSpinner = $screen.find('.spinner-small');
|
||||||
var $selectedFilenames = $('#settings-selected-filenames');
|
//var $selectedFilenames = $('#settings-selected-filenames');
|
||||||
var $inputFiles = $screen.find('#session-select-files');
|
var $inputFiles = $screen.find('#session-select-files');
|
||||||
var $btnSelectFiles = $screen.find('.btn-select-files');
|
var $btnSelectFiles = $screen.find('.btn-select-files');
|
||||||
|
var $inputBox = $screen.find('.inputbox')
|
||||||
var rest = new JK.Rest();
|
var rest = new JK.Rest();
|
||||||
var sessionId;
|
var sessionId;
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@
|
||||||
context.JK.GenreSelectorHelper.render('#session-settings-genre');
|
context.JK.GenreSelectorHelper.render('#session-settings-genre');
|
||||||
$dialog = $('[layout-id="session-settings"]');
|
$dialog = $('[layout-id="session-settings"]');
|
||||||
|
|
||||||
var currentSession = sessionScreen.getCurrentSession();
|
var currentSession = context.SessionStore.currentSession;
|
||||||
sessionId = currentSession.id;
|
sessionId = currentSession.id;
|
||||||
|
|
||||||
// id
|
// id
|
||||||
|
|
@ -65,13 +66,21 @@
|
||||||
$('#session-settings-fan-access').val('listen-chat-band');
|
$('#session-settings-fan-access').val('listen-chat-band');
|
||||||
}
|
}
|
||||||
|
|
||||||
// notation files
|
/**
|
||||||
|
// notation files in the account screen. ugh.
|
||||||
$selectedFilenames.empty();
|
$selectedFilenames.empty();
|
||||||
for (var i=0; i < currentSession.music_notations.length; i++) {
|
for (var i=0; i < currentSession.music_notations.length; i++) {
|
||||||
var notation = currentSession.music_notations[i];
|
var notation = currentSession.music_notations[i];
|
||||||
$selectedFilenames.append('<a href="' + notation.file_url + '" rel="external">' + notation.file_name + '</a> ');
|
$selectedFilenames.append('<a href="' + notation.file_url + '" rel="external">' + notation.file_name + '</a> ');
|
||||||
|
}*/
|
||||||
|
|
||||||
|
$inputBox.empty();
|
||||||
|
for (var i=0; i < currentSession.music_notations.length; i++) {
|
||||||
|
var notation = currentSession.music_notations[i];
|
||||||
|
addNotation(notation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
context.JK.dropdown($('#session-settings-language'));
|
context.JK.dropdown($('#session-settings-language'));
|
||||||
context.JK.dropdown($('#session-settings-musician-access'));
|
context.JK.dropdown($('#session-settings-musician-access'));
|
||||||
context.JK.dropdown($('#session-settings-fan-access'));
|
context.JK.dropdown($('#session-settings-fan-access'));
|
||||||
|
|
@ -81,6 +90,29 @@
|
||||||
$('#session-settings-fan-access').easyDropDown(easyDropDownState)
|
$('#session-settings-fan-access').easyDropDown(easyDropDownState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addNotation(notation) {
|
||||||
|
|
||||||
|
var $notation = $('<div class="notation-entry"><div>' + notation.file_name + '</div><a href="#" data-id="' + notation.id + '">X</a></div>')
|
||||||
|
$notation.find('a').on('click', function(e) {
|
||||||
|
|
||||||
|
if($(this).attr('data-deleting')) {
|
||||||
|
// ignore duplicate delete attempts
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this).attr('data-deleting', true)
|
||||||
|
var $notationEntry = $(this).closest('.notation-entry').find('div').text('deleting...')
|
||||||
|
|
||||||
|
rest.deleteMusicNotation({id: notation.id})
|
||||||
|
.done(function() {
|
||||||
|
$notation.remove()
|
||||||
|
})
|
||||||
|
.fail(app.ajaxError)
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
$inputBox.append($notation);
|
||||||
|
}
|
||||||
|
|
||||||
function saveSettings(evt) {
|
function saveSettings(evt) {
|
||||||
|
|
||||||
var data = {};
|
var data = {};
|
||||||
|
|
@ -111,16 +143,14 @@
|
||||||
data.fan_access = false;
|
data.fan_access = false;
|
||||||
data.fan_chat = false;
|
data.fan_chat = false;
|
||||||
}
|
}
|
||||||
else if (fanAccess == 'listen-chat-each') {
|
else if (fanAccess == 'listen-chat') {
|
||||||
data.fan_access = true;
|
|
||||||
data.fan_chat = false;
|
|
||||||
}
|
|
||||||
else if (fanAccess == 'listen-chat-band') {
|
|
||||||
data.fan_access = true;
|
data.fan_access = true;
|
||||||
data.fan_chat = true;
|
data.fan_chat = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
rest.updateSession($('#session-settings-id').val(), data).done(settingsSaved);
|
rest.updateSession($('#session-settings-id').val(), data).done(settingsSaved);
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadNotations(notations) {
|
function uploadNotations(notations) {
|
||||||
|
|
@ -177,7 +207,7 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.always(function() {
|
.always(function() {
|
||||||
$btnSelectFiles.text('SELECT FILES...').data('uploading', null)
|
$btnSelectFiles.text('ADD FILES...').data('uploading', null)
|
||||||
$uploadSpinner.hide();
|
$uploadSpinner.hide();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -203,10 +233,9 @@
|
||||||
else {
|
else {
|
||||||
// upload as soon as user picks their files.
|
// upload as soon as user picks their files.
|
||||||
uploadNotations($inputFiles.get(0).files)
|
uploadNotations($inputFiles.get(0).files)
|
||||||
.done(function() {
|
.done(function(response) {
|
||||||
context._.each(fileNames, function(fileName) {
|
context._.each(response, function(notation) {
|
||||||
var $text = $('<span>').text(fileName);
|
addNotation(notation)
|
||||||
$selectedFilenames.append($text);
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -225,13 +254,13 @@
|
||||||
|
|
||||||
function settingsSaved(response) {
|
function settingsSaved(response) {
|
||||||
// No response returned from this call. 204.
|
// No response returned from this call. 204.
|
||||||
sessionScreen.refreshCurrentSession(true);
|
context.SessionActions.syncWithServer()
|
||||||
app.layout.closeDialog('session-settings');
|
app.layout.closeDialog('session-settings');
|
||||||
}
|
}
|
||||||
|
|
||||||
function events() {
|
function events() {
|
||||||
$('#session-settings-dialog-submit').on('click', saveSettings);
|
$('#session-settings-dialog-submit').on('click', saveSettings);
|
||||||
|
$('#session-settings-dialog').on('submit', saveSettings)
|
||||||
$inputFiles.on('change', changeSelectedFiles);
|
$inputFiles.on('change', changeSelectedFiles);
|
||||||
$btnSelectFiles.on('click', toggleSelectFiles);
|
$btnSelectFiles.on('click', toggleSelectFiles);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ context.JK.SoundCloudPlayerDialog = class SoundCloudPlayerDialog
|
||||||
initialize:(@url, @caption) =>
|
initialize:(@url, @caption) =>
|
||||||
dialogBindings = {
|
dialogBindings = {
|
||||||
'beforeShow' : @beforeShow,
|
'beforeShow' : @beforeShow,
|
||||||
'afterShow' : @afterShow
|
'afterShow' : @afterShow,
|
||||||
|
'afterHide' : @afterHide
|
||||||
}
|
}
|
||||||
|
|
||||||
@dialog = $('[layout-id="' + @dialogId + '"]')
|
@dialog = $('[layout-id="' + @dialogId + '"]')
|
||||||
|
|
@ -27,6 +28,12 @@ context.JK.SoundCloudPlayerDialog = class SoundCloudPlayerDialog
|
||||||
beforeShow:() =>
|
beforeShow:() =>
|
||||||
@player.addClass("hidden")
|
@player.addClass("hidden")
|
||||||
@player.attr("src", "")
|
@player.attr("src", "")
|
||||||
|
|
||||||
|
# the Windows client does not play back correctly
|
||||||
|
if context.jamClient.IsNativeClient()
|
||||||
|
context.JK.popExternalLink(@url)
|
||||||
|
return false
|
||||||
|
else
|
||||||
u = encodeURIComponent(@url)
|
u = encodeURIComponent(@url)
|
||||||
src = "https://w.soundcloud.com/player/?url=#{u}&auto_play=true&hide_related=false&show_comments=true&show_user=true&show_reposts=false&visual=true&loop=true"
|
src = "https://w.soundcloud.com/player/?url=#{u}&auto_play=true&hide_related=false&show_comments=true&show_user=true&show_reposts=false&visual=true&loop=true"
|
||||||
@player.attr("src", src)
|
@player.attr("src", src)
|
||||||
|
|
@ -37,4 +44,7 @@ context.JK.SoundCloudPlayerDialog = class SoundCloudPlayerDialog
|
||||||
showDialog:() =>
|
showDialog:() =>
|
||||||
@app.layout.showDialog(@dialogId)
|
@app.layout.showDialog(@dialogId)
|
||||||
|
|
||||||
|
afterHide: () =>
|
||||||
|
@player.attr('src', '')
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
var $draggingFaderHandle = null;
|
var $draggingFaderHandle = null;
|
||||||
var $draggingFader = null;
|
var $draggingFader = null;
|
||||||
|
var $floater = null;
|
||||||
var draggingOrientation = null;
|
var draggingOrientation = null;
|
||||||
|
|
||||||
var logger = g.JK.logger;
|
var logger = g.JK.logger;
|
||||||
|
|
@ -20,6 +21,7 @@
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
var $fader = $(this);
|
var $fader = $(this);
|
||||||
|
var floaterConvert = $fader.data('floaterConverter')
|
||||||
var sessionModel = window.JK.CurrentSessionModel || null;
|
var sessionModel = window.JK.CurrentSessionModel || null;
|
||||||
|
|
||||||
var mediaControlsDisabled = $fader.data('media-controls-disabled');
|
var mediaControlsDisabled = $fader.data('media-controls-disabled');
|
||||||
|
|
@ -43,7 +45,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
draggingOrientation = $fader.attr('orientation');
|
draggingOrientation = $fader.attr('data-orientation');
|
||||||
var offset = $fader.offset();
|
var offset = $fader.offset();
|
||||||
var position = { top: e.pageY - offset.top, left: e.pageX - offset.left}
|
var position = { top: e.pageY - offset.top, left: e.pageX - offset.left}
|
||||||
|
|
||||||
|
|
@ -53,6 +55,10 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(floaterConvert) {
|
||||||
|
window.JK.FaderHelpers.setFloaterValue($fader.find('.floater'), floaterConvert(faderPct))
|
||||||
|
}
|
||||||
|
|
||||||
$fader.parent().triggerHandler('fader_change', {percentage: faderPct, dragging: false})
|
$fader.parent().triggerHandler('fader_change', {percentage: faderPct, dragging: false})
|
||||||
|
|
||||||
setHandlePosition($fader, faderPct);
|
setHandlePosition($fader, faderPct);
|
||||||
|
|
@ -61,9 +67,9 @@
|
||||||
|
|
||||||
function setHandlePosition($fader, value) {
|
function setHandlePosition($fader, value) {
|
||||||
var ratio, position;
|
var ratio, position;
|
||||||
var $handle = $fader.find('div[control="fader-handle"]');
|
var $handle = $fader.find('div[data-control="fader-handle"]');
|
||||||
|
|
||||||
var orientation = $fader.attr('orientation');
|
var orientation = $fader.attr('data-orientation');
|
||||||
var handleCssAttribute = getHandleCssAttribute($fader);
|
var handleCssAttribute = getHandleCssAttribute($fader);
|
||||||
|
|
||||||
// required because this method is entered directly when from a callback
|
// required because this method is entered directly when from a callback
|
||||||
|
|
@ -81,7 +87,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function faderValue($fader, e, offset) {
|
function faderValue($fader, e, offset) {
|
||||||
var orientation = $fader.attr('orientation');
|
var orientation = $fader.attr('data-orientation');
|
||||||
var getPercentFunction = getVerticalFaderPercent;
|
var getPercentFunction = getVerticalFaderPercent;
|
||||||
var relativePosition = offset.top;
|
var relativePosition = offset.top;
|
||||||
if (orientation && orientation == 'horizontal') {
|
if (orientation && orientation == 'horizontal') {
|
||||||
|
|
@ -92,7 +98,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHandleCssAttribute($fader) {
|
function getHandleCssAttribute($fader) {
|
||||||
var orientation = $fader.attr('orientation');
|
var orientation = $fader.attr('data-orientation');
|
||||||
return (orientation === 'horizontal') ? 'left' : 'top';
|
return (orientation === 'horizontal') ? 'left' : 'top';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,12 +140,34 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// simple snap feature to stick to the mid point
|
||||||
|
if(faderPct > 46 && faderPct < 54 && $draggingFader.data('snap')) {
|
||||||
|
faderPct = 50
|
||||||
|
var orientation = $draggingFader.attr('data-orientation');
|
||||||
|
if(orientation == 'horizontal') {
|
||||||
|
var width = $draggingFader.width()
|
||||||
|
var left = width / 2
|
||||||
|
ui.position.left = left
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var height = $draggingFader.height()
|
||||||
|
var top = height / 2
|
||||||
|
ui.position.top = top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var floaterConvert = $draggingFaderHandle.data('floaterConverter')
|
||||||
|
|
||||||
|
if(floaterConvert && $floater) {
|
||||||
|
window.JK.FaderHelpers.setFloaterValue($floater, floaterConvert(faderPct))
|
||||||
|
}
|
||||||
$draggingFader.parent().triggerHandler('fader_change', {percentage: faderPct, dragging: true})
|
$draggingFader.parent().triggerHandler('fader_change', {percentage: faderPct, dragging: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFaderDragStart(e, ui) {
|
function onFaderDragStart(e, ui) {
|
||||||
$draggingFaderHandle = $(this);
|
$draggingFaderHandle = $(this);
|
||||||
$draggingFader = $draggingFaderHandle.closest('div[control="fader"]');
|
$draggingFader = $draggingFaderHandle.closest('div[data-control="fader"]');
|
||||||
|
$floater = $draggingFaderHandle.find('.floater')
|
||||||
draggingOrientation = $draggingFader.attr('orientation');
|
draggingOrientation = $draggingFader.attr('orientation');
|
||||||
|
|
||||||
var mediaControlsDisabled = $draggingFaderHandle.data('media-controls-disabled');
|
var mediaControlsDisabled = $draggingFaderHandle.data('media-controls-disabled');
|
||||||
|
|
@ -210,12 +238,12 @@
|
||||||
|
|
||||||
selector.html(g._.template(templateSource, options));
|
selector.html(g._.template(templateSource, options));
|
||||||
|
|
||||||
selector.find('div[control="fader"]')
|
selector.find('div[data-control="fader"]')
|
||||||
.data('media-controls-disabled', selector.data('media-controls-disabled'))
|
.data('media-controls-disabled', selector.data('media-controls-disabled'))
|
||||||
.data('media-track-opener', selector.data('media-track-opener'))
|
.data('media-track-opener', selector.data('media-track-opener'))
|
||||||
.data('showHelpAboutMediaMixers', selector.data('showHelpAboutMediaMixers'))
|
.data('showHelpAboutMediaMixers', selector.data('showHelpAboutMediaMixers'))
|
||||||
|
|
||||||
selector.find('div[control="fader-handle"]').draggable({
|
selector.find('div[data-control="fader-handle"]').draggable({
|
||||||
drag: onFaderDrag,
|
drag: onFaderDrag,
|
||||||
start: onFaderDragStart,
|
start: onFaderDragStart,
|
||||||
stop: onFaderDragStop,
|
stop: onFaderDragStop,
|
||||||
|
|
@ -233,6 +261,43 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
renderFader2: function (selector, userOptions, floaterConverter) {
|
||||||
|
selector = $(selector);
|
||||||
|
if (userOptions === undefined) {
|
||||||
|
throw ("renderFader: userOptions is required");
|
||||||
|
}
|
||||||
|
var renderDefaults = {
|
||||||
|
faderType: "vertical"
|
||||||
|
};
|
||||||
|
var options = $.extend({}, renderDefaults, userOptions);
|
||||||
|
|
||||||
|
selector.find('div[data-control="fader"]')
|
||||||
|
.data('media-controls-disabled', selector.data('media-controls-disabled'))
|
||||||
|
.data('media-track-opener', selector.data('media-track-opener'))
|
||||||
|
.data('showHelpAboutMediaMixers', selector.data('showHelpAboutMediaMixers'))
|
||||||
|
.data('floaterConverter', floaterConverter)
|
||||||
|
.data('snap', userOptions.snap)
|
||||||
|
|
||||||
|
selector.find('div[data-control="fader-handle"]').draggable({
|
||||||
|
drag: onFaderDrag,
|
||||||
|
start: onFaderDragStart,
|
||||||
|
stop: onFaderDragStop,
|
||||||
|
containment: "parent",
|
||||||
|
axis: options.faderType === 'horizontal' ? 'x' : 'y'
|
||||||
|
}).data('media-controls-disabled', selector.data('media-controls-disabled'))
|
||||||
|
.data('media-track-opener', selector.data('media-track-opener'))
|
||||||
|
.data('showHelpAboutMediaMixers', selector.data('showHelpAboutMediaMixers'))
|
||||||
|
.data('floaterConverter', floaterConverter)
|
||||||
|
.data('snap', userOptions.snap)
|
||||||
|
|
||||||
|
// Embed any custom styles, applied to the .fader below selector
|
||||||
|
if ("style" in options) {
|
||||||
|
for (var key in options.style) {
|
||||||
|
selector.find(' .fader').css(key, options.style[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
convertLinearToDb: function (input) {
|
convertLinearToDb: function (input) {
|
||||||
|
|
||||||
// deal with extremes better
|
// deal with extremes better
|
||||||
|
|
@ -263,27 +328,48 @@
|
||||||
|
|
||||||
// composite function resembling audio taper
|
// composite function resembling audio taper
|
||||||
if (input <= 1) { return -80; }
|
if (input <= 1) { return -80; }
|
||||||
if (input <= 28) { return (2 * input - 80); }
|
if (input <= 28) { return Math.round((2 * input - 80)); } // -78 to -24 db
|
||||||
if (input <= 79) { return (0.5 * input - 38); }
|
if (input <= 79) { return Math.round((0.5 * input - 38)); } // -24 to 1.5 db
|
||||||
if (input < 99) { return (0.875 * input - 67.5); }
|
if (input < 99) { return Math.round((0.875 * input - 67.5)); } // 1.625 - 19.125 db
|
||||||
if (input >= 99) { return 20; }
|
if (input >= 99) { return 20; }
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
convertAudioTaperToPercent: function(db) {
|
||||||
|
if(db <= -78) { return 0}
|
||||||
|
if(db <= -24) { return (db + 80) / 2 }
|
||||||
|
if(db <= 1.5) { return (db + 38) / .5 }
|
||||||
|
if(db <= 19.125) { return (db + 67.5) / 0.875 }
|
||||||
|
return 100;
|
||||||
|
},
|
||||||
|
|
||||||
setFaderValue: function (faderId, faderValue) {
|
|
||||||
var $fader = $('[fader-id="' + faderId + '"]');
|
setFaderValue: function (faderId, faderValue, floaterValue) {
|
||||||
|
var $fader = $('[data-fader-id="' + faderId + '"]');
|
||||||
this.setHandlePosition($fader, faderValue);
|
this.setHandlePosition($fader, faderValue);
|
||||||
|
if(floaterValue !== undefined) {
|
||||||
|
var $floater = $fader.find('.floater')
|
||||||
|
this.setFloaterValue($floater, floaterValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
showFader: function(faderId) {
|
||||||
|
var $fader = $('[data-fader-id="' + faderId + '"]');
|
||||||
|
$fader.find('div[data-control="fader-handle"]').show()
|
||||||
},
|
},
|
||||||
|
|
||||||
setHandlePosition: function ($fader, faderValue) {
|
setHandlePosition: function ($fader, faderValue) {
|
||||||
draggingOrientation = $fader.attr('orientation');
|
draggingOrientation = $fader.attr('data-orientation');
|
||||||
setHandlePosition($fader, faderValue);
|
setHandlePosition($fader, faderValue);
|
||||||
draggingOrientation = null;
|
draggingOrientation = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setFloaterValue: function($floater, floaterValue) {
|
||||||
|
$floater.text(floaterValue)
|
||||||
|
},
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
$('body').on('click', 'div[control="fader"]', faderClick);
|
$('body').on('click', 'div[data-control="fader"]', faderClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
context.JK = context.JK || {};
|
context.JK = context.JK || {};
|
||||||
context.JK.FakeJamClient = function(app, p2pMessageFactory) {
|
context.JK.FakeJamClient = function(app, p2pMessageFactory) {
|
||||||
var ChannelGroupIds = context.JK.ChannelGroupIds;
|
var ChannelGroupIds = context.JK.ChannelGroupIds
|
||||||
var logger = context.JK.logger;
|
var logger = context.JK.logger;
|
||||||
logger.info("*** Fake JamClient instance initialized. ***");
|
logger.info("*** Fake JamClient instance initialized. ***");
|
||||||
|
|
||||||
|
|
@ -170,22 +170,22 @@
|
||||||
function FTUEGetMusicInputs() {
|
function FTUEGetMusicInputs() {
|
||||||
dbg('FTUEGetMusicInputs');
|
dbg('FTUEGetMusicInputs');
|
||||||
return {
|
return {
|
||||||
"i~11~MultiChannel (FW AP Multi)~0^i~11~Multichannel (FW AP Multi)~1":
|
"i~11~MultiChannel (FWAPMulti)~0^i~11~Multichannel (FWAPMulti)~1":
|
||||||
"Multichannel (FW AP Multi) - Channel 1/Multichannel (FW AP Multi) - Channel 2"
|
"Multichannel (FWAPMulti) - Channel 1/Multichannel (FWAPMulti) - Channel 2"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function FTUEGetMusicOutputs() {
|
function FTUEGetMusicOutputs() {
|
||||||
dbg('FTUEGetMusicOutputs');
|
dbg('FTUEGetMusicOutputs');
|
||||||
return {
|
return {
|
||||||
"o~11~Multichannel (FW AP Multi)~0^o~11~Multichannel (FW AP Multi)~1":
|
"o~11~Multichannel (FWAPMulti)~0^o~11~Multichannel (FWAPMulti)~1":
|
||||||
"Multichannel (FW AP Multi) - Channel 1/Multichannel (FW AP Multi) - Channel 2"
|
"Multichannel (FWAPMulti) - Channel 1/Multichannel (FWAPMulti) - Channel 2"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function FTUEGetChatInputs() {
|
function FTUEGetChatInputs() {
|
||||||
dbg('FTUEGetChatInputs');
|
dbg('FTUEGetChatInputs');
|
||||||
return {
|
return {
|
||||||
"i~11~MultiChannel (FW AP Multi)~0^i~11~Multichannel (FW AP Multi)~1":
|
"i~11~MultiChannel (FWAPMulti)~0^i~11~Multichannel (FWAPMulti)~1":
|
||||||
"Multichannel (FW AP Multi) - Channel 1/Multichannel (FW AP Multi) - Channel 2"
|
"Multichannel (FWAPMulti) - Channel 1/Multichannel (FWAPMulti) - Channel 2"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function FTUEGetChannels() {
|
function FTUEGetChannels() {
|
||||||
|
|
@ -450,7 +450,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function GetASIODevices() {
|
function GetASIODevices() {
|
||||||
var response =[{"device_id":0,"device_name":"Realtek High Definition Audio","device_type": 0,"interfaces":[{"interface_id":0,"interface_name":"Realtek HDA SPDIF Out","pins":[{"is_input":false,"pin_id":0,"pin_name":"PC Speaker"}]},{"interface_id":1,"interface_name":"Realtek HD Audio rear output","pins":[{"is_input":false,"pin_id":0,"pin_name":"PC Speaker"}]},{"interface_id":2,"interface_name":"Realtek HD Audio Mic input","pins":[{"is_input":true,"pin_id":0,"pin_name":"Recording Control"}]},{"interface_id":3,"interface_name":"Realtek HD Audio Line input","pins":[{"is_input":true,"pin_id":0,"pin_name":"Recording Control"}]},{"interface_id":4,"interface_name":"Realtek HD Digital input","pins":[{"is_input":true,"pin_id":0,"pin_name":"Capture"}]},{"interface_id":5,"interface_name":"Realtek HD Audio Stereo input","pins":[{"is_input":true,"pin_id":0,"pin_name":"Recording Control"}]}],"wavert_supported":false},{"device_id":1,"device_name":"M-Audio FW Audiophile","device_type": 1,"interfaces":[{"interface_id":0,"interface_name":"FW AP Multi","pins":[{"is_input":false,"pin_id":0,"pin_name":"Output"},{"is_input":true,"pin_id":1,"pin_name":"Input"}]},{"interface_id":1,"interface_name":"FW AP 1/2","pins":[{"is_input":false,"pin_id":0,"pin_name":"Output"},{"is_input":true,"pin_id":1,"pin_name":"Input"}]},{"interface_id":2,"interface_name":"FW AP SPDIF","pins":[{"is_input":false,"pin_id":0,"pin_name":"Output"},{"is_input":true,"pin_id":1,"pin_name":"Input"}]},{"interface_id":3,"interface_name":"FW AP 3/4","pins":[{"is_input":false,"pin_id":0,"pin_name":"Output"}]}],"wavert_supported":false},{"device_id":2,"device_name":"Virtual Audio Cable","device_type": 2,"interfaces":[{"interface_id":0,"interface_name":"Virtual Cable 2","pins":[{"is_input":true,"pin_id":0,"pin_name":"Capture"},{"is_input":false,"pin_id":1,"pin_name":"Output"}]},{"interface_id":1,"interface_name":"Virtual Cable 1","pins":[{"is_input":true,"pin_id":0,"pin_name":"Capture"},{"is_input":false,"pin_id":1,"pin_name":"Output"}]}],"wavert_supported":false},{"device_id":3,"device_name":"WebCamDV WDM Audio Capture","device_type": 3,"interfaces":[{"interface_id":0,"interface_name":"WebCamDV Audio","pins":[{"is_input":true,"pin_id":0,"pin_name":"Recording Control"},{"is_input":false,"pin_id":1,"pin_name":"Volume Control"}]}],"wavert_supported":false}];
|
var response =[{"device_id":0,"device_name":"Realtek High Definition Audio","device_type": 0,"interfaces":[{"interface_id":0,"interface_name":"Realtek HDA SPDIF Out","pins":[{"is_input":false,"pin_id":0,"pin_name":"PC Speaker"}]},{"interface_id":1,"interface_name":"Realtek HD Audio rear output","pins":[{"is_input":false,"pin_id":0,"pin_name":"PC Speaker"}]},{"interface_id":2,"interface_name":"Realtek HD Audio Mic input","pins":[{"is_input":true,"pin_id":0,"pin_name":"Recording Control"}]},{"interface_id":3,"interface_name":"Realtek HD Audio Line input","pins":[{"is_input":true,"pin_id":0,"pin_name":"Recording Control"}]},{"interface_id":4,"interface_name":"Realtek HD Digital input","pins":[{"is_input":true,"pin_id":0,"pin_name":"Capture"}]},{"interface_id":5,"interface_name":"Realtek HD Audio Stereo input","pins":[{"is_input":true,"pin_id":0,"pin_name":"Recording Control"}]}],"wavert_supported":false},{"device_id":1,"device_name":"M-Audio FW Audiophile","device_type": 1,"interfaces":[{"interface_id":0,"interface_name":"FWAPMulti","pins":[{"is_input":false,"pin_id":0,"pin_name":"Output"},{"is_input":true,"pin_id":1,"pin_name":"Input"}]},{"interface_id":1,"interface_name":"FW AP 1/2","pins":[{"is_input":false,"pin_id":0,"pin_name":"Output"},{"is_input":true,"pin_id":1,"pin_name":"Input"}]},{"interface_id":2,"interface_name":"FW AP SPDIF","pins":[{"is_input":false,"pin_id":0,"pin_name":"Output"},{"is_input":true,"pin_id":1,"pin_name":"Input"}]},{"interface_id":3,"interface_name":"FW AP 3/4","pins":[{"is_input":false,"pin_id":0,"pin_name":"Output"}]}],"wavert_supported":false},{"device_id":2,"device_name":"Virtual Audio Cable","device_type": 2,"interfaces":[{"interface_id":0,"interface_name":"Virtual Cable 2","pins":[{"is_input":true,"pin_id":0,"pin_name":"Capture"},{"is_input":false,"pin_id":1,"pin_name":"Output"}]},{"interface_id":1,"interface_name":"Virtual Cable 1","pins":[{"is_input":true,"pin_id":0,"pin_name":"Capture"},{"is_input":false,"pin_id":1,"pin_name":"Output"}]}],"wavert_supported":false},{"device_id":3,"device_name":"WebCamDV WDM Audio Capture","device_type": 3,"interfaces":[{"interface_id":0,"interface_name":"WebCamDV Audio","pins":[{"is_input":true,"pin_id":0,"pin_name":"Recording Control"},{"is_input":false,"pin_id":1,"pin_name":"Volume Control"}]}],"wavert_supported":false}];
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -475,8 +475,8 @@
|
||||||
}
|
}
|
||||||
function SessionGetControlState(mixerIds, isMasterOrPersonal) {
|
function SessionGetControlState(mixerIds, isMasterOrPersonal) {
|
||||||
dbg("SessionGetControlState");
|
dbg("SessionGetControlState");
|
||||||
var groups = [
|
var groups =
|
||||||
ChannelGroupIds.MasterGroup,
|
[ChannelGroupIds.MasterGroup,
|
||||||
ChannelGroupIds.MonitorGroup,
|
ChannelGroupIds.MonitorGroup,
|
||||||
ChannelGroupIds.AudioInputMusicGroup,
|
ChannelGroupIds.AudioInputMusicGroup,
|
||||||
ChannelGroupIds.AudioInputChatGroup,
|
ChannelGroupIds.AudioInputChatGroup,
|
||||||
|
|
@ -485,13 +485,12 @@
|
||||||
ChannelGroupIds.UserChatInputGroup,
|
ChannelGroupIds.UserChatInputGroup,
|
||||||
ChannelGroupIds.PeerMediaTrackGroup,
|
ChannelGroupIds.PeerMediaTrackGroup,
|
||||||
ChannelGroupIds.JamTrackGroup,
|
ChannelGroupIds.JamTrackGroup,
|
||||||
ChannelGroupIds.MetronomeGroup
|
ChannelGroupIds.MetronomeGroup];
|
||||||
]
|
|
||||||
var names = [
|
var names = [
|
||||||
"FW AP Multi",
|
"FWAPMulti",
|
||||||
"FW AP Multi",
|
"FWAPMulti",
|
||||||
"FW AP Multi",
|
"FWAPMulti",
|
||||||
"FW AP Multi",
|
"FWAPMulti",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
@ -545,6 +544,7 @@
|
||||||
stereo: true,
|
stereo: true,
|
||||||
volume_left: -40,
|
volume_left: -40,
|
||||||
volume_right:-40,
|
volume_right:-40,
|
||||||
|
pan: 0,
|
||||||
instrument_id:50, // see globals.js
|
instrument_id:50, // see globals.js
|
||||||
mode: isMasterOrPersonal,
|
mode: isMasterOrPersonal,
|
||||||
rid: mixerIds[i]
|
rid: mixerIds[i]
|
||||||
|
|
@ -554,10 +554,10 @@
|
||||||
}
|
}
|
||||||
function SessionGetIDs() {
|
function SessionGetIDs() {
|
||||||
return [
|
return [
|
||||||
"FW AP Multi_0_10000",
|
"FWAPMulti_0_10000",
|
||||||
"FW AP Multi_1_10100",
|
"FWAPMulti_1_10100",
|
||||||
"FW AP Multi_2_10200",
|
"FWAPMulti_2_10200",
|
||||||
"FW AP Multi_3_10500",
|
"FWAPMulti_3_10500",
|
||||||
"User@208.191.152.98#",
|
"User@208.191.152.98#",
|
||||||
"User@208.191.152.98_*"
|
"User@208.191.152.98_*"
|
||||||
];
|
];
|
||||||
|
|
@ -624,9 +624,9 @@
|
||||||
|
|
||||||
function doCallbacks() {
|
function doCallbacks() {
|
||||||
var names = ["vu"];
|
var names = ["vu"];
|
||||||
//var ids = ["FW AP Multi_2_10200", "FW AP Multi_0_10000"];
|
//var ids = ["FWAPMulti_2_10200", "FWAPMulti_0_10000"];
|
||||||
var ids= ["i~11~MultiChannel (FW AP Multi)~0^i~11~Multichannel (FW AP Multi)~1",
|
var ids= ["i~11~MultiChannel (FWAPMulti)~0^i~11~Multichannel (FWAPMulti)~1",
|
||||||
"i~11~MultiChannel (FW AP Multi)~0^i~11~Multichannel (FW AP Multi)~2"];
|
"i~11~MultiChannel (FWAPMulti)~0^i~11~Multichannel (FWAPMulti)~2"];
|
||||||
|
|
||||||
var args = [];
|
var args = [];
|
||||||
for (var i=0; i<ids.length; i++) {
|
for (var i=0; i<ids.length; i++) {
|
||||||
|
|
|
||||||
|
|
@ -93,8 +93,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStartRecording(from, payload) {
|
function onStartRecording(from, payload) {
|
||||||
logger.debug("received start recording request from " + from);
|
logger.debug("received start recording request from " + from, context.SessionStore.isRecording);
|
||||||
if(context.JK.CurrentSessionModel.recordingModel.isRecording()) {
|
if(context.SessionStore.isRecording) {
|
||||||
// reject the request to start the recording
|
// reject the request to start the recording
|
||||||
context.JK.JamServer.sendP2PMessage(from, JSON.stringify(p2pMessageFactory.startRecordingAck(payload.recordingId, false, "already-recording", null)));
|
context.JK.JamServer.sendP2PMessage(from, JSON.stringify(p2pMessageFactory.startRecordingAck(payload.recordingId, false, "already-recording", null)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
var $includeType = null;
|
var $includeType = null;
|
||||||
var didLoadAllFeeds = false, isLoading = false;
|
var didLoadAllFeeds = false, isLoading = false;
|
||||||
var $templateRecordingDiscardedSoon = null;
|
var $templateRecordingDiscardedSoon = null;
|
||||||
|
var defaults;
|
||||||
|
|
||||||
function defaultQuery() {
|
function defaultQuery() {
|
||||||
var query = { limit: feedBatchSize };
|
var query = { limit: feedBatchSize };
|
||||||
|
|
@ -47,9 +48,9 @@
|
||||||
var currentQuery = defaultQuery();
|
var currentQuery = defaultQuery();
|
||||||
|
|
||||||
// specify search criteria based on form
|
// specify search criteria based on form
|
||||||
currentQuery.sort = $sortFeedBy.val();
|
currentQuery.sort = $sortFeedBy.length == 0 ? defaults.sort : $sortFeedBy.val();
|
||||||
currentQuery.time_range = $includeDate.val();
|
currentQuery.time_range = $includeDate.length == 0 ? defaults.time_range : $includeDate.val();
|
||||||
currentQuery.type = $includeType.val();
|
currentQuery.type = $includeType.length == 0 ? defaults.type : $includeType.val();
|
||||||
|
|
||||||
return currentQuery;
|
return currentQuery;
|
||||||
}
|
}
|
||||||
|
|
@ -423,6 +424,11 @@
|
||||||
ui.addSessionLike(feed.id, JK.currentUserId, $('.likes', $feedItem), $('.btn-like', $feedItem))
|
ui.addSessionLike(feed.id, JK.currentUserId, $('.likes', $feedItem), $('.btn-like', $feedItem))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// should we show the select checkbox?
|
||||||
|
if(!defaults.show_checkbox) {
|
||||||
|
$feedItem.find('.select-box').hide();
|
||||||
|
}
|
||||||
|
|
||||||
// put the feed item on the page
|
// put the feed item on the page
|
||||||
renderFeed($feedItem);
|
renderFeed($feedItem);
|
||||||
|
|
||||||
|
|
@ -448,6 +454,7 @@
|
||||||
mix_class: feed['has_mix?'] ? 'has-mix' : 'no-mix',
|
mix_class: feed['has_mix?'] ? 'has-mix' : 'no-mix',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("OPTIONS", options)
|
||||||
var $feedItem = $(context._.template($('#template-feed-recording').html(), options, {variable: 'data'}));
|
var $feedItem = $(context._.template($('#template-feed-recording').html(), options, {variable: 'data'}));
|
||||||
var $controls = $feedItem.find('.recording-controls');
|
var $controls = $feedItem.find('.recording-controls');
|
||||||
|
|
||||||
|
|
@ -534,6 +541,14 @@
|
||||||
|
|
||||||
context.JK.helpBubble($feedItem.find('.help-launcher'), recordingUtils.onMixHover, {}, {width:'450px', closeWhenOthersOpen: true, positions:['top', 'left', 'bottom', 'right'], offsetParent: $screen.parent()})
|
context.JK.helpBubble($feedItem.find('.help-launcher'), recordingUtils.onMixHover, {}, {width:'450px', closeWhenOthersOpen: true, positions:['top', 'left', 'bottom', 'right'], offsetParent: $screen.parent()})
|
||||||
|
|
||||||
|
// should we show the select checkbox?
|
||||||
|
if(!defaults.show_checkbox) {
|
||||||
|
$feedItem.find('.select-box').hide();
|
||||||
|
}
|
||||||
|
if(defaults.hide_avatar) {
|
||||||
|
$feedItem.find('.avatar-small.ib').hide();
|
||||||
|
}
|
||||||
|
|
||||||
// put the feed item on the page
|
// put the feed item on the page
|
||||||
renderFeed($feedItem);
|
renderFeed($feedItem);
|
||||||
|
|
||||||
|
|
@ -582,7 +597,7 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initialize(_$parent, _$scroller, _$content, _$noMorefeeds, _$refresh, _$sortFeedBy, _$includeDate, _$includeType, defaults) {
|
function initialize(_$parent, _$scroller, _$content, _$noMorefeeds, _$refresh, _$sortFeedBy, _$includeDate, _$includeType, _defaults) {
|
||||||
$screen = _$parent;
|
$screen = _$parent;
|
||||||
$scroller = _$scroller;
|
$scroller = _$scroller;
|
||||||
$content = _$content;
|
$content = _$content;
|
||||||
|
|
@ -596,12 +611,10 @@
|
||||||
if($scroller.length == 0) throw "$scroller must be specified";
|
if($scroller.length == 0) throw "$scroller must be specified";
|
||||||
if($content.length == 0) throw "$content must be specified";
|
if($content.length == 0) throw "$content must be specified";
|
||||||
if($noMoreFeeds.length == 0) throw "$noMoreFeeds must be specified";
|
if($noMoreFeeds.length == 0) throw "$noMoreFeeds must be specified";
|
||||||
if($refresh.length == 0) throw "$refresh must be specified";
|
|
||||||
if($sortFeedBy.length == 0) throw "$sortFeedBy must be specified";
|
|
||||||
if($includeDate.length == 0) throw "$includeDate must be specified";
|
|
||||||
if($includeType.length ==0) throw "$includeType must be specified";
|
|
||||||
|
|
||||||
defaults = $.extend({}, {sort: 'date', time_range: 'month', type: 'all'}, defaults)
|
// show_checkbox will show a checkbox in the upper left
|
||||||
|
defaults = $.extend({}, {sort: 'date', time_range: 'month', type: 'all', show_checkbox: false, hide_avatar: true}, _defaults)
|
||||||
|
|
||||||
// set default search criteria
|
// set default search criteria
|
||||||
$sortFeedBy.val(defaults.date)
|
$sortFeedBy.val(defaults.date)
|
||||||
$includeDate.val(defaults.time_range)
|
$includeDate.val(defaults.time_range)
|
||||||
|
|
|
||||||
|
|
@ -123,23 +123,23 @@
|
||||||
0: {"title": "", "message": ""}, // NO_EVENT,
|
0: {"title": "", "message": ""}, // NO_EVENT,
|
||||||
1: {"title": "", "message": ""}, // BACKEND_ERROR: generic error - eg P2P message error
|
1: {"title": "", "message": ""}, // BACKEND_ERROR: generic error - eg P2P message error
|
||||||
2: {"title": "", "message": ""}, // BACKEND_MIXER_CHANGE, - event that controls have been regenerated
|
2: {"title": "", "message": ""}, // BACKEND_MIXER_CHANGE, - event that controls have been regenerated
|
||||||
3: {"title": "High Packet Jitter", "message": "Your network connection is currently experiencing packet jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>."}, // PACKET_JTR,
|
3: {"title": "High Packet Jitter", "message": "Your network connection is currently experiencing packet jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // PACKET_JTR,
|
||||||
4: {"title": "High Packet Loss", "message": "Your network connection is currently experiencing packet loss at a rate that is too high to deliver good audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>." }, // PACKET_LOSS
|
4: {"title": "High Packet Loss", "message": "Your network connection is currently experiencing packet loss at a rate that is too high to deliver good audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems" }, // PACKET_LOSS
|
||||||
5: {"title": "High Packet Late", "message": "Your network connection is currently experiencing packet loss at a rate that is too high to deliver good audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>."}, // PACKET_LATE,
|
5: {"title": "High Packet Late", "message": "Your network connection is currently experiencing packet loss at a rate that is too high to deliver good audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // PACKET_LATE,
|
||||||
6: {"title": "Large Jitter Queue", "message": "Your network connection is currently experiencing packet jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>."}, // JTR_QUEUE_DEPTH,
|
6: {"title": "Large Jitter Queue", "message": "Your network connection is currently experiencing packet jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // JTR_QUEUE_DEPTH,
|
||||||
7: {"title": "High Network Jitter", "message": "Your network connection is currently experiencing network jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>."}, // NETWORK_JTR,
|
7: {"title": "High Network Jitter", "message": "Your network connection is currently experiencing network jitter at a level that is too high to deliver good audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // NETWORK_JTR,
|
||||||
8: {"title": "High Session Latency", "message": "The latency of your audio device combined with your Internet connection has become high enough to impact your session quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>." }, // NETWORK_PING,
|
8: {"title": "High Session Latency", "message": "The latency of your audio device combined with your Internet connection has become high enough to impact your session quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems" }, // NETWORK_PING,
|
||||||
9: {"title": "Bandwidth Throttled", "message": "The available bandwidth on your network has diminished, and this may impact your audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>."}, // BITRATE_THROTTLE_WARN,
|
9: {"title": "Bandwidth Throttled", "message": "The available bandwidth on your network has diminished, and this may impact your audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // BITRATE_THROTTLE_WARN,
|
||||||
10:{"title": "Low Bandwidth", "message": "The available bandwidth on your network has become too low, and this may impact your audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>." }, // BANDWIDTH_LOW
|
10:{"title": "Low Bandwidth", "message": "The available bandwidth on your network has become too low, and this may impact your audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems" }, // BANDWIDTH_LOW
|
||||||
|
|
||||||
// IO related events
|
// IO related events
|
||||||
11:{"title": "Variable Input Rate", "message": "The input rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>." }, // INPUT_IO_RATE
|
11:{"title": "Variable Input Rate", "message": "The input rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems" }, // INPUT_IO_RATE
|
||||||
12:{"title": "High Input Jitter", "message": "The input rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>."}, // INPUT_IO_JTR,
|
12:{"title": "High Input Jitter", "message": "The input rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // INPUT_IO_JTR,
|
||||||
13:{"title": "Variable Output Rate", "message": "The output rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>." }, // OUTPUT_IO_RATE
|
13:{"title": "Variable Output Rate", "message": "The output rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // OUTPUT_IO_RATE
|
||||||
14:{"title": "High Output Jitter", "message": "The output rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>."}, // OUTPUT_IO_JTR,
|
14:{"title": "High Output Jitter", "message": "The output rate of your audio device is varying too much to deliver good audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // OUTPUT_IO_JTR,
|
||||||
|
|
||||||
// CPU load related
|
// CPU load related
|
||||||
15: { "title": "CPU Utilization High", "message": "The CPU of your computer is unable to keep up with the current processing load, and this may impact your audio quality. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>." }, // CPU_LOAD
|
15: { "title": "CPU Utilization High", "message": "The CPU of your computer is unable to keep up with the current processing load, and this may impact your audio quality. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // CPU_LOAD
|
||||||
16: {"title": "Decode Violations", "message": ""}, // DECODE_VIOLATIONS,
|
16: {"title": "Decode Violations", "message": ""}, // DECODE_VIOLATIONS,
|
||||||
17: {"title": "", "message": ""}, // LAST_THRESHOLD
|
17: {"title": "", "message": ""}, // LAST_THRESHOLD
|
||||||
18: {"title": "Wifi Alert", "message": ""}, // WIFI_NETWORK_ALERT, //user or peer is using wifi
|
18: {"title": "Wifi Alert", "message": ""}, // WIFI_NETWORK_ALERT, //user or peer is using wifi
|
||||||
|
|
@ -162,10 +162,10 @@
|
||||||
33: {"title": "Client No Longer Pinned", "message": "This client is no longer designated as the source of the broadcast."}, // SESSION_LIVEBROADCAST_UNPINNED, //node unpinned by user
|
33: {"title": "Client No Longer Pinned", "message": "This client is no longer designated as the source of the broadcast."}, // SESSION_LIVEBROADCAST_UNPINNED, //node unpinned by user
|
||||||
|
|
||||||
34: {"title": "", "message": ""}, // BACKEND_STATUS_MSG, //status/informational message
|
34: {"title": "", "message": ""}, // BACKEND_STATUS_MSG, //status/informational message
|
||||||
35: {"title": "LAN Unpredictable", "message": "Your local network is adding considerable variance to transmit times. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>."}, // LOCAL_NETWORK_VARIANCE_HIGH,//the ping time via a hairpin for the user network is unnaturally high or variable.
|
35: {"title": "LAN Unpredictable", "message": "Your local network is adding considerable variance to transmit times. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // LOCAL_NETWORK_VARIANCE_HIGH,//the ping time via a hairpin for the user network is unnaturally high or variable.
|
||||||
|
|
||||||
//indicates problem with user computer stack or network itself (wifi, antivirus etc)
|
//indicates problem with user computer stack or network itself (wifi, antivirus etc)
|
||||||
36: {"title": "LAN High Latency", "message": "Your local network is adding considerable latency. For troubleshooting tips, <a href='https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems'>click here</a>."}, // LOCAL_NETWORK_LATENCY_HIGH,
|
36: {"title": "LAN High Latency", "message": "Your local network is adding considerable latency. For troubleshooting tips, click the '?'.", help: "https://jamkazam.desk.com/customer/portal/articles/1288778-troubleshoot-session-quality-problems"}, // LOCAL_NETWORK_LATENCY_HIGH,
|
||||||
37: {"title": "", "message": ""}, // RECORDING_CLOSE, //update and remove tracks from front-end
|
37: {"title": "", "message": ""}, // RECORDING_CLOSE, //update and remove tracks from front-end
|
||||||
38: {"title": "No Audio Sent", "message": ""}, // PEER_REPORTS_NO_AUDIO_RECV, //update and remove tracks from front-end
|
38: {"title": "No Audio Sent", "message": ""}, // PEER_REPORTS_NO_AUDIO_RECV, //update and remove tracks from front-end
|
||||||
39: {"title": "", "message": ""}, // SHOW_PREFERENCES, //show preferences dialog
|
39: {"title": "", "message": ""}, // SHOW_PREFERENCES, //show preferences dialog
|
||||||
|
|
@ -314,19 +314,17 @@
|
||||||
MASTER_VS_PERSONAL_MIX : 'master_vs_personal_mix'
|
MASTER_VS_PERSONAL_MIX : 'master_vs_personal_mix'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recreate ChannelGroupIDs ENUM from C++
|
context.JK.ChannelGroupIds = {
|
||||||
context.JK.ChannelGroupIds =
|
|
||||||
{
|
|
||||||
"MasterGroup": 0,
|
"MasterGroup": 0,
|
||||||
"MonitorGroup": 1,
|
"MonitorGroup": 1,
|
||||||
"MasterCatGroup": 2,
|
"MasterCatGroup" : 2,
|
||||||
"MonitorCatGroup": 3,
|
"MonitorCatGroup" : 3,
|
||||||
"AudioInputMusicGroup": 4,
|
"AudioInputMusicGroup": 4,
|
||||||
"AudioInputChatGroup": 5,
|
"AudioInputChatGroup": 5,
|
||||||
"MediaTrackGroup": 6,
|
"MediaTrackGroup": 6,
|
||||||
"StreamOutMusicGroup": 7,
|
"StreamOutMusicGroup": 7,
|
||||||
"StreamOutChatGroup": 8,
|
"StreamOutChatGroup": 8,
|
||||||
"StreamOutMediaGroup": 9,
|
"StreamOutMediaGroup" : 9,
|
||||||
"UserMusicInputGroup": 10,
|
"UserMusicInputGroup": 10,
|
||||||
"UserChatInputGroup": 11,
|
"UserChatInputGroup": 11,
|
||||||
"UserMediaInputGroup": 12,
|
"UserMediaInputGroup": 12,
|
||||||
|
|
@ -335,4 +333,34 @@
|
||||||
"JamTrackGroup": 15,
|
"JamTrackGroup": 15,
|
||||||
"MetronomeGroup": 16
|
"MetronomeGroup": 16
|
||||||
};
|
};
|
||||||
})(window,jQuery);
|
|
||||||
|
context.JK.ChannelGroupLookup = {
|
||||||
|
0: "MasterGroup",
|
||||||
|
1: "MonitorGroup",
|
||||||
|
2: "MasterCatGroup",
|
||||||
|
3: "MonitorCatGroup",
|
||||||
|
4: "AudioInputMusicGroup",
|
||||||
|
5: "AudioInputChatGroup",
|
||||||
|
6: "MediaTrackGroup",
|
||||||
|
7: "StreamOutMusicGroup",
|
||||||
|
8: "StreamOutChatGroup",
|
||||||
|
9: "StreamOutMediaGroup",
|
||||||
|
10: "UserMusicInputGroup",
|
||||||
|
11: "UserChatInputGroup",
|
||||||
|
12: "UserMediaInputGroup",
|
||||||
|
13: "PeerAudioInputMusicGroup",
|
||||||
|
14: "PeerMediaTrackGroup",
|
||||||
|
15: "JamTrackGroup",
|
||||||
|
16: "MetronomeGroup"
|
||||||
|
}
|
||||||
|
context.JK.CategoryGroupIds = {
|
||||||
|
"AudioInputMusic" : "AudioInputMusic",
|
||||||
|
"AudioInputChat" : "AudioInputChat",
|
||||||
|
"UserMusic" : "UserMusic",
|
||||||
|
"UserChat" : "UserChat",
|
||||||
|
"UserMedia" : "UserMedia",
|
||||||
|
"MediaTrack" : "MediaTrack",
|
||||||
|
"Metronome" : "Metronome"
|
||||||
|
}
|
||||||
|
|
||||||
|
})(window,jQuery);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
function bigHelpOptions(options) {
|
function bigHelpOptions(options) {
|
||||||
return {positions: options.positions, offsetParent: options.offsetParent,
|
return {positions: options.positions, offsetParent: options.offsetParent,
|
||||||
|
width:options.width,
|
||||||
spikeGirth: 15,
|
spikeGirth: 15,
|
||||||
spikeLength: 20,
|
spikeLength: 20,
|
||||||
fill: 'white',
|
fill: 'white',
|
||||||
|
|
@ -68,13 +69,13 @@
|
||||||
helpBubble.jamtrackLandingPreview($preview, $preview.offsetParent())
|
helpBubble.jamtrackLandingPreview($preview, $preview.offsetParent())
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
helpBubble.jamtrackLandingVideo($video, $video.offsetParent())
|
helpBubble.jamtrackLandingVideo($video, $video.closest('.row'))
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
helpBubble.jamtrackLandingCta($ctaButton, $alternativeCta)
|
helpBubble.jamtrackLandingCta($ctaButton, $alternativeCta)
|
||||||
}, 11000); // 5 seconds on top of 6 second show time of bubbles
|
}, 11000); // 5 seconds on top of 6 second show time of bubbles
|
||||||
}, 11000); // 5 seconds on top of 6 second show time of bubbles
|
}, 11000); // 5 seconds on top of 6 second show time of bubbles
|
||||||
}, 1500)
|
}, 15000)
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
@ -101,18 +102,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
helpBubble.jamtrackLandingPreview = function($element, $offsetParent) {
|
helpBubble.jamtrackLandingPreview = function($element, $offsetParent) {
|
||||||
context.JK.prodBubble($element, 'jamtrack-landing-preview', {}, bigHelpOptions({positions:['right'], offsetParent: $offsetParent}))
|
console.log("SHOWING THE PREVIEW BUBBLE")
|
||||||
|
context.JK.prodBubble($element, 'jamtrack-landing-preview', {}, bigHelpOptions({positions:['right', 'top'], offsetParent: $offsetParent, width:250}))
|
||||||
}
|
}
|
||||||
|
|
||||||
helpBubble.jamtrackLandingVideo = function($element, $offsetParent) {
|
helpBubble.jamtrackLandingVideo = function($element, $offsetParent) {
|
||||||
context.JK.prodBubble($element, 'jamtrack-landing-video', {}, bigHelpOptions({positions:['left'], offsetParent: $offsetParent}))
|
context.JK.prodBubble($element, 'jamtrack-landing-video', {}, bigHelpOptions({positions:['top', 'right'], offsetParent: $offsetParent}))
|
||||||
}
|
}
|
||||||
|
|
||||||
helpBubble.jamtrackLandingCta = function($element, $alternativeElement) {
|
helpBubble.jamtrackLandingCta = function($element, $alternativeElement) {
|
||||||
if ($element.visible()) {
|
if (!$alternativeElement || $element.visible()) {
|
||||||
context.JK.prodBubble($element, 'jamtrack-landing-cta', {}, bigHelpOptions({positions:['left']}))
|
context.JK.prodBubble($element, 'jamtrack-landing-cta', {}, bigHelpOptions({positions:['top', 'right'], width:240}))
|
||||||
}
|
}
|
||||||
else {
|
else if($alternativeElement) {
|
||||||
context.JK.prodBubble($alternativeElement, 'jamtrack-landing-cta', {}, bigHelpOptions({positions:['right']}))
|
context.JK.prodBubble($alternativeElement, 'jamtrack-landing-cta', {}, bigHelpOptions({positions:['right']}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
var rest = new context.JK.Rest();
|
var rest = new context.JK.Rest();
|
||||||
var _instruments = []; // will be list of structs: [ {label:xxx, value:yyy}, {...}, ... ]
|
var _instruments = []; // will be list of structs: [ {label:xxx, value:yyy}, {...}, ... ]
|
||||||
var _rsvp = false;
|
var _rsvp = false;
|
||||||
|
var _noICheck = false;
|
||||||
if (typeof(_parentSelector)=="undefined") {_parentSelector=null}
|
if (typeof(_parentSelector)=="undefined") {_parentSelector=null}
|
||||||
var _parentSelector = parentSelector;
|
var _parentSelector = parentSelector;
|
||||||
var deferredInstruments = null;
|
var deferredInstruments = null;
|
||||||
|
|
@ -109,13 +110,15 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.each(instrumentList, function (index, value) {
|
$.each(instrumentList, function (index, value) {
|
||||||
$('input[type="checkbox"][session-instrument-id="' + value.id + '"]')
|
var $item = $('input[type="checkbox"][session-instrument-id="' + value.id + '"]')
|
||||||
.attr('checked', 'checked')
|
.attr('checked', 'checked')
|
||||||
.iCheck({
|
if(!_noICheck) {
|
||||||
|
$item.iCheck({
|
||||||
checkboxClass: 'icheckbox_minimal',
|
checkboxClass: 'icheckbox_minimal',
|
||||||
radioClass: 'iradio_minimal',
|
radioClass: 'iradio_minimal',
|
||||||
inheritClass: true
|
inheritClass: true
|
||||||
});
|
})
|
||||||
|
}
|
||||||
if (_rsvp) {
|
if (_rsvp) {
|
||||||
$('select[session-instrument-id="' + value.id + '"].rsvp-count', _parentSelector).val(value.count);
|
$('select[session-instrument-id="' + value.id + '"].rsvp-count', _parentSelector).val(value.count);
|
||||||
$('select[session-instrument-id="' + value.id + '"].rsvp-level', _parentSelector).val(value.level);
|
$('select[session-instrument-id="' + value.id + '"].rsvp-level', _parentSelector).val(value.level);
|
||||||
|
|
@ -126,8 +129,9 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initialize(rsvp) {
|
function initialize(rsvp, noICheck) {
|
||||||
_rsvp = rsvp;
|
_rsvp = rsvp;
|
||||||
|
_noICheck = noICheck;
|
||||||
// XXX; _instruments should be populated in a template, rather than round-trip to server
|
// XXX; _instruments should be populated in a template, rather than round-trip to server
|
||||||
if(!context.JK.InstrumentSelectorDeferred) {
|
if(!context.JK.InstrumentSelectorDeferred) {
|
||||||
// this dance is to make sure there is only one server request instead of InstrumentSelector instances *
|
// this dance is to make sure there is only one server request instead of InstrumentSelector instances *
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,14 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function deleteMusicNotation(options) {
|
||||||
|
return $.ajax({
|
||||||
|
type: "DELETE",
|
||||||
|
url: "/api/music_notations/" +options.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function legacyJoinSession(options) {
|
function legacyJoinSession(options) {
|
||||||
var sessionId = options["session_id"];
|
var sessionId = options["session_id"];
|
||||||
delete options["session_id"];
|
delete options["session_id"];
|
||||||
|
|
@ -478,6 +486,14 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteParticipant(clientId) {
|
||||||
|
var url = "/api/participants/" + clientId;
|
||||||
|
return $.ajax({
|
||||||
|
type: "DELETE",
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function login(options) {
|
function login(options) {
|
||||||
var url = '/api/auths/login';
|
var url = '/api/auths/login';
|
||||||
|
|
||||||
|
|
@ -507,17 +523,13 @@
|
||||||
|
|
||||||
function getUserProfile(options) {
|
function getUserProfile(options) {
|
||||||
var id = getId(options);
|
var id = getId(options);
|
||||||
var profile = null;
|
return $.ajax({
|
||||||
if (id != null && typeof(id) != 'undefined') {
|
|
||||||
profile = $.ajax({
|
|
||||||
type: "GET",
|
type: "GET",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
url: "/api/users/" + id + "/profile",
|
url: "/api/users/" + id + "/profile",
|
||||||
processData: false
|
processData: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAffiliatePartner(options) {
|
function createAffiliatePartner(options) {
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
|
|
@ -1827,6 +1839,7 @@
|
||||||
this.createScheduledSession = createScheduledSession;
|
this.createScheduledSession = createScheduledSession;
|
||||||
this.uploadMusicNotations = uploadMusicNotations;
|
this.uploadMusicNotations = uploadMusicNotations;
|
||||||
this.getMusicNotation = getMusicNotation;
|
this.getMusicNotation = getMusicNotation;
|
||||||
|
this.deleteMusicNotation = deleteMusicNotation;
|
||||||
this.getBroadcastNotification = getBroadcastNotification;
|
this.getBroadcastNotification = getBroadcastNotification;
|
||||||
this.quietBroadcastNotification = quietBroadcastNotification;
|
this.quietBroadcastNotification = quietBroadcastNotification;
|
||||||
this.legacyJoinSession = legacyJoinSession;
|
this.legacyJoinSession = legacyJoinSession;
|
||||||
|
|
@ -1882,6 +1895,7 @@
|
||||||
this.addRecordingLike = addRecordingLike;
|
this.addRecordingLike = addRecordingLike;
|
||||||
this.addPlayablePlay = addPlayablePlay;
|
this.addPlayablePlay = addPlayablePlay;
|
||||||
this.getSession = getSession;
|
this.getSession = getSession;
|
||||||
|
this.deleteParticipant = deleteParticipant;
|
||||||
this.getClientDownloads = getClientDownloads;
|
this.getClientDownloads = getClientDownloads;
|
||||||
this.createEmailInvitations = createEmailInvitations;
|
this.createEmailInvitations = createEmailInvitations;
|
||||||
this.createMusicianInvite = createMusicianInvite;
|
this.createMusicianInvite = createMusicianInvite;
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,6 @@ context.JK.JamTrackScreen=class JamTrackScreen
|
||||||
rest.addJamtrackToShoppingCart(params).done((response) =>
|
rest.addJamtrackToShoppingCart(params).done((response) =>
|
||||||
if(isFree)
|
if(isFree)
|
||||||
if context.JK.currentUserId?
|
if context.JK.currentUserId?
|
||||||
alert("TODO")
|
|
||||||
context.JK.currentUserFreeJamTrack = true # make sure the user sees no more free notices
|
context.JK.currentUserFreeJamTrack = true # make sure the user sees no more free notices
|
||||||
context.location = '/client#/redeemComplete'
|
context.location = '/client#/redeemComplete'
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@
|
||||||
var errors = JSON.parse(jqXHR.responseText);
|
var errors = JSON.parse(jqXHR.responseText);
|
||||||
var $errors = context.JK.format_all_errors(errors);
|
var $errors = context.JK.format_all_errors(errors);
|
||||||
logger.debug("Unprocessable entity sent from server:", JSON.stringify(errors))
|
logger.debug("Unprocessable entity sent from server:", JSON.stringify(errors))
|
||||||
this.notify({title: title, text: $errors, icon_url: "/assets/content/icon_alert_big.png"})
|
this.notify({title: title || "Validation Error", text: $errors, icon_url: "/assets/content/icon_alert_big.png"})
|
||||||
}
|
}
|
||||||
else if(jqXHR.status == 403) {
|
else if(jqXHR.status == 403) {
|
||||||
logger.debug("permission error sent from server:", jqXHR.responseText)
|
logger.debug("permission error sent from server:", jqXHR.responseText)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
$.fn.metronomePlaybackMode = function(options) {
|
$.fn.metronomePlaybackMode = function(options) {
|
||||||
|
|
||||||
options = options || {mode: 'self'}
|
options = $.extend(false, {mode: 'self', positions: ['top']}, options);
|
||||||
|
|
||||||
return this.each(function(index) {
|
return this.each(function(index) {
|
||||||
|
|
||||||
|
|
@ -78,8 +78,8 @@
|
||||||
spikeLength:0,
|
spikeLength:0,
|
||||||
width:180,
|
width:180,
|
||||||
closeWhenOthersOpen: true,
|
closeWhenOthersOpen: true,
|
||||||
offsetParent: $parent.offsetParent(),
|
offsetParent: options.offsetParent || $parent.offsetParent(),
|
||||||
positions:['top'],
|
positions: options.positions,
|
||||||
preShow: function() {
|
preShow: function() {
|
||||||
$parent.find('.down-arrow').removeClass('down-arrow').addClass('up-arrow')
|
$parent.find('.down-arrow').removeClass('down-arrow').addClass('up-arrow')
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
//= require bugsnag
|
||||||
|
//= require bind-polyfill
|
||||||
|
//= require jquery
|
||||||
|
//= require jquery.monkeypatch
|
||||||
|
//= require jquery_ujs
|
||||||
|
//= require jquery.ui.draggable
|
||||||
|
//= require jquery.ui.droppable
|
||||||
|
//= require jquery.bt
|
||||||
|
//= require jquery.icheck
|
||||||
|
//= require jquery.easydropdown
|
||||||
|
//= require jquery.metronomePlaybackMode
|
||||||
|
//= require classnames
|
||||||
|
//= require reflux
|
||||||
|
//= require AAC_underscore
|
||||||
|
//= require AAA_Log
|
||||||
|
//= require globals
|
||||||
|
//= require jam_rest
|
||||||
|
//= require ga
|
||||||
|
//= require utils
|
||||||
|
//= require playbackControls
|
||||||
|
//= require webcam_viewer
|
||||||
|
//= require react
|
||||||
|
//= require react_ujs
|
||||||
|
//= require react-init
|
||||||
|
//= require react-components
|
||||||
|
|
@ -14,6 +14,7 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
@isSearching = false
|
@isSearching = false
|
||||||
@pageNumber = 1
|
@pageNumber = 1
|
||||||
@instrument_logo_map = context.JK.getInstrumentIconMap24()
|
@instrument_logo_map = context.JK.getInstrumentIconMap24()
|
||||||
|
@instrumentSelector = null
|
||||||
|
|
||||||
init: (app) =>
|
init: (app) =>
|
||||||
@app = app
|
@app = app
|
||||||
|
|
@ -23,14 +24,18 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
@screen = $('#musicians-screen')
|
@screen = $('#musicians-screen')
|
||||||
@resultsListContainer = @screen.find('#musician-search-filter-results-list')
|
@resultsListContainer = @screen.find('#musician-search-filter-results-list')
|
||||||
@spinner = @screen.find('.paginate-wait')
|
@spinner = @screen.find('.paginate-wait')
|
||||||
|
@instrumentSelector = new context.JK.InstrumentSelector(JK.app)
|
||||||
|
@instrumentSelector.initialize(false, true)
|
||||||
|
|
||||||
this.registerResultsPagination()
|
this.registerResultsPagination()
|
||||||
|
|
||||||
@screen.find('#btn-musician-search-builder').on 'click', =>
|
@screen.find('#btn-musician-search-builder').on 'click', =>
|
||||||
this.showBuilder()
|
this.showBuilder()
|
||||||
|
false
|
||||||
|
|
||||||
@screen.find('#btn-musician-search-reset').on 'click', =>
|
@screen.find('#btn-musician-search-reset').on 'click', =>
|
||||||
this.resetFilter()
|
this.resetFilter()
|
||||||
|
false
|
||||||
|
|
||||||
afterShow: () =>
|
afterShow: () =>
|
||||||
@screen.find('#musician-search-filter-results').show()
|
@screen.find('#musician-search-filter-results').show()
|
||||||
|
|
@ -64,9 +69,11 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
|
|
||||||
@screen.find('#btn-perform-musician-search').on 'click', =>
|
@screen.find('#btn-perform-musician-search').on 'click', =>
|
||||||
this.performSearch()
|
this.performSearch()
|
||||||
|
false
|
||||||
|
|
||||||
@screen.find('#btn-musician-search-cancel').on 'click', =>
|
@screen.find('#btn-musician-search-cancel').on 'click', =>
|
||||||
this.cancelFilter()
|
this.cancelFilter()
|
||||||
|
false
|
||||||
|
|
||||||
this._populateSkill()
|
this._populateSkill()
|
||||||
this._populateStudio()
|
this._populateStudio()
|
||||||
|
|
@ -86,15 +93,16 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
blankOption = $ '<option value=""></option>'
|
blankOption = $ '<option value=""></option>'
|
||||||
blankOption.text label
|
blankOption.text label
|
||||||
blankOption.attr 'value', value
|
blankOption.attr 'value', value
|
||||||
blankOption.attr 'selected', '' if value == selection
|
|
||||||
element.append(blankOption)
|
element.append(blankOption)
|
||||||
|
element.val(selection)
|
||||||
context.JK.dropdown(element)
|
context.JK.dropdown(element)
|
||||||
|
|
||||||
_populateSelectIdentifier: (identifier) =>
|
_populateSelectIdentifier: (identifier) =>
|
||||||
elem = $ '#musician-search-filter-builder select[name='+identifier+']'
|
elem = $ '#musician-search-filter-builder select[name='+identifier+']'
|
||||||
struct = gon.musician_search_meta[identifier]['map']
|
struct = gon.musician_search_meta[identifier]['map']
|
||||||
keys = gon.musician_search_meta[identifier]['keys']
|
keys = gon.musician_search_meta[identifier]['keys']
|
||||||
this._populateSelectWithKeys(struct, @searchFilter[identifier], keys, elem)
|
console.log("@searchFilter", @searchFilter, identifier)
|
||||||
|
this._populateSelectWithKeys(struct, @searchFilter.data_blob[identifier], keys, elem)
|
||||||
|
|
||||||
_populateSelectWithInt: (sourceStruct, selection, element) =>
|
_populateSelectWithInt: (sourceStruct, selection, element) =>
|
||||||
struct =
|
struct =
|
||||||
|
|
@ -125,24 +133,23 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
ages_map = gon.musician_search_meta['ages']['map']
|
ages_map = gon.musician_search_meta['ages']['map']
|
||||||
$.each gon.musician_search_meta['ages']['keys'], (index, key) =>
|
$.each gon.musician_search_meta['ages']['keys'], (index, key) =>
|
||||||
ageTemplate = @screen.find('#template-search-filter-setup-ages').html()
|
ageTemplate = @screen.find('#template-search-filter-setup-ages').html()
|
||||||
selected = ''
|
|
||||||
ageLabel = ages_map[key]
|
ageLabel = ages_map[key]
|
||||||
if 0 < @searchFilter.data_blob.ages.length
|
if 0 < @searchFilter.data_blob.ages.length
|
||||||
key_val = key.toString()
|
key_val = key.toString()
|
||||||
ageMatch = $.grep(@searchFilter.data_blob.ages, (n, i) ->
|
ageMatch = $.grep(@searchFilter.data_blob.ages, (n, i) ->
|
||||||
n == key_val)
|
n == key_val)
|
||||||
selected = 'checked' if ageMatch.length > 0
|
selected = 'checked' if ageMatch.length > 0
|
||||||
ageHtml = context.JK.fillTemplate(ageTemplate,
|
ageHtml = context._.template(ageTemplate,
|
||||||
id: key
|
{ id: key
|
||||||
description: ageLabel
|
description: ageLabel
|
||||||
checked: selected)
|
checked: selected},
|
||||||
|
{variable: 'data'})
|
||||||
@screen.find('#search-filter-ages').append ageHtml
|
@screen.find('#search-filter-ages').append ageHtml
|
||||||
|
|
||||||
_populateGenres: () =>
|
_populateGenres: () =>
|
||||||
@screen.find('#search-filter-genres').empty()
|
@screen.find('#search-filter-genres').empty()
|
||||||
@rest.getGenres().done (genres) =>
|
@rest.getGenres().done (genres) =>
|
||||||
genreTemplate = @screen.find('#template-search-filter-setup-genres').html()
|
genreTemplate = @screen.find('#template-search-filter-setup-genres').html()
|
||||||
selected = ''
|
|
||||||
$.each genres, (index, genre) =>
|
$.each genres, (index, genre) =>
|
||||||
if 0 < @searchFilter.data_blob.genres.length
|
if 0 < @searchFilter.data_blob.genres.length
|
||||||
genreMatch = $.grep(@searchFilter.data_blob.genres, (n, i) ->
|
genreMatch = $.grep(@searchFilter.data_blob.genres, (n, i) ->
|
||||||
|
|
@ -150,35 +157,19 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
else
|
else
|
||||||
genreMatch = []
|
genreMatch = []
|
||||||
selected = 'checked' if genreMatch.length > 0
|
selected = 'checked' if genreMatch.length > 0
|
||||||
genreHtml = context.JK.fillTemplate(genreTemplate,
|
genreHtml = context._.template(genreTemplate,
|
||||||
id: genre.id
|
{ id: genre.id
|
||||||
description: genre.description
|
description: genre.description
|
||||||
checked: selected)
|
checked: selected },
|
||||||
|
{ variable: 'data' })
|
||||||
@screen.find('#search-filter-genres').append genreHtml
|
@screen.find('#search-filter-genres').append genreHtml
|
||||||
|
|
||||||
_populateInstruments: () =>
|
_populateInstruments: () =>
|
||||||
@screen.find('#search-filter-instruments').empty()
|
|
||||||
@rest.getInstruments().done (instruments) =>
|
# TODO hydrate user's selection from json_store
|
||||||
$.each instruments, (index, instrument) =>
|
@instrumentSelector.render(@screen.find('.session-instrumentlist'), [])
|
||||||
instrumentTemplate = @screen.find('#template-search-filter-setup-instrument').html()
|
@instrumentSelector.setSelectedInstruments(@searchFilter.data_blob.instruments)
|
||||||
selected = ''
|
|
||||||
proficiency = '1'
|
|
||||||
if 0 < @searchFilter.data_blob.instruments.length
|
|
||||||
instMatch = $.grep(@searchFilter.data_blob.instruments, (inst, i) ->
|
|
||||||
yn = inst.instrument_id == instrument.id
|
|
||||||
proficiency = inst.proficiency_level if yn
|
|
||||||
yn)
|
|
||||||
selected = 'checked' if instMatch.length > 0
|
|
||||||
instrumentHtml = context.JK.fillTemplate(instrumentTemplate,
|
|
||||||
id: instrument.id
|
|
||||||
description: instrument.description
|
|
||||||
checked: selected)
|
|
||||||
@screen.find('#search-filter-instruments').append instrumentHtml
|
|
||||||
profsel = '#search-filter-instruments tr[data-instrument-id="'+instrument.id+'"] select'
|
|
||||||
jprofsel = @screen.find(profsel)
|
|
||||||
jprofsel.val(proficiency)
|
|
||||||
context.JK.dropdown(jprofsel)
|
|
||||||
return true
|
|
||||||
|
|
||||||
_builderSelectValue: (identifier) =>
|
_builderSelectValue: (identifier) =>
|
||||||
elem = $ '#musician-search-filter-builder select[name='+identifier+']'
|
elem = $ '#musician-search-filter-builder select[name='+identifier+']'
|
||||||
|
|
@ -188,12 +179,7 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
vals = []
|
vals = []
|
||||||
elem = $ '#search-filter-'+identifier+' input[type=checkbox]:checked'
|
elem = $ '#search-filter-'+identifier+' input[type=checkbox]:checked'
|
||||||
if 'instruments' == identifier
|
if 'instruments' == identifier
|
||||||
elem.each (idx) ->
|
vals = @instrumentSelector.getSelectedInstruments()
|
||||||
row = $(this).parent().parent()
|
|
||||||
instrument =
|
|
||||||
instrument_id: row.data('instrument-id')
|
|
||||||
proficiency_level: row.find('select').val()
|
|
||||||
vals.push instrument
|
|
||||||
else
|
else
|
||||||
elem.each (idx) ->
|
elem.each (idx) ->
|
||||||
vals.push $(this).val()
|
vals.push $(this).val()
|
||||||
|
|
@ -231,18 +217,20 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
|
|
||||||
performSearch: () =>
|
performSearch: () =>
|
||||||
if this.willSearch(true)
|
if this.willSearch(true)
|
||||||
|
filter = {}
|
||||||
$.each gon.musician_search_meta.filter_keys.single, (index, key) =>
|
$.each gon.musician_search_meta.filter_keys.single, (index, key) =>
|
||||||
@searchFilter[key] = this._builderSelectValue(key)
|
filter[key] = this._builderSelectValue(key)
|
||||||
$.each gon.musician_search_meta.filter_keys.multi, (index, key) =>
|
$.each gon.musician_search_meta.filter_keys.multi, (index, key) =>
|
||||||
@searchFilter[key] = this._builderSelectMultiValue(key)
|
filter[key] = this._builderSelectMultiValue(key)
|
||||||
@rest.postMusicianSearchFilter({ filter: JSON.stringify(@searchFilter), page: @pageNumber }).done(this.didSearch)
|
@rest.postMusicianSearchFilter({ filter: JSON.stringify(filter), page: @pageNumber }).done(this.didSearch)
|
||||||
|
|
||||||
renderResultsHeader: () =>
|
renderResultsHeader: () =>
|
||||||
@screen.find('#musician-search-filter-description').html(@searchResults.description)
|
|
||||||
if @searchResults.is_blank_filter
|
if @searchResults.is_blank_filter
|
||||||
@screen.find('#btn-musician-search-reset').hide()
|
@screen.find('#btn-musician-search-reset').hide()
|
||||||
|
@screen.find('.musician-search-text').text('Click search button to look for musicians with similar interests, skill levels, etc.')
|
||||||
else
|
else
|
||||||
@screen.find('#btn-musician-search-reset').show()
|
@screen.find('#btn-musician-search-reset').show()
|
||||||
|
@screen.find('.musician-search-text').text(@searchResults.summary)
|
||||||
|
|
||||||
renderMusicians: () =>
|
renderMusicians: () =>
|
||||||
this.renderResultsHeader() if @pageNumber == 1
|
this.renderResultsHeader() if @pageNumber == 1
|
||||||
|
|
@ -338,20 +326,25 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
@screen.find('.search-m-message').on 'click', (evt) ->
|
@screen.find('.search-m-message').on 'click', (evt) ->
|
||||||
userId = $(this).parent().data('musician-id')
|
userId = $(this).parent().data('musician-id')
|
||||||
objThis.app.layout.showDialog 'text-message', d1: userId
|
objThis.app.layout.showDialog 'text-message', d1: userId
|
||||||
|
return false
|
||||||
|
|
||||||
|
|
||||||
_bindFriendMusician: () =>
|
_bindFriendMusician: () =>
|
||||||
objThis = this
|
objThis = this
|
||||||
@screen.find('.search-m-friend').on 'click', (evt) ->
|
@screen.find('.search-m-friend').on 'click', (evt) =>
|
||||||
# if the musician is already a friend, remove the button-orange class, and prevent the link from working
|
# if the musician is already a friend, remove the button-orange class, and prevent the link from working
|
||||||
if 0 == $(this).closest('.button-orange').size()
|
$self = $(evt.target)
|
||||||
|
if 0 == $self.closest('.button-orange').size()
|
||||||
return false
|
return false
|
||||||
$(this).click (ee) ->
|
logger.debug("evt.target", evt.target)
|
||||||
|
$self.click (ee) ->
|
||||||
ee.preventDefault()
|
ee.preventDefault()
|
||||||
return
|
return false
|
||||||
evt.stopPropagation()
|
evt.stopPropagation()
|
||||||
uid = $(this).parent().data('musician-id')
|
uid = $self.parent().data('musician-id')
|
||||||
objThis.rest.sendFriendRequest objThis.app, uid, this.friendRequestCallback
|
objThis.rest.sendFriendRequest objThis.app, uid, this.friendRequestCallback
|
||||||
|
@app.notify({text: 'A friend request has been sent.'})
|
||||||
|
return false
|
||||||
|
|
||||||
_bindFollowMusician: () =>
|
_bindFollowMusician: () =>
|
||||||
objThis = this
|
objThis = this
|
||||||
|
|
@ -361,7 +354,7 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
return false
|
return false
|
||||||
$(this).click (ee) ->
|
$(this).click (ee) ->
|
||||||
ee.preventDefault()
|
ee.preventDefault()
|
||||||
return
|
return false
|
||||||
evt.stopPropagation()
|
evt.stopPropagation()
|
||||||
newFollowing = {}
|
newFollowing = {}
|
||||||
newFollowing.user_id = $(this).parent().data('musician-id')
|
newFollowing.user_id = $(this).parent().data('musician-id')
|
||||||
|
|
@ -377,8 +370,9 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
# remove the orange look to indicate it's not selectable
|
# remove the orange look to indicate it's not selectable
|
||||||
# @FIXME -- this will need to be tweaked when we allow unfollowing
|
# @FIXME -- this will need to be tweaked when we allow unfollowing
|
||||||
objThis.screen.find('div[data-musician-id=' + newFollowing.user_id + '] .search-m-follow').removeClass('button-orange').addClass 'button-grey'
|
objThis.screen.find('div[data-musician-id=' + newFollowing.user_id + '] .search-m-follow').removeClass('button-orange').addClass 'button-grey'
|
||||||
return
|
return false
|
||||||
error: objThis.app.ajaxError
|
error: objThis.app.ajaxError
|
||||||
|
return false
|
||||||
|
|
||||||
_formatLocation: (musician) ->
|
_formatLocation: (musician) ->
|
||||||
if musician.city and musician.state
|
if musician.city and musician.state
|
||||||
|
|
@ -394,10 +388,11 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter
|
||||||
# TODO:
|
# TODO:
|
||||||
|
|
||||||
paginate: () =>
|
paginate: () =>
|
||||||
|
|
||||||
if @pageNumber < @searchResults.page_count && this.willSearch(false)
|
if @pageNumber < @searchResults.page_count && this.willSearch(false)
|
||||||
@screen.find('.paginate-wait').show()
|
@screen.find('.paginate-wait').show()
|
||||||
@pageNumber += 1
|
@pageNumber += 1
|
||||||
@rest.postMusicianSearchFilter({ filter: JSON.stringify(@searchFilter), page: @pageNumber }).done(this.didSearch)
|
@rest.postMusicianSearchFilter({ filter: JSON.stringify(@searchFilter.data_blob), page: @pageNumber }).done(this.didSearch)
|
||||||
return true
|
return true
|
||||||
false
|
false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
context = window
|
||||||
|
$ = jQuery
|
||||||
|
|
||||||
|
panHelper = class PanHelper
|
||||||
|
|
||||||
|
###
|
||||||
|
Convert the pan value that comes from a backend mixer
|
||||||
|
to a 0-100 % usable by a draggable panner element
|
||||||
|
###
|
||||||
|
convertPanToPercent: (mixerPan) ->
|
||||||
|
value = (((mixerPan + 90) / 90) * 100) / 2
|
||||||
|
|
||||||
|
if value < 0
|
||||||
|
0
|
||||||
|
else if value > 100
|
||||||
|
100
|
||||||
|
else
|
||||||
|
value
|
||||||
|
|
||||||
|
###
|
||||||
|
Convert the % value of a draggable panner element
|
||||||
|
to a mixer-ready pan value
|
||||||
|
###
|
||||||
|
convertPercentToPan: (percent) ->
|
||||||
|
value = 2 * percent / 100 * 90 - 90
|
||||||
|
|
||||||
|
if value < -90
|
||||||
|
-90
|
||||||
|
else if value > 90
|
||||||
|
90
|
||||||
|
else
|
||||||
|
Math.round(value)
|
||||||
|
|
||||||
|
convertPercentToPanForDisplay: (percent) ->
|
||||||
|
Math.abs(context.JK.PanHelpers.convertPercentToPan(percent))
|
||||||
|
|
||||||
|
context.JK.PanHelpers = new panHelper()
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Playback widget (play, pause , etc)
|
* Playback widget (play, pause , etc)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function(context, $) {
|
(function(context, $) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
@ -18,7 +19,7 @@
|
||||||
context.JK = context.JK || {};
|
context.JK = context.JK || {};
|
||||||
context.JK.PlaybackControls = function($parentElement, options){
|
context.JK.PlaybackControls = function($parentElement, options){
|
||||||
|
|
||||||
options = $.extend(false, {playmodeControlsVisible:false}, options);
|
options = $.extend(false, {playmodeControlsVisible:false, mediaActions:null}, options);
|
||||||
|
|
||||||
var logger = context.JK.logger;
|
var logger = context.JK.logger;
|
||||||
if($parentElement.length == 0) {
|
if($parentElement.length == 0) {
|
||||||
|
|
@ -68,24 +69,43 @@
|
||||||
if(endReached) {
|
if(endReached) {
|
||||||
update(0, playbackDurationMs, playbackPlaying);
|
update(0, playbackDurationMs, playbackPlaying);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(options.mediaActions) {
|
||||||
|
options.mediaActions.mediaStartPlay({playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode})
|
||||||
|
}
|
||||||
|
else {
|
||||||
$self.triggerHandler('play', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode});
|
$self.triggerHandler('play', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK) {
|
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK) {
|
||||||
var sessionModel = context.JK.CurrentSessionModel || null;
|
context.JK.GA.trackJamTrackPlaySession(context.SessionStore.id(), true)
|
||||||
context.JK.GA.trackJamTrackPlaySession(sessionModel.id(), true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopPlay(endReached) {
|
function stopPlay(endReached) {
|
||||||
|
logger.debug("STOP PLAY CLICKED")
|
||||||
updateIsPlaying(false);
|
updateIsPlaying(false);
|
||||||
|
|
||||||
|
if(options.mediaActions) {
|
||||||
|
logger.debug("mediaStopPlay", endReached)
|
||||||
|
options.mediaActions.mediaStopPlay({playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode, endReached : endReached})
|
||||||
|
}
|
||||||
|
else {
|
||||||
$self.triggerHandler('stop', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode, endReached : endReached});
|
$self.triggerHandler('stop', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode, endReached : endReached});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function pausePlay(endReached) {
|
function pausePlay(endReached) {
|
||||||
updateIsPlaying(false);
|
updateIsPlaying(false);
|
||||||
|
|
||||||
|
if(options.mediaActions) {
|
||||||
|
options.mediaActions.mediaPausePlay({playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode, endReached : endReached})
|
||||||
|
}
|
||||||
|
else {
|
||||||
$self.triggerHandler('pause', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode, endReached : endReached});
|
$self.triggerHandler('pause', {playbackMode: playbackMode, playbackMonitorMode: playbackMonitorMode, endReached : endReached});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateOffsetBasedOnPosition(offsetLeft) {
|
function updateOffsetBasedOnPosition(offsetLeft) {
|
||||||
var sliderBarWidth = $sliderBar.width();
|
var sliderBarWidth = $sliderBar.width();
|
||||||
|
|
@ -93,7 +113,12 @@
|
||||||
playbackPositionMs = parseInt((offsetLeft / sliderBarWidth) * playbackDurationMs);
|
playbackPositionMs = parseInt((offsetLeft / sliderBarWidth) * playbackDurationMs);
|
||||||
updateCurrentTimeText(playbackPositionMs);
|
updateCurrentTimeText(playbackPositionMs);
|
||||||
if(canUpdateBackend) {
|
if(canUpdateBackend) {
|
||||||
|
if(options.mediaActions) {
|
||||||
|
options.mediaActions.mediaChangePosition({positionMs: playbackPositionMs, playbackMonitorMode: playbackMonitorMode})
|
||||||
|
}
|
||||||
|
else {
|
||||||
$self.triggerHandler('change-position', {positionMs: playbackPositionMs, playbackMonitorMode: playbackMonitorMode});
|
$self.triggerHandler('change-position', {positionMs: playbackPositionMs, playbackMonitorMode: playbackMonitorMode});
|
||||||
|
}
|
||||||
canUpdateBackend = false;
|
canUpdateBackend = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -127,34 +152,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$playButton.on('click', function(e) {
|
$playButton.on('click', function(e) {
|
||||||
var sessionModel = context.JK.CurrentSessionModel || null;
|
console.log("CLICKED PLAY")
|
||||||
//if(sessionModel && sessionModel.areControlsLockedForJamTrackRecording() && $parentElement.closest('.session-track').data('track_data').type == 'jam_track') {
|
|
||||||
// context.JK.prodBubble($fader, 'jamtrack-controls-disabled', {}, {positions:['top'], offsetParent: $playButton})
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
startPlay();
|
startPlay();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$pauseButton.on('click', function(e) {
|
$pauseButton.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;
|
|
||||||
//}
|
|
||||||
|
|
||||||
pausePlay();
|
pausePlay();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$stopButton.on('click', function(e) {
|
$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();
|
stopPlay();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
@ -211,22 +219,8 @@
|
||||||
throw "unknown playbackMonitorMode: " + playbackMonitorMode;
|
throw "unknown playbackMonitorMode: " + playbackMonitorMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function monitorRecordingPlayback() {
|
|
||||||
if(!monitoring) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK) {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var positionMs = context.jamClient.SessionCurrrentPlayPosMs();
|
|
||||||
var durationMs = context.jamClient.SessionGetTracksPlayDurationMs();
|
|
||||||
}
|
|
||||||
|
|
||||||
var isPlaying = context.jamClient.isSessionTrackPlaying();
|
function executeMonitor(positionMs, durationMs, isPlaying) {
|
||||||
|
|
||||||
if(positionMs < 0) {
|
if(positionMs < 0) {
|
||||||
// bug in backend?
|
// bug in backend?
|
||||||
|
|
@ -237,7 +231,6 @@
|
||||||
seenActivity = true;
|
seenActivity = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.METRONOME) {
|
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.METRONOME) {
|
||||||
updateIsPlaying(isPlaying);
|
updateIsPlaying(isPlaying);
|
||||||
}
|
}
|
||||||
|
|
@ -254,12 +247,35 @@
|
||||||
// this is so the jamtrack 'Get Ready!' stays hidden when it's not playing
|
// this is so the jamtrack 'Get Ready!' stays hidden when it's not playing
|
||||||
$jamTrackGetReady.attr('data-current-time', -1)
|
$jamTrackGetReady.attr('data-current-time', -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
monitorPlaybackTimeout = setTimeout(monitorRecordingPlayback, 500);
|
monitorPlaybackTimeout = setTimeout(monitorRecordingPlayback, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function monitorRecordingPlayback() {
|
||||||
|
if(!monitoring) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(options.mediaActions) {
|
||||||
|
options.mediaActions.positionUpdate(playbackMonitorMode)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK) {
|
||||||
|
var positionMs = context.jamClient.SessionCurrrentJamTrackPlayPosMs();
|
||||||
|
var duration = context.jamClient.SessionGetJamTracksPlayDurationMs();
|
||||||
|
var durationMs = duration.media_len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var positionMs = context.jamClient.SessionCurrrentPlayPosMs();
|
||||||
|
var durationMs = context.jamClient.SessionGetTracksPlayDurationMs();
|
||||||
|
}
|
||||||
|
|
||||||
|
var isPlaying = context.jamClient.isSessionTrackPlaying();
|
||||||
|
|
||||||
|
executeMonitor(positionMs, durationMs, isPlaying)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function update(currentTimeMs, durationTimeMs, isPlaying, offsetStart) {
|
function update(currentTimeMs, durationTimeMs, isPlaying, offsetStart) {
|
||||||
|
|
||||||
if(dragging) {
|
if(dragging) {
|
||||||
|
|
@ -304,7 +320,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCurrentTimeText(timeMs) {
|
function updateCurrentTimeText(timeMs) {
|
||||||
$currentTime.text(context.JK.prettyPrintSeconds(parseInt(timeMs / 1000)));
|
var time = context.JK.prettyPrintSeconds(parseInt(timeMs / 1000))
|
||||||
|
$currentTime.text(time);
|
||||||
|
if(options.mediaActions) {
|
||||||
|
options.mediaActions.currentTimeChanged(time)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSliderPosition(timeMs) {
|
function updateSliderPosition(timeMs) {
|
||||||
|
|
@ -362,6 +382,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function startMonitor(_playbackMonitorMode) {
|
function startMonitor(_playbackMonitorMode) {
|
||||||
|
logger.debug("startMonitor: " + _playbackMonitorMode)
|
||||||
|
|
||||||
|
if(monitoring && _playbackMonitorMode == playbackMonitorMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
monitoring = true;
|
monitoring = true;
|
||||||
// resets everything to zero
|
// resets everything to zero
|
||||||
init();
|
init();
|
||||||
|
|
@ -376,6 +402,11 @@
|
||||||
logger.debug("playbackControl.startMonitor " + playbackMonitorMode + "")
|
logger.debug("playbackControl.startMonitor " + playbackMonitorMode + "")
|
||||||
|
|
||||||
styleControls();
|
styleControls();
|
||||||
|
|
||||||
|
if(monitorPlaybackTimeout != null) {
|
||||||
|
clearTimeout(monitorPlaybackTimeout);
|
||||||
|
monitorPlaybackTimeout = null;
|
||||||
|
}
|
||||||
monitorRecordingPlayback();
|
monitorRecordingPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,6 +438,7 @@
|
||||||
this.setPlaybackMode = setPlaybackMode;
|
this.setPlaybackMode = setPlaybackMode;
|
||||||
this.startMonitor = startMonitor;
|
this.startMonitor = startMonitor;
|
||||||
this.stopMonitor = stopMonitor;
|
this.stopMonitor = stopMonitor;
|
||||||
|
this.executeMonitor = executeMonitor;
|
||||||
this.onPlayStopEvent = onPlayStopEvent;
|
this.onPlayStopEvent = onPlayStopEvent;
|
||||||
this.onPlayStartEvent = onPlayStartEvent;
|
this.onPlayStartEvent = onPlayStartEvent;
|
||||||
this.onPlayPauseEvent = onPlayPauseEvent;
|
this.onPlayPauseEvent = onPlayPauseEvent;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
var $biography = $screen.find('#biography');
|
var $biography = $screen.find('#biography');
|
||||||
|
|
||||||
// musical experience
|
// musical experience
|
||||||
var $instruments = $screen.find('#instruments');
|
var $instruments = $screen.find('.instruments-holder');
|
||||||
var $musicianStatus = $screen.find('#musician-status');
|
var $musicianStatus = $screen.find('#musician-status');
|
||||||
var $genres = $screen.find('#genres');
|
var $genres = $screen.find('#genres');
|
||||||
var $concertCount = $screen.find('#concert-count');
|
var $concertCount = $screen.find('#concert-count');
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
var $youTubeSamples = $screen.find('.youtube-samples');
|
var $youTubeSamples = $screen.find('.youtube-samples');
|
||||||
|
|
||||||
// online presence
|
// online presence
|
||||||
var $noOnlinePresence = $screen.find('.no-online-presence');
|
|
||||||
var $userWebsite = $screen.find('.user-website');
|
var $userWebsite = $screen.find('.user-website');
|
||||||
var $soundCloudPresence = $screen.find('.soundcloud-presence');
|
var $soundCloudPresence = $screen.find('.soundcloud-presence');
|
||||||
var $reverbNationPresence = $screen.find('.reverbnation-presence');
|
var $reverbNationPresence = $screen.find('.reverbnation-presence');
|
||||||
|
|
@ -95,7 +95,7 @@
|
||||||
var $age = $screen.find('#age');
|
var $age = $screen.find('#age');
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
var $btnEdit = $screen.find('#btn-edit');
|
var $btnEdit = $screen.find('.edit-profile-btn');
|
||||||
var $btnAddFriend = $screen.find('#btn-add-friend');
|
var $btnAddFriend = $screen.find('#btn-add-friend');
|
||||||
var $btnFollowUser = $screen.find('#btn-follow-user');
|
var $btnFollowUser = $screen.find('#btn-follow-user');
|
||||||
var $btnMessageUser = $screen.find('#btn-message-user');
|
var $btnMessageUser = $screen.find('#btn-message-user');
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetForm() {
|
function resetForm() {
|
||||||
$instruments.empty();
|
//$instruments.empty();
|
||||||
|
|
||||||
$aboutContent.show();
|
$aboutContent.show();
|
||||||
$historyContent.hide();
|
$historyContent.hide();
|
||||||
|
|
@ -411,7 +411,7 @@
|
||||||
|
|
||||||
/****************** ABOUT TAB *****************/
|
/****************** ABOUT TAB *****************/
|
||||||
function renderAbout() {
|
function renderAbout() {
|
||||||
$instruments.empty();
|
//$instruments.empty();
|
||||||
|
|
||||||
$aboutContent.show();
|
$aboutContent.show();
|
||||||
$historyContent.hide();
|
$historyContent.hide();
|
||||||
|
|
@ -477,7 +477,7 @@
|
||||||
|
|
||||||
function renderBio() {
|
function renderBio() {
|
||||||
$biography.html(user.biography ? user.biography : NOT_SPECIFIED_TEXT);
|
$biography.html(user.biography ? user.biography : NOT_SPECIFIED_TEXT);
|
||||||
if (isCurrentUser() && !user.biography) {
|
if (isCurrentUser()) {
|
||||||
$btnEditBio.show();
|
$btnEditBio.show();
|
||||||
} else {
|
} else {
|
||||||
$btnEditBio.hide();
|
$btnEditBio.hide();
|
||||||
|
|
@ -485,19 +485,26 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderMusicalExperience() {
|
function renderMusicalExperience() {
|
||||||
profileUtils.renderMusicalExperience(user, $screen)
|
profileUtils.renderMusicalExperience(user, $screen, isCurrentUser())
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPerformanceSamples() {
|
function renderPerformanceSamples() {
|
||||||
profileUtils.renderPerformanceSamples(user, $screen)
|
profileUtils.renderPerformanceSamples(user, $screen, isCurrentUser())
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderOnlinePresence() {
|
function renderOnlinePresence() {
|
||||||
profileUtils.renderOnlinePresence(user, $screen)
|
profileUtils.renderOnlinePresence(user, $screen, isCurrentUser())
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderInterests() {
|
function renderInterests() {
|
||||||
// current interests
|
// current interests
|
||||||
|
if (isCurrentUser()) {
|
||||||
|
$btnAddInterests.show();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnAddInterests.hide();
|
||||||
|
}
|
||||||
|
|
||||||
var noInterests = !user.paid_sessions && !user.free_sessions && !user.cowriting && !user.virtual_band && !user.traditional_band;
|
var noInterests = !user.paid_sessions && !user.free_sessions && !user.cowriting && !user.virtual_band && !user.traditional_band;
|
||||||
if (noInterests) {
|
if (noInterests) {
|
||||||
$noInterests.show();
|
$noInterests.show();
|
||||||
|
|
@ -506,12 +513,7 @@
|
||||||
$cowritingSection.hide();
|
$cowritingSection.hide();
|
||||||
$traditionalBandSection.hide();
|
$traditionalBandSection.hide();
|
||||||
$virtualBandSection.hide();
|
$virtualBandSection.hide();
|
||||||
|
|
||||||
if (isCurrentUser()) {
|
|
||||||
$btnAddInterests.show();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$btnAddInterests.hide();
|
|
||||||
$noInterests.hide();
|
$noInterests.hide();
|
||||||
|
|
||||||
// paid sessions
|
// paid sessions
|
||||||
|
|
|
||||||
|
|
@ -59,19 +59,17 @@
|
||||||
|
|
||||||
profileUtils.gigMap = {
|
profileUtils.gigMap = {
|
||||||
"": "not specified",
|
"": "not specified",
|
||||||
"0": "zero",
|
"0": "under 10",
|
||||||
"1": "under 10",
|
"1": "10 to 50",
|
||||||
"2": "10 to 50",
|
"2": "50 to 100",
|
||||||
"3": "50 to 100",
|
"3": "over 100"
|
||||||
"4": "over 100"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
profileUtils.studioMap = {
|
profileUtils.studioMap = {
|
||||||
"0": "zero",
|
"0": "under 10",
|
||||||
"1": "under 10",
|
"1": "10 to 50",
|
||||||
"2": "10 to 50",
|
"2": "50 to 100",
|
||||||
"3": "50 to 100",
|
"3": "over 100"
|
||||||
"4": "over 100"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
profileUtils.cowritingPurposeMap = {
|
profileUtils.cowritingPurposeMap = {
|
||||||
|
|
@ -99,6 +97,31 @@
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the server stores money in cents; display it as such
|
||||||
|
profileUtils.normalizeMoneyForDisplay = function(serverValue) {
|
||||||
|
if(serverValue || serverValue == 0) {
|
||||||
|
return (new Number(serverValue) / 100).toFixed(2)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the server stores money in cents; normalize it from what user entered
|
||||||
|
profileUtils.normalizeMoneyForSubmit = function(clientValue) {
|
||||||
|
var money = new Number(clientValue);
|
||||||
|
|
||||||
|
if(!context._.isNaN(money)) {
|
||||||
|
money = Math.round(money * 100)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// restore original value to allow server to reject with validation error
|
||||||
|
money = clientValue;
|
||||||
|
}
|
||||||
|
return money;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initialize standard profile help bubbles (topics stored as attributes on element):
|
// Initialize standard profile help bubbles (topics stored as attributes on element):
|
||||||
profileUtils.initializeHelpBubbles = function(parentElement) {
|
profileUtils.initializeHelpBubbles = function(parentElement) {
|
||||||
$(".help", parentElement).each(function( index ) {
|
$(".help", parentElement).each(function( index ) {
|
||||||
|
|
@ -307,18 +330,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatTitle(title) {
|
function formatTitle(title) {
|
||||||
return title && title.length > 30 ? title.substring(0, 30) + "..." : title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
profileUtils.renderMusicalExperience = function(player, $root) {
|
profileUtils.renderMusicalExperience = function(player, $root, isOwner) {
|
||||||
var $instruments = $root.find('#instruments');
|
var $instruments = $root.find('.instruments-holder');
|
||||||
var $musicianStatus = $root.find('#musician-status');
|
var $musicianStatus = $root.find('#musician-status');
|
||||||
var $genres = $root.find('#genres');
|
var $genres = $root.find('#genres');
|
||||||
var $concertCount = $root.find('#concert-count');
|
var $concertCount = $root.find('#concert-count');
|
||||||
var $studioCount = $root.find('#studio-count');
|
var $studioCount = $root.find('#studio-count');
|
||||||
|
var $btnAddExperiences = $root.find('.add-experiences')
|
||||||
|
|
||||||
$instruments.empty();
|
$instruments.find('.profile-instrument').remove()
|
||||||
|
|
||||||
|
if(isOwner) {
|
||||||
|
$btnAddExperiences.show()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnAddExperiences.hide()
|
||||||
|
}
|
||||||
if (player.instruments) {
|
if (player.instruments) {
|
||||||
for (var i = 0; i < player.instruments.length; i++) {
|
for (var i = 0; i < player.instruments.length; i++) {
|
||||||
var instrument = player.instruments[i];
|
var instrument = player.instruments[i];
|
||||||
|
|
@ -335,7 +365,7 @@
|
||||||
proficiency_level_css: proficiencyCssMap[proficiency]
|
proficiency_level_css: proficiencyCssMap[proficiency]
|
||||||
});
|
});
|
||||||
|
|
||||||
$instruments.append(instrumentHtml);
|
$instruments.prepend(instrumentHtml);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,16 +397,22 @@
|
||||||
var $youTubeSamples = $root.find('.youtube-samples');
|
var $youTubeSamples = $root.find('.youtube-samples');
|
||||||
var $btnAddRecordings = $root.find('.add-recordings');
|
var $btnAddRecordings = $root.find('.add-recordings');
|
||||||
|
|
||||||
|
$jamkazamSamples.find('.playable').remove()
|
||||||
|
$soundCloudSamples.find('.playable').remove()
|
||||||
|
$youTubeSamples.find('.playable').remove()
|
||||||
|
|
||||||
|
if (isOwner) {
|
||||||
|
$btnAddRecordings.show();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$btnAddRecordings.hide();
|
||||||
|
}
|
||||||
if (!performanceSamples || performanceSamples.length === 0) {
|
if (!performanceSamples || performanceSamples.length === 0) {
|
||||||
$noSamples.show()
|
$noSamples.show()
|
||||||
$jamkazamSamples.hide()
|
$jamkazamSamples.hide()
|
||||||
$soundCloudSamples.hide()
|
$soundCloudSamples.hide()
|
||||||
$youTubeSamples.hide()
|
$youTubeSamples.hide()
|
||||||
if (isOwner) {
|
|
||||||
$btnAddRecordings.show();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$btnAddRecordings.hide();
|
|
||||||
$noSamples.hide();
|
$noSamples.hide();
|
||||||
|
|
||||||
// show samples section
|
// show samples section
|
||||||
|
|
@ -402,15 +438,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$.each(jamkazamSamples, function(index, sample) {
|
$.each(jamkazamSamples, function(index, sample) {
|
||||||
$jamkazamSamples.append("<a class='jamkazam-playable' href='/recordings/" + sample.claimed_recording.id + "' rel='external'>" + formatTitle(sample.claimed_recording.name) + "</a><br/>");
|
$jamkazamSamples.append("<a class='jamkazam-playable playable' href='/recordings/" + sample.claimed_recording.id + "' rel='external'>" + formatTitle(sample.claimed_recording.name) + "</a>");
|
||||||
});
|
});
|
||||||
|
|
||||||
$.each(soundCloudSamples, function(index, sample) {
|
$.each(soundCloudSamples, function(index, sample) {
|
||||||
$soundCloudSamples.append("<a class='sound-cloud-playable' href='' soundcloud_url='" + sample.url + "'>" + formatTitle(sample.description) + "</a><br/>");
|
$soundCloudSamples.append("<a class='sound-cloud-playable playable' href='' soundcloud_url='" + sample.url + "'>" + formatTitle(sample.description) + "</a>");
|
||||||
});
|
});
|
||||||
|
|
||||||
$.each(youTubeSamples, function(index, sample) {
|
$.each(youTubeSamples, function(index, sample) {
|
||||||
$youTubeSamples.append("<a class='youtube-playable' href='" + sample.url + "' rel='external'>" + formatTitle(sample.description) + "</a><br/>");
|
$youTubeSamples.append("<a class='youtube-playable playable' href='" + sample.url + "' rel='external'>" + formatTitle(sample.description) + "</a>");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}// function renderPerformanceSamples
|
}// function renderPerformanceSamples
|
||||||
|
|
@ -425,13 +461,17 @@
|
||||||
var $youTubePresence = $root.find('.youtube-presence');
|
var $youTubePresence = $root.find('.youtube-presence');
|
||||||
var $facebookPresence = $root.find('.facebook-presence');
|
var $facebookPresence = $root.find('.facebook-presence');
|
||||||
var $twitterPresence = $root.find('.twitter-presence');
|
var $twitterPresence = $root.find('.twitter-presence');
|
||||||
var $btnAddSites = $root.find('.add-sites');
|
var $btnAddSites = $root.find('.add-presences');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (isOwner) {
|
||||||
|
$btnAddSites.show();
|
||||||
|
} else {
|
||||||
|
$btnAddSites.hide();
|
||||||
|
}
|
||||||
// online presences
|
// online presences
|
||||||
var onlinePresences = player.online_presences;
|
var onlinePresences = player.online_presences;
|
||||||
if ((!onlinePresences || onlinePresences.length === 0) && !player.website) {
|
if (onlinePresences.length == 0 && !player.website) {
|
||||||
$noOnlinePresence.show()
|
$noOnlinePresence.show()
|
||||||
$userWebsite.show()
|
$userWebsite.show()
|
||||||
$soundCloudPresence.show()
|
$soundCloudPresence.show()
|
||||||
|
|
@ -441,18 +481,19 @@
|
||||||
$youTubePresence.show()
|
$youTubePresence.show()
|
||||||
$facebookPresence.show()
|
$facebookPresence.show()
|
||||||
$twitterPresence.show()
|
$twitterPresence.show()
|
||||||
|
|
||||||
if (isOwner) {
|
|
||||||
$btnAddSites.show();
|
|
||||||
} else {
|
} else {
|
||||||
$btnAddSites.hide();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$btnAddSites.hide();
|
|
||||||
$noOnlinePresence.hide();
|
$noOnlinePresence.hide();
|
||||||
|
|
||||||
if (player.website) {
|
if (player.website) {
|
||||||
$userWebsite.find('a').attr('href', player.website);
|
// make sure website is rooted
|
||||||
|
var website = player.website;
|
||||||
|
if(website.indexOf('http') == -1) {
|
||||||
|
website = 'http://' + website;
|
||||||
|
}
|
||||||
|
$userWebsite.removeClass('hidden').find('a').attr('href', website)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$userWebsite.addClass('hidden').find('a').attr('href', '')
|
||||||
}
|
}
|
||||||
|
|
||||||
var soundCloudPresences = profileUtils.soundCloudPresences(onlinePresences);
|
var soundCloudPresences = profileUtils.soundCloudPresences(onlinePresences);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,15 @@
|
||||||
//= require ./react-components/actions/BroadcastActions
|
//= require_directory ./react-components/helpers
|
||||||
//= require ./react-components/stores/BroadcastStore
|
//= require_directory ./react-components/actions
|
||||||
|
//= require ./react-components/stores/AppStore
|
||||||
|
//= require ./react-components/stores/RecordingStore
|
||||||
|
//= require ./react-components/stores/SessionStore
|
||||||
|
//= require ./react-components/stores/MixerStore
|
||||||
|
//= require ./react-components/stores/SessionNotificationStore
|
||||||
|
//= require ./react-components/stores/MediaPlaybackStore
|
||||||
|
//= require ./react-components/stores/SessionMyTracksStore
|
||||||
|
//= require ./react-components/stores/SessionOtherTracksStore
|
||||||
|
//= require ./react-components/stores/SessionMediaTracksStore
|
||||||
|
//= require_directory ./react-components/stores
|
||||||
|
//= require_directory ./react-components/mixins
|
||||||
//= require_directory ./react-components
|
//= require_directory ./react-components
|
||||||
|
//= require_directory ./react-components/landing
|
||||||
|
|
@ -0,0 +1,204 @@
|
||||||
|
context = window
|
||||||
|
PLAYBACK_MONITOR_MODE = context.JK.PLAYBACK_MONITOR_MODE
|
||||||
|
EVENTS = context.JK.EVENTS
|
||||||
|
logger = context.JK.logger
|
||||||
|
|
||||||
|
mixins = []
|
||||||
|
|
||||||
|
# this check ensures we attempt to listen if this component is created in a popup
|
||||||
|
reactContext = if window.opener? then window.opener else window
|
||||||
|
|
||||||
|
MixerStore = reactContext.MixerStore
|
||||||
|
MixerActions = reactContext.MixerActions
|
||||||
|
MediaPlaybackStore = reactContext.MediaPlaybackStore
|
||||||
|
SessionActions = reactContext.SessionActions
|
||||||
|
MediaPlaybackActions = reactContext.MediaPlaybackActions
|
||||||
|
|
||||||
|
mixins.push(Reflux.listenTo(MixerStore,"onInputsChanged"))
|
||||||
|
mixins.push(Reflux.listenTo(MediaPlaybackStore, 'onMediaStateChanged'))
|
||||||
|
|
||||||
|
|
||||||
|
@MediaControls = React.createClass({
|
||||||
|
|
||||||
|
mixins: mixins
|
||||||
|
tempos : [ 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 63, 66, 69, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 126, 132, 138, 144, 152, 160, 168, 176, 184, 192, 200, 208 ]
|
||||||
|
|
||||||
|
onMediaStateChanged: (changes) ->
|
||||||
|
if changes.playbackStateChanged
|
||||||
|
if @state.controls?
|
||||||
|
if changes.playbackState == 'play_start'
|
||||||
|
@state.controls.onPlayStartEvent()
|
||||||
|
else if changes.playbackState == 'play_stop'
|
||||||
|
@state.controls.onPlayStopEvent()
|
||||||
|
else if changes.playbackState == 'play_pause'
|
||||||
|
@state.controls.onPlayPauseEvent();
|
||||||
|
else if changes.positionUpdateChanged
|
||||||
|
if @state.controls?
|
||||||
|
@state.controls.executeMonitor(changes.positionMs, changes.durationMs, changes.isPlaying)
|
||||||
|
|
||||||
|
onInputsChanged: (sessionMixers) ->
|
||||||
|
|
||||||
|
session = sessionMixers.session
|
||||||
|
mixers = sessionMixers.mixers
|
||||||
|
|
||||||
|
if @state.controls?
|
||||||
|
mediaSummary = mixers.mediaSummary
|
||||||
|
metro = mixers.metro
|
||||||
|
|
||||||
|
@monitorControls(@state.controls, mediaSummary)
|
||||||
|
@setState({mediaSummary: mediaSummary, metro: metro})
|
||||||
|
|
||||||
|
@updateMetronomeDetails(metro, @state.initializedMetronomeControls)
|
||||||
|
|
||||||
|
updateMetronomeDetails: (metro, initializedMetronomeControls) ->
|
||||||
|
logger.debug("MediaControls: setting tempo/sound/cricket", metro)
|
||||||
|
$root = jQuery(this.getDOMNode())
|
||||||
|
$root.find("select.metro-tempo").val(metro.tempo)
|
||||||
|
$root.find("select.metro-sound").val(metro.sound)
|
||||||
|
|
||||||
|
if initializedMetronomeControls
|
||||||
|
mode = if metro.cricket then 'cricket' else 'self'
|
||||||
|
logger.debug("settingcricket", mode)
|
||||||
|
$root.find('#metronome-playback-select').metronomeSetPlaybackMode(mode)
|
||||||
|
|
||||||
|
monitorControls: (controls, mediaSummary) ->
|
||||||
|
|
||||||
|
if mediaSummary.mediaOpen
|
||||||
|
if mediaSummary.jamTrackOpen
|
||||||
|
controls.startMonitor(PLAYBACK_MONITOR_MODE.JAMTRACK)
|
||||||
|
else if mediaSummary.backingTrackOpen
|
||||||
|
controls.startMonitor(PLAYBACK_MONITOR_MODE.MEDIA_FILE)
|
||||||
|
else if mediaSummary.metronomeOpen
|
||||||
|
controls.startMonitor(PLAYBACK_MONITOR_MODE.METRONOME)
|
||||||
|
else if mediaSummary.recordingOpen
|
||||||
|
controls.startMonitor(PLAYBACK_MONITOR_MODE.MEDIA_FILE)
|
||||||
|
else
|
||||||
|
logger.debug("unable to determine mediaOpen type", mediaSummary)
|
||||||
|
controls.startMonitor(PLAYBACK_MONITOR_MODE.MEDIA_FILE)
|
||||||
|
else
|
||||||
|
controls.stopMonitor()
|
||||||
|
|
||||||
|
metronomePlaybackModeChanged: (e, data) ->
|
||||||
|
|
||||||
|
mode = data.playbackMode # will be either 'self' or 'cricket'
|
||||||
|
|
||||||
|
logger.debug("setting metronome playback mode: ", mode)
|
||||||
|
isCricket = mode == 'cricket';
|
||||||
|
SessionActions.metronomeCricketChange(isCricket)
|
||||||
|
|
||||||
|
|
||||||
|
onMetronomeChanged: () ->
|
||||||
|
|
||||||
|
@setMetronomeFromForm()
|
||||||
|
|
||||||
|
setMetronomeFromForm: () ->
|
||||||
|
$root = jQuery(this.getDOMNode())
|
||||||
|
tempo = $root.find("select.metro-tempo:visible option:selected").val()
|
||||||
|
sound = $root.find("select.metro-sound:visible option:selected").val()
|
||||||
|
|
||||||
|
t = parseInt(tempo)
|
||||||
|
s = null
|
||||||
|
if tempo == NaN || tempo == 0 || tempo == null
|
||||||
|
t = 120
|
||||||
|
|
||||||
|
if sound == null || typeof(sound)=='undefined' || sound == ""
|
||||||
|
s = "Beep"
|
||||||
|
else
|
||||||
|
s = sound
|
||||||
|
|
||||||
|
logger.debug("Setting tempo and sound:", t, s)
|
||||||
|
MixerActions.metronomeChanged(t, s, 1, 0)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
|
||||||
|
tempo_options = []
|
||||||
|
for tempo in @tempos
|
||||||
|
tempo_options.push(`<option value={tempo}>{tempo}</option>`)
|
||||||
|
|
||||||
|
`<div className="media-controls has-mix">
|
||||||
|
|
||||||
|
<div className="jam-track-get-ready">
|
||||||
|
<div className="spinner-small"></div>
|
||||||
|
<span>Get Ready!</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="play-buttons">
|
||||||
|
<a className="play-button" href="#">
|
||||||
|
<img src="/assets/content/icon_playbutton.png" width="20" height="20" className="playbutton" />
|
||||||
|
<img src="/assets/content/icon_pausebutton.png" width="20" height="20" className="pausebutton" />
|
||||||
|
</a>
|
||||||
|
<a className="stop-button" href="#">
|
||||||
|
<img src="/assets/content/icon_stopbutton.png" width="20" height="20" className="stopbutton" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="metronome-playback-options">
|
||||||
|
<span id="metronome-playback-select"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="metronome-options">
|
||||||
|
<div className="metronome-selects">
|
||||||
|
<div class="metronome-field">
|
||||||
|
<select className="metronome-select metro-sound" title="Metronome Sound" name="metronome_sound">
|
||||||
|
<option value="Beep">Knock</option>
|
||||||
|
<option value="Click">Tap</option>
|
||||||
|
<option value="Snare">Snare</option>
|
||||||
|
<option value="Kick">Kick</option>
|
||||||
|
</select>
|
||||||
|
<label htmlFor="metronome_sound">Sound:</label>
|
||||||
|
</div>
|
||||||
|
<div class="metronome-field">
|
||||||
|
<select className="metronome-select metro-tempo" title="Metronome Tempo" name="metronome_tempo">
|
||||||
|
{tempo_options}
|
||||||
|
</select>
|
||||||
|
<label htmlFor="metronome_tempo">Tempo:</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="recording-time start-time">0:00</div>
|
||||||
|
<div className="recording-playback">
|
||||||
|
<div className="recording-slider"><img src="/assets/content/slider_playcontrols.png" height="16" width="5" /></div>
|
||||||
|
</div>
|
||||||
|
<div className="recording-time duration-time">0:00</div>
|
||||||
|
|
||||||
|
<div className="recording-current">0:00</div>
|
||||||
|
|
||||||
|
<div className="playback-mode-buttons icheckbuttons">
|
||||||
|
<input type="radio" name="playback-mode" defaultChecked="checked" value="preview-to-all" className="preview-to-all" /><label htmlFor="playback-mode-preview-all" className="radio-text">Preview to All</label>
|
||||||
|
<input type="radio" name="playback-mode" value="preview-to-me" className="preview-to-me" /><label htmlFor="playback-mode-preview-me" className="radio-text">Preview Only to Me</label>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
|
||||||
|
getInitialState: () ->
|
||||||
|
{controls: null, mediaSummary: {}, initializedMetronomeControls: false}
|
||||||
|
|
||||||
|
tryPrepareMetronome: (metro) ->
|
||||||
|
if @state.mediaSummary.metronomeOpen && !@state.initializedMetronomeControls
|
||||||
|
$root = jQuery(this.getDOMNode())
|
||||||
|
$root.on("change", ".metronome-select", @onMetronomeChanged)
|
||||||
|
$root.find('#metronome-playback-select').metronomePlaybackMode({positions:['bottom'], offsetParent:$('#minimal-container')}).on(EVENTS.METRONOME_PLAYBACK_MODE_SELECTED, @metronomePlaybackModeChanged)
|
||||||
|
@updateMetronomeDetails(metro, true)
|
||||||
|
@setState({initializedMetronomeControls: true})
|
||||||
|
|
||||||
|
|
||||||
|
componentDidUpdate: (prevProps, prevState) ->
|
||||||
|
@tryPrepareMetronome(@state.metro)
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
|
||||||
|
$root = jQuery(this.getDOMNode())
|
||||||
|
controls = context.JK.PlaybackControls($root, {mediaActions: MediaPlaybackActions})
|
||||||
|
|
||||||
|
mediaSummary = MixerStore.mixers.mediaSummary
|
||||||
|
metro = MixerStore.mixers.metro
|
||||||
|
|
||||||
|
@monitorControls(controls, mediaSummary)
|
||||||
|
|
||||||
|
@tryPrepareMetronome(metro)
|
||||||
|
|
||||||
|
@setState({mediaSummary: mediaSummary, controls: controls, metro: metro})
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
context = window
|
||||||
|
logger = context.JK.logger
|
||||||
|
|
||||||
|
mixins = []
|
||||||
|
|
||||||
|
if window.opener?
|
||||||
|
SessionActions = window.opener.SessionActions
|
||||||
|
MediaPlaybackStore = window.opener.MediaPlaybackStore
|
||||||
|
MixerActions = window.opener.MixerActions
|
||||||
|
|
||||||
|
mixins.push(Reflux.listenTo(MediaPlaybackStore, 'onMediaStateChanged'))
|
||||||
|
|
||||||
|
@PopupMediaControls = React.createClass({
|
||||||
|
|
||||||
|
mixins: mixins
|
||||||
|
|
||||||
|
onMediaStateChanged: (changes) ->
|
||||||
|
if changes.currentTimeChanged && @root?
|
||||||
|
@setState({time: changes.time})
|
||||||
|
|
||||||
|
showMetronome: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
SessionActions.showNativeMetronomeGui()
|
||||||
|
|
||||||
|
getInitialState: () ->
|
||||||
|
{time: '0:00'}
|
||||||
|
|
||||||
|
close: () ->
|
||||||
|
window.close()
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
closeLinkText = null
|
||||||
|
header = null
|
||||||
|
extraControls = null
|
||||||
|
|
||||||
|
# give the users options to close it
|
||||||
|
if @props.mediaSummary.jamTrackOpen
|
||||||
|
mediaType = "JamTrack"
|
||||||
|
mediaName = @props.jamTracks[0].name
|
||||||
|
closeLinkText = 'close JamTrack'
|
||||||
|
header = `<h3>{mediaType}: {mediaName} ({this.state.time})</h3>`
|
||||||
|
else if @props.mediaSummary.backingTrackOpen
|
||||||
|
mediaType = "Audio File"
|
||||||
|
mediaName = context.JK.getNameOfFile(@props.backingTracks[0].shortFilename)
|
||||||
|
closeLinkText = 'close audio file'
|
||||||
|
header = `<h3>{mediaType}: {mediaName} ({this.state.time})</h3>`
|
||||||
|
extraControls =
|
||||||
|
`<div>
|
||||||
|
<div className="field">
|
||||||
|
<input type="checkbox" name="loop" /><label htmlFor="loop">Loop audio file playback</label>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>`
|
||||||
|
else if @props.mediaSummary.metronomeOpen
|
||||||
|
mediaType = "Metronome"
|
||||||
|
closeLinkText = 'close metronome'
|
||||||
|
header = `<h3>Metronome</h3>`
|
||||||
|
extraControls =
|
||||||
|
`<div>
|
||||||
|
<a className="display-metronome" onClick={this.showMetronome}>Display visual metronome</a>
|
||||||
|
</div>`
|
||||||
|
else if @props.mediaSummary.recordingOpen
|
||||||
|
mediaType = "Recording"
|
||||||
|
mediaName = @props.recordedTracks[0].recordingName
|
||||||
|
closeLinkText = 'close recording'
|
||||||
|
header = `<h3>{mediaType}: {mediaName} ({this.state.time})</h3>`
|
||||||
|
else
|
||||||
|
mediaType = ""
|
||||||
|
|
||||||
|
`<div className="media-controls-popup">
|
||||||
|
{header}
|
||||||
|
<MediaControls />
|
||||||
|
{extraControls}
|
||||||
|
<a className="close-link" onClick={this.close}>{closeLinkText}</a>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
windowUnloaded: () ->
|
||||||
|
SessionActions.closeMedia() unless window.DontAutoCloseMedia
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
$(window).unload(@windowUnloaded)
|
||||||
|
|
||||||
|
@root = jQuery(this.getDOMNode())
|
||||||
|
|
||||||
|
$loop = @root.find('input[name="loop"]')
|
||||||
|
context.JK.checkbox($loop)
|
||||||
|
|
||||||
|
$loop.on('ifChecked', () =>
|
||||||
|
logger.debug("@props", @props)
|
||||||
|
# it doesn't matter if you do personal or master, because backend just syncs both
|
||||||
|
MixerActions.loopChanged(@props.backingTracks[0].mixers.personal.mixer, true)
|
||||||
|
)
|
||||||
|
$loop.on('ifUnchecked', () =>
|
||||||
|
# it doesn't matter if you do personal or master, because backend just syncs both
|
||||||
|
MixerActions.loopChanged(@props.backingTracks[0].mixers.personal.mixer, false)
|
||||||
|
)
|
||||||
|
|
||||||
|
@resizeWindow()
|
||||||
|
|
||||||
|
# this is necessary due to whatever the client's rendering behavior is.
|
||||||
|
setTimeout(@resizeWindow, 300)
|
||||||
|
|
||||||
|
componentDidUpdate: () ->
|
||||||
|
@resizeWindow()
|
||||||
|
|
||||||
|
resizeWindow: () =>
|
||||||
|
$container = $('#minimal-container')
|
||||||
|
width = $container.width()
|
||||||
|
height = $container.height()
|
||||||
|
|
||||||
|
# there is 20px or so of unused space at the top of the page. can't figure out why it's there. (above #minimal-container)
|
||||||
|
#mysteryTopMargin = 20
|
||||||
|
mysteryTopMargin = 0
|
||||||
|
# deal with chrome in real browsers
|
||||||
|
offset = (window.outerHeight - window.innerHeight) + mysteryTopMargin
|
||||||
|
|
||||||
|
# handle native client chrome that the above outer-inner doesn't catch
|
||||||
|
#if navigator.userAgent.indexOf('JamKazam') > -1
|
||||||
|
|
||||||
|
#offset += 25
|
||||||
|
|
||||||
|
window.resizeTo(width, height + offset)
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
mixins = []
|
||||||
|
|
||||||
|
# this check ensures we attempt to listen if this component is created in a popup
|
||||||
|
if window.opener
|
||||||
|
mixins.push(Reflux.listenTo(window.opener.RecordingStore,"onRecordingStateChanged"))
|
||||||
|
|
||||||
|
@PopupRecordingStartStop = React.createClass({
|
||||||
|
|
||||||
|
mixins: mixins
|
||||||
|
|
||||||
|
onRecordingStateChanged: (recordingState) ->
|
||||||
|
this.setState(isRecording: recordingState.isRecording, recordedOnce: this.state.recordedOnce || recordingState.isRecording)
|
||||||
|
|
||||||
|
startStopRecording: () ->
|
||||||
|
if this.state.isRecording
|
||||||
|
window.opener.RecordingActions.stopRecording()
|
||||||
|
else
|
||||||
|
window.opener.RecordingActions.startRecording()
|
||||||
|
|
||||||
|
onNoteShowHide: () ->
|
||||||
|
this.setState(showNote: !this.state.showNote)
|
||||||
|
|
||||||
|
getInitialState: () ->
|
||||||
|
{isRecording: window.ParentIsRecording, showNote: true, recordedOnce: false}
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
recordingVerb = if this.state.isRecording then 'Stop' else 'Start'
|
||||||
|
|
||||||
|
recordingBtnClasses = classNames({
|
||||||
|
"currently-recording" : this.state.isRecording,
|
||||||
|
"control" : true
|
||||||
|
})
|
||||||
|
|
||||||
|
noteJSX = `<div className="important-note">
|
||||||
|
<h5>
|
||||||
|
Important Note
|
||||||
|
</h5>
|
||||||
|
<div className="contents">
|
||||||
|
While playing in your session, you are listening to your own personal mix. This recording will use the master mix,
|
||||||
|
which may sound very different. To hear and adjust your master mix settings, click the MIXER button in the session toolbar.
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
recordingJSX = `<div className="recording-options">
|
||||||
|
<div className="field">
|
||||||
|
<input type="radio" name="recording-input-type" id="recording-input-both" defaultChecked="checked" />
|
||||||
|
<label htmlFor="recording-input-both">Record both video and audio</label>
|
||||||
|
<div className="clearall"></div>
|
||||||
|
</div>
|
||||||
|
<div className="field">
|
||||||
|
<input type="radio" name="recording-input-type" id="recording-input-audio" />
|
||||||
|
<label htmlFor="recording-input-audio">Record audio only</label>
|
||||||
|
<div className="clearall"></div>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
if this.state.showNote
|
||||||
|
noteText = 'hide note'
|
||||||
|
else
|
||||||
|
noteText = 'show note'
|
||||||
|
|
||||||
|
noteShowHideJSX = `<a href="#" className="note-show-hide" onClick={this.onNoteShowHide}>{noteText}</a>`
|
||||||
|
|
||||||
|
note = null
|
||||||
|
recordingOptions = null
|
||||||
|
noteShowHide = null
|
||||||
|
|
||||||
|
if this.state.showNote && !this.state.isRecording && !this.state.recordedOnce
|
||||||
|
# should we show the note itself? Only if not recording, too
|
||||||
|
note = noteJSX
|
||||||
|
|
||||||
|
if !this.state.isRecording && !this.state.recordedOnce
|
||||||
|
noteShowHide = noteShowHideJSX
|
||||||
|
|
||||||
|
if gon.global.video_available == "full"
|
||||||
|
recordingOptions = recordingJSX
|
||||||
|
|
||||||
|
|
||||||
|
`<div className="recording-start-stop">
|
||||||
|
<div className="control-holder">
|
||||||
|
<a className={recordingBtnClasses} onClick={this.startStopRecording}>
|
||||||
|
<span className="helper" />
|
||||||
|
<img src="/assets/content/recordbutton-off.png" width="20" height="20" />
|
||||||
|
<span id="recording-status">{recordingVerb} Recording</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{recordingOptions}
|
||||||
|
|
||||||
|
{note}
|
||||||
|
|
||||||
|
{noteShowHide}
|
||||||
|
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
windowUnloaded: () ->
|
||||||
|
window.opener.RecordingActions.recordingControlsClosed()
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
$(window).unload(@windowUnloaded)
|
||||||
|
|
||||||
|
$root = jQuery(this.getDOMNode())
|
||||||
|
|
||||||
|
$recordingType = $root.find('input[type="radio"]')
|
||||||
|
context.JK.checkbox($recordingType)
|
||||||
|
|
||||||
|
@resizeWindow()
|
||||||
|
|
||||||
|
# this is necessary due to whatever the client's rendering behavior is.
|
||||||
|
setTimeout(@resizeWindow, 300)
|
||||||
|
|
||||||
|
componentDidUpdate: () ->
|
||||||
|
@resizeWindow()
|
||||||
|
|
||||||
|
resizeWindow: () =>
|
||||||
|
$container = $('#minimal-container')
|
||||||
|
width = $container.width()
|
||||||
|
height = $container.height()
|
||||||
|
|
||||||
|
# there is 20px or so of unused space at the top of the page. can't figure out why it's there. (above #minimal-container)
|
||||||
|
mysteryTopMargin = 20
|
||||||
|
|
||||||
|
# deal with chrome in real browsers
|
||||||
|
offset = (window.outerHeight - window.innerHeight) + mysteryTopMargin
|
||||||
|
|
||||||
|
# handle native client chrome that the above outer-inner doesn't catch
|
||||||
|
#if navigator.userAgent.indexOf('JamKazam') > -1
|
||||||
|
|
||||||
|
#offset += 25
|
||||||
|
|
||||||
|
window.resizeTo(width, height + offset)
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
context = window
|
||||||
|
logger = context.JK.logger
|
||||||
|
|
||||||
|
@PopupWrapper = React.createClass({
|
||||||
|
|
||||||
|
getInitialState: () ->
|
||||||
|
{ready: false}
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
logger.debug("PopupProps", window.PopupProps)
|
||||||
|
return React.createElement(window[this.props.component], window.PopupProps)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
MixerActions = @MixerActions
|
||||||
|
|
||||||
|
@SessionBackingTrack = React.createClass({
|
||||||
|
|
||||||
|
mixins: [@MasterPersonalMixersMixin]
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
mode: React.PropTypes.bool.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMute: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
mixer = @mixer()
|
||||||
|
|
||||||
|
unless mixer?
|
||||||
|
logger.debug("ignoring mute because no media mixer")
|
||||||
|
return
|
||||||
|
|
||||||
|
muting = $(e.currentTarget).is('.enabled')
|
||||||
|
|
||||||
|
MixerActions.mute([mixer], muting)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
mixers = @mixers()
|
||||||
|
muteMixer = mixers.mixer
|
||||||
|
muteMixerId = muteMixer?.id
|
||||||
|
|
||||||
|
classes = classNames({
|
||||||
|
'track-icon-mute': true
|
||||||
|
'enabled' : !muteMixer?.mute
|
||||||
|
'muted' : muteMixer?.mute
|
||||||
|
})
|
||||||
|
|
||||||
|
componentClasses = classNames({
|
||||||
|
"session-track" : true
|
||||||
|
"backing-track" : true
|
||||||
|
})
|
||||||
|
|
||||||
|
pan = if mixers.mixer? then mixers.mixer?.pan else 0
|
||||||
|
|
||||||
|
panStyle = {
|
||||||
|
transform: "rotate(#{pan}deg)"
|
||||||
|
WebkitTransform: "rotate(#{pan}deg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
`<div className={componentClasses}>
|
||||||
|
<div className="session-track-contents">
|
||||||
|
<div className="name">{this.props.shortFilename}</div>
|
||||||
|
<div className="track-controls">
|
||||||
|
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={mixers} />
|
||||||
|
<div className="track-buttons">
|
||||||
|
<div className="track-icon-pan" style={panStyle}/>
|
||||||
|
<div className={classes} data-control="mute" data-mixer-id={muteMixerId} onClick={this.handleMute}/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$mute,
|
||||||
|
'SessionTrackVolumeHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@mixers()}
|
||||||
|
,
|
||||||
|
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$pan,
|
||||||
|
'SessionTrackPanHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@mixers()}
|
||||||
|
,
|
||||||
|
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
@SessionChatMixer= React.createClass({
|
||||||
|
|
||||||
|
handleMute: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
unless @props.mixers.mixer
|
||||||
|
logger.debug("ignoring mute; no mixer")
|
||||||
|
return
|
||||||
|
|
||||||
|
muting = $(e.currentTarget).is('.enabled')
|
||||||
|
|
||||||
|
MixerActions.mute([@props.mixers.mixer], muting)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
muteMixer = @props.mixers.muteMixer
|
||||||
|
vuMixer = @props.mixers.vuMixer
|
||||||
|
muteMixerId = muteMixer?.id
|
||||||
|
|
||||||
|
classes = classNames({
|
||||||
|
'track-icon-mute': true
|
||||||
|
'enabled' : !muteMixer?.mute
|
||||||
|
'muted' : muteMixer?.mute
|
||||||
|
})
|
||||||
|
|
||||||
|
pan = if @props.mixers.mixer? then @props.mixers.mixer.pan else 0
|
||||||
|
|
||||||
|
panStyle = {
|
||||||
|
transform: "rotate(#{pan}deg)"
|
||||||
|
WebkitTransform: "rotate(#{pan}deg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
`<div className="session-track chat-mixer">
|
||||||
|
<div className="disabled-track-overlay" />
|
||||||
|
<div className="session-track-contents">
|
||||||
|
<div className="name">Session Voice Chat Output</div>
|
||||||
|
<div className="track-instrument"><img height="45" src="/assets/content/icon_instrument_voice45.png" width="45" /></div>
|
||||||
|
<div className="track-controls">
|
||||||
|
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={this.props.mixers} />
|
||||||
|
<div className="track-buttons">
|
||||||
|
<div className={classes} data-control="mute" data-mixer-id={muteMixerId} onClick={this.handleMute}/>
|
||||||
|
<div className="track-icon-pan" style={panStyle}/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$mute,
|
||||||
|
'SessionTrackVolumeHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@props.mixers}
|
||||||
|
,
|
||||||
|
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$pan,
|
||||||
|
'SessionTrackPanHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@props.mixers}
|
||||||
|
,
|
||||||
|
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
@SessionInviteMusiciansBtn = React.createClass({
|
||||||
|
|
||||||
|
mixins: [Reflux.listenTo(@AppStore,"onAppInit")]
|
||||||
|
|
||||||
|
onAppInit: (app) ->
|
||||||
|
@app = app
|
||||||
|
|
||||||
|
@inviteMusiciansUtil = new JK.InviteMusiciansUtil(@app)
|
||||||
|
@inviteMusiciansUtil.initialize(JK.FriendSelectorDialogInstance)
|
||||||
|
|
||||||
|
openInviteDialog : (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
friendInput = @inviteMusiciansUtil.inviteSessionUpdate('#update-session-invite-musicians', context.SessionStore.currentSessionId)
|
||||||
|
@inviteMusiciansUtil.loadFriends()
|
||||||
|
$(friendInput).show()
|
||||||
|
@app.layout.showDialog('select-invites')
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
`<a className="session-invite-musicians" onClick={this.openInviteDialog}>
|
||||||
|
<img src="/assets/content/icon_add.png" width="19" height="19" />
|
||||||
|
Invite Musicians
|
||||||
|
</a>`
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
MixerActions = @MixerActions
|
||||||
|
|
||||||
|
@SessionJamTrack = React.createClass({
|
||||||
|
|
||||||
|
mixins: [@MasterPersonalMixersMixin]
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
mode: React.PropTypes.bool.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMute: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
mixer = @mixer()
|
||||||
|
|
||||||
|
unless mixer?
|
||||||
|
logger.debug("ignoring mute because no media mixer")
|
||||||
|
return
|
||||||
|
|
||||||
|
muting = $(e.currentTarget).is('.enabled')
|
||||||
|
|
||||||
|
MixerActions.mute([mixer], muting)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
mixers = @mixers()
|
||||||
|
muteMixer = mixers.mixer
|
||||||
|
muteMixerId = muteMixer?.id
|
||||||
|
|
||||||
|
classes = classNames({
|
||||||
|
'track-icon-mute': true
|
||||||
|
'enabled' : !muteMixer?.mute
|
||||||
|
'muted' : muteMixer?.mute
|
||||||
|
})
|
||||||
|
|
||||||
|
componentClasses = classNames({
|
||||||
|
"session-track" : true
|
||||||
|
"jam-track" : true
|
||||||
|
})
|
||||||
|
|
||||||
|
pan = if mixers.mixer? then mixers.mixer?.pan else 0
|
||||||
|
|
||||||
|
panStyle = {
|
||||||
|
transform: "rotate(#{pan}deg)"
|
||||||
|
WebkitTransform: "rotate(#{pan}deg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
`<div className={componentClasses}>
|
||||||
|
<div className="session-track-contents">
|
||||||
|
<div className="name">{this.props.part}</div>
|
||||||
|
<div className="track-controls">
|
||||||
|
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={mixers} />
|
||||||
|
<div className="track-buttons">
|
||||||
|
<div className="track-instrument"><img height="24" src={this.props.instrumentIcon} width="24" /></div>
|
||||||
|
<div className="track-icon-pan" style={panStyle}/>
|
||||||
|
<div className={classes} data-control="mute" data-mixer-id={muteMixerId} onClick={this.handleMute}/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$mute,
|
||||||
|
'SessionTrackVolumeHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@mixers()}
|
||||||
|
,
|
||||||
|
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$pan,
|
||||||
|
'SessionTrackPanHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@mixers()}
|
||||||
|
,
|
||||||
|
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
MixerActions = @MixerActions
|
||||||
|
|
||||||
|
@SessionJamTrackCategory = React.createClass({
|
||||||
|
|
||||||
|
handleMute: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
muting = $(e.currentTarget).is('.enabled')
|
||||||
|
|
||||||
|
MixerActions.mute([this.props.mixers.mixer], muting)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
# today, all mixers are the same for a remote participant; so just grab the 1st
|
||||||
|
mixers = @props.mixers
|
||||||
|
|
||||||
|
muteMixer = mixers.muteMixer
|
||||||
|
vuMixer = mixers.vuMixer
|
||||||
|
muteMixerId = muteMixer?.id
|
||||||
|
|
||||||
|
classes = classNames({
|
||||||
|
'track-icon-mute': true
|
||||||
|
'enabled' : !muteMixer?.mute
|
||||||
|
'muted' : muteMixer?.mute
|
||||||
|
})
|
||||||
|
|
||||||
|
componentClasses = classNames({
|
||||||
|
"session-track" : true
|
||||||
|
"jam-track-category" : true
|
||||||
|
})
|
||||||
|
|
||||||
|
pan = mixers.mixer.pan
|
||||||
|
|
||||||
|
panStyle = {
|
||||||
|
transform: "rotate(#{pan}deg)"
|
||||||
|
WebkitTransform: "rotate(#{pan}deg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
`<div className={componentClasses}>
|
||||||
|
<div className="session-track-contents">
|
||||||
|
<div className="jam-track-header">JamTrack:</div>
|
||||||
|
<div className="name">{this.props.jamTrackName}</div>
|
||||||
|
<div className="track-controls">
|
||||||
|
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={mixers} />
|
||||||
|
<div className="track-buttons">
|
||||||
|
<div className="track-icon-pan" style={panStyle}/>
|
||||||
|
<div className={classes} data-control="mute" data-mixer-id={muteMixerId} onClick={this.handleMute}/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$mute,
|
||||||
|
'SessionTrackVolumeHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@props.mixers}
|
||||||
|
,
|
||||||
|
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$pan,
|
||||||
|
'SessionTrackPanHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@props.mixers}
|
||||||
|
,
|
||||||
|
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
@SessionLeaveBtn = React.createClass({
|
||||||
|
|
||||||
|
onLeave: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
@rateSession()
|
||||||
|
|
||||||
|
SessionActions.leaveSession.trigger({location: '/client#/home'})
|
||||||
|
|
||||||
|
rateSession: () ->
|
||||||
|
unless @rateSessionDialog?
|
||||||
|
@rateSessionDialog = new context.JK.RateSessionDialog(context.JK.app);
|
||||||
|
@rateSessionDialog.initialize();
|
||||||
|
|
||||||
|
@rateSessionDialog.showDialog();
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
`<a className="session-leave button-grey right leave" onClick={this.onLeave}>
|
||||||
|
<img src="/assets/content/icon_leave.png" align="texttop" height="14" width="14"/>
|
||||||
|
LEAVE
|
||||||
|
</a>`
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
context = window
|
||||||
|
rest = context.JK.Rest()
|
||||||
|
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||||
|
MIX_MODES = context.JK.MIX_MODES
|
||||||
|
|
||||||
|
@SessionMasterCategoryControls = React.createClass({
|
||||||
|
|
||||||
|
mixins: [Reflux.listenTo(@SessionMediaTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit")]
|
||||||
|
|
||||||
|
onInputsChanged: (sessionMixers) ->
|
||||||
|
mixers = sessionMixers.mixers
|
||||||
|
inputGroupMixers = mixers.getAudioInputCategoryMixer(MIX_MODES.MASTER)
|
||||||
|
chatGroupMixers = mixers.getChatCategoryMixer(MIX_MODES.MASTER)
|
||||||
|
|
||||||
|
@setState({inputGroupMixers: inputGroupMixers, chatGroupMixers: chatGroupMixers})
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
categoryControls = []
|
||||||
|
|
||||||
|
if @state.inputGroupMixers?
|
||||||
|
input =
|
||||||
|
mixers: @state.inputGroupMixers
|
||||||
|
|
||||||
|
categoryControls.push(`<SessionMusicMixer key={input.mixers.mixer.id} {...input} />`)
|
||||||
|
|
||||||
|
if @state.chatGroupMixers?
|
||||||
|
input =
|
||||||
|
mixers: @state.chatGroupMixers
|
||||||
|
|
||||||
|
categoryControls.push(`<SessionChatMixer key={input.mixers.mixer.id} {...input} />`)
|
||||||
|
|
||||||
|
|
||||||
|
`<div className="session-category-controls">
|
||||||
|
<h2>master output</h2>
|
||||||
|
<div className="session-tracks-scroller">
|
||||||
|
{categoryControls}
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
|
||||||
|
getInitialState:() ->
|
||||||
|
{inputGroupMixers: null, chatGroupMixers: null}
|
||||||
|
|
||||||
|
|
||||||
|
onAppInit: (app) ->
|
||||||
|
@app = app
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
context = window
|
||||||
|
rest = context.JK.Rest()
|
||||||
|
SessionActions = @SessionActions
|
||||||
|
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||||
|
MIX_MODES = context.JK.MIX_MODES
|
||||||
|
EVENTS = context.JK.EVENTS
|
||||||
|
ChannelGroupIds = context.JK.ChannelGroupIds
|
||||||
|
|
||||||
|
@SessionMasterMediaTracks = React.createClass({
|
||||||
|
|
||||||
|
mixins: [@SessionMediaTracksMixin, Reflux.listenTo(@SessionMediaTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit")]
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
mediaTracks = []
|
||||||
|
|
||||||
|
if this.state.mediaSummary.mediaOpen
|
||||||
|
|
||||||
|
if this.state.mediaSummary.backingTrackOpen
|
||||||
|
for backingTrack in @state.backingTracks
|
||||||
|
backingTrack.mode = MIX_MODES.MASTER
|
||||||
|
mediaTracks.push(`<SessionBackingTrack key={backingTrack.track.id} {...backingTrack} />`)
|
||||||
|
else if this.state.mediaSummary.jamTrackOpen
|
||||||
|
mediaTracks.push(`<SessionJamTrackCategory key="JamTrackCategory" jamTrackName={this.state.jamTrackName} mixers={this.state.mediaCategoryMixer} mode={MIX_MODES.MASTER} />`)
|
||||||
|
for jamTrack in @state.jamTracks
|
||||||
|
jamTrack.mode = MIX_MODES.MASTER
|
||||||
|
mediaTracks.push(`<SessionJamTrack key={jamTrack.id} {...jamTrack} />`)
|
||||||
|
else if this.state.mediaSummary.recordingOpen
|
||||||
|
mediaTracks.push(`<SessionRecordedCategory key="RecordedCategory" recordingName={this.state.recordingName} mixers={this.state.mediaCategoryMixer} mode={MIX_MODES.MASTER} />`)
|
||||||
|
for recordedTrack in @state.recordedTracks
|
||||||
|
recordedTrack.mode = MIX_MODES.MASTER
|
||||||
|
mediaTracks.push(`<SessionRecordedTrack key={recordedTrack.track.id} {...recordedTrack} />`)
|
||||||
|
else if this.state.mediaSummary.metronomeOpen
|
||||||
|
@state.metronome.mode = MIX_MODES.MASTER
|
||||||
|
mediaTracks.push(`<SessionMetronome key={this.state.metronome.id} {...this.state.metronome} />`)
|
||||||
|
|
||||||
|
`<div className="session-media-tracks">
|
||||||
|
<h2>recorded audio</h2>
|
||||||
|
<div className="session-tracks-scroller">
|
||||||
|
{mediaTracks}
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
|
||||||
|
getInitialState:() ->
|
||||||
|
{mediaSummary:{mediaOpen: false}, isRecording: false, backingTracks: [], jamTracks: [], recordedTracks: [], metronome: null}
|
||||||
|
|
||||||
|
onAppInit: (app) ->
|
||||||
|
@app = app
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
context = window
|
||||||
|
MIX_MODES = context.JK.MIX_MODES
|
||||||
|
|
||||||
|
@SessionMasterMix = React.createClass({
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
`<div id="master-tracks">
|
||||||
|
<SessionMasterMyTracks mode={MIX_MODES.MASTER} />
|
||||||
|
<SessionMasterOtherTracks mode={MIX_MODES.MASTER} />
|
||||||
|
<SessionMasterMediaTracks mode={MIX_MODES.MASTER} />
|
||||||
|
<SessionMasterCategoryControls mode={MIX_MODES.MASTER} />
|
||||||
|
</div>`
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
context = window
|
||||||
|
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||||
|
MIX_MODES = context.JK.MIX_MODES
|
||||||
|
logger = context.JK.logger
|
||||||
|
|
||||||
|
@SessionMasterMyTracks = React.createClass({
|
||||||
|
|
||||||
|
mixins: [@SessionMyTracksMixin, Reflux.listenTo(@SessionMyTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit")]
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
content = null
|
||||||
|
tracks = []
|
||||||
|
|
||||||
|
if this.state.tracks.length > 0
|
||||||
|
for track in this.state.tracks
|
||||||
|
track.mode = MIX_MODES.MASTER
|
||||||
|
tracks.push(`<SessionMyTrack key={track.track.client_track_id} {...track} />`)
|
||||||
|
|
||||||
|
if @state.chat
|
||||||
|
@state.chat.mode = @props.mode
|
||||||
|
tracks.push(`<SessionMyChat key="chat" {...this.state.chat} />`)
|
||||||
|
|
||||||
|
else if this.state.session? && this.state.session.inSession()
|
||||||
|
logger.debug("no 'my inputs' for master mix")
|
||||||
|
|
||||||
|
`<div className="session-my-tracks">
|
||||||
|
<h2>my live tracks</h2>
|
||||||
|
<div className="session-tracks-scroller">
|
||||||
|
{content}
|
||||||
|
{tracks}
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
getInitialState:() ->
|
||||||
|
{tracks:[], session: null}
|
||||||
|
|
||||||
|
onAppInit: (app) ->
|
||||||
|
@app = app
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
MixerActions = @MixerActions
|
||||||
|
|
||||||
|
@SessionMasterOtherTrack = React.createClass({
|
||||||
|
|
||||||
|
handleMute: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
unless @props.mixers.mixer?
|
||||||
|
logger.debug("ignoring mute; no mixer")
|
||||||
|
return
|
||||||
|
|
||||||
|
muting = $(e.currentTarget).is('.enabled')
|
||||||
|
|
||||||
|
MixerActions.mute([@props.mixers.mixer], muting)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
muteMixer = @props.mixers.muteMixer
|
||||||
|
vuMixer = @props.mixers.vuMixer
|
||||||
|
muteMixerId = muteMixer?.id
|
||||||
|
|
||||||
|
classes = classNames({
|
||||||
|
'track-icon-mute': true
|
||||||
|
'enabled' : !muteMixer?.mute
|
||||||
|
'muted' : muteMixer?.mute
|
||||||
|
})
|
||||||
|
|
||||||
|
pan = if @props.mixers.mixer? then @props.mixers.mixer.pan else 0
|
||||||
|
|
||||||
|
panStyle = {
|
||||||
|
transform: "rotate(#{pan}deg)"
|
||||||
|
WebkitTransform: "rotate(#{pan}deg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# <div className="track-icon-equalizer" />
|
||||||
|
|
||||||
|
`<div className="session-track my-track">
|
||||||
|
<div className="disabled-track-overlay" />
|
||||||
|
<div className="session-track-contents">
|
||||||
|
<div className="name">{this.props.name}</div>
|
||||||
|
<div className="track-avatar"><img src={this.props.photoUrl}/></div>
|
||||||
|
<div className="track-instrument"><img height="45" src={this.props.instrumentIcon} width="45" /></div>
|
||||||
|
<div className="track-controls">
|
||||||
|
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={this.props.mixers} />
|
||||||
|
<div className="track-buttons">
|
||||||
|
<div className={classes} data-control="mute" data-mixer-id={muteMixerId} onClick={this.handleMute}/>
|
||||||
|
<div className="track-icon-pan" style={panStyle}/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$mute,
|
||||||
|
'SessionTrackVolumeHover',
|
||||||
|
() =>
|
||||||
|
{mixers:this.props.mixers}
|
||||||
|
,
|
||||||
|
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$pan,
|
||||||
|
'SessionTrackPanHover',
|
||||||
|
() =>
|
||||||
|
{mixers:this.props.mixers}
|
||||||
|
,
|
||||||
|
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
componentWillUpdate: (nextProps, nextState) ->
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
# disable hover effects if there is no mixer
|
||||||
|
if nextProps.mixers.mixer?
|
||||||
|
$mute.off("click", false)
|
||||||
|
$pan.off("click", false)
|
||||||
|
else
|
||||||
|
$mute.on("click", false)
|
||||||
|
$pan.on("click", false)
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
context = window
|
||||||
|
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||||
|
|
||||||
|
@SessionMasterOtherTracks = React.createClass({
|
||||||
|
|
||||||
|
mixins: [Reflux.listenTo(@SessionOtherTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit")]
|
||||||
|
|
||||||
|
onInputsChanged: (sessionMixers) ->
|
||||||
|
session = sessionMixers.session
|
||||||
|
mixers = sessionMixers.mixers
|
||||||
|
noAudioUsers = mixers.noAudioUsers
|
||||||
|
|
||||||
|
tracks = []
|
||||||
|
|
||||||
|
if session.inSession()
|
||||||
|
|
||||||
|
for participant in session.otherParticipants()
|
||||||
|
|
||||||
|
name = participant.user.name;
|
||||||
|
|
||||||
|
firstTrack = participant.tracks[0]
|
||||||
|
|
||||||
|
photoUrl = context.JK.resolveAvatarUrl(participant.user.photo_url)
|
||||||
|
|
||||||
|
for track in participant.tracks
|
||||||
|
|
||||||
|
mixerData = mixers.findMixerForTrack(participant.client_id, track, false, @props.mode)
|
||||||
|
|
||||||
|
instrumentIcon = context.JK.getInstrumentIcon45(firstTrack.instrument_id)
|
||||||
|
|
||||||
|
trackState = {
|
||||||
|
participant: participant,
|
||||||
|
track: track,
|
||||||
|
mixers: mixerData,
|
||||||
|
name: name,
|
||||||
|
instrumentIcon: instrumentIcon,
|
||||||
|
photoUrl: photoUrl,
|
||||||
|
hasMixer: mixerData.mixer? ,
|
||||||
|
noAudio: noAudioUsers[participant.client_id]
|
||||||
|
}
|
||||||
|
|
||||||
|
tracks.push(trackState)
|
||||||
|
# todo: sessionModel.setAudioEstablished
|
||||||
|
|
||||||
|
this.setState(tracks: tracks, session: session)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
tracks = []
|
||||||
|
|
||||||
|
for track in @state.tracks
|
||||||
|
tracks.push(`<SessionMasterOtherTrack key={track.track.client_track_id} {...track} />`)
|
||||||
|
|
||||||
|
`<div className="session-other-tracks">
|
||||||
|
<h2>other live tracks</h2>
|
||||||
|
<div className="session-tracks-scroller">
|
||||||
|
{tracks}
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
getInitialState:() ->
|
||||||
|
{tracks:[], session: null}
|
||||||
|
|
||||||
|
onAppInit: (app) ->
|
||||||
|
@app = app
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,307 @@
|
||||||
|
context = window
|
||||||
|
rest = context.JK.Rest()
|
||||||
|
SessionActions = @SessionActions
|
||||||
|
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||||
|
MIX_MODES = context.JK.MIX_MODES
|
||||||
|
EVENTS = context.JK.EVENTS
|
||||||
|
ChannelGroupIds = context.JK.ChannelGroupIds
|
||||||
|
|
||||||
|
@SessionMediaTracks = React.createClass({
|
||||||
|
|
||||||
|
mixins: [@SessionMediaTracksMixin, Reflux.listenTo(@SessionMediaTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit")]
|
||||||
|
|
||||||
|
inputsChangedProcessed: (state) ->
|
||||||
|
|
||||||
|
if state.mediaSummary.mediaOpen
|
||||||
|
if !@state.childWindow?
|
||||||
|
childWindow = window.open("/popups/media-controls", 'Media Controls', 'scrollbars=yes,toolbar=no,status=no,height=155,width=350')
|
||||||
|
childWindow.PopupProps = state
|
||||||
|
state.childWindow = childWindow
|
||||||
|
else
|
||||||
|
if !state.metronomeFlickerTimeout? # if the metronomeFlickerTimeout is active, we don't consider closing the childWindow
|
||||||
|
@checkCloseWindow()
|
||||||
|
state.childWindow = null
|
||||||
|
|
||||||
|
checkCloseWindow: () ->
|
||||||
|
if @state.childWindow?
|
||||||
|
@state.childWindow.DontAutoCloseMedia = true
|
||||||
|
@state.childWindow.close()
|
||||||
|
|
||||||
|
|
||||||
|
closeAudio: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
SessionActions.closeMedia()
|
||||||
|
|
||||||
|
cancelDownloadJamTrack: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
logger.debug("closing DownloadJamTrack widget")
|
||||||
|
@state.downloadJamTrack.root.remove()
|
||||||
|
@state.downloadJamTrack.destroy()
|
||||||
|
|
||||||
|
SessionActions.downloadingJamTrack(false)
|
||||||
|
|
||||||
|
@setState({downloadJamTrack: null})
|
||||||
|
|
||||||
|
openRecording: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
# just ignore the click if they are currently recording for now
|
||||||
|
if @state.isRecording
|
||||||
|
@app.notify({
|
||||||
|
"title": "Currently Recording",
|
||||||
|
"text": "You can't open a recording while creating a recording.",
|
||||||
|
"icon_url": "/assets/content/icon_alert_big.png"
|
||||||
|
})
|
||||||
|
return
|
||||||
|
|
||||||
|
@app.layout.showDialog('localRecordings') unless @app.layout.isDialogShowing('localRecordings')
|
||||||
|
|
||||||
|
openBackingTrack: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
if @state.backingTrackDialogOpen
|
||||||
|
logger.debug("backing track dialog already open")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# just ignore the click if they are currently recording for now
|
||||||
|
if @state.isRecording
|
||||||
|
@app.notify({
|
||||||
|
"title": "Currently Recording",
|
||||||
|
"text": "You can't open a backing track while creating a recording.",
|
||||||
|
"icon_url": "/assets/content/icon_alert_big.png"
|
||||||
|
});
|
||||||
|
return
|
||||||
|
|
||||||
|
@setState({backingTrackDialogOpen: true})
|
||||||
|
context.jamClient.ShowSelectBackingTrackDialog("window.JK.HandleBackingTrackSelectedCallback2");
|
||||||
|
|
||||||
|
openMetronome: (e) ->
|
||||||
|
|
||||||
|
if @state.isRecording
|
||||||
|
@app.notify({
|
||||||
|
"title": "Currently Recording",
|
||||||
|
"text": "You can't open a metronome while creating a recording.",
|
||||||
|
"icon_url": "/assets/content/icon_alert_big.png"
|
||||||
|
})
|
||||||
|
return
|
||||||
|
|
||||||
|
SessionActions.openMetronome()
|
||||||
|
|
||||||
|
openJamTrack: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
if @state.isRecording
|
||||||
|
@app.notify({
|
||||||
|
"title": "Currently Recording",
|
||||||
|
"text": "You can't open a jam track while creating a recording.",
|
||||||
|
"icon_url": "/assets/content/icon_alert_big.png"
|
||||||
|
})
|
||||||
|
return
|
||||||
|
|
||||||
|
@app.layout.showDialog('open-jam-track-dialog').one(EVENTS.DIALOG_CLOSED, (e, data) =>
|
||||||
|
# once the dialog is closed, see if the user has a jamtrack selected
|
||||||
|
if !data.canceled && data.result.jamTrack
|
||||||
|
@loadJamTrack(data.result.jamTrack)
|
||||||
|
|
||||||
|
else
|
||||||
|
logger.debug("OpenJamTrack dialog closed with no selection; ignoring", data)
|
||||||
|
)
|
||||||
|
|
||||||
|
loadJamTrack: (jamTrack) ->
|
||||||
|
if @state.downloadJamTrack
|
||||||
|
# if there was one showing before somehow, destroy it.
|
||||||
|
logger.warn("destroying existing JamTrack")
|
||||||
|
@state.downloadJamTrack.root.remove()
|
||||||
|
@state.downloadJamTrack.destroy()
|
||||||
|
#set to null
|
||||||
|
|
||||||
|
|
||||||
|
downloadJamTrack = new context.JK.DownloadJamTrack(@app, jamTrack, 'large');
|
||||||
|
|
||||||
|
# the widget indicates when it gets to any transition; we can hide it once it reaches completion
|
||||||
|
$(downloadJamTrack).on(EVENTS.JAMTRACK_DOWNLOADER_STATE_CHANGED, (e, data) =>
|
||||||
|
if data.state == downloadJamTrack.states.synchronized
|
||||||
|
logger.debug("jamtrack synchronized; hide widget and show tracks")
|
||||||
|
downloadJamTrack.root.remove()
|
||||||
|
downloadJamTrack.destroy()
|
||||||
|
downloadJamTrack = null
|
||||||
|
|
||||||
|
this.setState({downloadJamTrack: null})
|
||||||
|
|
||||||
|
# XXX: test with this removed; it should be unnecessary
|
||||||
|
context.jamClient.JamTrackStopPlay();
|
||||||
|
|
||||||
|
sampleRate = context.jamClient.GetSampleRate()
|
||||||
|
sampleRateForFilename = if sampleRate == 48 then '48' else '44'
|
||||||
|
fqId = jamTrack.id + '-' + sampleRateForFilename
|
||||||
|
|
||||||
|
if jamTrack.jmep
|
||||||
|
logger.debug("setting jmep data")
|
||||||
|
|
||||||
|
context.jamClient.JamTrackLoadJmep(fqId, jamTrack.jmep)
|
||||||
|
else
|
||||||
|
logger.debug("no jmep data for jamtrack")
|
||||||
|
|
||||||
|
# JamTrackPlay means 'load'
|
||||||
|
result = context.jamClient.JamTrackPlay(fqId);
|
||||||
|
|
||||||
|
SessionActions.downloadingJamTrack(false)
|
||||||
|
|
||||||
|
console.log("JamTrackPlay: result", )
|
||||||
|
if !result
|
||||||
|
@app.notify(
|
||||||
|
{
|
||||||
|
title: "JamTrack Can Not Open",
|
||||||
|
text: "Unable to open your JamTrack. Please contact support@jamkazam.com"
|
||||||
|
}
|
||||||
|
, null, true)
|
||||||
|
else
|
||||||
|
participantCnt = context.SessionStore.participants().length
|
||||||
|
rest.playJamTrack(jamTrack.id)
|
||||||
|
.done(() =>
|
||||||
|
@app.refreshUser();
|
||||||
|
)
|
||||||
|
|
||||||
|
context.stats.write('web.jamtrack.open', {
|
||||||
|
value: 1,
|
||||||
|
session_size: participantCnt,
|
||||||
|
user_id: context.JK.currentUserId,
|
||||||
|
user_name: context.JK.currentUserName
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@setState({downloadJamTrack: downloadJamTrack})
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
scrollerClassData = {'session-tracks-scroller': true}
|
||||||
|
mediaOptions = `<div className="media-options">
|
||||||
|
<div className="open-media-file-header">
|
||||||
|
<div className="vertical-helper" />
|
||||||
|
<img src="/assets/content/icon_open_folder.png" width="21" height="21" />
|
||||||
|
<span className="open-text">Open:</span>
|
||||||
|
</div>
|
||||||
|
<ul className="open-media-file-options">
|
||||||
|
<li>
|
||||||
|
<a className="open-recording" onClick={this.openRecording}>Recording</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a className="open-jamtrack" onClick={this.openJamTrack}>JamTrack</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a className="open-backingtrack" onClick={this.openBackingTrack}>Audio File</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div className="use-metronome-header">
|
||||||
|
<img src="/assets/content/icon_instrument_metronome21.png" width="21" height="21" />
|
||||||
|
<a className="open-metronome" onClick={this.openMetronome}>Use Metronome</a>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
contents = null
|
||||||
|
mediaTracks = []
|
||||||
|
|
||||||
|
if this.state.downloadJamTrack?
|
||||||
|
closeOptions =
|
||||||
|
`<div>
|
||||||
|
<a className="closeAudio" onClick={this.cancelDownloadJamTrack}>
|
||||||
|
<img src="/assets/content/icon_close.png" width="18" height="20" />
|
||||||
|
Close JamTrack
|
||||||
|
</a>
|
||||||
|
<div className="download-jamtrack-holder"></div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
contents = closeOptions
|
||||||
|
|
||||||
|
else if this.state.mediaSummary.mediaOpen
|
||||||
|
|
||||||
|
# give the users options to close it
|
||||||
|
if this.state.mediaSummary.jamTrackOpen
|
||||||
|
mediaType = "JamTrack"
|
||||||
|
else if this.state.mediaSummary.backingTrackOpen
|
||||||
|
mediaType = "Audio File"
|
||||||
|
else if this.state.mediaSummary.metronomeOpen
|
||||||
|
mediaType = "Metronome"
|
||||||
|
else if this.state.mediaSummary.recordingOpen
|
||||||
|
mediaType = "Recording"
|
||||||
|
else
|
||||||
|
mediaType = ""
|
||||||
|
|
||||||
|
closeOptions = `<a className="closeAudio" onClick={this.closeAudio}>
|
||||||
|
<img src="/assets/content/icon_close.png" width="18" height="20" />
|
||||||
|
Close {mediaType}
|
||||||
|
</a>`
|
||||||
|
|
||||||
|
|
||||||
|
if this.state.mediaSummary.backingTrackOpen
|
||||||
|
for backingTrack in @state.backingTracks
|
||||||
|
backingTrack.mode = MIX_MODES.PERSONAL
|
||||||
|
mediaTracks.push(`<SessionBackingTrack key={backingTrack.track.id} {...backingTrack} />`)
|
||||||
|
else if this.state.mediaSummary.jamTrackOpen
|
||||||
|
mediaTracks.push(`<SessionJamTrackCategory key="JamTrackCategory" jamTrackName={this.state.jamTrackName} mixers={this.state.mediaCategoryMixer} mode={MIX_MODES.PERSONAL} />`)
|
||||||
|
for jamTrack in @state.jamTracks
|
||||||
|
jamTrack.mode = MIX_MODES.PERSONAL
|
||||||
|
mediaTracks.push(`<SessionJamTrack key={jamTrack.id} {...jamTrack} />`)
|
||||||
|
else if this.state.mediaSummary.recordingOpen
|
||||||
|
mediaTracks.push(`<SessionRecordedCategory key="RecordedCategory" recordingName={this.state.recordingName} mixers={this.state.mediaCategoryMixer} mode={MIX_MODES.PERSONAL} />`)
|
||||||
|
for recordedTrack in @state.recordedTracks
|
||||||
|
recordedTrack.mode = MIX_MODES.PERSONAL
|
||||||
|
mediaTracks.push(`<SessionRecordedTrack key={recordedTrack.track.id} {...recordedTrack} />`)
|
||||||
|
else if this.state.mediaSummary.metronomeOpen
|
||||||
|
@state.metronome.mode = MIX_MODES.PERSONAL
|
||||||
|
mediaTracks.push(`<SessionMetronome key={this.state.metronome.id} {...this.state.metronome} />`)
|
||||||
|
|
||||||
|
contents = closeOptions
|
||||||
|
else
|
||||||
|
|
||||||
|
scrollerClassData['media-options-showing'] = true
|
||||||
|
contents = mediaOptions
|
||||||
|
|
||||||
|
scrollerClasses = classNames(scrollerClassData)
|
||||||
|
|
||||||
|
`<div className="session-media-tracks">
|
||||||
|
<h2>recorded audio</h2>
|
||||||
|
{contents}
|
||||||
|
<div className={scrollerClasses}>
|
||||||
|
<ReactCSSTransitionGroup transitionName="session-track-list" transitionAppear={true}>
|
||||||
|
{mediaTracks}
|
||||||
|
</ReactCSSTransitionGroup>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
|
||||||
|
getInitialState:() ->
|
||||||
|
{mediaSummary:{mediaOpen: false}, isRecording: false, backingTracks: [], jamTracks: [], recordedTracks: [], metronome: null}
|
||||||
|
|
||||||
|
onAppInit: (app) ->
|
||||||
|
@app = app
|
||||||
|
|
||||||
|
handleBackingTrackSelectedCallback: (result) ->
|
||||||
|
|
||||||
|
@setState({backingTrackDialogOpen: false})
|
||||||
|
|
||||||
|
SessionActions.openBackingTrack(result)
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
context.JK.HandleBackingTrackSelectedCallback2 = @handleBackingTrackSelectedCallback
|
||||||
|
|
||||||
|
componentDidUpdate: () ->
|
||||||
|
|
||||||
|
if @state.downloadJamTrack?
|
||||||
|
$holder = $(@getDOMNode()).find('.download-jamtrack-holder')
|
||||||
|
|
||||||
|
if $holder.find('.download-jamtrack').length == 0
|
||||||
|
|
||||||
|
SessionActions.downloadingJamTrack(true)
|
||||||
|
$holder.append(@state.downloadJamTrack.root)
|
||||||
|
|
||||||
|
# kick off the download JamTrack process
|
||||||
|
@state.downloadJamTrack.init()
|
||||||
|
|
||||||
|
@checkCloseWindow() if !@state.mediaSummary.mediaOpen && !@state.metronomeFlickerTimeout?
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
MixerActions = @MixerActions
|
||||||
|
|
||||||
|
@SessionMetronome = React.createClass({
|
||||||
|
|
||||||
|
handleMute: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
muting = $(e.currentTarget).is('.enabled')
|
||||||
|
|
||||||
|
MixerActions.mute([this.props.mixers.mixer], muting)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
# today, all mixers are the same for a remote participant; so just grab the 1st
|
||||||
|
mixers = @props.mixers
|
||||||
|
|
||||||
|
muteMixer = mixers.muteMixer
|
||||||
|
vuMixer = mixers.vuMixer
|
||||||
|
muteMixerId = muteMixer?.id
|
||||||
|
|
||||||
|
classes = classNames({
|
||||||
|
'track-icon-mute': true
|
||||||
|
'enabled' : !muteMixer?.mute
|
||||||
|
'muted' : muteMixer?.mute
|
||||||
|
})
|
||||||
|
|
||||||
|
componentClasses = classNames({
|
||||||
|
"session-track" : true
|
||||||
|
"metronome" : true
|
||||||
|
})
|
||||||
|
|
||||||
|
pan = if mixers.mixer? then mixers.mixer?.pan else 0
|
||||||
|
|
||||||
|
panStyle = {
|
||||||
|
transform: "rotate(#{pan}deg)"
|
||||||
|
WebkitTransform: "rotate(#{pan}deg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
`<div className={componentClasses}>
|
||||||
|
<div className="session-track-contents">
|
||||||
|
<div className="name">Metronome</div>
|
||||||
|
<div className="track-controls">
|
||||||
|
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={mixers} />
|
||||||
|
<div className="track-buttons">
|
||||||
|
<div className="track-instrument"><img height="24" src={this.props.instrumentIcon} width="24" /></div>
|
||||||
|
<div className="track-icon-pan" style={panStyle}/>
|
||||||
|
<div className={classes} data-control="mute" data-mixer-id={muteMixerId} onClick={this.handleMute}/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$mute,
|
||||||
|
'SessionTrackVolumeHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@props.mixers}
|
||||||
|
,
|
||||||
|
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$pan,
|
||||||
|
'SessionTrackPanHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@props.mixers}
|
||||||
|
,
|
||||||
|
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
@SessionMixerBtn = React.createClass({
|
||||||
|
|
||||||
|
openDialog: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
context.JK.app.layout.showDialog('session-master-mix-dialog')
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
`<a className="session-mixer button-grey left" onClick={this.openDialog}>
|
||||||
|
<img src="/assets/content/icon_mixer.png" align="texttop" height="14" width="14"/>
|
||||||
|
MIXER
|
||||||
|
</a>`
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
@SessionMusicMixer= React.createClass({
|
||||||
|
|
||||||
|
handleMute: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
unless @props.mixers.mixer
|
||||||
|
logger.debug("ignoring mute; no mixer")
|
||||||
|
return
|
||||||
|
|
||||||
|
muting = $(e.currentTarget).is('.enabled')
|
||||||
|
|
||||||
|
MixerActions.mute([@props.mixers.mixer], muting)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
muteMixer = @props.mixers.muteMixer
|
||||||
|
vuMixer = @props.mixers.vuMixer
|
||||||
|
muteMixerId = muteMixer?.id
|
||||||
|
|
||||||
|
classes = classNames({
|
||||||
|
'track-icon-mute': true
|
||||||
|
'enabled' : !muteMixer?.mute
|
||||||
|
'muted' : muteMixer?.mute
|
||||||
|
})
|
||||||
|
|
||||||
|
pan = if @props.mixers.mixer? then @props.mixers.mixer.pan else 0
|
||||||
|
|
||||||
|
panStyle = {
|
||||||
|
transform: "rotate(#{pan}deg)"
|
||||||
|
WebkitTransform: "rotate(#{pan}deg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
`<div className="session-track music-mixer">
|
||||||
|
<div className="disabled-track-overlay" />
|
||||||
|
<div className="session-track-contents">
|
||||||
|
<div className="name">Session Music Output</div>
|
||||||
|
<div className="track-instrument"><img height="45" src="/assets/content/icon_instrument_voice45.png" width="45" /></div>
|
||||||
|
<div className="track-controls">
|
||||||
|
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={this.props.mixers} />
|
||||||
|
<div className="track-buttons">
|
||||||
|
<div className={classes} data-control="mute" data-mixer-id={muteMixerId} onClick={this.handleMute}/>
|
||||||
|
<div className="track-icon-pan" style={panStyle}/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$mute,
|
||||||
|
'SessionTrackVolumeHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@props.mixers}
|
||||||
|
,
|
||||||
|
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$pan,
|
||||||
|
'SessionTrackPanHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@props.mixers}
|
||||||
|
,
|
||||||
|
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
MixerActions = @MixerActions
|
||||||
|
|
||||||
|
@SessionMyChat = React.createClass({
|
||||||
|
|
||||||
|
mixins: [@MasterPersonalMixersMixin]
|
||||||
|
|
||||||
|
|
||||||
|
handleMute: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
mixers = @mixers()
|
||||||
|
unless mixers.mixer
|
||||||
|
logger.debug("ignoring mute; no mixer")
|
||||||
|
return
|
||||||
|
|
||||||
|
muting = $(e.currentTarget).is('.enabled')
|
||||||
|
|
||||||
|
MixerActions.mute([mixers.mixer, mixers.oppositeMixer], muting)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
mixers = @mixers()
|
||||||
|
muteMixer = mixers.muteMixer
|
||||||
|
vuMixer = mixers.vuMixer
|
||||||
|
muteMixerId = muteMixer?.id
|
||||||
|
|
||||||
|
classes = classNames({
|
||||||
|
'track-icon-mute': true
|
||||||
|
'enabled' : !muteMixer?.mute
|
||||||
|
'muted' : muteMixer?.mute
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# <div className="track-icon-equalizer" />
|
||||||
|
|
||||||
|
`<div className="session-track chat-track">
|
||||||
|
<div className="disabled-track-overlay" />
|
||||||
|
<div className="session-track-contents">
|
||||||
|
<div className="name">{this.props.name}</div>
|
||||||
|
<div className="track-avatar"><img src={this.props.photoUrl}/></div>
|
||||||
|
<div className="track-instrument"><img height="45" src='/assets/content/icon_instrument_headphones45.png' width="45" /></div>
|
||||||
|
<div className="track-controls">
|
||||||
|
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={mixers} />
|
||||||
|
<div className="track-buttons">
|
||||||
|
<div className={classes} data-control="mute" data-mixer-id={muteMixerId} onClick={this.handleMute}/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$mute,
|
||||||
|
'SessionTrackVolumeHover',
|
||||||
|
() =>
|
||||||
|
{mixers:@mixers()}
|
||||||
|
,
|
||||||
|
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
context = window
|
||||||
|
|
||||||
|
MixerActions = @MixerActions
|
||||||
|
|
||||||
|
@SessionMyTrack = React.createClass({
|
||||||
|
|
||||||
|
|
||||||
|
handleMute: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
unless this.props.mixers.mixer
|
||||||
|
logger.debug("ignoring mute; no mixer")
|
||||||
|
return
|
||||||
|
|
||||||
|
muting = $(e.currentTarget).is('.enabled')
|
||||||
|
|
||||||
|
MixerActions.mute([this.props.mixers.mixer, this.props.mixers.oppositeMixer], muting)
|
||||||
|
|
||||||
|
render: () ->
|
||||||
|
|
||||||
|
muteMixer = this.props.mixers.muteMixer
|
||||||
|
vuMixer = this.props.mixers.vuMixer
|
||||||
|
muteMixerId = muteMixer?.id
|
||||||
|
|
||||||
|
classes = classNames({
|
||||||
|
'track-icon-mute': true
|
||||||
|
'enabled' : !muteMixer?.mute
|
||||||
|
'muted' : muteMixer?.mute
|
||||||
|
})
|
||||||
|
|
||||||
|
pan = if this.props.mixers.mixer? then this.props.mixers.mixer.pan else 0
|
||||||
|
|
||||||
|
panStyle = {
|
||||||
|
transform: "rotate(#{pan}deg)"
|
||||||
|
WebkitTransform: "rotate(#{pan}deg)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# <div className="track-icon-equalizer" />
|
||||||
|
|
||||||
|
`<div className="session-track my-track">
|
||||||
|
<div className="disabled-track-overlay" />
|
||||||
|
<div className="session-track-contents">
|
||||||
|
<div className="name">{this.props.name}</div>
|
||||||
|
<div className="track-avatar"><img src={this.props.photoUrl}/></div>
|
||||||
|
<div className="track-instrument"><img height="45" src={this.props.instrumentIcon} width="45" /></div>
|
||||||
|
<div className="track-controls">
|
||||||
|
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="best" mixers={this.props.mixers} />
|
||||||
|
<div className="track-buttons">
|
||||||
|
<div className={classes} data-control="mute" data-mixer-id={muteMixerId} onClick={this.handleMute}/>
|
||||||
|
<div className="track-icon-pan" style={panStyle}/>
|
||||||
|
</div>
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<br className="clearall"/>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
componentDidMount: () ->
|
||||||
|
|
||||||
|
context.jamClient.SessionSetUserName(this.props.clientId, this.props.name)
|
||||||
|
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$mute,
|
||||||
|
'SessionTrackVolumeHover',
|
||||||
|
() =>
|
||||||
|
{mixers:this.props.mixers}
|
||||||
|
,
|
||||||
|
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
context.JK.interactReactBubble(
|
||||||
|
$pan,
|
||||||
|
'SessionTrackPanHover',
|
||||||
|
() =>
|
||||||
|
{mixers:this.props.mixers}
|
||||||
|
,
|
||||||
|
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
|
||||||
|
|
||||||
|
componentWillUpdate: (nextProps, nextState) ->
|
||||||
|
$root = $(this.getDOMNode())
|
||||||
|
$mute = $root.find('.track-icon-mute')
|
||||||
|
$pan = $root.find('.track-icon-pan')
|
||||||
|
|
||||||
|
# disable hover effects if there is no mixer
|
||||||
|
if nextProps.mixers.mixer?
|
||||||
|
$mute.off("click", false)
|
||||||
|
$pan.off("click", false)
|
||||||
|
else
|
||||||
|
$mute.on("click", false)
|
||||||
|
$pan.on("click", false)
|
||||||
|
})
|
||||||