* wip
This commit is contained in:
parent
c28d8f3e7f
commit
a769dd37bf
|
|
@ -94,6 +94,7 @@ gem 'react-rails', '~> 1.0'
|
|||
|
||||
source 'https://rails-assets.org' do
|
||||
gem 'rails-assets-reflux'
|
||||
gem 'rails-assets-classnames'
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
//= require jquery.exists
|
||||
//= require jquery.payment
|
||||
//= require jquery.visible
|
||||
//= require classnames
|
||||
//= require reflux
|
||||
//= require howler.core.js
|
||||
//= require jstz
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@
|
|||
|
||||
if (type === 2) { // BACKEND_MIXER_CHANGE
|
||||
|
||||
context.MixerActions.mixersChanged(type, text)
|
||||
context.SessionActions.mixersChanged(type, text)
|
||||
|
||||
if(context.JK.CurrentSessionModel)
|
||||
context.JK.CurrentSessionModel.onBackendMixerChanged(type, text)
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@
|
|||
}
|
||||
|
||||
function deleteParticipant(clientId) {
|
||||
var url = "/api/participants/" + lientId;
|
||||
var url = "/api/participants/" + clientId;
|
||||
return $.ajax({
|
||||
type: "DELETE",
|
||||
url: url
|
||||
|
|
|
|||
|
|
@ -2,8 +2,21 @@ context = window
|
|||
|
||||
@SessionLeaveBtn = React.createClass({
|
||||
|
||||
onLeave: (e) ->
|
||||
e.preventDefault()
|
||||
@rateSession()
|
||||
|
||||
SessionActions.leaveSession.trigger({location: '/client#/home'})
|
||||
|
||||
rateSession: () ->
|
||||
unless @rateSessionDialog?
|
||||
@rateSessionDialog = new context.JK.RateSessionDialog(context.JK.app);
|
||||
@rateSessionDialog.initialize();
|
||||
|
||||
@rateSessionDialog.showDialog();
|
||||
|
||||
render: () ->
|
||||
`<a className="session-leave button-grey right leave">
|
||||
`<a className="session-leave button-grey right leave" onClick={this.onLeave}>
|
||||
X LEAVE
|
||||
</a>`
|
||||
})
|
||||
|
|
@ -29,12 +29,17 @@ MixerActions = @MixerActions
|
|||
muteMixer = this.state.mixers.muteMixer
|
||||
vuMixer = this.state.mixers.vuMixer
|
||||
|
||||
classes = React.addons.classSet({
|
||||
classes = classNames({
|
||||
'track-icon-mute': true
|
||||
'enabled' : !muteMixer.mute
|
||||
'muted' : muteMixer.mute
|
||||
})
|
||||
|
||||
panStyle = {
|
||||
transform: "rotate(#{this.state.mixers.mixer.pan}deg)"
|
||||
WebkitTransform: "rotate(#{this.state.mixers.mixer.pan}deg)"
|
||||
}
|
||||
|
||||
`<div className="session-track my-track">
|
||||
<div className="name">{this.props.name}</div>
|
||||
<div className="track-avatar"><img src={this.props.photoUrl}/></div>
|
||||
|
|
@ -43,7 +48,7 @@ MixerActions = @MixerActions
|
|||
<SessionTrackVU orientation="horizontal" lightCount={4} lightWidth={17} lightHeight={3} side="vul" mixers={this.state.mixers} />
|
||||
<div className="track-buttons">
|
||||
<div className={classes} data-control="mute" data-mixer-id={muteMixer.id} onClick={this.handleMute}/>
|
||||
<div className="track-icon-pan"/>
|
||||
<div className="track-icon-pan" style={panStyle}/>
|
||||
<div className="track-icon-equalizer" />
|
||||
</div>
|
||||
<br className="clearall"/>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ SessionActions = @SessionActions
|
|||
|
||||
@SessionScreen = React.createClass({
|
||||
|
||||
mixins: [Reflux.listenTo(@AppStore,"onAppInit")]
|
||||
mixins: [Reflux.listenTo(@AppStore,"onAppInit"), Reflux.listenTo(@SessionActions.allowLeaveSession, "onAllowLeaveSession")]
|
||||
|
||||
render: () ->
|
||||
`<div className="session-container">
|
||||
|
|
@ -29,8 +29,9 @@ SessionActions = @SessionActions
|
|||
componentDidMount: () ->
|
||||
@logger = context.JK.logger
|
||||
|
||||
beforeShow: (data) =>
|
||||
beforeShow: (data) ->
|
||||
@logger.debug("session beforeShow")
|
||||
@allowLeave = false
|
||||
|
||||
afterShow: (data) ->
|
||||
@logger.debug("session afterShow")
|
||||
|
|
@ -38,14 +39,30 @@ SessionActions = @SessionActions
|
|||
SessionActions.joinSession.trigger(data.id)
|
||||
|
||||
beforeHide: () ->
|
||||
@logger.debug("session beforeHide")
|
||||
context.JK.HelpBubbleHelper.clearJamTrackGuide();
|
||||
|
||||
beforeLeave: () ->
|
||||
@logger.debug("session beforeLeave")
|
||||
beforeLeave: (data) ->
|
||||
@logger.debug("session beforeLeave", @allowLeave)
|
||||
|
||||
if @allowLeave
|
||||
return true
|
||||
else
|
||||
leaveSessionWarningDialog = new context.JK.LeaveSessionWarningDialog(context.JK.app,
|
||||
() =>
|
||||
@allowLeave = true
|
||||
context.location.hash = data.hash
|
||||
)
|
||||
|
||||
leaveSessionWarningDialog.initialize()
|
||||
@app.layout.showDialog('leave-session-warning')
|
||||
return false
|
||||
|
||||
beforeDisconnect: () ->
|
||||
@logger.debug("session beforeDisconnect")
|
||||
|
||||
onAllowLeaveSession: () ->
|
||||
@allowLeave = true
|
||||
|
||||
onAppInit: (@app) ->
|
||||
|
||||
screenBindings = {
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ context = window
|
|||
for i in [0..this.props.lightCount-1]
|
||||
lightClass = if i >= redSwitch then 'vu-red-off' else 'vu-green-off'
|
||||
|
||||
lightClasses = React.addons.classSet('vulight', 'vu' + i, lightClass)
|
||||
lightClasses = classNames('vulight', 'vu' + i, lightClass)
|
||||
|
||||
lights.push(`<td width={this.props.lightWidth} height={this.props.lightHeight} className={lightClasses}></td>`)
|
||||
lights.push(`<td key={i} width={this.props.lightWidth} height={this.props.lightHeight} className={lightClasses}></td>`)
|
||||
|
||||
tableClasses = React.addons.classSet('vu', 'horizontal', this.props.side + '-' + this.state.mixers.mixer.mixerId)
|
||||
tableClasses = classNames('vu', 'horizontal', this.props.side + '-' + this.state.mixers.mixer.mixerId)
|
||||
|
||||
`<table className={tableClasses} data-light-count={this.props.lightCount}>
|
||||
<tr>
|
||||
|
|
@ -32,11 +32,11 @@ context = window
|
|||
for i in [0..this.props.lightCount-1].reverse()
|
||||
lightClass = if (i >= redSwitch) then "vu-red-off" else "vu-green-off"
|
||||
|
||||
lightClasses = React.addons.classSet('vulight', 'vu' + i, lightClass)
|
||||
lightClasses = classNames('vulight', 'vu' + i, lightClass)
|
||||
|
||||
lights.push(`<tr><td width={this.props.lightWidth} height={this.props.lightHeight} className={lightClasses}></td></tr>`)
|
||||
lights.push(`<tr><td key={i} width={this.props.lightWidth} height={this.props.lightHeight} className={lightClasses}></td></tr>`)
|
||||
|
||||
tableClasses = React.addons.classSet('vu', 'vertical', this.props.side + '-' + this.state.mixers.mixer.mixerId)
|
||||
tableClasses = classNames('vu', 'vertical', this.props.side + '-' + this.state.mixers.mixer.mixerId)
|
||||
|
||||
`<table className={tableClasses} data-light-count={this.props.lightCount}>
|
||||
{lights}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ MixerActions = @MixerActions
|
|||
|
||||
muteMixer = this.state.mixers.muteMixer
|
||||
|
||||
classes = React.addons.classSet({
|
||||
classes = classNames({
|
||||
'track-icon-mute': true
|
||||
'enabled' : !muteMixer.mute
|
||||
'muted' : muteMixer.mute
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ context = window
|
|||
joinSession: {}
|
||||
leaveSession: {}
|
||||
resyncServer: {asyncResult: true}
|
||||
myTracksChanged: {}
|
||||
mixersChanged: {}
|
||||
})
|
||||
|
|
@ -17,15 +17,12 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
@muteBothMasterAndPersonalGroups = [ChannelGroupIds.AudioInputMusicGroup, ChannelGroupIds.MediaTrackGroup,
|
||||
ChannelGroupIds.JamTrackGroup, ChannelGroupIds.MetronomeGroup]
|
||||
|
||||
|
||||
@organize()
|
||||
|
||||
updateMixers: (type, text, @masterMixers, @personalMixers) ->
|
||||
|
||||
@organize()
|
||||
|
||||
if @session.inSession() && text == 'RebuildAudioIoControl'
|
||||
SessionActions.myTracksChanged.trigger()
|
||||
|
||||
|
||||
|
||||
|
|
@ -62,7 +59,7 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
localMediaMixers = @mixersForGroupIds(@mediaTrackGroups, MIX_MODES.MASTER)
|
||||
peerLocalMediaMixers = @mixersForGroupId(ChannelGroupIds.PeerMediaTrackGroup, MIX_MODES.MASTER)
|
||||
|
||||
logger.debug("localMediaMixers", localMediaMixers)
|
||||
#logger.debug("localMediaMixers", localMediaMixers)
|
||||
#logger.debug("peerLocalMediaMixers", peerLocalMediaMixers)
|
||||
|
||||
# get the server data regarding various media tracks
|
||||
|
|
@ -263,7 +260,7 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
else if oppositeMixer.group_id != ChannelGroupIds.AudioInputMusicGroup
|
||||
logger.error("found local mixer in opposite mode that was not of groupID: AudioInputMusicGroup", mixer, oppositeMixer)
|
||||
else
|
||||
logger.debug("local track is not present: ", track, mixer)
|
||||
logger.debug("local track is not present: ", track, @allMixers)
|
||||
else
|
||||
switch @mixMode
|
||||
when MIX_MODES.MASTER
|
||||
|
|
@ -459,3 +456,6 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
context.JK.VuHelpers.updateVU2('vul', mixer, value)
|
||||
# Do the right
|
||||
context.JK.VuHelpers.updateVU2('vur', mixer, value)
|
||||
|
||||
getTrackInfo: () ->
|
||||
context.JK.TrackHelpers(context.jamClient, @masterMixers)
|
||||
|
|
@ -13,7 +13,6 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
this.listenTo(context.MixerActions.initGain, this.onInitGain)
|
||||
this.listenTo(context.MixerActions.initPan, this.onInitPan)
|
||||
this.listenTo(context.MixerActions.panChanged, this.onPanChanged)
|
||||
this.listenTo(context.MixerActions.mixersChanged, this.onMixersChanged)
|
||||
|
||||
context.JK.HandleVolumeChangeCallback2 = @handleVolumeChangeCallback
|
||||
context.JK.HandleMetronomeCallback2 = @handleMetronomeCallback
|
||||
|
|
@ -104,6 +103,8 @@ MIX_MODES = context.JK.MIX_MODES;
|
|||
# TODO: grab correct mix mode , line 870 sessionModel.js
|
||||
@mixers.updateMixers(type, text, masterMixers, personalMixers)
|
||||
|
||||
this.trigger({session: @session, mixers: @mixers})
|
||||
SessionActions.mixersChanged.trigger(type, text, @mixers.getTrackInfo())
|
||||
|
||||
this.trigger({session: @session, mixers: @mixers})
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ logger = context.JK.logger
|
|||
rest = context.JK.Rest()
|
||||
EVENTS = context.JK.EVENTS;
|
||||
|
||||
|
||||
SessionActions = @SessionActions
|
||||
|
||||
@SessionStore = Reflux.createStore(
|
||||
|
|
@ -24,27 +25,77 @@ SessionActions = @SessionActions
|
|||
sessionPageEnterDeferred: null
|
||||
gearUtils: null
|
||||
sessionUtils: null
|
||||
joinDeffered: null
|
||||
recordingModel: null
|
||||
currentTrackChanges: 0
|
||||
|
||||
|
||||
init: ->
|
||||
# Register with the app store to get @app
|
||||
this.listenTo(context.AppStore, this.onAppInit);
|
||||
this.listenTo(context.AppStore, this.onAppInit)
|
||||
|
||||
onAppInit: (@app) ->
|
||||
@gearUtils = context.JK.GearUtilsInstance
|
||||
@sessionUtils = context.JK.SessionUtils
|
||||
@recordingModel = new context.JK.RecordingModel(@app, this, rest, context.jamClient);
|
||||
|
||||
onWatchedInputs: (inputTracks) ->
|
||||
|
||||
logger.debug("obtained tracks at start of session")
|
||||
@sessionPageEnterDeferred.resolve(inputTracks);
|
||||
@sessionPageEnterDeferred = null
|
||||
|
||||
onMixersChanged: (type, text, trackInfo) ->
|
||||
|
||||
return unless @inSession()
|
||||
|
||||
if text == 'RebuildAudioIoControl'
|
||||
if @backendMixerAlertThrottleTimer
|
||||
clearTimeout(@backendMixerAlertThrottleTimer)
|
||||
|
||||
@backendMixerAlertThrottleTimer = setTimeout(
|
||||
() =>
|
||||
@backendMixerAlertThrottleTimer = null
|
||||
if @sessionPageEnterDeferred
|
||||
# this means we are still waiting for the BACKEND_MIXER_CHANGE that indicates we have user tracks built-out/ready
|
||||
|
||||
# we will get at least one BACKEND_MIXER_CHANGE that corresponds to the backend doing a 'audio pause', which won't matter much
|
||||
# so we need to check that we actaully have userTracks before considering ourselves done
|
||||
if trackInfo.userTracks.length > 0
|
||||
logger.debug("obtained tracks at start of session")
|
||||
@sessionPageEnterDeferred.resolve(trackInfo.userTracks);
|
||||
@sessionPageEnterDeferred = null
|
||||
|
||||
return
|
||||
|
||||
|
||||
// wait until we are fully in session before trying to sync tracks to server
|
||||
if @joinDeferred
|
||||
@joinDeferred
|
||||
.done(()=>
|
||||
@syncTracks()
|
||||
|
||||
, 100)
|
||||
else if @session.inSession() && text == 'RebuildMediaControl'
|
||||
SessionActions.mediaTracksChanged.trigger(@mixers.getTrackInfo())
|
||||
else if @session.inSession() && text == 'RebuildRemoteUserControl'
|
||||
SessionActions.otherTracksChanged.trigger(@mixers.getTrackInfo())
|
||||
|
||||
|
||||
|
||||
onJoinSession: (sessionId) ->
|
||||
|
||||
# initialize webcamViewer
|
||||
if gon.global.video_available && gon.global.video_available != "none"
|
||||
webcamViewer.beforeShow()
|
||||
@webcamViewer.beforeShow()
|
||||
|
||||
# double-check that we are connected to the server via websocket
|
||||
|
||||
return unless @ensureConnected()
|
||||
|
||||
# just make double sure a previous session state is cleared out
|
||||
@sessionEnded()
|
||||
|
||||
# update the session data to be empty
|
||||
@updateCurrentSession(null)
|
||||
|
||||
|
|
@ -153,7 +204,7 @@ SessionActions = @SessionActions
|
|||
|
||||
# tell the server we want to join
|
||||
|
||||
rest.joinSession({
|
||||
@joinDeferred = rest.joinSession({
|
||||
client_id: @app.clientId,
|
||||
ip_address: context.JK.JamServer.publicIP,
|
||||
as_musician: true,
|
||||
|
|
@ -177,7 +228,7 @@ SessionActions = @SessionActions
|
|||
else
|
||||
context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.join);
|
||||
|
||||
#recordingModel.reset();
|
||||
@recordingModel.reset(response.id);
|
||||
|
||||
context.jamClient.JoinSession({sessionID: response.id});
|
||||
|
||||
|
|
@ -417,7 +468,96 @@ SessionActions = @SessionActions
|
|||
|
||||
context.JK.JamServer.connected
|
||||
|
||||
# called by anyone wanting to leave the session with a certain behavior
|
||||
onLeaveSession: (behavior) ->
|
||||
logger.debug("attempting to leave session", behavior)
|
||||
if behavior.notify
|
||||
@app.layout.notify(behavior.notify)
|
||||
|
||||
SessionActions.allowLeaveSession.trigger()
|
||||
|
||||
if behavior.location
|
||||
if jQuery.isNumeric(behavior.location)
|
||||
window.history.go(behavior.location)
|
||||
else
|
||||
window.location = behavior.location
|
||||
else
|
||||
logger.warn("no location specified in leaveSession action", behavior)
|
||||
window.location = '/client#/home'
|
||||
|
||||
if gon.global.video_available && gon.global.video_available != "none"
|
||||
@webcamViewer.setVideoOff()
|
||||
|
||||
@leaveSession()
|
||||
|
||||
@sessionUtils.SessionPageLeave()
|
||||
|
||||
leaveSession: () ->
|
||||
|
||||
if @joinDeferred?.state() == 'resolved'
|
||||
deferred = new $.Deferred()
|
||||
|
||||
@recordingModel.stopRecordingIfNeeded()
|
||||
.always(()=>
|
||||
@performLeaveSession(deferred)
|
||||
)
|
||||
|
||||
performLeaveSession: (deferred) ->
|
||||
|
||||
logger.debug("SessionModel.leaveCurrentSession()")
|
||||
# TODO - sessionChanged will be called with currentSession = null\
|
||||
|
||||
# leave the session right away without waiting on REST. Why? If you can't contact the server, or if it takes a long
|
||||
# time, for that entire duration you'll still be sending voice data to the other users.
|
||||
# this may be bad if someone decides to badmouth others in the left-session during this time
|
||||
logger.debug("performLeaveSession: calling jamClient.LeaveSession for clientId=" + @app.clientId)
|
||||
context.jamClient.LeaveSession({ sessionID: @currentSessionId })
|
||||
@leaveSessionRest(@currentSessionId)
|
||||
.done(=>
|
||||
deferred.resolve(arguments[0], arguments[1], arguments[2]))
|
||||
.fail(=>
|
||||
deferred.reject(arguments[0], arguments[1], arguments[2]);
|
||||
)
|
||||
|
||||
# 'unregister' for callbacks
|
||||
context.jamClient.SessionRegisterCallback("");
|
||||
#context.jamClient.SessionSetAlertCallback("");
|
||||
context.jamClient.SessionSetConnectionStatusRefreshRate(0);
|
||||
|
||||
@sessionEnded()
|
||||
|
||||
this.trigger(new context.SessionHelper(@app, @currentSession))
|
||||
|
||||
sessionEnded: () ->
|
||||
# cleanup
|
||||
|
||||
context.JK.JamServer.unregisterMessageCallback(context.JK.MessageType.SESSION_JOIN, @trackChanges);
|
||||
context.JK.JamServer.unregisterMessageCallback(context.JK.MessageType.SESSION_DEPART, @trackChanges);
|
||||
context.JK.JamServer.unregisterMessageCallback(context.JK.MessageType.TRACKS_CHANGED, @trackChanges);
|
||||
context.JK.JamServer.unregisterMessageCallback(context.JK.MessageType.HEARTBEAT_ACK, @trackChanges);
|
||||
|
||||
if @sessionPageEnterDeferred?
|
||||
@sessionPageEnterDeferred.reject('session_over')
|
||||
@sessionPageEnterDeferred = null
|
||||
|
||||
if @backendMixerAlertThrottleTimer
|
||||
clearTimeout(@backendMixerAlertThrottleTimer)
|
||||
@backendMixerAlertThrottleTimer = null
|
||||
|
||||
@userTracks = null;
|
||||
@startTime = null;
|
||||
|
||||
if @joinDeffered?.state() == 'resolved'
|
||||
$(document).trigger(EVENTS.SESSION_ENDED, {session: {id: @currentSessionId}})
|
||||
|
||||
@currentTrackChanges = 0
|
||||
@currentSession = null
|
||||
@joinDeferred = null
|
||||
@currentSessionId = null
|
||||
@currentParticipants = {}
|
||||
@previousAllTracks = {userTracks: [], backingTracks: [], metronomeTracks: []}
|
||||
@openBackingTrack = null
|
||||
@shownAudioMediaMixerHelp = false
|
||||
@controlsLockedForJamTrackRecording = false;
|
||||
}
|
||||
)
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
context.JK = context.JK || {};
|
||||
var logger = context.JK.logger;
|
||||
|
||||
context.JK.RecordingModel = function(app, sessionModel, _rest, _jamClient) {
|
||||
context.JK.RecordingModel = function(app, _rest, _jamClient) {
|
||||
var currentRecording = null; // the JSON response from the server for a recording
|
||||
var currentOrLastRecordingId = null;
|
||||
var currentRecordingId = null;
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
var waitingOnStopTimer = null;
|
||||
var jamClient = _jamClient;
|
||||
|
||||
var sessionModel = sessionModel;
|
||||
var sessionId = null;
|
||||
var $self = $(this);
|
||||
|
||||
function isRecording (recordingId) {
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
}
|
||||
|
||||
/** called every time a session is joined, to ensure clean state */
|
||||
function reset() {
|
||||
function reset(_sessionId) {
|
||||
currentlyRecording = false;
|
||||
waitingOnServerStop = false;
|
||||
waitingOnClientStop = false;
|
||||
|
|
@ -57,6 +57,7 @@
|
|||
currentRecording = null;
|
||||
currentRecordingId = null;
|
||||
stoppingRecording = false;
|
||||
sessionId = _sessionId
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -84,7 +85,7 @@
|
|||
currentlyRecording = true;
|
||||
stoppingRecording = false;
|
||||
|
||||
currentRecording = rest.startRecording({"music_session_id": sessionModel.id()})
|
||||
currentRecording = rest.startRecording({"music_session_id": sessionId})
|
||||
.done(function(recording) {
|
||||
currentRecordingId = recording.id;
|
||||
currentOrLastRecordingId = recording.id;
|
||||
|
|
|
|||
|
|
@ -720,7 +720,7 @@
|
|||
|
||||
// we redirect to the session screen, which handles the REST call to POST /participants.
|
||||
logger.debug("joining session screen: " + sessionId)
|
||||
context.location = '/client#/session/' + sessionId;
|
||||
context.location = '/client#/session2/' + sessionId;
|
||||
};
|
||||
|
||||
if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>') {
|
||||
|
|
|
|||
|
|
@ -16,12 +16,14 @@
|
|||
// take all necessary arguments to complete its work.
|
||||
context.JK.TrackHelpers = {
|
||||
|
||||
getTrackInfo: function(jamClient) {
|
||||
getTrackInfo: function(jamClient, masterTracks) {
|
||||
|
||||
var allTracks = context.jamClient.SessionGetAllControlState(true);
|
||||
if(masterTracks === undefined) {
|
||||
masterTracks = context.jamClient.SessionGetAllControlState(true);
|
||||
}
|
||||
|
||||
var userTracks = context.JK.TrackHelpers.getUserTracks(jamClient, allTracks);
|
||||
var backingTracks = context.JK.TrackHelpers.getBackingTracks(jamClient, allTracks);
|
||||
var userTracks = context.JK.TrackHelpers.getUserTracks(jamClient, masterTracks);
|
||||
var backingTracks = context.JK.TrackHelpers.getBackingTracks(jamClient, masterTracks);
|
||||
var metronomeTracks = context.JK.TrackHelpers.getTracks(jamClient, ChannelGroupIds.MetronomeGroup);
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
var os = null;
|
||||
|
||||
var reactHovers = []
|
||||
|
||||
context.JK.stringToBool = function (s) {
|
||||
switch (s.toLowerCase()) {
|
||||
case "true":
|
||||
|
|
@ -217,6 +219,11 @@
|
|||
|
||||
if(!options) options = {};
|
||||
|
||||
context._.each(reactHovers, function(react) {
|
||||
reactHovers.btOff();
|
||||
})
|
||||
reactHovers = []
|
||||
|
||||
function waitForBubbleHover($bubble) {
|
||||
$bubble.hoverIntent({
|
||||
over: function() {
|
||||
|
|
@ -235,6 +242,7 @@
|
|||
|
||||
options.trigger = 'none'
|
||||
options.clickAnywhereToClose = true
|
||||
options.closeWhenOthersOpen = true
|
||||
options.preShow = function(container) {
|
||||
var reactElement = context[reactElementName]
|
||||
if(!reactElementName) {
|
||||
|
|
|
|||
|
|
@ -301,6 +301,8 @@
|
|||
background-repeat:no-repeat;
|
||||
text-align: center;
|
||||
margin-left:10px;
|
||||
//-webkit-transform: rotate(7deg); /* Chrome, Safari, Opera */
|
||||
//transform: rotate(7deg);
|
||||
}
|
||||
|
||||
.track-icon-equalizer {
|
||||
|
|
|
|||
Loading…
Reference in New Issue