diff --git a/web/app/assets/javascripts/backend_alerts.js b/web/app/assets/javascripts/backend_alerts.js index 5d1f74ff5..b9c55c332 100644 --- a/web/app/assets/javascripts/backend_alerts.js +++ b/web/app/assets/javascripts/backend_alerts.js @@ -78,10 +78,10 @@ if (type === 2) { // BACKEND_MIXER_CHANGE - context.SessionActions.mixersChanged(type, text) + context.MixerActions.mixersChanged(type, text) - if(context.JK.CurrentSessionModel) - context.JK.CurrentSessionModel.onBackendMixerChanged(type, text) + //if(context.JK.CurrentSessionModel) + // context.JK.CurrentSessionModel.onBackendMixerChanged(type, text) } else if (type === ALERT_NAMES.NO_VALID_AUDIO_CONFIG) { // NO_VALID_AUDIO_CONFIG if(context.JK.GearUtilsInstance && context.JK.GearUtilsInstance.isRestartingAudio()) { diff --git a/web/app/assets/javascripts/minimal/minimal.js b/web/app/assets/javascripts/minimal/minimal.js new file mode 100644 index 000000000..e69de29bb diff --git a/web/app/assets/javascripts/panHelpers.js.coffee b/web/app/assets/javascripts/panHelpers.js.coffee index fe4f8f33d..3347d86b3 100644 --- a/web/app/assets/javascripts/panHelpers.js.coffee +++ b/web/app/assets/javascripts/panHelpers.js.coffee @@ -31,4 +31,7 @@ panHelper = class PanHelper else Math.round(value) + convertPercentToPanForDisplay: (percent) -> + Math.abs(context.JK.PanHelpers.convertPercentToPan(percent)) + context.JK.PanHelpers = new panHelper() \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components.js b/web/app/assets/javascripts/react-components.js index 43fbc0d08..c5c6bb14b 100644 --- a/web/app/assets/javascripts/react-components.js +++ b/web/app/assets/javascripts/react-components.js @@ -4,5 +4,6 @@ //= require ./react-components/stores/SessionStore //= require ./react-components/stores/MixerStore //= require ./react-components/stores/SessionMyTracksStore +//= require ./react-components/stores/SessionOtherTracksStore //= require_directory ./react-components/stores //= require_directory ./react-components \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/SessionInviteMusiciansBtn.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionInviteMusiciansBtn.js.jsx.coffee index 00f4316f6..f1c0934f7 100644 --- a/web/app/assets/javascripts/react-components/SessionInviteMusiciansBtn.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionInviteMusiciansBtn.js.jsx.coffee @@ -2,8 +2,16 @@ context = window @SessionInviteMusiciansBtn = React.createClass({ + openInviteDialog : (e) -> + e.preventDefault() + + #friendInput = inviteMusiciansUtil.inviteSessionUpdate('#update-session-invite-musicians', sessionId); + #inviteMusiciansUtil.loadFriends(); + #$(friendInput).show(); + render: () -> - ` + ` + Invite Musicians ` }) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee index d2612de05..94fa7ab25 100644 --- a/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee @@ -4,76 +4,93 @@ MixerActions = @MixerActions @SessionMyTrack = React.createClass({ - mixins: [Reflux.listenTo(@SessionMyTracksStore,"onInputsChanged")] - - onInputsChanged: (sessionMixers) -> - - mixers = sessionMixers.mixers - newMixers = mixers.findMixerForTrack.apply(mixers, this.props.mixerFinder) - - this.setState({mixers: newMixers}) - - - getInitialState: () -> - {mixers: this.props.mixers} - + handleMute: (e) -> e.preventDefault() + unless this.props.mixers.mixer + logger.debug("ignoring mute; no mixer") + return + muting = $(e.currentTarget).is('.enabled') - MixerActions.mute([this.state.mixers.mixer, this.state.mixers.oppositeMixer], muting) + MixerActions.mute([this.props.mixers.mixer, this.props.mixers.oppositeMixer], muting) render: () -> - muteMixer = this.state.mixers.muteMixer - vuMixer = this.state.mixers.vuMixer + muteMixer = this.props.mixers.muteMixer + vuMixer = this.props.mixers.vuMixer + muteMixerId = muteMixer?.id classes = classNames({ 'track-icon-mute': true - 'enabled' : !muteMixer.mute - 'muted' : muteMixer.mute + 'enabled' : !muteMixer?.mute + 'muted' : muteMixer?.mute }) + pan = if this.props.mixers.mixer? then this.props.mixers.mixer.pan else 0 + panStyle = { - transform: "rotate(#{this.state.mixers.mixer.pan}deg)" - WebkitTransform: "rotate(#{this.state.mixers.mixer.pan}deg)" + transform: "rotate(#{pan}deg)" + WebkitTransform: "rotate(#{pan}deg)" } `
-
{this.props.name}
-
-
-
- -
-
-
-
+
+
+
{this.props.name}
+
+
+
+ +
+
+
+
+
+
+ +
- - -
` componentDidMount: () -> - $root = jQuery(this.getDOMNode()) + + console.log("SessionSetUserName", this.props.clientId, this.props.name) + context.jamClient.SessionSetUserName(this.props.clientId, this.props.name) + + $root = $(this.getDOMNode()) $mute = $root.find('.track-icon-mute') $pan = $root.find('.track-icon-pan') context.JK.interactReactBubble( $mute, 'SessionTrackVolumeHover', - {mixers:this.state.mixers, mixerFinder: this.props.mixerFinder}, + () => + {mixers:this.props.mixers, mixerFinder: this.props.mixerFinder} + , {width:235, positions:['right', 'left'], offsetParent:$root.closest('.screen')}) context.JK.interactReactBubble( $pan, 'SessionTrackPanHover', - {mixers:this.state.mixers, mixerFinder: this.props.mixerFinder}, + () => + {mixers:this.props.mixers, mixerFinder: this.props.mixerFinder} + , {width:331, positions:['right', 'left'], offsetParent:$root.closest('.screen')}) + componentWillUpdate: (nextProps, nextState) -> + $root = $(this.getDOMNode()) + $mute = $root.find('.track-icon-mute') + $pan = $root.find('.track-icon-pan') + # disable hover effects if there is no mixer + if nextProps.mixers.mixer? + $mute.off("click", false) + $pan.off("click", false) + else + $mute.on("click", false) + $pan.on("click", false) }) diff --git a/web/app/assets/javascripts/react-components/SessionMyTracks.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionMyTracks.js.jsx.coffee index b5b254ba7..7f3d1f189 100644 --- a/web/app/assets/javascripts/react-components/SessionMyTracks.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionMyTracks.js.jsx.coffee @@ -1,9 +1,6 @@ context = window - - ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; - @SessionMyTracks = React.createClass({ mixins: [Reflux.listenTo(@SessionMyTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit")] @@ -22,16 +19,15 @@ ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; for track in participant.tracks # try to find mixer info for this track - mixerFinder = [participant.client_id, track, true] + mixerFinder = [participant.client_id, track, true] # so that other callers can re-find their mixer data mixerData = mixers.findMixerForTrack(participant.client_id, track, true) - mixerData.mixerFinder = mixerFinder # so that other callers can re-find their mixer data # todo: sessionModel.setAudioEstablished instrumentIcon = context.JK.getInstrumentIcon45(track.instrument_id); photoUrl = context.JK.resolveAvatarUrl(participant.user.photo_url); - tracks.push({track: track, mixerFinder: mixerFinder, mixers: mixerData, name: name, instrumentIcon: instrumentIcon, photoUrl: photoUrl}) + tracks.push({track: track, mixerFinder: mixerFinder, mixers: mixerData, name: name, instrumentIcon: instrumentIcon, photoUrl: photoUrl, clientId: participant.client_id}) # TODO: also deal with chat diff --git a/web/app/assets/javascripts/react-components/SessionOtherTrack.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionOtherTrack.js.jsx.coffee new file mode 100644 index 000000000..c55b515d8 --- /dev/null +++ b/web/app/assets/javascripts/react-components/SessionOtherTrack.js.jsx.coffee @@ -0,0 +1,119 @@ +context = window + +MixerActions = @MixerActions + +@SessionOtherTrack = React.createClass({ + + handleMute: (e) -> + e.preventDefault() + + unless this.props.hasMixer + logger.debug("ignoring mute; no mixer") + return + + muting = $(e.currentTarget).is('.enabled') + + MixerActions.mute([this.props.mixers.mixer, this.props.mixers.oppositeMixer], muting) + + render: () -> + + # today, all mixers are the same for a remote participant; so just grab the 1st + mixers = if this.props.tracks.length > 0 then this.props.tracks[0].mixers else {} + + muteMixer = mixers.muteMixer + vuMixer = mixers.vuMixer + muteMixerId = muteMixer?.id + + classes = classNames({ + 'track-icon-mute': true + 'enabled' : !muteMixer?.mute + 'muted' : muteMixer?.mute + }) + + componentClasses = classNames({ + "session-track" : true + "my-track" : true + "has-mixer" : this.props.hasMixer + "no-mixer" : !this.props.hasMixer + }) + + pan = if mixers.mixer? then mixers.mixer?.pan else 0 + + panStyle = { + transform: "rotate(#{pan}deg)" + WebkitTransform: "rotate(#{pan}deg)" + } + + `
+
+
+
{this.props.name}
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
` + + componentDidMount: () -> + + console.log("SessionSetUserName (other)", this.props.clientId, this.props.name) + + context.jamClient.SessionSetUserName(this.props.client_id, this.props.name) + + $root = $(this.getDOMNode()) + $mute = $root.find('.track-icon-mute') + $pan = $root.find('.track-icon-pan') + + context.JK.interactReactBubble( + $mute, + 'SessionTrackVolumeHover', + () => + mixers = if this.props.tracks.length > 0 then this.props.tracks[0].mixers else {} + mixerFinder = if this.props.tracks.length > 0 then this.props.tracks[0].mixerFinder else null + {mixers:mixers, mixerFinder: mixerFinder} + , + {width:235, positions:['right', 'left'], offsetParent:$root.closest('.screen')}) + + context.JK.interactReactBubble( + $pan, + 'SessionTrackPanHover', + () => + mixers = if this.props.tracks.length > 0 then this.props.tracks[0].mixers else {} + mixerFinder = if this.props.tracks.length > 0 then this.props.tracks[0].mixerFinder else null + {mixers:mixers, mixerFinder: mixerFinder} + , + {width:331, positions:['right', 'left'], offsetParent:$root.closest('.screen')}) + + unless this.props.hasMixer + $mute.on("mouseenter", false) + $mute.on("mouseleave", false) + $pan.on("mouseentere", false) + $pan.on("mouseleave", false) + + componentWillUpdate: (nextProps, nextState) -> + $root = $(this.getDOMNode()) + $mute = $root.find('.track-icon-mute') + $pan = $root.find('.track-icon-pan') + + # disable hover effects if there is no mixer + if nextProps.hasMixer + $mute.off("mouseenter", false) + $mute.off("mouseleave", false) + $pan.off("mouseenter", false) + $pan.off("mouseleave", false) + else + $mute.on("mouseenter", false) + $mute.on("mouseleave", false) + $pan.on("mouseentere", false) + $pan.on("mouseleave", false) +}) diff --git a/web/app/assets/javascripts/react-components/SessionOtherTracks.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionOtherTracks.js.jsx.coffee index 155cecdeb..29060d8ad 100644 --- a/web/app/assets/javascripts/react-components/SessionOtherTracks.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionOtherTracks.js.jsx.coffee @@ -1,18 +1,75 @@ context = window +ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; @SessionOtherTracks = React.createClass({ + mixins: [Reflux.listenTo(@SessionOtherTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit")] + + onInputsChanged: (sessionMixers) -> + + session = sessionMixers.session + mixers = sessionMixers.mixers + + logger.debug("SessionOtherTracks: onInputsChanged") + participants = [] + + if session.inSession() + + for participant in session.otherParticipants() + + tracks = [] + name = participant.user.name; + + firstTrack = participant.tracks[0] + hasMixer = false + + for track in participant.tracks + # try to find mixer info for this track + mixerFinder = [participant.client_id, track, false] # so that other callers can re-find their mixer data + + mixerData = mixers.findMixerForTrack(participant.client_id, track, false) + if mixerData.mixer? + hasMixer = true + + tracks.push(track: track, mixers: mixerData, mixerFinder: mixerFinder) + # todo: sessionModel.setAudioEstablished + + instrumentIcon = context.JK.getInstrumentIcon45(firstTrack.instrument_id) + photoUrl = context.JK.resolveAvatarUrl(participant.user.photo_url) + + participantState = {participant:participant, tracks: tracks, name: name, instrumentIcon: instrumentIcon, photoUrl: photoUrl, hasMixer: hasMixer} + + participants.push(participantState) + + this.setState(participants:participants, session:session) + render: () -> - noOthers = `
` + content = null + participants = [] - active = noOthers + noOthers = `
No other musicians are in your session.
` + + if this.state.participants.length > 0 + for participant in this.state.participants + participants.push(``) + else if this.state.session? && this.state.session.inSession() + content = noOthers `

other live tracks

- {active} + {content} + + {participants} +
` + + getInitialState:() -> + {participants:[], session: null} + + onAppInit: (app) -> + @app = app }) diff --git a/web/app/assets/javascripts/react-components/SessionRecordBtn.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionRecordBtn.js.jsx.coffee index 0506b1f4f..a406c7b25 100644 --- a/web/app/assets/javascripts/react-components/SessionRecordBtn.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionRecordBtn.js.jsx.coffee @@ -2,8 +2,19 @@ context = window @SessionRecordBtn = React.createClass({ + datAss: () -> + alert("dat ass") + openRecording: () -> + recording = window.open("/popups/session/#{1}/recording-controls", 'Recording', 'scrollbars=yes,toolbar=no,status=no,height=315,width=350') + + + window.callMe = @datAss + $(recording).on('load', ()-> + alert("loaded") + recording.bling() + ) render: () -> - ` + ` RECORD ` diff --git a/web/app/assets/javascripts/react-components/SessionTrackPan.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionTrackPan.js.jsx.coffee index 09963272b..72a9f9c3d 100644 --- a/web/app/assets/javascripts/react-components/SessionTrackPan.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionTrackPan.js.jsx.coffee @@ -40,7 +40,7 @@ logger = context.JK.logger $fader.data('showHelpAboutMediaMixers', this.state.behaviors.showHelpAboutMediaMixers) - context.JK.FaderHelpers.renderFader2($fader, {faderType: 'horizontal', snap:true}, context.JK.PanHelpers.convertPercentToPan) + context.JK.FaderHelpers.renderFader2($fader, {faderType: 'horizontal', snap:true}, context.JK.PanHelpers.convertPercentToPanForDisplay) # Initialize gain position MixerActions.initPan(this.state.mixers.mixer) diff --git a/web/app/assets/javascripts/react-components/SessionTrackSettingsBtn.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionTrackSettingsBtn.js.jsx.coffee index ab73b0c57..530df4c93 100644 --- a/web/app/assets/javascripts/react-components/SessionTrackSettingsBtn.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionTrackSettingsBtn.js.jsx.coffee @@ -15,8 +15,8 @@ logger = context.JK.logger @app = app render: () -> - `` + ` }) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/SessionTrackVU.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionTrackVU.js.jsx.coffee index d378136d7..68b0d5b67 100644 --- a/web/app/assets/javascripts/react-components/SessionTrackVU.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionTrackVU.js.jsx.coffee @@ -2,9 +2,6 @@ context = window @SessionTrackVU = React.createClass({ - getInitialState: () -> - {mixers: this.props.mixers} - render: () -> lights = [] @@ -20,7 +17,7 @@ context = window lights.push(``) - tableClasses = classNames('vu', 'horizontal', this.props.side + '-' + this.state.mixers.mixer.mixerId) + tableClasses = classNames('vu', 'horizontal', this.props.side + '-' + this.props.mixers.mixer?.id) ` @@ -36,7 +33,7 @@ context = window lights.push(``) - tableClasses = classNames('vu', 'vertical', this.props.side + '-' + this.state.mixers.mixer.mixerId) + tableClasses = classNames('vu', 'vertical', this.props.side + '-' + this.props.mixers.mixer?.id) `
{lights} diff --git a/web/app/assets/javascripts/react-components/SessionTrackVolumeHover.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionTrackVolumeHover.js.jsx.coffee index c766d4651..f8147e2ed 100644 --- a/web/app/assets/javascripts/react-components/SessionTrackVolumeHover.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionTrackVolumeHover.js.jsx.coffee @@ -32,10 +32,13 @@ MixerActions = @MixerActions muteMixer = this.state.mixers.muteMixer + muteMixerId = muteMixer?.id + volume_left = this.state.mixers.mixer?.volume_left + classes = classNames({ 'track-icon-mute': true - 'enabled' : !muteMixer.mute - 'muted' : muteMixer.mute + 'enabled' : !muteMixer?.mute + 'muted' : muteMixer?.mute }) @@ -49,10 +52,10 @@ MixerActions = @MixerActions
Volume
-
{this.state.mixers.mixer.volume_left}dB
+
{volume_left}dB
-
+
@@ -84,7 +87,7 @@ MixerActions = @MixerActions # re-initialize icheck $checkbox = $root.find('input') - if nextState.mixers.muteMixer.mute + if nextState.mixers.muteMixer?.mute $checkbox.iCheck('check').attr('checked', true) else $checkbox.iCheck('uncheck').attr('checked', false) diff --git a/web/app/assets/javascripts/react-components/actions/MixerActions.js.coffee b/web/app/assets/javascripts/react-components/actions/MixerActions.js.coffee index 1f23bfb1b..9aa71fa0d 100644 --- a/web/app/assets/javascripts/react-components/actions/MixerActions.js.coffee +++ b/web/app/assets/javascripts/react-components/actions/MixerActions.js.coffee @@ -7,4 +7,6 @@ context = window panChanged: {} initPan: {} mixersChanged: {} + syncTracks: {} + mixerModeChanged: {} }) diff --git a/web/app/assets/javascripts/react-components/actions/SessionActions.js.coffee b/web/app/assets/javascripts/react-components/actions/SessionActions.js.coffee index 41ff315f6..44ea905cf 100644 --- a/web/app/assets/javascripts/react-components/actions/SessionActions.js.coffee +++ b/web/app/assets/javascripts/react-components/actions/SessionActions.js.coffee @@ -3,6 +3,6 @@ context = window @SessionActions = Reflux.createActions({ joinSession: {} leaveSession: {} - resyncServer: {asyncResult: true} mixersChanged: {} + allowLeaveSession: {} }) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/helpers/MixerHelper.js.coffee b/web/app/assets/javascripts/react-components/helpers/MixerHelper.js.coffee index 3233de9b8..a1352040c 100644 --- a/web/app/assets/javascripts/react-components/helpers/MixerHelper.js.coffee +++ b/web/app/assets/javascripts/react-components/helpers/MixerHelper.js.coffee @@ -27,7 +27,7 @@ MIX_MODES = context.JK.MIX_MODES; organize: () -> - for masterMixer, i in @masterMixers + for masterMixer in @masterMixers @allMixers['M' + masterMixer.id] = masterMixer; # populate allMixers by mixer.id # populate mixer pair @@ -36,7 +36,7 @@ MIX_MODES = context.JK.MIX_MODES; @mixersByTrackId[masterMixer.id] = mixerPair mixerPair.master = masterMixer; - for personalMixer, i in @personalMixers + for personalMixer in @personalMixers @allMixers['P' + personalMixer.id] = personalMixer @@ -222,7 +222,7 @@ MIX_MODES = context.JK.MIX_MODES; if mixer.client_id == clientId for groupId in groupIds if mixer.group_id == groupId - if (mixer.groupId != ChannelGroupIds.UserMusicInputGroup) && !(mixer.id in usedMixers) + if (mixer.groupId != ChannelGroupIds.UserMusicInputGroup) && !(mixer.id of usedMixers) mixers = foundMixers[mixer.group_id] if !mixers mixers = [] @@ -365,7 +365,7 @@ MIX_MODES = context.JK.MIX_MODES; initPan: (mixer) -> panPercent= context.JK.PanHelpers.convertPanToPercent(mixer.pan) - context.JK.FaderHelpers.setFaderValue(mixer.id, panPercent, mixer.pan) + context.JK.FaderHelpers.setFaderValue(mixer.id, panPercent, Math.abs(mixer.pan)) context.JK.FaderHelpers.showFader(mixer.id) setMixerPan: (mixer, panPercent) -> @@ -449,7 +449,10 @@ MIX_MODES = context.JK.MIX_MODES; if mixer if mixer.stereo # // stereo track - context.JK.VuHelpers.updateVU2('vul', mixer, value) + if mixerId.substr(-4) == "_vul" + context.JK.VuHelpers.updateVU2('vul', mixer, value) + else + context.JK.VuHelpers.updateVU2('vur', mixer, value) else if mixerId.substr(-4) == "_vul" # Do the left @@ -458,4 +461,4 @@ MIX_MODES = context.JK.MIX_MODES; context.JK.VuHelpers.updateVU2('vur', mixer, value) getTrackInfo: () -> - context.JK.TrackHelpers(context.jamClient, @masterMixers) \ No newline at end of file + context.JK.TrackHelpers.getTrackInfo(context.jamClient, @masterMixers) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/helpers/SessionHelper.js.coffee b/web/app/assets/javascripts/react-components/helpers/SessionHelper.js.coffee index 1d7a82f0d..d61e3b71b 100644 --- a/web/app/assets/javascripts/react-components/helpers/SessionHelper.js.coffee +++ b/web/app/assets/javascripts/react-components/helpers/SessionHelper.js.coffee @@ -15,6 +15,14 @@ context = window else [] + otherParticipants: () -> + others = [] + for participant in @participants() + myTrack = @app.clientId == participant.client_id + + others.push(participant) unless myTrack + others + # if any participant has the metronome open, then we say this session has the metronome open isMetronomeOpen: () -> metronomeOpen = false; @@ -78,3 +86,5 @@ context = window logger.warn('unable to find participant with clientId: ' + clientId) unless found found + id: () -> + @session.id diff --git a/web/app/assets/javascripts/react-components/stores/MixerStore.js.coffee b/web/app/assets/javascripts/react-components/stores/MixerStore.js.coffee index cdb0908a0..620ca65dd 100644 --- a/web/app/assets/javascripts/react-components/stores/MixerStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/MixerStore.js.coffee @@ -1,6 +1,7 @@ context = window logger = context.JK.logger -MIX_MODES = context.JK.MIX_MODES; +MIX_MODES = context.JK.MIX_MODES +rest = context.JK.Rest() @MixerStore = Reflux.createStore( { @@ -13,6 +14,9 @@ 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) + this.listenTo(context.MixerActions.syncTracks, this.onSyncTracks) + this.listenTo(context.MixerActions.mixerModeChanged, this.onMixerModeChanged) context.JK.HandleVolumeChangeCallback2 = @handleVolumeChangeCallback context.JK.HandleMetronomeCallback2 = @handleMetronomeCallback @@ -60,11 +64,10 @@ MIX_MODES = context.JK.MIX_MODES; @session = session - masterMixers = context.jamClient.SessionGetAllControlState(true); - personalMixers = context.jamClient.SessionGetAllControlState(false); + @masterMixers = context.jamClient.SessionGetAllControlState(true); + @personalMixers = context.jamClient.SessionGetAllControlState(false); - # TODO: grab correct mix mode , line 870 sessionModel.js - @mixers = new context.MixerHelper(session, masterMixers, personalMixers, MIX_MODES.PERSONAL) + @mixers = new context.MixerHelper(session, @masterMixers, @personalMixers, @mixers?.mixMode || MIX_MODES.PERSONAL) this.trigger({session: @session, mixers: @mixers}) @@ -96,15 +99,51 @@ MIX_MODES = context.JK.MIX_MODES; onMixersChanged: (type, text) -> - if @mixers - masterMixers = context.jamClient.SessionGetAllControlState(true); - personalMixers = context.jamClient.SessionGetAllControlState(false); + @masterMixers = context.jamClient.SessionGetAllControlState(true); + @personalMixers = context.jamClient.SessionGetAllControlState(false); - # TODO: grab correct mix mode , line 870 sessionModel.js - @mixers.updateMixers(type, text, masterMixers, personalMixers) + @mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, @mixers?.mixMode || MIX_MODES.PERSONAL) - SessionActions.mixersChanged.trigger(type, text, @mixers.getTrackInfo()) + SessionActions.mixersChanged.trigger(type, text, @mixers.getTrackInfo()) this.trigger({session: @session, mixers: @mixers}) + + onMixerModeChanged: (mode) -> + + @mixers = new context.MixerHelper(@session, @masterMixers, @personalMixers, mode) + this.trigger({session: @session, mixers: @mixers}) + + onSyncTracks: () -> + logger.debug("MixerStore: onSyncTracks") + unless @session.inSession() + logger.debug("dropping queued up sync tracks because no longer in session") + return + + allTracks = @mixers.getTrackInfo() + + inputTracks = allTracks.userTracks; + backingTracks = allTracks.backingTracks; + metronomeTracks = allTracks.metronomeTracks; + + # create a trackSync request based on backend data + syncTrackRequest = {} + syncTrackRequest.client_id = @app.clientId + syncTrackRequest.tracks = inputTracks + syncTrackRequest.backing_tracks = backingTracks + syncTrackRequest.metronome_open = metronomeTracks.length > 0 + syncTrackRequest.id = @session.id() + + rest.putTrackSyncChange(syncTrackRequest) + .fail((jqXHR)=> + if jqXHR.status != 404 + @app.notify({ + "title": "Can't Sync Local Tracks", + "text": "The client is unable to sync local track information with the server. You should rejoin the session to ensure a good experience.", + "icon_url": "/assets/content/icon_alert_big.png" + }) + + else + logger.debug("Unable to sync local tracks because session is gone.") + ) } ) diff --git a/web/app/assets/javascripts/react-components/stores/SessionOtherTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/SessionOtherTracksStore.js.coffee new file mode 100644 index 000000000..703d65305 --- /dev/null +++ b/web/app/assets/javascripts/react-components/stores/SessionOtherTracksStore.js.coffee @@ -0,0 +1,21 @@ +$ = jQuery +context = window +logger = context.JK.logger + +@SessionOtherTracksStore = Reflux.createStore( + { + + init: -> + # Register with the app store to get @app + this.listenTo(context.AppStore, this.onAppInit); + this.listenTo(context.MixerStore, this.onSessionMixerChange) + + onAppInit: (@app) -> + @gearUtils = context.JK.GearUtilsInstance + @sessionUtils = context.JK.SessionUtils + + onSessionMixerChange: (sessionMixers) -> + + this.trigger(sessionMixers) + } +) diff --git a/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee b/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee index 04bd575ff..701e90c56 100644 --- a/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee @@ -2,7 +2,8 @@ $ = jQuery context = window logger = context.JK.logger rest = context.JK.Rest() -EVENTS = context.JK.EVENTS; +EVENTS = context.JK.EVENTS +MIX_MODES = context.JK.MIX_MODES SessionActions = @SessionActions @@ -28,7 +29,7 @@ SessionActions = @SessionActions joinDeffered: null recordingModel: null currentTrackChanges: 0 - + previousAllTracks: {userTracks: [], backingTracks: [], metronomeTracks: []} init: -> # Register with the app store to get @app @@ -50,11 +51,12 @@ SessionActions = @SessionActions return unless @inSession() if text == 'RebuildAudioIoControl' + if @backendMixerAlertThrottleTimer clearTimeout(@backendMixerAlertThrottleTimer) - @backendMixerAlertThrottleTimer = setTimeout( - () => + @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 @@ -63,25 +65,43 @@ SessionActions = @SessionActions # 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.resolve(trackInfo.userTracks) @sessionPageEnterDeferred = null return - - // wait until we are fully in session before trying to sync tracks to server + # wait until we are fully in session before trying to sync tracks to server if @joinDeferred @joinDeferred .done(()=> - @syncTracks() - + MixerActions.syncTracks() + ) , 100) - else if @session.inSession() && text == 'RebuildMediaControl' - SessionActions.mediaTracksChanged.trigger(@mixers.getTrackInfo()) - else if @session.inSession() && text == 'RebuildRemoteUserControl' - SessionActions.otherTracksChanged.trigger(@mixers.getTrackInfo()) + else if text == 'RebuildMediaControl' || text == 'RebuildRemoteUserControl' + backingTracks = trackInfo.backingTracks + previousBackingTracks = @previousAllTracks.backingTracks + metronomeTracks = trackInfo.metronomeTracks + previousMetronomeTracks = @previousAllTracks.metronomeTracks + # the way we know if backing tracks changes, or recordings are opened, is via this event. + # but we want to report to the user when backing tracks change; so we need to detect change on our own + if !(previousBackingTracks.length == 0 && backingTracks.length == 0) && previousBackingTracks != backingTracks + logger.debug("backing tracks changed", previousBackingTracks, backingTracks) + MixerActions.syncTracks() + else if !(previousMetronomeTracks.length == 0 && metronomeTracks.length == 0) && previousMetronomeTracks != metronomeTracks + logger.debug("metronome state changed ", previousMetronomeTracks, metronomeTracks) + MixerActions.syncTracks() + else + @refreshCurrentSession(true) + + @previousAllTracks = trackInfo + + else if text == 'Global Peer Input Mixer Mode' + MixerActions.mixerModeChanged(MIX_MODES.MASTER) + + else if text == 'Local Peer Stream Mixer Mode' + MixerActions.mixerModeChanged(MIX_MODES.PERSONAL) onJoinSession: (sessionId) -> @@ -349,7 +369,7 @@ SessionActions = @SessionActions @requestingSessionRefresh = false if @pendingSessionRefresh # and when the request is done, if we have a pending, fire it off again - pendingSessionRefresh = false + @pendingSessionRefresh = false @refreshCurrentSessionRest(force) ) @@ -389,11 +409,11 @@ SessionActions = @SessionActions for client_id, participant of newParticipantIds # grow the 'all participants seen' list - unless (client_id in @participantsEverSeen) + unless (client_id of @participantsEverSeen) @participantsEverSeen[client_id] = participant; - if client_id in oldParticipantIds + if client_id of oldParticipantIds # if the participant is here now, and here before, there is still a chance we missed a # very fast leave/join. So check if joined_session_at is different if oldParticipantIds[client_id].joined_session_at != participant.joined_session_at @@ -403,7 +423,7 @@ SessionActions = @SessionActions joins.push(participant); for client_id, participant of oldParticipantIds - unless (client_id in newParticipantIds) + unless (client_id of newParticipantIds) # old participant id that's not in new participant ids: Leave leaves.push(participant); diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js index 8a30cc099..1a11989bc 100644 --- a/web/app/assets/javascripts/utils.js +++ b/web/app/assets/javascripts/utils.js @@ -215,7 +215,7 @@ * @param text * @param options */ - context.JK.interactReactBubble = function($element, reactElementName, reactProps, options) { + context.JK.interactReactBubble = function($element, reactElementName, reactPropsCallback, options) { if(!options) options = {}; @@ -248,7 +248,7 @@ if(!reactElementName) { throw "unknown react element" + reactElementName } - var element = React.createElement(reactElement, reactProps); + var element = React.createElement(reactElement, reactPropsCallback()); var $container = $(container) diff --git a/web/app/assets/stylesheets/client/react-components/SessionScreen.css.scss b/web/app/assets/stylesheets/client/react-components/SessionScreen.css.scss index 8796f4553..f8de208a1 100644 --- a/web/app/assets/stylesheets/client/react-components/SessionScreen.css.scss +++ b/web/app/assets/stylesheets/client/react-components/SessionScreen.css.scss @@ -73,21 +73,38 @@ margin: 0; } - .session-my-tracks { - .session-track { - float:left; - margin: 10px 0; + .session-track { + float:left; + margin: 10px 0; + + color: $ColorTextTypical; + background-color: #242323; + border-radius: 6px; + min-height: 76px; + max-width: 210px; + position:relative; + @include border_box_sizing; + + .session-track-contents { padding: 6px 6px 6px 10px; - color: $ColorTextTypical; - background-color: #242323; + } + .disabled-track-overlay { + width: 0; + height: 0; + position: absolute; + background-color:#555; border-radius: 6px; - min-height: 76px; - max-width: 210px; - @include border_box_sizing; + } + + &.no-mixer { + .disabled-track-overlay { + width: 100%; + height: 100%; + opacity:0.5; + } } } - .react-holder { &.SessionTrackVolumeHover { height:331px; @@ -231,6 +248,12 @@ } } + .when-empty { + margin-top:20px; + margin-left:22px; + color:$ColorTextTypical; + overflow:hidden; + } .session-track { @@ -337,6 +360,8 @@ .session-track-settings { height:18px; cursor:pointer; + color:white; + padding-bottom:1px; // to line up with SessionOtherTracks span { top: -4px; @@ -344,4 +369,17 @@ left:3px; } } + + .session-invite-musicians { + height:19px; + cursor: pointer; + color:white; + + span { + top:-5px; + position:relative; + left:3px; + } + + } } \ No newline at end of file diff --git a/web/app/assets/stylesheets/minimal/minimal.css.scss b/web/app/assets/stylesheets/minimal/minimal.css.scss index f97d05c7f..f159f3f0d 100644 --- a/web/app/assets/stylesheets/minimal/minimal.css.scss +++ b/web/app/assets/stylesheets/minimal/minimal.css.scss @@ -5,5 +5,6 @@ *= require client/screen_common *= require client/content *= require client/ftue +*= require minimal/recording_controls *= require minimal/minimal_main */ \ No newline at end of file diff --git a/web/app/assets/stylesheets/minimal/recording_controls.css.scss b/web/app/assets/stylesheets/minimal/recording_controls.css.scss new file mode 100644 index 000000000..1ba110ca7 --- /dev/null +++ b/web/app/assets/stylesheets/minimal/recording_controls.css.scss @@ -0,0 +1,6 @@ +body.recording-controls { + width:100%; + height:100%; + background-color:#404040; + overflow: hidden !important; +} \ No newline at end of file diff --git a/web/app/controllers/popups_controller.rb b/web/app/controllers/popups_controller.rb new file mode 100644 index 000000000..e05e2f8ee --- /dev/null +++ b/web/app/controllers/popups_controller.rb @@ -0,0 +1,9 @@ +class PopupsController < ApplicationController + + respond_to :html + + def recording_controls + render :layout => "minimal" + end + +end \ No newline at end of file diff --git a/web/app/views/layouts/minimal.html.erb b/web/app/views/layouts/minimal.html.erb index 411b792c5..3a5ad3ea9 100644 --- a/web/app/views/layouts/minimal.html.erb +++ b/web/app/views/layouts/minimal.html.erb @@ -18,7 +18,7 @@ <% end %> <%= render "shared/ad_sense" %> - +
<%= javascript_include_tag "minimal/minimal" %>
diff --git a/web/app/views/popups/recording_controls.html.slim b/web/app/views/popups/recording_controls.html.slim new file mode 100644 index 000000000..531396f40 --- /dev/null +++ b/web/app/views/popups/recording_controls.html.slim @@ -0,0 +1,11 @@ +- provide(:page_name, 'recording-controls') +.recording-controls + | IM HERE + +javascript: + window.bling = function () { + alert("bling!!") + window.opener.callMe() + } + + console.log("window.opener", window.opener) \ No newline at end of file diff --git a/web/config/routes.rb b/web/config/routes.rb index 7be4d9f68..72437c717 100644 --- a/web/config/routes.rb +++ b/web/config/routes.rb @@ -135,6 +135,10 @@ SampleApp::Application.routes.draw do # admin-only page to control settings match '/extras/settings', to: 'extras#settings' + scope '/popups' do + match '/session/:id/recording-controls', to: 'popups#recording_controls' + end + scope '/corp' do # about routes match '/about', to: 'corps#about', as: 'corp_about'