From b686020b496fa277d5b1019372dac0ef74e6ad58 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Mon, 26 Oct 2015 20:20:26 -0500 Subject: [PATCH 01/15] * wip --- .../javascripts/configureTracksHelper2.js | 249 +----------------- .../dialog/configureTrackDialog.js | 4 +- .../assets/javascripts/react-components.js | 1 + .../ConfigureTracks.js.jsx.coffee | 18 ++ .../actions/ConfigureTracksActions.js.coffee | 5 + .../stores/ConfigureTracksStore.js.coffee | 37 +++ .../_configure_tracks_dialog.html.haml | 26 +- 7 files changed, 65 insertions(+), 275 deletions(-) create mode 100644 web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee create mode 100644 web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee create mode 100644 web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee diff --git a/web/app/assets/javascripts/configureTracksHelper2.js b/web/app/assets/javascripts/configureTracksHelper2.js index 7c4f07128..57111335b 100644 --- a/web/app/assets/javascripts/configureTracksHelper2.js +++ b/web/app/assets/javascripts/configureTracksHelper2.js @@ -22,136 +22,7 @@ var $instrumentsHolder = null; var isDragging = false; - function removeHoverer($hoverChannel) { - var $channel = $hoverChannel.data('original') - $channel.data('cloned', null); - $hoverChannel.remove(); - } - function hoverIn($channel) { - if(isDragging) return; - - var $container = $channel.closest('.target'); - var inTarget = $container.length > 0; - if(!inTarget) { - $container = $channel.closest('.channels-holder') - } - - var $inputs = $container.find('.ftue-input'); - - var index = $inputs.index($channel); - // $channel.css('padding', '0 5px'); - if(inTarget) { - $channel.data('container', $container) - $channel.addClass('hovering'); - $channel.css('color', 'white') - $channel.css('background-color', '#333'); - $channel.css('border', '#333'); - $channel.css('border-radius', '2px'); - $channel.css('min-width', '49%'); - $channel.css('width', 'auto'); - $channel.css('position', 'absolute'); - $container.css('overflow', 'visible'); - } - else { - var $offsetParent = $channel.offsetParent(); - var parentOffset = $offsetParent.offset(); - - var hoverChannel = $(context._.template($templateAssignablePort.html(), {id: 'bogus', name: $channel.text(), direction: 'bogus'}, { variable: 'data' })); - hoverChannel - .css('position', 'absolute') - .css('color', 'white') - .css('left', $channel.position().left) - .css('top', $channel.position().top) - .css('background-color', '#333') - .css('min-width', $channel.width()) - .css('min-height', $channel.height()) - .css('z-index', 10000) - .css('background-position', '4px 6px') - .css('padding-left', '14px') - .data('original', $channel); - - $channel.data('cloned', hoverChannel); - hoverChannel - .hover(function(e) { - var hoverCheckTimeout = hoverChannel.data('hoverCheckTimeout'); - if(hoverCheckTimeout) { - clearTimeout(hoverCheckTimeout); - hoverChannel.data('hoverCheckTimeout', null); - } - }, function() { removeHoverer($(this)); }) - .mousedown(function(e) { - // because we have obscured the element the user wants to drag, - // we proxy a mousedown on the hover-element to the covered .ftue-input ($channel). - // this causes jquery.drag to get going even though the user clicked a different element - $channel.trigger(e) - }) - hoverChannel.data('hoverCheckTimeout', setTimeout(function() { - // check if element has already been left - hoverChannel.data('hoverCheckTimeout', null); - removeHoverer(hoverChannel); - }, 500)); - hoverChannel.prependTo($offsetParent); - } - - $channel.css('z-index', 10000) - if(inTarget && $inputs.length == 2) { - - if(index == 0) { - $channel.css('right', '50%') - } - else { - $channel.css('left', '51%') - } - } - - } - - function hoverOut($channel) { - - var $cloned = $channel.data('cloned'); - if($cloned) { - return; // let the cloned handle the rest of hover out logic when it's hovered-out - } - - $channel - .removeClass('hovering') - .css('color', '') - .css('font-weight', '') - .css('position', '') - .css('width', '') - .css('background-color', '') - .css('padding', '') - .css('padding-left', '') - .css('background-position', '') - .css('border', '') - .css('border-radius', '') - .css('right', '') - .css('left', '') - .css('min-width', '') - .css('z-index', '') - .css('margin-left', '') - .css('max-width', 'auto'); - - //var $container = $channel.closest('.target'); - var $container = $channel.data('container'); - if($container) { - $container.css('overflow', '') - } - } - - function fixClone($clone) { - $clone - .css('color', '') - .css('font-weight', '') - .css('width', 'auto') - .css('background-color', '') - .css('padding', '') - .css('border', '') - .css('border-radius', '') - .css('right', '') - .css('min-width', '') - } // inputChannelFilter is an optional argument that is used by the Gear Wizard. // basically, if an input channel isn't in there, it's not going to be displayed @@ -176,11 +47,6 @@ var $channel = $(context._.template($templateAssignablePort.html(), $.extend({}, inputChannel, {direction:'in'}), { variable: 'data' })); - $channel.hover( - function() { hoverIn ($(this)) }, - function() { hoverOut($(this)) } - ); - if(forceInputsToUnassign || inputChannel.assignment == ASSIGNMENT.UNASSIGNED) { unassignInputChannel($channel); } @@ -205,10 +71,7 @@ context._.each(outputChannels, function (outputChannel, index) { var $channel = $(context._.template($templateAssignablePort.html(), $.extend({}, outputChannel, {direction:'out'}), { variable: 'data' })); - $channel.hover( - function() { hoverIn ($(this)) }, - function() { hoverOut($(this)) } - ); + if(outputChannel.assignment == ASSIGNMENT.UNASSIGNED) { unassignOutputChannel($channel); @@ -223,29 +86,6 @@ } addChannelToOutput($channel, $output.find('.output-target')); } - - $channel.draggable({ - helper: 'clone', - start: function(e,ui) { - isDragging = true; - var $channel = $(this); - fixClone(ui.helper); - var $output = $channel.closest('.output-target'); - var isUnassigned = $output.length == 0; - if(isUnassigned) { - $outputChannelHolder.find('.output-target').addClass('possible-target'); - } - else { - $outputChannelHolder.find('.output-target').addClass('possible-target'); - $unassignedOutputsHolder.addClass('possible-target'); - } - }, - stop: function() { - isDragging = false; - $outputChannelHolder.find('.output-target').removeClass('possible-target'); - $unassignedOutputsHolder.removeClass('possible-target') - } - }); }); } @@ -439,93 +279,6 @@ $originallyAssignedTrack.attr('output-count', $originallyAssignedTrack.find('.ftue-input:not(.ui-draggable-dragging)').length) } - - function initializeUnassignedOutputDroppable() { - $unassignedOutputsHolder.droppable( - { - accept: '.ftue-input[data-direction="out"]', - activeClass: 'drag-in-progress', - hoverClass: 'drag-hovering', - drop: function( event, ui ) { - var $channel = ui.draggable; - - //$channel.css('left', '0').css('top', '0'); - unassignOutputChannel($channel); - } - }); - } - - function initializeUnassignedInputDroppable() { - $unassignedInputsHolder.droppable( - { - accept: '.ftue-input[data-direction="in"]', - activeClass: 'drag-in-progress', - hoverClass: 'drag-hovering', - drop: function( event, ui ) { - var $channel = ui.draggable; - //$channel.css('left', '0').css('top', '0'); - unassignInputChannel($channel); - } - }); - } - - function initializeOutputDroppables() { - var i; - for(i = 0; i < MAX_OUTPUTS; i++) { - var $target = $(context._.template($templateOutputTarget.html(), {num: i }, { variable: 'data' })); - $outputChannelHolder.append($target); - $target.find('.output-target').droppable( - { - accept: '.ftue-input[data-direction="out"]', - activeClass: 'drag-in-progress', - hoverClass: 'drag-hovering', - drop: function( event, ui ) { - var $slot = $(this); - if($slot.attr('output-count') == 1) { - return false; // max of 1 output per slot - } - var $channel = ui.draggable; - //$channel.css('left', '0').css('top', '0'); - addChannelToOutput($channel, $slot); - } - }); - } - } - - function initializeTrackDroppables() { - var i; - for(i = 0; i < MAX_TRACKS; i++) { - var $target = $(context._.template($templateTrackTarget.html(), {num: i }, { variable: 'data' })); - $tracksHolder.append($target); - $target.find('.track-target').droppable( - { - accept: '.ftue-input[data-direction="in"]', - activeClass: 'drag-in-progress', - hoverClass: 'drag-hovering', - drop: function( event, ui ) { - var $track = $(this); - if($track.attr('track-count') == 2) { - return false; // max of 2 inputs per track - } - - var $channel = ui.draggable; - //$channel.css('left', '0').css('top', '0'); - addChannelToTrack($channel, $track); - } - }); - } - } - - function initializeInstrumentDropdown() { - var i; - for(i = 0; i < MAX_TRACKS; i++) { - var $root = $('
'); - $root.instrumentSelector().attr('data-num', i); - $instrumentsHolder.append($root); - } - } - - function initialize(_$parent) { $parent = _$parent; diff --git a/web/app/assets/javascripts/dialog/configureTrackDialog.js b/web/app/assets/javascripts/dialog/configureTrackDialog.js index 20801cfa6..12558b064 100644 --- a/web/app/assets/javascripts/dialog/configureTrackDialog.js +++ b/web/app/assets/javascripts/dialog/configureTrackDialog.js @@ -247,8 +247,8 @@ $btnAddNewGear = $dialog.find('.btn-add-new-audio-gear'); $btnUpdateTrackSettings = $dialog.find('.btn-update-settings'); - configureTracksHelper = new context.JK.ConfigureTracksHelper(app); - configureTracksHelper.initialize($dialog); + //configureTracksHelper = new context.JK.ConfigureTracksHelper(app); + //configureTracksHelper.initialize($dialog); voiceChatHelper = new context.JK.VoiceChatHelper(app); voiceChatHelper.initialize($dialog, 'configure_track_dialog', true, {vuType: "vertical", lightCount: 10, lightWidth: 3, lightHeight: 17}, 191); diff --git a/web/app/assets/javascripts/react-components.js b/web/app/assets/javascripts/react-components.js index ff86ff8e6..a0d400953 100644 --- a/web/app/assets/javascripts/react-components.js +++ b/web/app/assets/javascripts/react-components.js @@ -3,6 +3,7 @@ //= require_directory ./react-components/helpers //= require_directory ./react-components/actions //= require ./react-components/stores/AppStore +//= require ./react-components/stores/ConfigureTracksStore //= require ./react-components/stores/BrowserMediaStore //= require ./react-components/stores/RecordingStore //= require ./react-components/stores/VideoStore diff --git a/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee new file mode 100644 index 000000000..19de40dc0 --- /dev/null +++ b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee @@ -0,0 +1,18 @@ +context = window +rest = context.JK.Rest() +ReactCSSTransitionGroup = React.addons.CSSTransitionGroup +MIX_MODES = context.JK.MIX_MODES + +@ConfigureTracks = React.createClass({ + + mixins: [Reflux.listenTo(@ConfigureTrackStore,"onConfigureTracksChanged")] + + onConfigureTrackChanged: (state) -> + @setState({configureTracks: state) + + render: () -> + + `
+ +
` +}) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee new file mode 100644 index 000000000..551f91773 --- /dev/null +++ b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee @@ -0,0 +1,5 @@ +context = window + +@ConfigureTracksActions = Reflux.createActions({ + reset: {} +}) diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee new file mode 100644 index 000000000..0b52520a0 --- /dev/null +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -0,0 +1,37 @@ +$ = jQuery +context = window +logger = context.JK.logger + +@ConfigureTracksStore = Reflux.createStore( + { + listenables: @ConfigureTracksActions + + musicPorts: {inputs:[], outputs:[]} + + init: () -> + this.listenTo(context.AppStore, this.onAppInit); + + onAppInit: (@app) -> + + onReset: () -> + logger.debug("ConfigureTracksStore:reset") + @loadChannels() + + + onTrySave: () -> + logger.debug("ConfigureTracksStore:trySave") + + changed: () -> + @state = {musicPorts: @musicPorts} + + loadChannels: (forceInputsToUnassign, inputChannelFilter) -> + # inputChannelFilter is an optional argument that is used by the Gear Wizard. + # basically, if an input channel isn't in there, it's not going to be displayed + @musicPorts = context.jamClient.FTUEGetChannels() + + @changed() + + + + } +) \ No newline at end of file diff --git a/web/app/views/dialogs/_configure_tracks_dialog.html.haml b/web/app/views/dialogs/_configure_tracks_dialog.html.haml index 5611533d1..cb65af8eb 100644 --- a/web/app/views/dialogs/_configure_tracks_dialog.html.haml +++ b/web/app/views/dialogs/_configure_tracks_dialog.html.haml @@ -16,32 +16,8 @@ .tab.no-selection-range{'tab-id' => 'music-audio'} - .column - .certified-audio-profile-section - .sub-header Certified Audio Profile - %select.certified-audio-profile - .clearall + = react_component 'ConfigureTracks', {} - .unused-audio-inputs-section - .sub-header Unused Input Ports - .unassigned-input-channels.channels-holder - - .unused-audio-outputs-section - .sub-header Unused Output Ports - .unassigned-output-channels.channels-holder - - .column - .input-tracks-section - .sub-column - .sub-header Track Input Port(s) - .input-tracks.tracks - .sub-column - .sub-header Instrument - .instruments - - .output-channels-section - .sub-header Audio Output Port - .output-channels .clearall From 52524c774de6701a97b529a35ae2d937a318cacf Mon Sep 17 00:00:00 2001 From: Seth Call Date: Tue, 27 Oct 2015 09:19:14 -0500 Subject: [PATCH 02/15] * wip --- .../javascripts/configureTracksHelper2.js | 16 -------- .../dialog/configureTrackDialog.js | 12 +++--- .../ConfigureTracks.js.jsx.coffee | 34 ++++++++++++--- .../actions/ConfigureTracksActions.js.coffee | 1 + .../stores/ConfigureTracksStore.js.coffee | 41 ++++++++++++++++--- 5 files changed, 71 insertions(+), 33 deletions(-) diff --git a/web/app/assets/javascripts/configureTracksHelper2.js b/web/app/assets/javascripts/configureTracksHelper2.js index 57111335b..d87319a53 100644 --- a/web/app/assets/javascripts/configureTracksHelper2.js +++ b/web/app/assets/javascripts/configureTracksHelper2.js @@ -282,22 +282,6 @@ function initialize(_$parent) { $parent = _$parent; - $templateAssignablePort = $('#template-assignable-port'); - $templateTrackTarget = $('#template-track-target'); - $templateOutputTarget = $('#template-output-target'); - $unassignedInputsHolder = $parent.find('.unassigned-input-channels') - $unassignedOutputsHolder = $parent.find('.unassigned-output-channels'); - $tracksHolder = $parent.find('.tracks'); - $instrumentsHolder = $parent.find('.instruments'); - $outputChannelHolder = $parent.find('.output-channels'); - - - initializeUnassignedInputDroppable(); - initializeTrackDroppables(); - initializeInstrumentDropdown(); - - initializeUnassignedOutputDroppable(); - initializeOutputDroppables(); } this.initialize = initialize; diff --git a/web/app/assets/javascripts/dialog/configureTrackDialog.js b/web/app/assets/javascripts/dialog/configureTrackDialog.js index 12558b064..6720df09f 100644 --- a/web/app/assets/javascripts/dialog/configureTrackDialog.js +++ b/web/app/assets/javascripts/dialog/configureTrackDialog.js @@ -91,7 +91,7 @@ } function validateAudioSettings() { - return configureTracksHelper.trySave(); + return window.ConfigureTracksActions.trySave(); } function showVoiceChatPanel() { @@ -103,7 +103,7 @@ $musicAudioTabSelector.click(function () { // validate voice chat settings if (validateVoiceChatSettings()) { - configureTracksHelper.reset(); + window.ConfigureTracksActions.reset(); voiceChatHelper.reset(); showMusicAudioPanel(); } @@ -113,7 +113,7 @@ // validate audio settings if (validateAudioSettings()) { logger.debug("initializing voice chat helper") - configureTracksHelper.reset(); + window.ConfigureTracksActions.reset(); voiceChatHelper.reset(); showVoiceChatPanel(); } @@ -133,7 +133,7 @@ //}); $btnUpdateTrackSettings.click(function() { - if(configureTracksHelper.trySave() && voiceChatHelper.trySave()) { + if(window.ConfigureTracksActions.trySave() && voiceChatHelper.trySave()) { app.layout.closeDialog('configure-tracks'); } @@ -183,7 +183,7 @@ currentProfile = profile; - configureTracksHelper.reset(); + window.ConfigureTracksActions.reset(); } function beforeShow() { @@ -207,7 +207,7 @@ return; } - configureTracksHelper.reset(); + window.ConfigureTracksActions.reset(); voiceChatHelper.reset(); voiceChatHelper.beforeShow(); } diff --git a/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee index 19de40dc0..5c9bae882 100644 --- a/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee @@ -1,18 +1,42 @@ context = window rest = context.JK.Rest() ReactCSSTransitionGroup = React.addons.CSSTransitionGroup -MIX_MODES = context.JK.MIX_MODES +ASSIGNMENT = context.JK.ASSIGNMENT +VOICE_CHAT = context.JK.VOICE_CHAT +MAX_TRACKS = context.JK.MAX_TRACKS +MAX_OUTPUTS = context.JK.MAX_OUTPUTS +gearUtils = context.JK.GearUtils @ConfigureTracks = React.createClass({ - mixins: [Reflux.listenTo(@ConfigureTrackStore,"onConfigureTracksChanged")] + mixins: [Reflux.listenTo(@ConfigureTracksStore,"onConfigureTracksChanged")] - onConfigureTrackChanged: (state) -> - @setState({configureTracks: state) + getInitialState: () -> + {configureTracks: null} + + onConfigureTracksChanged: (configureTracks) -> + @setState({configureTracks: configureTracks}) render: () -> + console.log("@state.configureTracks", @state.configureTracks) + + liveTracks = [] + + trackAssignments = @state.configureTracks?.trackAssignments + + if trackAssignments + + for track in trackAssignments.inputs.assigned + + + + `
- + +

Session Audio Inputs (Live Performance Tracks)

+ {liveTracks} + +
` }) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee index 551f91773..0afa11498 100644 --- a/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee +++ b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee @@ -2,4 +2,5 @@ context = window @ConfigureTracksActions = Reflux.createActions({ reset: {} + trySave: {} }) diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index 0b52520a0..03f74afd3 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -1,10 +1,15 @@ $ = jQuery context = window logger = context.JK.logger +ASSIGNMENT = context.JK.ASSIGNMENT +VOICE_CHAT = context.JK.VOICE_CHAT +MAX_TRACKS = context.JK.MAX_TRACKS +MAX_OUTPUTS = context.JK.MAX_OUTPUTS +gearUtils = context.JK.GearUtils @ConfigureTracksStore = Reflux.createStore( { - listenables: @ConfigureTracksActions + listenables: ConfigureTracksActions musicPorts: {inputs:[], outputs:[]} @@ -14,24 +19,48 @@ logger = context.JK.logger onAppInit: (@app) -> onReset: () -> - logger.debug("ConfigureTracksStore:reset") + logger.debug("ConfigureTracksStore:reset", this) @loadChannels() onTrySave: () -> logger.debug("ConfigureTracksStore:trySave") + @trySave() + + trySave: () -> changed: () -> - @state = {musicPorts: @musicPorts} + @item = {musicPorts: @musicPorts, trackAssignments: @trackAssignments} + + @trigger(@item) loadChannels: (forceInputsToUnassign, inputChannelFilter) -> # inputChannelFilter is an optional argument that is used by the Gear Wizard. # basically, if an input channel isn't in there, it's not going to be displayed @musicPorts = context.jamClient.FTUEGetChannels() + @trackAssignments = {inputs: {unassigned:[], assigned:[], chat:[]}, outputs: {unassigned:[], assigned: []}} + for input in @musicPorts.inputs + if input.assigment == ASSIGNMENT.UNASSIGNED + @trackAssignments.inputs.unassigned.push(input) + else if input.assignment == ASSIGNMENT.CHAT + @trackAssignments.inputs.chat.push(input) + else + # make sure this assignment isn't already preset (you can have multiple inputs per 'track slot') + found = false + for assigned in @trackAssignments.inputs.assigned + if assigned[0].assignment == input.assignment + assigned.push(input) + found = true + + if !found + @trackAssignments.inputs.assigned.push([input]) + for output in @musiPorts.outputs + if output.assignment == ASSIGNMENT.OUTPUT + @trackAssignments.outputs.assigned.push(output) + else + @trackAssignments.outputs.unassigned.push(output) + @changed() - - - } ) \ No newline at end of file From f7267d38c6758d50b30f2aa82512b075285bbb5e Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 30 Oct 2015 09:59:50 -0500 Subject: [PATCH 03/15] * wip --- .../dialog/configureTrackDialog.js | 3 + web/app/assets/javascripts/fakeJamClient.js | 6 + .../ConfigureLiveTracksDialog.js.jsx.coffee | 68 ++++++++++ .../ConfigureTracks.js.jsx.coffee | 69 +++++++++- .../actions/ConfigureTracksActions.js.coffee | 2 + .../stores/ConfigureTracksStore.js.coffee | 51 ++++++- web/app/assets/javascripts/utils.js | 4 + .../react-components/ConfigureTracks.css.scss | 126 ++++++++++++++++++ .../configureLiveTracksDialog.css.scss | 25 ++++ .../_configureLiveTracksDialog.html.slim | 6 + web/app/views/dialogs/_dialogs.html.haml | 1 + 11 files changed, 349 insertions(+), 12 deletions(-) create mode 100644 web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee create mode 100644 web/app/assets/stylesheets/client/react-components/ConfigureTracks.css.scss create mode 100644 web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss create mode 100644 web/app/views/dialogs/_configureLiveTracksDialog.html.slim diff --git a/web/app/assets/javascripts/dialog/configureTrackDialog.js b/web/app/assets/javascripts/dialog/configureTrackDialog.js index 6720df09f..5c631e196 100644 --- a/web/app/assets/javascripts/dialog/configureTrackDialog.js +++ b/web/app/assets/javascripts/dialog/configureTrackDialog.js @@ -214,6 +214,9 @@ function afterShow() { sessionUtils.SessionPageEnter(); + + context.ConfigureTracksActions.vstScan(); + } function onCancel() { diff --git a/web/app/assets/javascripts/fakeJamClient.js b/web/app/assets/javascripts/fakeJamClient.js index 077ad4ced..26fcb4cc3 100644 --- a/web/app/assets/javascripts/fakeJamClient.js +++ b/web/app/assets/javascripts/fakeJamClient.js @@ -1052,6 +1052,10 @@ function GetAutoStart() { return true; } function SaveSettings() {} + + function VSTScan(callback) {setTimeout(eval(callback+ "()"), 1000)} + function hasVstHost() { return false;} + // Javascript Bridge seems to camel-case // Set the instance functions: this.AbortRecording = AbortRecording; @@ -1315,6 +1319,8 @@ this.StopNetworkTest = StopNetworkTest; this.log = log; this.getOperatingMode = getOperatingMode; + this.VSTScan = VSTSCan; + this.hasVstHost = hasVstHost; this.clientID = "devtester"; }; diff --git a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee new file mode 100644 index 000000000..387d1a59f --- /dev/null +++ b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee @@ -0,0 +1,68 @@ +context = window +ConfigureTracksStore = @ConfigureTracksStore +@ConfigureLiveTracksDialog = React.createClass({ + + mixins: [Reflux.listenTo(@ConfigureTracksStore,"onConfigureTracksChanged")] + + onConfigureTracksChanged:(configureTracks) -> + @setState({configureTracks: configureTracks}) + + getInitialState: () -> + {configureTracks: null} + + render: () -> + + inputOneOptions = [] + inputTwoOptions = [] + + defaultSelectionOne = `` + defaultSelectionTwo = `` + + inputOneOptions.push(defaultSelectionOne) + inputTwoOptions.push(defaultSelectionTwo) + + instruments = [] + for displayName, value of context.JK.server_to_client_instrument_map + instruments.push(``) + + if @state.configureTracks? + for input in @state.configureTracks.musicPorts.inputs + item = `` + inputOneOptions.push(item) + inputTwoOptions.push(item) + + `
+
+

Track Type

+ + +
+ +
+

Audio Input Ports

+

Select one or two inputs ports to assign to this track. Note that if you assign a single input port, the app will automatically duplicate this port into a stereo track.

+ + +
+
+

Instrument

+ +
+
+

Audio Effects (optional)

+ +
+
` + + componentDidMount: () -> + $root = $(@getDOMNode()) + context.JK.checkbox($root.find('input[type="checkbox"]')) +}) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee index 5c9bae882..e6256f4f3 100644 --- a/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee @@ -22,21 +22,78 @@ gearUtils = context.JK.GearUtils console.log("@state.configureTracks", @state.configureTracks) liveTracks = [] + outputs = [] trackAssignments = @state.configureTracks?.trackAssignments if trackAssignments - for track in trackAssignments.inputs.assigned + for inputsForTrack in trackAssignments.inputs.assigned + candidate = inputsForTrack[0] + inputs = [] + for input in inputsForTrack + inputs.push(`
{input.name}
`) + if !inputsForTrack.instrument_id? + instrument = `?` + else + instrument = `` + liveTracks.push( + `
+
{candidate.assignment}:{inputs}
+
None
+
{instrument}
+
+ update + delete +
+
`) - `
+ for output, i in trackAssignments.outputs.assigned + outputs.push( + `
+
{i + 1}:
{output.name}
+
`) + + `
-

Session Audio Inputs (Live Performance Tracks)

- {liveTracks} - - +
+
+

Session Audio Inputs (Live Performance Tracks)

+

Plugin

+

Instrument

+
+
+ {liveTracks} +
+ ADD A LIVE TRACK . . . +
+
+
+

Session Audio Outputs (Requires 2 Ports)

+
+ {outputs} +
+ UPDATE OUTPUTS . . . +
+
` + + onUpdateLiveTrack:(liveTrack, e) -> + e.preventDefault() + + onDeleteLiveTrack:(liveTrack, e) -> + e.preventDefault() + + openLiveTrackDialog: (e) -> + e.preventDefault() + + context.JK.app.layout.showDialog('configure-live-tracks-dialog') + + openOutputTrackDialog: (e) -> + e.preventDefault() + + context.JK.app.layout.app.showDialog('configure-output-tracks-dialog') }) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee index 0afa11498..b4448c579 100644 --- a/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee +++ b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee @@ -3,4 +3,6 @@ context = window @ConfigureTracksActions = Reflux.createActions({ reset: {} trySave: {} + vstScan: {} + vstScanComplete: {} }) diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index 03f74afd3..93e842ff1 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -12,9 +12,11 @@ gearUtils = context.JK.GearUtils listenables: ConfigureTracksActions musicPorts: {inputs:[], outputs:[]} + trackNumber: null + editingTrack: null + init: () -> - this.listenTo(context.AppStore, this.onAppInit); onAppInit: (@app) -> @@ -29,8 +31,19 @@ gearUtils = context.JK.GearUtils trySave: () -> + onVstScan: () -> + hasVst = context.jamClient.hasVstHost() + logger.debug("hasVst", hasVst) + if hasVst + logger.debug("vstScan starting") + result = context.jamClient.VSTScan() + logger.debug("vstScan completed", result) + + + onVstScanComplete:() -> + changed: () -> - @item = {musicPorts: @musicPorts, trackAssignments: @trackAssignments} + @item = {musicPorts: @musicPorts, trackAssignments: @trackAssignments, trackNumber: @trackNumber, editingTrack: @editingTrack} @trigger(@item) @@ -39,9 +52,11 @@ gearUtils = context.JK.GearUtils # basically, if an input channel isn't in there, it's not going to be displayed @musicPorts = context.jamClient.FTUEGetChannels() + # let's populate this bad boy @trackAssignments = {inputs: {unassigned:[], assigned:[], chat:[]}, outputs: {unassigned:[], assigned: []}} + for input in @musicPorts.inputs - if input.assigment == ASSIGNMENT.UNASSIGNED + if input.assignment == ASSIGNMENT.UNASSIGNED @trackAssignments.inputs.unassigned.push(input) else if input.assignment == ASSIGNMENT.CHAT @trackAssignments.inputs.chat.push(input) @@ -49,18 +64,42 @@ gearUtils = context.JK.GearUtils # make sure this assignment isn't already preset (you can have multiple inputs per 'track slot') found = false for assigned in @trackAssignments.inputs.assigned - if assigned[0].assignment == input.assignment + if assigned.assignment == input.assignment assigned.push(input) found = true if !found - @trackAssignments.inputs.assigned.push([input]) - for output in @musiPorts.outputs + initial = [input] + initial.assignment = input.assignment # store the assignment on the array itself, so we don't have to check inside the array for an input's assignment (which will all be the same) + @trackAssignments.inputs.assigned.push(initial) + for output in @musicPorts.outputs if output.assignment == ASSIGNMENT.OUTPUT @trackAssignments.outputs.assigned.push(output) else @trackAssignments.outputs.unassigned.push(output) + @loadTrackInstruments(forceInputsToUnassign) @changed() + + loadTrackInstruments: (forceInputsToUnassign) -> + for inputsForTrack in @trackAssignments.inputs.assigned + clientInstrument = context.jamClient.TrackGetInstrument(inputsForTrack[0].assignment) + + instrument = context.JK.client_to_server_instrument_map[clientInstrument]; + + inputsForTrack.instrument_id = instrument?.server_id + + openLiveTrackDialog: (trackNumber) -> + @trackNumber = trackNumber + + @editingTrack = null + for inputsForTrack in @trackAssignments.inputs.assigned + if inputsForTrack.assignment == trackNumber + @editingTrack = inputsForTrack + break + + @changed() + + @app.layout.showDialog('configure-live-tracks-dialog') } ) \ No newline at end of file diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js index 68aa5b692..c25a3292c 100644 --- a/web/app/assets/javascripts/utils.js +++ b/web/app/assets/javascripts/utils.js @@ -733,6 +733,10 @@ return date.toLocaleTimeString(); } + context.JK.iconMapBase = function() { + return icon_map_base + } + context.JK.formatUtcTime = function(date, change) { if (change) { date.setMinutes(Math.ceil(date.getMinutes() / 30) * 30); diff --git a/web/app/assets/stylesheets/client/react-components/ConfigureTracks.css.scss b/web/app/assets/stylesheets/client/react-components/ConfigureTracks.css.scss new file mode 100644 index 000000000..f76f8276d --- /dev/null +++ b/web/app/assets/stylesheets/client/react-components/ConfigureTracks.css.scss @@ -0,0 +1,126 @@ +@import "client/common"; + +.ConfigureTracks { + + .inputs-view { + border-width:1px 0; + border-color:$ColorText; + border-style:solid; + padding:20px 0; + height:220px; + + .live-tracks { + height:150px; + overflow:auto; + a { + margin-left:3px; + } + } + + .live-input { + display:inline-block; + } + .live-track { + margin-bottom:20px; + } + + a.delete-live-track { + margin-left:20px; + } + .assignment { + display:inline-block; + width:20px; + } + + .input-track-info { + @include border_box_sizing; + width:60%; + display:inline-block; + } + + .plugin-info { + @include border_box_sizing; + width:30%; + display:inline-block; + } + + .plugin-instrument { + @include border_box_sizing; + width:10%; + display:inline-block; + text-align:center; + + img { + vertical-align:middle; + } + } + } + + .outputs-view { + border-width:0 0 1px; + border-color:$ColorText; + border-style:solid; + padding:20px 0; + + .assignment { + display:inline-block; + width:20px; + } + + + .output-tracks { + height:73px; + overflow:auto; + a { + margin-left:3px; + } + } + + + .output-track { + margin-bottom: 20px; + } + + .output-track-info { + display:inline-block; + } + + .output { + display:inline-block; + margin-bottom:0 !important; + } + } + h3 { + display:inline-block; + font-size:14px; + margin:0 0 20px; + @include border_box_sizing; + &.session-audio-inputs-header { + color:white; + font-weight:bold; + width:60%; + } + + &.session-audio-outputs-header { + color:white; + font-weight:bold; + width:60%; + } + + &.plugin-header { + width:30%; + } + &.instrument-header { + width:10%; + text-align:center; + } + } + .live-track-actions { + display:block; + padding-left:30px; + margin-top:10px; + a { + font-size:12px; + } + } +} \ No newline at end of file diff --git a/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss new file mode 100644 index 000000000..282c08a2f --- /dev/null +++ b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss @@ -0,0 +1,25 @@ +@import "client/common"; + +#configure-live-tracks-dialog { + width: 800px; + + .track-type { + width:100%; + @include border_box_sizing; + } + .audio-input-ports { + width:50%; + @include border_box_sizing; + float:left; + } + .instrument-selection { + width:50%; + @include border_box_sizing; + float:left; + } + .audio-effects { + width:50%; + @include border_box_sizing; + float:left; + } +} \ No newline at end of file diff --git a/web/app/views/dialogs/_configureLiveTracksDialog.html.slim b/web/app/views/dialogs/_configureLiveTracksDialog.html.slim new file mode 100644 index 000000000..eace5771b --- /dev/null +++ b/web/app/views/dialogs/_configureLiveTracksDialog.html.slim @@ -0,0 +1,6 @@ +.dialog.dialog-overlay-sm.top-parent layout='dialog' layout-id='configure-live-tracks-dialog' id='configure-live-tracks-dialog' + .content-head + = image_tag "content/icon_add.png", {:height => 19, :width => 19, :class => 'content-icon'} + h1 add live track + .dialog-inner + = react_component 'ConfigureLiveTracksDialog', {} diff --git a/web/app/views/dialogs/_dialogs.html.haml b/web/app/views/dialogs/_dialogs.html.haml index 45db4cb3f..761559fdf 100644 --- a/web/app/views/dialogs/_dialogs.html.haml +++ b/web/app/views/dialogs/_dialogs.html.haml @@ -44,3 +44,4 @@ = render 'dialogs/recordingSelectorDialog' = render 'dialogs/soundCloudPlayerDialog' = render 'dialogs/deleteVideoConfirmDialog' += render 'dialogs/configureLiveTracksDialog' \ No newline at end of file From 9e461c61dd7c521a3045f7fe1f417dd9e2882e0e Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 30 Oct 2015 14:43:59 -0500 Subject: [PATCH 04/15] * update deliverable csv for jamtrack users --- admin/app/controllers/email_controller.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/admin/app/controllers/email_controller.rb b/admin/app/controllers/email_controller.rb index 1e0c55182..4c999fd30 100644 --- a/admin/app/controllers/email_controller.rb +++ b/admin/app/controllers/email_controller.rb @@ -15,5 +15,11 @@ class EmailController < ApplicationController headers['Content-Type'] ||= 'text/csv' @users = User.where(subscribe_email: true) + + # if specified, return only users that have redeemed or bought a JamTrack + if params[:any_jam_track] + @users = @users.select('DISTINCT users.id, email, first_name, last_name').joins(:sales => :sale_line_items).where("sale_line_items.product_type = 'JamTrack'") + end + end end \ No newline at end of file From 022fd60b3c953eb92b680e754799a11f579fdabc Mon Sep 17 00:00:00 2001 From: Seth Call Date: Sun, 1 Nov 2015 06:39:51 -0600 Subject: [PATCH 05/15] * wip --- .../dialog/configureTrackDialog.js | 2 +- web/app/assets/javascripts/fakeJamClient.js | 11 ++++- .../ConfigureLiveTracksDialog.js.jsx.coffee | 33 ++++++++++++-- .../stores/ConfigureTracksStore.js.coffee | 38 +++++++++++++--- .../configureLiveTracksDialog.css.scss | 45 +++++++++++++++++++ 5 files changed, 118 insertions(+), 11 deletions(-) diff --git a/web/app/assets/javascripts/dialog/configureTrackDialog.js b/web/app/assets/javascripts/dialog/configureTrackDialog.js index 5c631e196..3b4f478c5 100644 --- a/web/app/assets/javascripts/dialog/configureTrackDialog.js +++ b/web/app/assets/javascripts/dialog/configureTrackDialog.js @@ -215,7 +215,7 @@ function afterShow() { sessionUtils.SessionPageEnter(); - context.ConfigureTracksActions.vstScan(); + //context.ConfigureTracksActions.vstScan(); } diff --git a/web/app/assets/javascripts/fakeJamClient.js b/web/app/assets/javascripts/fakeJamClient.js index 26fcb4cc3..8b1b8477a 100644 --- a/web/app/assets/javascripts/fakeJamClient.js +++ b/web/app/assets/javascripts/fakeJamClient.js @@ -1055,6 +1055,12 @@ function VSTScan(callback) {setTimeout(eval(callback+ "()"), 1000)} function hasVstHost() { return false;} + function getPluginList() { return {vsts:[]} } + + function clearPluginList() {} + function listTrackAssignments() { + return {} + } // Javascript Bridge seems to camel-case // Set the instance functions: @@ -1319,8 +1325,11 @@ this.StopNetworkTest = StopNetworkTest; this.log = log; this.getOperatingMode = getOperatingMode; - this.VSTScan = VSTSCan; + this.VSTScan = VSTScan; this.hasVstHost = hasVstHost; + this.getPluginList = getPluginList; + this.clearPluginList = clearPluginList; + this.listTrackAssignments = listTrackAssignments; this.clientID = "devtester"; }; diff --git a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee index 387d1a59f..308305446 100644 --- a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee @@ -12,6 +12,7 @@ ConfigureTracksStore = @ConfigureTracksStore render: () -> + action = 'ADD TRACK' inputOneOptions = [] inputTwoOptions = [] @@ -31,11 +32,17 @@ ConfigureTracksStore = @ConfigureTracksStore inputOneOptions.push(item) inputTwoOptions.push(item) + + if @state.configureTracks.editingTrack? + action = 'EDIT TRACK' + + vsts = [] + vsts.push(``) `

