Working on Jazz imports Stockton Helbing
This commit is contained in:
parent
17322eab1d
commit
e95c7fe8e5
|
|
@ -358,4 +358,5 @@ audio_in_music_notations.sql
|
|||
lesson_time_tracking.sql
|
||||
packaged_test_drive.sql
|
||||
packaged_test_drive2.sql
|
||||
jamclass_report.sql
|
||||
jamclass_report.sql
|
||||
jamblasters_network.sql
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE jamblasters ADD COLUMN ipv6_link_local VARCHAR;
|
||||
ALTER TABLE jamblasters ADD COLUMN ipv4_link_local VARCHAR;
|
||||
ALTER TABLE jamblasters ADD COLUMN display_name VARCHAR;
|
||||
|
|
@ -505,6 +505,11 @@ module JamRuby
|
|||
@storage_format == 'Tency'
|
||||
end
|
||||
|
||||
def is_helbing_storage?
|
||||
assert_storage_set
|
||||
@storage_format == 'Helbing'
|
||||
end
|
||||
|
||||
def is_paris_storage?
|
||||
assert_storage_set
|
||||
@storage_format == 'Paris'
|
||||
|
|
@ -550,7 +555,7 @@ module JamRuby
|
|||
song = metalocation[(first_dash+3)..-1].strip
|
||||
bits << song
|
||||
|
||||
elsif is_tency_storage? || is_tim_tracks_storage?
|
||||
elsif is_tency_storage? || is_tim_tracks_storage? || is_helbing_storage?
|
||||
|
||||
suffix = '/meta.yml'
|
||||
|
||||
|
|
@ -582,6 +587,9 @@ module JamRuby
|
|||
if is_tim_tracks_storage?
|
||||
song = metalocation[(first_dash+3)..-1].strip
|
||||
bits << song
|
||||
elsif is_helbing_storage?
|
||||
song = metalocation[(first_dash+3)..-1].strip
|
||||
bits << song
|
||||
elsif is_tency_storage?
|
||||
last_dash = metalocation.rindex('-')
|
||||
if last_dash
|
||||
|
|
@ -881,6 +889,9 @@ module JamRuby
|
|||
elsif is_tim_tracks_storage?
|
||||
jam_track.vendor_id = metadata[:id]
|
||||
jam_track.licensor = JamTrackLicensor.find_by_name!('Tim Waurick')
|
||||
elsif is_helbing_storage?
|
||||
jam_track.vendor_id = metadata[:id]
|
||||
jam_track.licensor = JamTrackLicensor.find_by_name!('Stockton Helbing')
|
||||
elsif is_drumma_storage?
|
||||
jam_track.vendor_id = metadata[:id]
|
||||
jam_track.licensor = JamTrackLicensor.find_by_name!('Drumma Boy')
|
||||
|
|
@ -2231,6 +2242,8 @@ module JamRuby
|
|||
tim_tracks_s3_manager
|
||||
elsif is_drumma_storage?
|
||||
drumma_s3_manager
|
||||
elsif is_helbing_storage?
|
||||
helbing_s3_manager
|
||||
else
|
||||
s3_manager
|
||||
end
|
||||
|
|
@ -2256,6 +2269,10 @@ module JamRuby
|
|||
@tim_tracks_s3_manager ||= S3Manager.new('jamkazam-timtracks', APP_CONFIG.aws_access_key_id, APP_CONFIG.aws_secret_access_key)
|
||||
end
|
||||
|
||||
def helbing_s3_manager
|
||||
@tim_tracks_s3_manager ||= S3Manager.new('jamkazam-helbing', APP_CONFIG.aws_access_key_id, APP_CONFIG.aws_secret_access_key)
|
||||
end
|
||||
|
||||
def s3_manager
|
||||
@s3_manager ||= S3Manager.new(APP_CONFIG.aws_bucket_jamtracks, APP_CONFIG.aws_access_key_id, APP_CONFIG.aws_secret_access_key)
|
||||
end
|
||||
|
|
@ -2328,6 +2345,12 @@ module JamRuby
|
|||
@storage_format == 'TimTracks'
|
||||
end
|
||||
|
||||
def is_helbing_storage?
|
||||
assert_storage_set
|
||||
@storage_format == 'Helbing'
|
||||
end
|
||||
|
||||
|
||||
def assert_storage_set
|
||||
raise "no storage_format set" if @storage_format.nil?
|
||||
end
|
||||
|
|
@ -2418,6 +2441,22 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def iterate_helbing_song_storage(&blk)
|
||||
count = 0
|
||||
song_storage_manager.list_directories('mapped').each do |song|
|
||||
@@log.debug("searching through song directory '#{song}'")
|
||||
|
||||
metalocation = "#{song}meta.yml"
|
||||
|
||||
metadata = load_metalocation(metalocation)
|
||||
|
||||
blk.call(metadata, metalocation)
|
||||
|
||||
count += 1
|
||||
#break if count > 100
|
||||
end
|
||||
end
|
||||
|
||||
def iterate_song_storage(&blk)
|
||||
if is_tency_storage?
|
||||
iterate_tency_song_storage do |metadata, metalocation|
|
||||
|
|
@ -2435,6 +2474,10 @@ module JamRuby
|
|||
iterate_drumma_song_storage do |metadata, metalocation|
|
||||
blk.call(metadata, metalocation)
|
||||
end
|
||||
elsif is_helbing_storage?
|
||||
iterate_helbing_song_storage do |metadata, metalocation|
|
||||
blk.call(metadata, metalocation)
|
||||
end
|
||||
else
|
||||
iterate_default_song_storage do |metadata, metalocation|
|
||||
blk.call(metadata, metalocation)
|
||||
|
|
@ -3387,7 +3430,10 @@ module JamRuby
|
|||
|
||||
if is_tim_tracks_storage?
|
||||
meta[:genres] = ['acapella']
|
||||
elsif is_helbing_storage?
|
||||
meta[:genres] = ['jazz']
|
||||
end
|
||||
|
||||
meta
|
||||
rescue AWS::S3::Errors::NoSuchKey
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ module JamRuby
|
|||
has_many :tracks, :class_name => "JamRuby::Track", :inverse_of => :connection, :foreign_key => 'connection_id', :dependent => :delete_all
|
||||
has_many :backing_tracks, :class_name => "JamRuby::BackingTrack", :inverse_of => :connection, :foreign_key => 'connection_id', :dependent => :delete_all
|
||||
has_many :video_sources, :class_name => "JamRuby::VideoSource", :inverse_of => :connection, :foreign_key => 'connection_id', :dependent => :delete_all
|
||||
has_one :jamblaster, class_name: "JamRuby::Jamblaster", foreign_key: "client_id"
|
||||
|
||||
validates :metronome_open, :inclusion => {:in => [true, false]}
|
||||
validates :as_musician, :inclusion => {:in => [true, false, nil]}
|
||||
|
|
@ -87,6 +88,12 @@ module JamRuby
|
|||
joining_session
|
||||
end
|
||||
|
||||
def same_network_jamblasters
|
||||
# return all jamblasters that are currently connected with the same public IP address (don't include this one though)
|
||||
Jamblaster.joins(:connection).where("connections.ip_address = ?", ip_address).where("connections.id != ?", id).limit(100)
|
||||
end
|
||||
|
||||
|
||||
def can_join_music_session
|
||||
|
||||
# puts "can_join_music_session: #{music_session_id} was #{music_session_id_was}" if music_session_id_changed?
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ module JamRuby
|
|||
has_many :jamblasters_users, class_name: "JamRuby::JamblasterUser"
|
||||
has_many :users, class_name: 'JamRuby::User', through: :jamblasters_users
|
||||
has_many :jamblaster_pairing_requests, class_name: "JamRuby::JamblasterPairingRequest", foreign_key: :jamblaster_id
|
||||
|
||||
belongs_to :connection, class_name: "JamRuby::Connection", foreign_key: "client_id"
|
||||
validates :user, presence: true
|
||||
|
||||
validates :serial_no, uniqueness: true
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ module JamRuby
|
|||
|
||||
# updating_password corresponds to a lost_password
|
||||
attr_accessor :test_drive_packaging, :validate_instruments, :updating_password, :updating_email, :updated_email, :update_email_confirmation_url, :administratively_created, :current_password, :setting_password, :confirm_current_password, :updating_avatar, :updating_progression_field, :mods_json, :expecting_gift_card
|
||||
|
||||
belongs_to :icecast_server_group, class_name: "JamRuby::IcecastServerGroup", inverse_of: :users, foreign_key: 'icecast_server_group_id'
|
||||
|
||||
has_many :controlled_sessions, :class_name => "JamRuby::MusicSession", inverse_of: :session_controller, foreign_key: :session_controller_id
|
||||
|
|
|
|||
|
|
@ -102,6 +102,13 @@ gem 'zip-codes'
|
|||
gem 'email_validator'
|
||||
#gem "browserify-rails", "~> 0.7"
|
||||
|
||||
|
||||
if ENV['FASTER_PATH'] == '1'
|
||||
# https://github.com/danielpclark/faster_path
|
||||
# supposed to dramatically speed up page load time. Gotta install rust. go to github if interested
|
||||
gem 'faster_path', '~> 0.1.0', :group => :development
|
||||
end
|
||||
|
||||
source 'https://rails-assets.org' do
|
||||
gem 'rails-assets-reflux', '0.3.0'
|
||||
gem 'rails-assets-classnames'
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@
|
|||
PREVIEW_PLAYED: 'preview_played',
|
||||
VST_OPERATION_SELECTED: 'vst_operation_selected',
|
||||
VST_EFFECT_SELECTED: 'vst_effect_selected',
|
||||
LESSON_SESSION_ACTION: 'lesson_session_action'
|
||||
LESSON_SESSION_ACTION: 'lesson_session_action',
|
||||
JAMBLASTER_ACTION: 'jamblaster_action'
|
||||
};
|
||||
|
||||
context.JK.PLAYBACK_MONITOR_MODE = {
|
||||
|
|
|
|||
|
|
@ -595,6 +595,19 @@
|
|||
return detail;
|
||||
}
|
||||
|
||||
function getUserJamBlasters(options) {
|
||||
if(!options) {
|
||||
options = {}
|
||||
}
|
||||
var id = getId(options);
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/api/users/" + id + '/jamblasters?' + $.param(options),
|
||||
processData: false
|
||||
});
|
||||
}
|
||||
|
||||
function getUserProfile(options) {
|
||||
if (!options) {
|
||||
options = {}
|
||||
|
|
@ -2550,6 +2563,7 @@
|
|||
this.cancelSession = cancelSession;
|
||||
this.updateScheduledSession = updateScheduledSession;
|
||||
this.getUserDetail = getUserDetail;
|
||||
this.getUserJamBlasters = getUserJamBlasters;
|
||||
this.getUserAuthorizations = getUserAuthorizations;
|
||||
this.getGoogleAuth = getGoogleAuth;
|
||||
this.getUserProfile = getUserProfile;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
(function(context, $) {
|
||||
|
||||
"use strict";
|
||||
|
||||
context.JK = context.JK || {};
|
||||
|
||||
|
||||
// creates an iconic/graphical instrument selector. useful when there is minimal real-estate
|
||||
|
||||
$.fn.jamblasterOptions = function(options) {
|
||||
|
||||
return this.each(function(index) {
|
||||
|
||||
function close() {
|
||||
$parent.btOff();
|
||||
$parent.focus();
|
||||
}
|
||||
|
||||
var $parent = $(this);
|
||||
if($parent.data('jamblasterOptions')) {
|
||||
//return;
|
||||
}
|
||||
|
||||
$parent.data('jamblasterOptions', options)
|
||||
function onJamBlasterOptionSelected() {
|
||||
var $li = $(this);
|
||||
var option = $li.attr('data-jamblaster-option');
|
||||
|
||||
close();
|
||||
$parent.triggerHandler(context.JK.EVENTS.JAMBLASTER_ACTION, {option: option, options: $parent.data('jamblasterOptions')});
|
||||
return false;
|
||||
};
|
||||
|
||||
// if the user goes into the bubble, remove
|
||||
function waitForBubbleHover($bubble) {
|
||||
$bubble.hoverIntent({
|
||||
over: function() {
|
||||
if(timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
},
|
||||
out: function() {
|
||||
$parent.btOff();
|
||||
}});
|
||||
}
|
||||
|
||||
var timeout = null;
|
||||
|
||||
var html = context._.template($('#template-jamblaster-options').html(), options, { variable: 'data' })
|
||||
|
||||
context.JK.hoverBubble($parent, html, {
|
||||
trigger:'none',
|
||||
cssClass: 'jamblaster-options-popup',
|
||||
spikeGirth:0,
|
||||
spikeLength:0,
|
||||
overlap: -10,
|
||||
width:120,
|
||||
closeWhenOthersOpen: true,
|
||||
offsetParent: $parent.closest('.screen'),
|
||||
positions:['bottom'],
|
||||
preShow: function() {
|
||||
|
||||
},
|
||||
postShow:function(container) {
|
||||
$(container).find('li').click(onJamBlasterOptionSelected)
|
||||
if(timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
waitForBubbleHover($(container))
|
||||
timeout = setTimeout(function() {$parent.btOff()}, 6000)
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
})(window, jQuery);
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
return this.each(function(index) {
|
||||
|
||||
function close() {
|
||||
//$parent.btOff();
|
||||
$parent.btOff();
|
||||
$parent.focus();
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
}
|
||||
},
|
||||
out: function() {
|
||||
//$parent.btOff();
|
||||
$parent.btOff();
|
||||
}});
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
timeout = null;
|
||||
}
|
||||
waitForBubbleHover($(container))
|
||||
//timeout = setTimeout(function() {$parent.btOff()}, 6000)
|
||||
timeout = setTimeout(function() {$parent.btOff()}, 6000)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
//= require jquery.exists
|
||||
//= require jquery.manageVsts
|
||||
//= require jquery.lessonSessionActions
|
||||
//= require jquery.jamblasterOptions
|
||||
//= require ResizeSensor
|
||||
//= require AAA_Log
|
||||
//= require AAC_underscore
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ logger = context.JK.logger
|
|||
for object in this.props.sourceObjects
|
||||
nm = "check_#{object.id}"
|
||||
checked = @isChecked(object.id)
|
||||
object_options.push `<div className='checkItem'><input type='checkbox' key={object.id} name={nm} data-object-id={object.id} checked={checked}></input><label htmlFor={nm}>{object.description}</label><br className="clearall"/></div>`
|
||||
object_options.push `<div key={object.id} className='checkItem'><input type='checkbox' key={object.id} name={nm} data-object-id={object.id} checked={checked}></input><label htmlFor={nm}>{object.description}</label><br className="clearall"/></div>`
|
||||
|
||||
`<div className="CheckBoxList react-component">
|
||||
<div className="checkbox-scroller left">
|
||||
|
|
|
|||
|
|
@ -41,11 +41,11 @@ MIDI_TRACK = context.JK.MIDI_TRACK
|
|||
for midiDevice in @state.configureTracks.attachedMidiDevices.midiDevices
|
||||
if midiDevice.deviceIndex == inputsForTrack.vst?.midiDeviceIndex
|
||||
midiDeviceName = midiDevice.deviceName
|
||||
inputs.push(`<div className="live-input">{midiDeviceName}</div>`)
|
||||
inputs.push(`<div key={i} className="live-input">{midiDeviceName}</div>`)
|
||||
else
|
||||
trackTypeLabel = 'AUDIO'
|
||||
for input in inputsForTrack
|
||||
inputs.push(`<div className="live-input">{input.name}</div>`)
|
||||
inputs.push(`<div key={i} className="live-input">{input.name}</div>`)
|
||||
|
||||
if !inputsForTrack.instrument_id?
|
||||
instrument = `<span className="none">?</span>`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
context = window
|
||||
@JamBlasterNameDialog = React.createClass({
|
||||
|
||||
mixins: [Reflux.listenTo(@AppStore, "onAppInit")]
|
||||
teacher: null
|
||||
|
||||
beforeShow: (args) ->
|
||||
logger.debug("JamBlasterNameDialog.beforeShow", args.d1)
|
||||
@setState({name: args.d1})
|
||||
|
||||
|
||||
afterHide: () ->
|
||||
|
||||
onAppInit: (@app) ->
|
||||
dialogBindings = {
|
||||
'beforeShow': @beforeShow,
|
||||
'afterHide': @afterHide
|
||||
};
|
||||
|
||||
@app.bindDialog('jamblaster-name-dialog', dialogBindings);
|
||||
|
||||
getInitialState: () ->
|
||||
{
|
||||
name: ''
|
||||
}
|
||||
|
||||
|
||||
componentDidMount: () ->
|
||||
@root = $(@getDOMNode())
|
||||
@dialog = @root.closest('.dialog')
|
||||
|
||||
doCancel: (e) ->
|
||||
e.preventDefault()
|
||||
@app.layout.closeDialog('jamblaster-name-dialog', true);
|
||||
|
||||
onNameChange: (e) ->
|
||||
|
||||
@setState({name: $(e.target).val()})
|
||||
|
||||
updateName: (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
# validate
|
||||
|
||||
name = @root.find('.name').val()
|
||||
|
||||
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
|
||||
|
||||
result = context.jamClient.setJBName(name.trim())
|
||||
|
||||
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.')
|
||||
else
|
||||
@app.layout.closeDialog('jamblaster-name-dialog')
|
||||
render: () ->
|
||||
`<div>
|
||||
<div className="content-head">
|
||||
<img className="content-icon" src="/assets/content/icon_add.png" height={19} width={19}/>
|
||||
|
||||
<h1>update name of JamBlaster</h1>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<p>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>
|
||||
|
||||
<label>JamBlaster Name:</label>
|
||||
<input className="name" type="text" value={this.state.name} onChange={this.onNameChange}></input>
|
||||
|
||||
<div className="actions">
|
||||
<a onClick={this.doCancel} className="button-grey">CANCEL</a>
|
||||
<a onClick={this.updateName} className="button-orange name">UPDATE</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
})
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
context = window
|
||||
@JamBlasterPairingDialog = React.createClass({
|
||||
|
||||
mixins: [@BonjourMixin, Reflux.listenTo(@AppStore, "onAppInit")]
|
||||
teacher: null
|
||||
|
||||
beforeShow: (args) ->
|
||||
logger.debug("JamBlasterPairingDialog.beforeShow", args.d1)
|
||||
@setState({timer: null, pairing: false, bonjourClientId: args.d1, pairingTimeout: false, paired: false})
|
||||
@resyncBonjour()
|
||||
@setTimer(false)
|
||||
|
||||
afterHide: () ->
|
||||
@clearTimer()
|
||||
|
||||
onAppInit: (@app) ->
|
||||
dialogBindings = {
|
||||
'beforeShow': @beforeShow,
|
||||
'afterHide': @afterHide
|
||||
};
|
||||
|
||||
@app.bindDialog('jamblaster-pairing-dialog', dialogBindings);
|
||||
|
||||
getInitialState: () ->
|
||||
{
|
||||
timer: null
|
||||
pairing: false,
|
||||
pairStart: null,
|
||||
clients: [],
|
||||
pairingTimeout: false
|
||||
paired: false,
|
||||
userJamBlasters: [],
|
||||
localClients: []
|
||||
}
|
||||
|
||||
clearTimer: () ->
|
||||
if @interval?
|
||||
clearInterval(@interval)
|
||||
@interval = null
|
||||
|
||||
clearPairingTimer: () ->
|
||||
if @pairingInterval?
|
||||
clearInterval(@pairingInterval)
|
||||
@pairingInterval = null
|
||||
|
||||
setTimer: (connecting) ->
|
||||
@clearTimer()
|
||||
|
||||
if connecting
|
||||
time = 5000 # every 5 seconds
|
||||
else
|
||||
time = 60000 # every minute
|
||||
|
||||
@interval = setInterval((() => @resyncBonjour()), time)
|
||||
|
||||
pairingTimer: () ->
|
||||
@clearPairingTimer()
|
||||
|
||||
@pairingInterval = setInterval((() => @updatePairingTimer()), 800)
|
||||
|
||||
updatePairingTimer: () ->
|
||||
|
||||
now = new Date().getTime()
|
||||
|
||||
delta = (now - @state.pairStart) / 1000
|
||||
|
||||
if delta > 60
|
||||
@clearPairingTimer()
|
||||
@setTimer(false)
|
||||
@setState({pairing: false, pairingTimeout: true, timer: null})
|
||||
else
|
||||
client = @findJamBlaster(@state.bonjourClientId)
|
||||
if client.isPaired
|
||||
@clearPairingTimer()
|
||||
@setTimer(false)
|
||||
@setState({pairing: false, pairingTimeout: false, timer: null, paired: true})
|
||||
else
|
||||
@setState({timer: 60 - delta})
|
||||
|
||||
componentDidMount: () ->
|
||||
@root = $(@getDOMNode())
|
||||
@dialog = @root.closest('.dialog')
|
||||
|
||||
componentDidUpdate: () ->
|
||||
|
||||
doCancel: (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
if @state.pairing
|
||||
return
|
||||
|
||||
@app.layout.closeDialog('jamblaster-pairing-dialog', true);
|
||||
|
||||
close: (e) ->
|
||||
e.preventDefault()
|
||||
@app.layout.closeDialog('jamblaster-pairing-dialog')
|
||||
|
||||
pair: (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
if @state.pairing
|
||||
return
|
||||
|
||||
@setState({pairing: true, pairStart: new Date().getTime(), timer: 60})
|
||||
@setTimer(true)
|
||||
|
||||
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?
|
||||
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")
|
||||
else
|
||||
context.JK.Banner.showAlert("JamBlaster offline", "JamBlaster appears to be offline. Please reboot it")
|
||||
|
||||
render: () ->
|
||||
|
||||
if @state.pairing
|
||||
countdown = @state.timer
|
||||
else
|
||||
countdown = null
|
||||
|
||||
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>
|
||||
</div>`
|
||||
|
||||
|
||||
if @state.paired
|
||||
message = `<p>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>`
|
||||
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>
|
||||
|
||||
<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}
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
})
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
context = window
|
||||
rest = context.JK.Rest()
|
||||
logger = context.JK.logger
|
||||
|
||||
@JamBlasterScreen = React.createClass({
|
||||
|
||||
mixins: [
|
||||
@ICheckMixin,
|
||||
@PostProcessorMixin,
|
||||
@BonjourMixin,
|
||||
Reflux.listenTo(AppStore, "onAppInit"),
|
||||
Reflux.listenTo(UserStore, "onUserChanged")
|
||||
]
|
||||
|
||||
TILE_AUDIO: 'audio'
|
||||
TILE_INTERNET: 'internet'
|
||||
TILE_MANAGEMENT: 'management'
|
||||
TILE_USB: 'usb'
|
||||
|
||||
TILES: ['audio', 'internet', 'management', 'usb']
|
||||
|
||||
onAppInit: (@app) ->
|
||||
@app.bindScreen('jamblaster',
|
||||
{beforeShow: @beforeShow, afterShow: @afterShow, beforeHide: @beforeHide})
|
||||
|
||||
onUserChanged: (userState) ->
|
||||
@setState({user: userState?.user})
|
||||
|
||||
componentDidMount: () ->
|
||||
@root = $(@getDOMNode())
|
||||
|
||||
componentWillUpdate: (nextProps, nextState) ->
|
||||
|
||||
componentDidUpdate: () ->
|
||||
items = @root.find('.jamtable .optionsColumn .jamblaster-options-btn')
|
||||
|
||||
$.each(items, (i, node) => (
|
||||
$node = $(node)
|
||||
|
||||
jamblaster = @findJamBlaster($node.attr('data-jamblaster-id'))
|
||||
|
||||
$node.jamblasterOptions(jamblaster).off(context.JK.EVENTS.JAMBLASTER_ACTION).on(context.JK.EVENTS.JAMBLASTER_ACTION,
|
||||
@jamblasterOptionSelected)
|
||||
))
|
||||
#context.JK.popExternalLinks(@root)
|
||||
|
||||
jamblasterOptionSelected: (e, data) ->
|
||||
jamblasterId = data.options.id
|
||||
jamblaster = @findJamBlaster(jamblasterId)
|
||||
|
||||
if data.option == 'auto-connect'
|
||||
context.JK.Banner.showNotice('Auto-Connect',
|
||||
'Auto-Connect is always on by default. It can not currently configurable.')
|
||||
else if data.option == 'restart'
|
||||
context.JK.Banner.showNotice('Restart',
|
||||
'To restart the JamBlaster, you must manually cycle power (unplug, then plug).')
|
||||
else if data.option == 'name'
|
||||
context.layout.showDialog('jamblaster-name-dialog').one(context.JK.EVENTS.DIALOG_CLOSED, (e, data) =>
|
||||
@resyncBonjour()
|
||||
)
|
||||
|
||||
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')
|
||||
else if data.option == 'set-static-ports'
|
||||
context.layout.showDialog('jamblaster-port-dialog')
|
||||
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',
|
||||
user: null,
|
||||
userJamBlasters: [],
|
||||
localClients: [],
|
||||
clients: []
|
||||
}
|
||||
|
||||
beforeHide: (e) ->
|
||||
|
||||
|
||||
beforeShow: (e) ->
|
||||
|
||||
afterShow: (e) ->
|
||||
@resyncBonjour()
|
||||
|
||||
openMenu: (client, e) ->
|
||||
logger.debug("open jamblaster options menu")
|
||||
$this = $(e.target)
|
||||
if !$this.is('.jamblaster-options-btn')
|
||||
$this = $this.closest('.jamblaster-options-btn')
|
||||
$this.btOn()
|
||||
|
||||
connect: (client, e) ->
|
||||
logger.debug("beginning pairing to #{client.connect_url}")
|
||||
|
||||
context.jamClient.startPairing(client.connect_url)
|
||||
|
||||
disconnect: (client, e) ->
|
||||
logger.debug("disconnecting from currently paired client #{client.connect_url}")
|
||||
context.jamClient.endPairing()
|
||||
mergeClients: () ->
|
||||
|
||||
clientsJsx = []
|
||||
for client in @state.clients
|
||||
if client.display_name?
|
||||
displayName = client.display_name
|
||||
else
|
||||
displayName = client.name
|
||||
|
||||
if client.serial_no? && displayName? && displayName.indexOf(client.serial_no) == -1
|
||||
displayName = "#{displayName} (#{client.serial_no})"
|
||||
name = `<span className="displayNameColumn">{displayName}</span>`
|
||||
|
||||
if client.isPaired
|
||||
connect = `<span className="connectColumn"><a
|
||||
onClick={this.disconnect.bind(this, client)}>disconnect</a></span>`
|
||||
else if client.has_local
|
||||
connect = `<span className="connectColumn"><a onClick={this.connect.bind(this, client)}>connect</a></span>`
|
||||
else
|
||||
connect = `<span className="connectColumn">offline</span>`
|
||||
|
||||
options = `<span className="optionsColumn"><a data-jamblaster-id={client.id} className="jamblaster-options-btn"
|
||||
onClick={this.openMenu.bind(this, client)}>more options
|
||||
<div className="details-arrow arrow-down"/>
|
||||
</a></span>`
|
||||
|
||||
clientsJsx.push(`<tr>
|
||||
<td>{name}{options}{connect}</td>
|
||||
</tr>`)
|
||||
|
||||
clientsJsx
|
||||
|
||||
mainContent: () ->
|
||||
if @state.selected == @TILE_AUDIO
|
||||
@audio()
|
||||
else if @state.selected == @TILE_INTERNET
|
||||
@internet()
|
||||
else if @state.selected == @TILE_MANAGEMENT
|
||||
@management()
|
||||
else if @state.selected == @TILE_USB
|
||||
@usb()
|
||||
|
||||
management: () ->
|
||||
clients = @mergeClients()
|
||||
`<div className="management-content">
|
||||
<table className="jamtable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="jamblasterColumn">JAMBLASTERS ON YOUR NETWORK</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{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.
|
||||
</p>
|
||||
</div>`
|
||||
|
||||
render: () ->
|
||||
disabled = @state.updating
|
||||
|
||||
if !@state.user?.id || !@state.userJamBlasters? || !@state.localClients?
|
||||
return `<div>Loading</div>`
|
||||
|
||||
|
||||
`<div className="content-body-scroller">
|
||||
<div className="">
|
||||
<h2>jamblaster settings</h2>
|
||||
|
||||
<div className="tiles">
|
||||
</div>
|
||||
|
||||
<div className="jamclass-section">
|
||||
{this.mainContent()}
|
||||
</div>
|
||||
</div>
|
||||
<br className="clearall"/>
|
||||
</div>`
|
||||
})
|
||||
|
|
@ -204,8 +204,8 @@
|
|||
</span>
|
||||
<span className="alt-time-block">
|
||||
<span className="alt-time">Time:</span>
|
||||
<select className="hour">{this.hours}</select> : <select disabled={this.props.disabled} className="minute">{this.minutes}</select>
|
||||
<select disabled={this.props.disabled} className="am_pm">{this.am_pm}</select>
|
||||
<select className="hour" defaultValue="06" disabled={this.props.disabled}>{this.hours}</select> : <select disabled={this.props.disabled} className="minute">{this.minutes}</select>
|
||||
<select disabled={this.props.disabled} className="am_pm" defaultValue="PM">{this.am_pm}</select>
|
||||
<br/>
|
||||
<span>* Time will be local to {window.JK.currentTimezone()}</span>
|
||||
{errorText}
|
||||
|
|
@ -227,8 +227,8 @@
|
|||
</span>
|
||||
<span className="alt-time-block">
|
||||
<span className="alt-time">Time:</span>
|
||||
<select className="hour">{this.hours}</select> : <select disabled={this.props.disabled} className="minute">{this.minutes}</select>
|
||||
<select disabled={this.props.disabled} className="am_pm">{this.am_pm}</select>
|
||||
<select className="hour" defaultValue="06" disabled={this.props.disabled}>{this.hours}</select> : <select disabled={this.props.disabled} className="minute">{this.minutes}</select>
|
||||
<select disabled={this.props.disabled} className="am_pm" defaultValue="PM">{this.am_pm}</select>
|
||||
<br/>
|
||||
<span>*Time will be local to {window.JK.currentTimezone()}</span>
|
||||
{errorText}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
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) ->
|
||||
found = null
|
||||
if @clients?
|
||||
for client in @clients
|
||||
if client.id == id
|
||||
found = client
|
||||
break
|
||||
if client.ipv6_addr == id
|
||||
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})
|
||||
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
//= require jquery.exists
|
||||
//= require jquery.visible
|
||||
//= require jquery.lessonSessionActions
|
||||
//= require jquery.jamblasterOptions
|
||||
//= require jquery.manageVsts
|
||||
//= require jquery.scrollTo
|
||||
//= require jquery.pulse
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
*= require ./muteSelect
|
||||
*= require ./manageVsts
|
||||
*= require ./lessonSessionActions
|
||||
*= require ./jamblasterOptions
|
||||
*= require ./vstEffects
|
||||
*= require ./metronomePlaybackModeSelect
|
||||
*= require ./terms
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
@import "client/common";
|
||||
|
||||
.jamblaster-options-popup {
|
||||
|
||||
width:120px;
|
||||
height:100px;
|
||||
a{
|
||||
color:#fc0 !important;
|
||||
}
|
||||
li {
|
||||
border-bottom:0 !important;
|
||||
}
|
||||
|
||||
.bt-content {
|
||||
height:80px;
|
||||
width:100px;
|
||||
background-color:#333;
|
||||
overflow:auto;
|
||||
border:1px solid #ED3618;
|
||||
text-align:left;
|
||||
font-family: 'Raleway', Arial, Helvetica, sans-serif;
|
||||
ul {
|
||||
@include vertical-align-column;
|
||||
height:100%;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
li {
|
||||
font-size:12px;
|
||||
margin-left:0 !important;
|
||||
list-style-type: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
@import "client/common";
|
||||
|
||||
#jamblaster-screen {
|
||||
|
||||
div[data-react-class="JamBlasterScreen"] {
|
||||
height:100%;
|
||||
}
|
||||
.content-body-scroller {
|
||||
height:100%;
|
||||
padding:30px;
|
||||
@include border_box_sizing;
|
||||
}
|
||||
|
||||
ol {
|
||||
li {
|
||||
margin-left:15px;
|
||||
margin-bottom:2px;
|
||||
list-style:decimal;
|
||||
color:$ColorTextTypical;
|
||||
}
|
||||
}
|
||||
|
||||
.student-right-content {
|
||||
p {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
ul {
|
||||
margin-bottom:25px;
|
||||
li {
|
||||
margin-left:-10px;
|
||||
margin-bottom:2px;
|
||||
list-style:disc;
|
||||
color:$ColorTextTypical;
|
||||
}
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
font-weight:700;
|
||||
margin-bottom: 20px !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;
|
||||
}
|
||||
.test-drive-main {
|
||||
}
|
||||
p {
|
||||
line-height:125% !important;
|
||||
font-size:14px !important;
|
||||
margin:0 0 20px 0 !important;
|
||||
color: $ColorTextTypical;
|
||||
}
|
||||
.avatar {
|
||||
display:inline-block;
|
||||
padding:1px;
|
||||
width:36px;
|
||||
height:36px;
|
||||
background-color:#ed4818;
|
||||
margin:0 10px 0 0;
|
||||
-webkit-border-radius:18px;
|
||||
-moz-border-radius:18px;
|
||||
border-radius:18px;
|
||||
float:none;
|
||||
}
|
||||
.avatar img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
-webkit-border-radius:18px;
|
||||
-moz-border-radius:18px;
|
||||
border-radius:18px;
|
||||
}
|
||||
|
||||
.calender-integration-notice {
|
||||
display:block;
|
||||
text-align:center;
|
||||
}
|
||||
.actions {
|
||||
display:block;
|
||||
text-align:center;
|
||||
}
|
||||
.jamclass-section {
|
||||
margin-bottom:40px;
|
||||
&.my-lessons {
|
||||
max-height:300px;
|
||||
overflow:auto;
|
||||
}
|
||||
}
|
||||
.management-content {
|
||||
min-width:400px;
|
||||
max-width:700px;
|
||||
}
|
||||
.jamtable {
|
||||
|
||||
height:100%;
|
||||
width:100%;
|
||||
table-layout:fixed;
|
||||
margin-bottom:20px;
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
color:#fc0 !important;
|
||||
}
|
||||
th {
|
||||
font-size:14px;
|
||||
padding:3px 10px;
|
||||
@include border_box_sizing;
|
||||
&.role {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
td {
|
||||
background-color: #2b2b2b;
|
||||
padding:4px 15px;
|
||||
font-size:14px;
|
||||
vertical-align:middle;
|
||||
color: $ColorTextTypical;
|
||||
@include border_box_sizing;
|
||||
}
|
||||
tbody {
|
||||
|
||||
}
|
||||
|
||||
.displayNameColumn {
|
||||
float:left;
|
||||
}
|
||||
|
||||
.connectColumn {
|
||||
float:right;
|
||||
margin-right:20px;
|
||||
}
|
||||
|
||||
.optionsColumn{
|
||||
float:right;
|
||||
text-align:center;
|
||||
}
|
||||
.jamblaster-options-btn {
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
vertical-align: bottom;
|
||||
color:#fc0;
|
||||
|
||||
.arrow-down {
|
||||
float:none;
|
||||
margin-left:5px;
|
||||
margin-top:0;
|
||||
margin-right:0;
|
||||
border-top: 4px solid #fc0;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
display:inline-block;
|
||||
}
|
||||
.arrow-up {
|
||||
float:none;
|
||||
margin-right:0;
|
||||
margin-left:5px;
|
||||
margin-bottom:2px;
|
||||
border-bottom: 4px solid #fc0;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
display:inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
@import "client/common";
|
||||
|
||||
#jamblaster-name-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:0 -13px 30px 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
@import "client/common";
|
||||
|
||||
#jamblaster-pairing-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:0 -13px 30px 0;
|
||||
}
|
||||
.countdown {
|
||||
color:white;
|
||||
font-size:18px;
|
||||
font-weight:bold;
|
||||
padding:0 10px;
|
||||
width:30px;
|
||||
display:inline-block;
|
||||
}
|
||||
}
|
||||
|
|
@ -46,6 +46,13 @@ class ApiUsersController < ApiController
|
|||
respond_with @user, responder: ApiResponder, :status => 200
|
||||
end
|
||||
|
||||
def jamblasters
|
||||
@user = current_user
|
||||
@connection = Connection.find_by_client_id(params[:client_id])
|
||||
|
||||
respond_with @user, responder: ApiResponder, :status => 200
|
||||
end
|
||||
|
||||
def google_auth
|
||||
@user = current_user
|
||||
respond_with @user, responder: ApiResponder, :status => 200
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
object @user
|
||||
|
||||
child :jamblasters do
|
||||
attributes :id, :user_id, :serial_no, :client_id, :ipv6_link_local, :ipv4_link_local, :display_name
|
||||
end
|
||||
|
||||
node :same_network_jamblasters do
|
||||
if @connection
|
||||
jamblasters = @connection.same_network_jamblasters
|
||||
result = []
|
||||
jamblasters.each do |jamblaster|
|
||||
result.push ({id: jamblaster.id, user_id: jamblaster.user_id, serial_no: jamblaster.serial_no, client_id: jamblaster.client_id, ipv4_link_local: jamblaster.ipv4_link_local, ipv6_link_local: jamblaster.ipv6_link_local, display_name: jamblaster.display_name})
|
||||
end
|
||||
result
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
script type='text/template' id='template-jamblaster-options'
|
||||
|
||||
ul
|
||||
li data-jamblaster-option="auto-connect"
|
||||
a href='#' Auto Connect
|
||||
|
||||
li data-jamblaster-option="restart"
|
||||
a href='#' Restart
|
||||
|
||||
li data-jamblaster-option="name"
|
||||
a href='#' Name
|
||||
|
||||
li data-jamblaster-option="check-for-updates"
|
||||
a href='#' Check for Updates
|
||||
|
||||
li data-jamblaster-option="set-static-ports"
|
||||
a href='#' Set Static Ports
|
||||
|
||||
li data-jamblaster-option="factory-reset"
|
||||
a href='#' Factory Reset
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
<%= render "muteSelect" %>
|
||||
<%= render "manageVsts" %>
|
||||
<%= render "lessonSessionActions" %>
|
||||
<%= render "jamblasterOptions" %>
|
||||
<%= render "vstEffects" %>
|
||||
<%= render "metronome_playback_mode" %>
|
||||
<%= render "clients/wizard/buttons" %>
|
||||
|
|
@ -38,6 +39,7 @@
|
|||
<%= render "bandProfile" %>
|
||||
<%= render "band_setup" %>
|
||||
<%= render "band_setup_photo" %>
|
||||
<%= render "clients/jamclass/jamblaster" %>
|
||||
<%= render "clients/teachers/setup/introduction" %>
|
||||
<%= render "clients/teachers/setup/basics" %>
|
||||
<%= render "clients/teachers/setup/experience" %>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
#jamblaster-screen.screen.secondary layout="screen" layout-id="jamblaster"
|
||||
.content-head
|
||||
.content-icon
|
||||
= image_tag "content/icon_jamtracks.png", :size => "24x24"
|
||||
h1
|
||||
| jamblaster
|
||||
= render "screen_navigation"
|
||||
.content-body
|
||||
= react_component 'JamBlasterScreen', {}
|
||||
|
||||
|
|
@ -55,4 +55,6 @@
|
|||
= render 'dialogs/rescheduleLessonDialog'
|
||||
= render 'dialogs/rateUserDialog'
|
||||
= render 'dialogs/musicNotationUploadDialog'
|
||||
= render 'dialogs/testDrivePackageDialog'
|
||||
= render 'dialogs/testDrivePackageDialog'
|
||||
= render 'dialogs/jamblasterNameDialog'
|
||||
= render 'dialogs/jamblasterPairingDialog'
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
.dialog.dialog-overlay-sm.top-parent layout='dialog' layout-id='jamblaster-name-dialog' id='jamblaster-name-dialog'
|
||||
= react_component 'JamBlasterNameDialog', {}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
.dialog.dialog-overlay-sm.top-parent layout='dialog' layout-id='jamblaster-pairing-dialog' id='jamblaster-pairing-dialog'
|
||||
= react_component 'JamBlasterPairingDialog', {}
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
</div>
|
||||
|
||||
<%= render "clients/lessonSessionActions" %>
|
||||
<%= render "clients/jamblasterOptions" %>
|
||||
<%= render "clients/manageVsts" %>
|
||||
<%= render 'dialogs/dialogs' %>
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@
|
|||
<%= render "clients/jam_track_preview" %>
|
||||
<%= render "clients/help" %>
|
||||
<%= render "clients/lessonSessionActions" %>
|
||||
<%= render "clients/jamblasterOptions" %>
|
||||
<%= render "clients/manageVsts" %>
|
||||
<%= render 'dialogs/dialogs' %>
|
||||
|
||||
|
|
|
|||
|
|
@ -119,10 +119,6 @@ if defined?(Bundler)
|
|||
config.websocket_gateway_port = 6767 + ENV['JAM_INSTANCE'].to_i
|
||||
config.websocket_gateway_port_ssl = 6443 + ENV['JAM_INSTANCE'].to_i
|
||||
# Runs the websocket gateway within the web app
|
||||
config.websocket_gateway_uri = "ws://localhost:#{config.websocket_gateway_port}/websocket"
|
||||
config.websocket_gateway_trusted_uri = "ws://localhost:#{config.websocket_gateway_port + 1}/websocket"
|
||||
config.websocket_gateway_uri_ssl = "wss://localhost:#{config.websocket_gateway_port_ssl}/websocket"
|
||||
config.websocket_gateway_trusted_uri_ssl = "wss://localhost:#{config.websocket_gateway_port_ssl + 1}/websocket"
|
||||
config.force_ssl = ENV['FORCE_SSL'].nil? ? false : ENV['FORCE_SSL'] == 'true'
|
||||
config.websocket_gateway_max_connections_per_user = 20
|
||||
config.lock_connections = false
|
||||
|
|
@ -137,6 +133,12 @@ if defined?(Bundler)
|
|||
# set this to false if you want to disable signups (lock down public user creation)
|
||||
config.signup_enabled = true
|
||||
|
||||
config.websocket_gateway_uri = "ws://#{config.external_hostname}:#{config.websocket_gateway_port}/websocket"
|
||||
config.websocket_gateway_trusted_uri = "ws://#{config.external_hostname}:#{config.websocket_gateway_port + 1}/websocket"
|
||||
config.websocket_gateway_uri_ssl = "wss://#{config.external_hostname}:#{config.websocket_gateway_port_ssl}/websocket"
|
||||
config.websocket_gateway_trusted_uri_ssl = "wss://#{config.external_hostname}:#{config.websocket_gateway_port_ssl + 1}/websocket"
|
||||
|
||||
|
||||
config.storage_type = :fog
|
||||
# config.storage_type = :file # or :fog, if using AWS
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
if defined? FasterPath
|
||||
puts "OMG"
|
||||
require "faster_path/optional/monkeypatches"
|
||||
FasterPath.sledgehammer_everything!
|
||||
end
|
||||
|
||||
|
||||
# Load the rails application
|
||||
require File.expand_path('../application', __FILE__)
|
||||
|
||||
|
|
|
|||
|
|
@ -325,6 +325,7 @@ SampleApp::Application.routes.draw do
|
|||
match '/users' => 'api_users#create', :via => :post
|
||||
match '/users/:id' => 'api_users#show', :via => :get, :as => 'api_user_detail'
|
||||
match '/users/:id/authorizations' => 'api_users#authorizations', :via => :get
|
||||
match '/users/:id/jamblasters' => 'api_users#jamblasters', :via => :get
|
||||
#match '/users' => 'api_users#create', :via => :post
|
||||
match '/users/:id' => 'api_users#update', :via => :post
|
||||
match '/users/:id' => 'api_users#delete', :via => :delete
|
||||
|
|
|
|||
|
|
@ -18,6 +18,18 @@ namespace :jam_tracks do
|
|||
end
|
||||
|
||||
task dry_run: :environment do |task, args|
|
||||
if ENV['STORAGE']
|
||||
JamTrackImporter.storage_format = ENV['STORAGE']
|
||||
end
|
||||
JamTrackImporter.dry_run
|
||||
end
|
||||
|
||||
# valid values for STORAGE
|
||||
# Helbing
|
||||
task dry_run: :environment do |task, args|
|
||||
if ENV['STORAGE']
|
||||
JamTrackImporter.storage_format = ENV['STORAGE']
|
||||
end
|
||||
JamTrackImporter.dry_run
|
||||
end
|
||||
|
||||
|
|
@ -192,6 +204,11 @@ namespace :jam_tracks do
|
|||
JamTrackImporter.synchronize_all(skip_audio_upload: false)
|
||||
end
|
||||
|
||||
task sync_helbing: :environment do |task, args|
|
||||
JamTrackImporter.storage_format = 'Helbing'
|
||||
JamTrackImporter.synchronize_all(skip_audio_upload: false)
|
||||
end
|
||||
|
||||
task tency_dups: :environment do |task, args|
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -737,6 +737,8 @@ module JamWebsockets
|
|||
os = options["os"]
|
||||
udp_reachable = options["udp_reachable"].nil? ? true : options["udp_reachable"] == 'true'
|
||||
jamblaster_serial_no = options["jamblaster_serial_no"]
|
||||
ipv4_link_local = options["ipv4_link_local"]
|
||||
ipv6_link_local = options["ipv6_link_local"]
|
||||
|
||||
# TESTING
|
||||
#if jamblaster_serial_no.nil?
|
||||
|
|
@ -745,8 +747,8 @@ module JamWebsockets
|
|||
|
||||
client.subscriptions = Set.new # list of subscriptions that this client is watching in real-time
|
||||
|
||||
@log.info("handle_login: client_type=#{client_type} token=#{token} client_id=#{client_id} channel_id=#{client.channel_id} udp_reachable=#{udp_reachable}")
|
||||
|
||||
serial_no_debug = jamblaster_serial_no ? "serial_no=#{jamblaster_serial_no}" : ''
|
||||
@log.info("handle_login: type=#{client_type} username=#{username} password=#{password ? '*' : 'null' } token=#{token} client_id=#{client_id} channel_id=#{client.channel_id} udp_reachable=#{udp_reachable} #{serial_no_debug}")
|
||||
if client_type == Connection::TYPE_LATENCY_TESTER
|
||||
handle_latency_tester_login(client_id, client_type, client, override_ip)
|
||||
return
|
||||
|
|
@ -775,6 +777,8 @@ module JamWebsockets
|
|||
end
|
||||
if jamblaster && connecting
|
||||
jamblaster.client_id = client_id
|
||||
jamblaster.ipv4_link_local = ipv4_link_local
|
||||
jamblaster.ipv6_link_local = ipv6_link_local
|
||||
jamblaster.save
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue