jam-cloud/web/app/assets/javascripts/react-components/PopupRecordingStartStop.js....

295 lines
9.4 KiB
CoffeeScript

context = window
logger = context.JK.logger
NoVideoRecordActive = 0
WebCamRecordActive = 1
ScreenRecordActive = 2
WebCam2RecordActive = 3
DesktopRecordActive = 4
recording_sources = [WebCamRecordActive, WebCam2RecordActive, ScreenRecordActive, DesktopRecordActive]
recording_data = {
2: {key: 'video-window', text: 'Record session video window'},
1: {key: 'webcam-only', text: 'Record my webcam only'},
3: {key: 'webcam-only-2', text: 'Record my 2nd webcam only'},
4: {key: 'desktop-only', text: 'Record my computer desktop'}
}
mixins = []
# make sure this is actually us opening the window, not someone else (by checking for MixerStore)
# this check ensures we attempt to listen if this component is created in a popup
reactContext = if window.opener? then window.opener else window
accessOpener = false
if window.opener?
try
m = window.opener.MixerStore
accessOpener = true
catch e
reactContext = window
MixerStore = reactContext.MixerStore
RecordingStore = reactContext.RecordingStore
VideoStore = reactContext.VideoStore
if accessOpener
mixins.push(Reflux.listenTo(RecordingStore,"onRecordingStateChanged"))
# mixins.push(Reflux.listenTo(MixerStore,"onMixersChanged"))
@PopupRecordingStartStop = React.createClass({
mixins: mixins
#onMixersChanged: (mixers) ->
# this.setState(chatMixer: mixers.chatMixer)
onRecordingStateChanged: (recordingState) ->
if @unloaded
#console.log("PopupMediaControls unloaded. ignore onMixersChnaged")
return
this.setState(isRecording: recordingState.isRecording, recordedOnce: this.state.recordedOnce || recordingState.isRecording)
startStopRecording: () ->
if this.state.isRecording
window.opener.RecordingActions.stopRecording()
else
recordChat = false
recordVideo = NoVideoRecordActive
$root = $(this.getDOMNode())
if @inputType != 'audio-only'
selection = $root.find('#recording-selection').val()
if selection == 'video-window'
recordVideo = ScreenRecordActive
else if selection == 'webcam-only'
recordVideo = WebCamRecordActive
else if selection == 'webcam-only-2'
recordVideo = WebCam2RecordActive
else
recordVideo = DesktopRecordActive
recordChat = $root.find('#include-chat').is(':checked')
# if the video window isn't open, but a video option was selected...
window.opener.VideoActions.refreshVideoState.trigger()
if recordVideo != NoVideoRecordActive && !VideoStore.anyVideoOpen
#if recordVideo != NoVideoRecordActive && !VideoStore.videoShared
logger.debug("prevent video from opening", VideoStore)
context.JK.prodBubble($root.find('.control'), 'video-window-not-open', {}, {positions:['bottom']})
return
if recordVideo == WebCamRecordActive && !VideoStore.openVideoSources.webcam1
context.JK.prodBubble($root.find('.control'), 'no-webcam-1', {}, {positions:['bottom']})
return
if recordVideo == WebCam2RecordActive && !VideoStore.openVideoSources.webcam2
context.JK.prodBubble($root.find('.control'), 'no-webcam-2', {}, {positions:['bottom']})
return
if recordVideo == DesktopRecordActive && !VideoStore.openVideoSources.screen_capture
context.JK.prodBubble($root.find('.control'), 'no-screen-capture', {}, {positions:['bottom']})
return
logger.debug("@inputType, @udiotye", recordChat, recordVideo)
window.opener.RecordingActions.startRecording(recordVideo, recordChat)
onNoteShowHide: () ->
$root = $(this.getDOMNode())
audioVideoValue = $root.find('input[name="recording-input-type"]').val()
console.log("audio video value", audioVideoValue)
this.setState(showNote: !this.state.showNote)
getInitialState: () ->
{isRecording: window.ParentIsRecording, showNote: true, recordedOnce: false, chatMixer: MixerStore.mixers?.chatMixer, openWindows: []}
render: () ->
recordingVerb = if this.state.isRecording then 'Stop' else 'Start'
recordingBtnClasses = classNames({
"currently-recording" : this.state.isRecording,
"control" : true
})
noteJSX = `<div className="important-note">
<h5>
Important Note
</h5>
<div className="contents">
While playing in your session, you are listening to your own personal mix. This recording will use the master mix,
which may sound very different. To hear and adjust your master mix settings, click the MIXER button in the session toolbar.
</div>
</div>`
chatHelp = `<a href="#" onClick={this.onChatHelp} className="chat-help">[?]</a>`
options = []
for source in recording_sources
if this.state.openWindows?
found = this.state.openWindows.indexOf(source) > -1
if found
data = recording_data[source]
options.push(`<option value={data.key}>{data.text}</option>`)
recordingJSX =
`<div className="recording-options">
<div className="video-settings">
<h3>Recording Type</h3>
<div className="field">
<input type="radio" name="recording-input-type" id="recording-input-audio" value="audio-only" defaultChecked="checked" />
<label htmlFor="recording-input-audio">Audio only</label>
<div className="clearall"></div>
</div>
<div className="field">
<input type="radio" name="recording-input-type" id="recording-input-both" value="audio-video" />
<label htmlFor="recording-input-both">Audio and video</label>
<div className="clearall"></div>
</div>
<div className="field">
<select className="easydropdown" name="recording-selection" id="recording-selection">
{options}
</select>
</div>
</div>
<div className="audio-settings">
<input type="checkbox" name="include-chat" id="include-chat" /><label htmlFor="include-chat">Include voice chat in recorded audio {chatHelp}</label>
</div>
</div>`
if this.state.showNote
noteText = 'hide note'
else
noteText = 'show note'
noteShowHideJSX = `<a href="#" className="note-show-hide" onClick={this.onNoteShowHide}>{noteText}</a>`
note = null
recordingOptions = null
noteShowHide = null
if this.state.showNote && !this.state.isRecording && !this.state.recordedOnce
# should we show the note itself? Only if not recording, too
note = noteJSX
if !this.state.isRecording && !this.state.recordedOnce
noteShowHide = noteShowHideJSX
if gon.global.video_available == "full"
recordingOptions = recordingJSX
`<div className="recording-start-stop">
<div className="control-holder">
<a className={recordingBtnClasses} onClick={this.startStopRecording}>
<span className="helper" />
<img src="/assets/content/recordbutton-off.png" width="20" height="20" />
<span id="recording-status">{recordingVerb} Recording</span>
</a>
</div>
{recordingOptions}
{note}
{noteShowHide}
</div>`
windowUnloaded: () ->
@unloaded = true
window.unloaded = true
window.opener.RecordingActions.recordingControlsClosed()
onChatHelp: (e) ->
e.preventDefault()
context.JK.prodBubble($(e.target), 'vid-record-chat-input', {}, {positions:['left']})
trackInputType: (e) ->
$checkedType = $(e.target);
@inputType = $checkedType.val()
logger.debug("updated @inputType",e.target, @inputType)
trackAudioType: (e) ->
$checkedType = $(e.target);
@audioType = $checkedType.val()
logger.debug("updated @audioType", @inputType)
componentDidMount: () ->
$(window).unload(@windowUnloaded)
$root = jQuery(this.getDOMNode())
$recordingType = $root.find('input[type="radio"]')
context.JK.checkbox($recordingType)
@inputType = 'audio-only'
@audioType = 'audio-only'
$root.find('input[name="recording-input-type"]').on('ifChanged', @trackInputType)
$root.find('input[name="recording-input-chat-option"]').on('ifChanged', @trackAudioType)
$recordingRegion = $root.find('#recording-selection')
#console.log("$recordingou", $recordingRegion)
#context.JK.dropdown($recordingRegion)
$includeChat = $root.find('#include-chat')
context.JK.checkbox($includeChat)
openWindows = window.opener.jamClient.getOpenVideoSources()
console.log("open video sources", openWindows)
fixedwindows = []
if openWindows?
for key, value of openWindows
fixedwindows.push(value)
this.setState({openWindows: fixedwindows})
@resizeWindow()
# this is necessary due to whatever the client's rendering behavior is.
setTimeout(@resizeWindow, 300)
componentDidUpdate: () ->
@resizeWindow()
$root = jQuery(this.getDOMNode())
$includeChat = $root.find('#include-chat')
shouldComponentUpdate: () ->
return !@unloaded
resizeWindow: () =>
$container = $('#minimal-container')
width = $container.width()
height = $container.height()
# there is 20px or so of unused space at the top of the page. can't figure out why it's there. (above #minimal-container)
mysteryTopMargin = 20
# deal with chrome in real browsers
offset = (window.outerHeight - window.innerHeight) + mysteryTopMargin
# handle native client chrome that the above outer-inner doesn't catch
#if navigator.userAgent.indexOf('JamKazam') > -1
#offset += 25
window.resizeTo(width, height + offset)
})