Track Type

- - +
+
@@ -57,12 +64,30 @@ ConfigureTracksStore = @ConfigureTracksStore

Audio Effects (optional)

+ manage audio plugins + SETTING . . . +
+ +
` + cancel: (e) -> + e.preventDefault() + + update: (e) -> + e.preventDefault() + + vstSettings: (e) -> + e.preventDefault() + ConfigureTracksActions.showVstSettings() + componentDidMount: () -> $root = $(@getDOMNode()) - context.JK.checkbox($root.find('input[type="checkbox"]')) + context.JK.checkbox($root.find('input[type="radio"]')) + }) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index 93e842ff1..dbcb830dd 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -7,6 +7,19 @@ MAX_TRACKS = context.JK.MAX_TRACKS MAX_OUTPUTS = context.JK.MAX_OUTPUTS gearUtils = context.JK.GearUtils +### + + QVariantMap scanForPlugins(); +QVariantMap VSTListVsts(); +void VSTClearAll(); +QVariantMap VSTSetTrackAssignment(const QVariantMap vst, const QString& trackId); +QVariantMap VSTListTrackAssignments(); +void VSTShowHideGui(bool show,const QString& trackId); +void VST_ScanForMidiDevices(); +QVariantMap VST_GetMidiDeviceList(); +bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDeviceIndex); +### + @ConfigureTracksStore = Reflux.createStore( { listenables: ConfigureTracksActions @@ -15,14 +28,17 @@ gearUtils = context.JK.GearUtils trackNumber: null editingTrack: null - init: () -> onAppInit: (@app) -> onReset: () -> logger.debug("ConfigureTracksStore:reset", this) + @trackNumber = null + @editingTrack = null @loadChannels() + @onVstScan() + @onMidiScan() onTrySave: () -> @@ -32,15 +48,26 @@ gearUtils = context.JK.GearUtils trySave: () -> onVstScan: () -> - hasVst = context.jamClient.hasVstHost() - logger.debug("hasVst", hasVst) - if hasVst + @hasVst = context.jamClient.hasVstHost() + logger.debug("hasVst", @hasVst) + if @hasVst logger.debug("vstScan starting") result = context.jamClient.VSTScan() logger.debug("vstScan completed", result) + @vstPluginList = context.jamClient.VSTListVsts() + @vstTrackAssignments = context.jamClient.VSTListTrackAssignments() - onVstScanComplete:() -> + console.log("@vstPluginList", @vstPluginList) + console.log("@vstTrackAssignments", @vstTrackAssignments) + + onMidiScan: () -> + @attachedMidiDevices = context.jamClient.listAttachedMidiDevices(); + + console.log("@attachedMidiDevices", @attachedMidiDevices) + + onShowVstSettings: () -> + context.jamClient.showHideVstGui(true, @trackNumber) if @trackNumber? changed: () -> @item = {musicPorts: @musicPorts, trackAssignments: @trackAssignments, trackNumber: @trackNumber, editingTrack: @editingTrack} @@ -79,6 +106,7 @@ gearUtils = context.JK.GearUtils @trackAssignments.outputs.unassigned.push(output) @loadTrackInstruments(forceInputsToUnassign) + @changed() loadTrackInstruments: (forceInputsToUnassign) -> diff --git a/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss index 282c08a2f..b87510eab 100644 --- a/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss +++ b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss @@ -3,23 +3,68 @@ #configure-live-tracks-dialog { width: 800px; + .dialog-inner { + width:auto; + } + + h3 { + color:white; + font-weight:bold; + margin-bottom:10px; + } + + .actions { + clear:both; + text-align:center; + } .track-type { width:100%; @include border_box_sizing; + margin-bottom:20px; + padding:10px; + + .track-type-option { + margin-bottom:10px; + } + label { + vertical-align:middle; + display:inline-block; + margin-left:10px; + } + .iradio_minimal { + vertical-align:middle; + display:inline-block; + } } .audio-input-ports { width:50%; @include border_box_sizing; float:left; + margin-bottom:40px; + padding:10px; + + select { + width: 90%; + @include border_box_sizing; + margin-bottom:10px; + } + p { + margin-bottom:10px; + line-height:125%; + } } .instrument-selection { width:50%; @include border_box_sizing; float:left; + margin-bottom:40px; + padding:10px; } .audio-effects { width:50%; @include border_box_sizing; float:left; + margin-bottom:20px; + padding:10px; } } \ No newline at end of file From 1da8c7372160452bcd7b289adb4e9eda03ccbf55 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Mon, 9 Nov 2015 15:33:04 -0600 Subject: [PATCH 06/15] * wip --- ruby/lib/jam_ruby/jam_track_importer.rb | 2 +- .../dialog/configureTrackDialog.js | 8 +- web/app/assets/javascripts/globals.js | 4 +- .../assets/javascripts/jquery.manageVsts.js | 71 ++++ .../assets/javascripts/jquery.trackEffects.js | 75 ++++ .../assets/javascripts/react-components.js | 2 +- .../ConfigureAudioTrack.js.jsx.coffee | 0 .../ConfigureLiveTracksDialog.js.jsx.coffee | 367 ++++++++++++++++-- .../ConfigureOutputsDialog.js.jsx.coffee | 87 +++++ .../ConfigureTracks.js.jsx.coffee | 35 +- .../SessionMyTrack.js.jsx.coffee | 38 +- .../SessionMyTracks.js.jsx.coffee | 2 +- .../actions/ConfigureTracksActions.js.coffee | 14 + .../mixins/SessionMyTracksMixin.js.coffee | 28 +- .../stores/ConfigureTracksStore.js.coffee | 288 +++++++++++++- .../stores/SessionStore.js.coffee | 3 + .../wizard/gear/step_configure_tracks.js | 9 +- web/app/assets/stylesheets/client/client.css | 2 + .../stylesheets/client/manageVsts.css.scss | 23 ++ .../react-components/ConfigureTracks.css.scss | 50 ++- .../stylesheets/client/vstEffects.css.scss | 39 ++ .../client/wizard/gearWizard.css.scss | 59 ++- .../configureLiveTracksDialog.css.scss | 103 ++++- .../dialogs/configureOutputsDialog.css.scss | 36 ++ .../dialogs/configureTracksDialog.css.scss | 16 +- web/app/views/clients/_manageVsts.html.slim | 7 + web/app/views/clients/_vstEffects.html.slim | 9 + web/app/views/clients/index.html.erb | 2 + .../wizard/gear/_gear_wizard.html.haml | 11 +- .../_configureLiveTracksDialog.html.slim | 6 +- .../dialogs/_configureOutputsDialog.html.slim | 2 + .../_configure_tracks_dialog.html.haml | 5 +- web/app/views/dialogs/_dialogs.html.haml | 3 +- 33 files changed, 1282 insertions(+), 124 deletions(-) create mode 100644 web/app/assets/javascripts/jquery.manageVsts.js create mode 100644 web/app/assets/javascripts/jquery.trackEffects.js create mode 100644 web/app/assets/javascripts/react-components/ConfigureAudioTrack.js.jsx.coffee create mode 100644 web/app/assets/javascripts/react-components/ConfigureOutputsDialog.js.jsx.coffee create mode 100644 web/app/assets/stylesheets/client/manageVsts.css.scss create mode 100644 web/app/assets/stylesheets/client/vstEffects.css.scss create mode 100644 web/app/assets/stylesheets/dialogs/configureOutputsDialog.css.scss create mode 100644 web/app/views/clients/_manageVsts.html.slim create mode 100644 web/app/views/clients/_vstEffects.html.slim create mode 100644 web/app/views/dialogs/_configureOutputsDialog.html.slim diff --git a/ruby/lib/jam_ruby/jam_track_importer.rb b/ruby/lib/jam_ruby/jam_track_importer.rb index a92aca61b..0cdf0160f 100644 --- a/ruby/lib/jam_ruby/jam_track_importer.rb +++ b/ruby/lib/jam_ruby/jam_track_importer.rb @@ -1352,7 +1352,7 @@ module JamRuby stripped_time = total_time # default to the case where we just start the preview at the beginning burp_gaps.each do |gap| - command_strip_lead_silence = "sox \"#{ogg_44100}\" \"#{out_wav}\" silence 1 #{gap} 1%" + command_strip_lead_silence = "sox \"#{ogg_44100}\" \"#{out_wav}\" silence 1 #{gap} 1%" @@log.debug("stripping silence: " + command_strip_lead_silence) diff --git a/web/app/assets/javascripts/dialog/configureTrackDialog.js b/web/app/assets/javascripts/dialog/configureTrackDialog.js index 3b4f478c5..421cb1d3c 100644 --- a/web/app/assets/javascripts/dialog/configureTrackDialog.js +++ b/web/app/assets/javascripts/dialog/configureTrackDialog.js @@ -50,7 +50,7 @@ function setInstructions(type) { if (type === 'audio') { - $instructions.html('Choose your audio device. Drag and drop to assign input ports to tracks, and specify the instrument for each track. Drag and drop to assign a pair of output ports for session stereo audio monitoring.') + $instructions.html("Click the 'ADD LIVE TRACK' button to add more tracks. You may set up a live track for each instrumental and/or vocal part to perform in sessions. You must also set up exactly two Session Audio Output ports to deliver the stereo audio in your sessions.") return; var os = context.jamClient.GetOSAsString(); $instructions.html(configure_audio_instructions[os]); @@ -91,7 +91,7 @@ } function validateAudioSettings() { - return window.ConfigureTracksActions.trySave(); + return true; } function showVoiceChatPanel() { @@ -133,7 +133,7 @@ //}); $btnUpdateTrackSettings.click(function() { - if(window.ConfigureTracksActions.trySave() && voiceChatHelper.trySave()) { + if(voiceChatHelper.trySave()) { app.layout.closeDialog('configure-tracks'); } @@ -152,7 +152,7 @@ }); $certifiedAudioProfile.html(optionsHtml); - context.JK.dropdown($certifiedAudioProfile); + //context.JK.dropdown($certifiedAudioProfile); } function deviceChanged() { diff --git a/web/app/assets/javascripts/globals.js b/web/app/assets/javascripts/globals.js index c085e548b..86e8972a0 100644 --- a/web/app/assets/javascripts/globals.js +++ b/web/app/assets/javascripts/globals.js @@ -53,7 +53,9 @@ METRONOME_PLAYBACK_MODE_SELECTED: 'metronome_playback_mode_selected', CHECKOUT_SIGNED_IN: 'checkout_signed_in', CHECKOUT_SKIP_SIGN_IN: 'checkout_skip_sign_in', - PREVIEW_PLAYED: 'preview_played' + PREVIEW_PLAYED: 'preview_played', + VST_OPERATION_SELECTED: 'vst_operation_selected', + VST_EFFECT_SELECTED: 'vst_effect_selected' }; context.JK.PLAYBACK_MONITOR_MODE = { diff --git a/web/app/assets/javascripts/jquery.manageVsts.js b/web/app/assets/javascripts/jquery.manageVsts.js new file mode 100644 index 000000000..a14cec2e1 --- /dev/null +++ b/web/app/assets/javascripts/jquery.manageVsts.js @@ -0,0 +1,71 @@ +(function(context, $) { + + "use strict"; + + context.JK = context.JK || {}; + + + // creates an iconic/graphical instrument selector. useful when there is minimal real-estate + + $.fn.manageVsts = function(options) { + + return this.each(function(index) { + + function close() { + $parent.btOff(); + $parent.focus(); + } + + var $parent = $(this); + + function onManageVstSelected() { + var $li = $(this); + var vstOperation = $li.attr('data-manage-vst-option'); + + close(); + $parent.triggerHandler(context.JK.EVENTS.VST_OPERATION_SELECTED, {vstOperation: vstOperation}); + 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; + + context.JK.hoverBubble($parent, $('#template-manage-vsts').html(), { + trigger:'none', + cssClass: 'manage-vsts-popup', + spikeGirth:0, + spikeLength:0, + width:190, + closeWhenOthersOpen: true, + offsetParent: $parent.closest('.dialog'), + positions:['bottom'], + preShow: function() { + }, + postShow:function(container) { + $(container).find('li').click(onManageVstSelected) + if(timeout) { + clearTimeout(timeout); + timeout = null; + } + waitForBubbleHover($(container)) + timeout = setTimeout(function() {$parent.btOff()}, 3000) + } + }); + }); + } + + +})(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/jquery.trackEffects.js b/web/app/assets/javascripts/jquery.trackEffects.js new file mode 100644 index 000000000..b0a15c74e --- /dev/null +++ b/web/app/assets/javascripts/jquery.trackEffects.js @@ -0,0 +1,75 @@ +(function(context, $) { + + "use strict"; + + context.JK = context.JK || {}; + + + // creates an iconic/graphical instrument selector. useful when there is minimal real-estate + + $.fn.trackEffects = function(options) { + + return this.each(function(index) { + + function close() { + $parent.btOff(); + $parent.focus(); + } + + var $parent = $(this); + + function onOptionSelected() { + var $li = $(this); + var vstOperation = $li.attr('data-manage-vst-option'); + + close(); + $parent.triggerHandler(context.JK.EVENTS.VST_EFFECT_SELECTED, {vstOperation: vstOperation}); + 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; + + context.JK.hoverBubble($parent, $('#template-vst-effects').html(), { + trigger:'none', + cssClass: 'vst-effects-popup', + spikeGirth:0, + spikeLength:0, + width:220, + closeWhenOthersOpen: true, + offsetParent: $parent.closest('.screen'), + positions:['bottom'], + preShow: function() { + + }, + postShow:function(container) { + if (options && options['postShow']) { + options['postShow']($(container)) + } + $(container).find('li').click(onOptionSelected) + if(timeout) { + clearTimeout(timeout); + timeout = null; + } + waitForBubbleHover($(container)) + timeout = setTimeout(function() {$parent.btOff()}, 3000) + } + }); + }); + } + + +})(window, jQuery); \ 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 a0d400953..75472bb42 100644 --- a/web/app/assets/javascripts/react-components.js +++ b/web/app/assets/javascripts/react-components.js @@ -3,12 +3,12 @@ //= require_directory ./react-components/helpers //= require_directory ./react-components/actions //= require ./react-components/stores/AppStore -//= require ./react-components/stores/ConfigureTracksStore //= require ./react-components/stores/BrowserMediaStore //= require ./react-components/stores/RecordingStore //= require ./react-components/stores/VideoStore //= require ./react-components/stores/SessionStore //= require ./react-components/stores/MixerStore +//= require ./react-components/stores/ConfigureTracksStore //= require ./react-components/stores/JamTrackStore //= require ./react-components/stores/SessionNotificationStore //= require ./react-components/stores/MediaPlaybackStore diff --git a/web/app/assets/javascripts/react-components/ConfigureAudioTrack.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureAudioTrack.js.jsx.coffee new file mode 100644 index 000000000..e69de29bb diff --git a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee index 308305446..6fda3639c 100644 --- a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee @@ -2,17 +2,17 @@ context = window ConfigureTracksStore = @ConfigureTracksStore @ConfigureLiveTracksDialog = React.createClass({ - mixins: [Reflux.listenTo(@ConfigureTracksStore,"onConfigureTracksChanged")] + mixins: [Reflux.listenTo(@ConfigureTracksStore,"onConfigureTracksChanged"), Reflux.listenTo(@AppStore, "onAppInit")] onConfigureTracksChanged:(configureTracks) -> @setState({configureTracks: configureTracks}) + onAppInit: (@app) -> + getInitialState: () -> - {configureTracks: null} + {configureTracks: null, midiInterface: null} - render: () -> - - action = 'ADD TRACK' + renderAudio: () -> inputOneOptions = [] inputTwoOptions = [] @@ -21,73 +21,366 @@ ConfigureTracksStore = @ConfigureTracksStore inputOneOptions.push(defaultSelectionOne) inputTwoOptions.push(defaultSelectionTwo) + inputOneValue = '' + inputTwoValue = '' + selectedInstrument = '' + selectedVst = 'NONE' + instruments = [] + instruments.push(``) for displayName, value of context.JK.server_to_client_instrument_map instruments.push(``) - if @state.configureTracks? - for input in @state.configureTracks.musicPorts.inputs - item = `` - inputOneOptions.push(item) - inputTwoOptions.push(item) - - - if @state.configureTracks.editingTrack? - action = 'EDIT TRACK' - vsts = [] - vsts.push(``) - `
-
-

