initial version of jamblaster management page
This commit is contained in:
parent
e95c7fe8e5
commit
bd0dc40a4c
|
|
@ -66,8 +66,8 @@ module JamRuby
|
|||
return
|
||||
end
|
||||
|
||||
#wav_file = File.join(tmp_dir, File.basename(click_track_file[:original_filename]))
|
||||
#JamTrackImporter.song_storage_manager.download(click_track_file[:original_filename], wav_file)
|
||||
wav_file = File.join(tmp_dir, File.basename(click_track_file[:original_filename]))
|
||||
JamTrackImporter.song_storage_manager.download(click_track_file[:original_filename], wav_file)
|
||||
|
||||
JamTrack.transaction do
|
||||
click_track = jam_track.click_track
|
||||
|
|
@ -81,6 +81,8 @@ module JamRuby
|
|||
click_track.instrument_id = 'computer'
|
||||
click_track.jam_track = jam_track
|
||||
click_track.position = 10000
|
||||
click_track.wav_file = wav_file
|
||||
|
||||
if !click_track.save
|
||||
@@log.error("unable to create jamtrack click track #{click_track.errors.inspect}")
|
||||
finish("jam_track_click", "unable to create: #{click_track.errors.inspect}")
|
||||
|
|
@ -1601,6 +1603,8 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def assign_instrument_parts(wav_file, tracks, addt_files, reassign = false)
|
||||
if !reassign
|
||||
track = JamTrackTrack.new
|
||||
|
|
@ -2651,6 +2655,34 @@ module JamRuby
|
|||
importer
|
||||
end
|
||||
|
||||
# created for helbing tracks which had .mp3 as click track
|
||||
def convert_click_track_to_wav(jam_track)
|
||||
importer = JamTrackImporter.new
|
||||
importer.name = jam_track.name
|
||||
|
||||
track = jam_track.click_track
|
||||
|
||||
if !track
|
||||
Dir.mktmpdir do |tmp_dir|
|
||||
|
||||
# something like: "mapped/Victor Young - Stella By Starlight/meta.yml"
|
||||
metalocation = jam_track.metalocation
|
||||
base_dir = metalocation[0...metalocation.rindex('/')]
|
||||
click_mp3 = File.join(tmp_dir, 'Click.mp3')
|
||||
click_wav = File.join(tmp_dir, 'Click.wav')
|
||||
song_storage_manager.download(base_dir + '/Click.mp3', click_mp3)
|
||||
|
||||
`ffmpeg -i "#{click_mp3}" "#{click_wav}"`
|
||||
|
||||
song_storage_manager.upload(base_dir + '/Click.wav', click_wav)
|
||||
importer.finish("success", nil)
|
||||
end
|
||||
else
|
||||
importer.finish('success', nil)
|
||||
end
|
||||
importer
|
||||
end
|
||||
|
||||
def synchronize_jamtrack_master_preview(jam_track)
|
||||
importer = JamTrackImporter.new
|
||||
importer.name = jam_track.name
|
||||
|
|
@ -2717,7 +2749,8 @@ module JamRuby
|
|||
def import_click_tracks
|
||||
importers = []
|
||||
|
||||
JamTrack.all.each do |jam_track|
|
||||
licensor = JamTrackLicensor.find_by_name!('Stockton Helbing')
|
||||
JamTrack.where(licensor_id: licensor.id).each do |jam_track|
|
||||
#jam_track = JamTrack.find('126')
|
||||
importers << import_click_track(jam_track)
|
||||
end
|
||||
|
|
@ -2796,6 +2829,32 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def convert_click_track_to_wavs
|
||||
importers = []
|
||||
|
||||
licensor = JamTrackLicensor.find_by_name!('Stockton Helbing')
|
||||
JamTrack.where(licensor_id: licensor.id).each do |jam_track|
|
||||
importers << convert_click_track_to_wav(jam_track)
|
||||
end
|
||||
|
||||
@@log.info("SUMMARY")
|
||||
@@log.info("-------")
|
||||
importers.each do |importer|
|
||||
if importer
|
||||
if importer.reason == "success" || importer.reason == "jam_track_exists" || importer.reason == "other_processing"
|
||||
@@log.info("#{importer.name} #{importer.reason}")
|
||||
else
|
||||
@@log.error("#{importer.name} failed to import.")
|
||||
@@log.error("#{importer.name} reason=#{importer.reason}")
|
||||
@@log.error("#{importer.name} detail=#{importer.detail}")
|
||||
end
|
||||
else
|
||||
@@log.error("NULL IMPORTER")
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
def synchronize_jamtrack_aac_previews
|
||||
|
||||
importers = []
|
||||
|
|
@ -2818,8 +2877,6 @@ module JamRuby
|
|||
else
|
||||
@@log.error("NULL IMPORTER")
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -3118,11 +3175,11 @@ module JamRuby
|
|||
|
||||
def resync_instruments(licensor)
|
||||
|
||||
load_paris_mappings if @paris_mapping.nil?
|
||||
load_paris_mappings if @paris_mapping.nil? && is_paris_storage?
|
||||
|
||||
JamTrack.where(licensor_id: licensor.id).each do |jam_track|
|
||||
|
||||
if @paris_metadata[jam_track.vendor_id].nil?
|
||||
if is_paris_storage? && @paris_metadata[jam_track.vendor_id].nil?
|
||||
next
|
||||
end
|
||||
puts "RESYNCING JAMTRACK #{jam_track.id}"
|
||||
|
|
@ -3135,6 +3192,7 @@ module JamRuby
|
|||
|
||||
#puts ">>>>>>>>> HIT KEY TO CONTINUE <<<<<<<<<<"
|
||||
#STDIN.gets
|
||||
break
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -323,7 +323,16 @@ module JamRuby
|
|||
end
|
||||
|
||||
if options[:artist].present?
|
||||
query = query.where("original_artist=?", options[:artist])
|
||||
artist_param = options[:artist]
|
||||
# todo: add licensor option
|
||||
if artist_param == 'Stockton Helbing'
|
||||
licensor = JamTrackLicensor.find_by_name('Stockton Helbing')
|
||||
if licensor
|
||||
query = query.where(licensor_id: licensor.id)
|
||||
end
|
||||
else
|
||||
query = query.where("original_artist=?", options[:artist])
|
||||
end
|
||||
end
|
||||
|
||||
if options[:song].present?
|
||||
|
|
|
|||
|
|
@ -128,10 +128,11 @@
|
|||
return false;
|
||||
});
|
||||
|
||||
//$btnAddNewGear.click(function() {
|
||||
$btnAddNewGear.click(function() {
|
||||
|
||||
// return false;
|
||||
//});
|
||||
app.layout.showDialog("add-new-audio-gear")
|
||||
return false;
|
||||
});
|
||||
|
||||
$btnUpdateTrackSettings.click(function() {
|
||||
if(voiceChatHelper.trySave()) {
|
||||
|
|
@ -245,6 +246,8 @@
|
|||
function afterShow() {
|
||||
sessionUtils.SessionPageEnter();
|
||||
|
||||
window.JamBlasterActions.resyncBonjour()
|
||||
|
||||
//context.ConfigureTracksActions.vstScan();
|
||||
|
||||
}
|
||||
|
|
@ -271,9 +274,9 @@
|
|||
|
||||
$dialog = $('#configure-tracks-dialog');
|
||||
$instructions = $dialog.find('.instructions span');
|
||||
$musicAudioTab = $dialog.find('div[tab-id="music-audio"]');
|
||||
$musicAudioTab = $dialog.find('div[data-tab-id="music-audio"]');
|
||||
$musicAudioTabSelector = $dialog.find('.tab-configure-audio');
|
||||
$voiceChatTab = $dialog.find('div[tab-id="voice-chat"]');
|
||||
$voiceChatTab = $dialog.find('div[data-tab-id="voice-chat"]');
|
||||
$voiceChatTabSelector = $dialog.find('.tab-configure-voice');
|
||||
$certifiedAudioProfile = $dialog.find('.certified-audio-profile');
|
||||
$btnCancel = $dialog.find('.btn-cancel');
|
||||
|
|
|
|||
|
|
@ -210,6 +210,7 @@
|
|||
JK.JamServer.registerMessageCallback(JK.MessageType.STOP_APPLICATION, function(header, payload) {
|
||||
context.jamClient.ShutdownApplication();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function handleGettingStarted(app) {
|
||||
|
|
|
|||
|
|
@ -49,9 +49,15 @@
|
|||
|
||||
var html = context._.template($('#template-jamblaster-options').html(), options, { variable: 'data' })
|
||||
|
||||
var extraClasses = ' '
|
||||
var width = 120;
|
||||
if(options.isDynamicPorts || options.autoconnect) {
|
||||
extraClasses += 'isDynamicPorts '
|
||||
width = 140;
|
||||
}
|
||||
context.JK.hoverBubble($parent, html, {
|
||||
trigger:'none',
|
||||
cssClass: 'jamblaster-options-popup',
|
||||
cssClass: 'jamblaster-options-popup' + extraClasses,
|
||||
spikeGirth:0,
|
||||
spikeLength:0,
|
||||
overlap: -10,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
//= require ./react-components/stores/UserActivityStore
|
||||
//= require ./react-components/stores/LessonTimerStore
|
||||
//= require ./react-components/stores/SchoolStore
|
||||
//= require ./react-components/stores/JamBlasterStore
|
||||
//= require ./react-components/stores/StripeStore
|
||||
//= require ./react-components/stores/AvatarStore
|
||||
//= require ./react-components/stores/AttachmentStore
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
context = window
|
||||
JamBlasterActions = @JamBlasterActions
|
||||
|
||||
@ConfigureTracksDialogContents = React.createClass({
|
||||
|
||||
mixins: [Reflux.listenTo(@AppStore, "onAppInit"), Reflux.listenTo(@JamBlasterStore, "onJamBlasterChanged")]
|
||||
|
||||
|
||||
onAppInit: (@app) ->
|
||||
|
||||
onJamBlasterChanged: (jamblasterState) ->
|
||||
@setState(jamblasterState)
|
||||
|
||||
getInitialState: () ->
|
||||
{
|
||||
timer: null,
|
||||
pairing: false,
|
||||
pairStart: null,
|
||||
allJamBlasters: [],
|
||||
pairingTimeout: false,
|
||||
paired: false,
|
||||
userJamBlasters: [],
|
||||
localJamBlasters: []
|
||||
}
|
||||
|
||||
|
||||
render: () ->
|
||||
pairedJamBlaster = this.state.pairedJamBlaster
|
||||
hasPairedJamBlaster = pairedJamBlaster?
|
||||
|
||||
if hasPairedJamBlaster
|
||||
`<JamBlasterTrackConfig />`
|
||||
else
|
||||
`<div>
|
||||
<div className="dialog-tabs">
|
||||
<a className="selected tab-configure-audio">Inputs & Outputs</a>
|
||||
<a className="tab-configure-voice">Voice Chat</a>
|
||||
</div>
|
||||
<div className="instructions">
|
||||
<span>Choose your audio device. Drag and drop to assign input ports to tracks, and specify the instrument
|
||||
for each track. Drag and drop to assign a pair of output ports for session stereo audio monitoring.</span>
|
||||
</div>
|
||||
<div className="clearall"></div>
|
||||
<div className="tab no-selection-range" data-tab-id="music-audio">
|
||||
<ConfigureTracks />
|
||||
|
||||
<div className="clearall"></div>
|
||||
</div>
|
||||
<div className="tab" data-tab-id="voice-chat">
|
||||
<form className="select-voice-chat-option section voice">
|
||||
<div className="sub-header">Select Voice Chat Option</div>
|
||||
<div className="voicechat-option reuse-audio-input">
|
||||
<input type="radio" name="voicechat" defaultChecked="checked"/>
|
||||
|
||||
<h3>Use Music Microphone</h3>
|
||||
|
||||
<p>I am already using a microphone to capture my vocal or instrumental music, so I can talk with other
|
||||
musicians using that microphone</p>
|
||||
</div>
|
||||
<div className="voicechat-option use-chat-input">
|
||||
<input type="radio" name="voicechat"/>
|
||||
|
||||
<h3>Use Chat Microphone</h3>
|
||||
|
||||
<p>I am not using a microphone for acoustic instruments or vocals, so use the input selected to the right
|
||||
for voice chat during my sessions</p>
|
||||
</div>
|
||||
</form>
|
||||
<div className="clearall"></div>
|
||||
<div className="select-voice-chat">
|
||||
<div className="sub-header">Voice Chat Input</div>
|
||||
<div className="ftue-box chat-inputs"></div>
|
||||
<div className="vu-meter">
|
||||
<div className="ftue-controls">
|
||||
<div className="ftue-vu-left voice-chat-vu-left"></div>
|
||||
<div className="ftue-fader chat-fader"></div>
|
||||
<div className="gain-label">GAIN</div>
|
||||
<div className="ftue-vu-right voice-chat-vu-right"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="clearall"></div>
|
||||
</div>
|
||||
|
||||
<div className="buttons">
|
||||
<a className="btn-add-new-audio-gear button-grey">ADD NEW AUDIO GEAR</a>
|
||||
<a className="button-grey btn-cancel">CANCEL</a>
|
||||
<a className="button-orange btn-update-settings">SAVE SETTINGS</a>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
)
|
||||
|
|
@ -44,7 +44,7 @@ context = window
|
|||
|
||||
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.')
|
||||
|
|
@ -64,7 +64,7 @@ context = window
|
|||
|
||||
if !result
|
||||
context.JK.Banner.showAlert('unable to set the name',
|
||||
'Please email support@jamkazam.com with the name you are trying to set, or refresh the page and try again.')
|
||||
'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: () ->
|
||||
|
|
@ -74,13 +74,15 @@ context = window
|
|||
|
||||
<h1>update name of JamBlaster</h1>
|
||||
</div>
|
||||
<div>
|
||||
<div className="dialog-inner">
|
||||
|
||||
<p>You can change the display name for this JamBlaster. The name can only contain A-Z, 0-9, commas, apostrophes,
|
||||
<p className="help-text">You can change the display name for this JamBlaster. The name can only contain A-Z, 0-9, commas, apostrophes,
|
||||
spaces, or hyphens. A valid example: "John Doe's JamBlaster"</p>
|
||||
|
||||
<div className="field">
|
||||
<label>JamBlaster Name:</label>
|
||||
<input className="name" type="text" value={this.state.name} onChange={this.onNameChange}></input>
|
||||
</div>
|
||||
|
||||
<div className="actions">
|
||||
<a onClick={this.doCancel} className="button-grey">CANCEL</a>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
context = window
|
||||
JamBlasterActions = @JamBlasterActions
|
||||
|
||||
@JamBlasterPairingDialog = React.createClass({
|
||||
|
||||
mixins: [@BonjourMixin, Reflux.listenTo(@AppStore, "onAppInit")]
|
||||
teacher: null
|
||||
mixins: [@BonjourMixin, Reflux.listenTo(@AppStore, "onAppInit"), Reflux.listenTo(@JamBlasterStore, "onJamBlasterChanged")]
|
||||
|
||||
|
||||
beforeShow: (args) ->
|
||||
logger.debug("JamBlasterPairingDialog.beforeShow", args.d1)
|
||||
@setState({timer: null, pairing: false, bonjourClientId: args.d1, pairingTimeout: false, paired: false})
|
||||
@resyncBonjour()
|
||||
JamBlasterActions.resyncBonjour()
|
||||
@setTimer(false)
|
||||
|
||||
afterHide: () ->
|
||||
|
|
@ -21,16 +23,19 @@ context = window
|
|||
|
||||
@app.bindDialog('jamblaster-pairing-dialog', dialogBindings);
|
||||
|
||||
onJamBlasterChanged: (jamblasterState) ->
|
||||
@setState(jamblasterState)
|
||||
|
||||
getInitialState: () ->
|
||||
{
|
||||
timer: null
|
||||
timer: null,
|
||||
pairing: false,
|
||||
pairStart: null,
|
||||
clients: [],
|
||||
pairingTimeout: false
|
||||
allJamBlasters: [],
|
||||
pairingTimeout: false,
|
||||
paired: false,
|
||||
userJamBlasters: [],
|
||||
localClients: []
|
||||
localJamBlasters: []
|
||||
}
|
||||
|
||||
clearTimer: () ->
|
||||
|
|
@ -51,7 +56,7 @@ context = window
|
|||
else
|
||||
time = 60000 # every minute
|
||||
|
||||
@interval = setInterval((() => @resyncBonjour()), time)
|
||||
@interval = setInterval((() => JamBlasterActions.resyncBonjour()), time)
|
||||
|
||||
pairingTimer: () ->
|
||||
@clearPairingTimer()
|
||||
|
|
@ -101,7 +106,7 @@ context = window
|
|||
if @state.pairing
|
||||
return
|
||||
|
||||
@setState({pairing: true, pairStart: new Date().getTime(), timer: 60})
|
||||
@setState({pairing: true, pairStart: new Date().getTime(), timer: 60, pairingTimeout: false, paired: false})
|
||||
@setTimer(true)
|
||||
|
||||
client = @findJamBlaster(this.state.bonjourClientId)
|
||||
|
|
@ -110,52 +115,55 @@ context = window
|
|||
context.JK.Banner.showNotice("JamBlaster already paired", "This JamBlaster is already paired.")
|
||||
@app.layout.closeDialog("jamblaster-pairing-dialog", true)
|
||||
else if client?
|
||||
if client.connect_url?
|
||||
context.jamClient.startPairing(client.connect_url)
|
||||
else
|
||||
context.JK.Banner.showAlert("JamBlaster offline", "JamBlaster appears to be offline. Please reboot it")
|
||||
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")
|
||||
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: () ->
|
||||
|
||||
if @state.pairing
|
||||
countdown = @state.timer
|
||||
countdown = `<div className="countdown-msg">You have <span className="countdown">{Math.round(this.state.timer)}</span> seconds to push the button on the back of the JamBlaster.
|
||||
</div>`
|
||||
else
|
||||
countdown = null
|
||||
|
||||
|
||||
cancelClasses = {"button-grey": true, disabled: @state.pairing}
|
||||
connectClasses = {"button-orange": true, disabled: @state.pairing}
|
||||
|
||||
actions = `<div className="actions">
|
||||
<a onClick={this.doCancel} className={cancelClasses}>CANCEL</a>
|
||||
<a onClick={this.pair} className={connectClasses}>CONNECT</a>
|
||||
<span className="countdown">{countdown}</span>
|
||||
<a onClick={this.doCancel} className={classNames(cancelClasses)}>CANCEL</a>
|
||||
<a onClick={this.pair} className={classNames(connectClasses)}>CONNECT</a>
|
||||
</div>`
|
||||
|
||||
|
||||
if @state.paired
|
||||
message = `<p>You have successfully connected to this JamBlaster!</p>`
|
||||
message = `<p className="message">You have successfully connected to this JamBlaster!</p>`
|
||||
actions = `<div className="actions">
|
||||
<a onClick={this.close} className="button-orange">CLOSE</a>
|
||||
</div>`
|
||||
else if @state.pairingTimeout
|
||||
message = `<p>No connection established. You may click the CONNECT button to try again. If you cannot connect, please contact us at support@jamkazam.com.</p>`
|
||||
message = `<p className="message">No connection established. You may click the CONNECT button to try again. If you cannot connect, please contact us at support@jamkazam.com.</p>`
|
||||
else
|
||||
|
||||
cancelClasses = {"button-grey": true, disabled: @state.pairing}
|
||||
connectClasses = {"button-orange": true, disabled: @state.pairing}
|
||||
|
||||
`<div>
|
||||
<div className="content-head">
|
||||
<img className="content-icon" src="/assets/content/icon_add.png" height={19} width={19}/>
|
||||
|
||||
<h1>connect to JamBlaster</h1>
|
||||
</div>
|
||||
<div>
|
||||
<div className="dialog-inner">
|
||||
|
||||
<p>To connect this application/device with the selected JamBlaster, please click the Connect button below, and then push the small black plastic button located on the back of the JamBlaster between the USB and power ports to confirm this pairing within 60 seconds of clicking the Connect button below.</p>
|
||||
<p>To connect this application/device with the selected JamBlaster, please click the CONNECT button below, and then push the small black plastic button located on the back of the JamBlaster between the USB and power ports to confirm this pairing within 60 seconds of clicking the Connect button below.</p>
|
||||
|
||||
{message}
|
||||
|
||||
{actions}
|
||||
{countdown} {actions}
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
context = window
|
||||
@JamBlasterPortDialog = React.createClass({
|
||||
|
||||
mixins: [Reflux.listenTo(@AppStore, "onAppInit")]
|
||||
teacher: null
|
||||
|
||||
beforeShow: (args) ->
|
||||
logger.debug("JamBlasterPortDialog.beforeShow")
|
||||
|
||||
|
||||
afterHide: () ->
|
||||
|
||||
onAppInit: (@app) ->
|
||||
dialogBindings = {
|
||||
'beforeShow': @beforeShow,
|
||||
'afterHide': @afterHide
|
||||
};
|
||||
|
||||
@app.bindDialog('jamblaster-port-dialog', dialogBindings);
|
||||
|
||||
getInitialState: () ->
|
||||
{
|
||||
name: ''
|
||||
}
|
||||
|
||||
|
||||
componentDidMount: () ->
|
||||
@root = $(@getDOMNode())
|
||||
@dialog = @root.closest('.dialog')
|
||||
|
||||
doCancel: (e) ->
|
||||
e.preventDefault()
|
||||
@app.layout.closeDialog('jamblaster-port-dialog', true);
|
||||
|
||||
updatePort: (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
# validate
|
||||
|
||||
staticPort = @root.find('.port').val()
|
||||
|
||||
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
|
||||
|
||||
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})
|
||||
|
||||
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">
|
||||
<img className="content-icon" src="/assets/content/icon_add.png" height={19} width={19}/>
|
||||
|
||||
<h1>set static port for JamBlaster</h1>
|
||||
</div>
|
||||
<div className="dialog-inner">
|
||||
|
||||
<p className="help-text">You can specify any port you like, but we recommend an even number in the range including 1026-49150 to avoid conflicts with other programs. When configuring Port Forwarding in your router, be sure to open this port <b>along with the next 10</b>. For example, if this field is 12000, then in your router, forward ports 12000-12010 to your computer's IP address.</p>
|
||||
|
||||
<div className="field">
|
||||
<label>Port:</label>
|
||||
<input className="port" type="text"></input>
|
||||
</div>
|
||||
|
||||
<div className="actions">
|
||||
<a onClick={this.doCancel} className="button-grey">CANCEL</a>
|
||||
<a onClick={this.updatePort} className="button-orange name">SAVE</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
})
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
context = window
|
||||
rest = context.JK.Rest()
|
||||
logger = context.JK.logger
|
||||
JamBlasterActions = @JamBlasterActions
|
||||
|
||||
@JamBlasterScreen = React.createClass({
|
||||
|
||||
|
|
@ -9,7 +10,8 @@ logger = context.JK.logger
|
|||
@PostProcessorMixin,
|
||||
@BonjourMixin,
|
||||
Reflux.listenTo(AppStore, "onAppInit"),
|
||||
Reflux.listenTo(UserStore, "onUserChanged")
|
||||
Reflux.listenTo(UserStore, "onUserChanged"),
|
||||
Reflux.listenTo(JamBlasterStore, "onJamBlasterChanged")
|
||||
]
|
||||
|
||||
TILE_AUDIO: 'audio'
|
||||
|
|
@ -17,7 +19,10 @@ logger = context.JK.logger
|
|||
TILE_MANAGEMENT: 'management'
|
||||
TILE_USB: 'usb'
|
||||
|
||||
TILES: ['audio', 'internet', 'management', 'usb']
|
||||
TILES: ['management', 'audio', 'internet']
|
||||
|
||||
networkStale: false
|
||||
ipRegex: /^0([0-9])+/
|
||||
|
||||
onAppInit: (@app) ->
|
||||
@app.bindScreen('jamblaster',
|
||||
|
|
@ -26,44 +31,120 @@ logger = context.JK.logger
|
|||
onUserChanged: (userState) ->
|
||||
@setState({user: userState?.user})
|
||||
|
||||
componentDidMount: () ->
|
||||
@root = $(@getDOMNode())
|
||||
onJamBlasterChanged: (jamblasterState) ->
|
||||
@setState(jamblasterState)
|
||||
|
||||
componentDidMount: () ->
|
||||
@checkboxes = [{selector: 'input.dhcp', stateKey: 'dhcp'}]
|
||||
@root = $(@getDOMNode())
|
||||
@iCheckify()
|
||||
|
||||
|
||||
componentWillUpdate: (nextProps, nextState) ->
|
||||
|
||||
componentDidUpdate: () ->
|
||||
@iCheckify()
|
||||
|
||||
items = @root.find('.jamtable .optionsColumn .jamblaster-options-btn')
|
||||
|
||||
$.each(items, (i, node) => (
|
||||
$node = $(node)
|
||||
|
||||
jamblaster = @findJamBlaster($node.attr('data-jamblaster-id'))
|
||||
jamblaster = @findJamBlaster({
|
||||
server_id: $node.attr('data-jamblaster-id'),
|
||||
ipv6_addr: $node.attr('data-jamblaster-addr')
|
||||
})
|
||||
|
||||
$node.jamblasterOptions(jamblaster).off(context.JK.EVENTS.JAMBLASTER_ACTION).on(context.JK.EVENTS.JAMBLASTER_ACTION,
|
||||
@jamblasterOptionSelected)
|
||||
))
|
||||
|
||||
@root.find('input.networksettings').inputmask({
|
||||
alias: "ip",
|
||||
"placeholder": "_"
|
||||
});
|
||||
|
||||
checkboxChanged: (e) ->
|
||||
checked = $(e.target).is(':checked')
|
||||
|
||||
value = $(e.target).val()
|
||||
console.log("checkbox changed: ", value)
|
||||
|
||||
|
||||
@setState({userdhcp: "true" == value})
|
||||
|
||||
componentWillUpdate: (nextProps, nextState) ->
|
||||
if @networkStale && @state.pairedJamBlaster?
|
||||
console.log("stale network update", @state)
|
||||
nextState.userdhcp = @state.pairedJamBlaster.network?.dhcp
|
||||
nextState.useraddr = @state.pairedJamBlaster.network?.addr
|
||||
nextState.usersubnet = @state.pairedJamBlaster.network?.subnet
|
||||
nextState.usergateway = @state.pairedJamBlaster.network?.gateway
|
||||
nextState.userdns1 = @state.pairedJamBlaster.network?.dns1
|
||||
nextState.userdns2 = @state.pairedJamBlaster.network?.dns2
|
||||
nextState.userdhcperror = false
|
||||
nextState.useraddrerror = false
|
||||
nextState.usersubneterror = false
|
||||
nextState.usergatewayerror = false
|
||||
nextState.userdns1error = false
|
||||
nextState.userdns2error = false
|
||||
@networkStale = false
|
||||
|
||||
#context.JK.popExternalLinks(@root)
|
||||
|
||||
jamblasterOptionSelected: (e, data) ->
|
||||
jamblasterId = data.options.id
|
||||
jamblaster = @findJamBlaster(jamblasterId)
|
||||
jamblaster = data.options
|
||||
jamblaster = @findJamBlaster(jamblaster)
|
||||
|
||||
if data.option == 'auto-connect'
|
||||
context.JK.Banner.showNotice('Auto-Connect',
|
||||
'Auto-Connect is always on by default. It can not currently configurable.')
|
||||
JamBlasterActions.setAutoPair(!jamblaster.autoconnect)
|
||||
else if data.option == 'restart'
|
||||
context.JK.Banner.showNotice('Restart',
|
||||
'To restart the JamBlaster, you must manually cycle power (unplug, then plug).')
|
||||
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 if data.option == 'name'
|
||||
context.layout.showDialog('jamblaster-name-dialog').one(context.JK.EVENTS.DIALOG_CLOSED, (e, data) =>
|
||||
@resyncBonjour()
|
||||
@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 on start up. Please reboot the JamBlaster')
|
||||
'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'
|
||||
context.layout.showDialog('jamblaster-port-dialog')
|
||||
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.')
|
||||
|
|
@ -74,17 +155,18 @@ logger = context.JK.logger
|
|||
selected: 'management',
|
||||
user: null,
|
||||
userJamBlasters: [],
|
||||
localClients: [],
|
||||
clients: []
|
||||
localJamBlasters: [],
|
||||
allJamBlasters: []
|
||||
}
|
||||
|
||||
beforeHide: (e) ->
|
||||
|
||||
@clearTimer()
|
||||
|
||||
beforeShow: (e) ->
|
||||
@setTimer()
|
||||
|
||||
afterShow: (e) ->
|
||||
@resyncBonjour()
|
||||
JamBlasterActions.resyncBonjour()
|
||||
|
||||
openMenu: (client, e) ->
|
||||
logger.debug("open jamblaster options menu")
|
||||
|
|
@ -93,18 +175,34 @@ logger = context.JK.logger
|
|||
$this = $this.closest('.jamblaster-options-btn')
|
||||
$this.btOn()
|
||||
|
||||
clearTimer: () ->
|
||||
if @interval?
|
||||
clearInterval(@interval)
|
||||
@interval = null
|
||||
|
||||
# Refresh bonjour status every 30 second, so that we catch major changes
|
||||
setTimer: () ->
|
||||
@clearTimer()
|
||||
time = 30000 # every 30 seconds
|
||||
|
||||
@interval = setInterval((() => JamBlasterActions.resyncBonjour()), time)
|
||||
|
||||
connect: (client, e) ->
|
||||
logger.debug("beginning pairing to #{client.connect_url}")
|
||||
|
||||
context.jamClient.startPairing(client.connect_url)
|
||||
|
||||
@clearTimer()
|
||||
@app.layout.showDialog('jamblaster-pairing-dialog', {d1: client}).one(context.JK.EVENTS.DIALOG_CLOSED, (e, data) =>
|
||||
JamBlasterActions.resyncBonjour()
|
||||
@setTimer()
|
||||
)
|
||||
disconnect: (client, e) ->
|
||||
logger.debug("disconnecting from currently paired client #{client.connect_url}")
|
||||
context.jamClient.endPairing()
|
||||
mergeClients: () ->
|
||||
setTimeout((() => JamBlasterActions.resyncBonjour()), 1000)
|
||||
|
||||
mergeClients: () ->
|
||||
clientsJsx = []
|
||||
for client in @state.clients
|
||||
for client in @state.allJamBlasters
|
||||
if client.display_name?
|
||||
displayName = client.display_name
|
||||
else
|
||||
|
|
@ -122,7 +220,9 @@ logger = context.JK.logger
|
|||
else
|
||||
connect = `<span className="connectColumn">offline</span>`
|
||||
|
||||
options = `<span className="optionsColumn"><a data-jamblaster-id={client.id} className="jamblaster-options-btn"
|
||||
options = `<span className="optionsColumn"><a data-jamblaster-id={client.server_id}
|
||||
data-jamblaster-addr={client.ipv6_addr}
|
||||
className="jamblaster-options-btn"
|
||||
onClick={this.openMenu.bind(this, client)}>more options
|
||||
<div className="details-arrow arrow-down"/>
|
||||
</a></span>`
|
||||
|
|
@ -134,6 +234,10 @@ logger = context.JK.logger
|
|||
clientsJsx
|
||||
|
||||
mainContent: () ->
|
||||
if !@state.user?.id || !@state.userJamBlasters? || !@state.localJamBlasters?
|
||||
return `<div>Loading ...</div>`
|
||||
|
||||
|
||||
if @state.selected == @TILE_AUDIO
|
||||
@audio()
|
||||
else if @state.selected == @TILE_INTERNET
|
||||
|
|
@ -143,9 +247,141 @@ logger = context.JK.logger
|
|||
else if @state.selected == @TILE_USB
|
||||
@usb()
|
||||
|
||||
audio: () ->
|
||||
`<div className="audio-content">
|
||||
<JamBlasterTrackConfig />
|
||||
</div>`
|
||||
|
||||
ipSettingsChanged: (key, e) ->
|
||||
userKey = 'user' + key
|
||||
state = {}
|
||||
ip = $(e.target).val()
|
||||
state[userKey] = ip
|
||||
if ip?
|
||||
bits = ip.split('.')
|
||||
|
||||
console.log("bits", bits)
|
||||
for bit in bits
|
||||
result = @ipRegex.test(bit.replace(/_/g, ''))
|
||||
console.log("STILL GOT THAT _?", result)
|
||||
error = false
|
||||
if result == true || bit == "___"
|
||||
error = true
|
||||
break
|
||||
|
||||
if error
|
||||
console.log("SETTING ERROR for " + userKey + 'error')
|
||||
state[userKey + 'error'] = true
|
||||
else
|
||||
state[userKey + 'error'] = false
|
||||
this.setState(state)
|
||||
|
||||
onSaveNetworkSettings: (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
JamBlasterActions.saveNetworkSettings({
|
||||
dhcp: this.state.userdhcp,
|
||||
addr: this.state.useraddr,
|
||||
gateway: this.state.usergateway,
|
||||
subnet: this.state.usersubnet,
|
||||
dns1: this.state.userdns1,
|
||||
dns2: this.state.userdns2
|
||||
})
|
||||
@networkStale = true
|
||||
|
||||
usb: () ->
|
||||
`<div className="networking-content">
|
||||
<h3>USB Settings</h3>
|
||||
</div>`
|
||||
|
||||
internet: () ->
|
||||
pairedJamBlaster = this.state.pairedJamBlaster
|
||||
hasPairedJamBlaster = pairedJamBlaster?
|
||||
isJamBlasterDhcp = !!this.state.userdhcp
|
||||
|
||||
if hasPairedJamBlaster
|
||||
status =
|
||||
`<div className="jamblaster-network-status">
|
||||
<div className="status-field"><span className="status-label">Ethernet:</span><span>Connected</span></div>
|
||||
<div className="status-field"><span className="status-label">Internet:</span><span>Connected</span></div>
|
||||
<div className="status-field"><span className="status-label">Streaming:</span><span>Supported</span></div>
|
||||
</div>`
|
||||
else
|
||||
status =
|
||||
`<div className="jamblaster-network-status">
|
||||
<div className="status-field"><span className="status-label">Ethernet:</span><span>Unknown</span></div>
|
||||
<div className="status-field"><span className="status-label">Internet:</span><span>Unknown</span></div>
|
||||
<div className="status-field"><span className="status-label">Streaming:</span><span>Unknown</span></div>
|
||||
</div>`
|
||||
|
||||
addrClasses = {field: true, error: this.state.useraddrerror}
|
||||
subnetClasses = {field: true, error: this.state.usersubneterror}
|
||||
gatewayClasses = {field: true, error: this.state.usergatewayerror}
|
||||
dns1Classes = {field: true, error: this.state.userdns1error}
|
||||
dns2Classes = {field: true, error: this.state.userdns2error}
|
||||
|
||||
saveBtnClasses = {}
|
||||
saveBtnClasses["save-settings-btn"] = true
|
||||
saveBtnClasses["button-orange"] = true
|
||||
saveBtnClasses["disabled"] = !hasPairedJamBlaster
|
||||
|
||||
ipdisabled = !hasPairedJamBlaster || isJamBlasterDhcp
|
||||
|
||||
`<div className="networking-content">
|
||||
<h3>Internet Settings</h3>
|
||||
|
||||
<div className="column-left column">
|
||||
<div className="assign-ip-address">
|
||||
<h4>Assign IP Address</h4>
|
||||
|
||||
<div className="dhcpfield">
|
||||
<input className="dhcp" type="radio" name="dhcp" readOnly={true} value="true" defaultChecked={isJamBlasterDhcp}
|
||||
disabled={!hasPairedJamBlaster}/><label>Using DHCP</label>
|
||||
</div>
|
||||
<div className="dhcpfield">
|
||||
<input className="dhcp" type="radio" name="dhcp" readOnly={true} value="false" defaultChecked={!isJamBlasterDhcp}
|
||||
disabled={!hasPairedJamBlaster}/><label>Manually</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="manual-settings">
|
||||
<h4>Manual Settings</h4>
|
||||
<div className={classNames(addrClasses)}>
|
||||
<label>IP Address:</label><input className="addr networksettings" type="text" value={this.state.useraddr} name="addr" onBlur={this.ipSettingsChanged.bind(this, 'addr')} disabled={ipdisabled}></input>
|
||||
</div>
|
||||
<div className={classNames(subnetClasses)}>
|
||||
<label>Subnet Mask:</label><input className="subnet networksettings" type="text" value={this.state.usersubnet} name="subnet" onBlur={this.ipSettingsChanged.bind(this, 'subnet')} disabled={ipdisabled}></input>
|
||||
</div>
|
||||
<div className={classNames(gatewayClasses)}>
|
||||
<label>Router:</label><input className="gateway networksettings" type="text" value={this.state.usergateway} name="gateway" onBlur={this.ipSettingsChanged.bind(this, 'gateway')} disabled={ipdisabled}></input>
|
||||
</div>
|
||||
<div className={classNames(dns1Classes)}>
|
||||
<label>DNS Server 1:</label><input className="dns1 networksettings" type="text" value={this.state.userdns1} name="dns1" onBlur={this.ipSettingsChanged.bind(this, 'dns1')} disabled={ipdisabled}></input>
|
||||
</div>
|
||||
<div className={classNames(dns1Classes)}>
|
||||
<label>DNS Server 2:</label><input className="dns2 networksettings" type="text" value={this.state.userdns2} name="dns1" onBlur={this.ipSettingsChanged.bind(this, 'dns2')} disabled={ipdisabled}></input>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="save-settings">
|
||||
<a onClick={this.onSaveNetworkSettings} className={classNames(saveBtnClasses)}>SAVE SETTINGS</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="column-right column">
|
||||
<h4>Network Status</h4>
|
||||
{status}
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
management: () ->
|
||||
clients = @mergeClients()
|
||||
if @state.refreshingBonjour
|
||||
refreshingText = 'SCANNING'
|
||||
else
|
||||
refreshingText = 'SCAN NETWORK'
|
||||
|
||||
refreshClasses = {"resync-bonjour": true, "button-orange": true, disabled: @state.refreshingBonjour}
|
||||
`<div className="management-content">
|
||||
|
||||
<table className="jamtable">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
@ -156,23 +392,53 @@ logger = context.JK.logger
|
|||
{clients}
|
||||
</tbody>
|
||||
</table>
|
||||
<p>If you don't see your JamBlaster listed above, please check to make sure you have power connected to your JamBlaster,
|
||||
and make sure your JamBlaster is connected via an Ethernet cable to the same router/network as the device on which you are viewing this application.
|
||||
<a onClick={JamBlasterActions.resyncBonjour} className={classNames(refreshClasses)}>{refreshingText}</a>
|
||||
|
||||
<p className="help-text">If you don't see your JamBlaster listed above, please check to make sure you have power
|
||||
connected to your JamBlaster,
|
||||
and make sure your JamBlaster is connected via an Ethernet cable to the same router/network as the device on
|
||||
which you are viewing this application.
|
||||
</p>
|
||||
</div>`
|
||||
|
||||
tiles: () ->
|
||||
@TILES
|
||||
|
||||
selectionMade: (selection, e) ->
|
||||
e.preventDefault()
|
||||
|
||||
if selection == @TILE_INTERNET
|
||||
@networkStale = true
|
||||
|
||||
@setState({selected: selection})
|
||||
|
||||
createTileLink: (i, tile) ->
|
||||
if this.state.selected?
|
||||
active = this.state.selected == tile
|
||||
else
|
||||
active = tile == @TILE_MANAGEMENT
|
||||
|
||||
tileClasses = {activeTile: active, 'jamblaster-tile': true}
|
||||
tileClasses = classNames(tileClasses)
|
||||
|
||||
classes = classNames({last: i == @tiles().length - 1})
|
||||
|
||||
return `<div key={i} className={tileClasses}><a className={classes}
|
||||
onClick={this.selectionMade.bind(this, tile)}>{tile}</a></div>`
|
||||
|
||||
render: () ->
|
||||
disabled = @state.updating
|
||||
|
||||
if !@state.user?.id || !@state.userJamBlasters? || !@state.localClients?
|
||||
return `<div>Loading</div>`
|
||||
|
||||
tiles = []
|
||||
for tile, i in @tiles()
|
||||
tiles.push(@createTileLink(i, tile))
|
||||
|
||||
`<div className="content-body-scroller">
|
||||
<div className="">
|
||||
<h2>jamblaster settings</h2>
|
||||
|
||||
<div className="tiles">
|
||||
{tiles}
|
||||
</div>
|
||||
|
||||
<div className="jamclass-section">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,187 @@
|
|||
context = window
|
||||
JamBlasterActions = @JamBlasterActions
|
||||
|
||||
@JamBlasterTrackConfig = React.createClass({
|
||||
|
||||
mixins: [@ICheckMixin, @BonjourMixin, Reflux.listenTo(@AppStore, "onAppInit"),
|
||||
Reflux.listenTo(@JamBlasterStore, "onJamBlasterChanged")]
|
||||
|
||||
beforeShow: () ->
|
||||
|
||||
onAppInit: (@app) ->
|
||||
|
||||
onJamBlasterChanged: (jamblasterState) ->
|
||||
@setState(jamblasterState)
|
||||
|
||||
|
||||
componentDidMount: () ->
|
||||
@checkboxes = [
|
||||
{selector: 'input.track1Active', stateKey: 'track1Active'},
|
||||
{selector: 'input.track2Active', stateKey: 'track2Active'},
|
||||
{selector: 'input.micActive', stateKey: 'micActive'},
|
||||
{selector: 'input.track1Phantom', stateKey: 'track1Phantom'},
|
||||
{selector: 'input.track2Phantom', stateKey: 'track2Phantom'},
|
||||
{selector: 'input.inputTypeTrack1', stateKey: 'inputTypeTrack1'},
|
||||
{selector: 'input.inputTypeTrack2', stateKey: 'inputTypeTrack2'},
|
||||
{selector: 'input.combined', stateKey: 'combined'}]
|
||||
|
||||
@root = $(@getDOMNode())
|
||||
@iCheckify()
|
||||
|
||||
|
||||
componentDidUpdate: () ->
|
||||
@iCheckify()
|
||||
|
||||
checkboxChanged: (e) ->
|
||||
checked = $(e.target).is(':checked')
|
||||
|
||||
value = $(e.target).val()
|
||||
name = $(e.target).attr('name')
|
||||
console.log("checkbox changed: ", value)
|
||||
|
||||
if $(e.target).attr('type') == 'checkbox'
|
||||
state = {}
|
||||
state[name] = checked
|
||||
@setState(state)
|
||||
|
||||
JamBlasterActions.updateAudio(name, checked)
|
||||
else
|
||||
state = {}
|
||||
value = value == 'line'
|
||||
state[name] = value
|
||||
@setState(state)
|
||||
|
||||
JamBlasterActions.updateAudio(name, value)
|
||||
|
||||
|
||||
getInitialState: () ->
|
||||
{
|
||||
allJamBlasters: [],
|
||||
userJamBlasters: [],
|
||||
localJamBlasters: []
|
||||
}
|
||||
|
||||
convertToClientInstrument: (instrumentId) ->
|
||||
clientInstrumentId = null
|
||||
if instrumentId != null && instrumentId != ''
|
||||
clientInstrumentId = context.JK.instrument_id_to_instrument[instrumentId].client_id
|
||||
else
|
||||
clientInstrumentId = 10
|
||||
clientInstrumentId
|
||||
|
||||
render: () ->
|
||||
pairedJamBlaster = this.state.pairedJamBlaster
|
||||
hasPairedJamBlaster = pairedJamBlaster?
|
||||
masterDisabled = this.props.disabled
|
||||
|
||||
if !hasPairedJamBlaster
|
||||
return `<div className="jamblaster-track-config">
|
||||
You have no paired JamBlaster currently. If you've paired the JamBlaster in the past, be sure it's plugged in
|
||||
and connected to an ethernet cable. If you have not paired a JamBlaster before, please go to the <a
|
||||
href="/client#/jamblaster">JamBlaster management page</a>.
|
||||
</div>`
|
||||
|
||||
instruments = []
|
||||
for instrument in context.JK.server_to_client_instrument_alpha
|
||||
instruments.push(`<option key={instrument.server_id} value={instrument.server_id}>{instrument.display}</option>`)
|
||||
|
||||
combined = pairedJamBlaster.tracks?.combined
|
||||
track1Active = pairedJamBlaster.tracks?.track1Active
|
||||
track2Active = pairedJamBlaster.tracks?.track2Active
|
||||
inputTypeTrack1 = pairedJamBlaster.tracks?.inputTypeTrack1
|
||||
inputTypeTrack2 = pairedJamBlaster.tracks?.inputTypeTrack2
|
||||
track1Phantom = pairedJamBlaster.tracks?.track1Phantom
|
||||
track2Phantom = pairedJamBlaster.tracks?.track2Phantom
|
||||
micActive = pairedJamBlaster.tracks?.micActive
|
||||
track1Instrument = context.JK.convertClientInstrumentToServer(pairedJamBlaster.tracks?.track1Instrument)
|
||||
track2Instrument = context.JK.convertClientInstrumentToServer(pairedJamBlaster.tracks?.track2Instrument)
|
||||
|
||||
`<div className="jamblaster-track-config">
|
||||
<div className="input-1">
|
||||
<h3>Input 1</h3>
|
||||
<div className="track-active-field">
|
||||
<input className="track1Active input-active" name="track1Active" type="checkbox" readOnly={true} disabled={masterDisabled || combined}
|
||||
checked={track1Active}></input><label>Active</label>
|
||||
</div>
|
||||
|
||||
<div className="input-type-section">
|
||||
<h4>Type</h4>
|
||||
|
||||
<div className="input-type field">
|
||||
<div className="input-type-choice">
|
||||
<input className="input-type inputTypeTrack1" type="radio" name="inputTypeTrack1" readOnly={true} value="line" disabled={masterDisabled}
|
||||
defaultChecked={inputTypeTrack1}/><label>Line</label>
|
||||
</div>
|
||||
<div className="input-type-choice">
|
||||
<input className="input-type inputTypeTrack1" type="radio" name="inputTypeTrack1" readOnly={true} value="instrument" disabled={masterDisabled}
|
||||
defaultChecked={!inputTypeTrack1}/><label>Instrument</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="phantom-section">
|
||||
<h4>Power</h4>
|
||||
|
||||
<div className="phantom field">
|
||||
<input className="phantom track1Phantom" name="track1Phantom" type="checkbox" readOnly={true} disabled={masterDisabled}
|
||||
checked={track1Phantom}/><label>Phantom power</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="instrument-section">
|
||||
<h4>Instrument</h4>
|
||||
<select name="track1Instrument" value={track1Instrument} disabled={masterDisabled}>
|
||||
{instruments}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="input-2">
|
||||
<h3>Input 2</h3>
|
||||
<div className="track-active-field">
|
||||
<input className="track2Active input-active" name="track2Active" type="checkbox" readOnly={true} disabled={masterDisabled || combined}
|
||||
checked={track2Active}></input><label>Active</label>
|
||||
</div>
|
||||
|
||||
<div className="input-type-section">
|
||||
<h4>Type</h4>
|
||||
|
||||
<div className="input-type field">
|
||||
<div className="input-type-choice">
|
||||
<input className="input-type inputTypeTrack2" type="radio" name="inputTypeTrack2" readOnly={true} value="line" disabled={masterDisabled}
|
||||
defaultChecked={inputTypeTrack2}/><label>Line</label>
|
||||
</div>
|
||||
<div className="input-type-choice">
|
||||
<input className="input-type inputTypeTrack2" type="radio" name="inputTypeTrack2" readOnly={true} value="instrument" disabled={masterDisabled}
|
||||
defaultChecked={!inputTypeTrack2}/><label>Instrument</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="phantom-section">
|
||||
<h4>Power</h4>
|
||||
|
||||
<div className="phantom field">
|
||||
<input className="phantom track2Phantom" name="track2Phantom" type="checkbox" disabled={masterDisabled}
|
||||
readOnly={true} checked={track2Phantom}/><label>Phantom power</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="instrument-section">
|
||||
<h4>Instrument</h4>
|
||||
<select name="track2Instrument" value={track2Instrument} disabled={masterDisabled}>
|
||||
{instruments}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="microphone">
|
||||
<h3>Mic</h3>
|
||||
<div className="track-active-field">
|
||||
<input className="micActive input-active" name="micActive" type="checkbox" readOnly={true} disabled={masterDisabled}
|
||||
checked={micActive}></input><label>Active</label>
|
||||
</div>
|
||||
</div>
|
||||
<br className="clearall"/>
|
||||
|
||||
<div className="combined-option">
|
||||
<input className="combined" type="checkbox" name="combined" checked={combined} readOnly={true} disabled={masterDisabled} ></input><label>combined inputs 1 & 2 into a single stereo track</label>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
context = window
|
||||
rest = context.JK.Rest()
|
||||
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||
MIX_MODES = context.JK.MIX_MODES
|
||||
|
||||
@SessionMasterCategoryControls = React.createClass({
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
context = window
|
||||
rest = context.JK.Rest()
|
||||
SessionActions = @SessionActions
|
||||
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||
MIX_MODES = context.JK.MIX_MODES
|
||||
EVENTS = context.JK.EVENTS
|
||||
ChannelGroupIds = context.JK.ChannelGroupIds
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
context = window
|
||||
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||
MIX_MODES = context.JK.MIX_MODES
|
||||
logger = context.JK.logger
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
context = window
|
||||
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||
|
||||
@SessionMasterOtherTracks = React.createClass({
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ context = window
|
|||
rest = context.JK.Rest()
|
||||
SessionActions = @SessionActions
|
||||
JamTrackActions = @JamTrackActions
|
||||
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||
MIX_MODES = context.JK.MIX_MODES
|
||||
EVENTS = context.JK.EVENTS
|
||||
ChannelGroupIds = context.JK.ChannelGroupIds
|
||||
|
|
@ -302,9 +301,7 @@ ChannelGroupIds = context.JK.ChannelGroupIds
|
|||
<h2>recorded audio</h2>
|
||||
{contents}
|
||||
<div className={scrollerClasses}>
|
||||
<ReactCSSTransitionGroup transitionName="session-track-list" transitionAppear={true}>
|
||||
{mediaTracks}
|
||||
</ReactCSSTransitionGroup>
|
||||
{mediaTracks}
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
context = window
|
||||
MIX_MODES = context.JK.MIX_MODES
|
||||
SessionActions = context.SessionActions
|
||||
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
|
||||
|
||||
@SessionMyTracks = React.createClass({
|
||||
|
||||
|
|
@ -44,9 +43,7 @@ ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
|
|||
{delayVstEnable}
|
||||
<div className="session-tracks-scroller">
|
||||
{content}
|
||||
<ReactCSSTransitionGroup transitionName="session-track-list" transitionAppear={true}>
|
||||
{tracks}
|
||||
</ReactCSSTransitionGroup>
|
||||
{tracks}
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
context = window
|
||||
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||
NotificationActions = @NotificationActions
|
||||
|
||||
@SessionNotifications = React.createClass({
|
||||
|
|
@ -30,9 +29,8 @@ NotificationActions = @NotificationActions
|
|||
Clear Notifications
|
||||
</a>
|
||||
<div className="session-tracks-scroller">
|
||||
<ReactCSSTransitionGroup transitionName="session-track-list" transitionAppear={true}>
|
||||
{notifications}
|
||||
</ReactCSSTransitionGroup>
|
||||
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
context = window
|
||||
MixerActions = context.MixerActions
|
||||
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
||||
|
||||
@SessionOtherTracks = React.createClass({
|
||||
|
||||
|
|
@ -88,9 +87,8 @@ ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
|
|||
<SessionInviteMusiciansBtn />
|
||||
<div className="session-tracks-scroller">
|
||||
{content}
|
||||
<ReactCSSTransitionGroup transitionName="session-track-list" transitionAppear={true}>
|
||||
{participants}
|
||||
</ReactCSSTransitionGroup>
|
||||
{participants}
|
||||
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
context = window
|
||||
|
||||
@CallbackActions = Reflux.createActions({
|
||||
genericCallback: {}
|
||||
})
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
context = window
|
||||
|
||||
@JamBlasterActions = Reflux.createActions({
|
||||
resyncBonjour: {},
|
||||
clearPortBindState: {},
|
||||
saveNetworkSettings: {},
|
||||
pairState: {},
|
||||
setAutoPair: {},
|
||||
updateAudio: {}
|
||||
})
|
||||
|
|
@ -674,7 +674,7 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
oppositeMixer = oppositeMixers[ChannelGroupIds.UserMusicInputGroup][0]
|
||||
|
||||
if !oppositeMixer
|
||||
logger.warn("unable to find UserMusicInputGroup corresponding to PeerAudioInputMusicGroup mixer", mixer )
|
||||
logger.warn("unable to find UserMusicInputGroup corresponding to PeerAudioInputMusicGroup mixer", mixer, @personalMixers )
|
||||
|
||||
when MIX_MODES.PERSONAL
|
||||
mixers = @groupedMixersForClientId(client_id, [ ChannelGroupIds.UserMusicInputGroup], {}, MIX_MODES.PERSONAL)
|
||||
|
|
|
|||
|
|
@ -2,96 +2,16 @@ context = window
|
|||
teacherActions = window.JK.Actions.Teacher
|
||||
|
||||
@BonjourMixin = {
|
||||
|
||||
resyncBonjour: () ->
|
||||
rest.getUserJamBlasters({client_id: @app.clientId}).done((response) => @getUserJamBlastersDone(response)).fail((response) => @getUserJamBlastersFail(response))
|
||||
|
||||
getUserJamBlastersDone: (response) ->
|
||||
@setState({userJamBlasters: response})
|
||||
|
||||
@getLocalClients(response)
|
||||
|
||||
|
||||
findJamBlaster: (id) ->
|
||||
findJamBlaster: (oldClient) ->
|
||||
found = null
|
||||
if @clients?
|
||||
for client in @clients
|
||||
if client.id == id
|
||||
if @state.allJamBlasters?
|
||||
for client in @state.allJamBlasters
|
||||
if oldClient.server_id? && client.server_id == oldClient.server_id
|
||||
found = client
|
||||
break
|
||||
if client.ipv6_addr == id
|
||||
if oldClient.ipv6_addr? && client.ipv6_addr == oldClient.ipv6_addr
|
||||
found = client
|
||||
break
|
||||
|
||||
found
|
||||
|
||||
getUserJamBlastersFail: (jqXHR) ->
|
||||
@app.layout.ajaxError(jqXHR)
|
||||
|
||||
mergeBonjourClients: (localClients, userJamBlasters) ->
|
||||
console.log("@state.localClients", localClients)
|
||||
console.log("@state.userJamBlasters", userJamBlasters)
|
||||
|
||||
# for localClient in @state.localClients
|
||||
|
||||
for localClient in localClients
|
||||
if localClient.connect_url.indexOf(':30330') && localClient.is_jb
|
||||
client = {}
|
||||
client.ipv6_addr = localClient.ipv6_addr
|
||||
client.isPaired = localClient.isPaired
|
||||
client.name = localClient.name
|
||||
client.has_local = true
|
||||
client.has_server = false
|
||||
client.id = client.ipv6_addr
|
||||
client.connect_url = localClient.connect_url
|
||||
|
||||
|
||||
for serverClient in userJamBlasters
|
||||
# see if we can join on ipv6
|
||||
if ipv6_addr == serverClient.ipv6_link_local
|
||||
# ok, matched! augment with server data
|
||||
client.serial_no = serverClient.serial_no
|
||||
client.user_id = serverClient.user_id
|
||||
client.id = serverClient.id
|
||||
client.client_id = serverClient.client_id
|
||||
client.ipv4_link_local = serverClient.ipv4_link_local
|
||||
client.display_name = serverClient.display_name
|
||||
client.has_server = true
|
||||
break
|
||||
clients.push(client)
|
||||
|
||||
for serverClient in userJamBlasters
|
||||
|
||||
foundLocal = false
|
||||
for localClient in localClients
|
||||
if ipv6_addr == serverClient.ipv6_link_local
|
||||
foundLocal = true
|
||||
break
|
||||
if !foundLocal
|
||||
# this server version of the client has not been spoken for in the earlier loop above
|
||||
# so we need to add it in to the client list
|
||||
|
||||
client = {}
|
||||
client.serial_no = serverClient.serial_no
|
||||
client.user_id = serverClient.user_id
|
||||
client.id = serverClient.id
|
||||
client.client_id = serverClient.client_id
|
||||
client.ipv4_link_local = serverClient.ipv4_link_local
|
||||
client.display_name = serverClient.display_name
|
||||
client.has_local = false
|
||||
client.has_server = true
|
||||
clients.push(client)
|
||||
|
||||
console.log("all client", clients)
|
||||
|
||||
@clients = clients
|
||||
@setState({clients: clients})
|
||||
|
||||
getLocalClients: (userJamBlasters) ->
|
||||
localClients = context.jamClient.getLocalClients()
|
||||
|
||||
@mergeBonjourClients(localClients, userJamBlasters)
|
||||
|
||||
@setState({localClients: localClients})
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
$ = jQuery
|
||||
context = window
|
||||
logger = context.JK.logger
|
||||
SessionActions = @SessionActions
|
||||
JamBlasterActions = @JamBlasterActions
|
||||
|
||||
@CallbackStore = Reflux.createStore(
|
||||
{
|
||||
init: () ->
|
||||
# Register with the app store to get @app
|
||||
this.listenTo(context.AppStore, this.onAppInit)
|
||||
|
||||
onAppInit: (@app) ->
|
||||
if context.jamClient.RegisterGenericCallBack?
|
||||
context.jamClient.RegisterGenericCallBack('CallbackActions.genericCallback')
|
||||
|
||||
onGenericCallback: (map) ->
|
||||
if map.cmd == 'join_session'
|
||||
SessionActions.joinSession(map['music_session_id'])
|
||||
else if map.cmd == 'client_pair_state'
|
||||
JamBlasterActions.pairState(map)
|
||||
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,345 @@
|
|||
$ = jQuery
|
||||
context = window
|
||||
logger = context.JK.logger
|
||||
|
||||
@JamBlasterStore = Reflux.createStore(
|
||||
{
|
||||
listenables: @JamBlasterActions
|
||||
|
||||
userJamBlasters: []
|
||||
localJamBlasters: []
|
||||
allJamBlasters: []
|
||||
|
||||
init: () ->
|
||||
# Register with the app store to get @app
|
||||
this.listenTo(context.AppStore, this.onAppInit)
|
||||
|
||||
onAppInit: (@app) ->
|
||||
|
||||
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)
|
||||
audio = jQuery({}, @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
|
||||
|
||||
combined = @pairedJamBlaster.tracks.combined
|
||||
if name == 'combined'
|
||||
combined = value
|
||||
|
||||
track1Instrument = audio.track1Instrument
|
||||
track2Instrument = audio.track2Instrument
|
||||
if name == 'track1Instrument'
|
||||
track1Instrument = @convertToClientInstrument(value)
|
||||
if name == 'track2Instrument'
|
||||
track2Instrument = @convertToClientInstrument(value)
|
||||
|
||||
|
||||
|
||||
|
||||
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}
|
||||
|
||||
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}
|
||||
|
||||
else # input2Active
|
||||
|
||||
audio.track2 = {stereo: false, right: true, inst: track2Instrument}
|
||||
|
||||
|
||||
|
||||
|
||||
logger.debug("updating JamBlaster track state", audio)
|
||||
context.jamClient.setJbTrackState(audio);
|
||||
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.')
|
||||
|
||||
convertToClientInstrument: (instrumentId) ->
|
||||
clientInstrumentId = null
|
||||
if instrumentId != null && instrumentId != ''
|
||||
clientInstrumentId = context.JK.instrument_id_to_instrument[instrumentId].client_id
|
||||
else
|
||||
clientInstrumentId = 10
|
||||
clientInstrumentId
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
})
|
||||
|
||||
onPairState: (state) ->
|
||||
if state.client_pair_state == 10
|
||||
# fully paired
|
||||
logger.debug("backend indicates we are paired with a client")
|
||||
@onResyncBonjour()
|
||||
|
||||
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
|
||||
@onClearNetworkState()
|
||||
@onResyncBonjour()
|
||||
|
||||
onResyncBonjour: () ->
|
||||
|
||||
if @refreshingBonjour
|
||||
logger.debug("already refreshing bonjour")
|
||||
return
|
||||
|
||||
@refreshingBonjour = true
|
||||
@changed()
|
||||
rest.getUserJamBlasters({client_id: @app.clientId}).done((response) => @getUserJamBlastersDone(response)).fail((response) => @getUserJamBlastersFail(response))
|
||||
|
||||
getUserJamBlastersDone: (response) ->
|
||||
@userJamBlasters = response
|
||||
|
||||
@changed()
|
||||
|
||||
@getLocalClients(response)
|
||||
|
||||
|
||||
findJamBlaster: (oldClient) ->
|
||||
found = null
|
||||
if @clients?
|
||||
for client in @clients
|
||||
if oldClient.server_id? && client.server_id == oldClient.server_id
|
||||
found = client
|
||||
break
|
||||
if oldClient.ipv6_addr? && client.ipv6_addr == oldClient.ipv6_addr
|
||||
found = client
|
||||
break
|
||||
|
||||
found
|
||||
|
||||
getUserJamBlastersFail: (jqXHR) ->
|
||||
@refreshingBonjour = false
|
||||
@changed()
|
||||
@app.layout.ajaxError(jqXHR)
|
||||
|
||||
getAutoPair: () ->
|
||||
if @lastClientAutoPair?
|
||||
return @lastClientAutoPair
|
||||
else
|
||||
return @getJbAutoPair()
|
||||
|
||||
getNetworkState: (client) ->
|
||||
if @lastClientNetworkState? && @lastClientNetworkState.ipv6_addr == client.ipv6_addr
|
||||
return @lastClientNetworkState
|
||||
else
|
||||
return @getJbNetworkState(client)
|
||||
|
||||
getPortState: (client) ->
|
||||
if @lastClientPortState? && @lastClientPortState.ipv6_addr == client.ipv6_addr
|
||||
return @lastClientPortState
|
||||
else
|
||||
return @getJbPortBindState(client)
|
||||
|
||||
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
|
||||
|
||||
getJbAutoPair:() ->
|
||||
@lastClientAutoPair = context.jamClient.getJBAutoPair()
|
||||
console.log("context.jamClient.getJBAutoPair()", @lastClientAutoPair)
|
||||
return @lastClientAutoPair
|
||||
|
||||
getJbTrackState:(client) ->
|
||||
@lastClientTrackState = context.jamClient.getJbTrackState()
|
||||
console.log("context.jamClient.getJbTrackState()", @lastClientTrackState)
|
||||
@lastClientTrackState.ipv6_addr = client.ipv6_addr
|
||||
return @lastClientTrackState
|
||||
|
||||
onClearPortBindState: () ->
|
||||
@lastClientPortState = null
|
||||
|
||||
onClearNetworkState: () ->
|
||||
@lastClientNetworkState = null
|
||||
|
||||
mergeBonjourClients: (localClients, userJamBlasters) ->
|
||||
console.log("@state.localClients", localClients)
|
||||
console.log("@state.userJamBlasters", userJamBlasters)
|
||||
|
||||
# for localClient in @state.localClients
|
||||
|
||||
autoconnect = @getAutoPair()
|
||||
|
||||
foundPaired = null
|
||||
clients = []
|
||||
for localClient in localClients
|
||||
if localClient.connect_url.indexOf(':30330') > -1 && localClient.is_jb
|
||||
client = {}
|
||||
client.ipv6_addr = localClient.ipv6_addr
|
||||
client.isConnected = localClient.isPaired
|
||||
client.name = localClient.name
|
||||
client.has_local = true
|
||||
client.has_server = false
|
||||
client.id = client.ipv6_addr
|
||||
client.connect_url = localClient.connect_url
|
||||
client.isPaired = localClient.pstate? && localClient.pstate == 10 # ePairingState.Paired
|
||||
client.autoconnect = autoconnect
|
||||
|
||||
if client.isPaired
|
||||
client.portState = @getPortState(client)
|
||||
client.network = @getNetworkState(client)
|
||||
client.tracks = @getJbTrackState(client)
|
||||
client.isDynamicPorts = client.portState?.use_static_port
|
||||
foundPaired = client
|
||||
|
||||
|
||||
if client.tracks?
|
||||
client.tracks.inputTypeTrack1 = client.tracks.input1_linemode
|
||||
client.tracks.inputTypeTrack2 = client.tracks.input2_linemode
|
||||
client.tracks.track1Phantom = client.tracks.input1_48V
|
||||
client.tracks.track2Phantom = client.tracks.input2_48V
|
||||
client.tracks.micActive = client.tracks.has_chat
|
||||
|
||||
# combined
|
||||
track1 = client.tracks.track1
|
||||
track2 = client.tracks.track1
|
||||
if track1?
|
||||
|
||||
client.tracks.combined = track1.stereo
|
||||
if track1.stereo
|
||||
client.tracks.track1Active = true
|
||||
client.tracks.track2Active = true
|
||||
client.tracks.track1Active = track1.left
|
||||
client.tracks.track2Active = track1.right
|
||||
client.tracks.track1Instrument = track1.inst
|
||||
|
||||
if track2?
|
||||
client.tracks.track2Instrument = track2.inst
|
||||
client.tracks.track1Active = track2.left
|
||||
client.tracks.track2Active = track2.right
|
||||
# map["adaptiveframe"] = jbcfg.adaptiveframe();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for serverClient in userJamBlasters
|
||||
# see if we can join on ipv6
|
||||
if ipv6_addr == serverClient.ipv6_link_local
|
||||
# ok, matched! augment with server data
|
||||
client.serial_no = serverClient.serial_no
|
||||
client.user_id = serverClient.user_id
|
||||
client.id = serverClient.id
|
||||
client.server_id = serverClient.id
|
||||
client.client_id = serverClient.client_id
|
||||
client.ipv4_link_local = serverClient.ipv4_link_local
|
||||
client.display_name = serverClient.display_name
|
||||
client.has_server = true
|
||||
break
|
||||
clients.push(client)
|
||||
|
||||
for serverClient in userJamBlasters
|
||||
|
||||
foundLocal = false
|
||||
for localClient in localClients
|
||||
if ipv6_addr == serverClient.ipv6_link_local
|
||||
foundLocal = true
|
||||
break
|
||||
if !foundLocal
|
||||
# this server version of the client has not been spoken for in the earlier loop above
|
||||
# so we need to add it in to the client list
|
||||
|
||||
client = {}
|
||||
client.serial_no = serverClient.serial_no
|
||||
client.user_id = serverClient.user_id
|
||||
client.id = serverClient.id
|
||||
client.client_id = serverClient.client_id
|
||||
client.ipv4_link_local = serverClient.ipv4_link_local
|
||||
client.display_name = serverClient.display_name
|
||||
client.has_local = false
|
||||
client.has_server = true
|
||||
client.autoconnect = autoconnect
|
||||
clients.push(client)
|
||||
|
||||
@pairedJamBlaster = foundPaired
|
||||
|
||||
console.log("all client", clients)
|
||||
|
||||
@clients = clients
|
||||
@changed()
|
||||
|
||||
getLocalClients: (userJamBlasters) ->
|
||||
@localClients = context.jamClient.getLocalClients()
|
||||
|
||||
@mergeBonjourClients(@localClients, userJamBlasters)
|
||||
|
||||
@refreshingBonjour = false
|
||||
@changed()
|
||||
|
||||
|
||||
changed: () ->
|
||||
@trigger({userJamBlasters: @userJamBlasters, allJamBlasters: @clients, localJamBlasters: @localClients, refreshingBonjour: @refreshingBonjour, pairedJamBlaster: @pairedJamBlaster})
|
||||
}
|
||||
)
|
||||
|
|
@ -101,7 +101,16 @@
|
|||
track.instrument_id = context.JK.server_to_client_instrument_map["Other"].server_id;
|
||||
}
|
||||
else {
|
||||
track.instrument_id = context.JK.client_to_server_instrument_map[localMusicTracks[i].instrument_id].server_id;
|
||||
|
||||
var instrument = context.JK.client_to_server_instrument_map[localMusicTracks[i].instrument_id]
|
||||
if (instrument) {
|
||||
track.instrument_id = instrument.server_id
|
||||
}
|
||||
else {
|
||||
logger.debug("backend reported an invalid instrument ID of " + localMusicTracks[i].instrument_id)
|
||||
track.instrument_id = 'other'
|
||||
}
|
||||
|
||||
}
|
||||
if (localMusicTracks[i].stereo) {
|
||||
track.sound = "stereo";
|
||||
|
|
|
|||
|
|
@ -688,6 +688,15 @@
|
|||
return instrumentArray;
|
||||
}
|
||||
|
||||
context.JK.convertClientInstrumentToServer = function(clientId) {
|
||||
var serverInstrument = context.JK.client_to_server_instrument_map[clientId]
|
||||
|
||||
if (!serverInstrument)
|
||||
return 'other'
|
||||
else
|
||||
return serverInstrument.server_id
|
||||
}
|
||||
|
||||
context.JK.showErrorDialog = function (app, msg, title) {
|
||||
app.layout.showDialog('error-dialog');
|
||||
$('#error-msg', 'div[layout-id="error-dialog"]').html(msg);
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ ul.shortcuts {
|
|||
padding:2px;
|
||||
}
|
||||
|
||||
.account-home, .band-setup, .account-menu-group, .get-help, .community-forum, .invite-friends {
|
||||
.account-home, .band-setup, .account-menu-group, .get-help, .community-forum, .invite-friends, .jamblaster-config {
|
||||
border-bottom:1px;
|
||||
border-style:solid;
|
||||
border-color:#ED3618;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@
|
|||
border-bottom:0 !important;
|
||||
}
|
||||
|
||||
&.isDynamicPorts .bt-content{
|
||||
width:140px !important;
|
||||
}
|
||||
|
||||
.bt-content {
|
||||
height:80px;
|
||||
width:100px;
|
||||
|
|
|
|||
|
|
@ -5,12 +5,40 @@
|
|||
div[data-react-class="JamBlasterScreen"] {
|
||||
height:100%;
|
||||
}
|
||||
|
||||
|
||||
h3 {
|
||||
font-weight:bold;
|
||||
font-size:18px;
|
||||
color:white;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size:16px;
|
||||
color:white;
|
||||
font-weight:bold;
|
||||
margin:30px 0 10px 0;
|
||||
}
|
||||
.content-body-scroller {
|
||||
height:100%;
|
||||
padding:30px;
|
||||
@include border_box_sizing;
|
||||
}
|
||||
|
||||
.column {
|
||||
float:left;
|
||||
width:50%;
|
||||
@include border_box_sizing;
|
||||
|
||||
&.column-left {
|
||||
padding-right:20px;
|
||||
}
|
||||
&.column-right {
|
||||
padding-left:20px;
|
||||
}
|
||||
}
|
||||
|
||||
ol {
|
||||
li {
|
||||
margin-left:15px;
|
||||
|
|
@ -20,6 +48,58 @@
|
|||
}
|
||||
}
|
||||
|
||||
.tiles {
|
||||
float:right;
|
||||
margin-bottom: 40px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
.jamblaster-tile {
|
||||
float:left;
|
||||
@include border-box_sizing;
|
||||
width:117px;
|
||||
border-radius:4px;
|
||||
margin-left:7px;
|
||||
height: 32px;
|
||||
line-height:32px;
|
||||
position: relative;
|
||||
background-color:#535353;
|
||||
|
||||
&.activeTile
|
||||
{
|
||||
background-color: #ed3618;
|
||||
}
|
||||
|
||||
a {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
bottom:0;
|
||||
left:0;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 0 10px 0;
|
||||
color:white;
|
||||
background-color:transparent;
|
||||
@include border-box_sizing;
|
||||
}
|
||||
}
|
||||
|
||||
.networking-content {
|
||||
.field {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.iradio_minimal {
|
||||
display: inline-block;
|
||||
top: 4px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
label {
|
||||
display:inline-block;
|
||||
}
|
||||
.dhcpfield {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
}
|
||||
|
||||
.student-right-content {
|
||||
p {
|
||||
margin-bottom:10px;
|
||||
|
|
@ -35,28 +115,11 @@
|
|||
}
|
||||
}
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
font-size: 22px;
|
||||
font-weight:700;
|
||||
margin-bottom: 20px !important;
|
||||
margin-bottom: 40px !important;
|
||||
display:inline-block;
|
||||
}
|
||||
.column {
|
||||
@include border_box_sizing;
|
||||
width:50%;
|
||||
}
|
||||
.column-left {
|
||||
float:left;
|
||||
width:70%;
|
||||
}
|
||||
.column-right {
|
||||
float:right;
|
||||
width:30%;
|
||||
padding-left:20px;
|
||||
|
||||
.jamclass-section {
|
||||
padding-top:36px;
|
||||
}
|
||||
}
|
||||
span.price {
|
||||
color:white;
|
||||
}
|
||||
|
|
@ -112,7 +175,7 @@
|
|||
height:100%;
|
||||
width:100%;
|
||||
table-layout:fixed;
|
||||
margin-bottom:20px;
|
||||
margin-bottom:10px;
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
color:#fc0 !important;
|
||||
|
|
@ -178,4 +241,55 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.resync-bonjour {
|
||||
float:right;
|
||||
margin-right:3px;
|
||||
margin-bottom:20px;
|
||||
width:110px;
|
||||
}
|
||||
p.help-text {
|
||||
clear:both;
|
||||
}
|
||||
.save-settings-btn {
|
||||
width:200px;
|
||||
}
|
||||
.manual-settings {
|
||||
margin:20px 0;
|
||||
label {
|
||||
display:inline-block;
|
||||
color: $ColorTextTypical;
|
||||
width: 90px;
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
input {
|
||||
display:inline-block;
|
||||
|
||||
}
|
||||
}
|
||||
.status-label {
|
||||
width:80px;
|
||||
display:inline-block;
|
||||
}
|
||||
.status-field {
|
||||
margin-bottom:10px;
|
||||
color:$ColorTextTypical;
|
||||
}
|
||||
|
||||
.input-1 {
|
||||
@include border-box_sizing;
|
||||
width:200px;
|
||||
margin-right:20px;
|
||||
}
|
||||
|
||||
.input-2 {
|
||||
@include border-box_sizing;
|
||||
width:200px;
|
||||
margin-right:20px;
|
||||
}
|
||||
|
||||
.microphone {
|
||||
@include border-box_sizing;
|
||||
width:200px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
@import "client/common";
|
||||
|
||||
.jamblaster-track-config {
|
||||
|
||||
|
||||
h3 {
|
||||
font-weight:bold;
|
||||
font-size:18px;
|
||||
color:white;
|
||||
margin-bottom:10px;
|
||||
width:100%;
|
||||
border-width:0 0 1px 0;
|
||||
border-color: $ColorTextTypical;
|
||||
border-style:solid;
|
||||
padding-bottom:5px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size:14px;
|
||||
color:white;
|
||||
margin:0 0 10px 0;
|
||||
}
|
||||
|
||||
.input-1 {
|
||||
position:relative;
|
||||
@include border-box_sizing;
|
||||
width:200px;
|
||||
margin-right:20px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
.input-2 {
|
||||
position:relative;
|
||||
@include border-box_sizing;
|
||||
width:200px;
|
||||
margin-right:20px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
.microphone {
|
||||
position:relative;
|
||||
@include border-box_sizing;
|
||||
width:200px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
.iradio_minimal {
|
||||
display: inline-block;
|
||||
top: 4px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.icheckbox_minimal {
|
||||
display: inline-block;
|
||||
top: 2px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
label {
|
||||
display:inline-block;
|
||||
}
|
||||
.input-type-section {
|
||||
margin:20px 0 30px;
|
||||
}
|
||||
.phantom-section {
|
||||
margin:20px 0 30px;
|
||||
}
|
||||
.instrument-section {
|
||||
margin:20px 0 30px;
|
||||
}
|
||||
.track-active-field {
|
||||
position:absolute;
|
||||
top:-4px;
|
||||
right:0;
|
||||
}
|
||||
.input-type-choice {
|
||||
&:first-of-type {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
.tab {
|
||||
padding-top:20px;
|
||||
}
|
||||
.tab[tab-id="music-audio"] {
|
||||
.tab[data-tab-id="music-audio"] {
|
||||
.column {
|
||||
&:nth-of-type(1) {
|
||||
width: 30%;
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.tab[tab-id="voice-chat"] {
|
||||
.tab[data-tab-id="voice-chat"] {
|
||||
.column {
|
||||
&:nth-of-type(1) {
|
||||
width: 50%;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@
|
|||
}
|
||||
.actions {
|
||||
float:right;
|
||||
margin:0 -13px 30px 0;
|
||||
margin:20px 0 30px 0;
|
||||
}
|
||||
.help-text {
|
||||
margin:0 0 20px 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#jamblaster-pairing-dialog {
|
||||
width: 600px;
|
||||
max-height:600px;
|
||||
|
||||
h2 {
|
||||
color:white;
|
||||
|
|
@ -11,7 +10,8 @@
|
|||
}
|
||||
.dialog-inner {
|
||||
width: auto;
|
||||
height:calc(100% - 29px)
|
||||
height:calc(100% - 29px);
|
||||
padding-bottom:75px;
|
||||
}
|
||||
|
||||
.field {
|
||||
|
|
@ -34,8 +34,13 @@
|
|||
|
||||
}
|
||||
.actions {
|
||||
float:right;
|
||||
margin:0 -13px 30px 0;
|
||||
position:absolute;
|
||||
right:0;
|
||||
bottom:0;
|
||||
margin:0 20px 30px 0;
|
||||
}
|
||||
.countdown-msg {
|
||||
margin-top:30px;
|
||||
}
|
||||
.countdown {
|
||||
color:white;
|
||||
|
|
@ -44,5 +49,9 @@
|
|||
padding:0 10px;
|
||||
width:30px;
|
||||
display:inline-block;
|
||||
text-align:center;
|
||||
}
|
||||
.message {
|
||||
margin-top:20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
@import "client/common";
|
||||
|
||||
#jamblaster-port-dialog {
|
||||
width: 600px;
|
||||
max-height:600px;
|
||||
|
||||
h2 {
|
||||
color:white;
|
||||
margin-bottom:10px;
|
||||
font-size:16px;
|
||||
}
|
||||
.dialog-inner {
|
||||
width: auto;
|
||||
height:calc(100% - 29px)
|
||||
}
|
||||
|
||||
.field {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
input {
|
||||
display:inline-block;
|
||||
}
|
||||
label {
|
||||
display:inline-block;
|
||||
}
|
||||
.iradio_minimal {
|
||||
display:inline-block;
|
||||
margin-right: 5px;
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
div[data-react-class="JamBlasterNameDialog"] {
|
||||
|
||||
}
|
||||
.actions {
|
||||
float:right;
|
||||
margin:20px 0 30px 0;
|
||||
}
|
||||
.help-text {
|
||||
margin:0 0 20px 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,13 @@
|
|||
script type='text/template' id='template-jamblaster-options'
|
||||
|
||||
ul
|
||||
= '{% if (data.autoconnect) { %}'
|
||||
li data-jamblaster-option="auto-connect"
|
||||
a href='#' Cancel Auto Connect
|
||||
= '{% } else { %}'
|
||||
li data-jamblaster-option="auto-connect"
|
||||
a href='#' Auto Connect
|
||||
= '{% } %}'
|
||||
|
||||
li data-jamblaster-option="restart"
|
||||
a href='#' Restart
|
||||
|
|
@ -13,8 +18,12 @@ script type='text/template' id='template-jamblaster-options'
|
|||
li data-jamblaster-option="check-for-updates"
|
||||
a href='#' Check for Updates
|
||||
|
||||
= '{% if (data.isDynamicPorts) { %}'
|
||||
li data-jamblaster-option="set-static-ports"
|
||||
a href='#' Revert To Dynamic Ports
|
||||
= '{% } else { %}'
|
||||
li data-jamblaster-option="set-static-ports"
|
||||
a href='#' Set Static Ports
|
||||
|
||||
= '{% } %}'
|
||||
li data-jamblaster-option="factory-reset"
|
||||
a href='#' Factory Reset
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
.input
|
||||
input type="number" name="static-port"
|
||||
label for="static-port" The first port that the client will open
|
||||
p.hint You can specify any port you like, but we recommend an even number in the range including 1026-49150 to avoid conflicts with other programs. When configuring Port Forwarding in your router, be sure to open this port along with the next ten. For example, if this field is 12000, then in your router, forward ports 12000-12010 to your computer's IP address.
|
||||
p.hint You can specify any port you like, but we recommend an even number in the range including 1026-49150 to avoid conflicts with other programs. When configuring Port Forwarding in your router, be sure to open this port along with the next 10. For example, if this field is 12000, then in your router, forward ports 12000-12010 to your computer's IP address.
|
||||
br clear='all'
|
||||
br clear='all'
|
||||
.buttons
|
||||
|
|
|
|||
|
|
@ -3,51 +3,4 @@
|
|||
= image_tag "content/icon_add.png", {:width => 19, :height => 19, :class => 'content-icon' }
|
||||
%h1 configure tracks
|
||||
.dialog-inner
|
||||
.dialog-tabs
|
||||
%a.selected.tab-configure-audio Inputs & Outputs
|
||||
%a.tab-configure-voice Voice Chat
|
||||
|
||||
.instructions
|
||||
%span
|
||||
Choose your audio device. Drag and drop to assign input ports to tracks, and specify the instrument
|
||||
for each track. Drag and drop to assign a pair of output ports for session stereo audio monitoring.
|
||||
|
||||
.clearall
|
||||
|
||||
.tab.no-selection-range{'tab-id' => 'music-audio'}
|
||||
|
||||
= react_component 'ConfigureTracks', {}
|
||||
|
||||
.clearall
|
||||
|
||||
|
||||
|
||||
.tab{'tab-id' => 'voice-chat'}
|
||||
|
||||
%form.select-voice-chat-option.section.voice
|
||||
.sub-header Select Voice Chat Option
|
||||
.voicechat-option.reuse-audio-input
|
||||
%input{type:"radio", name: "voicechat", checked:"checked"}
|
||||
%h3 Use Music Microphone
|
||||
%p I am already using a microphone to capture my vocal or instrumental music, so I can talk with other musicians using that microphone
|
||||
.voicechat-option.use-chat-input
|
||||
%input{type:"radio", name: "voicechat"}
|
||||
%h3 Use Chat Microphone
|
||||
%p I am not using a microphone for acoustic instruments or vocals, so use the input selected to the right for voice chat during my sessions
|
||||
.clearall
|
||||
.select-voice-chat
|
||||
.sub-header Voice Chat Input
|
||||
.ftue-box.chat-inputs
|
||||
.vu-meter
|
||||
.ftue-controls
|
||||
.ftue-vu-left.voice-chat-vu-left
|
||||
.ftue-fader.chat-fader
|
||||
.gain-label GAIN
|
||||
.ftue-vu-right.voice-chat-vu-right
|
||||
.clearall
|
||||
|
||||
.buttons
|
||||
%a.btn-add-new-audio-gear.button-grey{'layout-link' => 'add-new-audio-gear'} ADD NEW AUDIO GEAR
|
||||
%a.button-grey.btn-cancel{href:'#'} CANCEL
|
||||
%a.button-orange.btn-update-settings{href:'#'} SAVE SETTINGS
|
||||
|
||||
= react_component 'ConfigureTracksDialogContents', {}
|
||||
|
|
@ -57,4 +57,5 @@
|
|||
= render 'dialogs/musicNotationUploadDialog'
|
||||
= render 'dialogs/testDrivePackageDialog'
|
||||
= render 'dialogs/jamblasterNameDialog'
|
||||
= render 'dialogs/jamblasterPortDialog'
|
||||
= render 'dialogs/jamblasterPairingDialog'
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
.dialog.dialog-overlay-sm.top-parent layout='dialog' layout-id='jamblaster-port-dialog' id='jamblaster-port-dialog'
|
||||
= react_component 'JamBlasterPortDialog', {}
|
||||
|
|
@ -47,6 +47,9 @@
|
|||
<% if current_user && current_user.affiliate_partner.present? %>
|
||||
<li class="affiliate account-menu-group"><%= link_to "Affiliate Report", '/client#/account/affiliate' %></li>
|
||||
<% end %>
|
||||
<% if @nativeClient %>
|
||||
<li class="jamblaster-config"><%= link_to "JamBlaster", '/client#/jamblaster' %></li>
|
||||
<% end %>
|
||||
<% if current_user && current_user.musician? %>
|
||||
<li class="band-setup"><%= link_to "Band Setup", '/client#/band/setup/new' %></li>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
namespace :jam_tracks do
|
||||
|
||||
task import_click_tracks: :environment do |task, args|
|
||||
JamTrackImporter.storage_format = 'Tency'
|
||||
JamTrackImporter.storage_format = 'Helbing'
|
||||
JamTrackImporter.import_click_tracks
|
||||
end
|
||||
|
||||
|
|
@ -124,8 +124,8 @@ namespace :jam_tracks do
|
|||
end
|
||||
|
||||
task resync_instruments: :environment do |task, args|
|
||||
JamTrackImporter.storage_format = 'Paris'
|
||||
JamTrackImporter.resync_instruments(JamTrackLicensor.find_by_name!('Paris Music'))
|
||||
JamTrackImporter.storage_format = ENV['STORAGE_FORMAT']
|
||||
JamTrackImporter.resync_instruments(JamTrackLicensor.find_by_name!('Stockton Helbing'))
|
||||
end
|
||||
|
||||
|
||||
|
|
@ -249,6 +249,11 @@ namespace :jam_tracks do
|
|||
JamTrackImporter.synchronize_jamtrack_aac_previews
|
||||
end
|
||||
|
||||
task sync_click_mp3_to_wav: :environment do |task, args|
|
||||
JamTrackImporter.storage_format = 'Helbing'
|
||||
JamTrackImporter.convert_click_track_to_wavs
|
||||
end
|
||||
|
||||
# popuplate preview info without uploading/processing audio files (use what's in S3)
|
||||
task sync_previews_dev: :environment do |task, args|
|
||||
JamTrackImporter.synchronize_previews_dev
|
||||
|
|
|
|||
Loading…
Reference in New Issue