context = window logger = context.JK.logger reactContext = if window.opener? then window.opener else window # make sure this is actually us opening the window, not someone else (by checking for MixerStore) if window.opener? try m = window.opener.MixerStore catch e reactContext = window userAgent = window.navigator.userAgent; if /iPhone|iPad|iPod|android/i.test(navigator.userAgent) # iPad or iPhone reactContext = window VideoStore = reactContext.VideoStore VideoActions = reactContext.VideoActions PlatformStore = reactContext.PlatformStore ALERT_NAMES = context.JK.ALERT_NAMES; BackendNumericToBackendString = { 1 : "CIF (352X288)", 2 : "VGA (640X480)", 3 : "4CIF (704X576)", 4 : "1/2WHD (640X360)", 5 : "WHD (1280X720)", 6 : "FHD (1920x1080)" } BackendToFrontendFPS = { 1: 30, 2: 24, 3: 20, 4: 15, 5: 10 } mixins = [] mixins.push(Reflux.listenTo(VideoStore, 'onVideoStateChanged')) @WebcamViewer = React.createClass({ mixins: mixins logger: context.JK.logger visible: false getInitialState: () -> { currentDevice: null deviceNames: {} deviceCaps: null currentCaptureResolution: 0 captureResolutions: {} frameRates: {} rescanning: false } onVideoStateChanged: (changes) -> @setState(changes) render: () -> if @props.showBackBtn backBtn = `BACK` selectedDevice = this.selectedDeviceName(@state) # build list of webcams webcams = [] noneSelected = selectedDevice == null || selectedDevice.length == 0 # the backend does not allow setting no video camera. So if a webcam is selected, prevent un-selecting if noneSelected webcams.push `` context._.each @state.deviceNames, (deviceName, deviceGuid) -> selected = deviceGuid == selectedDevice webcams.push `` noWebcams = Object.keys(@state.deviceNames).length == 0 # build list of capture resolutions captureResolutions = [] # load current settings from backend captureResolution = @state.currentCaptureResolution resolutions = @state.captureResolutions context._.each resolutions, (resolution, resolutionKey, obj) => value = resolutionKey text = resolution selected = captureResolution.toString() == value.toString() captureResolutions.push `` testBtnClassNames = {'button-orange' : true, 'webcam-test-btn' : true} if noWebcams if PlatformStore.isWindows() testBtnClassNames.disabled = !@state.videoEnabled testBtnClasses = classNames(testBtnClassNames) testBtn = `TEST VIDEO` else testBtn = null else if @state.videoShared testBtnClassNames.disabled = !@state.videoEnabled testBtnClasses = classNames(testBtnClassNames) testBtn = `STOP WEBCAM` else testBtnClassNames.disabled = !@state.videoEnabled || noneSelected testBtnClasses = classNames(testBtnClassNames) testBtn = `TEST WEBCAM` if @state.rescanning rescanning = ` CHECKING GEAR ` if @props.show_header if noWebcams if PlatformStore.isWindows() testVideoHelpText = `The TEST VIDEO button will open the JamKazam video window to verify that receiving video works on your system.` header = `

video gear:

JamKazam does not detect any webcams. You will not be able to send video, but you can still receive it from others. {testVideoHelpText}
` else header = `

video gear:

Select webcam to use for video in sessions. Verify that you see video from webcam in the external application window (it may be behind this window).
` if @state.videoEnabled disableVideoBtnText = "DISABLE VIDEO" else disableVideoBtnText = "ENABLE VIDEO" if @props.show_disable || !@state.videoEnabled || @state.everDisabled if @state.videoEnabled disableHelpBtn = `[?]` disableBtnClasses = classNames({'button-grey' : true, 'disable-video' : true, 'disabled' : @state.videoShared}) disableVideo = `
{disableVideoBtnText} {disableHelpBtn}
` `
{header}

select webcam:

select video capture resolution:

