-
-
@@ -103,7 +114,7 @@ mixins.push(Reflux.listenTo(ExternalVideoStore, "onExternalVideoStateChanged"))
-
+
-
+
@@ -130,18 +141,31 @@ mixins.push(Reflux.listenTo(ExternalVideoStore, "onExternalVideoStateChanged"))
context.JK.dropdown($root.find('select'))
- $includeChatCheckbox = $root.find('#include-chat')
- context.JK.checkbox($includeChatCheckbox)
-
$inputAudioRadioBtn = $root.find('#recording-input-audio')
- context.JK.checkbox($inputAudioRadioBtn)
+ $inputBothRadioBtn = $root.find('#recording-input-both')
- $inputBothRadioBtn = $root.find('#recording-input-both')
+ #only enable audio & video radio button if a video is ongoing
$inputBothRadioBtn.iCheck().attr('disabled', !context.JK.videoIsOngoing)
- context.JK.checkbox($inputBothRadioBtn)
+ # if @state.recordingInputType == 'audio-video'
+ # $inputBothRadioBtn.iCheck('check').attr('checked', true)
+ # else
+ # $inputAudioRadioBtn.iCheck('check').attr('checked', true)
+
+ $inputBothRadioBtn.prop('disabled',true).iCheck('update').iCheck('uncheck');
+
+ context.JK.checkbox($inputAudioRadioBtn)
+ context.JK.checkbox($inputBothRadioBtn)
+
+ $includeChatCheckbox = $root.find('#include-chat')
+ $includeChatCheckbox.iCheck('check').attr('checked', @state.includeChat)
+ $includeChatCheckbox.on 'ifToggled', (e) =>
+ @setState(includeChat: e.target.checked)
+ context.JK.checkbox($includeChatCheckbox)
componentDidUpdate: () ->
$root = $(this.getDOMNode())
context.JK.dropdown($root.find('select'))
+ $root.find('#audio-format').unbind('change').change(this.setAudioFormatChange)
+ $root.find('#video-format').unbind('change').change(this.setVideoFormatChange)
})
\ No newline at end of file
diff --git a/web/app/assets/javascripts/react-components/SessionRecordingVu.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionRecordingVu.js.jsx.coffee
index 9d8fe5dc4..58adb1536 100644
--- a/web/app/assets/javascripts/react-components/SessionRecordingVu.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/SessionRecordingVu.js.jsx.coffee
@@ -4,7 +4,7 @@ mixins = []
MixerStore = context.MixerStore
-mixins.push(Reflux.listenTo(MixerStore,"onInputChanged"))
+mixins.push(Reflux.listenTo(SessionMyTracksStore,"onInputChanged"))
@SessionRecordingVu = React.createClass({
mixins: mixins
@@ -17,16 +17,15 @@ mixins.push(Reflux.listenTo(MixerStore,"onInputChanged"))
categoryMixers = mixers.simulatedMusicCategoryMixers[MIX_MODES.PERSONAL]
if categoryMixers
inputGroupMixers = categoryMixers
-
@setState({mixers: inputGroupMixers})
getInitialState: () ->
{ mixers: @props.mixers }
- render: () ->
- monitorMuteMixer = @props.mixers.muteMixer[0]
+ renderVu: () ->
+ monitorMuteMixer = @state.mixers.muteMixer[0]
monitorMuteMixerId = mixers?.id
- monitorVolumeLeft = @props.mixers.mixer[0].volume_left
+ monitorVolumeLeft = @state.mixers.mixer[0].volume_left
monitorMuteClasses = classNames({
'track-icon-mute': true
'enabled' : !monitorMuteMixer?.mute
@@ -38,7 +37,6 @@ mixins.push(Reflux.listenTo(MixerStore,"onInputChanged"))
Volume:
-
@@ -63,17 +61,19 @@ mixins.push(Reflux.listenTo(MixerStore,"onInputChanged"))
To change the volume of individual tracks in the mix, use the personal mix controls in the session window.
-
- `
+
`
+
+ render: () ->
+ if Object.keys(@state.mixers).length > 0 then @renderVu() else `
Loading...`
handleAudioInputMute: (e) ->
e.preventDefault()
muting = $(e.currentTarget).is('.enabled')
- MixerActions.mute(@props.mixers.muteMixer, muting)
+ MixerActions.mute(@state.mixers.muteMixer, muting)
handleAudioInputMuteCheckbox: (e) ->
muting = $(e.target).is(':checked')
- MixerActions.mute(@props.mixers.muteMixer, muting)
+ MixerActions.mute(@state.mixers.muteMixer, muting)
componentDidMount: () ->
$root = jQuery(this.getDOMNode())
@@ -83,7 +83,7 @@ mixins.push(Reflux.listenTo(MixerStore,"onInputChanged"))
context.JK.checkbox($audioInputMuteCheckbox)
$audioInputMuteCheckbox.on('ifChanged', @handleAudioInputMuteCheckbox)
- if @props.mixers.muteMixer[0].mute
+ if @state.mixers.muteMixer[0].mute
$audioInputMuteCheckbox.iCheck('check').attr('checked', true)
else
$audioInputMuteCheckbox.iCheck('uncheck').attr('checked', false)
diff --git a/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx.coffee b/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx.coffee
index d4a277618..906e9758c 100644
--- a/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx.coffee
@@ -14,15 +14,17 @@ BackendToFrontendFPS = {
@RecordingStore = Reflux.createStore(
{
listenables: @RecordingActions
- recordingWindow: null
+ #recordingWindow: null
+ recordingWindowOpened: false
init: ->
# Register with the app store to get @app
this.listenTo(context.AppStore, this.onAppInit)
onSessionEnded: () ->
- if @recordingWindow?
- @recordingWindow.close()
+ if @recordingWindowOpened
+ #@recordingWindow.close()
+ @closeRecordingWindow()
onAppInit: (app) ->
@app = app
@@ -46,7 +48,6 @@ BackendToFrontendFPS = {
# @recordingModel.startRecording(recordVideo, recordChat, frameRate)
onStartRecording: `async function(recordVideo, recordChat) {
- console.log("onStartRecording...", recordVideo, recordChat)
let frameRate = 0;
if (recordVideo) {
//if (await context.jamClient.GetCurrentVideoFrameRate() != null) {
@@ -58,7 +59,6 @@ BackendToFrontendFPS = {
const WebCamRecordActive = 1;
const ScreenRecordActive = 2;
logger.debug('onStartRecording: recordVideo: '+recordVideo+' , recordChat:' +recordChat+' frameRate: '+frameRate);
- //logger.debug('this.recordingModel', this.recordingModel)
this.recordingModel.startRecording(recordVideo, recordChat, frameRate);
}`
@@ -69,15 +69,15 @@ BackendToFrontendFPS = {
details.cause = 'starting'
@mixTransferred = false
this.trigger(details)
-
- @popupRecordingControls() unless @recordingWindow?
+ @popupRecordingControls() unless @recordingWindowOpened
onStartedRecording: (details) ->
details.cause = 'started'
@mixTransferred = false
this.trigger(details)
- @popupRecordingControls() unless @recordingWindow?
+ #@popupRecordingControls() unless @recordingWindowOpened
+ @closeRecordingWindow() if @recordingWindowOpened
onStoppingRecording: (details) ->
details.cause = 'stopping'
@@ -86,31 +86,33 @@ BackendToFrontendFPS = {
onStoppedRecording: (details) ->
details.cause = 'stopped'
-
- if @recordingWindow?
- @recordingWindow.close()
+ if @recordingWindowOpened
+ #@recordingWindow.close()
+ @closeRecordingWindow()
this.trigger(details)
onAbortedRecording: (details) ->
details.cause = 'aborted'
- if @recordingWindow?
- @recordingWindow.close()
+ if @recordingWindowOpened
+ #@recordingWindow.close()
+ @closeRecordingWindow()
this.trigger(details)
onOpenRecordingControls: () ->
logger.debug("recording controls opening")
-
- if @recordingWindow?
- @recordingWindow.close()
+ if @recordingWindowOpened
+ #@recordingWindow.close()
+ @closeRecordingWindow()
@popupRecordingControls()
onRecordingControlsClosed: () ->
logger.debug("recording controls closed")
- @recordingWindow = null
+ #@recordingWindow = null
+ @recordingWindowOpened = false
onMixTransferred: () ->
@mixTransferred = true
@@ -121,6 +123,10 @@ BackendToFrontendFPS = {
#@recordingWindow.ParentRecordingStore = context.RecordingStore
#@recordingWindow.ParentIsRecording = @recordingModel.isRecording()
@app.layout.showDialog('session-recording', {})
+ @recordingWindowOpened = true
+ closeRecordingWindow: () ->
+ @app.layout.cancelDialog('session-recording');
+ @recordingWindowOpened = false
}
)
diff --git a/web/spec/features/session_recording_spec.rb b/web/spec/features/session_recording_spec.rb
new file mode 100644
index 000000000..e6a9fa912
--- /dev/null
+++ b/web/spec/features/session_recording_spec.rb
@@ -0,0 +1,46 @@
+require 'spec_helper'
+
+describe "Session Recording", :js => true, :type => :feature, :capybara_feature => true do
+ subject { page }
+
+ before(:all) do
+ #Capybara.javascript_driver = :poltergeist
+ #Capybara.current_driver = Capybara.javascript_driver
+ #Capybara.default_max_wait_time = 30 # these tests are SLOOOOOW
+ end
+
+ let(:creator) { FactoryGirl.create(:user) }
+
+ before(:each) do
+ ActiveMusicSession.delete_all
+ end
+
+ it "video checkbox is diabled if video session is not started" do
+ creator.subscription_plan_code = SubscriptionDefinitions::JAM_PLATINUM
+ creator.subscription_trial_ends_at = 1.day.ago
+ creator.admin_override_plan_code = SubscriptionDefinitions::JAM_PLATINUM
+ creator.admin_override_ends_at = 1.day.from_now
+ creator.save!
+
+ create_new_session(creator: creator, include_video: true) do
+ expect(page.find("input#recording-input-both")).not_to be_checked
+ # page.find('.btnCancel').click
+ # video_window = page.window_opened_by do
+ # page.find('.in-session-controls a.session-video-btn').click
+ # end
+ # sleep 1
+ # within_window(video_window) do
+ # click_link "JOIN ROOM"
+ # end
+ # sleep 1
+ end
+ end
+
+ it "start/stop recording", focus: true do
+ create_new_session(creator: creator) do
+ page.find('.recording-left .form-actions a', text: 'START RECORDING').click
+ page.find('.in-session-controls a.session-record-btn', text: 'STOP RECORDING').click
+ page.find('.in-session-controls a.session-record-btn', text: 'RECORD')
+ end
+ end
+end
\ No newline at end of file
diff --git a/web/spec/support/utilities.rb b/web/spec/support/utilities.rb
index b48177a59..ca17b81f8 100644
--- a/web/spec/support/utilities.rb
+++ b/web/spec/support/utilities.rb
@@ -344,8 +344,8 @@ end
# will select the value from a easydropdown'ed select element
def jk_select(text, select)
# the approach here is to find the hidden select element, and work way back up to the elements that need to be interacted with
- find(select, :visible => false).find(:xpath, 'ancestor::div[contains(@class, "dropdown easydropdown") and not(contains(@class, "disabled"))]').trigger(:click)
- find(select, :visible => false).find(:xpath, 'ancestor::div[contains(@class, "dropdown-wrapper") and contains(@class, "easydropdown-wrapper") and contains(@class, "open") ]').find('li', text: text).trigger(:click)
+ find(select, :visible => false).find(:xpath, 'ancestor::div[contains(@class, "dropdown easydropdown") and not(contains(@class, "disabled"))]').click
+ find(select, :visible => false).find(:xpath, 'ancestor::div[contains(@class, "dropdown-wrapper") and contains(@class, "easydropdown-wrapper") and contains(@class, "open") ]').find('li', text: text).click
# works, but is 'cheating' because of visible = false
#select(genre, :from => 'genres', :visible => false)
@@ -418,6 +418,78 @@ def create_session(options={})
end
+#===START test helpers for session creation and recording windows===
+def create_new_session(options={}, &block)
+ creator = options[:creator] || FactoryGirl.create(:user)
+ unique_session_name = options[:name] || "create_join_session #{SecureRandom.urlsafe_base64}"
+ audio_format = options[:audio_format] || '.mp3'
+ video_format = options[:video_format] || '.mp4'
+ audio_delay = options[:audio_delay] || 0
+ include_voice_chat = options[:include_voice_chat] || false
+ include_video = options[:include_video] || false
+
+ in_client(creator) do
+ #page.driver.resize(1500, 800) # makes sure all the elements are visible
+ emulate_client
+ fast_signin(creator, "/client#/createSession")
+ expect(page).to have_selector('h1', text: 'sessions')
+
+ find('a.quick-start-solo').click()
+ find('.in-session-controls a.session-record-btn').click()
+
+ within('#session-recording') do
+ expect(page).to have_selector('h1', text: 'recording')
+ expect(page).to have_selector('a', text: 'START RECORDING')
+
+ if include_video
+ find('.recording-type-both ins.iCheck-helper').click
+ end
+ fill_in('Name', :with => unique_session_name)
+ jk_select(audio_format, 'select#audio-format')
+ jk_select(video_format, 'select#video-format')
+ fill_in('Audio Delay (ms)', :with => audio_delay)
+ if include_voice_chat
+ find('.include-chat-check ins.iCheck-helper').click
+ end
+ end
+ yield
+ end
+ return creator, unique_session_name
+end
+
+def create_session_and_join(creator, joiners=[], options={})
+ options[:creator] = creator
+ creator, unique_session_name = create_new_session(options)
+
+ # find session in second client
+ [*joiners].each do |joiner|
+ join_session(joiner, name: unique_session_name)
+ end
+
+ return creator, unique_session_name
+end
+
+def join_with_session(joiner, options)
+ name = options[:name]
+
+ in_client(joiner) do
+ #page.driver.resize(1500, 800) # makes sure all the elements are visible
+ emulate_client
+ fast_signin(joiner, "/client#/findSession")
+
+ # verify the session name is seen by second client
+ expect(page).to have_text(name)
+ find('.join-link').click
+ unless options[:no_verify]
+ find('#btn-accept-terms').click
+ expect(page).to have_selector('h2', text: 'my live tracks')
+ find('#session-screen .session-my-tracks .session-track.my-track')
+ end
+ end
+
+end
+#===END test helpers for session creation and recording windows===
+
def schedule_session(options = {})
creator = options[:creator] || FactoryGirl.create(:user)
unique_session_name = options[:name] || "schedule_session #{SecureRandom.urlsafe_base64}"