Track Type

-
-
-
+ instrumentDisabled = true + vstDisabled = true + + if @state.configureTracks? + + selectedInstrument = @state.configureTracks.editingTrack.instrument_id if @state.configureTracks.editingTrack.instrument_id? + + if @state.configureTracks.editingTrack.length == 1 + input = @state.configureTracks.editingTrack[0] + if input.number == 0 + inputOneValue = input.id + else + inputTwoValue = input.id + + if @state.configureTracks.editingTrack.length > 1 + inputOneValue = @state.configureTracks.editingTrack[0].id + inputTwoValue = @state.configureTracks.editingTrack[1].id + + instrumentDisabled = @state.configureTracks.editingTrack.length == 0 + vstDisabled = @state.configureTracks.editingTrack.length == 0 + + for input in @state.configureTracks.musicPorts.inputs + + include = false + # we need to see that this input is unassigned, or one of the two selected + for unassignedInputs in @state.configureTracks.trackAssignments.inputs.unassigned + if unassignedInputs.id == input.id + include = true + break + + if !include + # not see if it's the currently edited track + for currentInput in @state.configureTracks.editingTrack + if currentInput.id == input.id + include = true + + if include + item = `` + inputOneOptions.push(item) + inputTwoOptions.push(item) + + + for plugin in @state.configureTracks.vstPluginList.vsts + if plugin.isInstrument == false && plugin.category == 'Effect' + vsts.push(``) + else if plugin.category == 'NONE' + vsts.push(``) + + if @state.configureTracks.editingTrack.vst? + vstAssignedThisTrack = true + selectedVst = @state.configureTracks.editingTrack.vst.file + + vstSettingBtnClasses = classNames({'button-orange': vstAssignedThisTrack, 'button-grey': !vstAssignedThisTrack}) + `