[?]
{backBtn} {testBtn}
{rescanning}
{disableVideo}
` componentDidMount: () -> if @props.isVisible @beforeShow() $root = $(@getDOMNode()) $videoSettingsHelp = $root.find('.ftue-video-settings-help') context.JK.helpBubble($videoSettingsHelp, 'ftue-video-settings', {}, {width:300}) if $videoSettingsHelp.length > 0 $videoSettingsHelp.click(false) $videoDisableHelp = $root.find('.ftue-video-disable-help') context.JK.helpBubble($videoDisableHelp, 'ftue-video-disable', {}, {width:300}) if $videoDisableHelp.length > 0 $videoDisableHelp.click(false) componentWillUpdate: (nextProps, nextState) -> # protect against non-video clients pointed at video-enabled server from getting into a session #@logger.debug("webcam devices", nextState.deviceNames, @state.deviceNames) if !@initialScan? @initialScan = true else if @visible @findChangedWebcams(nextState.deviceNames, @state.deviceNames) componentWillReceiveProps:(nextProps) -> if nextProps.isVisible @beforeShow() else @beforeHide() beforeShow:() -> @visible = true VideoActions.refresh() VideoActions.stopVideo() context.JK.onBackendEvent(ALERT_NAMES.USB_CONNECTED, 'webcam-viewer', @onUsbDeviceConnected); context.JK.onBackendEvent(ALERT_NAMES.USB_DISCONNECTED, 'webcam-viewer', @onUsbDeviceDisconnected); beforeHide: () -> @visible = false context.JK.offBackendEvent(ALERT_NAMES.USB_CONNECTED, 'webcam-viewer', @onUsbDeviceConnected); context.JK.offBackendEvent(ALERT_NAMES.USB_DISCONNECTED, 'webcam-viewer', @onUsbDeviceDisconnected); if @rescanTimeout? clearTimeout(@rescanTimeout) @rescanTimeout = null @setVideoOff() onUsbDeviceConnected: () -> # don't handle USB events when minimized #return if !context.jamClient.IsFrontendVisible() logger.debug("USB device connected") @scheduleRescanSystem(3000) onUsbDeviceDisconnected:() -> # don't handle USB events when minimized #return if !context.jamClient.IsFrontendVisible() logger.debug("USB device disconnected") @scheduleRescanSystem(3000) scheduleRescanSystem: (time) -> if @rescanTimeout? clearTimeout(@rescanTimeout) @rescanTimeout = null @setState({rescanning: true}) @rescanTimeout = setTimeout(() => @setState({rescanning: false}) VideoActions.refresh() , time) selectWebcam:(e) -> e.preventDefault() device = $(e.target).val() VideoActions.selectDevice(device, {}) disableVideo: (e) -> e.preventDefault() return if @state.videoShared if @state.videoEnabled context.JK.Banner.showYesNo({ title: "Disable Video?", html: "You will not be able to send or receive video.", yes: => VideoActions.setVideoEnabled(false) }) else VideoActions.setVideoEnabled(true) updateBackend: (captureResolution) -> @logger.debug 'Selecting capture resolution: ', captureResolution VideoActions.setCaptureResolution(captureResolution) selectResolution:(e) -> e.preventDefault() resolution = $(e.target).val() @logger.debug 'new capture resolution selected: ' + resolution if resolution? @updateBackend(resolution) setVideoOff:() -> VideoActions.stopVideo() back: () => window.location = '/client#/account' toggleWebcam:(e) -> e.preventDefault() return unless this.state.videoEnabled $toggleBtn = $(e.target) # we should only do this if no device is currently selected $root = $(@getDOMNode()) $select = $root.find('.webcam-select-container select') if Object.keys(@state.deviceNames).length == 0 context.JK.Banner.showYesNo({ yes_text: 'RUN TEST', title: "Run Video Test?", html: "A video window will show up with changing colors and shapes for 10 seconds. The test was successful if you were able to see the changing colors. Close the window once the colors and shapes stop changing.", yes: => VideoActions.testVideo() }) else device = $select.val() #VideoActions.selectDevice(device, {}) if VideoStore.videoShared VideoActions.stopVideo() else VideoActions.toggleVideo() #if this.isVideoShared() # $toggleBtn.removeClass("selected") # VideoActions.stopVideo() # @setState({videoShared: false}) #else # $toggleBtn.addClass("selected") # VideoActions.startVideo() # @setState({videoShared: true}) selectedDeviceName:(state) -> webcamName = null # protect against non-video clients pointed at video-enabled server from getting into a session webcam = state.currentDevice #@logger.debug("currently selected video device", webcam) if (webcam? && Object.keys(webcam).length>0) webcamName = Object.keys(webcam)[0] webcamName findChangedWebcams: (newList, oldList) -> newKeys = Object.keys(newList) oldKeys = Object.keys(oldList) webcamSelect = $(@getDOMNode()).find('.webcam-select-container select') if newKeys.length > oldKeys.length for newKey in newKeys if oldKeys.indexOf(newKey) == -1 newWebcam = newList[newKey] @logger.debug("new webcam found: " + newWebcam, newKey) context.JK.prodBubble(webcamSelect, 'new-webcam-found', {name: newWebcam}, {positions:['right']}) break else if newKeys.length < oldKeys.length for oldKey in oldKeys if newKeys.indexOf(oldKey) == -1 oldWebcam = oldList[oldKey] @logger.debug("webcam no longer found: " + oldWebcam) context.JK.prodBubble(webcamSelect, 'old-webcam-lost', {name: oldWebcam}, {positions:['right']}) break } )