Compare commits

...

149 Commits

Author SHA1 Message Date
Nuwan 5bbbf95107 starting off session broadcast feature with the files needed are been added 2023-09-27 20:51:53 +05:30
Nuwan 8ef9530129 guard session recording 2023-09-22 16:18:02 +05:30
Nuwan 40282a82f3 debug jamtrack volume 2023-09-21 17:16:08 +05:30
Nuwan 25d651f450 add more volume data to SessionSetTrackVolumeData
id, _id and groupID added to the third parameter of this API call
2023-09-19 11:56:39 +05:30
Nuwan f835894620 add more context details to SessionSetTrackVolumeData
add  mediaType, isJamTrack, and isMetronome to trackVolumeObject parameter
of SessionSetTrackVolumeData api
2023-09-13 18:29:35 +05:30
Nuwan bf1291abf4 removing unused bits 2023-09-07 20:03:34 +05:30
Nuwan 55d3202c11 Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2023-09-05 19:22:16 +05:30
Nuwan 61b58eddd1 prevent showing alert on audio instrument select
fix this bug due to previous introduction of alert which pops up
if midi instrument is selected without selecting midi interface and
vst plugin. The alert only applicable to the midi interface.
2023-09-05 19:19:16 +05:30
Seth Call fc9d69f5f9 Update to pass product from client back to ArtifactUpdate 2023-09-02 15:23:22 -05:00
Seth Call 21733110f4 skip all client updatse 2023-09-02 14:53:19 -05:00
Seth Call f9c3c33d6b Beta download page 2023-09-01 16:33:09 -05:00
Nuwan ccee1c6805 cleanup debug entries 2023-09-01 16:54:01 +05:30
Nuwan f92ae4dd8d debugging 2023-09-01 15:57:35 +05:30
Nuwan 9e2adc9ce0 fix artifact version upgrade 2023-09-01 13:51:16 +05:30
Nuwan c8be3b847f debug JamServer 2023-09-01 13:33:09 +05:30
Nuwan 6d2ef50a8d debug version upgrade 2023-09-01 10:20:46 +05:30
Nuwan 63ebf8259c changes related to client upgrade fixes 2023-09-01 00:45:44 +05:30
Nuwan ea5e32e14b fix recording window handling on conneted clients to the session 2023-08-31 22:22:30 +05:30
Nuwan 7936d8ac59 debug 2023-08-31 09:47:46 +05:30
Nuwan fff48bf399 client update debug logs 2023-08-31 09:36:25 +05:30
Nuwan d0966fe67a debug backing track on peer 2023-08-28 18:14:45 +05:30
Nuwan 4f1fd4880e fix inconsistency of volume gauge
this fixes the unpredictable behavior of volume level when changing the
volume gauge leveler.
2023-08-22 23:09:44 +05:30
Nuwan e3cb68dda8 Show instructions in midi track configuration popup 2023-08-21 16:45:12 +05:30
Nuwan d8d04dd33f Allow multiple recordings within session
change in recording flow. Now after stopping the recording we no longer ask
user to save or discard the recording, instead the app saves the recording to user's
computer and opens the file explorer to that folder.
therefore following scenario is no longer valid; hence skipping it.
2023-08-19 11:03:29 +05:30
Nuwan 701620089a async/await fix 2023-08-11 03:24:11 +05:30
Nuwan 126e08a90d fix for version upgrade alert 2023-08-05 18:07:27 +05:30
Nuwan 48b2316728 debug version upgrade 2023-08-05 17:19:11 +05:30
Nuwan 03e12da98a audio MIDI config alert
show an alert when midi interface or midi plugin is not selected
2023-08-05 00:39:24 +05:30
Nuwan c7822a14d0 more cleaning console logs 2023-08-02 09:15:09 +05:30
Nuwan 758e688db1 remove debug entries and cleanup 2023-08-02 08:57:59 +05:30
Nuwan 5e7d512a5e fix for midi instrument selection 2023-08-02 08:32:11 +05:30
Nuwan 6d4b775321 debugging 2023-07-28 15:52:36 +05:30
Nuwan 2f866e92a7 debugging 2023-07-28 15:19:59 +05:30
Nuwan fd929ab0dc remove debug lines 2023-07-28 12:29:59 +05:30
Nuwan 4fbe7fb8a3 debug websocket gateway handle login 2023-07-28 07:59:03 +05:30
Nuwan 7390355b3c provide detailed os name in jamserver to be consumed by websocket gateway router 2023-07-28 07:53:51 +05:30
Nuwan 9329e5d235 debug logs 2023-07-22 09:50:15 +05:30
Nuwan 5ca37d63c1 debug versioncheck api 2023-07-22 04:32:55 +05:30
Nuwan 20331c6d60 fix for version upgrade 2023-07-22 03:59:49 +05:30
Nuwan 60009208c0 fix for audio input port assignment
this fix addresses the invalid input port assignment issue
due to asynchronous nature of asyncjamClient method calls
2023-07-21 18:32:40 +05:30
Nuwan 81b3fecfd4 fix for client version upgrade 2023-07-20 04:11:44 +05:30
Nuwan e03389909e fix showing error alert on audio resync 2023-07-20 03:31:37 +05:30
Nuwan 483eb20c88 ArtifactsUpdate MacOSX-M 2023-07-12 10:39:57 +05:30
Nuwan e764047935 change in userAgent check to determine client type 2023-07-11 22:30:48 +05:30
Nuwan 287fad8443 Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2023-07-07 18:54:10 +05:30
Nuwan eba15f255e remove alert on session recording stop 2023-07-07 18:53:19 +05:30
Nuwan 42ee0bcf26 WIP fixing midi configuration 2023-07-07 18:53:19 +05:30
Nuwan 5932cc3d67 WIP midi and audio channel config 2023-07-07 18:53:19 +05:30
Nuwan b6868a4fbb Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2023-07-07 17:50:45 +05:30
Nuwan f1008baea8 remove alert on session recording stop 2023-07-07 17:50:12 +05:30
Nuwan 8e0e43359c WIP fixing midi configuration 2023-07-07 17:49:55 +05:30
Nuwan bc71730df4 remove alert on session recording stop 2023-07-06 10:05:21 +05:30
Nuwan 69addda196 fix Server Disconnect
add FakeJamClientProxy to wrap FakeJamClient. It accepts API calls and
sends back javascript promises.
2023-07-06 09:00:49 +05:30
Nuwan 917d8f1a8e WIP midi and audio channel config 2023-07-04 12:56:18 +05:30
Nuwan dd4f62cb07 fix js error 2023-06-14 16:55:13 +05:30
Nuwan 5d09d23809 suppress the preview recording window 2023-06-14 16:22:56 +05:30
Nuwan 01fda6b6f0 fix onSessionEnter 2023-06-02 06:48:56 +05:30
Nuwan d09baf05bb prevent session joining using web browser 2023-05-29 19:04:46 +05:30
Nuwan 03bb0f99fa fix start/stop recording dialog for session with video 2023-05-20 17:50:32 +05:30
Nuwan f4aebb44e2 fix start/stop recording dialog for session with video 2023-05-20 17:36:43 +05:30
Nuwan 7c306a13df remove debug message 2023-04-18 04:52:36 +05:30
Nuwan 6498485548 in session recording dialog box remove the video opts
with the newly invented webRTC based video recording system we can drop this options.
Only enable the video recording radio button if the backend has sent the relevant event.
2023-04-18 04:42:40 +05:30
Nuwan 0beb922db5 disable video gear setup link 2023-04-07 11:58:49 +05:30
Nuwan b8d8ca73fa sort user friend list in alphabetical order 2023-04-06 12:06:25 +05:30
Nuwan 8d816d69ed fix array iteration key/value in gear_util getChatInputs 2023-04-03 23:35:26 +05:30
Nuwan bb1c15205c fix GetDetailedOS 2023-03-18 20:09:09 +05:30
Nuwan 599e650d57 side bar search fixing
1) change the search results limit to 40
2) fix band search sql
2023-03-17 10:15:34 +05:30
Nuwan 76c56612cf fix showing build upgrade message on app startup 2023-03-16 12:26:29 +05:30
Nuwan 8d2e9d6663 fix async handler in updateSingleRecording 2023-03-14 20:26:45 +05:30
Nuwan 51f5f5ecf0 fix recording manager - not showing data 2023-03-14 13:38:55 +05:30
Nuwan dd0e24fa19 disable legacy video system 2023-02-24 23:23:10 +05:30
Nuwan aa3ac642da this includes fix for Resync button doesn't do anything 2023-02-24 17:23:19 +05:30
Nuwan 359ccfe431 fix async call order in configure audio
This error was appearing in audio gear configuration when clicking Next button in
select & test audio gear step. on this button click the program executed
an event listener on input channel check box click (programmatically) and
autoAssignToSingleInput inside the click event handler was invoked
an async call stack which was resolved before the next button click handler completed.
As a result a pop up was showing up saying "The application is no longer modifying a new profile".

This commits fixes this issue by explicitly preventing this event lister handler been executed
in this case.
2023-02-23 19:12:16 +05:30
Nuwan 4cef5acde8 new boolean parameter for TrackDeleteProfile to delete it from the Audio.ini file 2023-02-22 12:36:56 +05:30
Nuwan 172f3a654d new boolean parameter for TrackDeleteProfile to delete it from the Audio.ini file 2023-02-22 12:24:11 +05:30
Nuwan 972f9fadcc new boolean parameter for TrackDeleteProfile to delete it from the Audio.ini file 2023-02-22 11:28:37 +05:30
Nuwan 1fb6907df0 using Jquery .attr() for accessing data attributes. using .prop() here is erronious here 2023-02-22 00:16:42 +05:30
Nuwan 27d697149c fix js error when selecting framesize or sample rate settings in configure audio 2023-02-21 19:24:13 +05:30
Nuwan 60af5432ce fix frontend error when changing framesize in audio input/output configuration 2023-02-17 16:37:56 +05:30
Nuwan 19050d317b Fix configure voice chat
add missing async/await call to fetch chat inputs
2023-02-16 18:21:11 +05:30
Nuwan 80bf8119af show logs in asyncJamClient 2023-02-06 00:28:53 +05:30
Nuwan 3d26f241b4 turn off log messages in asyncJamClient 2023-02-04 03:48:19 +05:30
Nuwan b7f9ade2ea handle sendP2PMessage in asyncJamClient 2023-02-04 03:35:07 +05:30
Nuwan 4423a9c122 more async fixes related to audio interface configuration 2023-02-01 15:34:15 +05:30
Nuwan 6c56fe3af8 async calls in configure audio
adds async/await call for jamClient api calls
2023-01-31 17:58:16 +05:30
Nuwan 009ee6a6dd add GetDetailedOS in to async call array 2023-01-26 01:11:21 +05:30
Nuwan 20177f71dd Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2023-01-26 00:48:27 +05:30
Seth Call 37533c9e18 Fix odd bug in jam_track_right for current_user, and send https redirectfor download link for jamtrack 2023-01-16 13:08:40 -05:00
Nuwan 2228b91285 Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2023-01-13 11:12:09 +05:30
Seth Call dccc668d48 Fix special branch casing 2023-01-04 17:57:27 -06:00
Seth Call 16c5dbb218 Fix special branch casing 2023-01-04 17:20:21 -06:00
Nuwan 46f2fbb55f Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2023-01-04 21:42:42 +05:30
Seth Call b3d4259b09 Try removing gemfile.lock 2023-01-04 08:44:02 -06:00
Seth Call d59b83bb42 wip 2023-01-04 08:43:13 -06:00
Seth Call 7dc640fb86 debugging build 2023-01-04 08:26:39 -06:00
Seth Call cbf348564d Try to fix build 2023-01-03 14:38:20 -06:00
Seth Call e9612cbc19 special case debians for this branch 2023-01-03 08:43:48 -06:00
Nuwan 5145bfeac1 add .ruby-version to .gitignore 2022-12-23 08:18:00 +05:30
Nuwan 3349c76076 Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2022-12-16 13:51:08 +05:30
Murali Gowrisankaran bb9813ae26 Removed enumeration for open and close Url APIs 2022-12-16 02:37:30 +00:00
Nuwan bd1134b2bd Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2022-12-13 12:09:37 +05:30
Murali Gowrisankaran cc4d1575c0 Added enumerated constants for window popup APIs 2022-12-13 06:07:29 +00:00
Nuwan 033d67639c fix js error 2022-12-07 19:44:45 +05:30
Nuwan d9b4a5b8d9 fix async call issue in bands search window 2022-12-03 02:21:47 +05:30
Nuwan 87762c5933 add bugsnag error reporting to asyncJamClient 2022-11-05 04:36:05 +05:30
Nuwan 9d787351fa fixes for recording related errors 2022-11-04 18:57:09 +05:30
Nuwan f392623049 wip session recording related fixes 2022-11-03 18:54:03 +05:30
Nuwan c207b76641 debug and fixing session recording wip 2022-11-02 04:15:22 +05:30
Nuwan 2c5708b28a fix syntax error - invalid comment 2022-10-29 00:04:50 +05:30
Nuwan 2370762c51 alperbatically order JKFrontendMethods method names in asyncJamClient 2022-10-28 22:18:29 +05:30
Nuwan 3be0e25bcb add jamClient.SessionSetTrackVolumeData
this new api method is used to send session track data
over web channel to qt c++ backend
2022-10-28 22:06:34 +05:30
Nuwan 768f3d976a convert anoter few jamClient. call to async format 2022-10-28 13:12:14 +05:30
Nuwan 5487e62f5a fixes for public session creation and joining 2022-10-12 19:39:09 +05:30
Nuwan 38baea686f fixes for the errors - public session
fix errors when creating group session
and when joining group session
2022-10-07 04:16:40 +05:30
Seth Call 8c472a90a8 Fix jamtracks for local dev 2022-09-12 17:04:48 -05:00
Nuwan 73a56b2cf6 fix session metronome related functions 2022-09-07 08:49:21 +05:30
Nuwan 6486761483 Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2022-09-02 11:11:11 +05:30
Nuwan 7a7986e30a fixing audio config and session related issues 2022-09-02 11:10:51 +05:30
Seth Call 1f63aa77b4 Pass in client_id to backend websocket connection 2022-09-01 16:44:16 -05:00
Seth Call cbbfebddc9 make onMixersChanged async so that it can await internally 2022-08-17 21:57:54 -05:00
Nuwan 794d131a3e change context._.each( loops to classic for loops 2022-08-15 22:30:58 +05:30
Seth Call 98aa2adc42 Remove 2 context._.each statements combined with async 2022-08-14 17:00:38 -05:00
Nuwan 21af8446ca async call fixes for audio gear setup 2022-08-13 00:33:24 +05:30
Nuwan 8e7b9b278a fix session leave issues 2022-08-08 16:31:00 +05:30
Nuwan 1c1626df73 fix not showing Account screen content 2022-08-03 21:13:51 +05:30
Nuwan 07a00505b8 fix listing audio profiles 2022-08-03 19:08:32 +05:30
Nuwan 09e1d27c64 fix async realted errors and cleanup 2022-08-03 18:38:42 +05:30
Nuwan 11915454cb replacing context.jamClient.isNativeClient() with context.JK.isQWebEngine 2022-08-02 18:51:05 +05:30
Nuwan 8cc3a6753b Merge remote-tracking branch 'origin/promised_based_api_interation' into promised_based_api_interation 2022-08-02 13:56:23 +05:30
Nuwan c4a37daa73 adding async/await for fixing issues related to promised based pi calls 2022-08-02 09:43:01 +05:30
Seth Call 08b2de242e Create context.JK.isQWebEngine property instead of gon.isQWebEngine 2022-08-01 21:49:33 -05:00
Seth Call e19819e035 Fix step 2 of the FTUE Gear Wizard by setting some async's where needed.
Also added in gon.isQWebEngine to act as flag indicating this is the native client.
2022-08-01 21:37:35 -05:00
Nuwan b32621fe42 Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2022-07-30 08:28:34 +05:30
Nuwan 795ab8bd13 fixing errors related to gear wizard 2022-07-30 08:27:59 +05:30
Murali Gowrisankaran 2adf33e689 Removed/commented out video related frontend API calls 2022-07-28 01:12:30 +00:00
Nuwan c3bcd3b470 fixing audio gear related async errors 2022-07-27 16:22:01 +05:30
Nuwan efbe685641 Merge branch 'promised_based_api_interation' of bitbucket.org:jamkazam/jam-cloud into promised_based_api_interation 2022-07-27 11:04:04 +05:30
Nuwan 9586e0547a fixing async errors 2022-07-27 11:03:20 +05:30
Murali Gowrisankaran ffddf28a25 Fixed enum for client ID 2022-07-27 01:31:14 +00:00
Murali Gowrisankaran 57fb3ea333 Revert "Fixed enum for client ID"
This reverts commit ad61bb00cb.
2022-07-27 01:26:43 +00:00
Murali Gowrisankaran ad61bb00cb Fixed enum for client ID 2022-07-27 01:24:47 +00:00
Nuwan f732e0dad6 fixing error due to async nature of api calls 2022-07-26 23:32:36 +05:30
Murali Gowrisankaran 21ce5c237d Added method for getClientID 2022-07-12 21:27:50 +00:00
Nuwan 4b281538b2 fix errors getting after async changes
this includes errors in websocket-gateway due to blank data been
passed from web frontend to websocket routes
2022-06-16 00:02:54 +05:30
Nuwan 69cc22106d fix js error in gear_utls after changing jamClient calls to async 2022-06-02 18:00:03 +05:30
Nuwan 99d20a9869 handle the response returned from ws server for unavailable methods 2022-04-20 16:36:23 +05:30
Nuwan 43caffb85e work continues on changing jamClient calls to asynchronous 2022-04-18 19:08:02 +05:30
Nuwan cd93211406 wip promised based jamClient 2022-04-13 03:02:44 +05:30
Nuwan f05287f45a convert jamClient.* calls as promises using async/await 2022-04-07 22:31:35 +05:30
160 changed files with 10725 additions and 4371 deletions

2
.gitignore vendored
View File

@ -11,3 +11,5 @@ working.png
ruby/.rails5-gems
web/.rails5-gems
websocket-gateway/.rails5-gems
.pg_data/
.ruby-version

2
build
View File

@ -61,7 +61,7 @@ if [ ! -z "$PACKAGE" ]; then
GEM_SERVER=http://localhost:9000/gems
# 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* || "$GIT_BRANCH" == *promised_based_api_interation* ]]; then
echo ""
echo "PUSHING WEB"

View File

@ -13,4 +13,4 @@ RUBY VERSION
ruby 2.4.1p111
BUNDLED WITH
1.17.3
2.3.17

View File

@ -8,6 +8,8 @@ RUBY_OUT=$TARGET/ruby
command -v "bundle" || { echo >&2 "bundle is required but not installed. Skipping ruby protocol buffers."; exit 0; }
# creates a bin folder with 'rprotoc' command inside
#echo "skipping creation of binstubs as it breaks bin/ruby-protoc invocation below"
rm Gemfile.lock
bundle install --binstubs
# die on error at this point

View File

@ -1875,9 +1875,9 @@ module JamRuby
mp3_48000 = File.join(tmp_dir, File.basename(basename, ".wav") + "-48000.mp3")
aac_48000 = File.join(tmp_dir, File.basename(basename, ".wav") + "-48000.aac")
`ffmpeg -i "#{wav_file}" -ar 48000 -ab 192k "#{mp3_48000}"`
`#{APP_CONFIG.ffmpeg_path} -i "#{wav_file}" -ar 48000 -ab 192k "#{mp3_48000}"`
`ffmpeg -i "#{wav_file}" -c:a libfdk_aac -b:a 192k "#{aac_48000}"`
`#{APP_CONFIG.ffmpeg_path} -i "#{wav_file}" -c:a libfdk_aac -b:a 192k "#{aac_48000}"`
# upload the new ogg files to s3
@@log.debug("uploading mp3 48000 to #{mp3_48000_s3_path}")
@ -1971,9 +1971,9 @@ module JamRuby
mp3_48000 = File.join(tmp_dir, File.basename(basename, ".wav") + "-48000.mp3")
aac_48000 = File.join(tmp_dir, File.basename(basename, ".wav") + "-48000.aac")
`ffmpeg -i "#{wav_file}" -ar 48000 -ab 192k "#{mp3_48000}"`
`#{APP_CONFIG.ffmpeg_path} -i "#{wav_file}" -ar 48000 -ab 192k "#{mp3_48000}"`
`ffmpeg -i "#{wav_file}" -c:a libfdk_aac -b:a 192k "#{aac_48000}"`
`#{APP_CONFIG.ffmpeg_path} -i "#{wav_file}" -c:a libfdk_aac -b:a 192k "#{aac_48000}"`
# upload the new ogg files to s3
@@log.debug("uploading mp3 48000 to #{mp3_48000_s3_path}")
@ -2710,7 +2710,7 @@ module JamRuby
click_wav = File.join(tmp_dir, 'Click.wav')
song_storage_manager.download(base_dir + '/Click.mp3', click_mp3)
`ffmpeg -i "#{click_mp3}" "#{click_wav}"`
`#{APP_CONFIG.ffmpeg_path} -i "#{click_mp3}" "#{click_wav}"`
song_storage_manager.upload(base_dir + '/Click.wav', click_wav)
importer.finish("success", nil)
@ -3136,6 +3136,10 @@ module JamRuby
count = 0
iterate_song_storage do |metadata, metalocation|
if metadata[:original_artist] != "AC DC"
@@log.info("skipping #{metadata[:original_artist]}")
next
end
next if metadata.nil? && (is_tency_storage? || is_paris_storage?)
importer = synchronize_from_meta(metalocation, options)

View File

@ -56,7 +56,7 @@ module JamRuby
part = jam_track_track.track_type == 'Click' ? 'ClickTrack' : jam_track_track.part
jam_file_opts << " -i #{Shellwords.escape("#{track_filename}+#{part}")}"
end
#puts "LS + " + `ls -la '#{tmp_dir}'`
# puts "LS + " + `ls -la '#{tmp_dir}'`
sku=jam_track.id
title=jam_track.name
@ -68,7 +68,7 @@ module JamRuby
step = bump_step(jam_track_right, step)
# From http://stackoverflow.com/questions/690151/getting-output-of-system-calls-in-ruby/5970819#5970819:
cli = "python #{py_file} -D -k #{sku} -p #{Shellwords.escape(tmp_dir)}/pkey.pem -s #{Shellwords.escape(tmp_dir)}/skey.pem #{jam_file_opts} -o #{Shellwords.escape(output_jkz)} -t #{Shellwords.escape(title)} -V #{Shellwords.escape(version)}"
cli = "python2 #{py_file} -D -k #{sku} -p #{Shellwords.escape(tmp_dir)}/pkey.pem -s #{Shellwords.escape(tmp_dir)}/skey.pem #{jam_file_opts} -o #{Shellwords.escape(output_jkz)} -t #{Shellwords.escape(title)} -V #{Shellwords.escape(version)}"
Open3.popen3(cli) do |stdin, stdout, stderr, wait_thr|
pid = wait_thr.pid
exit_status = wait_thr.value

View File

@ -34,7 +34,7 @@ module JamRuby
@@log.info "Executing python source in #{py_file}, outputting to #{output_json})"
# From http://stackoverflow.com/questions/690151/getting-output-of-system-calls-in-ruby/5970819#5970819:
cli = "python #{py_file} -i '#{input_text}' -o '#{output_json}'"
cli = "python2 #{py_file} -i '#{input_text}' -o '#{output_json}'"
Open3.popen3(cli) do |stdin, stdout, stderr, wait_thr|
pid = wait_thr.pid
exit_status = wait_thr.value

View File

@ -11,4 +11,4 @@ module JamRuby
Ars.where(active: true, beta: beta).where('ip is not NULL').where("ip != ''").all
end
end
end
end

View File

@ -3,8 +3,17 @@ module JamRuby
DEFAULT_ENVIRONMENT = 'public'
CLIENT_PREFIX = 'JamClient'
CLIENT_PREFIX_MODERN = 'JamClientModern'
PRODUCTS = ["#{CLIENT_PREFIX}/Win32", "#{CLIENT_PREFIX}/MacOSX", "#{CLIENT_PREFIX}/JamBlaster", "#{CLIENT_PREFIX}/JamBlasterClient"]
PRODUCTS = [
"#{CLIENT_PREFIX}/Win32",
"#{CLIENT_PREFIX}/MacOSX",
"#{CLIENT_PREFIX}/JamBlaster",
"#{CLIENT_PREFIX}/JamBlasterClient",
"#{CLIENT_PREFIX_MODERN}/Win32",
"#{CLIENT_PREFIX_MODERN}/MacOSX-Intel",
"#{CLIENT_PREFIX_MODERN}/MacOSX-M"
]
self.primary_key = 'id'
attr_accessible :version, :uri, :sha1, :environment, :product, as: :admin
@ -34,8 +43,8 @@ module JamRuby
Notification.send_client_update(product, version, determine_url, size)
end
def self.find_client_by_os(os, environment=DEFAULT_ENVIRONMENT)
ArtifactUpdate.find_by_product_and_environment("#{CLIENT_PREFIX}/#{os}", environment)
def self.find_client_by_os(product, os, environment=DEFAULT_ENVIRONMENT)
ArtifactUpdate.find_by_product_and_environment("#{product}/#{os}", environment)
end
def determine_url

View File

@ -60,7 +60,7 @@ module JamRuby
end
def verify_download_count
if (self.download_count < 0 || self.download_count > MAX_JAM_TRACK_DOWNLOADS) && !@current_user.admin
if (self.download_count < 0 || self.download_count > MAX_JAM_TRACK_DOWNLOADS) && !self.user.admin
errors.add(:download_count, "must be less than or equal to #{MAX_JAM_TRACK_DOWNLOADS}")
end
end

View File

@ -33,7 +33,7 @@ module JamRuby
dependent: :destroy
validate :not_already_recording, :on => :create
validate :not_still_finalizing_previous, :on => :create
#validate :not_still_finalizing_previous, :on => :create
validate :not_playback_recording, :on => :create
validate :already_stopped_recording
validate :only_one_mix

View File

@ -75,7 +75,7 @@ module JamRuby
rel = case params[SEARCH_TEXT_TYPE_ID].to_s
when 'bands'
@search_type = :bands
Band.where(nil)
Band.where(nil).joins(:users)
when 'fans'
@search_type = :fans
User.fans.not_deleted
@ -83,8 +83,13 @@ module JamRuby
@search_type = :musicians
User.musicians.not_deleted
end
@results = rel.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery).limit(10)
if @search_type == :bands
@results = rel.where("(bands.name_tsv @@ to_tsquery('jamenglish', ?))", tsquery)
else
@results = rel.where("(users.name_tsv @@ to_tsquery('jamenglish', ?))", tsquery)
end
@results = @results.limit(40)
@results = Search.scope_schools_together(@results, user)
end

View File

@ -533,7 +533,11 @@ describe Recording do
@user.first_recording_at.should_not be_nil
end
describe "chance for everyone to keep or discard" do
#NOTE: change in recording flow. Now after stopping the recording we no longer ask
#user to save or discard the recording, instead the app saves the recording to user's
#computer and opens the file explorer to that folder.
#therefore following scenario is no longer valid; hence skipping it.
xdescribe "chance for everyone to keep or discard" do
before(:each) do
@user2 = FactoryGirl.create(:user)
@connection2 = FactoryGirl.create(:connection, :user => @user2, :music_session => @music_session)

View File

@ -554,6 +554,8 @@ GEM
rabl (0.13.1)
activesupport (>= 2.3.14)
rack (1.6.13)
rack-cors (1.0.6)
rack (>= 1.6.0)
rack-oauth2 (1.12.0)
activesupport
attr_required
@ -873,6 +875,7 @@ DEPENDENCIES
puma
quiet_assets
rabl (= 0.13.1)
rack-cors (~> 1.0, >= 1.0.6)
rack-test
rails (= 4.2.8)
rails-assets-bluebird!

File diff suppressed because it is too large Load Diff

View File

@ -45,22 +45,24 @@
var invalidProfiles = prettyPrintAudioProfiles(context.JK.getBadConfigMap());
var sessionSummary = summarizeSession(userDetail);
if(gon.global.video_available && gon.global.video_available!="none" ) {
var webcamName;
var webcam = null;
if (context.jamClient.FTUECurrentSelectedVideoDevice) {
webcam = context.jamClient.FTUECurrentSelectedVideoDevice()
}
// if(gon.global.video_available && gon.global.video_available!="none" ) {
// var webcamName;
// var webcam = null;
// //if (context.jamClient.FTUECurrentSelectedVideoDevice) {
// webcam = await context.jamClient.FTUECurrentSelectedVideoDevice()
// //}
if (webcam == null || typeof(webcam) == "undefined" || Object.keys(webcam).length == 0) {
webcamName = "None Configured"
} else {
webcamName = _.values(webcam)[0]
}
}
else {
webcamName = 'video unavailable'
}
// if (webcam == null || typeof(webcam) == "undefined" || Object.keys(webcam).length == 0) {
// webcamName = "None Configured"
// } else {
// webcamName = _.values(webcam)[0]
// }
// }
// else {
// webcamName = 'video unavailable'
// }
var webcamName = 'video available in session';
var $template = $(context._.template($('#template-account-main').html(), {
email: userDetail.email,

View File

@ -56,29 +56,31 @@
$root.find('a[data-purpose=reload-audio]').addClass('disabled')
$root.find('.rescanning-notice').show();
},
function(canceled) {
async function(canceled) {
$root.find('a[data-purpose=reload-audio]').removeClass('disabled')
$root.find('.rescanning-notice').hide();
if(!canceled) {
var result = context.jamClient.ReloadAudioSystem(false, true, true);
var result = await context.jamClient.ReloadAudioSystem(false, true, true);
}
populateAccountAudio();
});
}
function onUsbDeviceConnected() {
async function onUsbDeviceConnected() {
if(showingGearWizard) { return; } // gear wizard also handles these events; unpredictable if both are rebuilding port audio
if(!context.jamClient.IsFrontendVisible()) {return;} // don't handle USB events when minimized
var isFrontendVisible = await context.jamClient.IsFrontendVisible();
if(!isFrontendVisible) {return;} // don't handle USB events when minimized
logger.debug("USB device connected");
scheduleRescanSystem(5000);
}
function onUsbDeviceDisconnected() {
async function onUsbDeviceDisconnected() {
if(showingGearWizard) { return; } // gear wizard also handles these events; unpredictable if both are rebuilding port audio
if(!context.jamClient.IsFrontendVisible()) {return;} // don't handle USB events when minimized
var isFrontendVisible = await context.jamClient.IsFrontendVisible();
if(!isFrontendVisible) {return;} // don't handle USB events when minimized
logger.debug("USB device disconnected");
@ -100,8 +102,8 @@
}
}
function populateAccountAudio() {
var profiles = gearUtils.getProfiles();
async function populateAccountAudio() {
var profiles = await gearUtils.getProfiles();
context._.each(profiles, function(profile) {
profile.active_text = profile.current ? '(active)' : '';
@ -111,14 +113,17 @@
// then you will have 'FTUE' (incomplete) profiles. This is the only time
var cleansedProfiles = [];
context._.each(profiles, function(profile) {
//context._.each(profiles, async function(profile) {
for (const profile of profiles) {
if(profile.id.indexOf('FTUE') == 0) {
context.jamClient.TrackDeleteProfile(profile.id);
await context.jamClient.TrackDeleteProfile(profile.id);
}
else {
cleansedProfiles.push(profile)
}
});
}
//});
var template = context._.template($('#template-account-audio').html(), {is_admin: context.JK.currentUserAdmin, profiles: cleansedProfiles}, {variable: 'data'});
@ -134,19 +139,18 @@
function resetForm() {
}
function handleDeleteAudioProfile(audioProfileId) {
logger.debug("deleting audio profile: " + audioProfileId);
context.jamClient.TrackDeleteProfile(audioProfileId);
async function handleDeleteAudioProfile(audioProfileId) {
console.log("deleting audio profile: " + audioProfileId);
await context.jamClient.TrackDeleteProfile(audioProfileId, true);
// redraw after deletion of profile
populateAccountAudio();
await populateAccountAudio();
}
function handleLoopbackAudioProfile(audioProfileId) {
async function handleLoopbackAudioProfile(audioProfileId) {
if(audioProfileId != context.jamClient.FTUEGetMusicProfileName()) {
var result = context.jamClient.FTUELoadAudioConfiguration(audioProfileId);
if(audioProfileId != await context.jamClient.FTUEGetMusicProfileName()) {
var result = await context.jamClient.FTUELoadAudioConfiguration(audioProfileId);
if(!result) {
logger.error("unable to activate audio configuration: " + audioProfileId);
@ -154,14 +158,14 @@
}
else {
// redraw after activation of profile
populateAccountAudio();
await populateAccountAudio();
}
}
app.layout.showDialog('loopback-wizard');
}
function handleConfigureAudioProfile(audioProfileId) {
async function handleConfigureAudioProfile(audioProfileId) {
if(!gearUtils.canBeConfigured(audioProfileId)) {
@ -170,9 +174,9 @@
}
if(audioProfileId == gearUtils.GearUtil)
if(audioProfileId != context.jamClient.FTUEGetMusicProfileName()) {
if(audioProfileId != await context.jamClient.FTUEGetMusicProfileName()) {
logger.debug("activating " + audioProfileId);
var result = context.jamClient.FTUELoadAudioConfiguration(audioProfileId);
var result = await context.jamClient.FTUELoadAudioConfiguration(audioProfileId);
if(!result) {
logger.error("unable to activate audio configuration: " + audioProfileId);
@ -181,7 +185,7 @@
}
// FTUELoadAudioConfiguration eventually sets this, but apparently asynchronously
result = context.jamClient.SetLastUsedProfileName(audioProfileId);
result = await context.jamClient.SetLastUsedProfileName(audioProfileId);
if(!result) {
logger.error("unable to activate audio configuration after loading it: " + audioProfileId);
@ -190,22 +194,25 @@
}
// redraw after activation of profile
populateAccountAudio();
await populateAccountAudio();
}
app.layout.showDialog('configure-tracks')
.one(EVENTS.DIALOG_CLOSED, populateAccountAudio)
.one(EVENTS.DIALOG_CLOSED, async function(){
await populateAccountAudio()
})
}
function handleActivateAudioProfile(audioProfileId) {
async function handleActivateAudioProfile(audioProfileId) {
logger.debug("activating audio profile: " + audioProfileId);
if(audioProfileId == context.jamClient.LastUsedProfileName()) {
if(audioProfileId == await context.jamClient.LastUsedProfileName()) {
context.JK.Banner.showAlert("This profile is already active.");
return;
}
var result = context.jamClient.SetLastUsedProfileName(audioProfileId);
var result = await context.jamClient.SetLastUsedProfileName(audioProfileId);
if(!result) {
logger.error("unable to activate audio configuration: " + audioProfileId);
@ -213,48 +220,52 @@
}
// redraw after activation of profile
populateAccountAudio();
await populateAccountAudio();
}
function handleStartAudioQualification() {
async function handleStartAudioQualification() {
app.afterFtue = function() {
app.afterFtue = async function() {
showingGearWizard = false;
if(populateAccountAudio().length == 1) {
if(await populateAccountAudio().length == 1) {
app.layout.showDialog('join-test-session');
}
};
app.cancelFtue = function() { showingGearWizard = false; populateAccountAudio() };
app.cancelFtue = async function() { showingGearWizard = false; await populateAccountAudio() };
showingGearWizard = true;
app.layout.startNewFtue()
}
function reloadAudio() {
async function reloadAudio() {
// false = don't start audio, true = reload last audio configuration, false = don't re-init tracks
context.jamClient.ReloadAudioSystem(false, true, false);
await context.jamClient.ReloadAudioSystem(false, true, false);
populateAccountAudio();
await populateAccountAudio();
}
function registerFtueSuccess() {
$('div[layout-id=ftue]').on("ftue_success", ftueSuccessHandler);
$('div[layout-id=ftue]').on("ftue_success", async function(){
await ftueSuccessHandler()
});
}
function unregisterFtueSuccess() {
$('div[layout-id=ftue]').off("ftue_success", ftueSuccessHandler);
$('div[layout-id=ftue]').off("ftue_success", async function(){
await ftueSuccessHandler();
});
}
function ftueSuccessHandler() {
populateAccountAudio();
async function ftueSuccessHandler() {
await populateAccountAudio();
}
// events for main screen
function events() {
// wire up main panel clicks
$root = $('#account-audio-content-scroller');
$root.on('click', 'a[data-purpose=delete-audio-profile]', function (evt) {
$root.on('click', 'a[data-purpose=delete-audio-profile]', async function (evt) {
evt.stopPropagation();
handleDeleteAudioProfile($(this).attr('data-id'));
await handleDeleteAudioProfile($(this).attr('data-id'));
return false;
});
@ -286,13 +297,13 @@
return false;
});
$root.on('click', 'a[data-purpose=configure-audio-profile]', function (evt) {
$root.on('click', 'a[data-purpose=configure-audio-profile]', async function (evt) {
evt.stopPropagation();
var $btn = $(this);
var status = $btn.closest('tr').attr('data-status');
if(status == "good") {
cancelRescan();
handleConfigureAudioProfile($btn.attr('data-id'));
await handleConfigureAudioProfile($btn.attr('data-id'));
}
else {
context.JK.Banner.showAlert("Unable to configure this profile. Please verify that the devices associated are connected.");
@ -301,10 +312,10 @@
});
$root.on('click', 'a[data-purpose=add-profile]', function (evt) {
$root.on('click', 'a[data-purpose=add-profile]', async function (evt) {
evt.stopPropagation();
cancelRescan();
handleStartAudioQualification();
await handleStartAudioQualification();
return false;
});

View File

@ -57,49 +57,101 @@ context.JK.AccountJamTracks = class AccountJamTracks
@createSession(jamRow.data(), false, jamRow.data('jamTrack'))
return false;
createSession:(sessionData, solo, jamTrack) =>
tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient)
# createSession:(sessionData, solo, jamTrack) =>
# tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient)
if (context.JK.guardAgainstBrowser(@app))
data = {}
data.client_id = @app.clientId
#data.description = $('#description').val()
data.description = "Jam Track Session"
data.as_musician = true
data.legal_terms = true
data.intellectual_property = true
data.approval_required = false
data.musician_access = !solo
data.fan_access = false
data.fan_chat = false
data.genre = $.map(sessionData.jamTrack.genres, (genre) -> genre.id)
data.genres = $.map(sessionData.jamTrack.genres, (genre)-> genre.id)
# data.genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre')
# data.musician_access = if $('#musician-access option:selected').val() == 'true' then true else false
# data.approval_required = if $('input[name=\'musician-access-option\']:checked').val() == 'true' then true else false
# data.fan_access = if $('#fan-access option:selected').val() == 'true' then true else false
# data.fan_chat = if $('input[name=\'fan-chat-option\']:checked').val() == 'true' then true else false
# if $('#band-list option:selected').val() != ''
# data.band = $('#band-list option:selected').val()
data.audio_latency = context.jamClient.FTUEGetExpectedLatency().latency
data.tracks = tracks
# if (context.JK.guardAgainstBrowser(@app))
# data = {}
# data.client_id = @app.clientId
# #data.description = $('#description').val()
# data.description = "Jam Track Session"
# data.as_musician = true
# data.legal_terms = true
# data.intellectual_property = true
# data.approval_required = false
# data.musician_access = !solo
# data.fan_access = false
# data.fan_chat = false
# data.genre = $.map(sessionData.jamTrack.genres, (genre) -> genre.id)
# data.genres = $.map(sessionData.jamTrack.genres, (genre)-> genre.id)
# # data.genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre')
# # data.musician_access = if $('#musician-access option:selected').val() == 'true' then true else false
# # data.approval_required = if $('input[name=\'musician-access-option\']:checked').val() == 'true' then true else false
# # data.fan_access = if $('#fan-access option:selected').val() == 'true' then true else false
# # data.fan_chat = if $('input[name=\'fan-chat-option\']:checked').val() == 'true' then true else false
# # if $('#band-list option:selected').val() != ''
# # data.band = $('#band-list option:selected').val()
# data.audio_latency = context.jamClient.FTUEGetExpectedLatency().latency
# data.tracks = tracks
rest.legacyCreateSession(data).done((response) =>
newSessionId = response.id
@sessionUtils.setAutoOpenJamTrack(jamTrack) # so that the session screen will pick this up
context.location = '/client#/session/' + newSessionId
# Re-loading the session settings will cause the form to reset with the right stuff in it.
# This is an extra xhr call, but it keeps things to a single codepath
#loadSessionSettings()
context.JK.GA.trackSessionCount data.musician_access, data.fan_access, 0
context.JK.GA.trackSessionMusicians context.JK.GA.SessionCreationTypes.create
).fail (jqXHR) =>
handled = false
if jqXHR.status = 422
response = JSON.parse(jqXHR.responseText)
if response['errors'] and response['errors']['tracks'] and response['errors']['tracks'][0] == 'Please select at least one track'
@app.notifyAlert 'No Inputs Configured', $('<span>You will need to reconfigure your audio device.</span>')
handled = true
if !handled
@app.notifyServerError jqXHR, 'Unable to Create Session'
# rest.legacyCreateSession(data).done((response) =>
# newSessionId = response.id
# @sessionUtils.setAutoOpenJamTrack(jamTrack) # so that the session screen will pick this up
# context.location = '/client#/session/' + newSessionId
# # Re-loading the session settings will cause the form to reset with the right stuff in it.
# # This is an extra xhr call, but it keeps things to a single codepath
# #loadSessionSettings()
# context.JK.GA.trackSessionCount data.musician_access, data.fan_access, 0
# context.JK.GA.trackSessionMusicians context.JK.GA.SessionCreationTypes.create
# ).fail (jqXHR) =>
# handled = false
# if jqXHR.status = 422
# response = JSON.parse(jqXHR.responseText)
# if response['errors'] and response['errors']['tracks'] and response['errors']['tracks'][0] == 'Please select at least one track'
# @app.notifyAlert 'No Inputs Configured', $('<span>You will need to reconfigure your audio device.</span>')
# handled = true
# if !handled
# @app.notifyServerError jqXHR, 'Unable to Create Session'
createSession: `async function(sessionData, solo, jamTrack){
const tracks = await context.JK.TrackHelpers.getUserTracks(context.jamClient);
if (context.JK.guardAgainstBrowser(this.app)) {
const data = {};
data.client_id = this.app.clientId;
//data.description = $('#description').val()
data.description = "Jam Track Session";
data.as_musician = true;
data.legal_terms = true;
data.intellectual_property = true;
data.approval_required = false;
data.musician_access = !solo;
data.fan_access = false;
data.fan_chat = false;
data.genre = $.map(sessionData.jamTrack.genres, genre => genre.id);
data.genres = $.map(sessionData.jamTrack.genres, genre => genre.id);
// data.genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre')
// data.musician_access = if $('#musician-access option:selected').val() == 'true' then true else false
// data.approval_required = if $('input[name=\'musician-access-option\']:checked').val() == 'true' then true else false
// data.fan_access = if $('#fan-access option:selected').val() == 'true' then true else false
// data.fan_chat = if $('input[name=\'fan-chat-option\']:checked').val() == 'true' then true else false
// if $('#band-list option:selected').val() != ''
// data.band = $('#band-list option:selected').val()
let expectedLatency = await context.jamClient.FTUEGetExpectedLatency()
data.audio_latency = expectedLatency.latency;
data.tracks = tracks;
return rest.legacyCreateSession(data).done(response => {
const newSessionId = response.id;
this.sessionUtils.setAutoOpenJamTrack(jamTrack); // so that the session screen will pick this up
context.location = '/client#/session/' + newSessionId;
// Re-loading the session settings will cause the form to reset with the right stuff in it.
// This is an extra xhr call, but it keeps things to a single codepath
//loadSessionSettings()
context.JK.GA.trackSessionCount(data.musician_access, data.fan_access, 0);
return context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.create);
}).fail(jqXHR => {
let handled = false;
if (jqXHR.status = 422) {
const response = JSON.parse(jqXHR.responseText);
if (response['errors'] && response['errors']['tracks'] && (response['errors']['tracks'][0] === 'Please select at least one track')) {
this.app.notifyAlert('No Inputs Configured', $('<span>You will need to reconfigure your audio device.</span>'));
handled = true;
}
}
if (!handled) {
return this.app.notifyServerError(jqXHR, 'Unable to Create Session');
}
});
}
}`

View File

@ -74,22 +74,22 @@
track2AudioInputChannels = _loadList(ASSIGNMENT.TRACK2, true, false);
}
function _loadList(assignment, input, chat) {
async function _loadList(assignment, input, chat) {
var list = [];
// get data needed for listboxes
var channels = context.jamClient.TrackGetChannels();
var channels = await context.jamClient.TrackGetChannels();
var musicDevices = context.jamClient.TrackGetMusicDeviceNames(input);
var musicDevices = await context.jamClient.TrackGetMusicDeviceNames(input);
// SEE loadList function in TrackAssignGui.cpp of client code
$.each(channels, function(index, val) {
$.each(channels, async function(index, val) {
if (input !== val.input) {
return;
}
var currAssignment = context.jamClient.TrackGetAssignment(val.id, val.input);
var currAssignment = await context.jamClient.TrackGetAssignment(val.id, val.input);
if (assignment !== currAssignment) {
return;
}
@ -97,9 +97,9 @@
logger.debug("channel id=" + val.id + ", channel input=" + val.input + ", channel assignment=" + currAssignment +
", channel name=" + val.name + ", channel type=" + val.device_type + ", chat=" + val.chat);
var os = context.jamClient.GetOSAsString();
var os = await context.jamClient.GetOSAsString();
if (os === context.JK.OS.WIN32) {
if (chat && ($.inArray(val.device_id, musicDevices) > -1 || context.jamClient.TrackIsMusicDeviceType(val.device_type))) {
if (chat && ($.inArray(val.device_id, musicDevices) > -1 || await context.jamClient.TrackIsMusicDeviceType(val.device_type))) {
return;
}
}
@ -137,13 +137,13 @@
app.layout.closeDialog('add-track');
}
function saveTrack() {
async function saveTrack() {
// TRACK 2 INPUTS
var trackId = null;
$("#add-track2-input > option").each(function() {
$("#add-track2-input > option").each(async function() {
logger.debug("Saving track 2 input = " + this.value);
trackId = this.value;
context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.TRACK2);
await context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.TRACK2);
});
// TRACK 2 INSTRUMENT
@ -151,13 +151,13 @@
var instrumentText = $('#add-track2-instrument > option:selected').text().toLowerCase();
logger.debug("Saving track 2 instrument = " + instrumentVal);
context.jamClient.TrackSetInstrument(ASSIGNMENT.TRACK2, instrumentVal);
await context.jamClient.TrackSetInstrument(ASSIGNMENT.TRACK2, instrumentVal);
// UPDATE SERVER
logger.debug("Adding track with instrument " + instrumentText);
var data = {};
context.jamClient.TrackSaveAssignments();
await context.jamClient.TrackSaveAssignments();
/**
setTimeout(function() {

View File

@ -74,4 +74,4 @@
//= require_directory ./wizard
//= require_directory ./wizard/gear
//= require_directory ./wizard/loopback
//= require everywhere/everywhere
//= require everywhere/everywhere

View File

@ -0,0 +1,673 @@
(function (context, $) {
"use strict";
context.JK = context.JK || {};
class Deferred {
constructor(request_id) {
var self = this;
this.request_id = request_id;
this.promise = new Promise(function (resolve, reject) {
self.reject = reject;
self.resolve = resolve;
});
}
}
context.JK.AsyncJamClient = function (app) {
const self = this;
const logger = context.JK.logger;
let deferredQueue = [];
let jkfrontendchannel = null;
let enumAppCounter = 1000;
let request_id = 1;
const JKFrontendMethods = Object.freeze({
UnknownJKAppMessage: enumAppCounter++,
AbortRecording: enumAppCounter++,
addUserBackingTracksToJamkazamAsset: enumAppCounter++,
applySubscriptionPolicy: enumAppCounter++,
BringVideoWindowToFront: enumAppCounter++,
browseForUserBackingTracksCandidate: enumAppCounter++,
cancelVideoUpload: enumAppCounter++,
clientID: enumAppCounter++,
ClientJoinedSession: enumAppCounter++,
ClientLeftSession: enumAppCounter++,
ClientUpdateStartDownload: enumAppCounter++,
ClientUpdateStartUpdate: enumAppCounter++,
ClientUpdateVersion: enumAppCounter++,
ClosePreviewRecording: enumAppCounter++,
CloseRecording: enumAppCounter++,
deleteVideo: enumAppCounter++,
DownloadFileStatus: enumAppCounter++,
endPairing: enumAppCounter++,
FTUEAudioResync: enumAppCounter++,
FTUECancel: enumAppCounter++,
FTUEChatFrameSize: enumAppCounter++,
FTUEClearChannelAssignments: enumAppCounter++,
FTUEClearChatInput: enumAppCounter++,
FTUECreateUpdatePlayBackProfile: enumAppCounter++,
FTUECurrentSelectedVideoDevice: enumAppCounter++,
FTUEGetAllAudioConfigurations: enumAppCounter++,
FTUEGetAllConfigurationList: enumAppCounter++,
FTUEGetAudioConfigurationsMissingDevice: enumAppCounter++,
FTUEGetAudioDevices: enumAppCounter++,
FTUEGetAutoSelectVideoLayout: enumAppCounter++,
FTUEGetAvailableEncodeVideoResolutions: enumAppCounter++,
FTUEGetAvailableVideoLayoutGroupStyles: enumAppCounter++,
FTUEGetBadConfigurationMissingDev: enumAppCounter++,
FTUEGetCaptureResolution: enumAppCounter++,
FTUEGetChannels: enumAppCounter++,
FTUEGetChatInputs: enumAppCounter++,
FTUEGetChatInputVolume: enumAppCounter++,
FTUEGetChatLatency: enumAppCounter++,
FTUEGetConfigurationDevice: enumAppCounter++,
FTUEGetConfigurationDevs: enumAppCounter++,
FTUEGetCurrentCaptureResolution: enumAppCounter++,
FTUEGetCurrentVideoCaptureDeviceCapability: enumAppCounter++,
FTUEGetDefaultAudioConfigurations: enumAppCounter++,
FTUEGetDevices: enumAppCounter++,
FTUEGetExpectedLatency: enumAppCounter++,
FTUEGetFrameSize: enumAppCounter++,
FTUEGetGoodAudioConfigurations: enumAppCounter++,
FTUEGetGoodConfigurationList: enumAppCounter++,
FTUEgetInputDeviceSampleRate: enumAppCounter++,
FTUEGetInputLatency: enumAppCounter++,
FTUEGetInputMusicDevice: enumAppCounter++,
FTUEGetInputVolume: enumAppCounter++,
FTUEGetIoPerfData: enumAppCounter++,
FTUEGetMapUserCntPreferredVideoLayoutGroupStyle: enumAppCounter++,
FTUEGetMusicInputs: enumAppCounter++,
FTUEGetMusicOutputs: enumAppCounter++,
FTUEGetMusicProfileName: enumAppCounter++,
FTUEgetOutputDeviceSampleRate: enumAppCounter++,
FTUEGetOutputLatency: enumAppCounter++,
FTUEGetOutputMusicDevice: enumAppCounter++,
FTUEGetOutputVolume: enumAppCounter++,
FTUEGetPreferredChatSampleRate: enumAppCounter++,
FTUEGetPreferredMixerSampleRate: enumAppCounter++,
FTUEGetPreferredOutputSampleRate: enumAppCounter++,
FTUEGetSendFrameRates: enumAppCounter++,
FTUEGetStatus: enumAppCounter++,
FTUEGetUserCountPreferredVideoLayoutGroupStyle: enumAppCounter++,
FTUEGetVideoCaptureDeviceCapabilities: enumAppCounter++,
FTUEGetVideoCaptureDeviceNames: enumAppCounter++,
FTUEGetVideoShareEnable: enumAppCounter++,
FTUEGetVolumeRanges: enumAppCounter++,
FTUEHasControlPanel: enumAppCounter++,
FTUEInit: enumAppCounter++,
FTUEIsMusicDeviceWDM: enumAppCounter++,
FTUELoadAudioConfiguration: enumAppCounter++,
FTUEOpenControlPanel: enumAppCounter++,
FTUEPageEnter: enumAppCounter++,
FTUEPageLeave: enumAppCounter++,
FTUERefreshDevices: enumAppCounter++,
FTUERegisterLatencyCallback: enumAppCounter++,
FTUERegisterVUCallbacks: enumAppCounter++,
FTUESave: enumAppCounter++,
FTUESelectVideoCaptureDevice: enumAppCounter++,
FTUESetAutoSelectVideoLayout: enumAppCounter++,
FTUESetCaptureResolution: enumAppCounter++,
FTUESetChatInput: enumAppCounter++,
FTUESetChatInputVolume: enumAppCounter++,
FTUESetChatLatency: enumAppCounter++,
FTUESetFrameSize: enumAppCounter++,
FTUESetInputLatency: enumAppCounter++,
FTUESetInputMusicDevice: enumAppCounter++,
FTUESetInputVolume: enumAppCounter++,
FTUESetLatencySamples: enumAppCounter++,
FTUESetMusicDevice: enumAppCounter++,
FTUESetMusicInput: enumAppCounter++,
FTUESetMusicInput2: enumAppCounter++,
FTUESetMusicOutput: enumAppCounter++,
FTUESetMusicProfileName: enumAppCounter++,
FTUESetOutputLatency: enumAppCounter++,
FTUESetOutputMusicDevice: enumAppCounter++,
FTUESetOutputVolume: enumAppCounter++,
FTUESetPreferredChatSampleRate: enumAppCounter++,
FTUESetPreferredMixerSampleRate: enumAppCounter++,
FTUESetPreferredOutputSampleRate: enumAppCounter++,
FTUESetPreferredVideoLayoutGroupStyle: enumAppCounter++,
FTUESetSendFrameRates: enumAppCounter++,
FTUESetStatus: enumAppCounter++,
FTUESetUserCountPreferredVideoLayoutGroupStyle: enumAppCounter++,
FTUESetVideoEncodeResolution: enumAppCounter++,
FTUESetVideoShareEnable: enumAppCounter++,
FTUEStartIoPerfTest: enumAppCounter++,
FTUEStartLatency: enumAppCounter++,
FTUEUnsetMusicInput2: enumAppCounter++,
get48vAndLineInstState: enumAppCounter++,
getABLoopState: enumAppCounter++,
getAllClientsStateMap: enumAppCounter++,
getAllClientsStateStr: enumAppCounter++,
GetASIODevices: enumAppCounter++,
GetAutoStart: enumAppCounter++,
getAvailableMetronomeClickNames: enumAppCounter++,
getBackingTrackList: enumAppCounter++,
getClientParentChildRole: enumAppCounter++,
getConnectionDetail: enumAppCounter++,
GetCurrentVideoFrameRate: enumAppCounter++,
GetCurrentVideoResolution: enumAppCounter++,
GetDetailedOS: enumAppCounter++,
GetFTUE: enumAppCounter++,
GetJamTrackSettings: enumAppCounter++,
GetJamTrackTimeline: enumAppCounter++,
getJBAutoPair: enumAppCounter++,
getJbNetworkState: enumAppCounter++,
getJbPortBindState: enumAppCounter++,
getJbPreampState: enumAppCounter++,
getJbStaticPortFlag: enumAppCounter++,
getJbStaticPortValue: enumAppCounter++,
getJbTrackState: enumAppCounter++,
getJbUsbState: enumAppCounter++,
GetLastLatencyTestTimes: enumAppCounter++,
getLatencyServerState: enumAppCounter++,
getLocalClients: enumAppCounter++,
GetLocalRecordingState: enumAppCounter++,
getLogLevel: enumAppCounter++,
getMetronomeCricketTestState: enumAppCounter++,
GetMixerIDs: enumAppCounter++,
GetMixerMode: enumAppCounter++,
GetMixerVolume: enumAppCounter++,
getMyChildren: enumAppCounter++,
getMyNetworkState: enumAppCounter++,
getMyParentState: enumAppCounter++,
GetNetworkTestScore: enumAppCounter++,
getOpenVideoSources: enumAppCounter++,
getOperatingMode: enumAppCounter++,
GetOS: enumAppCounter++,
GetOSAsString: enumAppCounter++,
getParentClientId: enumAppCounter++,
getPeerState: enumAppCounter++,
GetRecordingManagerState: enumAppCounter++,
GetSampleRate: enumAppCounter++,
GetScoreWorkTimingInterval: enumAppCounter++,
getSessionSetCompressorState: enumAppCounter++,
GetStaticPort: enumAppCounter++,
GetUseStaticPort: enumAppCounter++,
GetVideoNetworkTestScore: enumAppCounter++,
hasBonjour: enumAppCounter++,
hasVstAssignment: enumAppCounter++,
hasVstHost: enumAppCounter++,
hasWebrtc: enumAppCounter++,
InitiateScoringSession: enumAppCounter++,
InvalidateJamTrack: enumAppCounter++,
IsAppInWritableVolume: enumAppCounter++,
IsAudioStarted: enumAppCounter++,
IsFrontendVisible: enumAppCounter++,
isJamBlaster: enumAppCounter++,
isLatencyTestBlocked: enumAppCounter++,
IsMyNetworkWireless: enumAppCounter++,
IsNativeClient: enumAppCounter++,
IsSessionLiveBroadCastRunning: enumAppCounter++,
isSessionTrackPaused: enumAppCounter++,
isSessionTrackPlaying: enumAppCounter++,
isSessVideoRecording: enumAppCounter++,
isSessVideoShared: enumAppCounter++,
isSessYouTubeVideoBroadcasting: enumAppCounter++,
isVideoRecordingAllowed: enumAppCounter++,
isVideoWindowOpen: enumAppCounter++,
IsVstLoaded: enumAppCounter++,
isWebCamOpen: enumAppCounter++,
jamBlasterSerialNo: enumAppCounter++,
JamTrackDownload: enumAppCounter++,
JamTrackGetImage: enumAppCounter++,
JamTrackGetTrackDetail: enumAppCounter++,
JamTrackGetTracks: enumAppCounter++,
JamTrackIsPlayable: enumAppCounter++,
JamTrackIsPlaying: enumAppCounter++,
JamTrackKeysRequest: enumAppCounter++,
JamTrackLoadJmep: enumAppCounter++,
JamTrackPlay: enumAppCounter++,
JamTrackStopPlay: enumAppCounter++,
JoinSession: enumAppCounter++,
LastUsedProfileName: enumAppCounter++,
LeaveSession: enumAppCounter++,
LeaveSessionAndMinimize: enumAppCounter++,
log: enumAppCounter++,
NetworkTest: enumAppCounter++,
NetworkTestResult: enumAppCounter++,
OnDownloadAvailable: enumAppCounter++,
OnLoggedIn: enumAppCounter++,
OnLoggedInUserName: enumAppCounter++,
OnLoggedOut: enumAppCounter++,
OnTrySyncCommand: enumAppCounter++,
openBackingTrackFile: enumAppCounter++,
OpenBackingTracksDirectory: enumAppCounter++,
OpenRecording: enumAppCounter++,
OpenSystemBrowser: enumAppCounter++,
openVideo: enumAppCounter++,
P2PMessageReceived: enumAppCounter++,
ParticipantJoined: enumAppCounter++,
ParticipantLeft: enumAppCounter++,
pauseVideoUpload: enumAppCounter++,
PerformQuit: enumAppCounter++,
PostTaskBarMessage: enumAppCounter++,
PreviewRecording: enumAppCounter++,
rebootJamBlaster: enumAppCounter++,
RegisterGenericCallBack: enumAppCounter++,
registerMasterClippingCallback: enumAppCounter++,
RegisterMixerInterfaceModeChangeCallback: enumAppCounter++,
RegisterMuteChangeCallBack: enumAppCounter++,
RegisterQuitCallback: enumAppCounter++,
RegisterRecordingCallbacks: enumAppCounter++,
RegisterRecordingManagerCallbacks: enumAppCounter++,
RegisterSessionJoinLeaveRequestCallBack: enumAppCounter++,
RegisterVolChangeCallBack: enumAppCounter++,
ReloadAudioSystem: enumAppCounter++,
removeBackingTrackFiles: enumAppCounter++,
ResetPageCounters: enumAppCounter++,
RestartApplication: enumAppCounter++,
restartParentClient: enumAppCounter++,
resumeVideoUpload: enumAppCounter++,
SaveSettings: enumAppCounter++,
SaveToClipboard: enumAppCounter++,
SendP2PMessage: enumAppCounter++,
SessGetInsetPosition: enumAppCounter++,
SessGetListOfPeersSharingVideo: enumAppCounter++,
SessGetPeersVideoPosition: enumAppCounter++,
SessGetVideoDisplayLayoutGroup: enumAppCounter++,
SessGetVideoReceiveEnable: enumAppCounter++,
SessGetVideoRecordings: enumAppCounter++,
SessionAddPlayTrack: enumAppCounter++,
SessionAddTrack: enumAppCounter++,
SessionAudioResync: enumAppCounter++,
SessionCloseBackingTrackFile: enumAppCounter++,
SessionCloseMetronome: enumAppCounter++,
SessionCurrentPlaybackMode: enumAppCounter++,
SessionCurrrentJamTrackPlayPosMs: enumAppCounter++,
SessionCurrrentPlayPosMs: enumAppCounter++,
SessionFirstGet: enumAppCounter++,
SessionFirstSet: enumAppCounter++,
SessionGetAllControlState: enumAppCounter++,
SessionGetControlState: enumAppCounter++,
SessionGetDeviceLatency: enumAppCounter++,
SessionGetIDs: enumAppCounter++,
SessionGetJamTracksPlayDurationMs: enumAppCounter++,
SessionGetMacHash: enumAppCounter++,
SessionGetMasterLocalMix: enumAppCounter++,
SessionGetTracksPlayDurationMs: enumAppCounter++,
SessionJamTrackSeekMs: enumAppCounter++,
SessionLiveBroadcastStart: enumAppCounter++,
SessionLiveBroadcastStop: enumAppCounter++,
SessionOpenBackingTrackFile: enumAppCounter++,
SessionOpenMetronome: enumAppCounter++,
SessionPageEnter: enumAppCounter++,
SessionPageLeave: enumAppCounter++,
SessionPausePlay: enumAppCounter++,
SessionRegisterCallback: enumAppCounter++,
SessionRemoveAllPlayTracks: enumAppCounter++,
SessionRemovePlayTrack: enumAppCounter++,
SessionRemoveTrack: enumAppCounter++,
SessionRequestUserControlUpdate: enumAppCounter++,
SessionSetAlertCallback: enumAppCounter++,
SessionSetAlertPeriod: enumAppCounter++,
SessionSetConnectionStatusRefreshRate: enumAppCounter++,
SessionSetControlState: enumAppCounter++,
SessionSetMasterLocalMix: enumAppCounter++,
SessionSetMetronome: enumAppCounter++,
SessionSetRecordingFilename: enumAppCounter++,
SessionSetRecordingFolder: enumAppCounter++,
SessionSetTrackVolumeData: enumAppCounter++,
SessionSetUserData: enumAppCounter++,
SessionSetUserName: enumAppCounter++,
SessionShowMetronomeGui: enumAppCounter++,
SessionStartPlay: enumAppCounter++,
SessionStopPlay: enumAppCounter++,
SessionTrackSeekMs: enumAppCounter++,
SessionTracksSeek: enumAppCounter++,
SessPlayVideoRecording: enumAppCounter++,
SessRotatePeerVideoPositions: enumAppCounter++,
SessSelectVideoDisplayLayoutGroup: enumAppCounter++,
SessSetInsetPosition: enumAppCounter++,
SessSetInsetSize: enumAppCounter++,
SessSetPeersVideoPosition: enumAppCounter++,
SessSetVideoReceiveEnable: enumAppCounter++,
SessStartVideoRecordAndReturnFileName: enumAppCounter++,
SessStartVideoSharing: enumAppCounter++,
SessStartWebcamVideoRecordAndReturnFileName: enumAppCounter++,
SessStartYouTubeVideoBroadcast: enumAppCounter++,
SessStopVideoRecord: enumAppCounter++,
SessStopVideoSharing: enumAppCounter++,
SessStopYouTubeVideoBroadcast: enumAppCounter++,
SessSubscribePeerVideo: enumAppCounter++,
SessUnsubscribePeerVideo: enumAppCounter++,
set48vAndLineInstState: enumAppCounter++,
setABLoopState: enumAppCounter++,
SetAutoStart: enumAppCounter++,
setBackingTrackOpenCallback: enumAppCounter++,
SetFakeRecordingImpl: enumAppCounter++,
SetFTUE: enumAppCounter++,
setJBAutoPair: enumAppCounter++,
setJBName: enumAppCounter++,
setJbNetworkState: enumAppCounter++,
setJbPortBindState: enumAppCounter++,
setJbPreampState: enumAppCounter++,
setJbStaticPortFlag: enumAppCounter++,
setJbStaticPortValue: enumAppCounter++,
setJbTrackState: enumAppCounter++,
setJbUsbState: enumAppCounter++,
setJmepMetronomeVolume: enumAppCounter++,
SetLastUsedProfileName: enumAppCounter++,
SetLatencyTestBlocked: enumAppCounter++,
setMetronomeCricketTestState: enumAppCounter++,
setMetronomeOpenCallback: enumAppCounter++,
SetMixerMode: enumAppCounter++,
SetNetworkTestScore: enumAppCounter++,
SetRecordingFilename: enumAppCounter++,
SetRecordingFolder: enumAppCounter++,
SetScoreWorkTimingInterval: enumAppCounter++,
setSessionMixerCategoryPlayoutState: enumAppCounter++,
setSessionSetCompressorState: enumAppCounter++,
SetStaticPort: enumAppCounter++,
SetUseStaticPort: enumAppCounter++,
SetVideoNetworkTestScore: enumAppCounter++,
SetVURefreshRate: enumAppCounter++,
ShowSelectBackingTrackDialog: enumAppCounter++,
ShowSelectVSTScanDialog: enumAppCounter++,
ShutdownApplication: enumAppCounter++,
StartLiveStreaming: enumAppCounter++,
startPairing: enumAppCounter++,
StartRecording: enumAppCounter++,
StopAudio: enumAppCounter++,
StopLiveStreaming: enumAppCounter++,
StopNetworkTest: enumAppCounter++,
StopRecording: enumAppCounter++,
TestLatency: enumAppCounter++,
TestNetworkPktBwRate: enumAppCounter++,
testVideoRender: enumAppCounter++,
TrackDeleteProfile: enumAppCounter++,
TrackGetAssignment: enumAppCounter++,
TrackGetChannels: enumAppCounter++,
TrackGetChatEnable: enumAppCounter++,
TrackGetChatUsesMusic: enumAppCounter++,
TrackGetCount: enumAppCounter++,
TrackGetDevices: enumAppCounter++,
TrackGetInstrument: enumAppCounter++,
TrackGetMusicDeviceID: enumAppCounter++,
TrackGetMusicDeviceNames: enumAppCounter++,
TrackHasControlPanel: enumAppCounter++,
TrackIsMusicDeviceType: enumAppCounter++,
TrackLoadAssignments: enumAppCounter++,
TrackLoadAudioProfile: enumAppCounter++,
TrackOpenControlPanel: enumAppCounter++,
TrackRefreshDevices: enumAppCounter++,
TrackSaveAssignments: enumAppCounter++,
TrackSetAssignment: enumAppCounter++,
TrackSetChatEnable: enumAppCounter++,
TrackSetChatInput: enumAppCounter++,
TrackSetChatUsesMusic: enumAppCounter++,
TrackSetCount: enumAppCounter++,
TrackSetInstrument: enumAppCounter++,
TrackSetMusicDevice: enumAppCounter++,
UpdateMixer: enumAppCounter++,
UpdateSessionInfo: enumAppCounter++,
uploadVideo: enumAppCounter++,
UserAttention: enumAppCounter++,
VideoDecision: enumAppCounter++,
VSTAddSearchPath: enumAppCounter++,
VSTClearAll: enumAppCounter++,
VSTListSearchPaths: enumAppCounter++,
VSTListTrackAssignments: enumAppCounter++,
VSTListVsts: enumAppCounter++,
VSTLoad: enumAppCounter++,
VSTRemoveSearchPath: enumAppCounter++,
VSTScan: enumAppCounter++,
VSTSetTrackAssignment: enumAppCounter++,
VSTShowHideGui: enumAppCounter++,
VST_EnableMidiForTrack: enumAppCounter++,
VST_GetMidiDeviceList: enumAppCounter++,
VST_ScanForMidiDevices: enumAppCounter++,
});
function setupWebSocketConnection() {
const baseUrl = "ws://localhost:3060";
logger.log(
"[asyncJamClient] connecting to WebSocket server at " + baseUrl + "."
);
const socket = new WebSocket(baseUrl);
socket.onclose = function (event) {
logger.error("[asyncJamClient] QWebChannel websocket closed");
if (event.code != 1000) {
// Error code 1000 means that the connection was closed normally.
// Try to reconnect.
if (!navigator.onLine) {
//alert("You are offline. Please connect to the Internet and try again.");
}
}
};
socket.onerror = function (error) {
logger.error("[asyncJamClient] QWebChannel websocket error: " + error);
};
socket.onopen = function () {
logger.log(
"[asyncJamClient] WebSocket connected, setting up QWebChannel."
);
const skipLogMethods = [
'getConnectionDetail'
]
const displayLogMethod = [
]
new QWebChannel(socket, function (channel) {
jkfrontendchannel = channel.objects.jkfrontendchannel;
if (jkfrontendchannel) {
window.isWebChannelReady = true;
let deferred;
try {
jkfrontendchannel.sendText.connect(function (message) {
// logger.log(
// "[asyncJamClient] Message received via QWebChannel: " +
// message
// );
//handle Method Not Implemented"
if (
typeof resp === "object" &&
resp[0] === "Method Not Implemented"
) {
//throw new Error("Method Not Implemented");
deferred.resolve(null); //return null value
} else {
let msg = JSON.parse(message);
let req_id = msg.request_id; //frontend originated request
let response = msg.response;
let evt_id = msg.event_id; //backend originated async event
let methodName = msg.method_name;
deferred = deferredQueue.find((d) => {
return d.request_id === req_id;
});
if (deferred) {
if(skipLogMethods.length > 0 && skipLogMethods.includes(methodName)){
}else{
if(displayLogMethod.includes(methodName)){
logger.log(
"[asyncJamClient] Message received via QWebChannel: " +
msg
);
}
}
deferred.resolve(response);
//remove this deferred object from queue
deferredQueue = deferredQueue.filter(
(d) => d.request_id !== deferred.request_id
);
} else if (evt_id) {
//logger.log("[asyncJamClient] event received:", evt_id, Object.keys(response)[0])
let method = Object.keys(response)[0]
switch (evt_id.toString()) {
case '3006': //execute_script
if(!response['execute_script'].match('HandleBridgeCallback2')){
logger.log(`[asyncJamClient] 3006 execute_script: ${response['execute_script']}`);
}
try {
eval(response['execute_script']);
} catch (error) {
logger.log(`[asyncJamClient] error: execute_script: ${response['execute_script']}`);
logger.log(error);
}
break;
case '3007': //message
logger.log(`[asyncJamClient] 3007 message: ${response['message']}`);
try {
const msg = response['message'];
const clientId = response['targetClientID'];
context.JK.JamServer.sendP2PMessage(clientId, msg)
} catch (error) {
logger.log(`[asyncJamClient] error: sendP2PMessage: ${response['message']}`);
logger.log(error);
}
break;
case '3010': //JKVideoSession
logger.log(`[asyncJamClient] 3010 JKVideoSession: ${response['JKVideoSession']['connect']}`);
const vidConnect = response['JKVideoSession']['connect'];
context.ExternalVideoActions.setVideoEnabled(vidConnect);
context.JK.videoIsOngoing = vidConnect;
break;
default:
break;
}
}
}
});
//TODO: handle method does not exist
} catch (e) {
logger.log(
"[asyncJamClient] Error when receving message via QWebChannel"
);
if (deferred) {
deferred.reject(e.message);
deferred = null;
}
Bugsnag.notify(e, function(event){
event.severity = 'info'
event.context = 'asyncJamClient'
event.setUser(gon.user_id, gon.user_email, gon.user_name)
});
}
}
});
};
}
function waitForOpenConnection(){
return new Promise((resolve, reject) => {
const maxNumberOfAttempts = 10
const intervalTime = 200 //ms
let currentAttempt = 0
const interval = setInterval(() => {
if (currentAttempt > maxNumberOfAttempts - 1) {
clearInterval(interval)
reject(new Error('Maximum number of attempts exceeded'))
} else if (jkfrontendchannel) {
clearInterval(interval)
resolve()
}
currentAttempt++
}, intervalTime)
})
}
async function sendWhenReady(prop, args){
if (jkfrontendchannel) {
return sendMessage(prop, args)
}else{
try {
await waitForOpenConnection()
return sendMessage(prop, args)
} catch (err) { console.error(err) }
}
}
function sendMessage(prop, args){
let appMessage = new Object();
appMessage.request_id = ++request_id;
appMessage.arguments = Array.from(args) || [];
let method = JKFrontendMethods[prop];
appMessage.method = method;
let deferred = new Deferred(appMessage.request_id);
const skipLogMethods = [
]
const displayLogMethod = [
'SessionSetTrackVolumeData'
]
if(skipLogMethods.length > 0 && skipLogMethods.includes(prop)){
}else{
if(displayLogMethod.includes(prop)){
logger.log(
"[asyncJamClient] diverting to backend:",
prop,
appMessage
);
}
}
if (jkfrontendchannel) {
try {
jkfrontendchannel.receiveText(JSON.stringify(appMessage));
deferredQueue.push(deferred);
return deferred.promise;
} catch (e) {
logger.error(
"[asyncJamClient] Native app not connected",
e.message
);
deferred.reject('Native app not connected')
return deferred.promise;
}
} else {
logger.info(
"[asyncJamClient] jkfrontendchannel is not ready yet"
);
deferred.reject('frontendchannel is not ready yet')
return deferred.promise;
}
}
function setupAsyncProxy() {
let proxy;
const handler = {
get(target, prop, receiver) {
//const origMethod = target[prop];
//console.log('[asyncJamClient] get:', target, prop);
return function (...args) {
// let result = origMethod.apply(this, args);
// console.log(prop + JSON.stringify(args)+ ' -> ' + JSON.stringify(result));
// return result;
return sendWhenReady(prop, arguments)
};
},
};
proxy = new Proxy(self, handler);
logger.log(
"[asyncJamClient] Connected to WebChannel, ready to send/receive messages!"
);
return proxy;
}
setupWebSocketConnection();
return setupAsyncProxy();
};
})(window, jQuery);

View File

@ -23,8 +23,8 @@
context.location = "/client#"; // leaveSession will be called in beforeHide below
}
function onStunEvent() {
var testResults = context.jamClient.NetworkTestResult();
async function onStunEvent() {
var testResults = await context.jamClient.NetworkTestResult();
$.each(testResults, function (index, val) {
if (val.bStunFailed) {
@ -49,8 +49,7 @@
}
function alertCallback(type, text) {
async function alertCallback(type, text) {
function timeCallback() {
var start = new Date();
setTimeout(function() {
@ -64,6 +63,7 @@
timeCallback();
logger.debug("alert callback", type, text);
console.log("alert callback", type, text);
var alertData = $.extend({}, ALERT_TYPES[type]);
@ -129,7 +129,7 @@
else if(type === ALERT_NAMES.RECORD_PLAYBACK_STATE) {
//if(context.JK.CurrentSessionModel)
// context.JK.CurrentSessionModel.onPlaybackStateChange(type, text);
context.MediaPlaybackActions.playbackStateChange(text);
await context.MediaPlaybackActions.playbackStateChange(text);
}
else if(type === ALERT_NAMES.VIDEO_WINDOW_OPENED) {
context.VideoActions.videoWindowOpened()
@ -150,8 +150,8 @@
}
}
function initialize() {
context.jamClient.SessionSetAlertCallback("JK.AlertCallback");
async function initialize() {
await context.jamClient.SessionSetAlertCallback("JK.AlertCallback");
}
this.initialize = initialize;

View File

@ -149,7 +149,7 @@
}
// called from sidebar when messages come in
function chatMessageReceived(payload) {
async function chatMessageReceived(payload) {
if (fullyInitialized) {
if (isChatPanelVisible()) {
@ -157,7 +157,7 @@
else {
highlightCount();
incrementChatCount();
context.jamClient.UserAttention(true);
await context.jamClient.UserAttention(true);
}
}
}

View File

@ -18,7 +18,7 @@
function cancelUpdate(e) {
if ((e.ctrlKey || e.metaKey) && e.keyCode == 78) {
logger.debug("update canceled!");
console.log("update canceled!");
app.layout.closeDialog('client-update');
app.clientUpdating = false;
}
@ -82,7 +82,7 @@
/***************************************/
function clientUpdateDownloadProgress(bytesReceived, bytesTotal, downloadSpeedMegSec, timeRemaining) {
// this fires way too many times to leave in. uncomment if debugging update feature
//logger.debug("bytesReceived: " + bytesReceived, ", bytesTotal: " + bytesTotal, ", downloadSpeed: " + downloadSpeedMegSec, ", timeRemaining: " + timeRemaining + ", updateSize: " + updateSize);
//console.log("bytesReceived: " + bytesReceived, ", bytesTotal: " + bytesTotal, ", downloadSpeed: " + downloadSpeedMegSec, ", timeRemaining: " + timeRemaining + ", updateSize: " + updateSize);
bytesReceived = Number(bytesReceived)
bytesTotal = Number(bytesTotal)
@ -93,7 +93,7 @@
}
function clientUpdateDownloadSuccess(updateLocation) {
logger.debug("client update downloaded successfully to: " + updateLocation);
console.log("client update downloaded successfully to: " + updateLocation);
updateClientUpdateDialog("update-proceeding");
@ -112,12 +112,12 @@
}
function clientUpdateLaunchSuccess(userTimeToRead) {
async function clientUpdateLaunchSuccess(userTimeToRead) {
if(userTimeToRead === undefined) {
userTimeToRead = 1000; // older clients didn't pass this in, and exit very quickly
}
logger.debug("client update launching in: " + userTimeToRead);
console.log("client update launching in: " + userTimeToRead);
// set timer to update countdown
var rounded = Math.round(userTimeToRead / 1000);
@ -135,7 +135,7 @@
}
}, rounded * 1000);
updateClientUpdateDialog("update-restarting", {countdown: rounded, os: context.JK.GetOSAsString()});
updateClientUpdateDialog("update-restarting", {countdown: rounded, os: await context.JK.GetOSAsString()});
}
function clientUpdateLaunchFailure(errorMsg) {
@ -145,7 +145,7 @@
}
function clientUpdateLaunchStatuses(statuses) {
logger.debug("client update launch statuses");
console.log("client update launch statuses");
if (statuses) {
for (var i = 0; i < statuses.length; i++) {
@ -155,7 +155,7 @@
}
function clientUpdateLaunchStatusChange(done, status) {
logger.debug("client update launch status change. starting=" + done + ", status=" + status);
console.log("client update launch status change. starting=" + done + ", status=" + status);
if (!done) {
var $ellipses = $('<span class="ellipses">.</span>');
@ -201,19 +201,24 @@
}
}
function runCheck(product, version, uri, size, currentVersion) {
async function runCheck(product, version, uri, size, currentVersion) {
if (app.clientUpdating) {
logger.debug("client is already updating; skipping")
console.log("client is already updating; skipping")
return
}
if(currentVersion === undefined) {
currentVersion = context.jamClient.ClientUpdateVersion();
console.log("runCheck: product , version", product, version)
// check kill switch before all other logic
if (!gon.check_for_client_updates) {
console.log("runCheck: skipping client update because the server is telling us not to")
return;
}
if(currentVersion === undefined) {
currentVersion = await context.jamClient.ClientUpdateVersion() //.then(function(currentVersion){
if (!forceShow && (currentVersion == null || currentVersion.indexOf("Compiled")) > -1) {
// this is a developer build; it doesn't make much sense to do an packaged update, so skip
logger.debug("skipping client update check because this is a development build ('" + currentVersion + "')")
console.log("skipping client update check because this is a development build ('" + currentVersion + "')")
return;
}
@ -221,9 +226,10 @@
if (currentVersion.indexOf('"') == 0 && currentVersion.lastIndexOf('"') == currentVersion.length - 1) {
currentVersion = currentVersion.substring(1, currentVersion.length - 1);
}
//});
}
logger.debug("our client version: " + currentVersion + ", server client version: " + version);
//console.log("_DEBUG_ our client version: " + currentVersion + ", server client version: " + version);
// test url in lieu of having a configured server with a client-update available
@ -233,7 +239,7 @@
updateSize = size;
if(context.SessionStore.inSession()) {
logger.debug("deferring client update because in session")
console.log("deferring client update because in session")
return;
}
@ -254,23 +260,23 @@
}
// check if updated is needed
function check() {
var os = context.JK.GetOSAsString();
async function check() {
var os = await context.jamClient.GetDetailedOS();
//os = 'Win32'
// check kill switch before all other logic
if (!gon.check_for_client_updates) {
logger.debug("skipping client update because the server is telling us not to")
console.log("skipping client update because the server is telling us not to")
return;
}
var product = "JamClient"
var currentVersion = context.jamClient.ClientUpdateVersion();
//var product = "JamClient"
var product = "JamClientModern"
var currentVersion = await context.jamClient.ClientUpdateVersion();
if (!forceShow && (currentVersion == null || currentVersion.indexOf("Compiled")) > -1) {
// this is a developer build; it doesn't make much sense to do an packaged update, so skip
logger.debug("skipping client update check because this is a development build ('" + currentVersion + "')")
console.log("skipping client update check because this is a development build ('" + currentVersion + "')")
return;
}
@ -283,7 +289,9 @@
type: "GET",
url: "/api/versioncheck?product=" + product + "&os=" + os,
success: function (response) {
runCheck(product, response.version, response.uri, response.size, currentVersion);
if(!jQuery.isEmptyObject(response)){
runCheck(product, response.version, response.uri, response.size, currentVersion);
}
},
error: function (jqXHR, textStatus, errorThrown) {
logger.error("Unable to do a client update check against /api/versioncheck");
@ -291,21 +299,21 @@
});
}
function startDownload(url) {
logger.debug("starting client updater download from: " + url);
async function startDownload(url) {
console.log("starting client updater download from: " + url);
updateClientUpdateDialog("update-downloading")
context.jamClient.ClientUpdateStartDownload(url,
await context.jamClient.ClientUpdateStartDownload(url,
"JK.ClientUpdate.DownloadProgressCallback",
"JK.ClientUpdate.DownloadSuccessCallback",
"JK.ClientUpdate.DownloadFailureCallback");
}
function startUpdate(updaterFilePath) {
logger.debug("starting client update from: " + updaterFilePath)
async function startUpdate(updaterFilePath) {
console.log("starting client update from: " + updaterFilePath)
context.jamClient.ClientUpdateStartUpdate(updaterFilePath,
await context.jamClient.ClientUpdateStartUpdate(updaterFilePath,
"JK.ClientUpdate.LaunchUpdateSuccessCallback",
"JK.ClientUpdate.LaunchUpdateFailureCallback",
"JK.ClientUpdate.LaunchUpdateStatusesCallback",

View File

@ -11,16 +11,30 @@ context.JK.ClientInit = class ClientInit
@ALERT_NAMES = context.JK.ALERT_NAMES;
@lastCheckedBroadcast = null
init: () =>
if context.gon.isNativeClient
this.nativeClientInit()
# init: () =>
# if context.gon.isNativeClient
# this.nativeClientInit()
context.JK.onBackendEvent(@ALERT_NAMES.WINDOW_OPEN_FOREGROUND_MODE, 'client_init', @watchBroadcast);
# context.JK.onBackendEvent(@ALERT_NAMES.WINDOW_OPEN_FOREGROUND_MODE, 'client_init', @watchBroadcast);
this.watchBroadcast()
# this.watchBroadcast()
if context.jamClient.RegisterSessionJoinLeaveRequestCallBack?
context.jamClient.RegisterSessionJoinLeaveRequestCallBack("SessionStore.handleJoinLeaveRequestCallback")
# if context.jamClient.RegisterSessionJoinLeaveRequestCallBack?
# context.jamClient.RegisterSessionJoinLeaveRequestCallBack("SessionStore.handleJoinLeaveRequestCallback")
init: `async function(){
if (context.gon.isNativeClient) {
await this.nativeClientInit();
}
context.JK.onBackendEvent(this.ALERT_NAMES.WINDOW_OPEN_FOREGROUND_MODE, 'client_init', this.watchBroadcast);
this.watchBroadcast();
//if (await context.jamClient.RegisterSessionJoinLeaveRequestCallBack != null) {
await context.jamClient.RegisterSessionJoinLeaveRequestCallBack("SessionStore.handleJoinLeaveRequestCallback");
//}
}`
checkBroadcast: () =>
promise = window.BroadcastActions.load.trigger()
@ -38,9 +52,15 @@ context.JK.ClientInit = class ClientInit
setTimeout(@checkBroadcast, 3000)
nativeClientInit: () =>
@gearUtils.bootstrapDefaultPlaybackProfile();
# nativeClientInit: () =>
# @gearUtils.bootstrapDefaultPlaybackProfile();
context.VideoActions.checkPromptConfigureVideo()
# context.VideoActions.checkPromptConfigureVideo()
nativeClientInit: `async function(){
await this.gearUtils.bootstrapDefaultPlaybackProfile();
return context.VideoActions.checkPromptConfigureVideo();
}`

View File

@ -146,8 +146,8 @@
});
$('#btn-driver-settings').unbind("click");
$('#btn-driver-settings').click(function () {
context.jamClient.TrackOpenControlPanel();
$('#btn-driver-settings').click(async function () {
await context.jamClient.TrackOpenControlPanel();
});
$('#btn-cancel-new-audio').unbind("click");
@ -156,10 +156,14 @@
$('#btn-error-ok').click(context.JK.showOverlay);
$('#btn-save-settings').unbind("click");
$('#btn-save-settings').click(saveSettings);
$('#btn-save-settings').click(async function(){
await saveSettings()
});
$('#btn-cancel-settings').unbind("click");
$('#btn-cancel-settings').click(cancelSettings);
$('#btn-cancel-settings').click(async function(){
await cancelSettings()
});
}
function _handleTrackInputAdd($selectedMusicInputs, selector) {
@ -262,14 +266,14 @@
return chatOtherUnassignedListCopy.length > 0 || chatOtherAssignedListCopy.length > 0;
}
function audioDriverChanged() {
async function audioDriverChanged() {
context.jamClient.TrackSetMusicDevice($('#audio-drivers').val());
await context.jamClient.TrackSetMusicDevice($('#audio-drivers').val());
logger.debug("Called TrackSetMusicDevice with " + $('#audio-drivers').val());
context.jamClient.TrackLoadAssignments();
initDialogData();
await context.jamClient.TrackLoadAssignments();
await initDialogData();
// refresh dialog
showVoiceChatPanel(true);
@ -319,8 +323,8 @@
});
}
function configureDriverSettingsButton() {
if (context.jamClient.TrackHasControlPanel()) {
async function configureDriverSettingsButton() {
if (await context.jamClient.TrackHasControlPanel()) {
$('#btn-driver-settings').show();
}
else {
@ -328,7 +332,7 @@
}
}
function showMusicAudioPanel(refreshLists) {
async function showMusicAudioPanel(refreshLists) {
_setInstructions('audio');
_activateTab('audio');
@ -336,11 +340,11 @@
$('#audio-drivers').empty();
// determine correct music device to preselect
var deviceId = context.jamClient.TrackGetMusicDeviceID();
var deviceId = await context.jamClient.TrackGetMusicDeviceID();
logger.debug("deviceId = " + deviceId);
// load Audio Driver dropdown
devices = context.jamClient.TrackGetDevices();
devices = await context.jamClient.TrackGetDevices();
logger.debug("Called TrackGetDevices with response " + JSON.stringify(devices));
var keys = Object.keys(devices);
@ -362,7 +366,7 @@
context.JK.dropdown($('#audio-drivers'));
if (deviceId === '') {
context.jamClient.TrackSetMusicDevice($('#audio-drivers').val());
await context.jamClient.TrackSetMusicDevice($('#audio-drivers').val());
}
configureDriverSettingsButton();
@ -384,7 +388,7 @@
context.JK.loadOptions($('#template-option').html(), $('#track1-input'), track1AudioInputChannels, "id", "name", -1);
// load Track 1 Instrument
var current_instrument = context.jamClient.TrackGetInstrument(ASSIGNMENT.TRACK1);
var current_instrument = await context.jamClient.TrackGetInstrument(ASSIGNMENT.TRACK1);
// if no instrument is stored on the backend, the user is opening this dialog for the first time after FTUE;
// initialize to the user's first instrument
@ -401,7 +405,7 @@
context.JK.loadOptions($('#template-option').html(), $('#track2-input'), track2AudioInputChannels, "id", "name", -1);
// load Track 2 Instrument
current_instrument = context.jamClient.TrackGetInstrument(ASSIGNMENT.TRACK2);
current_instrument = await context.jamClient.TrackGetInstrument(ASSIGNMENT.TRACK2);
context.JK.loadOptions($('#template-option').html(), $('#track2-instrument'), instrument_array, "id", "description", current_instrument);
// load Unused Outputs
@ -455,56 +459,56 @@
}
}
function initDialogData() {
_initMusicTabData();
_initVoiceChatTabData();
async function initDialogData() {
await _initMusicTabData();
await _initVoiceChatTabData();
}
function _initMusicTabData() {
inputUnassignedList = _loadList(ASSIGNMENT.UNASSIGNED, true, false);
async function _initMusicTabData() {
inputUnassignedList = await _loadList(ASSIGNMENT.UNASSIGNED, true, false);
//logger.debug("inputUnassignedList=" + JSON.stringify(inputUnassignedList));
track1AudioInputChannels = _loadList(ASSIGNMENT.TRACK1, true, false);
track1AudioInputChannels = await _loadList(ASSIGNMENT.TRACK1, true, false);
//logger.debug("track1AudioInputChannels=" + JSON.stringify(track1AudioInputChannels));
track2AudioInputChannels = _loadList(ASSIGNMENT.TRACK2, true, false);
track2AudioInputChannels = await _loadList(ASSIGNMENT.TRACK2, true, false);
//logger.debug("track2AudioInputChannels=" + JSON.stringify(track2AudioInputChannels));
outputUnassignedList = _loadList(ASSIGNMENT.UNASSIGNED, false, false);
outputAssignedList = _loadList(ASSIGNMENT.OUTPUT, false, false);
outputUnassignedList = await _loadList(ASSIGNMENT.UNASSIGNED, false, false);
outputAssignedList = await _loadList(ASSIGNMENT.OUTPUT, false, false);
}
function _initVoiceChatTabData() {
chatUnassignedList = _loadList(ASSIGNMENT.UNASSIGNED, true, false);
async function _initVoiceChatTabData() {
chatUnassignedList = await _loadList(ASSIGNMENT.UNASSIGNED, true, false);
//logger.debug("chatUnassignedList=" + JSON.stringify(chatUnassignedList));
chatAssignedList = _loadList(ASSIGNMENT.CHAT, true, false);
chatAssignedList = await _loadList(ASSIGNMENT.CHAT, true, false);
//logger.debug("chatAssignedList=" + JSON.stringify(chatAssignedList));
chatOtherUnassignedList = _loadList(ASSIGNMENT.UNASSIGNED, true, true);
chatOtherUnassignedList = await _loadList(ASSIGNMENT.UNASSIGNED, true, true);
//logger.debug("chatOtherUnassignedList=" + JSON.stringify(chatOtherUnassignedList));
chatOtherAssignedList = _loadList(ASSIGNMENT.CHAT, true, true);
chatOtherAssignedList = await _loadList(ASSIGNMENT.CHAT, true, true);
//logger.debug("chatOtherAssignedList=" + JSON.stringify(chatOtherAssignedList));
}
// TODO: copied in addTrack.js - refactor to common place
function _loadList(assignment, input, chat) {
async function _loadList(assignment, input, chat) {
var list = [];
// get data needed for listboxes
var channels = context.jamClient.TrackGetChannels();
var channels = await context.jamClient.TrackGetChannels();
var musicDevices = context.jamClient.TrackGetMusicDeviceNames(input);
var musicDevices = await context.jamClient.TrackGetMusicDeviceNames(input);
// SEE loadList function in TrackAssignGui.cpp of client code
$.each(channels, function (index, val) {
$.each(channels, async function (index, val) {
if (input !== val.input) {
return;
}
var currAssignment = context.jamClient.TrackGetAssignment(val.id, val.input);
var currAssignment = await context.jamClient.TrackGetAssignment(val.id, val.input);
if (assignment !== currAssignment) {
return;
}
@ -512,14 +516,15 @@
// logger.debug("channel id=" + val.id + ", channel input=" + val.input + ", channel assignment=" + currAssignment +
// ", channel name=" + val.name + ", channel type=" + val.device_type + ", chat=" + val.chat);
var os = context.jamClient.GetOSAsString();
var os = await context.jamClient.GetOSAsString();
if (os === context.JK.OS.WIN32) {
if (chat && ($.inArray(val.device_id, musicDevices) > -1 || context.jamClient.TrackIsMusicDeviceType(val.device_type))) {
if (chat && ($.inArray(val.device_id, musicDevices) > -1 || await context.jamClient.TrackIsMusicDeviceType(val.device_type))) {
return;
}
}
else {
if (chat && ($.inArray(val.device_id, musicDevices) > -1 || !context.jamClient.TrackIsMusicDeviceType(val.device_type))) {
var trackIsType = await context.jamClient.TrackIsMusicDeviceType(val.device_type)
if (chat && ($.inArray(val.device_id, musicDevices) > -1 || !trackIsType)) {
return;
}
}
@ -538,7 +543,7 @@
return list;
}
function saveSettings() {
async function saveSettings() {
if (!context.JK.verifyNotRecordingForTrackChange(app)) {
return;
}
@ -551,29 +556,29 @@
return;
}
saveAudioSettings();
saveVoiceChatSettings();
await saveAudioSettings();
await saveVoiceChatSettings();
context.jamClient.TrackSaveAssignments();
await context.jamClient.TrackSaveAssignments();
originalDeviceId = $('#audio-drivers').val();
app.layout.closeDialog('configure-audio');
}
function saveAudioSettings() {
async function saveAudioSettings() {
context.jamClient.TrackSetMusicDevice($('#audio-drivers').val());
await context.jamClient.TrackSetMusicDevice($('#audio-drivers').val());
// UNASSIGNED INPUTS
$('#audio-inputs-unused > option').each(function () {
$('#audio-inputs-unused > option').each(async function () {
logger.debug("Marking " + this.value + " as unassigned input.");
context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.UNASSIGNED);
await context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.UNASSIGNED);
});
// TRACK 1 INPUTS
$('#track1-input > option').each(function () {
$('#track1-input > option').each(async function () {
logger.debug("Saving track 1 input = " + this.value);
context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.TRACK1);
await context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.TRACK1);
});
// TRACK 1 INSTRUMENT
@ -581,15 +586,15 @@
var instrumentText = $('#track1-instrument > option:selected').text().toLowerCase();
logger.debug("Saving track 1 instrument = " + instrumentVal);
context.jamClient.TrackSetInstrument(ASSIGNMENT.TRACK1, instrumentVal);
await context.jamClient.TrackSetInstrument(ASSIGNMENT.TRACK1, instrumentVal);
// TRACK 2 INPUTS
var track2Selected = false;
$('#track2-input > option').each(function () {
$('#track2-input > option').each(async function () {
track2Selected = true;
logger.debug("Saving track 2 input = " + this.value);
context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.TRACK2);
await context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.TRACK2);
});
if (track2Selected) {
@ -598,66 +603,66 @@
instrumentText = $('#track2-instrument > option:selected').text().toLowerCase();
logger.debug("Saving track 2 instrument = " + instrumentVal);
context.jamClient.TrackSetInstrument(ASSIGNMENT.TRACK2, instrumentVal);
await context.jamClient.TrackSetInstrument(ASSIGNMENT.TRACK2, instrumentVal);
}
else {
// track 2 was removed
if (myTrackCount === 2) {
logger.debug("Deleting track " + myTracks[1].trackId);
context.jamClient.TrackSetCount(1);
await context.jamClient.TrackSetCount(1);
//sessionModel.deleteTrack(sessionId, myTracks[1].trackId);
}
}
// UNASSIGNED OUTPUTS
$('#audio-output-unused > option').each(function () {
$('#audio-output-unused > option').each(async function () {
logger.debug("Marking " + this.value + " as unassigned output.");
context.jamClient.TrackSetAssignment(this.value, false, ASSIGNMENT.UNASSIGNED);
await context.jamClient.TrackSetAssignment(this.value, false, ASSIGNMENT.UNASSIGNED);
});
// OUTPUT
$('#audio-output-selection > option').each(function () {
$('#audio-output-selection > option').each(async function () {
logger.debug("Saving session audio output = " + this.value);
context.jamClient.TrackSetAssignment(this.value, false, ASSIGNMENT.OUTPUT);
await context.jamClient.TrackSetAssignment(this.value, false, ASSIGNMENT.OUTPUT);
});
}
function saveVoiceChatSettings() {
async function saveVoiceChatSettings() {
var voiceChatType = isChatInputSpecified();
originalVoiceChat = voiceChatType;
logger.debug("Calling TrackSetChatEnable with value = " + voiceChatType);
context.jamClient.TrackSetChatEnable(voiceChatType == VOICE_CHAT.CHAT ? true : false);
await context.jamClient.TrackSetChatEnable(voiceChatType == VOICE_CHAT.CHAT ? true : false);
if (voiceChatType == VOICE_CHAT.CHAT) {
// UNASSIGNED VOICE CHAT
$('#voice-inputs-unused > option').each(function () {
$('#voice-inputs-unused > option').each(async function () {
logger.debug("Marking " + this.value + " as unassigned voice input.");
context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.UNASSIGNED);
await context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.UNASSIGNED);
});
// VOICE CHAT INPUT
$("#voice-inputs-selection > option").each(function () {
$("#voice-inputs-selection > option").each(async function () {
logger.debug("Saving chat input = " + this.value);
context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.CHAT);
await context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.CHAT);
});
}
// make sure any previously assigned chat devices are marked as unassigned
else if (voiceChatType == VOICE_CHAT.NO_CHAT) {
// chat devices that were assigned
$.each(chatOtherAssignedList, function (index, val) {
$.each(chatOtherAssignedList, async function (index, val) {
logger.debug("Marking " + val.id + " as unassigned voice input.");
context.jamClient.TrackSetAssignment(val.id, true, ASSIGNMENT.UNASSIGNED);
await context.jamClient.TrackSetAssignment(val.id, true, ASSIGNMENT.UNASSIGNED);
});
}
}
function cancelSettings() {
async function cancelSettings() {
logger.debug("Cancel settings");
// reset to original device ID
context.jamClient.TrackSetMusicDevice(originalDeviceId);
await context.jamClient.TrackSetMusicDevice(originalDeviceId);
$('#voice-chat-type').val(originalVoiceChat);
@ -759,10 +764,10 @@
return isValid;
}
function _setInstructions(type) {
async function _setInstructions(type) {
var $instructions = $('#instructions', 'div[layout-id="configure-audio"]');
if (type === 'audio') {
var os = context.jamClient.GetOSAsString();
var os = await context.jamClient.GetOSAsString();
$instructions.html(configure_audio_instructions[os]);
}
else if (type === 'voice') {
@ -774,18 +779,18 @@
return $('#voice-inputs-selection option').size() > 0 ? VOICE_CHAT.CHAT : VOICE_CHAT.NO_CHAT;
}
function _init() {
async function _init() {
// load instrument array for populating listboxes, using client_id in instrument_map as ID
instrument_array = context.JK.listInstruments();
originalVoiceChat = context.jamClient.TrackGetChatEnable() ? VOICE_CHAT.CHAT : VOICE_CHAT.NO_CHAT;
originalVoiceChat = await context.jamClient.TrackGetChatEnable() ? VOICE_CHAT.CHAT : VOICE_CHAT.NO_CHAT;
$('#voice-chat-type').val(originalVoiceChat);
originalDeviceId = context.jamClient.TrackGetMusicDeviceID();
originalDeviceId = await context.jamClient.TrackGetMusicDeviceID();
context.jamClient.TrackLoadAssignments();
initDialogData();
await context.jamClient.TrackLoadAssignments();
await initDialogData();
var $option1 = $('#voice-chat-type > option[value="1"]');

View File

@ -155,8 +155,8 @@
// inputChannelFilter is an optional argument that is used by the Gear Wizard.
// basically, if an input channel isn't in there, it's not going to be displayed
function loadChannels(forceInputsToUnassign, inputChannelFilter) {
var musicPorts = jamClient.FTUEGetChannels();
async function loadChannels(forceInputsToUnassign, inputChannelFilter) {
var musicPorts = await jamClient.FTUEGetChannels();
$unassignedInputsHolder.empty();
$unassignedOutputsHolder.empty();
@ -370,33 +370,44 @@
return true;
}
function save(state) {
async function save(state) {
context._.each(state.unassignedChannels, function(unassignedChannelId) {
context.jamClient.TrackSetAssignment(unassignedChannelId, true, ASSIGNMENT.UNASSIGNED);
});
//context._.each(state.unassignedChannels, async function(unassignedChannelId) {
for(const unassignedChannelId of state.unassignedChannels){
await context.jamClient.TrackSetAssignment(unassignedChannelId, true, ASSIGNMENT.UNASSIGNED);
}
//});
// save input/tracks
context._.each(state.tracks, function(track, index) {
//context._.each(state.tracks, async function(track, index) {
for(let index = 0; index < state.tracks.length; index++) {
var track = state.tracks[index];
var trackNumber = index + 1;
context._.each(track.channels, function(channelId) {
context.jamClient.TrackSetAssignment(channelId, true, trackNumber);
});
//context._.each(track.channels, async function(channelId) {
for(const channelId of track.channels){
await context.jamClient.TrackSetAssignment(channelId, true, trackNumber);
}
//});
logger.debug("context.jamClient.TrackSetInstrument(trackNumber, track.instrument_id)", trackNumber, track.instrument_id);
context.jamClient.TrackSetInstrument(trackNumber, context.JK.instrument_id_to_instrument[track.instrument_id].client_id);
});
await context.jamClient.TrackSetInstrument(trackNumber, context.JK.instrument_id_to_instrument[track.instrument_id].client_id);
}
//});
// save outputs
context._.each(state.outputs, function(output, index) {
context._.each(output.channels, function(channelId) {
context.jamClient.TrackSetAssignment(channelId, true, ASSIGNMENT.OUTPUT);
});
});
//context._.each(state.outputs, function(output, index) {
for(let index = 0; index < state.outputs.length; index ++) {
let output = state.outputs[index];
//context._.each(output.channels, async function(channelId) {
for (const channelId of output.channels) {
await context.jamClient.TrackSetAssignment(channelId, true, ASSIGNMENT.OUTPUT);
}
//});
}
//});
var result = context.jamClient.TrackSaveAssignments();
var result = await context.jamClient.TrackSaveAssignments();
if(!result || result.length == 0) {
// success
@ -408,20 +419,25 @@
}
}
function loadTrackInstruments(forceInputsToUnassign) {
async function loadTrackInstruments(forceInputsToUnassign) {
var $trackInstruments = $instrumentsHolder.find('.track-instrument');
context._.each($trackInstruments, function(trackInstrument) {
//context._.each($trackInstruments, async function(trackInstrument) {
for(let i = 0; i < $trackInstruments.length; i++) {
var trackInstrument = $trackInstruments[i];
var $trackInstrument = $(trackInstrument);
var trackIndex = parseInt($trackInstrument.attr('data-num')) + 1;
var clientInstrument = context.jamClient.TrackGetInstrument(trackIndex);
var clientInstrument = await context.jamClient.TrackGetInstrument(trackIndex);
var instrument = context.JK.client_to_server_instrument_map[clientInstrument];
$trackInstrument.instrumentSelectorSet(instrument ? instrument.server_id : instrument);
});
}
//});
}
function trySave() {
@ -440,9 +456,9 @@
return saved;
}
function reset(forceInputsToUnassign, inputChannelFilter) {
async function reset(forceInputsToUnassign, inputChannelFilter) {
loadChannels(forceInputsToUnassign, inputChannelFilter);
loadTrackInstruments(forceInputsToUnassign);
await loadTrackInstruments(forceInputsToUnassign);
}
function unassignOutputChannel($channel) {

View File

@ -26,8 +26,8 @@
// inputChannelFilter is an optional argument that is used by the Gear Wizard.
// basically, if an input channel isn't in there, it's not going to be displayed
function loadChannels(forceInputsToUnassign, inputChannelFilter) {
var musicPorts = jamClient.FTUEGetChannels();
async function loadChannels(forceInputsToUnassign, inputChannelFilter) {
var musicPorts = await jamClient.FTUEGetChannels();
$unassignedInputsHolder.empty();
$unassignedOutputsHolder.empty();
@ -177,33 +177,45 @@
return true;
}
function save(state) {
async function save(state) {
context._.each(state.unassignedChannels, function(unassignedChannelId) {
context.jamClient.TrackSetAssignment(unassignedChannelId, true, ASSIGNMENT.UNASSIGNED);
});
//context._.each(state.unassignedChannels, async function(unassignedChannelId) {
for (const unassignedChannelId of state.unassignedChannels) {
await context.jamClient.TrackSetAssignment(unassignedChannelId, true, ASSIGNMENT.UNASSIGNED);
}
//});
// save input/tracks
context._.each(state.tracks, function(track, index) {
//context._.each(state.tracks, async function(track, index) {
for (let index = 0; index < state.tracks; index++) {
var track = state.tracks[index];
var trackNumber = index + 1;
context._.each(track.channels, function(channelId) {
context.jamClient.TrackSetAssignment(channelId, true, trackNumber);
});
//context._.each(track.channels, async function(channelId) {
for (const channelId of track.channels) {
await context.jamClient.TrackSetAssignment(channelId, true, trackNumber);
}
//});
logger.debug("context.jamClient.TrackSetInstrument(trackNumber, track.instrument_id)", trackNumber, track.instrument_id);
context.jamClient.TrackSetInstrument(trackNumber, context.JK.instrument_id_to_instrument[track.instrument_id].client_id);
});
await context.jamClient.TrackSetInstrument(trackNumber, context.JK.instrument_id_to_instrument[track.instrument_id].client_id);
}
//});
// save outputs
context._.each(state.outputs, function(output, index) {
context._.each(output.channels, function(channelId) {
context.jamClient.TrackSetAssignment(channelId, true, ASSIGNMENT.OUTPUT);
});
});
//context._.each(state.outputs, async function(output, index) {
for(let index = 0; index < state.outputs.length; index++) {
let output = state.outputs[index];
//context._.each(output.channels, async function(channelId) {
for(const channelId of output.channels) {
await context.jamClient.TrackSetAssignment(channelId, true, ASSIGNMENT.OUTPUT);
}
//});
}
//});
var result = context.jamClient.TrackSaveAssignments();
var result = await context.jamClient.TrackSaveAssignments();
if(!result || result.length == 0) {
// success
@ -215,20 +227,26 @@
}
}
function loadTrackInstruments(forceInputsToUnassign) {
async function loadTrackInstruments(forceInputsToUnassign) {
var $trackInstruments = $instrumentsHolder.find('.track-instrument');
context._.each($trackInstruments, function(trackInstrument) {
//context._.each($trackInstruments, async function(trackInstrument) {
for(var i = 0; i < $trackInstruments.length; i++){
var trackInstrument = $trackInstruments[i];
var $trackInstrument = $(trackInstrument);
var trackIndex = parseInt($trackInstrument.attr('data-num')) + 1;
var clientInstrument = context.jamClient.TrackGetInstrument(trackIndex);
var clientInstrument = await context.jamClient.TrackGetInstrument(trackIndex);
var instrument = context.JK.client_to_server_instrument_map[clientInstrument];
$trackInstrument.instrumentSelectorSet(instrument ? instrument.server_id : instrument);
});
}
//});
}
function trySave() {
@ -247,9 +265,9 @@
return saved;
}
function reset(forceInputsToUnassign, inputChannelFilter) {
async function reset(forceInputsToUnassign, inputChannelFilter) {
loadChannels(forceInputsToUnassign, inputChannelFilter);
loadTrackInstruments(forceInputsToUnassign);
await loadTrackInstruments(forceInputsToUnassign);
}
function unassignOutputChannel($channel) {

View File

@ -116,7 +116,7 @@
return isValid;
}
function submitForm(evt) {
async function submitForm(evt) {
evt.preventDefault();
if(!gon.isNativeClient) {
@ -136,7 +136,7 @@
}
// if for some reason there are 0 tracks, show FTUE
var tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient);
var tracks = await context.JK.TrackHelpers.getUserTracks(context.jamClient);
if(tracks.length == 0) {
logger.error("we should never have 0 tracks and have gotten this far. Launch FTUE is the best we can do right now")
// If user hasn't completed FTUE - do so now.
@ -172,7 +172,7 @@
if ($('#band-list option:selected').val() !== '') {
data.band = $('#band-list option:selected').val();
}
data.audio_latency = context.jamClient.FTUEGetExpectedLatency().latency;
data.audio_latency = await context.jamClient.FTUEGetExpectedLatency().latency;
// 1. If no previous session data, a single stereo track with the
// top instrument in the user's profile.

View File

@ -51,22 +51,22 @@
gearUtils.updateDefaultBuffers(selectedDeviceInfo, frameBuffers)
}
function onFramesizeChanged() {
async function onFramesizeChanged() {
//context.JK.prodBubble($resyncBtn, 'push-resync-when-done', {}, {positions:['top']});
updateDefaultBuffers();
context.jamClient.FTUESetFrameSize(frameBuffers.selectedFramesize());
await context.jamClient.FTUESetFrameSize(frameBuffers.selectedFramesize());
invalidateScore();
}
function onBufferInChanged() {
async function onBufferInChanged() {
//context.JK.prodBubble($resyncBtn, 'push-resync-when-done', {}, {positions:['top']});
context.jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn());
await context.jamClient.FTUESetInputLatency(frameBuffers.selectedBufferIn());
invalidateScore();
}
function onBufferOutChanged() {
async function onBufferOutChanged() {
//context.JK.prodBubble($resyncBtn, 'push-resync-when-done', {}, {positions:['top']});
context.jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut());
await context.jamClient.FTUESetOutputLatency(frameBuffers.selectedBufferOut());
invalidateScore();
}
@ -110,12 +110,13 @@
}
}
function beforeShow() {
selectedDeviceInfo = gearUtils.selectedDeviceInfo(context.jamClient.FTUEGetInputMusicDevice(), context.jamClient.FTUEGetOutputMusicDevice());
deviceInformation = gearUtils.loadDeviceInfo();
startingFramesize = context.jamClient.FTUEGetFrameSize();
startingBufferIn = context.jamClient.FTUEGetInputLatency();
startingBufferOut = context.jamClient.FTUEGetOutputLatency();
async function beforeShow() {
let [p1, p2] = await Promise.all([context.jamClient.FTUEGetInputMusicDevice(), context.jamClient.FTUEGetOutputMusicDevice()])
selectedDeviceInfo = await gearUtils.selectedDeviceInfo(p1, p1);
deviceInformation = await gearUtils.loadDeviceInfo();
startingFramesize = await context.jamClient.FTUEGetFrameSize();
startingBufferIn = await context.jamClient.FTUEGetInputLatency();
startingBufferOut = await context.jamClient.FTUEGetOutputLatency();
var startingSpeed = translateFrameSizeToSpeed(startingFramesize)
logger.debug("speed upon entry: " + startingSpeed)
$speedOptions.filter('[value=' + startingSpeed + ']').iCheck('check')
@ -219,7 +220,7 @@
}
function initialize() {
async function initialize() {
var dialogBindings = {
'beforeShow': beforeShow,
'beforeHide': beforeHide,
@ -238,7 +239,7 @@
$fairLabel = $dialog.find('label[for="adjust-gear-speed-fair"]')
$fastLabel = $dialog.find('label[for="adjust-gear-speed-fast"]')
operatingSystem = context.JK.GetOSAsString();
operatingSystem = await context.JK.GetOSAsString();
$frameBuffers = $dialog.find('.frame-and-buffers');
frameBuffers.initialize($frameBuffers);

View File

@ -120,15 +120,17 @@
})
}
function onUsbDeviceConnected() {
if(!context.jamClient.IsFrontendVisible()) {return;} // don't handle USB events when minimized
async function onUsbDeviceConnected() {
var isFrontendVisible = await context.jamClient.IsFrontendVisible()
if(!isFrontendVisible) {return;} // don't handle USB events when minimized
logger.debug("USB device connected");
scheduleRescanSystem(3000);
}
function onUsbDeviceDisconnected() {
if(!context.jamClient.IsFrontendVisible()) {return;} // don't handle USB events when minimized
async function onUsbDeviceDisconnected() {
var isFrontendVisible = await context.jamClient.IsFrontendVisible()
if(!isFrontendVisible) {return;} // don't handle USB events when minimized
logger.debug("USB device disconnected");
scheduleRescanSystem(3000);
@ -149,8 +151,8 @@
context.JK.Banner.showYesNo({
title: "Confirm Restart",
html: "Are you sure you want to restart JamKazam?",
yes: function() {
context.jamClient.RestartApplication();
yes: async function() {
await context.jamClient.RestartApplication();
},
no : function() {
context.JK.Banner.hide();

View File

@ -50,31 +50,31 @@
context.JK.checkbox($autoStartInput);
context.JK.checkbox($useStaticPortInput);
$btnSave.click(function() {
$btnSave.click(async function() {
if (!validate()) {
return false;
}
var autostart = $autoStartField.find('.icheckbox_minimal').is('.checked');
context.jamClient.SetAutoStart(autostart);
await context.jamClient.SetAutoStart(autostart);
var useStaticPort = $useStaticPortField.find('.icheckbox_minimal').is('.checked');
context.jamClient.SetUseStaticPort(useStaticPort);
await context.jamClient.SetUseStaticPort(useStaticPort);
var staticPort = new Number($staticPortInput.val());
context.jamClient.SetStaticPort(staticPort);
await context.jamClient.SetStaticPort(staticPort);
app.layout.closeDialog('client-preferences-dialog')
context.jamClient.SaveSettings();
await context.jamClient.SaveSettings();
logger.debug("New Client Settings", {autostart: autostart, useStaticPort: useStaticPort, staticPort: staticPort})
if ((beforeValues.useStaticPort != useStaticPort) || (beforeValues.staticPort != staticPort)) {
context.JK.Banner.showYesNo({
title: "Please Restart",
html: "The changes you made won't take effect until you restart JamKazam. Restart now?",
yes: function() {
context.jamClient.RestartApplication();
yes: async function() {
await context.jamClient.RestartApplication();
},
no : function() {
context.JK.Banner.hide();
@ -85,14 +85,14 @@
})
}
function beforeShow() {
var autostart = context.jamClient.GetAutoStart();
async function beforeShow() {
var autostart = await context.jamClient.GetAutoStart();
autostart ? $autoStartInput.iCheck('check') : $autoStartInput.iCheck('uncheck');
var useStaticPort = context.jamClient.GetUseStaticPort();
var useStaticPort = await context.jamClient.GetUseStaticPort();
useStaticPort ? $useStaticPortInput.iCheck('check') : $useStaticPortInput.iCheck('uncheck');
var staticPort = context.jamClient.GetStaticPort();
var staticPort = await context.jamClient.GetStaticPort();
$staticPortInput.val(staticPort);

View File

@ -33,9 +33,9 @@
rest.getSessionHistory(sessionId)
.done(function(response) {
if (response && response.comments) {
$.each(response.comments, function(index, val) {
$.each(response.comments, async function(index, val) {
renderComment(val.comment, val.creator.id, val.creator.name,
context.JK.resolveAvatarUrl(val.creator.photo_url), $.timeago(val.created_at), val.creator.musician, true);
await context.JK.resolveAvatarUrl(val.creator.photo_url), $.timeago(val.created_at), val.creator.musician, true);
});
context.JK.bindHoverEvents($content);
context.JK.bindProfileClickEvents($content, ['comment-dialog']);
@ -49,9 +49,9 @@
rest.getClaimedRecording(claimedRecordingId)
.done(function(response) {
if (response.recording && response.recording.comments) {
$.each(response.recording.comments, function(index, val) {
$.each(response.recording.comments, async function(index, val) {
renderComment(val.comment, val.creator.id, val.creator.name,
context.JK.resolveAvatarUrl(val.creator.photo_url), $.timeago(val.created_at), val.creator.musician, true);
await context.JK.resolveAvatarUrl(val.creator.photo_url), $.timeago(val.created_at), val.creator.musician, true);
});
context.JK.bindHoverEvents($content);

View File

@ -158,7 +158,7 @@
//context.JK.dropdown($certifiedAudioProfile);
}
function deviceChanged() {
async function deviceChanged() {
var profile = $certifiedAudioProfile.val();
if(currentProfile == profile) {
@ -166,7 +166,7 @@
}
logger.debug("activating audio profile: " + profile);
var result = context.jamClient.FTUELoadAudioConfiguration(profile);
var result = await context.jamClient.FTUELoadAudioConfiguration(profile);
if(!result) {
logger.error("unable to activate audio configuration: " + profile + ", " + JSON.stringify(result));
@ -176,7 +176,7 @@
}
// FTUELoadAudioConfiguration eventually sets this, but apparently asynchronously
result = context.jamClient.SetLastUsedProfileName(profile);
result = await context.jamClient.SetLastUsedProfileName(profile);
if(!result) {
logger.error("unable to activate audio configuration after loading it: " + profile);
@ -189,20 +189,20 @@
window.ConfigureTracksActions.reset(false);
}
function beforeShow() {
async function beforeShow() {
profiles = gearUtils.getProfiles();
profiles = await gearUtils.getProfiles();
renderCertifiedGearDropdown();
showMusicAudioPanel();
currentProfile = context.jamClient.LastUsedProfileName();
currentProfile = await context.jamClient.LastUsedProfileName();
if(currentProfile != $certifiedAudioProfile.val()) {
logger.error("the currently active profile (" + currentProfile + ") is not the same as the Certified Audio Gear dropdown (" + $certifiedAudioProfile.val() + ")");
context.JK.alertSupportedNeeded("Unable to determine the current profile.");
}
var result = context.jamClient.FTUELoadAudioConfiguration(currentProfile);
var result = await context.jamClient.FTUELoadAudioConfiguration(currentProfile);
if(!result) {
logger.error("unable to activate audio configuration: " + currentProfile + ", " + JSON.stringify(result));
@ -221,12 +221,12 @@
voiceChatHelper.beforeShow();
}
function delayEnableVst() {
async function delayEnableVst() {
if (enableVstTimeout) {
clearTimeout(enableVstTimeout)
}
var isVstLoaded = context.jamClient.IsVstLoaded()
var hasVstAssignment = context.jamClient.hasVstAssignment()
var isVstLoaded = await context.jamClient.IsVstLoaded()
var hasVstAssignment = await context.jamClient.hasVstAssignment()
if (hasVstAssignment && !isVstLoaded) {
enableVstTimeout = setTimeout(function() { enableVst() }, 1000)

View File

@ -20,7 +20,7 @@
var template = $('#template-friend-selection').html();
var friends = rest.getFriends({ id: context.JK.currentUserId })
.done(function(friends) {
$.each(friends, function(index, val) {
$.each(friends, async function(index, val) {
var id = val.id;
var isSelected = selectedIds[id];
@ -28,7 +28,7 @@
userId: id,
css_class: isSelected ? 'selected' : '',
userName: val.name,
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
avatar_url: await context.JK.resolveAvatarUrl(val.photo_url),
status: "",
status_img_url: "",
check_mark_display: isSelected ? "block" : "none",

View File

@ -24,13 +24,13 @@
function registerEvents() {
$setupGearBtn.click(function() {
$setupGearBtn.click(async function() {
if (gon.isNativeClient) {
app.layout.closeDialog('getting-started');
// if no profiles, show FTUE in-line, if any, redirect to audio profile line
var profiles = context.jamClient.FTUEGetAllAudioConfigurations();
var profiles = await context.jamClient.FTUEGetAllAudioConfigurations();
if(profiles && profile.length > 0) {
window.location = '/client#/account/audio'

View File

@ -28,7 +28,8 @@
resetPagination();
showing = true;
getRecordings(0)
.done(function(data, textStatus, jqXHR) {
.then(function(resp) {
const [claimedRecordings, textStatus, jqXHR] = resp;
// initialize pagination
var $paginator = context.JK.Paginator.create(parseInt(jqXHR.getResponseHeader('total-entries')), perPage, 0, onPageSelected)
$('#local-recordings-dialog .paginator-holder').append($paginator);
@ -45,15 +46,15 @@
}
function getRecordings(page) {
return rest.getClaimedRecordings({page:page + 1, per_page:10})
.done(function(claimedRecordings) {
const promise = rest.getClaimedRecordingsPromise({page:page + 1, per_page:10})
promise.then(async function(resp) {
const [claimedRecordings, textStatus, jqXHR] = resp;
emptyList();
var $tbody = tbody();
const $tbody = tbody();
var recordings = $.map(claimedRecordings, function(val, i) { return val.recording; });
var localResults = context.jamClient.GetLocalRecordingState({recordings: recordings});
const recordings = $.map(claimedRecordings, function(val, i) { return val.recording; });
const localResults = await context.jamClient.GetLocalRecordingState({recordings: recordings});
if(localResults['error']) {
app.notify({
@ -69,7 +70,7 @@
$.each(claimedRecordings, function(index, claimedRecording) {
var options = {
const options = {
recordingId: claimedRecording.recording.id,
//date: context.JK.formatDate(claimedRecording.recording.created_at),
//time: context.JK.formatTime(claimedRecording.recording.created_at),
@ -79,15 +80,18 @@
duration: context.JK.prettyPrintSeconds(claimedRecording.recording.duration)
};
var tr = $(context._.template($('#template-claimed-recording-row').html(), options, { variable: 'data' }));
const tr = $(context._.template($('#template-claimed-recording-row').html(), options, { variable: 'data' }));
tr.data('server-model', claimedRecording);
$tbody.append(tr);
});
})
.fail(function(jqXHR, textStatus, errorMessage) {
.catch(function(error) {
const [jqXHR, textStatus, errorMessage] = error;
app.ajaxError(jqXHR, textStatus, errorMessage);
});
return promise;
}
function registerStaticEvents() {
@ -123,13 +127,13 @@
// tell the server we are about to start a recording
rest.startPlayClaimedRecording({id: context.SessionStore.id(), claimed_recording_id: claimedRecording.id})
.done(function(response) {
.then(async function(response) {
// update session info
context.SessionActions.updateSession.trigger(response);
var recordingId = $(this).attr('data-recording-id');
var openRecordingResult = context.jamClient.OpenRecording(claimedRecording.recording);
var openRecordingResult = await context.jamClient.OpenRecording(claimedRecording.recording);
logger.debug("OpenRecording response: %o", openRecordingResult);
@ -153,14 +157,15 @@
app.layout.closeDialog('localRecordings');
$(this).triggerHandler('openedSession', {});
}
openingRecording = false;
})
.fail(function(jqXHR) {
.catch(function(jqXHR) {
app.notifyServerError(jqXHR, "Unable to Open Recording For Playback");
})
.always(function() {
openingRecording = false;
openingRecording = false;
})
// .finally(function() {
// openingRecording = false;
// })
}

View File

@ -46,9 +46,9 @@
return getBackingTracks(targetPage);
}
function getBackingTracks(page) {
async function getBackingTracks(page) {
var result = context.jamClient.getBackingTrackList();
var result = await context.jamClient.getBackingTrackList();
var backingTracks = result.backing_tracks;
if (!backingTracks || backingTracks.length == 0) {
@ -86,8 +86,8 @@
// tell the server we are about to open a backing track:
rest.openBackingTrack({id: context.SessionStore.id(), backing_track_path: backingTrack.name})
.done(function(response) {
var result = context.jamClient.SessionOpenBackingTrackFile(backingTrack.name, false);
.done(async function(response) {
var result = await context.jamClient.SessionOpenBackingTrackFile(backingTrack.name, false);
// TODO: Possibly actually check the result. Investigate
// what real client returns:
@ -112,9 +112,9 @@
context.JK.helpBubble($whatAreBackingTracks, 'no help yet for this topic', {}, {positions:['bottom'], offsetParent: $dialog})
$whatAreBackingTracks.on('click', false) // no help yet
$displayAudioFileFolder.on('click', function(e) {
$displayAudioFileFolder.on('click', async function(e) {
e.stopPropagation();
context.jamClient.OpenBackingTracksDirectory();
await context.jamClient.OpenBackingTracksDirectory();
})
}

View File

@ -96,11 +96,11 @@
}
function afterShow() {
async function afterShow() {
$dialog.data('result', null)
showing = true;
sampleRate = context.jamClient.GetSampleRate()
sampleRate = await context.jamClient.GetSampleRate()
sampleRateForFilename = sampleRate == 48 ? '48' : '44';
doSearch();
}
@ -134,14 +134,14 @@
emptyList();
$.each(purchasedJamTracks.jamtracks, function(index, jamTrack) {
$.each(purchasedJamTracks.jamtracks, async function(index, jamTrack) {
var options = {}
options.jamTrackState = null;
options.jamTrackId = jamTrack.id;
options.name = jamTrack.name;
options.artist = jamTrack.original_artist;
var detail = context.jamClient.JamTrackGetTrackDetail(jamTrack.id + '-' + sampleRateForFilename) || {}
var detail = await context.jamClient.JamTrackGetTrackDetail(jamTrack.id + '-' + sampleRateForFilename) || {}
options.downloaded = detail.key_state == 'ready' ? 'Yes' : 'No'
var $tr = $(context._.template($templateOpenJamTrackRow.html(), options, { variable: 'data' }));

View File

@ -81,7 +81,7 @@
}
return false;
});
$('#btn-rate-session-send', $scopeSelector).click(function(evt) {
$('#btn-rate-session-send', $scopeSelector).click(async function(evt) {
var rr = getRating(), cc = getComment();
if (0 == rr && 0 == cc.length) {
closeDialog();
@ -93,10 +93,10 @@
}
var url = "/api/participant_histories/"+clientId+"/rating";
// get backend details too
if(context.jamClient.getAllClientsStateMap) {
var backendDetails = context.jamClient.getAllClientsStateMap()
//if(context.jamClient.getAllClientsStateMap) {
var backendDetails = await context.jamClient.getAllClientsStateMap()
console.log("got backend details", backendDetails)
}
//}
$.ajax({
type: "POST",

View File

@ -36,7 +36,7 @@
removeGoogleLoginErrors()
}
function beforeShow() {
async function beforeShow() {
$dialog.data('result', null);
if (recording == null) {
alert("recording data should not be null");
@ -46,7 +46,7 @@
resetForm();
if(context.jamClient.getClientParentChildRole() == CLIENT_ROLE.CHILD) {
if(await context.jamClient.getClientParentChildRole() == CLIENT_ROLE.CHILD) {
logger.debug("child client; launching preview after xfer");
$('#recording-finished-dialog span.nowait').addClass('hidden')
@ -61,14 +61,14 @@
$('#recording-finished-dialog span.nowait').removeClass('hidden')
$('#recording-finished-dialog .preview-area').css('visibility', 'visible')
$('#recording-finished-dialog form').css('visibility', 'visible')
launchPreview();
await launchPreview();
}
}
function waitForMixTransfer() {
timeout = setTimeout(function() {
timeout = setTimeout(async function() {
console.log("checking for file transfer", window.RecordingStore.mixTransferred)
if(window.RecordingStore.mixTransferred) {
@ -77,7 +77,7 @@
$('#recording-finished-dialog .preview-area').css('visibility', 'visible')
$('#recording-finished-dialog form').css('visibility', 'visible')
timeout = null
launchPreview()
await launchPreview()
}
else {
waitForMixTransfer();
@ -86,7 +86,7 @@
}, 1000)
}
function launchPreview() {
async function launchPreview() {
var parentSelector = '#recording-finished-dialog div.genre-selector';
context.JK.GenreSelectorHelper.render(parentSelector);
@ -97,7 +97,7 @@
context.JK.GenreSelectorHelper.setSelectedGenres(parentSelector, [genreDescription]);
}
var localResults = context.jamClient.GetLocalRecordingState({recordings: [recording]});
var localResults = await context.jamClient.GetLocalRecordingState({recordings: [recording]});
if (localResults['error']) {
logger.error("unable to open recording due to error: %o", localResults);
@ -128,7 +128,7 @@
else {
// load recording
var openRecordingResult = context.jamClient.PreviewRecording(recording);
var openRecordingResult = await context.jamClient.PreviewRecording(recording);
logger.debug("OpenRecording response: %o", openRecordingResult);
@ -161,7 +161,7 @@
}
}
}
function afterHide() {
async function afterHide() {
if(timeout) {
clearTimeout(timeout)
timeout = null
@ -177,12 +177,12 @@
logger.debug("VideoDecision rid:" + recording.id + ", name=" + name + ", keepResult=" + keepResult + ", saveToDisk=" + saveToDisk);
context.jamClient.VideoDecision(recording.id, name, keepResult && saveToDisk)
await context.jamClient.VideoDecision(recording.id, name, keepResult && saveToDisk)
}
recording = null;
playbackControls.stopMonitor();
context.jamClient.ClosePreviewRecording();
await context.jamClient.ClosePreviewRecording();
}
function onCancel() {
@ -337,24 +337,24 @@
}
}
function onPause() {
async function onPause() {
logger.debug("calling jamClient.SessionPausePlay");
context.jamClient.SessionPausePlay();
await context.jamClient.SessionPausePlay();
}
function onStop() {
async function onStop() {
logger.debug("calling jamClient.SessionStopPlay");
context.jamClient.SessionStopPlay();
await context.jamClient.SessionStopPlay();
}
function onPlay(e, data) {
async function onPlay(e, data) {
logger.debug("calling jamClient.SessionStartPlay");
context.jamClient.SessionStartPlay(data.playbackMode);
await context.jamClient.SessionStartPlay(data.playbackMode);
}
function onChangePlayPosition(e, data) {
async function onChangePlayPosition(e, data) {
logger.debug("calling jamClient.SessionTrackSeekMs(" + data.positionMs + ")");
context.jamClient.SessionTrackSeekMs(data.positionMs);
await context.jamClient.SessionTrackSeekMs(data.positionMs);
}
function registerStaticEvents() {

View File

@ -23,14 +23,23 @@ context.JK.SessionMasterMixDialog = class SessionMasterMixDialog
@app.bindDialog(@dialogId, dialogBindings)
@content = @dialog.find(".dialog-inner")
beforeShow:() =>
@logger.debug("session-master-mix-dlg: beforeShow")
context.jamClient.SetMixerMode(MIX_MODES.MASTER)
# beforeShow:() =>
# @logger.debug("session-master-mix-dlg: beforeShow")
# context.jamClient.SetMixerMode(MIX_MODES.MASTER)
beforeShow: `async function(){
this.logger.debug("session-master-mix-dlg: beforeShow");
await context.jamClient.SetMixerMode(MIX_MODES.MASTER);
}`
afterShow:() =>
@logger.debug("session-master-mix-dlg: afterShow")
afterHide:() =>
context.jamClient.SetMixerMode(MIX_MODES.PERSONAL)
# afterHide:() =>
# context.jamClient.SetMixerMode(MIX_MODES.PERSONAL)
afterHide: `async function(){
await context.jamClient.SetMixerMode(MIX_MODES.PERSONAL);
}`

View File

@ -452,7 +452,7 @@
registerEvents(false);
}
function initialize(_facebookHelper) {
async function initialize(_facebookHelper) {
facebookHelper = _facebookHelper;
var dialogBindings = {
@ -467,9 +467,9 @@
facebookHelper.deferredLoginStatus().done(function(response) { handleFbStateChange(response); });
if(context.jamClient.IsNativeClient()) {
$("#btn-share-copy").unbind('click').click(function() {
context.jamClient.SaveToClipboard($("#link-contents").text());
if(context.JK.isQWebEngine) {
$("#btn-share-copy").unbind('click').click(async function() {
await context.jamClient.SaveToClipboard($("#link-contents").text());
return false;
})
}

View File

@ -15,20 +15,20 @@
logger.debug("'CANCEL SHUTDOWN' selected")
context.JK.Banner.hide();
}},
{name: 'SHUT DOWN', click: function() {
{name: 'SHUT DOWN', click: async function() {
logger.debug("'COMPLETELY SHUT DOWN THE APP' selected")
context.jamClient.ShutdownApplication()
await context.jamClient.ShutdownApplication()
}},
],
html: $('#template-shutdown-prompt').html()});
}
function initialize() {
async function initialize() {
// guard against old clients
if(context.jamClient.RegisterQuitCallback) {
context.jamClient.RegisterQuitCallback("window.JK.ShutdownDialogCallback");
}
//if(context.jamClient.RegisterQuitCallback) {
await context.jamClient.RegisterQuitCallback("window.JK.ShutdownDialogCallback");
//}
}
function quitCallback(options) {

View File

@ -30,7 +30,7 @@ context.JK.SoundCloudPlayerDialog = class SoundCloudPlayerDialog
@player.attr("src", "")
# the Windows client does not play back correctly
if context.jamClient.IsNativeClient()
if context.JK.isQWebEngine
context.JK.popExternalLink(@url)
return false
else

View File

@ -262,7 +262,7 @@
}
// called from sidebar when messages come in
function messageReceived(payload) {
async function messageReceived(payload) {
if(showing && otherId == payload.sender_id) {
if(fullyInitialized) {
renderMessage(payload.msg, payload.sender_id, payload.sender_name, payload.created_at, true);
@ -278,7 +278,7 @@
app.notify({
"title": "Message from " + payload.sender_name,
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
"icon_url": await context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-reply",
text: "REPLY",

View File

@ -9,9 +9,10 @@
var rest = context.JK.Rest();
var dialogId = '#video-dialog';
function videoClick(e) {
async function videoClick(e) {
var $self = $(this);
if (!context.jamClient || !context.jamClient.IsNativeClient()) {
var isNativeClient = context.JK.isQWebEngine;
if (!isNativeClient) {
$('#video-dialog-header').html($self.data('video-header') || $self.attr('data-video-header'));
$('#video-dialog-iframe').attr('src', $self.data('video-url') || $self.attr('data-video-url'));
@ -22,7 +23,7 @@
}
else {
var videoUrl = $.param.querystring(window.location.href, 'showVideo=' + encodeURIComponent($self.data('video-url')));
context.jamClient.OpenSystemBrowser(videoUrl);
await context.jamClient.OpenSystemBrowser(videoUrl);
}
}

View File

@ -148,7 +148,8 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
@stateHolder.children().remove()
@stateHolder.append(context._.template(@state.template.html(), @jamTrack, { variable: 'data' }))
@stateHolder.find('.' + @size).removeClass('hidden')
@state.show()
# force this
@state.show.call(this)
# report a stat now that we've reached the end of this widget's journey
trackProgress: () =>
@ -184,38 +185,65 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
@tracked = true
showPackaging: () =>
@logger.debug("showing #{@state.name}")
console.log("showing #{@state.name}")
this.expectTransition()
showDownloading: () =>
@logger.debug("showing #{@state.name}")
# while downloading, we don't run the transition timer, because the download API is guaranteed to call success, or failure, eventually
context.jamClient.JamTrackDownload(@jamTrack.id, null, context.JK.currentUserId,
# showDownloading: () =>
# console.log("showing #{@state.name}")
# # while downloading, we don't run the transition timer, because the download API is guaranteed to call success, or failure, eventually
# context.jamClient.JamTrackDownload(@jamTrack.id, null, context.JK.currentUserId,
# this.makeDownloadProgressCallback(),
# this.makeDownloadSuccessCallback(),
# this.makeDownloadFailureCallback())
showDownloading: `async function(){
console.log('showing '+this.state.name);
// while downloading, we do not run the transition timer, because the download API is guaranteed to call success, or failure, eventually
await context.jamClient.JamTrackDownload(this.jamTrack.id, null, context.JK.currentUserId,
this.makeDownloadProgressCallback(),
this.makeDownloadSuccessCallback(),
this.makeDownloadFailureCallback())
this.makeDownloadFailureCallback());
}`
showKeying: () =>
@logger.debug("showing #{@state.name}")
context.jamClient.JamTrackKeysRequest()
this.waitForState()
# showKeying: () =>
# console.log("showing #{@state.name}")
# context.jamClient.JamTrackKeysRequest()
# this.waitForState()
showKeying: `async function(){
this.logger.debug('showing '+this.state.name);
await context.jamClient.JamTrackKeysRequest();
this.waitForState();
}`
showQuiet: () =>
@logger.debug("showing #{@state.name}")
console.log("showing #{@state.name}")
showInitial: () =>
@logger.debug("showing #{@state.name}")
@sampleRate = context.jamClient.GetSampleRate()
@fingerprint = context.jamClient.SessionGetMacHash()
logger.debug("fingerprint: ", @fingerprint)
@sampleRateForFilename = if @sampleRate == 48 then '48' else '44'
@attempts = @attempts + 1
this.expectTransition()
context.JK.SubscriptionUtils.subscribe('jam_track_right', @jamTrack.jam_track_right_id).on(context.JK.EVENTS.SUBSCRIBE_NOTIFICATION, this.onJamTrackRightEvent)
this.checkState()
# showInitial: () =>
# console.log("showing #{@state.name}")
# @sampleRate = context.jamClient.GetSampleRate()
# @fingerprint = context.jamClient.SessionGetMacHash()
# logger.debug("fingerprint: ", @fingerprint)
# @sampleRateForFilename = if @sampleRate == 48 then '48' else '44'
# @attempts = @attempts + 1
# this.expectTransition()
# context.JK.SubscriptionUtils.subscribe('jam_track_right', @jamTrack.jam_track_right_id).on(context.JK.EVENTS.SUBSCRIBE_NOTIFICATION, this.onJamTrackRightEvent)
# this.checkState()
showInitial: `async function() {
console.log('showing '+ this.state.name);
this.sampleRate = await context.jamClient.GetSampleRate();
this.fingerprint = await context.jamClient.SessionGetMacHash();
console.log("fingerprint: ", this.fingerprint);
this.sampleRateForFilename = this.sampleRate === 48 ? '48' : '44';
this.attempts = this.attempts + 1;
this.expectTransition();
context.JK.SubscriptionUtils.subscribe('jam_track_right', this.jamTrack.jam_track_right_id).on(context.JK.EVENTS.SUBSCRIBE_NOTIFICATION, this.onJamTrackRightEvent);
this.checkState();
}`
showError: () =>
@logger.debug("showing #{@state.name}")
console.log("showing #{@state.name}")
context.JK.SubscriptionUtils.unsubscribe('jam_track_right', @jamTrack.jam_track_right_id)
if @size == 'large'
@ -233,17 +261,17 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
@stateHolder.find('.retry').text(retryMsg)
showSynchronized: () =>
@logger.debug("showing #{@state.name}")
console.log("showing #{@state.name}")
context.JK.SubscriptionUtils.unsubscribe('jam_track_right', @jamTrack.jam_track_right_id)
showNoClient: () =>
@logger.debug("showing #{@state.name}")
console.log("showing #{@state.name}")
downloadCheck: () =>
@logger.debug "downloadCheck"
console.log "downloadCheck"
retry: () =>
@logger.debug "user initiated retry"
console.log "user initiated retry"
@path = []
@path.push('retry')
this.clear()
@ -263,7 +291,7 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
# if not, then let's see if we have timed out
if @state.timer?
if (new Date()).getTime() - @state.stateStartTime.getTime() > @state.max_time
@logger.debug("The current step (#{@state.name}) took too long")
console.log("The current step (#{@state.name}) took too long")
if @state == @states.keying
# specific message
@ -327,19 +355,19 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
return
if newState == @state
@logger.debug("DownloadJamTrack: ignoring state change #{@state.name}")
console.log("DownloadJamTrack: ignoring state change #{@state.name}")
return
if @state?
@logger.debug("DownloadJamTrack: state change: #{@state.name} => #{newState.name}")
console.log("DownloadJamTrack: state change: #{@state.name} => #{newState.name}")
# make sure there is no timer running on the old state
this.clearTransitionTimer()
this.clearStateTimer()
this.abortEnqueue()
@logger.debug("aborting getJamTrack right on state change")
console.log("aborting getJamTrack right on state change")
this.abortGetJamTrackRight()
else
@logger.debug("DownloadJamTrack: initial state: #{newState.name}")
console.log("DownloadJamTrack: initial state: #{newState.name}")
@state = newState
@ -353,38 +381,76 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
$(this).triggerHandler(@EVENTS.JAMTRACK_DOWNLOADER_STATE_CHANGED, {state: @state})
checkState: () =>
# check for the success state against the local state of the client... if it's playable, then we should be OK
fqId = "#{@jamTrack.id}-#{@sampleRateForFilename}"
@trackDetail = context.jamClient.JamTrackGetTrackDetail (fqId)
# checkState: () =>
# # check for the success state against the local state of the client... if it's playable, then we should be OK
# fqId = "#{@jamTrack.id}-#{@sampleRateForFilename}"
# @trackDetail = context.jamClient.JamTrackGetTrackDetail (fqId)
@logger.debug("DownloadJamTrack: JamTrackGetTrackDetail(#{fqId}).key_state: " + @trackDetail.key_state, @trackDetail)
# console.log("DownloadJamTrack: JamTrackGetTrackDetail(#{fqId}).key_state: " + @trackDetail.key_state, @trackDetail)
# first check if the version is not the same; if so, invalidate.
# # first check if the version is not the same; if so, invalidate.
if @trackDetail.version?
if @jamTrack.version != @trackDetail.version
@logger.info("DownloadJamTrack: JamTrack on disk is different version (stored: #{@trackDetail.version}, server: #{@jamTrack.version}. Invalidating")
context.jamClient.InvalidateJamTrack("#{@jamTrack.id}-#{@sampleRateForFilename}")
@trackDetail = context.jamClient.JamTrackGetTrackDetail ("#{@jamTrack.id}-#{@sampleRateForFilename}")
# if @trackDetail.version?
# if @jamTrack.version != @trackDetail.version
# @logger.info("DownloadJamTrack: JamTrack on disk is different version (stored: #{@trackDetail.version}, server: #{@jamTrack.version}. Invalidating")
# context.jamClient.InvalidateJamTrack("#{@jamTrack.id}-#{@sampleRateForFilename}")
# @trackDetail = context.jamClient.JamTrackGetTrackDetail ("#{@jamTrack.id}-#{@sampleRateForFilename}")
if @trackDetail.version?
@logger.error("after invalidating package, the version is still wrong!", @trackDetail)
throw "after invalidating package, the version is still wrong! #{@trackDetail.version}"
# if @trackDetail.version?
# @logger.error("after invalidating package, the version is still wrong!", @trackDetail)
# throw "after invalidating package, the version is still wrong! #{@trackDetail.version}"
switch @trackDetail.key_state
when 'pending'
this.transition(@states.keying)
when 'not authorized'
# TODO: if not authorized, do we need to re-initiate a keying attempt?
this.transition(@states.keying)
when 'ready'
this.transition(@states.synchronized)
when 'unknown'
@ajaxGetJamTrackRightAborted = false
@rest.getJamTrackRight({id: @jamTrack.id})
# switch @trackDetail.key_state
# when 'pending'
# this.transition(@states.keying)
# when 'not authorized'
# # TODO: if not authorized, do we need to re-initiate a keying attempt?
# this.transition(@states.keying)
# when 'ready'
# this.transition(@states.synchronized)
# when 'unknown'
# @ajaxGetJamTrackRightAborted = false
# @rest.getJamTrackRight({id: @jamTrack.id})
# .done(this.processJamTrackRight)
# .fail(this.processJamTrackRightFail)
checkState: `async function() {
// check for the success state against the local state of the client... if its playable, then we should be OK
const fqId = this.jamTrack.id+'-'+this.sampleRateForFilename;
this.trackDetail = await context.jamClient.JamTrackGetTrackDetail((fqId));
this.logger.debug('DownloadJamTrack: JamTrackGetTrackDetail('+fqId+').key_state: ' + this.trackDetail.key_state, this.trackDetail);
//first check if the version is not the same; if so, invalidate.
if (this.trackDetail.version != null) {
if (this.jamTrack.version !== this.trackDetail.version) {
this.logger.info('DownloadJamTrack: JamTrack on disk is different version (stored: '+this.trackDetail.version+', server: '+this.jamTrack.version+'. Invalidating');
await context.jamClient.InvalidateJamTrack(this.jamTrack.id+'-'+this.sampleRateForFilename);
this.trackDetail = await context.jamClient.JamTrackGetTrackDetail((this.jamTrack.id+'-'+this.sampleRateForFilename));
if (this.trackDetail.version != null) {
this.logger.error("after invalidating package, the version is still wrong!", this.trackDetail);
throw 'after invalidating package, the version is still wrong! ' + this.trackDetail.version;
}
}
}
switch (this.trackDetail.key_state) {
case 'pending':
return this.transition(this.states.keying);
case 'not authorized':
// TODO: if not authorized, do we need to re-initiate a keying attempt?
return this.transition(this.states.keying);
case 'ready':
return this.transition(this.states.synchronized);
case 'unknown':
this.ajaxGetJamTrackRightAborted = false;
return this.rest.getJamTrackRight({id: this.jamTrack.id})
.done(this.processJamTrackRight)
.fail(this.processJamTrackRightFail)
.fail(this.processJamTrackRightFail);
}
}`
# update progress indicator for packaging step
updateSteps: () =>
@ -402,7 +468,7 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
@updateSteps()
@logger.debug("DownloadJamTrack: processSigningState: " + signingState)
console.log("DownloadJamTrack: processSigningState: " + signingState)
switch signingState
when 'QUIET'
@ -459,23 +525,23 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
processJamTrackRight: (myJamTrack) =>
@logger.debug("processJamTrackRight", myJamTrack)
console.log("processJamTrackRight", myJamTrack)
unless @ajaxGetJamTrackRightAborted
this.processSigningState(myJamTrack)
else
@logger.debug("DownloadJamTrack: ignoring processJamTrackRight response")
console.log("DownloadJamTrack: ignoring processJamTrackRight response")
processJamTrackRightFail: () =>
unless @ajaxGetJamTrackRightAborted?
this.transitionError("status-check-error", "Unable to check with the server on the status of your JamTrack.")
else
@logger.debug("DownloadJamTrack: ignoring processJamTrackRightFail response")
console.log("DownloadJamTrack: ignoring processJamTrackRightFail response")
processEnqueueJamTrack: (enqueueResponse) =>
unless @ajaxEnqueueAborted
this.expectTransition() # the act of enqueuing should send down events to the client. we wait...
else
@logger.debug("DownloadJamTrack: ignoring processEnqueueJamTrack response")
console.log("DownloadJamTrack: ignoring processEnqueueJamTrack response")
displayUIForGuard:(response) =>
display = switch response.message
@ -496,10 +562,10 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
else
this.transitionError("enqueue-error", "Unable to ask the server to build your JamTrack.")
else
@logger.debug("DownloadJamTrack: ignoring processEnqueueJamTrackFail response")
console.log("DownloadJamTrack: ignoring processEnqueueJamTrackFail response")
onJamTrackRightEvent: (e, data) =>
@logger.debug("DownloadJamTrack: subscription notification received: type:" + data.type, data)
console.log("DownloadJamTrack: subscription notification received: type:" + data.type, data)
this.expectTransition()
this.processSigningState(data.body)
@ -513,7 +579,7 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
@root.find('.state-downloading .progress').text(progress)
downloadProgressCallback: (bytesReceived, bytesTotal) =>
@logger.debug("download #{bytesReceived}/#{bytesTotal}")
console.log("download #{bytesReceived}/#{bytesTotal}")
@bytesReceived = Number(bytesReceived)
@bytesTotal = Number(bytesTotal)
@ -524,7 +590,7 @@ context.JK.DownloadJamTrack = class DownloadJamTrack
downloadSuccessCallback: (updateLocation) =>
# is the package loadable yet?
@logger.debug("DownloadJamTrack: download complete - on to keying")
console.log("DownloadJamTrack: download complete - on to keying")
this.transition(@states.keying)
downloadFailureCallback: (errorMsg) =>

View File

@ -2,8 +2,11 @@
// !!!! Keep white space after last require !!!!
//
//= require fakeJamClient
//= require fakeJamClientProxy
//= require fakeJamClientMessages
//= require fakeJamClientRecordings
//= require qwebchannel.js
//= require asyncJamClient
//= require backend_alerts
//= require stun
//= require influxdb-latest
@ -28,12 +31,11 @@
$(window).on('pagehide', setNavigationStart)
}
$(document).on('JAMKAZAM_CONSTRUCTED', function(e, data) {
console.log('JAMKAZAM_CONSTRUCTED event called');
var app = data.app;
if(!app) throw "app not found";
// makes window.jamClient / context.jamClient set to something non-null very early on
context.JK.initJamClient(app);
@ -52,7 +54,8 @@
$.cookie("browser.timezone", window.jstz.determine().name(), { expires: 365, path: '/' });
}
$(document).on('JAMKAZAM_READY', function() {
$(document).on('JAMKAZAM_READY', async function() {
console.log('JAMKAZAM_READY event called');
// this event is fired when context.app is initialized
var app = context.JK.app;
@ -61,9 +64,9 @@
initializeDialogs(app);
checkAudioStopped();
await checkAudioStopped();
checkMacOSXInstalledCorrectly();
await checkMacOSXInstalledCorrectly();
watchPreferencesEvent(app);
@ -90,13 +93,14 @@
});
}
function checkMacOSXInstalledCorrectly() {
var os = context.jamClient.GetOSAsString();
async function checkMacOSXInstalledCorrectly() {
var os = await context.jamClient.GetOSAsString();
// check if method exists at all for migration purposes
if(context.jamClient.IsAppInWritableVolume && os == "MacOSX" && !context.jamClient.IsAppInWritableVolume()) {
var isAppInWritableVolume = await context.jamClient.IsAppInWritableVolume()
if(os == "MacOSX" && !isAppInWritableVolume) {
context.JK.Banner.showAlert(
{ title: "Drag JamKazam to the Applications Folder!",
buttons: [{name: 'SHUTDOWN APPLICATION', click: function() {context.jamClient.ShutdownApplication()}} ],
buttons: [{name: 'SHUTDOWN APPLICATION', click: async function() { await context.jamClient.ShutdownApplication()}} ],
html: $('#template-app-in-read-only-volume').html()});
return;
}
@ -164,26 +168,26 @@
}
// wait 10 seconds
function checkAudioStopped() {
async function checkAudioStopped() {
if(context.jamClient.ResetPageCounters) {
//if(context.jamClient.ResetPageCounters) {
// upgrade concern
context.jamClient.ResetPageCounters();
await context.jamClient.ResetPageCounters();
context.JK.AudioStopTimeout = setTimeout(function() {
context.JK.AudioStopTimeout = setTimeout(async function() {
if(context.jamClient.IsAudioStarted()) {
if(await context.jamClient.IsAudioStarted()) {
logger.debug("checkAudioStopped: stopping audio ...")
context.jamClient.StopAudio();
await context.jamClient.StopAudio();
}
}, 10000);
}
//}
}
function updateScoringIntervals() {
if(context.jamClient.SetLatencyTestBlocked) {
async function updateScoringIntervals() {
if(await context.jamClient.SetLatencyTestBlocked) {
// make sure latency testing is still going on, in case a refresh occurred during network test
context.jamClient.SetLatencyTestBlocked(false)
await context.jamClient.SetLatencyTestBlocked(false)
}
// set scoring intervals
@ -193,7 +197,7 @@
interval: gon.global.scoring_get_work_interval,
backoff: gon.global.scoring_get_work_backoff_interval
})
if(!success) logger.warning("unable to set scoring intervals")
//if(!success) logger.warning("unable to set scoring intervals")
}
}
@ -213,6 +217,7 @@
}
function initializeStun(app) {
stun = new context.JK.Stun(app);
context.JK.StunInstance = stun;
stun.initialize();
@ -226,12 +231,12 @@
window.location.reload();
});
JK.JamServer.registerMessageCallback(JK.MessageType.RESTART_APPLICATION, function(header, payload) {
context.jamClient.RestartApplication();
JK.JamServer.registerMessageCallback(JK.MessageType.RESTART_APPLICATION, async function(header, payload) {
await context.jamClient.RestartApplication();
});
JK.JamServer.registerMessageCallback(JK.MessageType.STOP_APPLICATION, function(header, payload) {
context.jamClient.ShutdownApplication();
JK.JamServer.registerMessageCallback(JK.MessageType.STOP_APPLICATION, async function(header, payload) {
await context.jamClient.ShutdownApplication();
});
}

View File

@ -923,6 +923,7 @@
}
function SessionSetAlertCallback(callback) {
//console('running.....')
alertCallbackName = callback;
// simulate a backend alert
@ -1529,6 +1530,12 @@
return {}
}
function RegisterSessionJoinLeaveRequestCallBack(){}
function RegisterGenericCallBack(){}
function GetDetailedOS(){}
// Javascript Bridge seems to camel-case
// Set the instance functions:
this.AbortRecording = AbortRecording;
@ -1575,6 +1582,8 @@
this.GetStaticPort = GetStaticPort;
this.SetStaticPort = SetStaticPort;
this.connected = true;
this.RegisterGenericCallBack = RegisterGenericCallBack;
this.GetDetailedOS = GetDetailedOS;
// FTUE (round 3)
this.FTUESetInputMusicDevice = FTUESetInputMusicDevice;
@ -1664,6 +1673,7 @@
this.SessionPageEnter = SessionPageEnter;
this.SessionPageLeave = SessionPageLeave;
this.SetMixerMode = SetMixerMode;
this.RegisterSessionJoinLeaveRequestCallBack = RegisterSessionJoinLeaveRequestCallBack;
this.SetVURefreshRate = SetVURefreshRate;
this.SessionGetMasterLocalMix = SessionGetMasterLocalMix;
@ -1811,6 +1821,8 @@
this.listTrackAssignments = listTrackAssignments;
this.applySubscriptionPolicy = applySubscriptionPolicy;
this.clientID = "devtester";
this.NetworkTestResult = NetworkTestResult;
};
})(window, jQuery);

View File

@ -0,0 +1,35 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
context.JK.FakeJamClientProxy = function(app, p2pMessageFactory) {
const handler = {
get: (target, prop, receiver) => {
return function (...args) {
return new Promise((resolve, reject) => {
try {
//console.log('[fakeJamClient]', prop)
if(target[prop]){
const result = target[prop].apply(target, args);
resolve(result);
}else{
console.error('[fakeJamClient] error: No such method in FakeJamClient', prop);
reject(`No such method in FakeJamClient: ${prop}`);
}
} catch (error) {
console.error('[fakeJamClient] error:', prop, error);
reject(error);
}
});
}
}
}
const fakeJamClient = new JK.FakeJamClient(app, p2pMessageFactory);
return new Proxy(fakeJamClient, handler);
}
})(window, jQuery);

View File

@ -46,19 +46,19 @@
'ftue-audio-output-fader': jamClient.FTUEGetOutputVolume
};
function latencyTimeoutCheck() {
async function latencyTimeoutCheck() {
if (context.JK.FtueWizard.latencyTimeout) {
jamClient.FTUERegisterLatencyCallback('');
await jamClient.FTUERegisterLatencyCallback('');
context.JK.app.setWizardStep("5");
}
}
function afterHide(data) {
async function afterHide(data) {
// Unsubscribe from FTUE VU callbacks.
jamClient.FTUERegisterVUCallbacks('', '', '');
await jamClient.FTUERegisterVUCallbacks('', '', '');
if (!successfulFtue && app.cancelFtue) {
app.cancelFtue();
await app.cancelFtue();
app.afterFtue = null;
app.cancelFtue = null;
}
@ -150,12 +150,12 @@
}
function settingsInit() {
jamClient.FTUEInit();
async function settingsInit() {
await jamClient.FTUEInit();
//setLevels(0);
resetFtueLatencyView();
setSaveButtonState($('#btn-ftue-2-save'), false);
if (jamClient.GetOSAsString() !== "Win32") {
if (await jamClient.GetOSAsString() !== "Win32") {
$('#btn-ftue-2-asio-control-panel').hide();
}
renderDisableTest();
@ -176,18 +176,19 @@
$('[layout-wizard="ftue"] [layout-wizard-step="2"] .settings-controls select[data-device="voice-chat-output"]').val("");
}
function setLevels(db) {
async function setLevels(db) {
if (db < -80 || db > 20) {
throw ("BUG! ftue.js:setLevels db arg must be between -80 and 20");
}
var trackIds = jamClient.SessionGetIDs();
var controlStates = jamClient.SessionGetControlState(trackIds);
$.each(controlStates, function (index, value) {
var trackIds = await jamClient.SessionGetIDs();
var controlStates = await jamClient.SessionGetControlState(trackIds);
$.each(controlStates, async function (index, value) {
context.JK.Mixer.fillTrackVolume(value, false);
// Default input/output to 0 DB
context.trackVolumeObject.volL = db;
context.trackVolumeObject.volR = db;
jamClient.SessionSetControlState(trackIds[index]);
//await jamClient.SessionSetControlState(trackIds[index]);
await context.jamClient.SessionSetTrackVolumeData(trackIds[index], null, context.trackVolumeObject)
});
$.each(context._.keys(faderMap), function (index, faderId) {
// faderChange takes a value from 0-100
@ -199,14 +200,14 @@
});
}
function testComplete() {
async function testComplete() {
logger.debug("Test complete");
var latencyMS = context.JK.FtueWizard.latencyMS;
var ftueSucceeded = latencyMS <= 20;
if (ftueSucceeded) {
logger.debug(latencyMS + " is <= 20. Setting FTUE status to true");
ftueSave(true); // Save the profile
context.jamClient.FTUESetStatus(true); // No FTUE wizard next time
await context.jamClient.FTUESetStatus(true); // No FTUE wizard next time
rest.userCertifiedGear({success: true});
// notify anyone curious about how it went
@ -300,36 +301,36 @@
}
function testLatency() {
async function testLatency() {
// we'll just register for call back right here and unregister in the callback.
context.JK.FtueWizard.latencyTimeout = true;
var cbFunc = 'JK.ftueLatencyCallback';
logger.debug("Registering latency callback: " + cbFunc);
jamClient.FTUERegisterLatencyCallback('JK.ftueLatencyCallback');
await jamClient.FTUERegisterLatencyCallback('JK.ftueLatencyCallback');
var now = new Date();
logger.debug("Starting Latency Test..." + now);
context.setTimeout(latencyTimeoutCheck, 300 * 1000); // Timeout to 5 minutes
jamClient.FTUEStartLatency();
await jamClient.FTUEStartLatency();
}
function openASIOControlPanel(evt) {
async function openASIOControlPanel(evt) {
if (win32) {
logger.debug("Calling FTUEOpenControlPanel()");
jamClient.FTUEOpenControlPanel();
await jamClient.FTUEOpenControlPanel();
}
}
function asioResync(evt) {
jamClient.FTUERefreshDevices();
async function asioResync(evt) {
await jamClient.FTUERefreshDevices();
ftueSave(false);
}
function ftueSave(persist) {
async function ftueSave(persist) {
// Explicitly set inputs and outputs to dropdown values
// before save as the client seems to want this on changes to
// things like frame size, etc..
var $audioSelects = $('[layout-wizard-step="2"] .settings-controls select');
$.each($audioSelects, function (index, value) {
$.each($audioSelects, async function (index, value) {
var $select = $(value);
setAudioDevice($select);
});
@ -341,16 +342,16 @@
// that we're using music for voice-chat.
if ($('[layout-wizard-step="2"] select[data-device="voice-chat-input"]').val()) {
// Voice input selected
jamClient.TrackSetChatEnable(true);
await jamClient.TrackSetChatEnable(true);
} else {
// No voice input selected.
jamClient.TrackSetChatEnable(false);
await jamClient.TrackSetChatEnable(false);
}
setDefaultInstrumentFromProfile();
logger.debug("Calling FTUESave(" + persist + ")");
var response = jamClient.FTUESave(persist);
var response = await jamClient.FTUESave(persist);
//setLevels(0);
if (response) {
logger.warn(response);
@ -363,33 +364,33 @@
}
}
function setAsioFrameSize(evt) {
async function setAsioFrameSize(evt) {
var val = parseFloat($(evt.currentTarget).val(), 10);
if (isNaN(val)) {
return;
}
logger.debug("Calling FTUESetFrameSize(" + val + ")");
jamClient.FTUESetFrameSize(val);
await jamClient.FTUESetFrameSize(val);
ftueSave(false);
}
function setAsioInputLatency(evt) {
async function setAsioInputLatency(evt) {
var val = parseInt($(evt.currentTarget).val(), 10);
if (isNaN(val)) {
return;
}
logger.debug("Calling FTUESetInputLatency(" + val + ")");
jamClient.FTUESetInputLatency(val);
await jamClient.FTUESetInputLatency(val);
ftueSave(false);
}
function setAsioOutputLatency(evt) {
async function setAsioOutputLatency(evt) {
var val = parseInt($(evt.currentTarget).val(), 10);
if (isNaN(val)) {
return;
}
logger.debug("Calling FTUESetOutputLatency(" + val + ")");
jamClient.FTUESetOutputLatency(val);
await jamClient.FTUESetOutputLatency(val);
ftueSave(false);
}
@ -402,8 +403,8 @@
return false;
}
function videoLinkClicked(evt) {
var myOS = jamClient.GetOSAsString();
async function videoLinkClicked(evt) {
var myOS = await jamClient.GetOSAsString();
var link;
if (myOS === 'MacOSX') {
link = $(evt.currentTarget).attr('external-link-mac');
@ -411,7 +412,7 @@
link = $(evt.currentTarget).attr('external-link-win');
}
if (link) {
context.jamClient.OpenSystemBrowser(link);
await context.jamClient.OpenSystemBrowser(link);
}
}
@ -449,7 +450,7 @@
* This function loads the available audio devices from jamClient, and
* builds up the select dropdowns in the audio-settings step of the FTUE wizard.
*/
function loadAudioDevices() {
async function loadAudioDevices() {
var funcs = [
jamClient.FTUEGetMusicInputs,
jamClient.FTUEGetChatInputs,
@ -461,13 +462,13 @@
'[layout-wizard-step="2"] .audio-output select'
];
var optionsHtml = '';
var deviceOptionFunc = function (deviceKey, index, list) {
var deviceOptionFunc = async function (deviceKey, index, list) {
optionsHtml += '<option title="' + devices[deviceKey] + '" value="' + deviceKey + '">' + devices[deviceKey] + '</option>';
};
for (var i = 0; i < funcs.length; i++) {
optionsHtml = '<option selected="selected" value="">Choose...</option>';
var devices = funcs[i](); // returns hash of device id: device name
var devices = await funcs[i](); // returns hash of device id: device name
var $select = $(selectors[i]);
$select.empty();
var sortedDeviceKeys = context._.keys(devices).sort();
@ -481,8 +482,8 @@
$('#asio-input-latency').val('0').change();
$('#asio-output-latency').val('0').change();
// Special-case for a non-ASIO device, set to 1
if (jamClient.GetOSAsString() === "Win32") { // Limit this check to Windows only.
if (!(jamClient.FTUEHasControlPanel())) {
if (await jamClient.GetOSAsString() === "Win32") { // Limit this check to Windows only.
if (!(await jamClient.FTUEHasControlPanel())) {
$('#asio-input-latency').val('1').change();
$('#asio-output-latency').val('1').change();
}
@ -493,9 +494,9 @@
/**
* Load available drivers and populate the driver select box.
*/
function loadAudioDrivers() {
var drivers = context.jamClient.FTUEGetDevices(false);
var chatDrivers = jamClient.FTUEGetChatInputs(false, false);
async function loadAudioDrivers() {
var drivers = await context.jamClient.FTUEGetDevices(false);
var chatDrivers = await jamClient.FTUEGetChatInputs(false, false);
var optionsHtml = '<option selected="selected" value="">Choose...</option>';
var chatOptionsHtml = '<option selected="selected" value="">Choose...</option>';
@ -558,7 +559,7 @@
/**
* Handler for the new FTUE save button.
*/
function newFtueSaveSettingsHandler(evt) {
async function newFtueSaveSettingsHandler(evt) {
evt.preventDefault();
var $saveButton = $('#btn-ftue-2-save');
if ($saveButton.hasClass('disabled')) {
@ -576,8 +577,8 @@
setDefaultInstrumentFromProfile();
logger.debug("Calling FTUESave(" + true + ")");
jamClient.FTUESave(true);
jamClient.FTUESetStatus(true); // No FTUE wizard next time
await jamClient.FTUESave(true);
await jamClient.FTUESetStatus(true); // No FTUE wizard next time
rest.userCertifiedGear({success: true});
// notify anyone curious about how it went
$('div[layout-id=ftue]').trigger('ftue_success');
@ -585,7 +586,7 @@
app.layout.closeDialog('ftue');
if (app.afterFtue) {
// If there's a function to invoke, invoke it.
app.afterFtue();
await app.afterFtue();
app.afterFtue = null;
app.cancelFtue = null;
}
@ -607,7 +608,7 @@
// { latency: 11.1875, latencyknown: true, latencyvar: 1}
function newFtueAudioDeviceChanged(evt) {
releaseDropdown(function () {
releaseDropdown(async function () {
renderStartNewFtueLatencyTesting();
var $select = $(evt.currentTarget);
@ -615,12 +616,12 @@
var $voiceSelect = $('.ftue-new .settings-2-voice select');
var audioDriverId = $audioSelect.val();
var voiceDriverId = $voiceSelect.val();
jamClient.FTUESetMusicDevice(audioDriverId);
jamClient.FTUESetChatInput(voiceDriverId);
await jamClient.FTUESetMusicDevice(audioDriverId);
await jamClient.FTUESetChatInput(voiceDriverId);
if (voiceDriverId) { // Let the back end know whether a voice device is selected
jamClient.TrackSetChatEnable(true);
await jamClient.TrackSetChatEnable(true);
} else {
jamClient.TrackSetChatEnable(false);
await jamClient.TrackSetChatEnable(false);
}
if (!audioDriverId) {
console.log("no audio driver ID");
@ -629,8 +630,8 @@
newFtueEnableControls(false);
return;
}
var musicInputs = jamClient.FTUEGetMusicInputs();
var musicOutputs = jamClient.FTUEGetMusicOutputs();
var musicInputs = await jamClient.FTUEGetMusicInputs();
var musicOutputs = await jamClient.FTUEGetMusicOutputs();
// set the music input to the first available input,
// and output to the first available output
@ -649,8 +650,8 @@
}
var result;
if (kin && kout) {
jamClient.FTUESetMusicInput(kin);
jamClient.FTUESetMusicOutput(kout);
await jamClient.FTUESetMusicInput(kin);
await jamClient.FTUESetMusicOutput(kout);
} else {
// TODO FIXME - how to handle a driver selection where we are unable to
// autoset both inputs and outputs? (I'd think this could happen if either
@ -680,22 +681,22 @@
renderVolumes();
logger.debug("Calling FTUESave(" + false + ")");
jamClient.FTUESave(false)
await jamClient.FTUESave(false)
pendingFtueSave = false; // this is not really used in any real fashion. just setting back to false due to batch modify above
setVuCallbacks();
var latency = jamClient.FTUEGetExpectedLatency();
var latency = await jamClient.FTUEGetExpectedLatency();
console.log("FTUEGetExpectedLatency: %o", latency);
newFtueUpdateLatencyView(latency);
});
}
function newFtueSave(persist) {
async function newFtueSave(persist) {
logger.debug("newFtueSave persist(" + persist + ")")
newFtueUpdateLatencyView('loading');
logger.debug("Calling FTUESave(" + persist + ")");
jamClient.FTUESave(persist);
await jamClient.FTUESave(persist);
var latency = jamClient.FTUEGetExpectedLatency();
newFtueUpdateLatencyView(latency);
}
@ -709,7 +710,7 @@
}
// simply tells backend what frontend shows in the UI
function newFtueAsioFrameSizeToBackend($input) {
async function newFtueAsioFrameSizeToBackend($input) {
var val = parseFloat($input.val(), 10);
if (isNaN(val)) {
logger.warn("unable to get value from framesize input: %o", $input.val());
@ -738,35 +739,35 @@
logger.debug("Defaulting WDM input/output");
logger.debug("Calling FTUESetInputLatency(" + defaultInput + ")");
jamClient.FTUESetInputLatency(defaultInput);
await jamClient.FTUESetInputLatency(defaultInput);
logger.debug("Calling FTUESetOutputLatency(" + defaultOutput + ")");
jamClient.FTUESetOutputLatency(defaultOutput);
await jamClient.FTUESetOutputLatency(defaultOutput);
}
logger.debug("Calling FTUESetFrameSize(" + val + ")");
jamClient.FTUESetFrameSize(val);
await jamClient.FTUESetFrameSize(val);
return true;
}
function newFtueAsioInputLatencyToBackend($input) {
async function newFtueAsioInputLatencyToBackend($input) {
var val = parseInt($input.val(), 10);
if (isNaN(val)) {
logger.warn("unable to get value from input latency input: %o", $input.val());
return false;
}
logger.debug("Calling FTUESetInputLatency(" + val + ")");
jamClient.FTUESetInputLatency(val);
await jamClient.FTUESetInputLatency(val);
return true;
}
function newFtueAsioOutputLatencyToBackend($input) {
async function newFtueAsioOutputLatencyToBackend($input) {
var val = parseInt($input.val(), 10);
if (isNaN(val)) {
logger.warn("unable to get value from output latency input: %o", $input.val());
return false;
}
logger.debug("Calling FTUESetOutputLatency(" + val + ")");
jamClient.FTUESetOutputLatency(val);
await jamClient.FTUESetOutputLatency(val);
return true;
}
@ -835,8 +836,9 @@
}
}
function isWDM() {
return jamClient.GetOSAsString() === "Win32" && !jamClient.FTUEHasControlPanel();
async function isWDM() {
let [osaStr, controlPanel] = await Promise.all([jamClient.GetOSAsString(), jamClient.FTUEHasControlPanel()])
return (osaStr === "Win32" && !controlPanel);
}
// Based on OS and Audio Hardware, set Frame/Buffer settings appropriately
@ -942,10 +944,10 @@
}
}
function audioDriverChanged(evt) {
async function audioDriverChanged(evt) {
var $select = $(evt.currentTarget);
currentAudioDriverId = $select.val();
jamClient.FTUESetMusicDevice(currentAudioDriverId);
await jamClient.FTUESetMusicDevice(currentAudioDriverId);
loadAudioDevices();
setAsioSettingsVisibility();
checkValidStateForTesting();
@ -980,13 +982,13 @@
return (audioInput && audioOutput);
}
function setVuCallbacks() {
jamClient.FTUERegisterVUCallbacks(
async function setVuCallbacks() {
await jamClient.FTUERegisterVUCallbacks(
"JK.ftueAudioOutputVUCallback",
"JK.ftueAudioInputVUCallback",
"JK.ftueChatInputVUCallback"
);
jamClient.SetVURefreshRate(200);
await jamClient.SetVURefreshRate(200);
}
function setAsioSettingsVisibility() {
@ -1061,7 +1063,7 @@
};
// Latency Callback
context.JK.ftueLatencyCallback = function (latencyMS) {
context.JK.ftueLatencyCallback = async function (latencyMS) {
// We always show gauge screen if we hit this.
// Clear out the 'timeout' variable.
context.JK.FtueWizard.latencyTimeout = false;
@ -1070,7 +1072,7 @@
context.JK.FtueWizard.latencyMS = latencyMS;
// Unregister callback:
context.jamClient.FTUERegisterLatencyCallback('');
await context.jamClient.FTUERegisterLatencyCallback('');
// Go to 'congrats' screen -- although latency may be too high.
context.JK.app.setWizardStep("6");
};

View File

@ -8,6 +8,8 @@
context.JK = context.JK || {};
var logger = context.JK.logger;
context.JK.isQWebEngine = !!navigator.userAgent.match("(JamKazam)")
context.JK.MIDI_TRACK = 100
context.JK.CLIENT_ROLE = {

View File

@ -56,6 +56,28 @@
});
}
// function createScheduledSessionPromise(options) {
// return new Promise((resolve, reject) => {
// $.ajax({
// type: "POST",
// dataType: "json",
// contentType: 'application/json',
// url: "/api/sessions",
// processData: false,
// data: JSON.stringify(options)
// })
// .done(resp => {
// console.log("Session created", resp);
// resolve(resp)
// })
// .fail(error => {
// console.log("Session create error", error);
// reject(error)
// })
// })
// }
function getBroadcastNotification(options) {
var userId = getId(options);
return $.ajax({
@ -131,6 +153,29 @@
});
}
function joinSessionPromise(options) {
console.log('joinSessionOpts', options);
var sessionId = options["session_id"];
delete options["session_id"];
return new Promise(function(resolve, reject){
$.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/" + sessionId + "/participants",
data: JSON.stringify(options),
processData: false
})
.done(function(resp){
resolve(resp);
})
.fail(function(xhr){
reject(xhr)
})
})
}
function cancelSession(options) {
var sessionId = options["session_id"];
delete options["session_id"];
@ -220,6 +265,26 @@
});
}
function getSessionHistoryPromise(id, includePending) {
var includeFlag = 'false';
if (includePending) {
includeFlag = 'true';
}
return new Promise(function(resolve, reject){
$.ajax({
type: "GET",
dataType: "json",
url: '/api/sessions/' + id + '/history?includePending=' + includeFlag,
contentType: 'application/json',
processData: false
}).done(function(resp){
resolve(resp)
}).fail(function(err){
reject(err)
})
})
}
function addSessionInfoComment(sessionId, comment) {
return $.ajax({
url: '/api/sessions/' + sessionId + "/details/comments",
@ -1113,17 +1178,24 @@
})
}
function getUserSyncs(options) {
async function getUserSyncs(options) {
if (!options) {
options = {};
}
var userId = getId(options)
return $.ajax({
type: 'GET',
dataType: "json",
url: "/api/users/" + userId + "/syncs?" + $.param(options),
processData: false
})
try {
return await $.ajax({
type: 'GET',
dataType: "json",
url: "/api/users/" + userId + "/syncs?" + $.param(options),
processData: false
})
} catch (error) {
console.error(error);
throw(error)
}
}
function getUserSync(options) {
@ -1302,6 +1374,23 @@
})
}
function startRecordingPromise(options) {
return new Promise(function(resolve, reject){
$.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/recordings/start",
data: JSON.stringify(options)
}).done(function(resp){
resolve(resp)
}).fail(function(jqXHR){
reject(jqXHR)
})
})
}
function stopRecording(options) {
var recordingId = options["id"]
@ -1362,6 +1451,22 @@
});
}
function getRecordingPromise(options) {
return new Promise(function(resolve, reject){
var recordingId = options["id"];
$.ajax({
type: "GET",
dataType: "json",
contentType: 'application/json',
url: "/api/recordings/" + recordingId
}).done(function(resp){
resolve(resp)
}).fail(function(jqXHR){
reject(jqXHR)
});
})
}
function getClaimedRecordings(options) {
return $.ajax({
type: "GET",
@ -1372,6 +1477,23 @@
});
}
function getClaimedRecordingsPromise(options) {
return new Promise(function(resolve, reject){
$.ajax({
type: "GET",
dataType: "json",
contentType: 'application/json',
url: "/api/claimed_recordings",
data: options
}).done(function(data, textStatus, jqXHR){
resolve([data, textStatus, jqXHR]);
}).fail(function(jqXHR, textStatus, errorMessage){
reject([jqXHR, textStatus, errorMessage]);
});
});
}
function getClaimedRecording(id) {
return $.ajax({
type: "GET",
@ -1404,11 +1526,11 @@
function deleteRecordingClaim(id) {
return $.ajax({
type: "DELETE",
dataType: "json",
contentType: 'application/json',
url: "/api/recordings/" + id + "/claim"
});
type: "DELETE",
dataType: "json",
contentType: 'application/json',
url: "/api/recordings/" + id + "/claim"
});
}
function claimRecording(options) {
@ -1429,13 +1551,22 @@
delete options["id"];
delete options["claimed_recording_id"];
return $.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/" + musicSessionId + "/claimed_recording/" + claimedRecordingId + "/start",
data: JSON.stringify(options)
return new Promise(function(resolve, reject){
$.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/" + musicSessionId + "/claimed_recording/" + claimedRecordingId + "/start",
data: JSON.stringify(options)
})
.done(function(resp){
resolve(resp);
}).fail(function(jqXHR){
reject(jqXHR)
})
})
}
function stopPlayClaimedRecording(options) {
@ -1456,13 +1587,20 @@
function openBackingTrack(options) {
var musicSessionId = options["id"];
delete options["id"];
return $.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/" + musicSessionId + "/backing_tracks/open",
data: JSON.stringify(options)
return new Promise(function(resolve, reject){
$.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/" + musicSessionId + "/backing_tracks/open",
data: JSON.stringify(options)
})
.done(function(resp){
resolve(resp);
})
.fail(function(xhr){
reject(xhr)
})
})
}
@ -1611,13 +1749,20 @@
function closeMetronome(options) {
var musicSessionId = options["id"];
delete options["id"];
return $.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/" + musicSessionId + "/metronome/close",
data: JSON.stringify(options)
return new Promise((resolve, reject) => {
$.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/sessions/" + musicSessionId + "/metronome/close",
data: JSON.stringify(options)
})
.done((resp) => {
resolve(resp)
})
.fail(jqXHR => {
reject(jqXHR);
})
})
}
@ -2968,6 +3113,7 @@
this.quietBroadcastNotification = quietBroadcastNotification;
this.legacyJoinSession = legacyJoinSession;
this.joinSession = joinSession;
this.joinSessionPromise = joinSessionPromise;
this.cancelSession = cancelSession;
this.updateScheduledSession = updateScheduledSession;
this.getUserDetail = getUserDetail;
@ -3047,11 +3193,13 @@
this.updateJoinRequest = updateJoinRequest;
this.updateUser = updateUser;
this.startRecording = startRecording;
this.startRecordingPromise = startRecordingPromise;
this.stopRecording = stopRecording;
this.getRecording = getRecording;
this.getRecordedTrack = getRecordedTrack;
this.getRecordedBackingTrack = getRecordedBackingTrack;
this.getClaimedRecordings = getClaimedRecordings;
this.getClaimedRecordingsPromise = getClaimedRecordingsPromise;
this.getClaimedRecording = getClaimedRecording;
this.updateClaimedRecording = updateClaimedRecording;
this.deleteClaimedRecording = deleteClaimedRecording;
@ -3216,6 +3364,9 @@
this.listInvoices = listInvoices;
this.getVideoConferencingRoomUrl = getVideoConferencingRoomUrl;
this.getLatencyToUsers = getLatencyToUsers;
this.getSessionHistoryPromise = getSessionHistoryPromise;
this.getRecordingPromise = getRecordingPromise;
return this;
};
})(window, jQuery);

View File

@ -91,8 +91,8 @@
/**
* This occurs when a new download from a recording has become available
*/
function downloadAvailable() {
context.jamClient.OnDownloadAvailable();
async function downloadAvailable() {
await context.jamClient.OnDownloadAvailable();
}
/**
@ -406,19 +406,18 @@
context.JK.JamServer.updateNotificationSeen(notificationId, notificationCreatedAt);
}
this.unloadFunction = function () {
this.unloadFunction = async function () {
logger.debug("window.unload function called.");
context.JK.JamServer.close(false);
if (context.jamClient) {
// Unregister for callbacks.
context.jamClient.RegisterRecordingCallbacks("", "", "", "", "");
context.jamClient.SessionRegisterCallback("");
context.jamClient.SessionSetAlertCallback("");
context.jamClient.FTUERegisterVUCallbacks("", "", "");
context.jamClient.FTUERegisterLatencyCallback("");
context.jamClient.RegisterVolChangeCallBack("");
await context.jamClient.RegisterRecordingCallbacks("", "", "", "", "");
await context.jamClient.SessionSetAlertCallback("");
await context.jamClient.FTUERegisterVUCallbacks("", "", "");
await context.jamClient.FTUERegisterLatencyCallback("");
await context.jamClient.RegisterVolChangeCallBack("");
}
};
@ -475,6 +474,9 @@
this.clientId = null;
this.initialRouting = initialRouting;
//video server
this.videoIsOngoing = false;
$(document).triggerHandler('JAMKAZAM_CONSTRUCTED', {app:this})
return this;
};

View File

@ -85,6 +85,7 @@
//= require ../web/affiliate_program
//= require ../web/affiliate_links
//= require fakeJamClient
//= require fakeJamClientProxy
//= require fakeJamClientMessages
//= require fakeJamClientRecordings
//= require JamServer

View File

@ -43,10 +43,10 @@
url: url,
data: JSON.stringify(data),
processData:false,
success: function(response) {
success: async function(response) {
context.JK.Sessions.JoinSession(session_id);
if (client !== undefined) {
client.JoinSession({ sessionID: session_id });
await client.JoinSession({ sessionID: session_id });
}
context.JK.refreshMusicSession(session_id);
},

View File

@ -38,7 +38,7 @@
var value = options.mode;
setValue(options.mode, $parent)
function onModeSelected() {
async function onModeSelected() {
var $li = $(this);
var playbackMode = $li.attr('data-playback-option');
@ -50,7 +50,7 @@
else {
// if no playback mode, then this must be an attempt to open metronome window
close();
context.jamClient.SessionShowMetronomeGui();
await context.jamClient.SessionShowMetronomeGui();
}
return false;
};

View File

@ -21,10 +21,10 @@
$.ajax({
type: "DELETE",
url: url
}).done(function (response) {
}).done(async function (response) {
context.JK.Sessions.LeaveSession(session_id);
if (client !== undefined) {
client.LeaveSession({ sessionID: session_id });
await client.LeaveSession({ sessionID: session_id });
}
});
};

View File

@ -254,9 +254,10 @@ context.JK.MusicianSearchFilter = class MusicianSearchFilter extends BaseSearchF
super()
loadSearchFilter: (sFilter) =>
super(sFilter)
@searchFilter = JSON.parse(sFilter)
@searchFilter = JSON.parse(sFilter)
args =
interests: this.filterData().interests
skill_level: this.filterData().skill_level
@ -822,7 +823,7 @@ context.JK.BandSearchFilter = class BandSearchFilter extends BaseSearchFilter
context.JK.bindHoverEvents()
return
_bindFollowBand: () =>
objThis = this
@screen.find('.search-m-follow').on 'click', (evt) ->

View File

@ -641,13 +641,13 @@
}
if(!clientType) {
clientType = context.JK.clientType();
context.JK.clientType().then(resp => clientType = resp).catch(error => logger.error('Error fetching clientType', error));
}
if(!mode) {
mode = 'client'
if (context.jamClient && context.jamClient.getOperatingMode) {
mode = context.jamClient.getOperatingMode()
}
//if (context.jamClient && context.jamClient.getOperatingMode) {
context.jamClient.getOperatingMode().then(resp => mode = resp).catch(error => logger.error('Error fetching operatingMode', error));
//}
isLatencyTesterMode = mode == 'server';
}
@ -670,9 +670,11 @@
if (isClientMode()) {
var client_type = context.JK.clientType()
var client_type;
context.JK.clientType().then(resp => client_type = resp).catch(error => logger.error('Error fetching clientType', error));
var client_id = (gon.global.env == "development" ? $.cookie('client_id') : null)
var machine = context.jamClient.SessionGetMacHash()
var machine;
context.jamClient.SessionGetMacHash().then(resp => machine = resp).catch(error => logger.error('Error fetching machine', error));
if (machine) {
machine = machine.all
}
@ -927,7 +929,7 @@
}
// Callbacks from jamClient
if (context.jamClient !== undefined && context.jamClient.IsNativeClient()) {
if (context.JK.isQWebEngine) {
context.jamClient.SendP2PMessage.connect(server.sendP2PMessage);
if (context.jamClient.SendLogin) {

View File

@ -18,6 +18,7 @@
//= require modern/JamServer_copy
//= require fakeJamClient
//= require fakeJamClientProxy
//= require fakeJamClientMessages
//= require fakeJamClientRecordings

View File

@ -229,10 +229,10 @@
$testScoreVideo.removeClass('testing');
}
function postDiagnostic() {
async function postDiagnostic() {
rest.createDiagnostic({
type: 'NETWORK_TEST_RESULT',
data: {client_type: context.JK.clientType(), client_id: context.JK.JamServer.clientID, summary: testSummary}
data: {client_type: 'client', client_id: context.JK.JamServer.clientID, summary: testSummary}
});
}
@ -249,8 +249,8 @@
return lastNetworkFailure;
}
function haltScoring() {
context.jamClient.SetLatencyTestBlocked(true)
async function haltScoring() {
await context.jamClient.SetLatencyTestBlocked(true)
rest.updateNetworkTesting({client_id: app.clientId, is_network_testing: true})
.fail(function(jqXHR) {
@ -264,8 +264,8 @@
})
}
function resumeScoring() {
context.jamClient.SetLatencyTestBlocked(false)
async function resumeScoring() {
await context.jamClient.SetLatencyTestBlocked(false)
rest.updateNetworkTesting({client_id: app.clientId, is_network_testing: false})
.fail(function(jqXHR) {
if(jqXHR.status == 404) {
@ -284,7 +284,7 @@
}
}
function testFinishedAudio() {
async function testFinishedAudio() {
var attempt = getCurrentAttemptAudio();
if (!testSummary.final) {
@ -302,13 +302,13 @@
}
// context.jamClient.GetNetworkTestScore() == 0 is a rough approximation if the user has passed the FTUE before
if (inGearWizard || context.jamClient.GetNetworkTestScore() == 0) {
if (inGearWizard || await context.jamClient.GetNetworkTestScore() == 0) {
trackedPass = true;
lastNetworkFailure = null;
context.JK.GA.trackNetworkTest(context.JK.detectOS(), testSummary.final.num_clients);
}
context.jamClient.SetNetworkTestScore(attempt.num_clients);
await context.jamClient.SetNetworkTestScore(attempt.num_clients);
if (testSummary.final.num_clients == 2) {
$testScoreAudio.addClass('acceptable');
}
@ -318,12 +318,12 @@
success = true;
}
else if (reason == "minimum_client_threshold") {
context.jamClient.SetNetworkTestScore(0);
await context.jamClient.SetNetworkTestScore(0);
renderStopTestAudio('', "We're sorry, but your router and Internet service will not effectively support JamKazam sessions. Please click the HELP button for more information.")
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.bandwidth, avgBandwidth(attempt.num_clients - 1));
}
else if (reason == "unreachable" || reason == "no-transmit") {
context.jamClient.SetNetworkTestScore(0);
await context.jamClient.SetNetworkTestScore(0);
// https://jamkazam.atlassian.net/browse/VRFS-2323
renderStopTestAudio('', "We're sorry, but your router will not support JamKazam in its current configuration. Please click <a rel='external' href='https://jamkazam.desk.com/customer/portal/articles/1716139-what-to-do-if-you-cannot-pass-the-network-test'>HERE</a> for more information.");
storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.stun, attempt.num_clients);
@ -415,7 +415,7 @@
}
}
function testFinishedVideo() {
async function testFinishedVideo() {
var attempt = getCurrentAttemptVideo();
@ -440,13 +440,13 @@
}
// context.jamClient.GetNetworkTestScore() == 0 is a rough approximation if the user has passed the FTUE before
if (inGearWizard || context.jamClient.GetVideoNetworkTestScore() == 0) {
if (inGearWizard || await context.jamClient.GetVideoNetworkTestScore() == 0) {
//trackedPass = true;
//lastNetworkFailure = null;
//context.JK.GA.trackNetworkTest(context.JK.detectOS(), testSummary.final.num_clients);
}
context.jamClient.SetVideoNetworkTestScore(attempt.num_clients);
await context.jamClient.SetVideoNetworkTestScore(attempt.num_clients);
if (!testSummary.video_final.num_clients) {
$testScoreVideo.addClass('acceptable');
}
@ -459,12 +459,12 @@
success = true;
}
else if (reason == "minimum_client_threshold") {
context.jamClient.SetVideoNetworkTestScore(testSummary.video_final.num_clients - 1);
await context.jamClient.SetVideoNetworkTestScore(testSummary.video_final.num_clients - 1);
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason)
//storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.bandwidth, avgBandwidth(attempt.num_clients - 1));
}
else if (reason == "unreachable" || reason == "no-transmit") {
context.jamClient.SetVideoNetworkTestScore(testSummary.video_final.num_clients - 1);
await context.jamClient.SetVideoNetworkTestScore(testSummary.video_final.num_clients - 1);
// https://jamkazam.atlassian.net/browse/VRFS-2323
renderStopTestVideo(testSummary.video_final.num_clients - 1, reason);
// storeLastNetworkFailure(context.JK.GA.NetworkTestFailReasons.stun, attempt.num_clients);
@ -664,7 +664,7 @@
}, (gon.ftue_network_test_duration + 5) * 1000);
}
function attemptTestPassAudio() {
async function attemptTestPassAudio() {
var attempt = {};
attempt.payload_size = AUDIO_PAYLOAD_SIZE;
@ -687,14 +687,14 @@
audioScoring = true;
logger.debug("network test attempt: " + numClientToTestAudio + "-person audio session, 400 packets/s, " + AUDIO_PAYLOAD_SIZE + " byte payload")
context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(false), createTimeoutCallbackName(false),
await context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(false), createTimeoutCallbackName(false),
NETWORK_TEST_TYPES.PktTest400LowLatency,
gon.ftue_network_test_duration,
numClientToTestAudio - 1,
AUDIO_PAYLOAD_SIZE, gon.global.ftue_network_test_backend_retries);
}
function attemptTestPassVideo() {
async function attemptTestPassVideo() {
var attempt = {};
attempt.payload_size = VIDEO_PAYLOAD_SIZE;
@ -715,7 +715,7 @@
setBackendGuard();
logger.debug("network test attempt: " + numClientToTestVideo + "-person video session, 400 packets/s, " + VIDEO_PAYLOAD_SIZE + " byte payload")
context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(false), createTimeoutCallbackName(false),
await context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(false), createTimeoutCallbackName(false),
NETWORK_TEST_TYPES.PktTest400LowLatency,
gon.ftue_network_test_duration,
numClientToTestVideo - 1,
@ -723,13 +723,13 @@
}
// you have to score a little to 'prime' the logic to know whether it's on wireless or not
function primePump() {
async function primePump() {
audioScoring = true;
primeDeferred = new $.Deferred();
setPrimeGuard();
context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(true), createTimeoutCallbackName(true),
await context.jamClient.TestNetworkPktBwRate(serverClientId, createSuccessCallbackName(true), createTimeoutCallbackName(true),
NETWORK_TEST_TYPES.PktTest400LowLatency,
PRIME_PUMP_TIME,
2,
@ -746,9 +746,9 @@
$self.triggerHandler(NETWORK_TEST_CANCEL)
}
function postPumpRun() {
async function postPumpRun() {
// check if on Wifi 1st
var isWireless = context.jamClient.IsMyNetworkWireless();
var isWireless = await context.jamClient.IsMyNetworkWireless();
if (isWireless == -1) {
logger.warn("unable to determine if the user is on wireless or not for network test. skipping prompt.")
}
@ -773,8 +773,8 @@
}
}
function pauseForRecentScoresTime() {
var lastScoreTimes = context.jamClient.GetLastLatencyTestTimes()
async function pauseForRecentScoresTime() {
var lastScoreTimes = await context.jamClient.GetLastLatencyTestTimes()
console.log(lastScoreTimes)
@ -1271,7 +1271,7 @@
}
}
function initialize(_$step, _inGearWizard) {
async function initialize(_$step, _inGearWizard) {
$step = _$step;
inGearWizard = _inGearWizard;
@ -1320,7 +1320,7 @@
}).show();
}
operatingSystem = context.JK.GetOSAsString();
operatingSystem = await context.JK.GetOSAsString();
initializeVideoWatchButton();

View File

@ -253,7 +253,7 @@
currentNotificationPage++;
}
function initializeActions(payload, type) {
async function initializeActions(payload, type) {
var $notification = $('li[notification-id=' + payload.notification_id + ']');
var $btnNotificationAction = '#btn-notification-action';
@ -393,13 +393,13 @@
else if (type === context.JK.MessageType.RECORDING_MASTER_MIX_COMPLETE) {
$notification.find('#div-actions').hide();
logger.debug("context.jamClient.OnDownloadAvailable!")
context.jamClient.OnDownloadAvailable(); // poke backend, letting it know a download is available
await context.jamClient.OnDownloadAvailable(); // poke backend, letting it know a download is available
}
else if (type === context.JK.MessageType.JAM_TRACK_SIGN_COMPLETE) {
$notification.find('#div-actions').hide();
logger.debug("context.jamClient.OnDownloadAvailable!")
context.jamClient.OnDownloadAvailable(); // poke backend, letting it know a download is available
await context.jamClient.OnDownloadAvailable(); // poke backend, letting it know a download is available
}
else if (type === context.JK.MessageType.BAND_INVITATION) {
@ -592,7 +592,7 @@
function registerJoinRequest() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.JOIN_REQUEST, function(header, payload) {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.JOIN_REQUEST, async function(header, payload) {
logger.debug("Handling JOIN_REQUEST msg " + JSON.stringify(payload));
handleNotification(payload, header.type);

View File

@ -41,9 +41,9 @@
var working = paginator.data('working');
if(!working) {
paginator.data('working', true);
onPageSelected(targetPage)
.done(function(data, textStatus, jqXHR) {
.then(function(data, textStatus, jqXHR) {
totalEntries = data.total_entries || parseInt(jqXHR.getResponseHeader('total-entries'));
pages = calculatePages(totalEntries, perPage);
options = { pages: pages,
@ -54,8 +54,10 @@
registerEvents(newPaginator);
paginator.replaceWith(newPaginator);
paginator = newPaginator;
paginator.data('working', false);
})
.always(function() {
.catch(function(err){
paginator.data('working', false);
});
}

View File

@ -303,7 +303,7 @@
}
}
function monitorRecordingPlayback() {
async function monitorRecordingPlayback() {
if (!monitoring) {
return;
}
@ -312,10 +312,10 @@
}
else {
if (playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK) {
var positionMs = context.jamClient.SessionCurrrentJamTrackPlayPosMs();
var duration = context.jamClient.SessionGetJamTracksPlayDurationMs();
var positionMs = await context.jamClient.SessionCurrrentJamTrackPlayPosMs();
var duration = await context.jamClient.SessionGetJamTracksPlayDurationMs();
var durationMs = duration.media_len;
var isPlaying = context.jamClient.isSessionTrackPlaying();
var isPlaying = await context.jamClient.isSessionTrackPlaying();
}
else if(playbackMonitorMode == PLAYBACK_MONITOR_MODE.BROWSER_MEDIA) {
var positionMs = BrowserMediaStore.onGetPlayPosition() || 0
@ -323,9 +323,9 @@
var isPlaying = BrowserMediaStore.playing;
}
else {
var positionMs = context.jamClient.SessionCurrrentPlayPosMs();
var durationMs = context.jamClient.SessionGetTracksPlayDurationMs();
var isPlaying = context.jamClient.isSessionTrackPlaying();
var positionMs = await context.jamClient.SessionCurrrentPlayPosMs();
var durationMs = await context.jamClient.SessionGetTracksPlayDurationMs();
var isPlaying = await context.jamClient.isSessionTrackPlaying();
}
executeMonitor(positionMs, durationMs, isPlaying)

View File

@ -0,0 +1,430 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebChannel module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
"use strict";
var QWebChannelMessageTypes = {
signal: 1,
propertyUpdate: 2,
init: 3,
idle: 4,
debug: 5,
invokeMethod: 6,
connectToSignal: 7,
disconnectFromSignal: 8,
setProperty: 9,
response: 10,
};
var QWebChannel = function(transport, initCallback)
{
if (typeof transport !== "object" || typeof transport.send !== "function") {
console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." +
" Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send));
return;
}
var channel = this;
this.transport = transport;
this.send = function(data)
{
if (typeof(data) !== "string") {
data = JSON.stringify(data);
}
channel.transport.send(data);
}
this.transport.onmessage = function(message)
{
var data = message.data;
if (typeof data === "string") {
data = JSON.parse(data);
}
switch (data.type) {
case QWebChannelMessageTypes.signal:
channel.handleSignal(data);
break;
case QWebChannelMessageTypes.response:
channel.handleResponse(data);
break;
case QWebChannelMessageTypes.propertyUpdate:
channel.handlePropertyUpdate(data);
break;
default:
console.error("invalid message received:", message.data);
break;
}
}
this.execCallbacks = {};
this.execId = 0;
this.exec = function(data, callback)
{
if (!callback) {
// if no callback is given, send directly
channel.send(data);
return;
}
if (channel.execId === Number.MAX_VALUE) {
// wrap
channel.execId = Number.MIN_VALUE;
}
if (data.hasOwnProperty("id")) {
console.error("Cannot exec message with property id: " + JSON.stringify(data));
return;
}
data.id = channel.execId++;
channel.execCallbacks[data.id] = callback;
channel.send(data);
};
this.objects = {};
this.handleSignal = function(message)
{
var object = channel.objects[message.object];
if (object) {
object.signalEmitted(message.signal, message.args);
} else {
console.warn("Unhandled signal: " + message.object + "::" + message.signal);
}
}
this.handleResponse = function(message)
{
if (!message.hasOwnProperty("id")) {
console.error("Invalid response message received: ", JSON.stringify(message));
return;
}
channel.execCallbacks[message.id](message.data);
delete channel.execCallbacks[message.id];
}
this.handlePropertyUpdate = function(message)
{
for (var i in message.data) {
var data = message.data[i];
var object = channel.objects[data.object];
if (object) {
object.propertyUpdate(data.signals, data.properties);
} else {
console.warn("Unhandled property update: " + data.object + "::" + data.signal);
}
}
channel.exec({type: QWebChannelMessageTypes.idle});
}
this.debug = function(message)
{
channel.send({type: QWebChannelMessageTypes.debug, data: message});
};
channel.exec({type: QWebChannelMessageTypes.init}, function(data) {
for (var objectName in data) {
var object = new QObject(objectName, data[objectName], channel);
}
// now unwrap properties, which might reference other registered objects
for (var objectName in channel.objects) {
channel.objects[objectName].unwrapProperties();
}
if (initCallback) {
initCallback(channel);
}
channel.exec({type: QWebChannelMessageTypes.idle});
});
};
function QObject(name, data, webChannel)
{
this.__id__ = name;
webChannel.objects[name] = this;
// List of callbacks that get invoked upon signal emission
this.__objectSignals__ = {};
// Cache of all properties, updated when a notify signal is emitted
this.__propertyCache__ = {};
var object = this;
// ----------------------------------------------------------------------
this.unwrapQObject = function(response)
{
if (response instanceof Array) {
// support list of objects
var ret = new Array(response.length);
for (var i = 0; i < response.length; ++i) {
ret[i] = object.unwrapQObject(response[i]);
}
return ret;
}
if (!response
|| !response["__QObject*__"]
|| response.id === undefined) {
return response;
}
var objectId = response.id;
if (webChannel.objects[objectId])
return webChannel.objects[objectId];
if (!response.data) {
console.error("Cannot unwrap unknown QObject " + objectId + " without data.");
return;
}
var qObject = new QObject( objectId, response.data, webChannel );
qObject.destroyed.connect(function() {
if (webChannel.objects[objectId] === qObject) {
delete webChannel.objects[objectId];
// reset the now deleted QObject to an empty {} object
// just assigning {} though would not have the desired effect, but the
// below also ensures all external references will see the empty map
// NOTE: this detour is necessary to workaround QTBUG-40021
var propertyNames = [];
for (var propertyName in qObject) {
propertyNames.push(propertyName);
}
for (var idx in propertyNames) {
delete qObject[propertyNames[idx]];
}
}
});
// here we are already initialized, and thus must directly unwrap the properties
qObject.unwrapProperties();
return qObject;
}
this.unwrapProperties = function()
{
for (var propertyIdx in object.__propertyCache__) {
object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]);
}
}
function addSignal(signalData, isPropertyNotifySignal)
{
var signalName = signalData[0];
var signalIndex = signalData[1];
object[signalName] = {
connect: function(callback) {
if (typeof(callback) !== "function") {
console.error("Bad callback given to connect to signal " + signalName);
return;
}
object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
object.__objectSignals__[signalIndex].push(callback);
if (!isPropertyNotifySignal && signalName !== "destroyed") {
// only required for "pure" signals, handled separately for properties in propertyUpdate
// also note that we always get notified about the destroyed signal
webChannel.exec({
type: QWebChannelMessageTypes.connectToSignal,
object: object.__id__,
signal: signalIndex
});
}
},
disconnect: function(callback) {
if (typeof(callback) !== "function") {
console.error("Bad callback given to disconnect from signal " + signalName);
return;
}
object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
var idx = object.__objectSignals__[signalIndex].indexOf(callback);
if (idx === -1) {
console.error("Cannot find connection of signal " + signalName + " to " + callback.name);
return;
}
object.__objectSignals__[signalIndex].splice(idx, 1);
if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) {
// only required for "pure" signals, handled separately for properties in propertyUpdate
webChannel.exec({
type: QWebChannelMessageTypes.disconnectFromSignal,
object: object.__id__,
signal: signalIndex
});
}
}
};
}
/**
* Invokes all callbacks for the given signalname. Also works for property notify callbacks.
*/
function invokeSignalCallbacks(signalName, signalArgs)
{
var connections = object.__objectSignals__[signalName];
if (connections) {
connections.forEach(function(callback) {
callback.apply(callback, signalArgs);
});
}
}
this.propertyUpdate = function(signals, propertyMap)
{
// update property cache
for (var propertyIndex in propertyMap) {
var propertyValue = propertyMap[propertyIndex];
object.__propertyCache__[propertyIndex] = propertyValue;
}
for (var signalName in signals) {
// Invoke all callbacks, as signalEmitted() does not. This ensures the
// property cache is updated before the callbacks are invoked.
invokeSignalCallbacks(signalName, signals[signalName]);
}
}
this.signalEmitted = function(signalName, signalArgs)
{
invokeSignalCallbacks(signalName, signalArgs);
}
function addMethod(methodData)
{
var methodName = methodData[0];
var methodIdx = methodData[1];
object[methodName] = function() {
var args = [];
var callback;
for (var i = 0; i < arguments.length; ++i) {
if (typeof arguments[i] === "function")
callback = arguments[i];
else
args.push(arguments[i]);
}
webChannel.exec({
"type": QWebChannelMessageTypes.invokeMethod,
"object": object.__id__,
"method": methodIdx,
"args": args
}, function(response) {
if (response !== undefined) {
var result = object.unwrapQObject(response);
if (callback) {
(callback)(result);
}
}
});
};
}
function bindGetterSetter(propertyInfo)
{
var propertyIndex = propertyInfo[0];
var propertyName = propertyInfo[1];
var notifySignalData = propertyInfo[2];
// initialize property cache with current value
// NOTE: if this is an object, it is not directly unwrapped as it might
// reference other QObject that we do not know yet
object.__propertyCache__[propertyIndex] = propertyInfo[3];
if (notifySignalData) {
if (notifySignalData[0] === 1) {
// signal name is optimized away, reconstruct the actual name
notifySignalData[0] = propertyName + "Changed";
}
addSignal(notifySignalData, true);
}
Object.defineProperty(object, propertyName, {
configurable: true,
get: function () {
var propertyValue = object.__propertyCache__[propertyIndex];
if (propertyValue === undefined) {
// This shouldn't happen
console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__);
}
return propertyValue;
},
set: function(value) {
if (value === undefined) {
console.warn("Property setter for " + propertyName + " called with undefined value!");
return;
}
object.__propertyCache__[propertyIndex] = value;
webChannel.exec({
"type": QWebChannelMessageTypes.setProperty,
"object": object.__id__,
"property": propertyIndex,
"value": value
});
}
});
}
// ----------------------------------------------------------------------
data.methods.forEach(addMethod);
data.properties.forEach(bindGetterSetter);
data.signals.forEach(function(signal) { addSignal(signal, false); });
for (var name in data.enums) {
object[name] = data.enums[name];
}
}
//required for use with nodejs
if (typeof module === 'object') {
module.exports = {
QWebChannel: QWebChannel
};
}

View File

@ -537,7 +537,7 @@ profileUtils = context.JK.ProfileUtils
context.JK.popExternalLink("/client#/account/paymentHistory", true)
paymentMethod: () ->
if context.jamClient.IsNativeClient()
if context.JK.isQWebEngine
return `<div>
<div classNames="column column-left">
<p>Updating payment is only supported in a web browser. Please click the button below to open this page in your system web browser.</p>

View File

@ -110,7 +110,7 @@ ConfigureTracksStore = @ConfigureTracksStore
</div>
<div className="instrument-selection">
<h3>Instrument</h3>
<select className="instrument-pick" name="instrument" onChange={this.instrumentSelected} value={selectedInstrument} disabled={instrumentDisabled}>
<select className="instrument-pick" name="instrument" onChange={this.audioInstrumentSelected} value={selectedInstrument} disabled={instrumentDisabled}>
{instruments}
</select>
</div>
@ -187,8 +187,8 @@ ConfigureTracksStore = @ConfigureTracksStore
<a className="scan-midi" onClick={this.scanMidi}>scan for connected MIDI interfaces</a>
</div>
<div className="instrument-selection">
<h3>Instrument</h3>
<select className="instrument-pick" name="instrument" onChange={this.instrumentSelected} value={selectedInstrument} disabled={instrumentDisabled}>
<h3>Instrument Display Name</h3>
<select className="midi-instrument-pick" name="instrument" onChange={this.midiInstrumentSelected} value={selectedInstrument} disabled={instrumentDisabled}>
{instruments}
</select>
</div>
@ -204,6 +204,15 @@ ConfigureTracksStore = @ConfigureTracksStore
{initialScan}
{scan}
</div>
<div className="midi-selection-instructions">
<u>Instructions:</u>
<ol>
<li>Select your MIDI interface.</li>
<li>Select your MIDI instrument and set its settings as needed. The instrument is ready to play after you select it, and you can test it.</li>
<li>Select the Instrument you want displayed in the Session window.</li>
<li>Click Add Track, then Save Settings.</li>
</ol>
</div>
</div>`
render: () ->
@ -286,13 +295,30 @@ ConfigureTracksStore = @ConfigureTracksStore
@setState({midiInterface: null})
instrumentSelected: (e) ->
audioInstrumentSelected: (e) ->
$root = $(@getDOMNode())
$select = $root.find('.instrument-pick')
instrumentId = $select.val()
instrumentId = $root.find('.instrument-pick').val()
ConfigureTracksActions.associateInstrumentWithTrack(instrumentId)
midiInstrumentSelected: (e) ->
$root = $(@getDOMNode())
midiInstrumentId = $root.find('.midi-instrument-pick').val()
midiSelVal = $root.find('.midi-select').val()
vstsSelVal = $root.find('.vsts').val()
if midiSelVal == "" || vstsSelVal == "NONE"
context.JK.Banner.showAlert("MIDI interface and MIDI plugin must be selected.")
else
ConfigureTracksActions.associateInstrumentWithTrack(midiInstrumentId)
# instrumentSelected: `async function(e) {
# const $root = $(this.getDOMNode());
# const $select = $root.find('.instrument-pick');
# const instrumentId = $select.val();
# await ConfigureTracksActions.associateInstrumentWithTrack(instrumentId);
# }`
doClose: (e) ->
e.preventDefault()
@ -342,20 +368,41 @@ ConfigureTracksStore = @ConfigureTracksStore
componentWillUpdate: () ->
$root = $(@getDOMNode())
componentDidUpdate: () ->
$root = $(@getDOMNode())
# componentDidUpdate: () ->
# $root = $(@getDOMNode())
$manageAudioPlugins = $root.find('.manage-audio-plugins')
# $manageAudioPlugins = $root.find('.manage-audio-plugins')
unless $manageAudioPlugins.data('initialized')
$manageAudioPlugins.manageVsts().on(context.JK.EVENTS.VST_OPERATION_SELECTED, @vstOperation).data('initialized', true)
# unless $manageAudioPlugins.data('initialized')
# $manageAudioPlugins.manageVsts().on(context.JK.EVENTS.VST_OPERATION_SELECTED, @vstOperation).data('initialized', true)
if true # easyDropdown support
# if true # easyDropdown support
# context.JK.dropdown($root.find('select'))
# $root.find('select.input-selectors').unbind('change').change(@inputChanged)
# $root.find('select.instrument-pick').unbind('change').change(@instrumentSelected)
# $root.find('select.vsts').unbind('change').change(@vstsChanged)
componentDidUpdate: `function() {
const $root = $(this.getDOMNode());
const $manageAudioPlugins = $root.find('.manage-audio-plugins');
if (!$manageAudioPlugins.data('initialized')) {
$manageAudioPlugins.manageVsts().on(context.JK.EVENTS.VST_OPERATION_SELECTED, this.vstOperation).data('initialized', true);
}
if (true) { // easyDropdown support
context.JK.dropdown($root.find('select'));
$root.find('select.input-selectors').unbind('change').change(this.inputChanged);
$root.find('select.instrument-pick').unbind('change').change(this.audioInstrumentSelected);
$root.find('select.midi-instrument-pick').unbind('change').change(this.midiInstrumentSelected);
$root.find('select.vsts').unbind('change').change(this.vstsChanged);
$root.find('select.midi-select').unbind('change').change(this.midiInterfaceChanged);
}
}`
context.JK.dropdown($root.find('select'))
$root.find('select.input-selectors').unbind('change').change(@inputChanged)
$root.find('select.instrument-pick').unbind('change').change(@instrumentSelected)
$root.find('select.vsts').unbind('change').change(@vstsChanged)
trackTypeChanged: (event) ->
if @ignoreICheck
@ -399,7 +446,6 @@ ConfigureTracksStore = @ConfigureTracksStore
midiInterfaceChanged: (e) ->
@updateMidiAssociations()
updateMidiAssociations: (e) ->
@ -411,10 +457,10 @@ ConfigureTracksStore = @ConfigureTracksStore
vstSelected = $select.val()
logger.debug("updateMidiAssocations", vstSelected, midiInterface)
#if vstSelected != 'NONE'
vstSelected = {file: vstSelected}
#else
# vstSelected = null
if vstSelected != 'NONE'
vstSelected = {file: vstSelected}
else
vstSelected = null
if midiInterface == ''
midiInterface = null
@ -438,4 +484,4 @@ ConfigureTracksStore = @ConfigureTracksStore
@setState({midiInterface: midiInterface})
})
})

View File

@ -46,7 +46,7 @@ ConfigureTracksStore = @ConfigureTracksStore
$output1 = $root.find('.output-1')
$output2 = $root.find('.output-2')
if @state.configureTracks? && @state.configureTracks.trackAssignments.outputs.assigned.length == 2
if @state.configureTracks? && @state.configureTracks.trackAssignments && @state.configureTracks.trackAssignments.outputs.assigned.length == 2
output1 = @state.configureTracks.trackAssignments.outputs.assigned[0].id
output2 = @state.configureTracks.trackAssignments.outputs.assigned[1].id

View File

@ -25,15 +25,15 @@ MIDI_TRACK = context.JK.MIDI_TRACK
outputs = []
trackAssignments = @state.configureTracks?.trackAssignments
if gon.midi_enabled
addMidiTrack = `<a onClick={this.openLiveTrackDialog.bind(this, 'midi')} className="button-orange">ADD MIDI TRACK . . . </a>`
if trackAssignments
#console.log("trackAssignments.inputs.assigned", trackAssignments.inputs.assigned)
for inputsForTrack, i in trackAssignments.inputs.assigned
candidate = inputsForTrack[0]
inputs = []
if candidate.assignment == MIDI_TRACK
trackTypeLabel = 'MIDI'
@ -46,14 +46,13 @@ MIDI_TRACK = context.JK.MIDI_TRACK
trackTypeLabel = 'AUDIO'
for input in inputsForTrack
inputs.push(`<div key={i} className="live-input">{input.name}</div>`)
if !inputsForTrack.instrument_id?
instrument = `<span className="none">?</span>`
else
instrument = `<span><img src={context.JK.getInstrumentIconMap24()[inputsForTrack.instrument_id].asset} /></span>`
vstName = 'None'
if inputsForTrack.vst? && inputsForTrack.vst.name != 'NONE'

View File

@ -229,6 +229,13 @@ AppStore = context.AppStore
context.JK.popExternalLink("https://jamkazam.freshdesk.com/support/solutions/articles/66000122535-what-are-jamkazam-s-free-vs-premium-features-")
e.preventDefault()
# comparePlans: `function(e) {
# if (context.JK.clientType() === 'client') {
# context.JK.popExternalLink("https://jamkazam.freshdesk.com/support/solutions/articles/66000122535-what-are-jamkazam-s-free-vs-premium-features-");
# return e.preventDefault();
# }
# }`
render: () ->
plan_codes = []
monthlies = []

View File

@ -370,6 +370,10 @@ SessionUtils = context.JK.SessionUtils
joinLinkClicked: (session) ->
context.JK.SessionUtils.ensureValidClient(AppStore.app, context.JK.GearUtils, @ensuredCallback.bind(this, session.id))
# joinLinkClicked: `async function (session) {
# await context.JK.SessionUtils.ensureValidClient(AppStore.app, context.JK.GearUtils, this.ensuredCallback.bind(this, session.id));
# }`
rsvpLinkClicked: (session) ->
@ui.launchRsvpSubmitDialog(session.id)
.one(EVENTS.RSVP_SUBMITTED, () -> SessionsActions.updateSession.trigger(session.id))
@ -387,6 +391,10 @@ SessionUtils = context.JK.SessionUtils
startSessionNow: (session) ->
@ui.launchSessionStartDialog(session)
# startSessionNow: `async function(session) {
# await this.ui.launchSessionStartDialog(session);
# }`
showStartSessionButton: (scheduledStart) ->
now = new Date()
scheduledDate = new Date(scheduledStart)

View File

@ -37,36 +37,71 @@ context = window
@setState({name: $(e.target).val()})
updateName: (e) ->
e.preventDefault()
# updateName: (e) ->
# e.preventDefault()
# validate
# # validate
name = @root.find('.name').val()
# name = @root.find('.name').val()
characterMatch = /^[^a-z0-9,' -]+$/i
# characterMatch = /^[^a-z0-9,' -]+$/i
if name.length == 0 || name == ''
context.JK.Banner.showAlert('invalid name', 'Please specify a name.')
return
else if name.length < 2
context.JK.Banner.showAlert('invalid name', 'Please specify a name at least 3 characters long.')
return
else if name.length > 63
context.JK.Banner.showAlert('invalid name', 'The name must be less than 64 characters long.')
return
else if characterMatch.test(name)
context.JK.Banner.showAlert('invalid name',
'The can only contain A-Z, 0-9, commas, apostrophes, spaces, or hyphens.')
return
# if name.length == 0 || name == ''
# context.JK.Banner.showAlert('invalid name', 'Please specify a name.')
# return
# else if name.length < 2
# context.JK.Banner.showAlert('invalid name', 'Please specify a name at least 3 characters long.')
# return
# else if name.length > 63
# context.JK.Banner.showAlert('invalid name', 'The name must be less than 64 characters long.')
# return
# else if characterMatch.test(name)
# context.JK.Banner.showAlert('invalid name',
# 'The can only contain A-Z, 0-9, commas, apostrophes, spaces, or hyphens.')
# return
result = context.jamClient.setJBName(name.trim())
# result = context.jamClient.setJBName(name.trim())
# if !result
# context.JK.Banner.showAlert('unable to set the name',
# 'Please email support@jamkazam.com and let us know the name you are specifying unsuccessfully, or refresh the page and try again.')
# else
# @app.layout.closeDialog('jamblaster-name-dialog')
updateName: `async function(e) {
e.preventDefault();
// validate
const name = this.root.find('.name').val();
const characterMatch = /^[^a-z0-9,' -]+$/i;
if ((name.length === 0) || (name === '')) {
context.JK.Banner.showAlert('invalid name', 'Please specify a name.');
return;
} else if (name.length < 2) {
context.JK.Banner.showAlert('invalid name', 'Please specify a name at least 3 characters long.');
return;
} else if (name.length > 63) {
context.JK.Banner.showAlert('invalid name', 'The name must be less than 64 characters long.');
return;
} else if (characterMatch.test(name)) {
context.JK.Banner.showAlert('invalid name',
'The can only contain A-Z, 0-9, commas, apostrophes, spaces, or hyphens.');
return;
}
const result = await context.jamClient.setJBName(name.trim());
if (!result) {
return context.JK.Banner.showAlert('unable to set the name',
'Please email support@jamkazam.com and let us know the name you are specifying unsuccessfully, or refresh the page and try again.');
} else {
return this.app.layout.closeDialog('jamblaster-name-dialog');
}
}`
if !result
context.JK.Banner.showAlert('unable to set the name',
'Please email support@jamkazam.com and let us know the name you are specifying unsuccessfully, or refresh the page and try again.')
else
@app.layout.closeDialog('jamblaster-name-dialog')
render: () ->
`<div>
<div className="content-head">

View File

@ -100,29 +100,57 @@ JamBlasterActions = @JamBlasterActions
e.preventDefault()
@app.layout.closeDialog('jamblaster-pairing-dialog')
pair: (e) ->
e.preventDefault()
# pair: (e) ->
# e.preventDefault()
if @state.pairing
return
# if @state.pairing
# return
@setState({pairing: true, pairStart: new Date().getTime(), timer: 60, pairingTimeout: false, paired: false})
@setTimer(true)
# @setState({pairing: true, pairStart: new Date().getTime(), timer: 60, pairingTimeout: false, paired: false})
# @setTimer(true)
client = @findJamBlaster(this.state.bonjourClientId)
# client = @findJamBlaster(this.state.bonjourClientId)
if client.isPaired
context.JK.Banner.showNotice("JamBlaster already paired", "This JamBlaster is already paired.")
@app.layout.closeDialog("jamblaster-pairing-dialog", true)
else if client?
logger.debug("trying to connect to #{client.connect_url}")
if client.connect_url?
@pairingTimer()
context.jamClient.startPairing(client.connect_url)
else
context.JK.Banner.showAlert("JamBlaster offline", "JamBlaster appears to be offline. Please reboot it.")
else
context.JK.Banner.showAlert("JamBlaster offline", "JamBlaster appears to be offline. Please reboot it.")
# if client.isPaired
# context.JK.Banner.showNotice("JamBlaster already paired", "This JamBlaster is already paired.")
# @app.layout.closeDialog("jamblaster-pairing-dialog", true)
# else if client?
# logger.debug("trying to connect to #{client.connect_url}")
# if client.connect_url?
# @pairingTimer()
# context.jamClient.startPairing(client.connect_url)
# else
# context.JK.Banner.showAlert("JamBlaster offline", "JamBlaster appears to be offline. Please reboot it.")
# else
# context.JK.Banner.showAlert("JamBlaster offline", "JamBlaster appears to be offline. Please reboot it.")
pair: `async function(e) {
e.preventDefault();
if (this.state.pairing) {
return;
}
this.setState({pairing: true, pairStart: new Date().getTime(), timer: 60, pairingTimeout: false, paired: false});
this.setTimer(true);
const client = this.findJamBlaster(this.state.bonjourClientId);
if (client.isPaired) {
context.JK.Banner.showNotice("JamBlaster already paired", "This JamBlaster is already paired.");
return this.app.layout.closeDialog("jamblaster-pairing-dialog", true);
} else if (client != null) {
logger.debug('trying to connect to '+client.connect_url);
if (client.connect_url != null) {
this.pairingTimer();
await context.jamClient.startPairing(client.connect_url);
} else {
context.JK.Banner.showAlert("JamBlaster offline", "JamBlaster appears to be offline. Please reboot it.");
}
} else {
context.JK.Banner.showAlert("JamBlaster offline", "JamBlaster appears to be offline. Please reboot it.");
}
}`
render: () ->

View File

@ -32,31 +32,66 @@ context = window
e.preventDefault()
@app.layout.closeDialog('jamblaster-port-dialog', true);
updatePort: (e) ->
e.preventDefault()
# updatePort: (e) ->
# e.preventDefault()
# validate
# # validate
staticPort = @root.find('.port').val()
# staticPort = @root.find('.port').val()
staticPort = new Number(staticPort);
# staticPort = new Number(staticPort);
console.log("staticPort", staticPort)
if context._.isNaN(staticPort)
@app.layout.notify({title: 'No Settings Have Been Saved!', text: 'Please enter a number from 1026-49150.'})
return
# console.log("staticPort", staticPort)
# if context._.isNaN(staticPort)
# @app.layout.notify({title: 'No Settings Have Been Saved!', text: 'Please enter a number from 1026-49150.'})
# return
if staticPort < 1026 || staticPort >= 65525
@app.layout.notify({title: 'No Settings Have Been Saved!', text: 'Please pick a port from 1026 to 65524.'})
return
# if staticPort < 1026 || staticPort >= 65525
# @app.layout.notify({title: 'No Settings Have Been Saved!', text: 'Please pick a port from 1026 to 65524.'})
# return
result = context.jamClient.setJbPortBindState({use_static_port: true, static_port: staticPort})
# result = context.jamClient.setJbPortBindState({use_static_port: true, static_port: staticPort})
# if !result
# context.JK.Banner.showAlert('unable to set a static port',
# 'Please email support@jamkazam.com and let us know the port number you are specifying unsuccessfully, or refresh the page and try again.')
# else
# @app.layout.closeDialog('jamblaster-port-dialog')
updatePort: `async function(e) {
e.preventDefault();
// validate
const name = this.root.find('.name').val();
const characterMatch = /^[^a-z0-9,' -]+$/i;
if ((name.length === 0) || (name === '')) {
context.JK.Banner.showAlert('invalid name', 'Please specify a name.');
return;
} else if (name.length < 2) {
context.JK.Banner.showAlert('invalid name', 'Please specify a name at least 3 characters long.');
return;
} else if (name.length > 63) {
context.JK.Banner.showAlert('invalid name', 'The name must be less than 64 characters long.');
return;
} else if (characterMatch.test(name)) {
context.JK.Banner.showAlert('invalid name',
'The can only contain A-Z, 0-9, commas, apostrophes, spaces, or hyphens.');
return;
}
const result = await context.jamClient.setJBName(name.trim());
if (!result) {
return context.JK.Banner.showAlert('unable to set the name',
'Please email support@jamkazam.com and let us know the name you are specifying unsuccessfully, or refresh the page and try again.');
} else {
return this.app.layout.closeDialog('jamblaster-name-dialog');
}
}`
if !result
context.JK.Banner.showAlert('unable to set a static port',
'Please email support@jamkazam.com and let us know the port number you are specifying unsuccessfully, or refresh the page and try again.')
else
@app.layout.closeDialog('jamblaster-port-dialog')
render: () ->
`<div>
<div className="content-head">

View File

@ -39,8 +39,6 @@ JamBlasterActions = @JamBlasterActions
@root = $(@getDOMNode())
@iCheckify()
componentDidUpdate: () ->
@iCheckify()
@ -91,65 +89,132 @@ JamBlasterActions = @JamBlasterActions
#context.JK.popExternalLinks(@root)
jamblasterOptionSelected: (e, data) ->
jamblaster = data.options
jamblaster = @findJamBlaster(jamblaster)
# jamblasterOptionSelected: (e, data) ->
# jamblaster = data.options
# jamblaster = @findJamBlaster(jamblaster)
if data.option == 'auto-connect'
JamBlasterActions.setAutoPair(!jamblaster.autoconnect)
else if data.option == 'restart'
context.JK.Banner.showYesNo({
title: "reboot JamBlaster",
html: "Are you sure?"
yes: =>
result = context.jamClient.rebootJamBlaster()
if result
setTimeout((() => context.JK.Banner.showNotice("JamBlaster is rebooting",
"It should be back online within a minute.")), 1)
setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
# if data.option == 'auto-connect'
# JamBlasterActions.setAutoPair(!jamblaster.autoconnect)
# else if data.option == 'restart'
# context.JK.Banner.showYesNo({
# title: "reboot JamBlaster",
# html: "Are you sure?"
# yes: =>
# result = context.jamClient.rebootJamBlaster()
# if result
# setTimeout((() => context.JK.Banner.showNotice("JamBlaster is rebooting",
# "It should be back online within a minute.")), 1)
# setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
else
setTimeout((() => context.JK.Banner.showAlert("could not reboot",
"The JamBlaster could not be rebooted remotely. Please cycle the power manually.")), 1)
# else
# setTimeout((() => context.JK.Banner.showAlert("could not reboot",
# "The JamBlaster could not be rebooted remotely. Please cycle the power manually.")), 1)
})
# })
else if data.option == 'name'
@app.layout.showDialog('jamblaster-name-dialog', {d1: jamblaster.name}).one(context.JK.EVENTS.DIALOG_CLOSED,
(e, data) =>
setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
)
# else if data.option == 'name'
# @app.layout.showDialog('jamblaster-name-dialog', {d1: jamblaster.name}).one(context.JK.EVENTS.DIALOG_CLOSED,
# (e, data) =>
# setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
# )
else if data.option == 'check-for-updates'
context.JK.Banner.showNotice('Check for Update',
'The JamBlaster only checks for updates when booting up. Please reboot the JamBlaster to initiate an update check.')
else if data.option == 'set-static-ports'
if jamblaster.isDynamicPorts
context.JK.Banner.showYesNo({
title: "revert to dynamic ports",
html: "Your JamBlaster is currently configured to use ports #{jamblaster.portState.static_port} - #{jamblaster.portState.static_port + 10}). Would you like to revert to the use of dynamic ports for UDP communication?"
yes: =>
context.jamClient.setJbPortBindState({use_static_port: false, static_port: 12000})
JamBlasterActions.clearPortBindState()
#setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
JamBlasterActions.resyncBonjour()
setTimeout((() => context.JK.Banner.showNotice("reboot JamBlaster",
"For these settings to take effect, you must restart the JamBlaster.")), 1)
# else if data.option == 'check-for-updates'
# context.JK.Banner.showNotice('Check for Update',
# 'The JamBlaster only checks for updates when booting up. Please reboot the JamBlaster to initiate an update check.')
# else if data.option == 'set-static-ports'
# if jamblaster.isDynamicPorts
# context.JK.Banner.showYesNo({
# title: "revert to dynamic ports",
# html: "Your JamBlaster is currently configured to use ports #{jamblaster.portState.static_port} - #{jamblaster.portState.static_port + 10}). Would you like to revert to the use of dynamic ports for UDP communication?"
# yes: =>
# context.jamClient.setJbPortBindState({use_static_port: false, static_port: 12000})
# JamBlasterActions.clearPortBindState()
# #setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
# JamBlasterActions.resyncBonjour()
# setTimeout((() => context.JK.Banner.showNotice("reboot JamBlaster",
# "For these settings to take effect, you must restart the JamBlaster.")), 1)
})
# })
# else
# @app.layout.showDialog('jamblaster-port-dialog').one(context.JK.EVENTS.DIALOG_CLOSED, (e, data) =>
# JamBlasterActions.clearPortBindState()
# JamBlasterActions.resyncBonjour()
# context.JK.Banner.showNotice("reboot JamBlaster",
# "For these settings to take effect, you must restart the JamBlaster.")
# )
# else if data.option == 'factory-reset'
# context.JK.Banner.showNotice('Factory Reset',
# 'The JamBlaster only checks for updates when it boots up, and if there is an update available, it will automatically begin updating.<br/><br/>Please reboot the JamBlaster to initiate an update check.')
# else
# logger.debug("unknown action")
jamblasterOptionSelected: `function(e, data) {
let jamblaster = data.options;
jamblaster = this.findJamBlaster(jamblaster);
if (data.option === 'auto-connect') {
return JamBlasterActions.setAutoPair(!jamblaster.autoconnect);
} else if (data.option === 'restart') {
return context.JK.Banner.showYesNo({
title: "reboot JamBlaster",
html: "Are you sure?",
yes: async () => {
const result = await context.jamClient.rebootJamBlaster();
if (result) {
setTimeout((() => context.JK.Banner.showNotice("JamBlaster is rebooting",
"It should be back online within a minute.")), 1);
return setTimeout((() => JamBlasterActions.resyncBonjour()), 1000);
} else {
return setTimeout((() => context.JK.Banner.showAlert("could not reboot",
"The JamBlaster could not be rebooted remotely. Please cycle the power manually.")), 1);
}
}
});
} else if (data.option === 'name') {
return this.app.layout.showDialog('jamblaster-name-dialog', {d1: jamblaster.name}).one(context.JK.EVENTS.DIALOG_CLOSED,
(e, data) => {
return setTimeout((() => JamBlasterActions.resyncBonjour()), 1000);
});
} else if (data.option === 'check-for-updates') {
return context.JK.Banner.showNotice('Check for Update',
'The JamBlaster only checks for updates when booting up. Please reboot the JamBlaster to initiate an update check.');
} else if (data.option === 'set-static-ports') {
if (jamblaster.isDynamicPorts) {
return context.JK.Banner.showYesNo({
title: "revert to dynamic ports",
html: 'Your JamBlaster is currently configured to use ports '+jamblaster.portState.static_port+' - '+(jamblaster.portState.static_port + 10)+'. Would you like to revert to the use of dynamic ports for UDP communication?',
yes: async () => {
await context.jamClient.setJbPortBindState({use_static_port: false, static_port: 12000});
JamBlasterActions.clearPortBindState();
//setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
JamBlasterActions.resyncBonjour();
return setTimeout((() => context.JK.Banner.showNotice("reboot JamBlaster",
"For these settings to take effect, you must restart the JamBlaster.")), 1);
}
});
} else {
return this.app.layout.showDialog('jamblaster-port-dialog').one(context.JK.EVENTS.DIALOG_CLOSED, (e, data) => {
JamBlasterActions.clearPortBindState();
JamBlasterActions.resyncBonjour();
return context.JK.Banner.showNotice("reboot JamBlaster",
"For these settings to take effect, you must restart the JamBlaster.");
});
}
} else if (data.option === 'factory-reset') {
return context.JK.Banner.showNotice('Factory Reset',
'The JamBlaster only checks for updates when it boots up, and if there is an update available, it will automatically begin updating.<br/><br/>Please reboot the JamBlaster to initiate an update check.');
} else {
return logger.debug("unknown action");
}
}`
else
@app.layout.showDialog('jamblaster-port-dialog').one(context.JK.EVENTS.DIALOG_CLOSED, (e, data) =>
JamBlasterActions.clearPortBindState()
JamBlasterActions.resyncBonjour()
context.JK.Banner.showNotice("reboot JamBlaster",
"For these settings to take effect, you must restart the JamBlaster.")
)
else if data.option == 'factory-reset'
context.JK.Banner.showNotice('Factory Reset',
'The JamBlaster only checks for updates when it boots up, and if there is an update available, it will automatically begin updating.<br/><br/>Please reboot the JamBlaster to initiate an update check.')
else
logger.debug("unknown action")
getInitialState: () ->
{
selected: 'management',
@ -195,10 +260,17 @@ JamBlasterActions = @JamBlasterActions
JamBlasterActions.resyncBonjour()
@setTimer()
)
disconnect: (client, e) ->
logger.debug("disconnecting from currently paired client #{client.connect_url}")
context.jamClient.endPairing()
setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
# disconnect: (client, e) ->
# logger.debug("disconnecting from currently paired client #{client.connect_url}")
# context.jamClient.endPairing()
# setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
disconnect: `async function(client,e){
logger.debug('disconnecting from currently paired client' +client.connect_url);
await context.jamClient.endPairing();
setTimeout((()=>JamBlasterActions.resyncBonjour()),1000);
}`
mergeClients: () ->
clientsJsx = []

View File

@ -231,69 +231,136 @@ rest = context.JK.Rest()
e.preventDefault()
context.JK.popExternalLink($(e.target).attr('href'))
onPlayJamTrack: (jamTrack, e) ->
# onPlayJamTrack: (jamTrack, e) ->
if context.jamClient.IsNativeClient()
e.preventDefault()
tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient)
data = {}
data.client_id = @app.clientId
#data.description = $('#description').val()
data.description = "Jam Track Session"
data.as_musician = true
data.legal_terms = true
data.intellectual_property = true
data.approval_required = false
data.musician_access = false
data.fan_access = false
data.fan_chat = false
console.log("jamTrack", jamTrack)
data.genre = $.map(jamTrack.genres, (genre) -> genre.id)
data.genres = $.map(jamTrack.genres, (genre)-> genre.id)
# if context.JK.isQWebEngine
# e.preventDefault()
# tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient)
# data = {}
# data.client_id = @app.clientId
# #data.description = $('#description').val()
# data.description = "Jam Track Session"
# data.as_musician = true
# data.legal_terms = true
# data.intellectual_property = true
# data.approval_required = false
# data.musician_access = false
# data.fan_access = false
# data.fan_chat = false
# console.log("jamTrack", jamTrack)
# data.genre = $.map(jamTrack.genres, (genre) -> genre.id)
# data.genres = $.map(jamTrack.genres, (genre)-> genre.id)
data.genre = ['rock'] if data.genre.length == 0
data.genres = ['rock'] if data.genres.length == 0
# data.genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre')
# data.musician_access = if $('#musician-access option:selected').val() == 'true' then true else false
# data.approval_required = if $('input[name=\'musician-access-option\']:checked').val() == 'true' then true else false
# data.fan_access = if $('#fan-access option:selected').val() == 'true' then true else false
# data.fan_chat = if $('input[name=\'fan-chat-option\']:checked').val() == 'true' then true else false
# if $('#band-list option:selected').val() != ''
# data.band = $('#band-list option:selected').val()
data.audio_latency = context.jamClient.FTUEGetExpectedLatency().latency
data.tracks = tracks
# data.genre = ['rock'] if data.genre.length == 0
# data.genres = ['rock'] if data.genres.length == 0
# # data.genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre')
# # data.musician_access = if $('#musician-access option:selected').val() == 'true' then true else false
# # data.approval_required = if $('input[name=\'musician-access-option\']:checked').val() == 'true' then true else false
# # data.fan_access = if $('#fan-access option:selected').val() == 'true' then true else false
# # data.fan_chat = if $('input[name=\'fan-chat-option\']:checked').val() == 'true' then true else false
# # if $('#band-list option:selected').val() != ''
# # data.band = $('#band-list option:selected').val()
# data.audio_latency = context.jamClient.FTUEGetExpectedLatency().latency
# data.tracks = tracks
rest.legacyCreateSession(data).done((response) =>
newSessionId = response.id
context.JK.SessionUtils.setAutoOpenJamTrack(jamTrack) # so that the session screen will pick this up
context.SessionActions.enterSession(newSessionId)
# Re-loading the session settings will cause the form to reset with the right stuff in it.
# This is an extra xhr call, but it keeps things to a single codepath
#loadSessionSettings()
context.JK.GA.trackSessionCount data.musician_access, data.fan_access, 0
context.JK.GA.trackSessionMusicians context.JK.GA.SessionCreationTypes.create
).fail (jqXHR) =>
handled = false
if jqXHR.status = 422
response = JSON.parse(jqXHR.responseText)
if response['errors'] and response['errors']['tracks'] and response['errors']['tracks'][0] == 'Please select at least one track'
@app.notifyAlert 'No Inputs Configured', $('<span>You will need to reconfigure your audio device.</span>')
handled = true
if !handled
@app.notifyServerError jqXHR, 'Unable to Create Session'
# rest.legacyCreateSession(data).done((response) =>
# newSessionId = response.id
# context.JK.SessionUtils.setAutoOpenJamTrack(jamTrack) # so that the session screen will pick this up
# context.SessionActions.enterSession(newSessionId)
# # Re-loading the session settings will cause the form to reset with the right stuff in it.
# # This is an extra xhr call, but it keeps things to a single codepath
# #loadSessionSettings()
# context.JK.GA.trackSessionCount data.musician_access, data.fan_access, 0
# context.JK.GA.trackSessionMusicians context.JK.GA.SessionCreationTypes.create
# ).fail (jqXHR) =>
# handled = false
# if jqXHR.status = 422
# response = JSON.parse(jqXHR.responseText)
# if response['errors'] and response['errors']['tracks'] and response['errors']['tracks'][0] == 'Please select at least one track'
# @app.notifyAlert 'No Inputs Configured', $('<span>You will need to reconfigure your audio device.</span>')
# handled = true
# if !handled
# @app.notifyServerError jqXHR, 'Unable to Create Session'
else
if true # /iPhone|iPad|iPod|android/i.test(navigator.userAgent)
# popup window
JamTrackPlayerActions.opened(jamTrack)
# else
# if true # /iPhone|iPad|iPod|android/i.test(navigator.userAgent)
# # popup window
# JamTrackPlayerActions.opened(jamTrack)
else
# popup window
JamTrackPlayerActions.open(jamTrack)
e.preventDefault()
# else
# # popup window
# JamTrackPlayerActions.open(jamTrack)
# e.preventDefault()
onPlayJamTrack: `async function(jamTrack, e) {
if (context.JK.isQWebEngine) {
e.preventDefault();
const tracks = await context.JK.TrackHelpers.getUserTracks(context.jamClient);
const data = {};
data.client_id = this.app.clientId;
//data.description = $('#description').val()
data.description = "Jam Track Session";
data.as_musician = true;
data.legal_terms = true;
data.intellectual_property = true;
data.approval_required = false;
data.musician_access = false;
data.fan_access = false;
data.fan_chat = false;
console.log("jamTrack", jamTrack);
data.genre = $.map(jamTrack.genres, genre => genre.id);
data.genres = $.map(jamTrack.genres, genre => genre.id);
if (data.genre.length === 0) { data.genre = ['rock']; }
if (data.genres.length === 0) { data.genres = ['rock']; }
// data.genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre')
// data.musician_access = if $('#musician-access option:selected').val() == 'true' then true else false
// data.approval_required = if $('input[name=\'musician-access-option\']:checked').val() == 'true' then true else false
// data.fan_access = if $('#fan-access option:selected').val() == 'true' then true else false
// data.fan_chat = if $('input[name=\'fan-chat-option\']:checked').val() == 'true' then true else false
// if $('#band-list option:selected').val() != ''
// data.band = $('#band-list option:selected').val()
let expectedLatency = await context.jamClient.FTUEGetExpectedLatency()
data.audio_latency = expectedLatency.latency;
data.tracks = tracks;
rest.legacyCreateSession(data).done(response => {
const newSessionId = response.id;
context.JK.SessionUtils.setAutoOpenJamTrack(jamTrack); // so that the session screen will pick this up
context.SessionActions.enterSession(newSessionId);
// Re-loading the session settings will cause the form to reset with the right stuff in it.
// This is an extra xhr call, but it keeps things to a single codepath
//loadSessionSettings()
context.JK.GA.trackSessionCount(data.musician_access, data.fan_access, 0);
context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.create);
}).fail(jqXHR => {
let handled = false;
if (jqXHR.status = 422) {
const response = JSON.parse(jqXHR.responseText);
if (response['errors'] && response['errors']['tracks'] && (response['errors']['tracks'][0] === 'Please select at least one track')) {
this.app.notifyAlert('No Inputs Configured', $('<span>You will need to reconfigure your audio device.</span>'));
handled = true;
}
}
if (!handled) {
this.app.notifyServerError(jqXHR, 'Unable to Create Session');
}
});
} else {
if (true) { // /iPhone|iPad|iPod|android/i.test(navigator.userAgent)
// popup window
JamTrackPlayerActions.opened(jamTrack);
} else {
// popup window
JamTrackPlayerActions.open(jamTrack);
e.preventDefault();
}
}
}`
onAppInit: (@app) ->
@rest = context.JK.Rest()

View File

@ -11,7 +11,7 @@ MIX_MODES = context.JK.MIX_MODES
if this.state.sold
if context.jamClient && context.jamClient.IsNativeClient()
if context.JK.isQWebEngine
platformMessage = `<div>
<p> To play your purchased JamTrack, start a session and then open the JamTrack</p>
<a className="download-jamkazam-wrapper" href="/client#/createSession">

View File

@ -0,0 +1,335 @@
# context = window
# logger = context.JK.logger
# NoVideoRecordActive = 0
# WebCamRecordActive = 1
# ScreenRecordActive = 2
# WebCam2RecordActive = 3
# DesktopRecordActive = 4
# recording_sources = [WebCamRecordActive, WebCam2RecordActive, ScreenRecordActive, DesktopRecordActive]
# recording_data = {
# 2: {key: 'video-window', text: 'Record session video window'},
# 1: {key: 'webcam-only', text: 'Record my webcam only'},
# 3: {key: 'webcam-only-2', text: 'Record my 2nd webcam only'},
# 4: {key: 'desktop-only', text: 'Record my computer desktop'}
# }
# mixins = []
# # make sure this is actually us opening the window, not someone else (by checking for MixerStore)
# # this check ensures we attempt to listen if this component is created in a popup
# reactContext = if window.opener? then window.opener else window
# accessOpener = false
# if window.opener?
# try
# m = window.opener.MixerStore
# accessOpener = true
# catch e
# reactContext = window
# MixerStore = reactContext.MixerStore
# RecordingStore = reactContext.RecordingStore
# VideoStore = reactContext.VideoStore
# if accessOpener
# mixins.push(Reflux.listenTo(RecordingStore,"onRecordingStateChanged"))
# # mixins.push(Reflux.listenTo(MixerStore,"onMixersChanged"))
# @PopupRecordingStartStop = React.createClass({
# mixins: mixins
# #onMixersChanged: (mixers) ->
# # this.setState(chatMixer: mixers.chatMixer)
# onRecordingStateChanged: (recordingState) ->
# if @unloaded
# #console.log("PopupMediaControls unloaded. ignore onMixersChnaged")
# return
# this.setState(isRecording: recordingState.isRecording, recordedOnce: this.state.recordedOnce || recordingState.isRecording)
# startStopRecording: () ->
# if this.state.isRecording
# window.opener.RecordingActions.stopRecording()
# else
# recordChat = false
# recordVideo = NoVideoRecordActive
# $root = $(this.getDOMNode())
# if @inputType != 'audio-only'
# selection = $root.find('#recording-selection').val()
# if selection == 'video-window'
# recordVideo = ScreenRecordActive
# else if selection == 'webcam-only'
# recordVideo = WebCamRecordActive
# else if selection == 'webcam-only-2'
# recordVideo = WebCam2RecordActive
# else
# recordVideo = DesktopRecordActive
# recordChat = $root.find('#include-chat').is(':checked')
# # if the video window isn't open, but a video option was selected...
# window.opener.VideoActions.refreshVideoState.trigger()
# if recordVideo != NoVideoRecordActive && !VideoStore.anyVideoOpen
# #if recordVideo != NoVideoRecordActive && !VideoStore.videoShared
# logger.debug("prevent video from opening", VideoStore)
# context.JK.prodBubble($root.find('.control'), 'video-window-not-open', {}, {positions:['bottom']})
# return
# if recordVideo == WebCamRecordActive && !VideoStore.openVideoSources.webcam1
# context.JK.prodBubble($root.find('.control'), 'no-webcam-1', {}, {positions:['bottom']})
# return
# if recordVideo == WebCam2RecordActive && !VideoStore.openVideoSources.webcam2
# context.JK.prodBubble($root.find('.control'), 'no-webcam-2', {}, {positions:['bottom']})
# return
# if recordVideo == DesktopRecordActive && !VideoStore.openVideoSources.screen_capture
# context.JK.prodBubble($root.find('.control'), 'no-screen-capture', {}, {positions:['bottom']})
# return
# logger.debug("@inputType, @udiotye", recordChat, recordVideo)
# window.opener.RecordingActions.startRecording(recordVideo, recordChat)
# onNoteShowHide: () ->
# $root = $(this.getDOMNode())
# audioVideoValue = $root.find('input[name="recording-input-type"]').val()
# console.log("audio video value", audioVideoValue)
# this.setState(showNote: !this.state.showNote)
# getInitialState: () ->
# {isRecording: window.ParentIsRecording, showNote: true, recordedOnce: false, chatMixer: MixerStore.mixers?.chatMixer, openWindows: []}
# 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>`
# chatHelp = `<a href="#" onClick={this.onChatHelp} className="chat-help">[?]</a>`
# options = []
# for source in recording_sources
# if this.state.openWindows?
# found = this.state.openWindows.indexOf(source) > -1
# if found
# data = recording_data[source]
# options.push(`<option value={data.key}>{data.text}</option>`)
# recordingJSX =
# `<div className="recording-options">
# <div className="video-settings">
# <h3>Recording Type</h3>
# <div className="field">
# <input type="radio" name="recording-input-type" id="recording-input-audio" value="audio-only" defaultChecked="checked" />
# <label htmlFor="recording-input-audio">Audio only</label>
# <div className="clearall"></div>
# </div>
# <div className="field">
# <input type="radio" name="recording-input-type" id="recording-input-both" value="audio-video" />
# <label htmlFor="recording-input-both">Audio and video</label>
# <div className="clearall"></div>
# </div>
# <div className="field">
# <select className="easydropdown" name="recording-selection" id="recording-selection">
# {options}
# </select>
# </div>
# </div>
# <div className="audio-settings">
# <input type="checkbox" name="include-chat" id="include-chat" /><label htmlFor="include-chat">Include voice chat in recorded audio {chatHelp}</label>
# </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: () ->
# @unloaded = true
# window.unloaded = true
# window.opener.RecordingActions.recordingControlsClosed()
# onChatHelp: (e) ->
# e.preventDefault()
# context.JK.prodBubble($(e.target), 'vid-record-chat-input', {}, {positions:['left']})
# trackInputType: (e) ->
# $checkedType = $(e.target);
# @inputType = $checkedType.val()
# logger.debug("updated @inputType",e.target, @inputType)
# trackAudioType: (e) ->
# $checkedType = $(e.target);
# @audioType = $checkedType.val()
# logger.debug("updated @audioType", @inputType)
# # componentDidMount: () ->
# # $(window).unload(@windowUnloaded)
# # $root = jQuery(this.getDOMNode())
# # $recordingType = $root.find('input[type="radio"]')
# # context.JK.checkbox($recordingType)
# # @inputType = 'audio-only'
# # @audioType = 'audio-only'
# # $root.find('input[name="recording-input-type"]').on('ifChanged', @trackInputType)
# # $root.find('input[name="recording-input-chat-option"]').on('ifChanged', @trackAudioType)
# # $recordingRegion = $root.find('#recording-selection')
# # #console.log("$recordingou", $recordingRegion)
# # #context.JK.dropdown($recordingRegion)
# # $includeChat = $root.find('#include-chat')
# # context.JK.checkbox($includeChat)
# # openWindows = window.opener.jamClient.getOpenVideoSources()
# # console.log("open video sources", openWindows)
# # fixedwindows = []
# # if openWindows?
# # for key, value of openWindows
# # fixedwindows.push(value)
# # this.setState({openWindows: fixedwindows})
# # @resizeWindow()
# # # this is necessary due to whatever the client's rendering behavior is.
# # setTimeout(@resizeWindow, 300)
# componentDidMount: `async function() {
# $(window).unload(this.windowUnloaded);
# const $root = jQuery(this.getDOMNode());
# const $recordingType = $root.find('input[type="radio"]');
# context.JK.checkbox($recordingType);
# this.inputType = 'audio-only';
# this.audioType = 'audio-only';
# $root.find('input[name="recording-input-type"]').on('ifChanged', this.trackInputType);
# $root.find('input[name="recording-input-chat-option"]').on('ifChanged', this.trackAudioType);
# const $recordingRegion = $root.find('#recording-selection');
# //console.log("$recordingou", $recordingRegion)
# //context.JK.dropdown($recordingRegion)
# const $includeChat = $root.find('#include-chat');
# context.JK.checkbox($includeChat);
# const openWindows = await window.opener.jamClient.getOpenVideoSources();
# console.log("open video sources", openWindows);
# const fixedwindows = [];
# if (openWindows != null) {
# for (let key in openWindows) {
# const value = openWindows[key];
# fixedwindows.push(value);
# }
# }
# this.setState({openWindows: fixedwindows});
# this.resizeWindow();
# //this is necessary due to whatever the client rendering behavior is.
# return setTimeout(this.resizeWindow, 300);
# }`
# componentDidUpdate: () ->
# @resizeWindow()
# $root = jQuery(this.getDOMNode())
# $includeChat = $root.find('#include-chat')
# shouldComponentUpdate: () ->
# return !@unloaded
# 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)
# })

View File

@ -7,14 +7,14 @@ ScreenRecordActive = 2
WebCam2RecordActive = 3
DesktopRecordActive = 4
recording_sources = [WebCamRecordActive, WebCam2RecordActive, ScreenRecordActive, DesktopRecordActive]
#recording_sources = [WebCamRecordActive, WebCam2RecordActive, ScreenRecordActive, DesktopRecordActive]
recording_data = {
2: {key: 'video-window', text: 'Record session video window'},
1: {key: 'webcam-only', text: 'Record my webcam only'},
3: {key: 'webcam-only-2', text: 'Record my 2nd webcam only'},
4: {key: 'desktop-only', text: 'Record my computer desktop'}
}
# recording_data = {
# 2: {key: 'video-window', text: 'Record session video window'},
# 1: {key: 'webcam-only', text: 'Record my webcam only'},
# 3: {key: 'webcam-only-2', text: 'Record my 2nd webcam only'},
# 4: {key: 'desktop-only', text: 'Record my computer desktop'}
# }
mixins = []
@ -34,18 +34,30 @@ if window.opener?
MixerStore = reactContext.MixerStore
RecordingStore = reactContext.RecordingStore
VideoStore = reactContext.VideoStore
ExternalVideoStore = reactContext.ExternalVideoStore
if accessOpener
mixins.push(Reflux.listenTo(ExternalVideoStore, "onExternalVideoStateChanged"))
mixins.push(Reflux.listenTo(RecordingStore,"onRecordingStateChanged"))
# mixins.push(Reflux.listenTo(MixerStore,"onMixersChanged"))
mixins.push(Reflux.listenTo(MixerStore,"onMixersChanged"))
@PopupRecordingStartStop = React.createClass({
mixins: mixins
#onMixersChanged: (mixers) ->
# this.setState(chatMixer: mixers.chatMixer)
getInitialState: () ->
{isRecording: window.ParentIsRecording, showNote: true, recordedOnce: false, chatMixer: MixerStore.mixers?.chatMixer, openWindows: []}
onExternalVideoStateChanged: (videoState) ->
$root = $(this.getDOMNode())
if videoState.videoEnabled
$root.find('#recording-input-both').iCheck('uncheck').attr('disabled', false)
else
$root.find('#recording-input-both').prop('disabled',true).iCheck('update').iCheck('uncheck');
$root.find('#recording-input-audio').iCheck('check').attr('checked', true)
onMixersChanged: (mixers) ->
this.setState(chatMixer: mixers.chatMixer)
onRecordingStateChanged: (recordingState) ->
if @unloaded
@ -62,44 +74,27 @@ if accessOpener
recordVideo = NoVideoRecordActive
$root = $(this.getDOMNode())
if @inputType != 'audio-only'
#return unless this.state.videoEnabled
return unless reactContext.JK.videoIsOngoing
selection = $root.find('#recording-selection').val()
if selection == 'video-window'
recordVideo = ScreenRecordActive
else if selection == 'webcam-only'
recordVideo = WebCamRecordActive
else if selection == 'webcam-only-2'
recordVideo = WebCam2RecordActive
else
recordVideo = DesktopRecordActive
# selection = $root.find('#recording-selection').val()
# if selection == 'video-window'
# recordVideo = ScreenRecordActive
# else if selection == 'webcam-only'
# recordVideo = WebCamRecordActive
# else if selection == 'webcam-only-2'
# recordVideo = WebCam2RecordActive
# else
# recordVideo = DesktopRecordActive
recordVideo = WebCamRecordActive
recordChat = $root.find('#include-chat').is(':checked')
# if the video window isn't open, but a video option was selected...
window.opener.VideoActions.refreshVideoState.trigger()
if recordVideo != NoVideoRecordActive && !VideoStore.anyVideoOpen
#if recordVideo != NoVideoRecordActive && !VideoStore.videoShared
logger.debug("prevent video from opening", VideoStore)
context.JK.prodBubble($root.find('.control'), 'video-window-not-open', {}, {positions:['bottom']})
return
if recordVideo == WebCamRecordActive && !VideoStore.openVideoSources.webcam1
context.JK.prodBubble($root.find('.control'), 'no-webcam-1', {}, {positions:['bottom']})
return
if recordVideo == WebCam2RecordActive && !VideoStore.openVideoSources.webcam2
context.JK.prodBubble($root.find('.control'), 'no-webcam-2', {}, {positions:['bottom']})
return
if recordVideo == DesktopRecordActive && !VideoStore.openVideoSources.screen_capture
context.JK.prodBubble($root.find('.control'), 'no-screen-capture', {}, {positions:['bottom']})
return
#window.opener.VideoActions.refreshVideoState.trigger()
logger.debug("@inputType, @udiotye", recordChat, recordVideo)
window.opener.RecordingActions.startRecording(recordVideo, recordChat)
@ -111,8 +106,7 @@ if accessOpener
console.log("audio video value", audioVideoValue)
this.setState(showNote: !this.state.showNote)
getInitialState: () ->
{isRecording: window.ParentIsRecording, showNote: true, recordedOnce: false, chatMixer: MixerStore.mixers?.chatMixer, openWindows: []}
render: () ->
@ -136,14 +130,14 @@ if accessOpener
chatHelp = `<a href="#" onClick={this.onChatHelp} className="chat-help">[?]</a>`
options = []
for source in recording_sources
if this.state.openWindows?
found = this.state.openWindows.indexOf(source) > -1
# options = []
# for source in recording_sources
# if this.state.openWindows?
# found = this.state.openWindows.indexOf(source) > -1
if found
data = recording_data[source]
options.push(`<option value={data.key}>{data.text}</option>`)
# if found
# data = recording_data[source]
# options.push(`<option value={data.key}>{data.text}</option>`)
recordingJSX =
`<div className="recording-options">
@ -155,15 +149,10 @@ if accessOpener
<div className="clearall"></div>
</div>
<div className="field">
<input type="radio" name="recording-input-type" id="recording-input-both" value="audio-video" />
<input type="radio" name="recording-input-type" id="recording-input-both" value="audio-video" disabled={!reactContext.JK.videoIsOngoing} />
<label htmlFor="recording-input-both">Audio and video</label>
<div className="clearall"></div>
</div>
<div className="field">
<select className="easydropdown" name="recording-selection" id="recording-selection">
{options}
</select>
</div>
</div>
<div className="audio-settings">
@ -220,6 +209,7 @@ if accessOpener
e.preventDefault()
context.JK.prodBubble($(e.target), 'vid-record-chat-input', {}, {positions:['left']})
trackInputType: (e) ->
$checkedType = $(e.target);
@inputType = $checkedType.val()
@ -230,41 +220,89 @@ if accessOpener
@audioType = $checkedType.val()
logger.debug("updated @audioType", @inputType)
componentDidMount: () ->
$(window).unload(@windowUnloaded)
# componentDidMount: () ->
# $(window).unload(@windowUnloaded)
$root = jQuery(this.getDOMNode())
# $root = jQuery(this.getDOMNode())
$recordingType = $root.find('input[type="radio"]')
context.JK.checkbox($recordingType)
# $recordingType = $root.find('input[type="radio"]')
# context.JK.checkbox($recordingType)
@inputType = 'audio-only'
@audioType = 'audio-only'
# @inputType = 'audio-only'
# @audioType = 'audio-only'
$root.find('input[name="recording-input-type"]').on('ifChanged', @trackInputType)
$root.find('input[name="recording-input-chat-option"]').on('ifChanged', @trackAudioType)
# $root.find('input[name="recording-input-type"]').on('ifChanged', @trackInputType)
# $root.find('input[name="recording-input-chat-option"]').on('ifChanged', @trackAudioType)
$recordingRegion = $root.find('#recording-selection')
#console.log("$recordingou", $recordingRegion)
#context.JK.dropdown($recordingRegion)
# $recordingRegion = $root.find('#recording-selection')
# #console.log("$recordingou", $recordingRegion)
# #context.JK.dropdown($recordingRegion)
$includeChat = $root.find('#include-chat')
context.JK.checkbox($includeChat)
# $includeChat = $root.find('#include-chat')
# context.JK.checkbox($includeChat)
openWindows = window.opener.jamClient.getOpenVideoSources()
# openWindows = window.opener.jamClient.getOpenVideoSources()
console.log("open video sources", openWindows)
# console.log("open video sources", openWindows)
fixedwindows = []
if openWindows?
for key, value of openWindows
fixedwindows.push(value)
# fixedwindows = []
# if openWindows?
# for key, value of openWindows
# fixedwindows.push(value)
this.setState({openWindows: fixedwindows})
@resizeWindow()
# this.setState({openWindows: fixedwindows})
# @resizeWindow()
# this is necessary due to whatever the client's rendering behavior is.
setTimeout(@resizeWindow, 300)
# # this is necessary due to whatever the client's rendering behavior is.
# setTimeout(@resizeWindow, 300)
componentDidMount: `function() {
$(window).unload(this.windowUnloaded);
const $root = jQuery(this.getDOMNode());
$root.find('#recording-input-audio').iCheck('check')
$root.find('#recording-input-both').iCheck().attr('disabled', !reactContext.JK.videoIsOngoing)
const $recordingType = $root.find('input[type="radio"]');
context.JK.checkbox($recordingType);
this.inputType = 'audio-only';
this.audioType = 'audio-only';
$root.find('input[name="recording-input-type"]').on('ifChanged', this.trackInputType);
$root.find('input[name="recording-input-chat-option"]').on('ifChanged', this.trackAudioType);
//const $recordingRegion = $root.find('#recording-selection');
//console.log("$recordingou", $recordingRegion)
//context.JK.dropdown($recordingRegion)
const $includeChat = $root.find('#include-chat');
context.JK.checkbox($includeChat);
//const openWindows = await window.opener.jamClient.getOpenVideoSources();
//console.log("open video sources", openWindows);
//const fixedwindows = [];
//if (openWindows != null) {
// for (let key in openWindows) {
// const value = openWindows[key];
// fixedwindows.push(value);
// }
//}
//this.setState({openWindows: fixedwindows});
//this.resizeWindow();
//this is necessary due to whatever the client rendering behavior is.
//return setTimeout(this.resizeWindow, 300);
}`
componentWillUnmount: () ->
$root = jQuery(this.getDOMNode());
$root.find('#recording-input-both').iCheck('uncheck').attr('disabled', true)
componentDidUpdate: () ->
@resizeWindow()

View File

@ -0,0 +1,38 @@
context = window
logger = context.JK.logger
mixins = []
@PopupSessionBroadcast = React.createClass({
render: () ->
`<div>
<div className="dialog-tabs">
<a className="selected tab-configure-audio">Inputs &amp; Outputs</a>
<a className="tab-configure-voice">Voice Chat</a>
</div>
<div className="tab no-selection-range" data-tab-id="music-audio">tab1</div>
<div className="tab" data-tab-id="voice-chat">tab2</div>
</div>`
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)
})

View File

@ -0,0 +1,24 @@
context = window
@SessionBroadcastBtn = React.createClass({
mixins: [Reflux.listenTo(@AppStore,"onAppInit")]
onClickBroadcast: (e) ->
e.preventDefault()
@popupBroadcastWindow()
popupBroadcastWindow: () ->
@broadcastWindow = window.open("/popups/broadcast-controls", 'Broadcast', 'scrollbars=yes,toolbar=no,status=no,height=640,width=800')
#@recordingWindow.ParentRecordingStore = context.RecordingStore
#@recordingWindow.ParentIsRecording = @recordingModel.isRecording()
render: () ->
`<a className="session-share button-grey left" onClick={this.onClickBroadcast}>
<img src="/assets/content/icon_share.png" align="texttop" height="14" width="14"/>
BROADCAST
</a>`
onAppInit: (app) ->
@app = app
})

View File

@ -71,24 +71,46 @@ ChannelGroupIds = context.JK.ChannelGroupIds
@app.layout.showDialog('localRecordings') unless @app.layout.isDialogShowing('localRecordings')
openBackingTrack: (e) ->
e.preventDefault()
if @state.backingTrackDialogOpen
logger.debug("backing track dialog already open")
return
# 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
# # 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");
# @setState({backingTrackDialogOpen: true})
# context.jamClient.ShowSelectBackingTrackDialog("window.JK.HandleBackingTrackSelectedCallback2");
openBackingTrack: `async function(e) {
e.preventDefault();
if (this.state.backingTrackDialogOpen) {
logger.debug("backing track dialog already open");
return;
}
// just ignore the click if they are currently recording for now
if (this.state.isRecording) {
this.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;
}
this.setState({backingTrackDialogOpen: true});
await context.jamClient.ShowSelectBackingTrackDialog("window.JK.HandleBackingTrackSelectedCallback2");
}`
openMetronome: (e) ->
@ -121,71 +143,142 @@ ChannelGroupIds = context.JK.ChannelGroupIds
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
# 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');
# 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
# # 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})
# this.setState({downloadJamTrack: null})
# XXX: test with this removed; it should be unnecessary
context.jamClient.JamTrackStopPlay();
# # 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
# sampleRate = context.jamClient.GetSampleRate()
# sampleRateForFilename = if sampleRate == 48 then '48' else '44'
# fqId = jamTrack.id + '-' + sampleRateForFilename
if jamTrack.jmep
logger.debug("setting jmep data")
# if jamTrack.jmep
# logger.debug("setting jmep data")
context.jamClient.JamTrackLoadJmep(fqId, jamTrack.jmep)
else
logger.debug("no jmep data for jamtrack")
# context.jamClient.JamTrackLoadJmep(fqId, jamTrack.jmep)
# else
# logger.debug("no jmep data for jamtrack")
# JamTrackPlay means 'load'
result = context.jamClient.JamTrackPlay(fqId);
# # JamTrackPlay means 'load'
# result = context.jamClient.JamTrackPlay(fqId);
SessionActions.downloadingJamTrack(false)
# SessionActions.downloadingJamTrack(false)
console.log("JamTrackPlay: result", 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();
)
# console.log("JamTrackPlay: result", 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
})
)
# context.stats.write('web.jamtrack.open', {
# value: 1,
# session_size: participantCnt,
# user_id: context.JK.currentUserId,
# user_name: context.JK.currentUserName
# })
# )
@setState({downloadJamTrack: downloadJamTrack})
# @setState({downloadJamTrack: downloadJamTrack})
loadJamTrack: `async function(jamTrack) {
if (this.state.downloadJamTrack) {
// if there was one showing before somehow, destroy it.
logger.warn("destroying existing JamTrack");
this.state.downloadJamTrack.root.remove();
this.state.downloadJamTrack.destroy();
}
//set to null
let downloadJamTrack = new context.JK.DownloadJamTrack(this.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, async (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
await context.jamClient.JamTrackStopPlay();
const sampleRate = await context.jamClient.GetSampleRate();
const sampleRateForFilename = sampleRate === 48 ? '48' : '44';
const fqId = jamTrack.id + '-' + sampleRateForFilename;
if (jamTrack.jmep) {
logger.debug("setting jmep data");
await context.jamClient.JamTrackLoadJmep(fqId, jamTrack.jmep);
} else {
logger.debug("no jmep data for jamtrack");
}
// JamTrackPlay means 'load'
const result = await context.jamClient.JamTrackPlay(fqId);
SessionActions.downloadingJamTrack(false);
console.log("JamTrackPlay: result", result);
if (!result) {
return this.app.notify(
{
title: "JamTrack Can Not Open",
text: "Unable to open your JamTrack. Please contact support@jamkazam.com"
}
, null, true);
} else {
const participantCnt = context.SessionStore.participants().length;
rest.playJamTrack(jamTrack.id)
.done(() => {
return this.app.refreshUser();
});
return context.stats.write('web.jamtrack.open', {
value: 1,
session_size: participantCnt,
user_id: context.JK.currentUserId,
user_name: context.JK.currentUserName
});
}
}
});
return this.setState({downloadJamTrack});
}`
render: () ->
@ -205,7 +298,7 @@ ChannelGroupIds = context.JK.ChannelGroupIds
<a className="open-jamtrack" onClick={this.openJamTrack}>JamTrack</a>
</li>
<li>
<a className="open-backingtrack" onClick={this.openBackingTrack}>Audio File</a>
<a className="open-backingtrack" onClick={ this.openBackingTrack }>Audio File</a>
</li>
</ul>
<div className="use-metronome-header">
@ -337,7 +430,6 @@ ChannelGroupIds = context.JK.ChannelGroupIds
@closeWindow()
handleBackingTrackSelectedCallback: (result) ->
@setState({backingTrackDialogOpen: false})
SessionActions.openBackingTrack(result)
@ -364,7 +456,7 @@ ChannelGroupIds = context.JK.ChannelGroupIds
@handlePopup()
windowUnloaded: () ->
windowUnloaded : () ->
logger.debug('SessionMediaTracks: window unloaded')
@setState({popupOpen: false})
@childWindow = null
@ -374,6 +466,7 @@ ChannelGroupIds = context.JK.ChannelGroupIds
unless @childWindow?
logger.debug("opening media control window")
@childWindow = window.open("/popups/media-controls", 'Media Controls', 'scrollbars=yes,toolbar=no,status=no,height=155,width=350')
console.log('childWindow', @childWindow)
@childWindow.PopupProps = {media: @state, jamTrackState: context.JamTrackStore.getState(), downloadingJamTrack: context.SessionStore.downloadingJamTrack, windowUnloaded: @windowUnloaded }
if !@state.popupOpen
setTimeout(() =>

View File

@ -91,53 +91,107 @@ ConfigureTracksActions = @ConfigureTracksActions
</div>
</div>`
componentDidMount: () ->
# componentDidMount: () ->
context.jamClient.SessionSetUserName(this.props.clientId, this.props.name)
# context.jamClient.SessionSetUserName(this.props.clientId, this.props.name)
$root = $(this.getDOMNode())
$mute = $root.find('.track-icon-mute')
$pan = $root.find('.track-icon-pan')
$connectionState = $root.find('.track-connection-state')
# $root = $(this.getDOMNode())
# $mute = $root.find('.track-icon-mute')
# $pan = $root.find('.track-icon-pan')
# $connectionState = $root.find('.track-connection-state')
context.JK.interactReactBubble(
$mute,
'SessionTrackVolumeHover',
() =>
{mixers:this.props.mixers, trackType: 'SessionMyTrack', mode: @props.mode}
# context.JK.interactReactBubble(
# $mute,
# 'SessionTrackVolumeHover',
# () =>
# {mixers:this.props.mixers, trackType: 'SessionMyTrack', mode: @props.mode}
# ,
# {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')})
# context.JK.interactReactBubble(
# $connectionState,
# 'SessionStatsHover',
# () =>
# {myTrack: true, participant: {client_id: this.props.connStatsClientId, user: name: 'You', possessive: 'Your'}, }
# ,
# {width:385, positions:['right', 'left'], offsetParent:$root.closest('.screen'), extraClasses: 'self'})
# unless this.props.hasMixer
# $mute.on("mouseenter", false)
# $mute.on("mouseleave", false)
# $pan.on("mouseentere", false)
# $pan.on("mouseleave", false)
# unless this.props.hasMixer
# $mute.on("mouseenter", false)
# $mute.on("mouseleave", false)
# $pan.on("mouseentere", false)
# $pan.on("mouseleave", false)
# context.JK.helpBubble($root.find('.disabled-track-overlay'), 'missing-my-tracks', {}, {positions:['top'], offsetParent: $root.closest('.top-parent')})
# @initializeVstEffects()
componentDidMount: `async function() {
await context.jamClient.SessionSetUserName(this.props.clientId, this.props.name);
const $root = $(this.getDOMNode());
const $mute = $root.find('.track-icon-mute');
const $pan = $root.find('.track-icon-pan');
const $connectionState = $root.find('.track-connection-state');
context.JK.interactReactBubble(
$mute,
'SessionTrackVolumeHover',
() => {
return {mixers:this.props.mixers, trackType: 'SessionMyTrack', mode: this.props.mode};
}
,
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')});
context.JK.interactReactBubble(
$pan,
'SessionTrackPanHover',
() => {
return {mixers:this.props.mixers};
}
,
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')});
context.JK.interactReactBubble(
$connectionState,
'SessionStatsHover',
() => {
return {myTrack: true, participant: {client_id: this.props.connStatsClientId, user: {name: 'You', possessive: 'Your'}}, };
}
,
{width:235, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
{width:385, positions:['right', 'left'], offsetParent:$root.closest('.screen'), extraClasses: 'self'});
context.JK.interactReactBubble(
$pan,
'SessionTrackPanHover',
() =>
{mixers:this.props.mixers}
,
{width:331, positions:['right', 'left'], offsetParent:$root.closest('.top-parent')})
if (!this.props.hasMixer) {
$mute.on("mouseenter", false);
$mute.on("mouseleave", false);
$pan.on("mouseentere", false);
$pan.on("mouseleave", false);
}
if (!this.props.hasMixer) {
$mute.on("mouseenter", false);
$mute.on("mouseleave", false);
$pan.on("mouseentere", false);
$pan.on("mouseleave", false);
}
context.JK.interactReactBubble(
$connectionState,
'SessionStatsHover',
() =>
{myTrack: true, participant: {client_id: this.props.connStatsClientId, user: name: 'You', possessive: 'Your'}, }
,
{width:385, positions:['right', 'left'], offsetParent:$root.closest('.screen'), extraClasses: 'self'})
context.JK.helpBubble($root.find('.disabled-track-overlay'), 'missing-my-tracks', {}, {positions:['top'], offsetParent: $root.closest('.top-parent')});
unless this.props.hasMixer
$mute.on("mouseenter", false)
$mute.on("mouseleave", false)
$pan.on("mouseentere", false)
$pan.on("mouseleave", false)
unless this.props.hasMixer
$mute.on("mouseenter", false)
$mute.on("mouseleave", false)
$pan.on("mouseentere", false)
$pan.on("mouseleave", false)
context.JK.helpBubble($root.find('.disabled-track-overlay'), 'missing-my-tracks', {}, {positions:['top'], offsetParent: $root.closest('.top-parent')})
@initializeVstEffects()
this.initializeVstEffects();
}`
componentWillUpdate: (nextProps, nextState) ->
$root = $(this.getDOMNode())

View File

@ -26,7 +26,7 @@ SessionActions = @SessionActions
<div className="in-session-controls">
<SessionSettingsBtn />
<SessionVolumeSettingsBtn />
<SessionShareBtn />
<SessionBroadcastBtn />
<SessionRecordBtn />
{videoBtn}
{filesBtn}
@ -50,7 +50,6 @@ SessionActions = @SessionActions
afterShow: (data) ->
@logger.debug("session afterShow")
SessionActions.joinSession.trigger(data.id)
beforeHide: () ->

View File

@ -247,14 +247,19 @@ StatsInfo = {
onStatsChanged: (stats) ->
stats = window.SessionStatsStore.stats
console.log('=stats', stats)
if stats?
if stats.parent?
# if we have a parent, then use stats from the JamBlaster (parent), not ourselves. Otherwise we'll get bad stats (no Audio etc)
console.log('=stats.parent', stats.parent)
console.log('=@props.participant.client_id', @props.participant.client_id)
console.log('=stats.parent[@props.participant.client_id]', stats.parent[@props.participant.client_id])
clientStats = stats.parent[@props.participant.client_id]
else
clientStats = stats[@props.participant.client_id]
else
clientStats = null
console.log('=clientStats', clientStats)
@setState({stats: clientStats})
getInitialState: () ->

View File

@ -9,7 +9,8 @@ rest = context.JK.Rest()
]
useVideoConferencingServer: () ->
context.SessionStore.currentSession.use_video_conferencing_server
#context.SessionStore.currentSession.use_video_conferencing_server
true
onUserChanged: (userState) ->
@setState({user: userState?.user})

View File

@ -0,0 +1,5 @@
context = window
@ExternalVideoActions = Reflux.createActions({
setVideoEnabled: {}
})

View File

@ -448,7 +448,7 @@ MIX_MODES = context.JK.MIX_MODES;
if correspondingTracks.length == 0
noCorrespondingTracks = true
logger.debug("unable to correlate all recorded tracks", recordingMixers, serverRecordedTracks)
#logger.debug("unable to correlate all recorded tracks", recordingMixers, serverRecordedTracks)
@app.notify({
title: "Unable to Open Recording",
text: "Could not correlate server and client tracks",
@ -703,19 +703,32 @@ MIX_MODES = context.JK.MIX_MODES;
muteMixer: muteMixer
}
mute: (mixerId, mode, muting) ->
# mute: (mixerId, mode, muting) ->
# mode = @mixMode unless mode?
mode = @mixMode unless mode?
# @fillTrackVolumeObject(mixerId, mode)
@fillTrackVolumeObject(mixerId, mode)
# context.trackVolumeObject.mute = muting
context.trackVolumeObject.mute = muting
# context.jamClient.SessionSetControlState(mixerId, mode)
context.jamClient.SessionSetControlState(mixerId, mode)
# # keep state of mixer in sync with backend
# mixer = @getMixer(mixerId, mode)
# mixer.mute = muting
# keep state of mixer in sync with backend
mixer = @getMixer(mixerId, mode)
mixer.mute = muting
mute: `async function(mixerId, mode, muting) {
if (mode == null) { mode = this.mixMode; }
this.fillTrackVolumeObject(mixerId, mode);
context.trackVolumeObject.mute = muting;
//await context.jamClient.SessionSetControlState(mixerId, mode);
await context.jamClient.SessionSetTrackVolumeData(mixerId, mode, context.trackVolumeObject);
// keep state of mixer in sync with backend
const mixer = this.getMixer(mixerId, mode);
mixer.mute = muting;
}`
getOriginalVolume: (mixers, gainType) ->
originalVolume = null
@ -731,43 +744,70 @@ MIX_MODES = context.JK.MIX_MODES;
originalVolume
faderChanged: (data, mixers, gainType, controlGroup) ->
mixers = [mixers] unless $.isArray(mixers)
# faderChanged: (data, mixers, gainType, controlGroup) ->
# mixers = [mixers] unless $.isArray(mixers)
originalVolume = @getOriginalVolume(mixers, gainType)
# originalVolume = @getOriginalVolume(mixers, gainType)
if controlGroup?
mixers = [mixers[0]]
# if controlGroup?
# mixers = [mixers[0]]
for mixer in mixers
broadcast = !(data.dragging) # If fader is still dragging, don't broadcast
mixer = @fillTrackVolumeObject(mixer.id, mixer.mode, broadcast)
# for mixer in mixers
# broadcast = !(data.dragging) # If fader is still dragging, don't broadcast
# mixer = @fillTrackVolumeObject(mixer.id, mixer.mode, broadcast)
relative = gainType == 'music' && (mixer.name == CategoryGroupIds.UserMedia || mixer.name == CategoryGroupIds.MediaTrack)
# relative = gainType == 'music' && (mixer.name == CategoryGroupIds.UserMedia || mixer.name == CategoryGroupIds.MediaTrack)
@setMixerVolume(mixer, data.percentage, relative, originalVolume, controlGroup)
# @setMixerVolume(mixer, data.percentage, relative, originalVolume, controlGroup)
# keep state of mixer in sync with backend
mixer = @getMixer(mixer.id, mixer.mode)
mixer.volume_left = context.trackVolumeObject.volL
# # keep state of mixer in sync with backend
# mixer = @getMixer(mixer.id, mixer.mode)
# mixer.volume_left = context.trackVolumeObject.volL
else
# else
for mixer in mixers
broadcast = !(data.dragging) # If fader is still dragging, don't broadcast
mixer = @fillTrackVolumeObject(mixer.id, mixer.mode, broadcast)
# for mixer in mixers
# broadcast = !(data.dragging) # If fader is still dragging, don't broadcast
# mixer = @fillTrackVolumeObject(mixer.id, mixer.mode, broadcast)
relative = gainType == 'music' && (mixer.name == CategoryGroupIds.UserMedia || mixer.name == CategoryGroupIds.MediaTrack)
# relative = gainType == 'music' && (mixer.name == CategoryGroupIds.UserMedia || mixer.name == CategoryGroupIds.MediaTrack)
@setMixerVolume(mixer, data.percentage, relative, originalVolume)
# @setMixerVolume(mixer, data.percentage, relative, originalVolume)
# keep state of mixer in sync with backend
mixer = @getMixer(mixer.id, mixer.mode)
mixer.volume_left = context.trackVolumeObject.volL
# # keep state of mixer in sync with backend
# mixer = @getMixer(mixer.id, mixer.mode)
# mixer.volume_left = context.trackVolumeObject.volL
#if groupId == ChannelGroupIds.UserMusicInputGroup
# # there may be other mixers with this same ID in the case of a Peer Music Stream, so update them as well
# context.JK.FaderHelpers.setFaderValue(mixerId, data.percentage)
# #if groupId == ChannelGroupIds.UserMusicInputGroup
# # # there may be other mixers with this same ID in the case of a Peer Music Stream, so update them as well
# # context.JK.FaderHelpers.setFaderValue(mixerId, data.percentage)
faderChanged: `async function(data, mixers, gainType, controlGroup) {
if (!Array.isArray(mixers)) {
mixers = [mixers];
}
let originalVolume = this.getOriginalVolume(mixers, gainType);
if (controlGroup != null) {
mixers = [mixers[0]];
for (let mixer of mixers) {
let broadcast = !(data.dragging);
mixer = this.fillTrackVolumeObject(mixer.id, mixer.mode, broadcast);
let relative = gainType === 'music' && (mixer.name === CategoryGroupIds.UserMedia || mixer.name === CategoryGroupIds.MediaTrack);
await this.setMixerVolume(mixer, data.percentage, relative, originalVolume, controlGroup);
mixer = this.getMixer(mixer.id, mixer.mode);
mixer.volume_left = context.trackVolumeObject.volL;
}
} else {
for (let mixer of mixers) {
let broadcast = !(data.dragging);
mixer = this.fillTrackVolumeObject(mixer.id, mixer.mode, broadcast);
let relative = gainType === 'music' && (mixer.name === CategoryGroupIds.UserMedia || mixer.name === CategoryGroupIds.MediaTrack);
await this.setMixerVolume(mixer, data.percentage, relative, originalVolume);
mixer = this.getMixer(mixer.id, mixer.mode);
mixer.volume_left = context.trackVolumeObject.volL;
}
}
}`
initGain: (mixer) ->
if $.isArray(mixer)
@ -777,78 +817,163 @@ MIX_MODES = context.JK.MIX_MODES;
context.JK.FaderHelpers.setFaderValue(mixer.id, gainPercent)
context.JK.FaderHelpers.showFader(mixer.id)
panChanged: (data, mixers, groupId) ->
mixers = [mixers] unless $.isArray(mixers)
# media tracks are the only controls that sometimes set two mixers right now
for mixer in mixers
broadcast = !(data.dragging) # If fader is still dragging, don't broadcast
mixer = @fillTrackVolumeObject(mixer.id, mixer.mode, broadcast)
# panChanged: (data, mixers, groupId) ->
# mixers = [mixers] unless $.isArray(mixers)
# # media tracks are the only controls that sometimes set two mixers right now
# for mixer in mixers
# broadcast = !(data.dragging) # If fader is still dragging, don't broadcast
# mixer = @fillTrackVolumeObject(mixer.id, mixer.mode, broadcast)
@setMixerPan(mixer, data.percentage)
# @setMixerPan(mixer, data.percentage)
# keep state of mixer in sync with backend
mixer = @getMixer(mixer.id, mixer.mode)
mixer.pan = context.trackVolumeObject.pan
# # keep state of mixer in sync with backend
# mixer = @getMixer(mixer.id, mixer.mode)
# mixer.pan = context.trackVolumeObject.pan
panChanged: `function(data, mixers, groupId) {
if (!$.isArray(mixers)) { mixers = [mixers]; }
// media tracks are the only controls that sometimes set two mixers right now
return (async () => {
const result = [];
for (let mixer of Array.from(mixers)) {
const broadcast = !(data.dragging); // If fader is still dragging, do not broadcast
mixer = this.fillTrackVolumeObject(mixer.id, mixer.mode, broadcast);
await this.setMixerPan(mixer, data.percentage);
// keep state of mixer in sync with backend
mixer = this.getMixer(mixer.id, mixer.mode);
result.push(mixer.pan = context.trackVolumeObject.pan);
}
return result;
})();
}`
initPan: (mixer) ->
panPercent= context.JK.PanHelpers.convertPanToPercent(mixer.pan)
context.JK.FaderHelpers.setFaderValue(mixer.id, panPercent, Math.abs(mixer.pan))
context.JK.FaderHelpers.showFader(mixer.id)
setMixerPan: (mixer, panPercent) ->
# setMixerPan: (mixer, panPercent) ->
context.trackVolumeObject.pan = context.JK.PanHelpers.convertPercentToPan(panPercent);
context.jamClient.SessionSetControlState(mixer.id, mixer.mode);
# context.trackVolumeObject.pan = context.JK.PanHelpers.convertPercentToPan(panPercent);
# context.jamClient.SessionSetControlState(mixer.id, mixer.mode);
loopChanged: (mixer, shouldLoop) ->
setMixerPan: `async function(mixer, panPercent) {
context.trackVolumeObject.pan = context.JK.PanHelpers.convertPercentToPan(panPercent);
//await context.jamClient.SessionSetControlState(mixer.id, mixer.mode);
await context.jamClient.SessionSetTrackVolumeData(mixer.id, mixer.mode, context.trackVolumeObject);
}`
@fillTrackVolumeObject(mixer.id, mixer.mode)
context.trackVolumeObject.loop = shouldLoop
context.jamClient.SessionSetControlState(mixer.id, mixer.mode)
# loopChanged: (mixer, shouldLoop) ->
# keep state of mixer in sync with backend
mixer = @getMixer(mixer.id, mixer.mode)
mixer.loop = context.trackVolumeObject.loop
# @fillTrackVolumeObject(mixer.id, mixer.mode)
# context.trackVolumeObject.loop = shouldLoop
# context.jamClient.SessionSetControlState(mixer.id, mixer.mode)
setMixerVolume: (mixer, volumePercent, relative, originalVolume, controlGroup) ->
###
// The context.trackVolumeObject has been filled with the mixer values
// that go with mixerId, and the range of that mixer
// has been set in currentMixerRangeMin-Max.
// All that needs doing is to translate the incoming percent
// into the real value ont the sliders range. Set Left/Right
// volumes on trackVolumeObject, and call SetControlState to stick.
###
# # keep state of mixer in sync with backend
# mixer = @getMixer(mixer.id, mixer.mode)
# mixer.loop = context.trackVolumeObject.loop
newVolume = context.JK.FaderHelpers.convertPercentToAudioTaper(volumePercent);
if relative
context.trackVolumeObject.volL = context.trackVolumeObject.volL + (newVolume - originalVolume)
context.trackVolumeObject.volR = context.trackVolumeObject.volR + (newVolume - originalVolume)
loopChanged: `async function (mixer, shouldLoop) {
# keep within range
if context.trackVolumeObject.volL < -80
context.trackVolumeObject.volL = -80
else if context.trackVolumeObject.volL > 20
context.trackVolumeObject.volL = 20
this.fillTrackVolumeObject(mixer.id, mixer.mode);
context.trackVolumeObject.loop = shouldLoop;
//await context.jamClient.SessionSetControlState(mixer.id, mixer.mode);
await context.jamClient.SessionSetTrackVolumeData(mixer.id, mixer.mode, context.trackVolumeObject);
if context.trackVolumeObject.volR < -80
context.trackVolumeObject.volR = -80
else if context.trackVolumeObject.volR > 20
context.trackVolumeObject.volR = 20
// keep state of mixer in sync with backend
mixer = this.getMixer(mixer.id, mixer.mode);
mixer.loop = context.trackVolumeObject.loop;
}`
# setMixerVolume: (mixer, volumePercent, relative, originalVolume, controlGroup) ->
# ###
# // The context.trackVolumeObject has been filled with the mixer values
# // that go with mixerId, and the range of that mixer
# // has been set in currentMixerRangeMin-Max.
# // All that needs doing is to translate the incoming percent
# // into the real value ont the sliders range. Set Left/Right
# // volumes on trackVolumeObject, and call SetControlState to stick.
# ###
# newVolume = context.JK.FaderHelpers.convertPercentToAudioTaper(volumePercent);
# if relative
# context.trackVolumeObject.volL = context.trackVolumeObject.volL + (newVolume - originalVolume)
# context.trackVolumeObject.volR = context.trackVolumeObject.volR + (newVolume - originalVolume)
# # keep within range
# if context.trackVolumeObject.volL < -80
# context.trackVolumeObject.volL = -80
# else if context.trackVolumeObject.volL > 20
# context.trackVolumeObject.volL = 20
# if context.trackVolumeObject.volR < -80
# context.trackVolumeObject.volR = -80
# else if context.trackVolumeObject.volR > 20
# context.trackVolumeObject.volR = 20
else
context.trackVolumeObject.volL = newVolume
context.trackVolumeObject.volR = newVolume
if controlGroup?
# else
# context.trackVolumeObject.volL = newVolume
# context.trackVolumeObject.volR = newVolume
# if controlGroup?
if mixer.mode == MIX_MODES.PERSONAL
controlGroupsArg = 0
else
controlGroupsArg = 1
context.jamClient.setSessionMixerCategoryPlayoutState(controlGroup == 'music', controlGroupsArg);
else
context.jamClient.SessionSetControlState(mixer.id, mixer.mode);
# if mixer.mode == MIX_MODES.PERSONAL
# controlGroupsArg = 0
# else
# controlGroupsArg = 1
# context.jamClient.setSessionMixerCategoryPlayoutState(controlGroup == 'music', controlGroupsArg);
# else
# context.jamClient.SessionSetControlState(mixer.id, mixer.mode);
setMixerVolume: `async function(mixer, volumePercent, relative, originalVolume, controlGroup) {
/*
// The context.trackVolumeObject has been filled with the mixer values
// that go with mixerId, and the range of that mixer
// has been set in currentMixerRangeMin-Max.
// All that needs doing is to translate the incoming percent
// into the real value ont the sliders range. Set Left/Right
// volumes on trackVolumeObject, and call SetControlState to stick.
*/
const newVolume = context.JK.FaderHelpers.convertPercentToAudioTaper(volumePercent);
if (relative) {
context.trackVolumeObject.volL = context.trackVolumeObject.volL + (newVolume - originalVolume);
context.trackVolumeObject.volR = context.trackVolumeObject.volR + (newVolume - originalVolume);
// keep within range
if (context.trackVolumeObject.volL < -80) {
context.trackVolumeObject.volL = -80;
} else if (context.trackVolumeObject.volL > 20) {
context.trackVolumeObject.volL = 20;
}
if (context.trackVolumeObject.volR < -80) {
context.trackVolumeObject.volR = -80;
} else if (context.trackVolumeObject.volR > 20) {
context.trackVolumeObject.volR = 20;
}
} else {
context.trackVolumeObject.volL = newVolume;
context.trackVolumeObject.volR = newVolume;
}
if (controlGroup != null) {
let controlGroupsArg;
if (mixer.mode === MIX_MODES.PERSONAL) {
controlGroupsArg = 0;
} else {
controlGroupsArg = 1;
}
await context.jamClient.setSessionMixerCategoryPlayoutState(controlGroup === 'music', controlGroupsArg);
} else {
//await context.jamClient.SessionSetControlState(mixer.id, mixer.mode);
await context.jamClient.SessionSetTrackVolumeData(mixer.id, mixer.mode, context.trackVolumeObject);
}
}`
percentFromMixerValue: (min, max, value) ->
try
@ -880,6 +1005,9 @@ MIX_MODES = context.JK.MIX_MODES;
_broadcast = broadcast
mixer = @getMixer(mixerId, mode)
context.trackVolumeObject.id = mixer.id
context.trackVolumeObject._id = mixer._id
context.trackVolumeObject.groupID = mixer.group_id
context.trackVolumeObject.clientID = mixer.client_id
context.trackVolumeObject.broadcast = _broadcast
context.trackVolumeObject.master = mixer.master
@ -889,6 +1017,9 @@ MIX_MODES = context.JK.MIX_MODES;
context.trackVolumeObject.record = mixer.record
context.trackVolumeObject.volL = mixer.volume_left
context.trackVolumeObject.pan = mixer.pan
context.trackVolumeObject.mediaType = mixer.media_type
context.trackVolumeObject.isJamTrack = mixer.is_jam_track
context.trackVolumeObject.isMetronome = mixer.is_metronome
# today we treat all tracks as mono, but this is required to make a stereo track happy
# context.trackVolumeObject.volR = mixer.volume_right;
@ -937,8 +1068,12 @@ MIX_MODES = context.JK.MIX_MODES;
# Do the right
context.JK.VuHelpers.updateVU2('vur', mixer, value)
###
getTrackInfo: () ->
context.JK.TrackHelpers.getTrackInfo(context.jamClient, @masterMixers)
# getTrackInfo: () ->
# context.JK.TrackHelpers.getTrackInfo(context.jamClient, @masterMixers)
getTrackInfo: `async function() {
return await context.JK.TrackHelpers.getTrackInfo(context.jamClient, this.masterMixers);
}`
getGroupMixer: (categoryId, mode) ->
groupId = if mode == MIX_MODES.MASTER then ChannelGroupIds.MasterCatGroup else ChannelGroupIds.MonitorCatGroup

View File

@ -0,0 +1,49 @@
context = window
@BetaDownloadLandingBottomPage = React.createClass({
render: () ->
`<div className="top-container">
<div className="row awesome">
<h2 className="awesome">Updating to the JamKazam BETA App</h2>
<p>The JamKazam BETA app installs exactly the same as the previous versions of JamKazam. By using this version
of the client, you will be able to play with other beta users, as well as users still on the current
production version. If at any time you want to go back to the current (non-BETA) version of the application,
just install the version of JamKazam found on our <a href="/downloads">downloads</a>.
</p>
<br/>
<p>Below are the typical installation instructions:</p>
</div>
<div className="row awesome-thing">
<div className="awesome-item">
<h3> <div className="awesome-number">1</div>Download the application.</h3>
<p>
Download the application by choosing your platform in the above section.
<div className="clearall" />
</p>
</div>
</div>
<div className="row awesome-thing">
<div className="awesome-item">
<h3> <div className="awesome-number">2</div>Run the installer</h3>
<p>
On Windows, double-click the .msi file and follow all the prompts to update your JamKazam application to
the BETA version. On Mac OS, double-click the .dmg file, and drag the JamKazam icon to the Application
folder in the window that opens, and selecting 'Replace' if prompted.
<div className="clearall" />
</p>
</div>
</div>
<div className="row awesome-thing">
<div className="awesome-item">
<h3> <div className="awesome-number">3</div>Launch the application</h3>
<p>
Launch the application exactly as you did before!
<div className="clearall" />
</p>
</div>
</div>
</div>`
})

View File

@ -0,0 +1,61 @@
context = window
rest = context.JK.Rest()
@BetaDownloadLandingPage = React.createClass({
render: () ->
if this.state.done
ctaButtonText10 = 'sending you in...'
ctaButtonText20 = 'sending you in...'
else if this.state.processing
ctaButtonText10 = 'hold on...'
ctaButtonText20 = 'hold on...'
else
ctaButtonText10 = `<span>ADD $10 CARD<br/>TO CART</span>`
ctaButtonText20 = `<span>ADD $20 CARD<br/>TO CART</span>`
`<div className="top-container">
<div className="full-row name-and-artist">
</div>
<div className="row summary-text">
<p className="top-summary">
The JamKazam BETA app is now ready for download!<br/><br/>We've updated the client to support Windows 10, Windows 11, Mac M1/M2, and Mac Intel.<br/>All JamKazam internals are completely upgraded, resulting in better video, clearer backing tracks & JamTracks, and countless other improvements.
</p>
</div>
</div>`
getInitialState: () ->
{processing:false}
componentDidMount:() ->
$root = $(this.getDOMNode())
# add item to cart, create the user if necessary, and then place the order to get the free JamTrack.
ctaClick: (card_type, e) ->
e.preventDefault()
return if @state.processing
loggedIn = context.JK.currentUserId?
rest.addGiftCardToShoppingCart({id: card_type}).done((response) =>
if loggedIn
@setState({done: true})
context.location = '/client#/shoppingCart'
else
@setState({done: true})
context.location = '/client#/shoppingCart'
).fail((jqXHR, textStatus, errorMessage) =>
if jqXHR.status == 422
errors = JSON.parse(jqXHR.responseText)
cart_errors = errors?.errors?.cart_id
context.JK.app.ajaxError(jqXHR, textStatus, errorMessage)
@setState({processing:false})
)
})

View File

@ -21,6 +21,7 @@ logger = context.JK.logger
else
mediaCategoryMixer = mixers.getUserMediaCategoryMixer(@props.mode)
console.log('_DEBUG_ mediaCategoryMixer', mediaCategoryMixer)
state =
isRecording: session.isRecording
mediaSummary: mixers.mediaSummary

View File

@ -15,11 +15,19 @@ VideoLiveStreamActions = @VideoLiveStreamActions
# Register with the app store to get @app
this.listenTo(context.AppStore, this.onAppInit)
onAppInit: (@app) ->
if context.jamClient.RegisterGenericCallBack?
console.log("REGISTERING GENERIC CALLBACK")
context.jamClient.RegisterGenericCallBack('CallbackStore.onGenericCallback')
#context.jamClient.RegisterGenericCallBack('StupidCallback')
# onAppInit: (@app) ->
# if context.jamClient.RegisterGenericCallBack?
# console.log("REGISTERING GENERIC CALLBACK")
# context.jamClient.RegisterGenericCallBack('CallbackStore.onGenericCallback')
# #context.jamClient.RegisterGenericCallBack('StupidCallback')
onAppInit: `async function(app) {
this.app = app;
//if (context.jamClient.RegisterGenericCallBack != null) {
console.log("REGISTERING GENERIC CALLBACK");
return await context.jamClient.RegisterGenericCallBack('CallbackStore.onGenericCallback');
//}
}`
onGenericCallback: (map) ->
console.log("GENERIC CALLBACK CALLED: ", map)

View File

@ -0,0 +1,22 @@
context = window
@ExternalVideoStore = Reflux.createStore(
{
listenables: ExternalVideoActions
state : null
init: () ->
this.listenTo(context.AppStore, this.onAppInit)
this.state = {
videoEnabled: false
}
onAppInit: (@app) ->
# on app init
onSetVideoEnabled: (enable) ->
console.log('ExternalVideoStore.onSetVideoEnabled', enable)
@state.videoEnabled = enable
this.trigger(this.state)
}
)

View File

@ -28,122 +28,257 @@ logger = context.JK.logger
else
context.JK.Banner.showAlert('unable to update the JamBlaster', msg)
onUpdateAudio: (name, value) ->
# input1_linemode
# input2_linemode
# input1_48V
# input2_48V
# has_chat
# track1 = {left, right, inst, stereo)
# track1 = {left, right, inst, stereo)
# onUpdateAudio: (name, value) ->
# # input1_linemode
# # input2_linemode
# # input1_48V
# # input2_48V
# # has_chat
# # track1 = {left, right, inst, stereo)
# # track1 = {left, right, inst, stereo)
if @pairedJamBlaster? && @pairedJamBlaster.tracks?
logger.debug("onUpdateAudio name=#{name} value=#{value}", @pairedJamBlaster.tracks)
# if @pairedJamBlaster? && @pairedJamBlaster.tracks?
# logger.debug("onUpdateAudio name=#{name} value=#{value}", @pairedJamBlaster.tracks)
if name == 'inputTypeTrack1'
result = context.jamClient.set48vAndLineInstState({input1_linemode: value})
@postSimpleChange(result, 'Unable to set the line mode for Track 1')
return
# if name == 'inputTypeTrack1'
# result = context.jamClient.set48vAndLineInstState({input1_linemode: value})
# @postSimpleChange(result, 'Unable to set the line mode for Track 1')
# return
else if name == 'inputTypeTrack2'
result = context.jamClient.set48vAndLineInstState({input2_linemode: value})
@postSimpleChange(result, 'Unable to set the line mode for Track 2')
return
# else if name == 'inputTypeTrack2'
# result = context.jamClient.set48vAndLineInstState({input2_linemode: value})
# @postSimpleChange(result, 'Unable to set the line mode for Track 2')
# return
else if name == 'track1Phantom'
result = context.jamClient.set48vAndLineInstState({input1_48V: value})
@postSimpleChange(result, 'Unable to set the phantom power for Track 1')
return
# else if name == 'track1Phantom'
# result = context.jamClient.set48vAndLineInstState({input1_48V: value})
# @postSimpleChange(result, 'Unable to set the phantom power for Track 1')
# return
else if name == 'track2Phantom'
result = context.jamClient.set48vAndLineInstState({input2_48V: value})
@postSimpleChange(result, 'Unable to set the phantom power for Track 2')
return
# else if name == 'track2Phantom'
# result = context.jamClient.set48vAndLineInstState({input2_48V: value})
# @postSimpleChange(result, 'Unable to set the phantom power for Track 2')
# return
#else if name == 'track1Instrument'
# result = context.jamClient.set48vAndLineInstState({input2_48V: value})
# @postSimpleChange(result, 'Unable to set the phantom power for Track 2')
# return
# #else if name == 'track1Instrument'
# # result = context.jamClient.set48vAndLineInstState({input2_48V: value})
# # @postSimpleChange(result, 'Unable to set the phantom power for Track 2')
# # return
#else if name == 'track1Instrument'
# result = context.jamClient.set48vAndLineInstState({input2_48V: value})
# @postSimpleChange(result, 'Unable to set the phantom power for Track 2')
# return
# #else if name == 'track1Instrument'
# # result = context.jamClient.set48vAndLineInstState({input2_48V: value})
# # @postSimpleChange(result, 'Unable to set the phantom power for Track 2')
# # return
audio = $.extend({}, @pairedJamBlaster.tracks)
if name == 'inputTypeTrack1'
audio.input1_linemode = value
else if name == 'inputTypeTrack2'
audio.input2_linemode = value
else if name == 'track1Phantom'
audio.input1_48V = value
else if name == 'track2Phantom'
audio.input2_48V = value
else if name == 'micActive'
audio.has_chat = value
# audio = $.extend({}, @pairedJamBlaster.tracks)
# if name == 'inputTypeTrack1'
# audio.input1_linemode = value
# else if name == 'inputTypeTrack2'
# audio.input2_linemode = value
# else if name == 'track1Phantom'
# audio.input1_48V = value
# else if name == 'track2Phantom'
# audio.input2_48V = value
# else if name == 'micActive'
# audio.has_chat = value
#track1Active = @pairedJamBlaster.tracks.track1Active
#if name == 'track1Active'
# track1Active = value
# #track1Active = @pairedJamBlaster.tracks.track1Active
# #if name == 'track1Active'
# # track1Active = value
#track2Active = @pairedJamBlaster.tracks.track2Active
#if name == 'track2Active'
# track2Active = value
# #track2Active = @pairedJamBlaster.tracks.track2Active
# #if name == 'track2Active'
# # track2Active = value
track1Active = true
track2Active = true
has_chat = true
# track1Active = true
# track2Active = true
# has_chat = true
audio.has_chat = true
# audio.has_chat = true
combined = @pairedJamBlaster.tracks.combined
if name == 'combined'
combined = value
# combined = @pairedJamBlaster.tracks.combined
# if name == 'combined'
# combined = value
track1Instrument = @pairedJamBlaster.tracks.track1Instrument
track2Instrument = @pairedJamBlaster.tracks.track2Instrument
if name == 'track1Instrument'
track1Instrument = @convertToClientInstrument(value)
if name == 'track2Instrument'
track2Instrument = @convertToClientInstrument(value)
# track1Instrument = @pairedJamBlaster.tracks.track1Instrument
# track2Instrument = @pairedJamBlaster.tracks.track2Instrument
# if name == 'track1Instrument'
# track1Instrument = @convertToClientInstrument(value)
# if name == 'track2Instrument'
# track2Instrument = @convertToClientInstrument(value)
if !track1Instrument
track1Instrument = context.JK.server_to_client_instrument_map.Other.client_id
if !track2Instrument
track2Instrument = context.JK.server_to_client_instrument_map.Other.client_id
# if !track1Instrument
# track1Instrument = context.JK.server_to_client_instrument_map.Other.client_id
# if !track2Instrument
# track2Instrument = context.JK.server_to_client_instrument_map.Other.client_id
if combined
# user has chosen to combine both inputs into one track. stereo=true is the key flag her
# if combined
# # user has chosen to combine both inputs into one track. stereo=true is the key flag her
audio.track1 = {stereo: true, left: true, inst: track1Instrument}
delete audio.track2 # backend will treat null as present
# audio.track1 = {stereo: true, left: true, inst: track1Instrument}
# delete audio.track2 # backend will treat null as present
else
# else
if track1Active && track2Active
# if track1Active && track2Active
audio.track1 = {stereo: false, left: true, inst: track1Instrument}
audio.track2 = {stereo: false, right: true, inst: track2Instrument}
# audio.track1 = {stereo: false, left: true, inst: track1Instrument}
# audio.track2 = {stereo: false, right: true, inst: track2Instrument}
else if track1Active #(means track)
# else if track1Active #(means track)
audio.track1 = {stereo: false, left: true, inst: track1Instrument}
delete audio.track2 # backend will treat null as present
# audio.track1 = {stereo: false, left: true, inst: track1Instrument}
# delete audio.track2 # backend will treat null as present
else # input2Active
# else # input2Active
audio.track2 = {stereo: false, right: true, inst: track2Instrument}
delete audio.track1 # backend will treat null as present
# audio.track2 = {stereo: false, right: true, inst: track2Instrument}
# delete audio.track1 # backend will treat null as present
logger.debug("updating JamBlaster track state", audio)
context.jamClient.setJbTrackState(audio);
@waitOnTracks()
else
context.JK.Banner.showAlert('no paired JamBlaster', 'it seems your JamBlaster has become disconnected. Please ensure it is powered on and connected via an ethernet cable.')
# logger.debug("updating JamBlaster track state", audio)
# context.jamClient.setJbTrackState(audio);
# @waitOnTracks()
# else
# context.JK.Banner.showAlert('no paired JamBlaster', 'it seems your JamBlaster has become disconnected. Please ensure it is powered on and connected via an ethernet cable.')
onUpdateAudio: `async function(name, value) {
// input1_linemode
// input2_linemode
// input1_48V
// input2_48V
// has_chat
// track1 = {left, right, inst, stereo)
// track1 = {left, right, inst, stereo)
if ((this.pairedJamBlaster != null) && (this.pairedJamBlaster.tracks != null)) {
let result;
logger.debug('onUpdateAudio name='+name+' value='+value, this.pairedJamBlaster.tracks);
if (name === 'inputTypeTrack1') {
result = await context.jamClient.set48vAndLineInstState({input1_linemode: value});
this.postSimpleChange(result, 'Unable to set the line mode for Track 1');
return;
} else if (name === 'inputTypeTrack2') {
result = await context.jamClient.set48vAndLineInstState({input2_linemode: value});
this.postSimpleChange(result, 'Unable to set the line mode for Track 2');
return;
} else if (name === 'track1Phantom') {
result = await context.jamClient.set48vAndLineInstState({input1_48V: value});
this.postSimpleChange(result, 'Unable to set the phantom power for Track 1');
return;
} else if (name === 'track2Phantom') {
result = await context.jamClient.set48vAndLineInstState({input2_48V: value});
this.postSimpleChange(result, 'Unable to set the phantom power for Track 2');
return;
}
//else if name == 'track1Instrument'
// result = context.jamClient.set48vAndLineInstState({input2_48V: value})
// @postSimpleChange(result, 'Unable to set the phantom power for Track 2')
// return
//else if name == 'track1Instrument'
// result = context.jamClient.set48vAndLineInstState({input2_48V: value})
// @postSimpleChange(result, 'Unable to set the phantom power for Track 2')
// return
const audio = $.extend({}, this.pairedJamBlaster.tracks);
if (name === 'inputTypeTrack1') {
audio.input1_linemode = value;
} else if (name === 'inputTypeTrack2') {
audio.input2_linemode = value;
} else if (name === 'track1Phantom') {
audio.input1_48V = value;
} else if (name === 'track2Phantom') {
audio.input2_48V = value;
} else if (name === 'micActive') {
audio.has_chat = value;
}
//track1Active = @pairedJamBlaster.tracks.track1Active
//if name == 'track1Active'
// track1Active = value
//track2Active = @pairedJamBlaster.tracks.track2Active
//if name == 'track2Active'
// track2Active = value
const track1Active = true;
const track2Active = true;
const has_chat = true;
audio.has_chat = true;
let {
combined
} = this.pairedJamBlaster.tracks;
if (name === 'combined') {
combined = value;
}
let {
track1Instrument
} = this.pairedJamBlaster.tracks;
let {
track2Instrument
} = this.pairedJamBlaster.tracks;
if (name === 'track1Instrument') {
track1Instrument = this.convertToClientInstrument(value);
}
if (name === 'track2Instrument') {
track2Instrument = this.convertToClientInstrument(value);
}
if (!track1Instrument) {
track1Instrument = context.JK.server_to_client_instrument_map.Other.client_id;
}
if (!track2Instrument) {
track2Instrument = context.JK.server_to_client_instrument_map.Other.client_id;
}
if (combined) {
// user has chosen to combine both inputs into one track. stereo=true is the key flag her
audio.track1 = {stereo: true, left: true, inst: track1Instrument};
delete audio.track2; // backend will treat null as present
} else {
if (track1Active && track2Active) {
audio.track1 = {stereo: false, left: true, inst: track1Instrument};
audio.track2 = {stereo: false, right: true, inst: track2Instrument};
} else if (track1Active) { //(means track)
audio.track1 = {stereo: false, left: true, inst: track1Instrument};
delete audio.track2; // backend will treat null as present
} else { // input2Active
audio.track2 = {stereo: false, right: true, inst: track2Instrument};
delete audio.track1; // backend will treat null as present
}
}
logger.debug("updating JamBlaster track state", audio);
await context.jamClient.setJbTrackState(audio);
return this.waitOnTracks();
} else {
context.JK.Banner.showAlert('no paired JamBlaster', 'it seems your JamBlaster has become disconnected. Please ensure it is powered on and connected via an ethernet cable.');
}
}`
waitOnTracks: () ->
@lastClientTrackState = null
@ -177,28 +312,52 @@ logger = context.JK.logger
clientInstrumentId = 10
clientInstrumentId
onSetAutoPair: (autopair) ->
# onSetAutoPair: (autopair) ->
if !autopair
context.jamClient.setJBAutoPair(autopair)
@lastClientAutoPair = null
JamBlasterActions.resyncBonjour()
setTimeout((() => context.JK.Banner.showNotice("autoconnect removed",
"To use the JamBlaster in the future, you will need to come to this screen and click the connect link.")), 1)
else
# if !autopair
# context.jamClient.setJBAutoPair(autopair)
# @lastClientAutoPair = null
# JamBlasterActions.resyncBonjour()
# setTimeout((() => context.JK.Banner.showNotice("autoconnect removed",
# "To use the JamBlaster in the future, you will need to come to this screen and click the connect link.")), 1)
# else
# context.JK.Banner.showYesNo({
# title: "enable auto-connect",
# html: "If you would like to automatically connect to your JamBlaster whenever you start this app, click the AUTO CONNECT button below.",
# yes_text: 'AUTO CONNECT',
# yes: =>
# context.jamClient.setJBAutoPair(autopair)
# @lastClientAutoPair = null
# JamBlasterActions.resyncBonjour()
# setTimeout((() => context.JK.Banner.showNotice("autoconnect enabled",
# "Your desktop JamKazam application will automatically reconnect to the JamBlaster .")), 1)
# })
onSetAutoPair: `async function(autopair) {
if (!autopair) {
await context.jamClient.setJBAutoPair(autopair);
this.lastClientAutoPair = null;
JamBlasterActions.resyncBonjour();
return setTimeout((() => context.JK.Banner.showNotice("autoconnect removed",
"To use the JamBlaster in the future, you will need to come to this screen and click the connect link.")), 1);
} else {
context.JK.Banner.showYesNo({
title: "enable auto-connect",
html: "If you would like to automatically connect to your JamBlaster whenever you start this app, click the AUTO CONNECT button below.",
yes_text: 'AUTO CONNECT',
yes: =>
context.jamClient.setJBAutoPair(autopair)
@lastClientAutoPair = null
JamBlasterActions.resyncBonjour()
setTimeout((() => context.JK.Banner.showNotice("autoconnect enabled",
"Your desktop JamKazam application will automatically reconnect to the JamBlaster .")), 1)
yes: async () => {
await context.jamClient.setJBAutoPair(autopair);
this.lastClientAutoPair = null;
JamBlasterActions.resyncBonjour();
return setTimeout((() => context.JK.Banner.showNotice("autoconnect enabled",
"Your desktop JamKazam application will automatically reconnect to the JamBlaster .")), 1);
}
})
});
}
}`
onPairState: (state) ->
if state.client_pair_state == 10
@ -206,20 +365,37 @@ logger = context.JK.logger
logger.debug("backend indicates we are paired with a client")
@onResyncBonjour()
onSaveNetworkSettings: (settings) ->
logger.debug("onSaveNetworkSettings", settings)
# onSaveNetworkSettings: (settings) ->
# logger.debug("onSaveNetworkSettings", settings)
result = context.jamClient.setJbNetworkState(settings)
if !result
context.JK.Banner.showAlert('unable to save network settings', 'Please double-check that your JamBlaster is online and paired.')
return
else
context.JK.Banner.showAlert('network settings updated', 'Please reboot the JamBlaster.')
# it will be refreshed by backend
setTimeout(()=>
@onClearNetworkState()
@onResyncBonjour()
, 1000)
# result = context.jamClient.setJbNetworkState(settings)
# if !result
# context.JK.Banner.showAlert('unable to save network settings', 'Please double-check that your JamBlaster is online and paired.')
# return
# else
# context.JK.Banner.showAlert('network settings updated', 'Please reboot the JamBlaster.')
# # it will be refreshed by backend
# setTimeout(()=>
# @onClearNetworkState()
# @onResyncBonjour()
# , 1000)
onSaveNetworkSettings: `async function(settings) {
logger.debug("onSaveNetworkSettings", settings);
const result = await context.jamClient.setJbNetworkState(settings);
if (!result) {
context.JK.Banner.showAlert('unable to save network settings', 'Please double-check that your JamBlaster is online and paired.');
} else {
context.JK.Banner.showAlert('network settings updated', 'Please reboot the JamBlaster.');
// it will be refreshed by backend
setTimeout(()=> {
this.onClearNetworkState();
this.onResyncBonjour();
}
, 1000);
}
}`
onResyncBonjour: () ->
@ -277,28 +453,55 @@ logger = context.JK.logger
else
return @getJbPortBindState(client)
getJbPortBindState:(client) ->
@lastClientPortState = context.jamClient.getJbPortBindState()
console.log("context.jamClient.getJbPortBindState()", @lastClientPortState)
@lastClientPortState.ipv6_addr = client.ipv6_addr
return @lastClientPortState
# getJbPortBindState:(client) ->
# @lastClientPortState = context.jamClient.getJbPortBindState()
# console.log("context.jamClient.getJbPortBindState()", @lastClientPortState)
# @lastClientPortState.ipv6_addr = client.ipv6_addr
# return @lastClientPortState
getJbNetworkState:(client) ->
@lastClientNetworkState = context.jamClient.getJbNetworkState()
console.log("context.jamClient.getJbNetworkState()", @lastClientNetworkState)
@lastClientNetworkState.ipv6_addr = client.ipv6_addr
return @lastClientNetworkState
getJbPortBindState: `async function(client) {
this.lastClientPortState = await context.jamClient.getJbPortBindState();
console.log("context.jamClient.getJbPortBindState()", this.lastClientPortState);
this.lastClientPortState.ipv6_addr = client.ipv6_addr;
return this.lastClientPortState;
}`
getJbAutoPair:() ->
@lastClientAutoPair = context.jamClient.getJBAutoPair()
console.log("context.jamClient.getJBAutoPair()", @lastClientAutoPair)
return @lastClientAutoPair
# getJbNetworkState:(client) ->
# @lastClientNetworkState = context.jamClient.getJbNetworkState()
# console.log("context.jamClient.getJbNetworkState()", @lastClientNetworkState)
# @lastClientNetworkState.ipv6_addr = client.ipv6_addr
# return @lastClientNetworkState
getJbTrackState:(client) ->
@lastClientTrackState = context.jamClient.getJbTrackState()
console.log("context.jamClient.getJbTrackState()", @lastClientTrackState)
@lastClientTrackState.ipv6_addr = client.ipv6_addr
return @lastClientTrackState
getJbNetworkState: `async function(client) {
this.lastClientNetworkState = await context.jamClient.getJbNetworkState();
console.log("context.jamClient.getJbNetworkState()", this.lastClientNetworkState);
this.lastClientNetworkState.ipv6_addr = client.ipv6_addr;
return this.lastClientNetworkState;
}`
# getJbAutoPair:() ->
# @lastClientAutoPair = context.jamClient.getJBAutoPair()
# console.log("context.jamClient.getJBAutoPair()", @lastClientAutoPair)
# return @lastClientAutoPair
getJbAutoPair: `async function() {
this.lastClientAutoPair = await context.jamClient.getJBAutoPair();
console.log("context.jamClient.getJBAutoPair()", this.lastClientAutoPair);
return this.lastClientAutoPair;
}`
# getJbTrackState:(client) ->
# @lastClientTrackState = context.jamClient.getJbTrackState()
# console.log("context.jamClient.getJbTrackState()", @lastClientTrackState)
# @lastClientTrackState.ipv6_addr = client.ipv6_addr
# return @lastClientTrackState
getJbTrackState: `async function(client) {
this.lastClientTrackState = await context.jamClient.getJbTrackState();
console.log("context.jamClient.getJbTrackState()", this.lastClientTrackState);
this.lastClientTrackState.ipv6_addr = client.ipv6_addr;
return this.lastClientTrackState;
}`
onClearPortBindState: () ->
@lastClientPortState = null
@ -413,17 +616,31 @@ logger = context.JK.logger
@clients = clients
@changed()
getLocalClients: (userJamBlasters) ->
@localClients = context.jamClient.getLocalClients()
# getLocalClients: (userJamBlasters) ->
# @localClients = context.jamClient.getLocalClients()
@mergeBonjourClients(@localClients, userJamBlasters)
# @mergeBonjourClients(@localClients, userJamBlasters)
@refreshingBonjour = false
@changed()
# @refreshingBonjour = false
# @changed()
get48vAndLineState: () ->
@phantomAndLineState = context.jamClient.get48vAndLineInstState()
console.log("get48vAndLineInstState", @phantomAndLineState)
getLocalClients: `async function(userJamBlasters) {
this.localClients = await context.jamClient.getLocalClients();
this.mergeBonjourClients(this.localClients, userJamBlasters);
this.refreshingBonjour = false;
return this.changed();
}`
# get48vAndLineState: () ->
# @phantomAndLineState = context.jamClient.get48vAndLineInstState()
# console.log("get48vAndLineInstState", @phantomAndLineState)
get48vAndLineState: `async function() {
this.phantomAndLineState = await context.jamClient.get48vAndLineInstState();
console.log("get48vAndLineInstState", this.phantomAndLineState);
}`
changed: () ->

View File

@ -203,20 +203,35 @@ JamTrackActions = @JamTrackActions
else
logger.debug("JamTrackStore: already downloading")
attemptKeying: () ->
if @keyCheckTimeout?
logger.debug("JamTrackStore: attemptKeying: skipping because already keying")
return
else if @jamTrack.activeMixdown.client_state == 'keying_timeout'
# if we have timed out keying, we shouldn't automatically retry
logger.debug("JamTrackStore: attempKeying: skipping because we have timed out before and user hasn't requested RETRY")
return
else
@keyCheckTimeout = setTimeout(@onKeyCheckTimeout, 10000)
@keyCheckoutInterval = setInterval(@checkOnKeying, 1000)
@jamTrack.activeMixdown.client_state = 'keying'
logger.debug("JamTrackStore: initiating keying requested")
context.jamClient.JamTrackKeysRequest()
# attemptKeying: () ->
# if @keyCheckTimeout?
# logger.debug("JamTrackStore: attemptKeying: skipping because already keying")
# return
# else if @jamTrack.activeMixdown.client_state == 'keying_timeout'
# # if we have timed out keying, we shouldn't automatically retry
# logger.debug("JamTrackStore: attempKeying: skipping because we have timed out before and user hasn't requested RETRY")
# return
# else
# @keyCheckTimeout = setTimeout(@onKeyCheckTimeout, 10000)
# @keyCheckoutInterval = setInterval(@checkOnKeying, 1000)
# @jamTrack.activeMixdown.client_state = 'keying'
# logger.debug("JamTrackStore: initiating keying requested")
# context.jamClient.JamTrackKeysRequest()
attemptKeying: `async function() {
if (this.keyCheckTimeout != null) {
logger.debug("JamTrackStore: attemptKeying: skipping because already keying");
} else if (this.jamTrack.activeMixdown.client_state === 'keying_timeout') {
// if we have timed out keying, we should not automatically retry
logger.debug("JamTrackStore: attempKeying: skipping because we have timed out before and user hasn't requested RETRY");
} else {
this.keyCheckTimeout = setTimeout(this.onKeyCheckTimeout, 10000);
this.keyCheckoutInterval = setInterval(this.checkOnKeying, 1000);
this.jamTrack.activeMixdown.client_state = 'keying';
logger.debug("JamTrackStore: initiating keying requested");
await context.jamClient.JamTrackKeysRequest();
}
}`
onKeyCheckTimeout: () ->
@keyCheckTimeout = null
@ -262,19 +277,35 @@ JamTrackActions = @JamTrackActions
this.trigger(@state)
onOpen: (jamTrack) ->
if @jamTrack?
@app.notify({text: 'Unable to open JamTrack because another one is already open.'})
return
# onOpen: (jamTrack) ->
# if @jamTrack?
# @app.notify({text: 'Unable to open JamTrack because another one is already open.'})
# return
@enqueuedMixdowns = {}
@jamTrack = jamTrack
# @enqueuedMixdowns = {}
# @jamTrack = jamTrack
# we can cache this because you can't switch gear while in a session (and possible change sample rate!)
sampleRate = context.jamClient.GetSampleRate()
@sampleRate = if sampleRate == 48 then 48 else 44
# # we can cache this because you can't switch gear while in a session (and possible change sample rate!)
# sampleRate = context.jamClient.GetSampleRate()
# @sampleRate = if sampleRate == 48 then 48 else 44
@changed()
# @changed()
onOpen: `async function(jamTrack) {
if (this.jamTrack != null) {
this.app.notify({text: 'Unable to open JamTrack because another one is already open.'});
return;
}
this.enqueuedMixdowns = {};
this.jamTrack = jamTrack;
// we can cache this because you can not switch gear while in a session (and possible change sample rate!)
const sampleRate = await context.jamClient.GetSampleRate();
this.sampleRate = sampleRate === 48 ? 48 : 44;
return this.changed();
}`
onClose: () ->
@jamTrack = null
@ -300,31 +331,59 @@ JamTrackActions = @JamTrackActions
@requestedFilter = null
requested
onCreateMixdown: (mixdown, done, fail) ->
# onCreateMixdown: (mixdown, done, fail) ->
volumeSettings = context.jamClient.GetJamTrackSettings();
# volumeSettings = context.jamClient.GetJamTrackSettings();
track_settings = []
# track_settings = []
for track in volumeSettings.tracks
track_settings.push({id: track.id, pan: track.pan, vol: track.vol_l, mute: track.mute})
# for track in volumeSettings.tracks
# track_settings.push({id: track.id, pan: track.pan, vol: track.vol_l, mute: track.mute})
mixdown.settings.tracks = track_settings
# mixdown.settings.tracks = track_settings
logger.debug("creating mixdown", mixdown)
# logger.debug("creating mixdown", mixdown)
rest.createMixdown(mixdown)
.done((created) =>
# rest.createMixdown(mixdown)
# .done((created) =>
@addMixdown(created)
# @addMixdown(created)
logger.debug("created mixdown", created)
# logger.debug("created mixdown", created)
@onEnqueueMixdown({id: created.id}, done, fail)
)
.fail((jqxhr) =>
fail(jqxhr)
)
# @onEnqueueMixdown({id: created.id}, done, fail)
# )
# .fail((jqxhr) =>
# fail(jqxhr)
# )
onCreateMixdown: `async function(mixdown, done, fail) {
const volumeSettings = await context.jamClient.GetJamTrackSettings();
const track_settings = [];
for (let track of Array.from(volumeSettings.tracks)) {
track_settings.push({id: track.id, pan: track.pan, vol: track.vol_l, mute: track.mute});
}
mixdown.settings.tracks = track_settings;
logger.debug("creating mixdown", mixdown);
return rest.createMixdown(mixdown)
.done(created => {
this.addMixdown(created);
logger.debug("created mixdown", created);
return this.onEnqueueMixdown({id: created.id}, done, fail);
})
.fail(jqxhr => {
return fail(jqxhr);
});
}`
onEditMixdown: (mixdown) ->
@ -351,25 +410,46 @@ JamTrackActions = @JamTrackActions
@app.layout.notify({title:'Unable to Deleted Custom Mix', text: 'The server was unable to delete this mix.'})
)
onOpenMixdown: (mixdown) ->
logger.debug("opening mixdown", mixdown)
# onOpenMixdown: (mixdown) ->
# logger.debug("opening mixdown", mixdown)
# check if it's already available in the backend or not
rest.markMixdownActive({id: @jamTrack.id, mixdown_id: mixdown.id})
.done((edited) =>
logger.debug("marked mixdown as active")
@jamTrack = edited
# # check if it's already available in the backend or not
# rest.markMixdownActive({id: @jamTrack.id, mixdown_id: mixdown.id})
# .done((edited) =>
# logger.debug("marked mixdown as active")
# @jamTrack = edited
# unload any currently loaded JamTrack
context.jamClient.JamTrackStopPlay();
# # unload any currently loaded JamTrack
# context.jamClient.JamTrackStopPlay();
@changed()
# @changed()
SessionActions.mixdownActive(mixdown)
)
.fail((jqxhr) =>
@app.layout.notify({title:'Unable to Edit Mixdown', text: 'Unable to mark this mixdown as active.'})
)
# SessionActions.mixdownActive(mixdown)
# )
# .fail((jqxhr) =>
# @app.layout.notify({title:'Unable to Edit Mixdown', text: 'Unable to mark this mixdown as active.'})
# )
onOpenMixdown: `function(mixdown) {
logger.debug("opening mixdown", mixdown);
// check if it is already available in the backend or not
rest.markMixdownActive({id: this.jamTrack.id, mixdown_id: mixdown.id})
.done(async (edited) => {
logger.debug("marked mixdown as active");
this.jamTrack = edited;
// unload any currently loaded JamTrack
await context.jamClient.JamTrackStopPlay();
this.changed();
SessionActions.mixdownActive(mixdown);
})
.fail(jqxhr => {
this.app.layout.notify({title:'Unable to Edit Mixdown', text: 'Unable to mark this mixdown as active.'});
});
}`
onActivateNoMixdown: (jamTrack) ->
logger.debug("activating no mixdown")

View File

@ -30,30 +30,62 @@ RecordingActions = @RecordingActions
@isRecording = session.isRecording
@sessionHelper = session
onMediaStartPlay: (data) ->
logger.debug("calling jamClient.SessionStartPlay");
context.jamClient.SessionStartPlay(data.playbackMode);
# onMediaStartPlay: (data) ->
# logger.debug("calling jamClient.SessionStartPlay");
# context.jamClient.SessionStartPlay(data.playbackMode);
onMediaStopPlay: (data) ->
# if a JamTrack is open, and the user hits 'pause' or 'stop', we need to automatically stop the recording
if @sessionHelper.jamTracks() && @isRecording
logger.debug("preemptive jamtrack stop")
@startStopRecording();
onMediaStartPlay: `async function(data) {
logger.debug("calling jamClient.SessionStartPlay ......")
await context.jamClient.SessionStartPlay(data.playbackMode)
}`
if !data.endReached
logger.debug("calling jamClient.SessionStopPlay. endReached:", data.endReached)
context.jamClient.SessionStopPlay()
# onMediaStopPlay: (data) ->
# # if a JamTrack is open, and the user hits 'pause' or 'stop', we need to automatically stop the recording
# if @sessionHelper.jamTracks() && @isRecording
# logger.debug("preemptive jamtrack stop")
# @startStopRecording();
onMediaPausePlay: (data) ->
# if a JamTrack is open, and the user hits 'pause' or 'stop', we need to automatically stop the recording
if @sessionHelper.jamTracks() && @isRecording
logger.debug("preemptive jamtrack stop")
@startStopRecording();
# if !data.endReached
# logger.debug("calling jamClient.SessionStopPlay. endReached:", data.endReached)
# context.jamClient.SessionStopPlay()
onMediaStopPlay: `async function(data) {
// if a JamTrack is open, and the user hits 'pause' or 'stop', we need to automatically stop the recording
if (this.sessionHelper.jamTracks() && this.isRecording) {
logger.debug("preemptive jamtrack stop");
this.startStopRecording();
}
if (!data.endReached) {
logger.debug("calling jamClient.SessionStopPlay. endReached:", data.endReached);
await context.jamClient.SessionStopPlay();
}
}`
# onMediaPausePlay: (data) ->
# # if a JamTrack is open, and the user hits 'pause' or 'stop', we need to automatically stop the recording
# if @sessionHelper.jamTracks() && @isRecording
# logger.debug("preemptive jamtrack stop")
# @startStopRecording();
if !data.endReached
logger.debug("calling jamClient.SessionPausePlay. endReached:", data.endReached)
context.jamClient.SessionPausePlay()
# if !data.endReached
# logger.debug("calling jamClient.SessionPausePlay. endReached:", data.endReached)
# context.jamClient.SessionPausePlay()
onMediaPausePlay: `async function(data) {
// if a JamTrack is open, and the user hits 'pause' or 'stop', we need to automatically stop the recording
if (this.sessionHelper.jamTracks() && this.isRecording) {
logger.debug("preemptive jamtrack stop");
this.startStopRecording();
}
if (!data.endReached) {
logger.debug("calling jamClient.SessionPausePlay. endReached:", data.endReached);
await context.jamClient.SessionPausePlay();
}
}`
startStopRecording: () ->
if @isRecording
@ -61,22 +93,43 @@ RecordingActions = @RecordingActions
else
RecordingActions.startRecording.trigger()
onMediaChangePosition: (data) ->
seek = data.positionMs;
# onMediaChangePosition: (data) ->
# seek = data.positionMs;
if data.playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK
# if positionMs == 0, then seek it back to whatever the earliest play start is to catch all the prelude
# if data.playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK
# # if positionMs == 0, then seek it back to whatever the earliest play start is to catch all the prelude
if(seek == 0)
duration = context.jamClient.SessionGetJamTracksPlayDurationMs();
seek = duration.start;
# if(seek == 0)
# duration = context.jamClient.SessionGetJamTracksPlayDurationMs();
# seek = duration.start;
logger.debug("calling jamClient.SessionTrackSeekMs(" + seek + ")");
# logger.debug("calling jamClient.SessionTrackSeekMs(" + seek + ")");
if data.playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK
context.jamClient.SessionJamTrackSeekMs(seek);
else
context.jamClient.SessionTrackSeekMs(seek);
# if data.playbackMonitorMode == PLAYBACK_MONITOR_MODE.JAMTRACK
# context.jamClient.SessionJamTrackSeekMs(seek);
# else
# context.jamClient.SessionTrackSeekMs(seek);
onMediaChangePosition: `async function(data) {
let seek = data.positionMs;
if (data.playbackMonitorMode === PLAYBACK_MONITOR_MODE.JAMTRACK) {
// if positionMs == 0, then seek it back to whatever the earliest play start is to catch all the prelude
if(seek === 0) {
const duration = await context.jamClient.SessionGetJamTracksPlayDurationMs();
seek = duration.start;
}
}
logger.debug("calling jamClient.SessionTrackSeekMs(" + seek + ")");
if (data.playbackMonitorMode === PLAYBACK_MONITOR_MODE.JAMTRACK) {
await context.jamClient.SessionJamTrackSeekMs(seek);
} else {
await context.jamClient.SessionTrackSeekMs(seek);
}
}`
issueChange: () ->
@ -102,19 +155,35 @@ RecordingActions = @RecordingActions
@issueChange()
onPositionUpdate: (playbackMode) ->
if playbackMode == PLAYBACK_MONITOR_MODE.JAMTRACK
@positionMs = context.jamClient.SessionCurrrentJamTrackPlayPosMs()
duration = context.jamClient.SessionGetJamTracksPlayDurationMs()
@durationMs = duration.media_len
else
@positionMs = context.jamClient.SessionCurrrentPlayPosMs()
@durationMs = context.jamClient.SessionGetTracksPlayDurationMs()
# onPositionUpdate: (playbackMode) ->
# if playbackMode == PLAYBACK_MONITOR_MODE.JAMTRACK
# @positionMs = context.jamClient.SessionCurrrentJamTrackPlayPosMs()
# duration = context.jamClient.SessionGetJamTracksPlayDurationMs()
# @durationMs = duration.media_len
# else
# @positionMs = context.jamClient.SessionCurrrentPlayPosMs()
# @durationMs = context.jamClient.SessionGetTracksPlayDurationMs()
@isPlaying = context.jamClient.isSessionTrackPlaying()
# @isPlaying = context.jamClient.isSessionTrackPlaying()
@positionUpdateChanged = true
@issueChange()
# @positionUpdateChanged = true
# @issueChange()
onPositionUpdate: `async function(playbackMode) {
if (playbackMode === PLAYBACK_MONITOR_MODE.JAMTRACK) {
this.positionMs = await context.jamClient.SessionCurrrentJamTrackPlayPosMs();
const duration = await context.jamClient.SessionGetJamTracksPlayDurationMs();
this.durationMs = duration.media_len;
} else {
this.positionMs = await context.jamClient.SessionCurrrentPlayPosMs();
this.durationMs = await context.jamClient.SessionGetTracksPlayDurationMs();
}
this.isPlaying = await context.jamClient.isSessionTrackPlaying();
this.positionUpdateChanged = true;
return this.issueChange();
}`
}
)

View File

@ -82,11 +82,11 @@ rest = context.JK.Rest()
SessionActions.syncWithServer()
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
console.log('MetronomeCallback#mixers', @mixers)
@issueChange()
handleBridgeCallback: (vuData) ->
eventName = null
mixerId = null
value = null
@ -105,7 +105,8 @@ rest = context.JK.Rest()
# TODO - no guarantee range will be -80 to 20. Get from the
# GetControlState for this mixer which returns min/max
# value is a DB value from -80 to 20. Convert to float from 0.0-1.0
#console.log('handleBridgeCallback@mixers',@mixers)
@mixers.updateVU(mixerId, mode, (leftValue + 80) / 80, leftClipping, (rightValue + 80) / 80, rightClipping)
#@mixers.updateVU(mixerId + "_vur", (rightValue + 80) / 80, rightClipping)
@ -113,13 +114,23 @@ rest = context.JK.Rest()
handleBackingTrackSelectedCallback: () ->
logger.debug("backing track selected")
onAppInit: (@app) ->
@gearUtils = context.JK.GearUtilsInstance
@sessionUtils = context.JK.SessionUtils
# onAppInit: (@app) ->
# @gearUtils = context.JK.GearUtilsInstance
# @sessionUtils = context.JK.SessionUtils
context.jamClient.SetVURefreshRate(150)
context.jamClient.RegisterVolChangeCallBack("JK.HandleVolumeChangeCallback2")
context.jamClient.setMetronomeOpenCallback("JK.HandleMetronomeCallback2")
# context.jamClient.SetVURefreshRate(150)
# context.jamClient.RegisterVolChangeCallBack("JK.HandleVolumeChangeCallback2")
# context.jamClient.setMetronomeOpenCallback("JK.HandleMetronomeCallback2")
onAppInit: `async function(app) {
this.app = app;
this.gearUtils = context.JK.GearUtilsInstance;
this.sessionUtils = context.JK.SessionUtils;
await context.jamClient.SetVURefreshRate(150);
await context.jamClient.RegisterVolChangeCallBack("JK.HandleVolumeChangeCallback2");
await context.jamClient.setMetronomeOpenCallback("JK.HandleMetronomeCallback2");
}`
sessionEnded: () ->
@ -128,56 +139,107 @@ rest = context.JK.Rest()
@missingMixerPeers = {}
clearTimeout(@recheckTimeout) if @recheckTimeout?
onSessionChange: (session) ->
# onSessionChange: (session) ->
@sessionEnded() unless session.inSession()
# @sessionEnded() unless session.inSession()
@session = session
# @session = session
@masterMixers = context.jamClient.SessionGetAllControlState(true);
@personalMixers = context.jamClient.SessionGetAllControlState(false);
# @masterMixers = context.jamClient.SessionGetAllControlState(true);
# @personalMixers = context.jamClient.SessionGetAllControlState(false);
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
# @mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
@issueChange()
# @issueChange()
onMute: (mixers, muting) ->
onSessionChange: `async function(session) {
if(!session){ return }
if (!session.inSession()) { this.sessionEnded(); }
mixers = [mixers] unless $.isArray(mixers)
this.session = session;
for mixer in mixers
@mixers.mute(mixer.id, mixer.mode, muting);
this.masterMixers = await context.jamClient.SessionGetAllControlState(true);
this.personalMixers = await context.jamClient.SessionGetAllControlState(false);
# simulate a state change to cause a UI redraw
@issueChange()
this.mixers = new context.MixerHelper(this.session, this.masterMixers, this.personalMixers, this.metro, this.noAudioUsers, this.clientsWithAudioOverride, (this.mixers != null ? this.mixers.mixMode : undefined) || MIX_MODES.PERSONAL);
console.log(this.mixers)
return this.issueChange();
}`
onFaderChanged: (data, mixers, gainType, controlGroup) ->
# onMute: (mixers, muting) ->
@mixers.faderChanged(data, mixers, gainType, controlGroup)
# mixers = [mixers] unless $.isArray(mixers)
@issueChange()
# for mixer in mixers
# @mixers.mute(mixer.id, mixer.mode, muting);
# # simulate a state change to cause a UI redraw
# @issueChange()
onMute: `async function(mixers, muting) {
if (!$.isArray(mixers)) { mixers = [mixers]; }
for (let mixer of Array.from(mixers)) {
await this.mixers.mute(mixer.id, mixer.mode, muting);
}
// simulate a state change to cause a UI redraw
this.issueChange();
}`
# onFaderChanged: (data, mixers, gainType, controlGroup) ->
# @mixers.faderChanged(data, mixers, gainType, controlGroup)
# @issueChange()
onFaderChanged: `async function(data, mixers, gainType, controlGroup) {
await this.mixers.faderChanged(data, mixers, gainType, controlGroup);
this.issueChange();
}`
onPanChanged: (data, mixers, groupId) ->
@mixers.panChanged(data, mixers, groupId)
@issueChange()
onLoopChanged: (mixer, shouldLoop) ->
@mixers.loopChanged(mixer, shouldLoop)
# onLoopChanged: (mixer, shouldLoop) ->
# @mixers.loopChanged(mixer, shouldLoop)
onOpenMetronome: () ->
context.jamClient.SessionStopPlay()
context.jamClient.SessionOpenMetronome(@mixers.metro.tempo, @mixers.metro.sound, 1, 0)
onLoopChanged: `async function (mixer, shouldLoop) {
await this.mixers.loopChanged(mixer, shouldLoop);
}`
onMetronomeChanged: (tempo, sound) ->
logger.debug("onMetronomeChanged", tempo, sound)
# onOpenMetronome: () ->
# context.jamClient.SessionStopPlay()
# context.jamClient.SessionOpenMetronome(@mixers.metro.tempo, @mixers.metro.sound, 1, 0)
@metro.tempo = tempo
@metro.sound = sound
context.jamClient.SessionSetMetronome(@metro.tempo, @metro.sound, 1, 0);
onOpenMetronome: `async function() {
await context.jamClient.SessionStopPlay();
await context.jamClient.SessionOpenMetronome(this.mixers.metro.tempo, this.mixers.metro.sound, 1, 0);
}`
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
@issueChange()
# onMetronomeChanged: (tempo, sound) ->
# logger.debug("onMetronomeChanged", tempo, sound)
# @metro.tempo = tempo
# @metro.sound = sound
# context.jamClient.SessionSetMetronome(@metro.tempo, @metro.sound, 1, 0);
# @mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
# @issueChange()
onMetronomeChanged: `async function(tempo, sound) {
logger.debug("onMetronomeChanged", tempo, sound);
this.metro.tempo = tempo;
this.metro.sound = sound;
await context.jamClient.SessionSetMetronome(this.metro.tempo, this.metro.sound, 1, 0);
this.mixers = new context.MixerHelper(this.session, this.masterMixers, this.personalMixers, this.metro, this.noAudioUsers, this.clientsWithAudioOverride, (this.mixers != null ? this.mixers.mixMode : undefined) || MIX_MODES.PERSONAL);
return this.issueChange();
}`
# codeInitiated means the user did not initiate this
onCloseMedia: (codeInitiated) ->
@ -259,23 +321,44 @@ rest = context.JK.Rest()
else
logger.debug("ignoring missing peer recheck. missingPeerAttempts: #{missingPeerAttempts}")
recheckForMixers: () ->
# increment how many times we've checked for this particular peer
for clientId, meh of @checkingMissingPeers
missingPeerAttempts = @missingMixerPeers[clientId]
missingPeerAttempts = 0 unless missingPeerAttempts?
missingPeerAttempts++
@missingMixerPeers[clientId] = missingPeerAttempts
# recheckForMixers: () ->
# # increment how many times we've checked for this particular peer
# for clientId, meh of @checkingMissingPeers
# missingPeerAttempts = @missingMixerPeers[clientId]
# missingPeerAttempts = 0 unless missingPeerAttempts?
# missingPeerAttempts++
# @missingMixerPeers[clientId] = missingPeerAttempts
# reset the peers we are looking for
@checkingMissingPeers = {}
# # reset the peers we are looking for
# @checkingMissingPeers = {}
@recheckTimeout = null
@masterMixers = context.jamClient.SessionGetAllControlState(true);
@personalMixers = context.jamClient.SessionGetAllControlState(false);
logger.debug("MixerStore: recheckForMixers")
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
@issueChange()
# @recheckTimeout = null
# @masterMixers = context.jamClient.SessionGetAllControlState(true);
# @personalMixers = context.jamClient.SessionGetAllControlState(false);
# logger.debug("MixerStore: recheckForMixers")
# @mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
# @issueChange()
recheckForMixers: `async function() {
// increment how many times we have checked for this particular peer
for (let clientId in this.checkingMissingPeers) {
const meh = this.checkingMissingPeers[clientId];
let missingPeerAttempts = this.missingMixerPeers[clientId];
if (missingPeerAttempts == null) { missingPeerAttempts = 0; }
missingPeerAttempts++;
this.missingMixerPeers[clientId] = missingPeerAttempts;
}
// reset the peers we are looking for
this.checkingMissingPeers = {};
this.recheckTimeout = null;
this.masterMixers = await context.jamClient.SessionGetAllControlState(true);
this.personalMixers = await context.jamClient.SessionGetAllControlState(false);
logger.debug("MixerStore: recheckForMixers");
this.mixers = new context.MixerHelper(this.session, this.masterMixers, this.personalMixers, this.metro, this.noAudioUsers, this.clientsWithAudioOverride, (this.mixers != null ? this.mixers.mixMode : undefined) || MIX_MODES.PERSONAL);
return this.issueChange();
}`
onInitGain: (mixer) ->
@mixers.initGain(mixer)
@ -283,17 +366,30 @@ rest = context.JK.Rest()
onInitPan: (mixer) ->
@mixers.initPan(mixer)
onMixersChanged: (type, text) ->
@masterMixers = context.jamClient.SessionGetAllControlState(true);
@personalMixers = context.jamClient.SessionGetAllControlState(false);
# onMixersChanged: (type, text) ->
# @masterMixers = context.jamClient.SessionGetAllControlState(true);
# @personalMixers = context.jamClient.SessionGetAllControlState(false);
logger.debug("MixerStore: onMixersChanged")
# logger.debug("MixerStore: onMixersChanged")
@mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
# @mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @metro, @noAudioUsers, @clientsWithAudioOverride, @mixers?.mixMode || MIX_MODES.PERSONAL)
SessionActions.mixersChanged.trigger(type, text, @mixers.getTrackInfo())
# SessionActions.mixersChanged.trigger(type, text, @mixers.getTrackInfo())
@issueChange()
# @issueChange()
onMixersChanged: `async function(type, text) {
this.masterMixers = await context.jamClient.SessionGetAllControlState(true);
this.personalMixers = await context.jamClient.SessionGetAllControlState(false);
logger.debug("MixerStore: onMixersChanged");
this.mixers = new context.MixerHelper(this.session, this.masterMixers, this.personalMixers, this.metro, this.noAudioUsers, this.clientsWithAudioOverride, (this.mixers != null ? this.mixers.mixMode : undefined) || MIX_MODES.PERSONAL);
SessionActions.mixersChanged.trigger(type, text, await this.mixers.getTrackInfo());
return this.issueChange();
}`
onMixerModeChanged: (mode) ->
if mode == MIX_MODES.MASTER
@ -301,37 +397,78 @@ rest = context.JK.Rest()
else
@app.layout.closeDialog('session-master-mix-dialog') if @app.layout.isDialogShowing('session-master-mix-dialog')
onSyncTracks: () ->
logger.debug("MixerStore: onSyncTracks")
unless @session.inSession()
logger.debug("dropping sync tracks because no longer in session")
return
# onSyncTracks: () ->
# logger.debug("MixerStore: onSyncTracks")
# unless @session.inSession()
# logger.debug("dropping sync tracks because no longer in session")
# return
allTracks = @mixers.getTrackInfo()
# allTracks = @mixers.getTrackInfo()
# console.log('allTracks', allTracks)
# inputTracks = allTracks.userTracks;
# backingTracks = allTracks.backingTracks;
# metronomeTracks = allTracks.metronomeTracks;
inputTracks = allTracks.userTracks;
backingTracks = allTracks.backingTracks;
metronomeTracks = allTracks.metronomeTracks;
# # create a trackSync request based on backend data
# syncTrackRequest = {}
# syncTrackRequest.client_id = @app.clientId
# syncTrackRequest.tracks = inputTracks
# syncTrackRequest.backing_tracks = backingTracks
# syncTrackRequest.metronome_open = metronomeTracks.length > 0
# syncTrackRequest.id = @session.id()
# create a trackSync request based on backend data
syncTrackRequest = {}
syncTrackRequest.client_id = @app.clientId
syncTrackRequest.tracks = inputTracks
syncTrackRequest.backing_tracks = backingTracks
syncTrackRequest.metronome_open = metronomeTracks.length > 0
syncTrackRequest.id = @session.id()
# rest.putTrackSyncChange(syncTrackRequest)
# .fail((jqXHR)=>
# if jqXHR.status != 404
# @app.notify({
# "title": "Can't Sync Local Tracks",
# "text": "The client is unable to sync local track information with the server. You should rejoin the session to ensure a good experience.",
# "icon_url": "/assets/content/icon_alert_big.png"
# })
rest.putTrackSyncChange(syncTrackRequest)
.fail((jqXHR)=>
if jqXHR.status != 404
@app.notify({
"title": "Can't Sync Local Tracks",
"text": "The client is unable to sync local track information with the server. You should rejoin the session to ensure a good experience.",
"icon_url": "/assets/content/icon_alert_big.png"
})
# else
# logger.debug("Unable to sync local tracks because session is gone.")
# )
else
logger.debug("Unable to sync local tracks because session is gone.")
)
onSyncTracks: `async function() {
logger.debug("MixerStore: onSyncTracks");
if (!this.session.inSession()) {
logger.debug("dropping sync tracks because no longer in session");
return;
}
const allTracks = await this.mixers.getTrackInfo();
console.log('allTracks', allTracks);
const inputTracks = allTracks.userTracks;
const {
backingTracks
} = allTracks;
const {
metronomeTracks
} = allTracks;
// create a trackSync request based on backend data
const syncTrackRequest = {};
syncTrackRequest.client_id = this.app.clientId;
syncTrackRequest.tracks = inputTracks;
syncTrackRequest.backing_tracks = backingTracks;
syncTrackRequest.metronome_open = metronomeTracks.length > 0;
syncTrackRequest.id = this.session.id();
return rest.putTrackSyncChange(syncTrackRequest)
.fail(jqXHR=> {
if (jqXHR.status !== 404) {
return this.app.notify({
"title": "Can't Sync Local Tracks",
"text": "The client is unable to sync local track information with the server. You should rejoin the session to ensure a good experience.",
"icon_url": "/assets/content/icon_alert_big.png"
});
} else {
return logger.debug("Unable to sync local tracks because session is gone.");
}
});
}`
}
)

Some files were not shown because too many files have changed in this diff Show More