Audio Input Ports

Select one or two inputs ports to assign to this track. Note that if you assign a single input port, the app will automatically duplicate this port into a stereo track.

- {inputOneOptions} - {inputTwoOptions}

Instrument

- {instruments}

Audio Effects (optional)

- {vsts} - manage audio plugins - SETTING . . . -
- -
` - cancel: (e) -> - e.preventDefault() + renderMidi: () -> + midiInterfaces = [] + midiInterfaces.push(``) + midiInstruments = [] - update: (e) -> + instruments = [] + instruments.push(``) + for displayName, value of context.JK.server_to_client_instrument_map + instruments.push(``) + + selectedMidiInterface = '' + selectedInstrument = '' + selectedMidiInstrument = '' + + instrumentDisabled = true + midiInstrumentDisabled = true + vstAssignedThisTrack = false + + if @state.configureTracks? + + logger.debug("current midi device: " + @state.configureTracks.editingTrack.midiDeviceIndex) + selectedMidiInterface = @state.configureTracks.editingTrack.midiDeviceIndex + + selectedInstrument = @state.configureTracks.editingTrack.instrument_id if @state.configureTracks.editingTrack.instrument_id? + instrumentDisabled = !@state.midiInterface? || !selectedMidiInterface? + midiInstrumentDisabled = !@state.midiInterface? || !selectedMidiInterface? + midiInstrumentDisabled = false + instrumentDisabled = false + + if @state.configureTracks.editingTrack.vst? + vstAssignedThisTrack = true + selectedMidiInstrument = @state.configureTracks.editingTrack.vst.file + vstSettingBtnClasses = classNames({'button-orange': vstAssignedThisTrack, 'button-grey': !vstAssignedThisTrack}) + + for midiDevice in @state.configureTracks.attachedMidiDevices.midiDevices + midiInterfaces.push(``) + + for plugin in @state.configureTracks.vstPluginList.vsts + if plugin.isInstrument == true + midiInstruments.push(``) + else if plugin.category == 'NONE' + midiInstruments.push(``) + + `
+
+

MIDI Interface

+ + scan for connected MIDI interfaces +
+
+

Instrument

+ +
+
+

MIDI Instrument (VST or AU Plugin)

+ + manage audio plugins
+ +
+
` + + render: () -> + + action = 'ADD TRACK' + header = 'add track' + + isAudio = !@state.configureTracks? || @state.configureTracks.trackType == 'audio' + isMidi = !isAudio + + if isAudio + activeElement = @renderAudio() + else + activeElement = @renderMidi() + + if !@state.configureTracks?.newTrack + action = 'CLOSE' + header = 'update track' + else + cancelBtn = `CANCEL` + + `
+
+ +

{header}

+
+
+
+

Track Type

+
+
+
+ + {activeElement} + +
+ {cancelBtn} + {action} +
+
+
` + + inputChanged: (e) -> + $root = $(@getDOMNode()) + $select1 = $root.find('.input-one') + $select2 = $root.find('.input-two') + + audioInput1 = $select1.val() + audioInput2 = $select2.val() + + if audioInput1 == '' + audioInput1 = null + + if audioInput2 == '' + audioInput2 = null + + if audioInput1? && audioInput1 == audioInput2 + e.preventDefault() + # TODO: tell user they can't do this + return + + ConfigureTracksActions.associateInputsWithTrack(audioInput1, audioInput2) + + vstsChanged: (e) -> + $root = $(@getDOMNode()) + $select = $root.find('select.vsts') + vstSelected = $select.val() + if vstSelected? + vstSelected = {file: vstSelected} + + ConfigureTracksActions.associateVSTWithTrack(vstSelected) + + if @state.configureTracks?.trackType == 'midi' + if @state.midiInterface? + ConfigureTracksActions.associateMIDIWithTrack(@state.midiInterface) + + + @setState({midiInterface: null}) + + instrumentSelected: (e) -> + $root = $(@getDOMNode()) + $select = $root.find('.instrument-pick') + + instrumentId = $select.val() + ConfigureTracksActions.associateInstrumentWithTrack(instrumentId) + + + doClose: (e) -> e.preventDefault() + # check that instrument is selected + + $root = $(@getDOMNode()) + $instrument = $root.find('.instrument-pick') + + instrumentId = $instrument.val() + + $select1 = $root.find('.input-one') + $select2 = $root.find('.input-two') + + audioInput1 = $select1.val() + audioInput2 = $select2.val() + + if audioInput1 == '' + audioInput1 = null + + if audioInput2 == '' + audioInput2 = null + + if audioInput1 == null && audioInput2 == null + context.JK.Banner.showAlert("At least one input must be specified.") + return + + if instrumentId == null || instrumentId == '' + context.JK.Banner.showAlert("Please select an instrument.") + return + + @app.layout.closeDialog('configure-live-tracks-dialog', false) + + onCancel: (e) -> + + ConfigureTracksActions.cancelEdit() + + @app.layout.closeDialog('configure-live-tracks-dialog', true) vstSettings: (e) -> e.preventDefault() ConfigureTracksActions.showVstSettings() + componentDidMount: () -> $root = $(@getDOMNode()) - context.JK.checkbox($root.find('input[type="radio"]')) + $radio = context.JK.checkbox($root.find('input[type="radio"]')) + $radio.on("ifChanged", @trackTypeChanged); + componentWillUpdate: () -> + @ignoreICheck = true + $root = $(@getDOMNode()) + $radio = $root.find('input[type="radio"]') + $radio.iCheck('enable') + + componentDidUpdate: () -> + $root = $(@getDOMNode()) + $radio = $root.find('input[type="radio"]') + $radio = context.JK.checkbox($root.find('input[type="radio"]')) + $radio.on("ifChanged", @trackTypeChanged); + if @state.configureTracks.editingTrack.assignment == 1 + $radio.iCheck('disable') + else + $radio.iCheck('enable') + + @ignoreICheck = false + + $manageAudioPlugins = $root.find('.manage-audio-plugins') + + unless $manageAudioPlugins.data('initialized') + $manageAudioPlugins.manageVsts().on(context.JK.EVENTS.VST_OPERATION_SELECTED, @vstOperation).data('initialized', true) + + trackTypeChanged: (event) -> + + if @ignoreICheck + logger.debug("ignoring track type changed") + return + + $checkedType = $(event.target); + value = $checkedType.val() + logger.debug("trackTypeChanged: " + value, $checkedType) + ConfigureTracksActions.desiredTrackType(value) + #@setState({trackType: value}) + + vstOperation: (e, data) -> + + if data.vstOperation == 'scan' + ConfigureTracksActions.vstScan() + else if data.vstOperation == 'clear' + ConfigureTracksActions.clearVsts() + + manageAudioPlugins: (e) -> + e.preventDefault() + + $root = $(@getDOMNode()) + $manageAudioPlugins = $root.find('.manage-audio-plugins') + $manageAudioPlugins.btOn() + + scanMidi: (e) -> + e.preventDefault() + + ConfigureTracksActions.midiScan() + + + midiInterfaceChanged: (e) -> + $root = $(@getDOMNode()) + $select = $root.find('select.midi-select') + midiInterface = $select.val() + + if midiInterface == '' + midiInterface = null + + ConfigureTracksActions.associateMIDIWithTrack(midiInterface) + + @setState({midiInterface: midiInterface}) }) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/ConfigureOutputsDialog.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureOutputsDialog.js.jsx.coffee new file mode 100644 index 000000000..41affdad2 --- /dev/null +++ b/web/app/assets/javascripts/react-components/ConfigureOutputsDialog.js.jsx.coffee @@ -0,0 +1,87 @@ +context = window +ConfigureTracksStore = @ConfigureTracksStore +@ConfigureOutputsDialog = React.createClass({ + + mixins: [Reflux.listenTo(@ConfigureTracksStore, "onConfigureTracksChanged"), Reflux.listenTo(@AppStore, "onAppInit")] + + onConfigureTracksChanged: (configureTracks) -> + @setState({configureTracks: configureTracks}) + + onAppInit: (@app) -> + + getInitialState: () -> + {configureTracks: null} + + render: () -> + + outputs = [] + outputs.push(``) + + if @state.configureTracks? + for output in @state.configureTracks.musicPorts.outputs + outputs.push(``) + + `
+
+ +

session audio outputs

+
+
+

Select two audio output ports that will be used to deliver the stereo audio of your sessions to your headphones or monitor.

