194 lines
6.6 KiB
CoffeeScript
194 lines
6.6 KiB
CoffeeScript
context = window
|
|
logger = context.JK.logger
|
|
rest = context.JK.Rest()
|
|
|
|
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
|
|
|
|
VideoLiveStreamStore = reactContext.VideoLiveStreamStore
|
|
VideoLiveStreamActions = reactContext.VideoLiveStreamActions
|
|
AppActions = reactContext.AppActions
|
|
|
|
if accessOpener
|
|
mixins.push(Reflux.listenTo(VideoLiveStreamStore,"onVideoLiveStreamChanged"))
|
|
|
|
@PopupVideoLiveStream = React.createClass({
|
|
mixins: mixins
|
|
|
|
onVideoLiveStreamChanged: (videoLiveStream) ->
|
|
if @unloaded
|
|
return
|
|
|
|
logger.debug("onVideoLiveStreamChanged", videoLiveStream)
|
|
this.setState({videoLiveStream: videoLiveStream})
|
|
|
|
render: () ->
|
|
|
|
# there are a few initial states: if auth is null, we don't know yet (and are checking against the server)
|
|
# if auth is set, then we can show the upload btn
|
|
# and if auth == false, then we need the user to try and log in
|
|
|
|
if @state.auth == false
|
|
action = `<input className="google_login_button" type='image' src="/assets/google_signin.png" height="30px" onClick={this.startGoogleLogin}/>`
|
|
instructions = `<p>To upload this recording to YouTube, you must give JamKazam the necessary access to your YouTube account by clicking the button below.</p>`
|
|
|
|
else if @state.videoLiveStream
|
|
|
|
videoLiveStream = @state.videoLiveStream
|
|
if videoLiveStream.broadcast?
|
|
|
|
logger.debug("broadcast_data", videoLiveStream.broadcast)
|
|
try
|
|
data = JSON.parse(videoLiveStream.broadcast.broadcast_data)
|
|
controlsUrl = "https://www.youtube.com/live_event_analytics?v=" + data.id
|
|
videoUrl = "https://www.youtube.com/watch?v=" + data.id
|
|
controlLink = `<a onClick={this.watchVideo} className="video-url" href={controlsUrl}>Open Broadcast Controls</a>`
|
|
videoLink = `<a onClick={this.watchVideo} className="video-url" href={videoUrl}>Open Video Page</a>`
|
|
catch e
|
|
logger.error("unable to parse broadcast data", e)
|
|
|
|
|
|
|
|
if videoLiveStream.errorMessage
|
|
action = null
|
|
instructions = `<p>The stream setup failed. Reason: ({videoLiveStream.errorMessage})</p>`
|
|
else if @state.auth == false
|
|
action = `<input className="google_login_button" type='image' src="/assets/google_signin.png" height="30px" onClick={this.startGoogleLogin}/>`
|
|
instructions = `<p>To upload this recording to YouTube, you must give JamKazam the necessary access to your YouTube account by clicking the button below.</p>`
|
|
else if videoLiveStream.streaming
|
|
action = `<div><a className="button-orange close-btn" onClick={this.onCloseRequested}>STOP LIVECASTING</a></div>`
|
|
instructions = `<p>{videoLink}{controlLink}</p>`
|
|
else if videoLiveStream.creatingBroadcast
|
|
action = null
|
|
instructions = `<p>Synchronizing with YouTube</p>`
|
|
else if videoLiveStream.waitingOnReady
|
|
action = null
|
|
instructions = `<p>Synchronizing with YouTube ... waiting on stream setup</p>`
|
|
else if videoLiveStream.waitingOnTesting || videoLiveStream.transitioningTesting
|
|
action = null
|
|
instructions = `<p>Synchronizing with YouTube ... stream is ready ... preparing ... </p>`
|
|
else if videoLiveStream.waitingOnLive
|
|
action = null
|
|
instructions = `<p>Synchronizing with YouTube ... stream is ready ... waiting to go live ...</p>`
|
|
else if !@state.initiated
|
|
action = `<a onClick={this.startBroadcasting} className="start-btn button-orange" href='#'>START BROADCASTING</a>`
|
|
if videoLiveStream.broadcast
|
|
instructions = `<p>Click 'Start Broadcasting' to setup a live streaming session on YouTube.</p>`
|
|
else
|
|
instructions = `<p>Press 'Start Broadcasting' to start broadcasting on YouTube.</p>`
|
|
else if @state.initiated
|
|
instructions = `<p>Streaming initiated. Please wait...</p>`
|
|
else
|
|
name = null
|
|
action = null
|
|
instructions = `<p>UNKNOWN STATE: {JSON.stringify(videoLiveStream)}</p>`
|
|
else
|
|
name = 'Loading...'
|
|
action = null
|
|
|
|
`<div className="video-live-stream">
|
|
<h3>Live Stream Video</h3>
|
|
{instructions}
|
|
<div className="control-holder">
|
|
{action}
|
|
</div>
|
|
</div>`
|
|
|
|
getInitialState: () ->
|
|
{auth: null, initiated: false}
|
|
|
|
startBroadcasting: (e) ->
|
|
e.preventDefault()
|
|
VideoLiveStreamActions.startLiveStreaming()
|
|
@setState({initiated: true})
|
|
|
|
watchVideo: (e) ->
|
|
e.preventDefault()
|
|
$link = $(e.target)
|
|
AppActions.openExternalUrl($link.attr('href'))
|
|
|
|
onCloseRequested: (e) ->
|
|
e.preventDefault()
|
|
window.close()
|
|
|
|
startGoogleLogin: (e) ->
|
|
e.preventDefault()
|
|
|
|
logger.debug("Starting google login")
|
|
window._oauth_win = window.open("/auth/google_login", "Log In to Google", "height=700,width=500,menubar=no,resizable=no,status=no");
|
|
window._oauth_callback = @oauthCallback
|
|
|
|
oauthCallback: () ->
|
|
window._oauth_win.close()
|
|
@checkAuth()
|
|
|
|
checkAuth:() ->
|
|
rest.getGoogleAuth()
|
|
.done((auth) =>
|
|
if auth.auth?
|
|
@setState({auth: auth.auth})
|
|
else
|
|
@setState({auth: false})
|
|
)
|
|
.fail(() =>
|
|
@setState({errorReason: 'Unable to fetch user authorization'})
|
|
)
|
|
|
|
componentDidMount: () ->
|
|
|
|
$(window).unload(@windowUnloaded)
|
|
|
|
@checkAuth()
|
|
|
|
VideoLiveStreamActions.loadBroadcast(gon.session_id)
|
|
|
|
@resizeWindow()
|
|
|
|
# this is necessary due to whatever the client's rendering behavior is.
|
|
setTimeout(@resizeWindow, 300)
|
|
|
|
shouldComponentUpdate: () ->
|
|
return !@unloaded
|
|
|
|
componentDidUpdate: () ->
|
|
@resizeWindow()
|
|
setTimeout(@resizeWindow, 1000)
|
|
|
|
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
|
|
mysteryTopMargin = 0
|
|
# 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
|
|
|
|
width = 100 if width < 100
|
|
height = 100 if height < 100
|
|
|
|
window.resizeTo(width, height + offset)
|
|
|
|
windowUnloaded: () ->
|
|
@unloaded = true
|
|
window.unloaded = true
|
|
VideoLiveStreamActions.popupClosed()
|
|
}) |