+ + + +
+
` + + componentDidUpdate: () -> + $root = $(@getDOMNode()) + $output1 = $root.find('.output-1') + $output2 = $root.find('.output-2') + + if @state.configureTracks? && @state.configureTracks.trackAssignments.outputs.assigned.length == 2 + + output1 = @state.configureTracks.trackAssignments.outputs.assigned[0].id + output2 = @state.configureTracks.trackAssignments.outputs.assigned[1].id + + $output1.val(output1) + $output2.val(output2) + + onClose: (e) -> + e.preventDefault() + + $root = $(@getDOMNode()) + $output1 = $root.find('.output-1') + $output2 = $root.find('.output-2') + + output1 = $output1.val() + output2 = $output2.val() + + if output1 == null || output1 == '' + context.JK.Banner.showAlert("Both output ports must have a selection.") + return + + if output2 == null || output2 == '' + context.JK.Banner.showAlert("Both output ports must have a selection.") + return + + if output1? && output1 != '' && output1 == output2 + context.JK.Banner.showAlert("Both output ports can not be the same.") + return + + ConfigureTracksActions.updateOutputs(output1, output2) + + @app.layout.closeDialog('configure-outputs-dialog', false) + + onCancel: (e) -> + + @app.layout.closeDialog('configure-outputs-dialog', true) + } +) diff --git a/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee index e6256f4f3..16d89786a 100644 --- a/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee @@ -19,8 +19,6 @@ gearUtils = context.JK.GearUtils render: () -> - console.log("@state.configureTracks", @state.configureTracks) - liveTracks = [] outputs = [] @@ -40,10 +38,16 @@ gearUtils = context.JK.GearUtils else instrument = `` + trackTypeLabel = 'AUDIO' + + vstName = 'None' + if inputsForTrack.vst + vstName = "#{inputsForTrack.vst.name} by #{inputsForTrack.vst.manuf}" + liveTracks.push( `
-
{candidate.assignment}:{inputs}
-
None
+
{candidate.assignment}:{trackTypeLabel}{inputs}
+
{vstName}
{instrument}
update @@ -68,7 +72,9 @@ gearUtils = context.JK.GearUtils
{liveTracks}
- ADD A LIVE TRACK . . . +
@@ -79,21 +85,36 @@ gearUtils = context.JK.GearUtils UPDATE OUTPUTS . . .
+
` onUpdateLiveTrack:(liveTrack, e) -> e.preventDefault() + ConfigureTracksActions.showEditTrack(liveTrack.assignment) + onDeleteLiveTrack:(liveTrack, e) -> e.preventDefault() + if liveTrack.assignment == 1 + # can't delete the last assignment + context.JK.Banner.showAlert('You can not delete the 1st audio track.') + else + context.JK.Banner.showYesNo({ + title: "Confirm Deletion", + html: "Are you sure you want to delete this live track?", + yes: => + ConfigureTracksActions.deleteTrack(liveTrack.assignment) + }) + + openLiveTrackDialog: (e) -> e.preventDefault() - context.JK.app.layout.showDialog('configure-live-tracks-dialog') + ConfigureTracksActions.showAddNewTrack() openOutputTrackDialog: (e) -> e.preventDefault() - context.JK.app.layout.app.showDialog('configure-output-tracks-dialog') + ConfigureTracksActions.showEditOutputs() }) \ 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 e36502a3c..37f8c0a00 100644 --- a/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionMyTrack.js.jsx.coffee @@ -1,6 +1,7 @@ context = window MixerActions = @MixerActions +ConfigureTracksActions = @ConfigureTracksActions @SessionMyTrack = React.createClass({ @@ -42,7 +43,9 @@ MixerActions = @MixerActions WebkitTransform: "rotate(#{pan}deg)" } - #
+ if @props.associatedVst? + @equalizerSet = true + vst = `
` `
@@ -55,11 +58,10 @@ MixerActions = @MixerActions
+ {vst}

- -
` @@ -96,6 +98,8 @@ MixerActions = @MixerActions context.JK.helpBubble($root.find('.disabled-track-overlay'), 'missing-my-tracks', {}, {positions:['top'], offsetParent: $root.closest('.top-parent')}) + @initializeVstEffects() + componentWillUpdate: (nextProps, nextState) -> $root = $(this.getDOMNode()) $mute = $root.find('.track-icon-mute') @@ -116,4 +120,32 @@ MixerActions = @MixerActions $mute.on("mouseleave", false) $pan.on("mouseentere", false) $pan.on("mouseleave", false) + + componentDidUpdate:() -> + @initializeVstEffects() + + initializeVstEffects: () -> + $root = $(this.getDOMNode()) + $equalizer = $root.find('.track-icon-equalizer') + if $equalizer.length > 0 && !$equalizer.data('initialized') + logger.debug("initializing trackEffects", $equalizer) + $equalizer.trackEffects({postShow: @prepVstEffects}).on(context.JK.EVENTS.VST_EFFECT_SELECTED, @vstOperation).data('initialized', true).click(() => + logger.debug("clicked!") + $equalizer.btOn() + ) + prepVstEffects: ($container) -> + $container.find('.vst-name').text(@props.associatedVst?.name) + + vstOperation: (e, data) -> + logger.debug("track effect selection: " + data.vstOperation) + + if !@props.associatedVst? + logger.warn("no associated VST") + return + + if data.vstOperation == 'open-vst' + ConfigureTracksActions.showVstSettings(@props.associatedVst.track) + else + ConfigureTracksActions.showEditTrack(@props.associatedVst.track + 1) + }) 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 97323d6f8..017255665 100644 --- a/web/app/assets/javascripts/react-components/SessionMyTracks.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionMyTracks.js.jsx.coffee @@ -5,7 +5,7 @@ ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; @SessionMyTracks = React.createClass({ - mixins: [@SessionMyTracksMixin, Reflux.listenTo(@SessionMyTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit")] + mixins: [@SessionMyTracksMixin, Reflux.listenTo(@SessionMyTracksStore,"onInputsChanged"), Reflux.listenTo(@AppStore,"onAppInit"), Reflux.listenTo(@ConfigureTracksStore, "onConfigureTracksChanged")] goToFtue: (e) -> e.preventDefault() diff --git a/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee index b4448c579..4a2890385 100644 --- a/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee +++ b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee @@ -3,6 +3,20 @@ context = window @ConfigureTracksActions = Reflux.createActions({ reset: {} trySave: {} + midiScan: {} vstScan: {} vstScanComplete: {} + clearVsts: {} + cancelEdit: {} + deleteTrack: {} + updateOutputs: {} + showAddNewTrack: {} + showEditTrack: {} + showEditOutputs: {} + showVstSettings: {} + associateInputsWithTrack: {} + associateInstrumentWithTrack: {} + associateVSTWithTrack: {} + associateMIDIWithTrack: {} + desiredTrackType: {} }) diff --git a/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee b/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee index 9d808485c..858bb8ad7 100644 --- a/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee +++ b/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee @@ -4,9 +4,21 @@ context = window onInputsChanged: (sessionMixers) -> + @sessionMixers = sessionMixers - session = sessionMixers.session - mixers = sessionMixers.mixers + @recompute() + + onConfigureTracksChanged: (configureTracks) -> + + @configureTracks = configureTracks + + @recompute() + + recompute: () -> + return if !@sessionMixers? + + session = @sessionMixers.session + mixers = @sessionMixers.mixers tracks = [] @@ -38,11 +50,21 @@ context = window instrumentIcon = context.JK.getInstrumentIcon45(track.instrument_id); trackName = "#{name}: #{track.instrument}" - tracks.push({track: track, mixerFinder: mixerFinder, mixers: mixerData, hasMixer:hasMixer, name: name, trackName: trackName, instrumentIcon: instrumentIcon, photoUrl: photoUrl, clientId: participant.client_id}) + associatedVst = null + # find any VST info + if hasMixer && @configureTracks? + for vst in @configureTracks.vstTrackAssignments.vsts + if vst.track == mixerData.mixer.track - 1 && vst.name != 'NONE' + logger.debug("found VST on track", vst, track) + associatedVst = vst + break + tracks.push({track: track, mixerFinder: mixerFinder, mixers: mixerData, hasMixer:hasMixer, name: name, trackName: trackName, instrumentIcon: instrumentIcon, photoUrl: photoUrl, clientId: participant.client_id, associatedVst: associatedVst}) else logger.warn("SessionMyTracks: unable to find participant") this.setState(tracks: tracks, session:session, chat: chat) + + } \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index dbcb830dd..eea6c8bd1 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -24,21 +24,39 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev { listenables: ConfigureTracksActions - musicPorts: {inputs:[], outputs:[]} + musicPorts: {inputs: [], outputs: []} trackNumber: null editingTrack: null + vstPluginList: {vsts: []} + vstTrackAssignments: {vsts: []} + attachedMidiDevices: {midiDevices: []} + midiTrackAssignments: {tracks: []} + trackType: 'audio' + init: () -> + this.listenTo(context.AppStore, this.onAppInit) + this.listenTo(context.MixerStore, this.onMixersChanged) onAppInit: (@app) -> + editingTrackValid: () -> + true + + onMixersChanged: (mixers) -> + @loadChannels() + @loadTrackInstruments() + @changed() + onReset: () -> logger.debug("ConfigureTracksStore:reset", this) @trackNumber = null @editingTrack = null @loadChannels() - @onVstScan() - @onMidiScan() + @loadTrackInstruments() + @performVstScan() + @performMidiScan() + @changed() onTrySave: () -> @@ -48,29 +66,88 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev trySave: () -> onVstScan: () -> + @performVstScan(true) + + performVstScan: (sendChanged) -> @hasVst = context.jamClient.hasVstHost() logger.debug("hasVst", @hasVst) if @hasVst logger.debug("vstScan starting") - result = context.jamClient.VSTScan() + result = context.jamClient.VSTScan("window.ConfigureTracksStore.onVstScanComplete") logger.debug("vstScan completed", result) - @vstPluginList = context.jamClient.VSTListVsts() - @vstTrackAssignments = context.jamClient.VSTListTrackAssignments() + onClearVsts: () -> + context.jamClient.VSTClearAll() - console.log("@vstPluginList", @vstPluginList) - console.log("@vstTrackAssignments", @vstTrackAssignments) + setTimeout((() => + @listVsts() + + @changed() + ), 250) + + onVstScanComplete: () -> + @listVsts() + @changed() + + + listVsts: () -> + + @vstPluginList = context.jamClient.VSTListVsts() + @vstTrackAssignments = context.jamClient.VSTListTrackAssignments() + + console.log("@vstTrackAssignments", @vstTrackAssignments) onMidiScan: () -> - @attachedMidiDevices = context.jamClient.listAttachedMidiDevices(); + @performMidiScan() + @changed() - console.log("@attachedMidiDevices", @attachedMidiDevices) + performMidiScan: () -> + context.jamClient.VST_ScanForMidiDevices(); + @attachedMidiDevices = context.jamClient.VST_GetMidiDeviceList(); - onShowVstSettings: () -> - context.jamClient.showHideVstGui(true, @trackNumber) if @trackNumber? + # trackNumber is 0-based, and optional + onShowVstSettings: (trackNumber) -> + if !trackNumber? + trackNumber = @trackNumber - 1 if @trackNumber? + + logger.debug("show VST GUI", trackNumber) + + context.jamClient.VSTShowHideGui(true, trackNumber) if trackNumber? changed: () -> - @item = {musicPorts: @musicPorts, trackAssignments: @trackAssignments, trackNumber: @trackNumber, editingTrack: @editingTrack} + @editingTrack = [] + @editingTrack.assignment = @trackNumber + + if @trackNumber? + + for inputsForTrack in @trackAssignments.inputs.assigned + if inputsForTrack.assignment == @trackNumber + @editingTrack = inputsForTrack + break + + # slap on vst, if any, from list of vst assignments + for vst in @vstTrackAssignments.vsts + if vst.track == @editingTrack.assignment - 1 + @editingTrack.vst = vst + @editingTrack.midiDeviceIndex = vst.midiDeviceIndex + break + + if @editingTrack.vst? + logger.debug("current track has a VST assigned:" + @editingTrack.vst.file) + + @item = { + musicPorts: @musicPorts, + trackAssignments: @trackAssignments, + trackNumber: @trackNumber, + editingTrack: @editingTrack, + vstPluginList: @vstPluginList, + vstTrackAssignments: @vstTrackAssignments, + attachedMidiDevices: @attachedMidiDevices, + nextTrackNumber: @nextTrackNumber, + newTrack: @newTrack, + midiTrackAssignments: @midiTrackAssignments, + trackType: @trackType + } @trigger(@item) @@ -80,7 +157,9 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev @musicPorts = context.jamClient.FTUEGetChannels() # let's populate this bad boy - @trackAssignments = {inputs: {unassigned:[], assigned:[], chat:[]}, outputs: {unassigned:[], assigned: []}} + @trackAssignments = {inputs: {unassigned: [], assigned: [], chat: []}, outputs: {unassigned: [], assigned: []}} + + nextTrackNumber = 0 for input in @musicPorts.inputs if input.assignment == ASSIGNMENT.UNASSIGNED @@ -88,6 +167,8 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev else if input.assignment == ASSIGNMENT.CHAT @trackAssignments.inputs.chat.push(input) else + nextTrackNumber = input.assignment if input.assignment > nextTrackNumber + # make sure this assignment isn't already preset (you can have multiple inputs per 'track slot') found = false for assigned in @trackAssignments.inputs.assigned @@ -105,29 +186,196 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev else @trackAssignments.outputs.unassigned.push(output) - @loadTrackInstruments(forceInputsToUnassign) + @nextTrackNumber = nextTrackNumber + 1 - @changed() loadTrackInstruments: (forceInputsToUnassign) -> for inputsForTrack in @trackAssignments.inputs.assigned - clientInstrument = context.jamClient.TrackGetInstrument(inputsForTrack[0].assignment) + clientInstrument = context.jamClient.TrackGetInstrument(inputsForTrack.assignment) instrument = context.JK.client_to_server_instrument_map[clientInstrument]; inputsForTrack.instrument_id = instrument?.server_id + + onAssociateInputsWithTrack: (inputId1, inputId2) -> + return unless @trackNumber? + + for inputs in @editingTrack + context.jamClient.TrackSetAssignment(inputs.id, true, ASSIGNMENT.UNASSIGNED) + + if inputId1? + logger.debug("setting input1 #{inputId1} to #{@trackNumber}") + context.jamClient.TrackSetAssignment(inputId1, true, @trackNumber) + + if inputId2? + logger.debug("setting input2 #{inputId2} to #{@trackNumber}") + context.jamClient.TrackSetAssignment(inputId2, true, @trackNumber) + + result = context.jamClient.TrackSaveAssignments(); + + if(!result || result.length == 0) + + else + context.JK.Banner.showAlert('Unable to save assignments. ' + result); + + onAssociateInstrumentWithTrack: (instrumentId) -> + return unless @trackNumber? + + logger.debug("context.jamClient.TrackSetInstrument(trackNumber, track.instrument_id)", @trackNumber, instrumentId) + + if instrumentId != null && instrumentId != '' + context.jamClient.TrackSetInstrument(@trackNumber, context.JK.instrument_id_to_instrument[instrumentId].client_id) + else + context.jamClient.TrackSetInstrument(@trackNumber, 0) + + if(!result || result.length == 0) + + else + context.JK.Banner.showAlert('Unable to save assignments. ' + result); + + + result = context.jamClient.TrackSaveAssignments() + + if(!result || result.length == 0) + + else + context.JK.Banner.showAlert('Unable to save assignments. ' + result); + + onAssociateVSTWithTrack: (vst) -> + if vst? + logger.debug("associating track:#{@trackNumber} with VST:#{vst.file}") + + found = null + for knownVst in @vstPluginList.vsts + if knownVst.file == vst.file + found = knownVst + break + if found? + context.jamClient.VSTSetTrackAssignment(found, @trackNumber - 1) + else + logger.error("unable to locate vst for #{vst}") + else + logger.debug("unassociated track:#{@trackNumber} with VST") + # no way to unset VST assignment yet + + setTimeout((() => ( + @listVsts() + + @changed() + )), 250) + + onCancelEdit: () -> + if @newTrack + for input in @editingTrack + context.jamClient.TrackSetAssignment(input.id, true, ASSIGNMENT.UNASSIGNED) + result = context.jamClient.TrackSaveAssignments() + if(!result || result.length == 0) + + else + context.JK.Banner.showAlert('Unable to save assignments. ' + result); + else + logger.error("unable to process cancel for an existing track") + + onDeleteTrack: (assignment) -> + track = null + for inputsForTrack in @trackAssignments.inputs.assigned + if inputsForTrack.assignment == assignment + track = inputsForTrack + break + + if track? + for input in inputsForTrack + context.jamClient.TrackSetAssignment(input.id, true, ASSIGNMENT.UNASSIGNED) + result = context.jamClient.TrackSaveAssignments() + + if(!result || result.length == 0) + + else + context.JK.Banner.showAlert('Unable to save assignments. ' + result); + else + logger.error("unable to find track to delete") + + onShowAddNewTrack: () -> + + # check if we have what we need... namely, free ports + + if @trackAssignments.inputs.unassigned.length == 0 + context.JK.Banner.showAlert('You have no more unassigned input ports.

You can free some up by editing an AUDIO track.') + return + + @openLiveTrackDialog(@nextTrackNumber) + + onShowEditTrack: (trackNumber) -> + @openLiveTrackDialog(trackNumber) + openLiveTrackDialog: (trackNumber) -> @trackNumber = trackNumber + logger.debug("opening live track dialog for track #{trackNumber}") - @editingTrack = null + @newTrack = true for inputsForTrack in @trackAssignments.inputs.assigned - if inputsForTrack.assignment == trackNumber - @editingTrack = inputsForTrack + logger.debug("inputsForTrack.assignment @trackNumber", inputsForTrack.assignment, @trackNumber ) + if inputsForTrack.assignment == @trackNumber + @newTrack = false break + if @newTrack + @trackType = 'audio' + else + if @trackNumber == 1 + @trackType = 'audio' + else + @trackType = 'audio' + for trackAssignment in @vstTrackAssignments.vsts + if trackAssignment.track == @trackNumber - 1 + if trackAssignment.midiDeviceIndex > -1 + logger.debug("editing midi track") + @trackType = 'midi' + break + + if @newTrack + # ensure that we always have an instrument set (50 = electric guitar + context.jamClient.TrackSetInstrument(@trackNumber, 50) + @changed() @app.layout.showDialog('configure-live-tracks-dialog') + + onDesiredTrackType: (trackType) -> + @trackType = trackType + + @changed() + + onUpdateOutputs: (outputId1, outputId2) -> + + context.jamClient.TrackSetAssignment(outputId1, true, ASSIGNMENT.OUTPUT); + context.jamClient.TrackSetAssignment(outputId2, true, ASSIGNMENT.OUTPUT); + + result = context.jamClient.TrackSaveAssignments(); + + if(!result || result.length == 0) + + else + context.JK.Banner.showAlert('Unable to save assignments. ' + result); + + onShowEditOutputs: () -> + @app.layout.showDialog('configure-outputs-dialog') + + onAssociateMIDIWithTrack: (midiInterface) -> + + if !midiInterface? || midiInterface == '' + logger.debug("disabling midiInterface:#{midiInterface}, track:#{@trackNumber - 1}") + context.jamClient.VST_EnableMidiForTrack(@trackNumber - 1, false, 0) + else + logger.debug("enabling midiInterface:#{midiInterface}, track:#{@trackNumber - 1}") + context.jamClient.VST_EnableMidiForTrack(@trackNumber - 1, true, midiInterface) + + setTimeout((() => ( + @listVsts() + + @changed() + )), 250) + } ) \ No newline at end of file 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 b0bbb0ac7..08e291141 100644 --- a/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee @@ -10,6 +10,7 @@ SessionActions = @SessionActions RecordingActions = @RecordingActions NotificationActions = @NotificationActions VideoActions = @VideoActions +ConfigureTracksActions = @ConfigureTracksActions @SessionStore = Reflux.createStore( { @@ -731,6 +732,8 @@ VideoActions = @VideoActions $(document).trigger(EVENTS.SESSION_STARTED, {session: {id: @currentSessionId}}) if document @handleAutoOpenJamTrack() + + ConfigureTracksActions.reset() ) .fail((xhr) => @updateCurrentSession(null) diff --git a/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js b/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js index 81c330620..e40b81609 100644 --- a/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js +++ b/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js @@ -21,14 +21,14 @@ } function handleNext() { - var saved = configureTracksHelper.trySave(); + /** var saved = configureTracksHelper.trySave(); if(saved) { context.JK.GA.trackConfigureTracksCompletion(context.JK.detectOS()); successfullyAssignedOnce = true; } - - return saved; +*/ + return context.ConfigureTracksStore.editingTrackValid() } function newSession() { @@ -38,7 +38,8 @@ function beforeShow() { var forceInputsToUnassigned = !successfullyAssignedOnce; - configureTracksHelper.reset(forceInputsToUnassigned, wizard.getChosenInputs()) + window.ConfigureTracksActions.reset(forceInputsToUnassigned, wizard.getChosenInputs()); + //configureTracksHelper.reset(forceInputsToUnassigned, wizard.getChosenInputs()) } function initialize(_$step, _wizard) { diff --git a/web/app/assets/stylesheets/client/client.css b/web/app/assets/stylesheets/client/client.css index 277f98cdb..1c0385193 100644 --- a/web/app/assets/stylesheets/client/client.css +++ b/web/app/assets/stylesheets/client/client.css @@ -53,6 +53,8 @@ *= require dialogs/dialog *= require ./iconInstrumentSelect *= require ./muteSelect + *= require ./manageVsts + *= require ./vstEffects *= require ./metronomePlaybackModeSelect *= require ./terms *= require ./createSession diff --git a/web/app/assets/stylesheets/client/manageVsts.css.scss b/web/app/assets/stylesheets/client/manageVsts.css.scss new file mode 100644 index 000000000..a7063e390 --- /dev/null +++ b/web/app/assets/stylesheets/client/manageVsts.css.scss @@ -0,0 +1,23 @@ +@import "client/common"; + +.manage-vsts-popup { + .bt-content { + height:38px; + width:190px; + 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; + } + } +} \ No newline at end of file diff --git a/web/app/assets/stylesheets/client/react-components/ConfigureTracks.css.scss b/web/app/assets/stylesheets/client/react-components/ConfigureTracks.css.scss index f76f8276d..72d90891a 100644 --- a/web/app/assets/stylesheets/client/react-components/ConfigureTracks.css.scss +++ b/web/app/assets/stylesheets/client/react-components/ConfigureTracks.css.scss @@ -10,7 +10,7 @@ height:220px; .live-tracks { - height:150px; + height:165px; overflow:auto; a { margin-left:3px; @@ -19,6 +19,12 @@ .live-input { display:inline-block; + &:before { + content: '(' + } + &:after { + content: ')' + } } .live-track { margin-bottom:20px; @@ -36,12 +42,44 @@ @include border_box_sizing; width:60%; display:inline-block; + + &.one { + .live-input { + width:50%; + @include border_box_sizing; + } + } + + &.two { + .live-input { + max-width:40%; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + @include border_box_sizing; + &:nth-of-type(1) { + padding-right:5px; + } + &:nth-of-type(2) { + padding-left:5px; + } + } + } + } + + .track-type-label { + display:inline-block; + white-space:nowrap; + padding-right:7px; } .plugin-info { @include border_box_sizing; width:30%; display:inline-block; + white-space:nowrap; + text-overflow: ellipsis; + overflow:hidden; } .plugin-instrument { @@ -88,6 +126,12 @@ .output { display:inline-block; margin-bottom:0 !important; + &:before { + content: '(' + } + &:after { + content: ')' + } } } h3 { @@ -117,8 +161,8 @@ } .live-track-actions { display:block; - padding-left:30px; - margin-top:10px; + padding-left: 17px; + margin-top: 5px; a { font-size:12px; } diff --git a/web/app/assets/stylesheets/client/vstEffects.css.scss b/web/app/assets/stylesheets/client/vstEffects.css.scss new file mode 100644 index 000000000..945e49b10 --- /dev/null +++ b/web/app/assets/stylesheets/client/vstEffects.css.scss @@ -0,0 +1,39 @@ +@import "client/common"; + +.vst-effects-popup { + margin-top: 3px; + margin-left: 120px; + + .bt-content { + width:220px; + 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; + margin-bottom:0 !important; + + padding:7px 0 10px 0; + + .vst-name { + text-overflow:ellipsis; + overflow:hidden; + } + &:nth-of-type(1) { + + border-width:0 0 1px 0 !important; + border-style:solid !important;; + border-color:#ED3618 !important;; + } + } + } +} \ No newline at end of file diff --git a/web/app/assets/stylesheets/client/wizard/gearWizard.css.scss b/web/app/assets/stylesheets/client/wizard/gearWizard.css.scss index 5e6084efc..d7bbb1f80 100644 --- a/web/app/assets/stylesheets/client/wizard/gearWizard.css.scss +++ b/web/app/assets/stylesheets/client/wizard/gearWizard.css.scss @@ -197,7 +197,7 @@ width: 25%; &:nth-of-type(2) { - width: 21%; + width: 71%; } &:nth-of-type(3) { @@ -217,9 +217,64 @@ margin-top: 45px; } - .output-channels, .unassigned-output-channels { + .outputs-view { display:none; } + + .inputs-view { + padding:0; + border-width:0; + + h3.session-audio-inputs-header { + font-weight:normal; + width:70%; + font-size:14px; + color:white; + } + + h3.plugin-header { + width:20%; + font-size:14px; + color:white; + } + + h3.instrument-header { + width:10%; + font-size:14px; + color:white; + } + + .input-track-info { + width:70%; + } + + .plugin-info { + width:20%; + } + + .plugin-instrument { + width:10%; + } + + .live-tracks { + height:198px; + } + .live-input { + display:block; + max-width:90%; + &:before { + content: '' + } + &:after { + content: '' + } + } + .input-track-info .live-input { + padding-left:19px; + padding-right:0; + } + .add-track-action { text-align:center;} + } } .wizard-step[layout-wizard-step="3"] { diff --git a/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss index b87510eab..684cd70b3 100644 --- a/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss +++ b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss @@ -13,6 +13,9 @@ margin-bottom:10px; } + .manage-audio-plugins { + font-size:12px; + } .actions { clear:both; text-align:center; @@ -20,7 +23,6 @@ .track-type { width:100%; @include border_box_sizing; - margin-bottom:20px; padding:10px; .track-type-option { @@ -37,7 +39,7 @@ } } .audio-input-ports { - width:50%; + width:60%; @include border_box_sizing; float:left; margin-bottom:40px; @@ -53,18 +55,99 @@ line-height:125%; } } - .instrument-selection { - width:50%; - @include border_box_sizing; - float:left; - margin-bottom:40px; - padding:10px; + + .audio { + .instrument-selection { + width:40%; + @include border_box_sizing; + float:left; + margin-bottom:26px; + padding:10px; + select { + width:90%; + } + } } - .audio-effects { - width:50%; + + .midi-interface { @include border_box_sizing; float:left; margin-bottom:20px; padding:10px; + position:relative; + width:50%; + + select { + width:80%; + margin-bottom:10px; + } + a { + font-size:12px; + } + } + .midi { + .instrument-selection { + width:50%; + @include border_box_sizing; + float:left; + margin-bottom:26px; + padding:10px; + select { + width:80%; + } + } + } + + .midi-instrument { + @include border_box_sizing; + float:left; + margin-bottom:20px; + padding:10px; + position:relative; + width:50%; + clear:both; + + select { + width:80%; + margin-bottom:10px; + } + } + .audio-effects { + width:40%; + @include border_box_sizing; + float:left; + margin-bottom:20px; + padding:10px; + position:relative; + + select { + width:90%; + margin-bottom:20px; + } + + a.manage-audio-plugins { + position:relative; + } + .down-arrow { + cursor:pointer; + width: 0; + height: 0; + border-left: 8px solid transparent; + border-right: 8px solid transparent; + border-top: 8px solid #fc0; + position: absolute; + top: 2px; + right: -20px; + } + .settings-holder { + right:10%; + text-align:right; + position:absolute; + margin-top: -27px; + @include border_box_sizing; + padding: 10px 0 10px 10px; + } + a.button-orange { + } } } \ No newline at end of file diff --git a/web/app/assets/stylesheets/dialogs/configureOutputsDialog.css.scss b/web/app/assets/stylesheets/dialogs/configureOutputsDialog.css.scss new file mode 100644 index 000000000..b0e9e28a4 --- /dev/null +++ b/web/app/assets/stylesheets/dialogs/configureOutputsDialog.css.scss @@ -0,0 +1,36 @@ +@import "client/common"; + +#configure-outputs-dialog { + width: 425px; + + .dialog-inner { + width: auto; + } + + h3 { + color: white; + font-weight: bold; + margin-bottom: 10px; + } + + .actions { + clear: both; + text-align: center; + } + + p { + margin-bottom:10px; + line-height:125%; + } + + select { + width: 100%; + + &.output-1 { + margin-bottom:15px; + } + &.output-2 { + margin-bottom:50px; + } + } +} \ No newline at end of file diff --git a/web/app/assets/stylesheets/dialogs/configureTracksDialog.css.scss b/web/app/assets/stylesheets/dialogs/configureTracksDialog.css.scss index 46b1bd830..aa776ede7 100644 --- a/web/app/assets/stylesheets/dialogs/configureTracksDialog.css.scss +++ b/web/app/assets/stylesheets/dialogs/configureTracksDialog.css.scss @@ -2,8 +2,6 @@ @charset "UTF-8"; #configure-tracks-dialog { - min-height: 700px; - max-height: 700px; width:800px; &[current-screen="account/audio"] { @@ -120,21 +118,21 @@ } .buttons { - bottom: 25px; - position: absolute; - right: 25px; - left:25px; + position:static; + margin-top:20px; + text-align:center; } .btn-add-new-audio-gear { - float:left; + position:absolute; + left:20px; } .btn-cancel { - float:right; + } .btn-update-settings { - float:right; + } } \ No newline at end of file diff --git a/web/app/views/clients/_manageVsts.html.slim b/web/app/views/clients/_manageVsts.html.slim new file mode 100644 index 000000000..d78dcc704 --- /dev/null +++ b/web/app/views/clients/_manageVsts.html.slim @@ -0,0 +1,7 @@ +script type='text/template' id='template-manage-vsts' + ul + li data-manage-vst-option="scan" + a href='#' scan for new or updated plugins + + li data-manage-vst-option="clear" + a href='#' clear plug-in list \ No newline at end of file diff --git a/web/app/views/clients/_vstEffects.html.slim b/web/app/views/clients/_vstEffects.html.slim new file mode 100644 index 000000000..4085f9ecc --- /dev/null +++ b/web/app/views/clients/_vstEffects.html.slim @@ -0,0 +1,9 @@ +script type='text/template' id='template-vst-effects' + ul + li data-manage-vst-option="open-vst" + a href='#' + | Open  + span.vst-name + + li data-manage-vst-option="update-track" + a href='#' Update Track . . . \ No newline at end of file diff --git a/web/app/views/clients/index.html.erb b/web/app/views/clients/index.html.erb index 962e21298..16f30f3a1 100644 --- a/web/app/views/clients/index.html.erb +++ b/web/app/views/clients/index.html.erb @@ -20,6 +20,8 @@ <%= render "jamServer" %> <%= render "iconInstrumentSelect" %> <%= render "muteSelect" %> +<%= render "manageVsts" %> +<%= render "vstEffects" %> <%= render "metronome_playback_mode" %> <%= render "clients/wizard/buttons" %> <%= render "clients/wizard/gear/gear_wizard" %> diff --git a/web/app/views/clients/wizard/gear/_gear_wizard.html.haml b/web/app/views/clients/wizard/gear/_gear_wizard.html.haml index c2c1d9b50..4f8f9ab87 100644 --- a/web/app/views/clients/wizard/gear/_gear_wizard.html.haml +++ b/web/app/views/clients/wizard/gear/_gear_wizard.html.haml @@ -81,16 +81,7 @@ .center %a.button-orange.watch-video{href:'https://www.youtube.com/watch?v=SjMeMZpKNR4', rel:'external'} WATCH VIDEO .wizard-step-column - %h2 Unassigned Ports - .unassigned-input-channels.channels-holder - .wizard-step-column - %h2 Track Input Port(s) - .tracks - .wizard-step-column - %h2 Instrument - .instruments - .output-channels - .unassigned-output-channels.channels-holder + = react_component 'ConfigureTracks', {} .wizard-step{ 'layout-wizard-step' => "3", 'dialog-title' => "Configure Voice Chat", 'dialog-purpose' => "ConfigureVoiceChat" } .ftuesteps diff --git a/web/app/views/dialogs/_configureLiveTracksDialog.html.slim b/web/app/views/dialogs/_configureLiveTracksDialog.html.slim index eace5771b..2c488ddaa 100644 --- a/web/app/views/dialogs/_configureLiveTracksDialog.html.slim +++ b/web/app/views/dialogs/_configureLiveTracksDialog.html.slim @@ -1,6 +1,2 @@ .dialog.dialog-overlay-sm.top-parent layout='dialog' layout-id='configure-live-tracks-dialog' id='configure-live-tracks-dialog' - .content-head - = image_tag "content/icon_add.png", {:height => 19, :width => 19, :class => 'content-icon'} - h1 add live track - .dialog-inner - = react_component 'ConfigureLiveTracksDialog', {} + = react_component 'ConfigureLiveTracksDialog', {} diff --git a/web/app/views/dialogs/_configureOutputsDialog.html.slim b/web/app/views/dialogs/_configureOutputsDialog.html.slim new file mode 100644 index 000000000..bb6f10e7c --- /dev/null +++ b/web/app/views/dialogs/_configureOutputsDialog.html.slim @@ -0,0 +1,2 @@ +.dialog.dialog-overlay-sm.top-parent layout='dialog' layout-id='configure-outputs-dialog' id='configure-outputs-dialog' + = react_component 'ConfigureOutputsDialog', {} diff --git a/web/app/views/dialogs/_configure_tracks_dialog.html.haml b/web/app/views/dialogs/_configure_tracks_dialog.html.haml index cb65af8eb..42d6d1d2e 100644 --- a/web/app/views/dialogs/_configure_tracks_dialog.html.haml +++ b/web/app/views/dialogs/_configure_tracks_dialog.html.haml @@ -4,7 +4,7 @@ %h1 configure tracks .dialog-inner .dialog-tabs - %a.selected.tab-configure-audio Music Audio + %a.selected.tab-configure-audio Inputs & Outputs %a.tab-configure-voice Voice Chat .instructions @@ -48,5 +48,6 @@ .buttons %a.btn-add-new-audio-gear.button-grey{'layout-link' => 'add-new-audio-gear'} ADD NEW AUDIO GEAR - %a.button-orange.btn-update-settings{href:'#'} UPDATE SETTINGS %a.button-grey.btn-cancel{href:'#'} CANCEL + %a.button-orange.btn-update-settings{href:'#'} SAVE SETTINGS + diff --git a/web/app/views/dialogs/_dialogs.html.haml b/web/app/views/dialogs/_dialogs.html.haml index 761559fdf..2c45d7df2 100644 --- a/web/app/views/dialogs/_dialogs.html.haml +++ b/web/app/views/dialogs/_dialogs.html.haml @@ -44,4 +44,5 @@ = render 'dialogs/recordingSelectorDialog' = render 'dialogs/soundCloudPlayerDialog' = render 'dialogs/deleteVideoConfirmDialog' -= render 'dialogs/configureLiveTracksDialog' \ No newline at end of file += render 'dialogs/configureLiveTracksDialog' += render 'dialogs/configureOutputsDialog' \ No newline at end of file From c3626ebe229e7ae00efc5163490be7adf651c3ee Mon Sep 17 00:00:00 2001 From: Seth Call Date: Wed, 11 Nov 2015 05:39:28 -0600 Subject: [PATCH 07/15] * wip --- .../react-components/stores/ConfigureTracksStore.js.coffee | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index eea6c8bd1..c97387807 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -86,9 +86,10 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev ), 250) onVstScanComplete: () -> - @listVsts() - @changed() - + setTimeout((() => + @listVsts() + @changed() + ), 0) listVsts: () -> From 5fad4953bcb46c45c3538a82523d3e11670c92ba Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 13 Nov 2015 14:00:37 -0600 Subject: [PATCH 08/15] * vst working --- .../ConfigureLiveTracksDialog.js.jsx.coffee | 3 +- .../ConfigureTracks.js.jsx.coffee | 2 +- .../mixins/SessionMyTracksMixin.js.coffee | 1 + .../stores/ConfigureTracksStore.js.coffee | 49 ++++++++++++++----- web/config/application.rb | 2 + web/config/environments/development.rb | 2 + web/config/initializers/gon.rb | 1 + 7 files changed, 45 insertions(+), 15 deletions(-) diff --git a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee index 6fda3639c..5beede426 100644 --- a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee @@ -122,12 +122,11 @@ ConfigureTracksStore = @ConfigureTracksStore midiInstruments = [] instruments = [] - instruments.push(``) for displayName, value of context.JK.server_to_client_instrument_map instruments.push(``) selectedMidiInterface = '' - selectedInstrument = '' + selectedInstrument = context.JK.client_to_server_instrument_map[50].server_id # default to electric guitar selectedMidiInstrument = '' instrumentDisabled = true diff --git a/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee index 16d89786a..24cd6a140 100644 --- a/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureTracks.js.jsx.coffee @@ -41,7 +41,7 @@ gearUtils = context.JK.GearUtils trackTypeLabel = 'AUDIO' vstName = 'None' - if inputsForTrack.vst + if inputsForTrack.vst? && inputsForTrack.vst != 'NONE' vstName = "#{inputsForTrack.vst.name} by #{inputsForTrack.vst.manuf}" liveTracks.push( diff --git a/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee b/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee index 858bb8ad7..5b8f55e99 100644 --- a/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee +++ b/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee @@ -54,6 +54,7 @@ context = window associatedVst = null # find any VST info if hasMixer && @configureTracks? + console.log("checking associations", @configureTracks.vstTrackAssignments.vsts, mixerData.mixer) for vst in @configureTracks.vstTrackAssignments.vsts if vst.track == mixerData.mixer.track - 1 && vst.name != 'NONE' logger.debug("found VST on track", vst, track) diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index c97387807..87339f22c 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -33,7 +33,6 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev midiTrackAssignments: {tracks: []} trackType: 'audio' - init: () -> this.listenTo(context.AppStore, this.onAppInit) this.listenTo(context.MixerStore, this.onMixersChanged) @@ -69,7 +68,7 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev @performVstScan(true) performVstScan: (sendChanged) -> - @hasVst = context.jamClient.hasVstHost() + @hasVst = gon.global.vst_enabled & context.jamClient.hasVstHost() logger.debug("hasVst", @hasVst) if @hasVst logger.debug("vstScan starting") @@ -103,11 +102,19 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev @changed() performMidiScan: () -> + + if !@hasVst + logger.debug("performMidiScan skipped due to no VST") + return context.jamClient.VST_ScanForMidiDevices(); @attachedMidiDevices = context.jamClient.VST_GetMidiDeviceList(); # trackNumber is 0-based, and optional onShowVstSettings: (trackNumber) -> + if !@hasVst + logger.debug("onShowVstSettings skipped due to no VST") + return + if !trackNumber? trackNumber = @trackNumber - 1 if @trackNumber? @@ -126,15 +133,16 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev @editingTrack = inputsForTrack break - # slap on vst, if any, from list of vst assignments - for vst in @vstTrackAssignments.vsts - if vst.track == @editingTrack.assignment - 1 - @editingTrack.vst = vst - @editingTrack.midiDeviceIndex = vst.midiDeviceIndex - break - if @editingTrack.vst? - logger.debug("current track has a VST assigned:" + @editingTrack.vst.file) + # slap on vst, if any, from list of vst assignments + for vst in @vstTrackAssignments.vsts + if vst.track == @editingTrack.assignment - 1 + @editingTrack.vst = vst + @editingTrack.midiDeviceIndex = vst.midiDeviceIndex + break + + if @editingTrack.vst? + logger.debug("current track has a VST assigned:" + @editingTrack.vst.file) @item = { musicPorts: @musicPorts, @@ -192,8 +200,15 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev loadTrackInstruments: (forceInputsToUnassign) -> for inputsForTrack in @trackAssignments.inputs.assigned + clientInstrument = context.jamClient.TrackGetInstrument(inputsForTrack.assignment) + if clientInstrument == 0 + logger.debug("defaulting track instrument for assignment #{@trackNumber}") + # ensure that we always have an instrument set (50 = electric guitar + context.jamClient.TrackSetInstrument(inputsForTrack.assignment, 50) + clientInstrument = 50 + instrument = context.JK.client_to_server_instrument_map[clientInstrument]; inputsForTrack.instrument_id = instrument?.server_id @@ -244,6 +259,11 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev context.JK.Banner.showAlert('Unable to save assignments. ' + result); onAssociateVSTWithTrack: (vst) -> + + if !@hasVst + logger.debug("onAssociateVSTWithTrack skipped due to no VST") + return + if vst? logger.debug("associating track:#{@trackNumber} with VST:#{vst.file}") @@ -336,8 +356,13 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev break if @newTrack - # ensure that we always have an instrument set (50 = electric guitar - context.jamClient.TrackSetInstrument(@trackNumber, 50) + + assignment = context.jamClient.TrackGetInstrument(@trackNumber) + + if assignment == 0 + logger.debug("defaulting track instrument for assignment #{@trackNumber}") + # ensure that we always have an instrument set (50 = electric guitar + context.jamClient.TrackSetInstrument(@trackNumber, 50) @changed() diff --git a/web/config/application.rb b/web/config/application.rb index 5d9fc97d6..3ea3b0500 100644 --- a/web/config/application.rb +++ b/web/config/application.rb @@ -377,5 +377,7 @@ if defined?(Bundler) config.download_tracker_day_range = 30 config.max_user_ip_address = 10 config.max_multiple_users_same_ip = 2 + + config.vst_enabled = true end end diff --git a/web/config/environments/development.rb b/web/config/environments/development.rb index dbc9da309..fdfbb2d01 100644 --- a/web/config/environments/development.rb +++ b/web/config/environments/development.rb @@ -102,4 +102,6 @@ SampleApp::Application.configure do config.react.variant = :development config.time_shift_style = :sox # or sbsms + + config.vst_enabled = true end diff --git a/web/config/initializers/gon.rb b/web/config/initializers/gon.rb index ba60612db..d58d5fa10 100644 --- a/web/config/initializers/gon.rb +++ b/web/config/initializers/gon.rb @@ -22,4 +22,5 @@ Gon.global.jamtrack_landing_bubbles_enabled = Rails.application.config.jamtrack_ Gon.global.jamtrack_browser_bubbles_enabled = Rails.application.config.jamtrack_browser_bubbles_enabled Gon.global.bugsnag_key = Rails.application.config.bugsnag_key Gon.global.bugsnag_notify_release_stages = Rails.application.config.bugsnag_notify_release_stages +Gon.global.vst_enabled = Rails.application.config.vst_enabled Gon.global.env = Rails.env From bec9388aae86429a8fd595b8f8d375ab93f9794a Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 13 Nov 2015 15:35:13 -0600 Subject: [PATCH 09/15] * vst fixems --- .../ConfigureLiveTracksDialog.js.jsx.coffee | 14 ++++++++++++-- .../mixins/SessionMyTracksMixin.js.coffee | 10 +++++++++- .../stores/ConfigureTracksStore.js.coffee | 6 ++++++ .../dialogs/configureLiveTracksDialog.css.scss | 13 +++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee index 5beede426..ea4d5a7d7 100644 --- a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee @@ -37,8 +37,15 @@ ConfigureTracksStore = @ConfigureTracksStore instrumentDisabled = true vstDisabled = true + if @state.configureTracks? + if @state.configureTracks.scanningVsts + scan = + `
+
Scanning your system
for VST & AU plug-ins...
+
` + selectedInstrument = @state.configureTracks.editingTrack.instrument_id if @state.configureTracks.editingTrack.instrument_id? if @state.configureTracks.editingTrack.length == 1 @@ -113,6 +120,7 @@ ConfigureTracksStore = @ConfigureTracksStore + {scan}
` @@ -320,7 +328,8 @@ ConfigureTracksStore = @ConfigureTracksStore @ignoreICheck = true $root = $(@getDOMNode()) $radio = $root.find('input[type="radio"]') - $radio.iCheck('enable') + #$radio.iCheck('enable') + $radio.iCheck('disable') componentDidUpdate: () -> $root = $(@getDOMNode()) @@ -330,7 +339,8 @@ ConfigureTracksStore = @ConfigureTracksStore if @state.configureTracks.editingTrack.assignment == 1 $radio.iCheck('disable') else - $radio.iCheck('enable') + $radio.iCheck('disable') + #$radio.iCheck('enable') @ignoreICheck = false diff --git a/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee b/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee index 5b8f55e99..7fc97a850 100644 --- a/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee +++ b/web/app/assets/javascripts/react-components/mixins/SessionMyTracksMixin.js.coffee @@ -54,9 +54,17 @@ context = window associatedVst = null # find any VST info if hasMixer && @configureTracks? + + # bug in the backend; track is wrong for personal mixers (always 1), but correct for master mix + trackAssignment = -1 + if @props.mode == context.JK.MIX_MODES.MASTER + trackAssignment = mixerData.mixer.track + else + trackAssignment = mixerData.oppositeMixer?.track + console.log("checking associations", @configureTracks.vstTrackAssignments.vsts, mixerData.mixer) for vst in @configureTracks.vstTrackAssignments.vsts - if vst.track == mixerData.mixer.track - 1 && vst.name != 'NONE' + if vst.track == trackAssignment - 1 && vst.name != 'NONE' logger.debug("found VST on track", vst, track) associatedVst = vst break diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index 87339f22c..6a78c5955 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -31,6 +31,7 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev vstTrackAssignments: {vsts: []} attachedMidiDevices: {midiDevices: []} midiTrackAssignments: {tracks: []} + scanningVsts: false trackType: 'audio' init: () -> @@ -67,11 +68,14 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev onVstScan: () -> @performVstScan(true) + @changed() + performVstScan: (sendChanged) -> @hasVst = gon.global.vst_enabled & context.jamClient.hasVstHost() logger.debug("hasVst", @hasVst) if @hasVst logger.debug("vstScan starting") + @scanningVsts = true result = context.jamClient.VSTScan("window.ConfigureTracksStore.onVstScanComplete") logger.debug("vstScan completed", result) @@ -86,6 +90,7 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev onVstScanComplete: () -> setTimeout((() => + @scanningVsts = false @listVsts() @changed() ), 0) @@ -155,6 +160,7 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev nextTrackNumber: @nextTrackNumber, newTrack: @newTrack, midiTrackAssignments: @midiTrackAssignments, + scanningVsts: @scanningVsts, trackType: @trackType } diff --git a/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss index 684cd70b3..c69210e75 100644 --- a/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss +++ b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss @@ -150,4 +150,17 @@ a.button-orange { } } + + .vstScan { + + margin-top:20px; + + .spinner-small { + float:left; + } + + span { + font-size:12px; + } + } } \ No newline at end of file From c2772398a88915e6efb5efea5b1562a4f793a0c1 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Thu, 19 Nov 2015 22:07:38 -0600 Subject: [PATCH 10/15] * importer --- ruby/lib/jam_ruby/jam_track_importer.rb | 64 ++++++++++++++++--- web/app/assets/javascripts/backend_alerts.js | 3 + web/app/assets/javascripts/globals.js | 3 +- .../actions/ConfigureTracksActions.js.coffee | 1 + web/lib/tasks/jam_tracks.rake | 10 +++ 5 files changed, 71 insertions(+), 10 deletions(-) diff --git a/ruby/lib/jam_ruby/jam_track_importer.rb b/ruby/lib/jam_ruby/jam_track_importer.rb index 0cdf0160f..22b8fc929 100644 --- a/ruby/lib/jam_ruby/jam_track_importer.rb +++ b/ruby/lib/jam_ruby/jam_track_importer.rb @@ -29,6 +29,7 @@ module JamRuby end def finish(reason, detail) + @@log.info("JamTrackImporter:#{self.name} #{reason}") self.reason = reason self.detail = detail end @@ -231,6 +232,7 @@ module JamRuby original_artist = parsed_metalocation[1] name = parsed_metalocation[2] + JamTrackImporter.summaries[:unique_artists] << original_artist success = dry_run_metadata(metadata, original_artist, name) @@ -269,6 +271,11 @@ module JamRuby @storage_format == 'Tency' end + def is_tim_tracks_storage? + assert_storage_set + @storage_format == 'TimTracks' + end + def assert_storage_set raise "no storage_format set" if @storage_format.nil? end @@ -276,7 +283,7 @@ module JamRuby def parse_metalocation(metalocation) # metalocation = mapped/4 Non Blondes - What's Up - 6475/meta.yml - if is_tency_storage? + if is_tency_storage? || is_tim_tracks_storage? suffix = '/meta.yml' @@ -305,15 +312,20 @@ module JamRuby return nil end - last_dash = metalocation.rindex('-') - if last_dash - song = metalocation[(first_dash+3)...last_dash].strip - bits << song + if is_tim_tracks_storage? + song = metalocation[(first_dash+3)..-1].strip else - finish("invalid_metalocation", "metalocation not valid #{metalocation}") - return nil + last_dash = metalocation.rindex('-') + if last_dash + song = metalocation[(first_dash+3)...last_dash].strip + bits << song + else + finish("invalid_metalocation", "metalocation not valid #{metalocation}") + return nil + end end + bits << 'meta.yml' bits else @@ -516,6 +528,9 @@ module JamRuby jam_track.vendor_id = metadata[:id] jam_track.licensor = JamTrackLicensor.find_by_name('Tency Music') #add_licensor_metadata('Tency Music', metalocation) + elsif is_tim_tracks_storage? + jam_track.vendor_id = metadata[:id] + jam_track.licensor = JamTrackLicensor.find_by_name('Tim Waurick') end else if !options[:resync_audio] @@ -664,7 +679,7 @@ module JamRuby instrument = 'other' part = 'Bouzouki' elsif potential_instrument == 'claps' || potential_instrument == 'hand claps' - instrument = 'computer' + instrument = 'other' part = 'Claps' else found_instrument = Instrument.find_by_id(potential_instrument) @@ -774,7 +789,6 @@ module JamRuby end end end - end @@ -1606,6 +1620,8 @@ module JamRuby def song_storage_manager if is_tency_storage? tency_s3_manager + elsif is_tim_tracks_storage? + tim_tracks_s3_manager else s3_manager end @@ -1619,6 +1635,10 @@ module JamRuby @tency_s3_manager ||= S3Manager.new('jamkazam-tency', APP_CONFIG.aws_access_key_id, APP_CONFIG.aws_secret_access_key) end + def tim_tracks_s3_manager + @tim_tracks_s3_manager ||= S3Manager.new('jamkazam-timtracks', 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 @@ -1657,10 +1677,32 @@ module JamRuby @storage_format == 'Tency' end + def is_tim_tracks_storage? + assert_storage_set + @storage_format == 'TimTracks' + end + def assert_storage_set raise "no storage_format set" if @storage_format.nil? end + def iterate_tim_tracks_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_tency_song_storage(&blk) count = 0 song_storage_manager.list_directories('mapped').each do |song| @@ -1700,6 +1742,10 @@ module JamRuby iterate_tency_song_storage do |metadata, metalocation| blk.call(metadata, metalocation) end + elsif is_tim_tracks_storage? + iterate_tim_tracks_song_storage do |metadata, metalocation| + blk.call(metadata, metalocation) + end else iterate_default_song_storage do |metadata, metalocation| blk.call(metadata, metalocation) diff --git a/web/app/assets/javascripts/backend_alerts.js b/web/app/assets/javascripts/backend_alerts.js index bf5b1993b..2bd2b3737 100644 --- a/web/app/assets/javascripts/backend_alerts.js +++ b/web/app/assets/javascripts/backend_alerts.js @@ -137,6 +137,9 @@ else if(type === ALERT_NAMES.VIDEO_WINDOW_CLOSED) { context.VideoActions.videoWindowClosed() } + else if (type === ALERT_NAMES.VST_CHANGED) { + context.ConfigureTracksActions.onVstChanged() + } else if((!context.JK.CurrentSessionModel || !context.JK.CurrentSessionModel.inSession()) && (ALERT_NAMES.INPUT_IO_RATE == type || ALERT_NAMES.INPUT_IO_JTR == type || ALERT_NAMES.OUTPUT_IO_RATE == type || ALERT_NAMES.OUTPUT_IO_JTR== type)) { // squelch these events if not in session diff --git a/web/app/assets/javascripts/globals.js b/web/app/assets/javascripts/globals.js index 86e8972a0..f6e13e0d4 100644 --- a/web/app/assets/javascripts/globals.js +++ b/web/app/assets/javascripts/globals.js @@ -128,7 +128,8 @@ RECORDING_DONE :48, //the recording writer thread is done VIDEO_WINDOW_OPENED :49, //video window opened VIDEO_WINDOW_CLOSED :50, - LAST_ALERT : 51 + VST_CHANGED: 51, // VST state changed + LAST_ALERT : 52 } // recreate eThresholdType enum from MixerDialog.h context.JK.ALERT_TYPES = { diff --git a/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee index 4a2890385..7b5b3aa2d 100644 --- a/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee +++ b/web/app/assets/javascripts/react-components/actions/ConfigureTracksActions.js.coffee @@ -19,4 +19,5 @@ context = window associateVSTWithTrack: {} associateMIDIWithTrack: {} desiredTrackType: {} + vstChanged: {} }) diff --git a/web/lib/tasks/jam_tracks.rake b/web/lib/tasks/jam_tracks.rake index bbabe08e5..f8bdc47e0 100644 --- a/web/lib/tasks/jam_tracks.rake +++ b/web/lib/tasks/jam_tracks.rake @@ -9,6 +9,11 @@ namespace :jam_tracks do JamTrackImporter.dry_run end + task timtracks_dry_run: :environment do |task, args| + JamTrackImporter.storage_format = 'TimTracks' + JamTrackImporter.dry_run + end + task tency_create_masters: :environment do |task, args| JamTrackImporter.storage_format = 'Tency' JamTrackImporter.create_masters @@ -75,6 +80,11 @@ namespace :jam_tracks do JamTrackImporter.synchronize_all(skip_audio_upload:false) end + task sync_tim_tracks: :environment do |task, args| + JamTrackImporter.storage_format = 'TimTracks' + JamTrackImporter.synchronize_all(skip_audio_upload:false) + end + task tency_dups: :environment do |task, args| end From 83b7009c510440fa96b85e225d8cc5aa7c0c9982 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 20 Nov 2015 16:18:08 -0600 Subject: [PATCH 11/15] * wip --- web/app/assets/javascripts/globals.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/app/assets/javascripts/globals.js b/web/app/assets/javascripts/globals.js index f6e13e0d4..148b5ecc5 100644 --- a/web/app/assets/javascripts/globals.js +++ b/web/app/assets/javascripts/globals.js @@ -193,7 +193,8 @@ 48: {"title": "", "message": ""}, // RECORDING_DONE 49: {"title": "", "message": ""}, // VIDEO_WINDOW_OPENED 50: {"title": "", "message": ""}, // VIDEO_WINDOW_CLOSED - 51: {"title": "", "message": ""} // LAST_ALERT + 51: {"title": "", "message": ""}, // VST_CHANGED + 52: {"title": "", "message": ""} // LAST_ALERT }; // add the alert's name to the ALERT_TYPES structure From 143506afd56a78524733c64873da8183dec21c47 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Sat, 21 Nov 2015 15:29:15 -0600 Subject: [PATCH 12/15] * wip --- web/app/assets/javascripts/backend_alerts.js | 3 ++- .../stores/ConfigureTracksStore.js.coffee | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/web/app/assets/javascripts/backend_alerts.js b/web/app/assets/javascripts/backend_alerts.js index 2bd2b3737..705f9ec29 100644 --- a/web/app/assets/javascripts/backend_alerts.js +++ b/web/app/assets/javascripts/backend_alerts.js @@ -138,7 +138,8 @@ context.VideoActions.videoWindowClosed() } else if (type === ALERT_NAMES.VST_CHANGED) { - context.ConfigureTracksActions.onVstChanged() + console.log("VST CHANGED!") + context.ConfigureTracksActions.vstChanged() } else if((!context.JK.CurrentSessionModel || !context.JK.CurrentSessionModel.inSession()) && (ALERT_NAMES.INPUT_IO_RATE == type || ALERT_NAMES.INPUT_IO_JTR == type || ALERT_NAMES.OUTPUT_IO_RATE == type || ALERT_NAMES.OUTPUT_IO_JTR== type)) { diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index 6a78c5955..e53fc4b70 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -77,7 +77,6 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev logger.debug("vstScan starting") @scanningVsts = true result = context.jamClient.VSTScan("window.ConfigureTracksStore.onVstScanComplete") - logger.debug("vstScan completed", result) onClearVsts: () -> context.jamClient.VSTClearAll() @@ -89,10 +88,21 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev ), 250) onVstScanComplete: () -> + # XXX must wait a long time to get track assignments after scan/ + console.log("vst scan complete") setTimeout((() => @scanningVsts = false @listVsts() @changed() + ), 1000 ) + + onVstChanged: () -> + seTitemout() + logger.debug("vst changed") + + setTimeout((() => + @listVsts() + @changed() ), 0) listVsts: () -> From dd8e3757665f3190aaddd2c47bcd29c754894005 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 4 Dec 2015 12:08:40 -0600 Subject: [PATCH 13/15] * scan weirdness --- .../stores/ConfigureTracksStore.js.coffee | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index e53fc4b70..ed27b9b74 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -90,11 +90,12 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev onVstScanComplete: () -> # XXX must wait a long time to get track assignments after scan/ console.log("vst scan complete") + @scanningVsts = false setTimeout((() => - @scanningVsts = false + console.log("!!") @listVsts() @changed() - ), 1000 ) + ), 1000 ) onVstChanged: () -> seTitemout() @@ -156,6 +157,10 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev @editingTrack.midiDeviceIndex = vst.midiDeviceIndex break + for inputsForTrack in @trackAssignments.inputs.assigned + if vst.track == inputsForTrack.assignment - 1 + inputsForTrack.vst = vst + if @editingTrack.vst? logger.debug("current track has a VST assigned:" + @editingTrack.vst.file) From 6d5db83aea95975166c306d75a64d6ebf98abcaa Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 4 Dec 2015 15:29:59 -0600 Subject: [PATCH 14/15] * midi not working still --- .../dialog/configureTrackDialog.js | 8 ++-- .../ConfigureLiveTracksDialog.js.jsx.coffee | 42 +++++++++++++++---- .../stores/ConfigureTracksStore.js.coffee | 25 +++++++---- .../stores/SessionStore.js.coffee | 2 +- .../wizard/gear/step_configure_tracks.js | 2 +- .../configureLiveTracksDialog.css.scss | 18 ++++++++ 6 files changed, 75 insertions(+), 22 deletions(-) diff --git a/web/app/assets/javascripts/dialog/configureTrackDialog.js b/web/app/assets/javascripts/dialog/configureTrackDialog.js index 421cb1d3c..17989b205 100644 --- a/web/app/assets/javascripts/dialog/configureTrackDialog.js +++ b/web/app/assets/javascripts/dialog/configureTrackDialog.js @@ -103,7 +103,7 @@ $musicAudioTabSelector.click(function () { // validate voice chat settings if (validateVoiceChatSettings()) { - window.ConfigureTracksActions.reset(); + window.ConfigureTracksActions.reset(false); voiceChatHelper.reset(); showMusicAudioPanel(); } @@ -113,7 +113,7 @@ // validate audio settings if (validateAudioSettings()) { logger.debug("initializing voice chat helper") - window.ConfigureTracksActions.reset(); + window.ConfigureTracksActions.reset(false); voiceChatHelper.reset(); showVoiceChatPanel(); } @@ -183,7 +183,7 @@ currentProfile = profile; - window.ConfigureTracksActions.reset(); + window.ConfigureTracksActions.reset(false); } function beforeShow() { @@ -207,7 +207,7 @@ return; } - window.ConfigureTracksActions.reset(); + window.ConfigureTracksActions.reset(false); voiceChatHelper.reset(); voiceChatHelper.beforeShow(); } diff --git a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee index ea4d5a7d7..3bc426721 100644 --- a/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ConfigureLiveTracksDialog.js.jsx.coffee @@ -257,14 +257,13 @@ ConfigureTracksStore = @ConfigureTracksStore $root = $(@getDOMNode()) $select = $root.find('select.vsts') vstSelected = $select.val() - if vstSelected? + if vstSelected != 'NONE' vstSelected = {file: vstSelected} - ConfigureTracksActions.associateVSTWithTrack(vstSelected) - if @state.configureTracks?.trackType == 'midi' - if @state.midiInterface? - ConfigureTracksActions.associateMIDIWithTrack(@state.midiInterface) + @updateMidiAssociations() + else + ConfigureTracksActions.associateVSTWithTrack(vstSelected) @setState({midiInterface: null}) @@ -329,7 +328,7 @@ ConfigureTracksStore = @ConfigureTracksStore $root = $(@getDOMNode()) $radio = $root.find('input[type="radio"]') #$radio.iCheck('enable') - $radio.iCheck('disable') + $radio.iCheck('enable') componentDidUpdate: () -> $root = $(@getDOMNode()) @@ -339,8 +338,7 @@ ConfigureTracksStore = @ConfigureTracksStore if @state.configureTracks.editingTrack.assignment == 1 $radio.iCheck('disable') else - $radio.iCheck('disable') - #$radio.iCheck('enable') + $radio.iCheck('enable') @ignoreICheck = false @@ -382,14 +380,40 @@ ConfigureTracksStore = @ConfigureTracksStore midiInterfaceChanged: (e) -> + + @updateMidiAssociations() + + updateMidiAssociations: (e) -> $root = $(@getDOMNode()) $select = $root.find('select.midi-select') midiInterface = $select.val() + $select = $root.find('select.vsts') + vstSelected = $select.val() + + logger.debug("updateMidiAssocations", vstSelected, midiInterface) + if vstSelected != 'NONE' + vstSelected = {file: vstSelected} + else + vstSelected = null + if midiInterface == '' midiInterface = null - ConfigureTracksActions.associateMIDIWithTrack(midiInterface) + midi = @state.midiInterface || midiInterface + + if vstSelected? && midi? + logger.debug("updating midi:#{midi} & vst: #{vstSelected.file}") + + ConfigureTracksActions.associateVSTWithTrack(vstSelected) + setTimeout((() => + ConfigureTracksActions.associateMIDIWithTrack(midi) + ), 250) + + else if midi? + logger.debug("updating midi:#{midiInterface}") + ConfigureTracksActions.associateMIDIWithTrack(midiInterface) @setState({midiInterface: midiInterface}) + }) \ No newline at end of file diff --git a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee index ed27b9b74..b3c2b23a0 100644 --- a/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/ConfigureTracksStore.js.coffee @@ -48,14 +48,16 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev @loadTrackInstruments() @changed() - onReset: () -> + onReset: (force) -> logger.debug("ConfigureTracksStore:reset", this) @trackNumber = null @editingTrack = null @loadChannels() @loadTrackInstruments() - @performVstScan() - @performMidiScan() + + if force || context.jamClient.hasVstAssignment() + @performVstScan() + @performMidiScan() @changed() @@ -92,13 +94,12 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev console.log("vst scan complete") @scanningVsts = false setTimeout((() => - console.log("!!") @listVsts() @changed() - ), 1000 ) + ), 100 ) onVstChanged: () -> - seTitemout() + setTimeout() logger.debug("vst changed") setTimeout((() => @@ -164,6 +165,9 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev if @editingTrack.vst? logger.debug("current track has a VST assigned:" + @editingTrack.vst.file) + logger.debug("trackAssignments:", @trackAssignments) + logger.debug("editingTrack:", @editingTrack) + @item = { musicPorts: @musicPorts, trackAssignments: @trackAssignments, @@ -286,7 +290,7 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev return if vst? - logger.debug("associating track:#{@trackNumber} with VST:#{vst.file}") + logger.debug("associating track:#{@trackNumber - 1} with VST:#{vst.file}") found = null for knownVst in @vstPluginList.vsts @@ -385,6 +389,9 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev # ensure that we always have an instrument set (50 = electric guitar context.jamClient.TrackSetInstrument(@trackNumber, 50) + @performVstScan() + @performMidiScan() + @changed() @app.layout.showDialog('configure-live-tracks-dialog') @@ -392,6 +399,8 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev onDesiredTrackType: (trackType) -> @trackType = trackType + if @trackType == 'midi' + @trackNumber = 100 @changed() onUpdateOutputs: (outputId1, outputId2) -> @@ -411,6 +420,8 @@ bool VST_EnableMidiForTrack(const QString& trackId, bool enableMidi, int midiDev onAssociateMIDIWithTrack: (midiInterface) -> + @trackNumber = 100 + if !midiInterface? || midiInterface == '' logger.debug("disabling midiInterface:#{midiInterface}, track:#{@trackNumber - 1}") context.jamClient.VST_EnableMidiForTrack(@trackNumber - 1, false, 0) 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 08e291141..8ef0c06cb 100644 --- a/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee @@ -733,7 +733,7 @@ ConfigureTracksActions = @ConfigureTracksActions @handleAutoOpenJamTrack() - ConfigureTracksActions.reset() + ConfigureTracksActions.reset(false) ) .fail((xhr) => @updateCurrentSession(null) diff --git a/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js b/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js index e40b81609..72e97aad3 100644 --- a/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js +++ b/web/app/assets/javascripts/wizard/gear/step_configure_tracks.js @@ -38,7 +38,7 @@ function beforeShow() { var forceInputsToUnassigned = !successfullyAssignedOnce; - window.ConfigureTracksActions.reset(forceInputsToUnassigned, wizard.getChosenInputs()); + window.ConfigureTracksActions.reset(false); //configureTracksHelper.reset(forceInputsToUnassigned, wizard.getChosenInputs()) } diff --git a/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss index c69210e75..212e6869d 100644 --- a/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss +++ b/web/app/assets/stylesheets/dialogs/configureLiveTracksDialog.css.scss @@ -111,6 +111,24 @@ width:80%; margin-bottom:10px; } + + .down-arrow { + cursor:pointer; + width: 0; + height: 0; + border-left: 8px solid transparent; + border-right: 8px solid transparent; + border-top: 8px solid #fc0; + position: relative; + top: -8px; + right: -125px; + } + + .settings-holder { + float: right; + margin-right: 65px; + margin-top: -1px; + } } .audio-effects { width:40%; From 1d3548cdf9e0eac3a1b4704f96968c8dc0e5ebb8 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Tue, 8 Dec 2015 13:37:18 -0600 Subject: [PATCH 15/15] * fix misnamed active music sessions var --- ruby/lib/jam_ruby/connection_manager.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/lib/jam_ruby/connection_manager.rb b/ruby/lib/jam_ruby/connection_manager.rb index 748e50eb9..12a915ce3 100644 --- a/ruby/lib/jam_ruby/connection_manager.rb +++ b/ruby/lib/jam_ruby/connection_manager.rb @@ -386,7 +386,7 @@ SQL end # go by who joined earliest - earliest = active_music_sessions.connections.order(:joined_session_at).first + earliest = active_music_session.connections.order(:joined_session_at).first if earliest music_session.session_controller = earliest