Display participants in host and guest views

Also add back media connection starting in Session
This commit is contained in:
Kevin Sawicki & Nathan Sobo
2013-07-25 13:47:30 -07:00
parent bb3cacf2cd
commit 3685cb3b52
8 changed files with 91 additions and 54 deletions

View File

@@ -21,7 +21,8 @@ module.exports =
rootView.command 'collaboration:start-session', ->
hostView ?= new HostView(hostSession)
copySession() if hostSession.start()
hostSession.start()
copySession()
rootView.command 'collaboration:join-session', ->
new JoinPromptView (id) ->

View File

@@ -12,20 +12,19 @@ class GuestView extends View
guestSession: null
initialize: (@guestSession) ->
# @guestSession.on 'participants-changed', (participants) =>
# @updateParticipants(participants)
#
# @updateParticipants(@guestSession.participants.toObject())
#
# @guestSession.waitForStream (stream) =>
# @video[0].src = URL.createObjectURL(stream)
@guestSession.on 'participant-entered participant-exited', =>
@updateParticipants()
@guestSession.waitForStream (stream) =>
@video[0].src = URL.createObjectURL(stream)
@updateParticipants()
@attach()
updateParticipants: (participants) ->
updateParticipants: ->
@participants.empty()
guestId = @guestSession.getId()
for participant in participants when participant.id isnt guestId
for participant in @guestSession.getOtherParticipants()
@participants.append(new ParticipantView(participant))
toggle: ->

View File

@@ -12,32 +12,22 @@ class HostView extends View
hostSession: null
initialize: (@hostSession) ->
if @hostSession.isSharing()
@share.addClass('running')
@share.on 'click', =>
@share.disable()
if @hostSession.isSharing()
@hostSession.stop()
else
@hostSession.start()
@hostSession.on 'started stopped', =>
@share.toggleClass('running').enable()
@hostSession.on 'participants-changed', (participants) =>
@updateParticipants(participants)
@hostSession.on 'participant-entered participant-exited', =>
@updateParticipants()
# @hostSession.waitForStream (stream) =>
# @video[0].src = URL.createObjectURL(stream)
@hostSession.one 'started', =>
@updateParticipants()
@hostSession.waitForStream (stream) =>
@video[0].src = URL.createObjectURL(stream)
@attach()
updateParticipants: (participants) ->
updateParticipants: ->
@participants.empty()
hostId = @hostSession.getId()
for participant in participants when participant.id isnt hostId
for participant in @hostSession.getOtherParticipants()
@participants.append(new ParticipantView(participant))
toggle: ->

View File

@@ -10,13 +10,13 @@ class MediaConnection
remote: null
connection: null
stream: null
isHost: null
isLeader: null
constructor: (@local, @remote, {@isHost}={}) ->
constructor: (@local, @remote, {@isLeader}={}) ->
start: ->
constraints = {video: true, audio: true}
# navigator.webkitGetUserMedia constraints, @onUserMediaAvailable, @onUserMediaUnavailable
navigator.webkitGetUserMedia constraints, @onUserMediaAvailable, @onUserMediaUnavailable
waitForStream: (callback) ->
if @stream
@@ -40,7 +40,7 @@ class MediaConnection
@stream = event.stream
@trigger 'stream-ready', @stream
@local.set 'ready', true unless @isHost
@local.set 'ready', true unless @isLeader
onRemoteSignal: ({key, newValue}) =>
switch key
@@ -55,7 +55,7 @@ class MediaConnection
sessionDescription = new RTCSessionDescription(remoteDescription)
@connection.setRemoteDescription(sessionDescription)
if not @isHost
if not @isLeader
success = (localDescription) =>
@connection.setLocalDescription(localDescription)
@local.set('description', localDescription)

View File

@@ -4,6 +4,7 @@ keytar = require 'keytar'
patrick = require 'patrick'
{Site} = require 'telepath'
MediaConnection = require './media-connection'
Project = require 'project'
WsChannel = require './ws-channel'
@@ -11,7 +12,9 @@ module.exports =
class Session
_.extend @prototype, require('event-emitter')
constructor: ({@site, @id}) ->
constructor: ({@site, @id, @port}) ->
@participants = []
if @site?
@id = guid.create().toString()
@leader = true
@@ -26,13 +29,25 @@ class Session
@channel.on 'channel:closed', => @trigger 'stopped'
@channel.on 'channel:participant-exited', (participant) =>
@trigger 'participant-exited', participant
@channel.on 'channel:participant-entered', (participant) =>
@participants.push(participant)
@trigger 'participant-entered', participant
if @isLeader()
@channel.on 'channel:participant-exited', (participant) =>
@participants = @participants.filter ({clientId}) ->
clientId isnt participant.clientId
@trigger 'participant-exited', participant
if @isLeader()
@doc = @createDocument()
@mediaConnection = @createMediaConnection()
@mediaConnection.start()
@connectDocument()
@channel.one 'channel:subscribed', (@participants) =>
@trigger 'started', @getParticipants()
@on 'participant-entered', =>
@snapshotRepository (repoSnapshot) =>
welcomePackage =
siteId: @nextGuestSiteId++
@@ -40,20 +55,26 @@ class Session
repoSnapshot: repoSnapshot
@channel.send 'welcome', welcomePackage
if @isLeader()
@doc = @createDocument()
@connectDocument()
@channel.one 'channel:subscribed', (participants) =>
@trigger 'started', participants
else
@channel.one 'channel:subscribed', (participants) =>
@channel.one 'channel:subscribed', (@participants) =>
@channel.one 'welcome', ({doc, siteId, repoSnapshot}) =>
@site = new Site(siteId)
@doc = @site.deserializeDocument(doc)
@connectDocument()
@mediaConnection = @createMediaConnection()
@mediaConnection.start()
repoUrl = @doc.get('collaborationState.repositoryState.url')
@mirrorRepository repoUrl, repoSnapshot, =>
@trigger 'started', participants
@trigger 'started', @getParticipants()
createMediaConnection: ->
guest = @doc.get('collaborationState.guest')
host = @doc.get('collaborationState.host')
new MediaConnection(guest, host, isLeader: @isLeader())
waitForStream: (callback) ->
@mediaConnection.waitForStream callback
createDocument: ->
@site.createDocument
@@ -73,8 +94,13 @@ class Session
getId: -> @id
subscribe: (channelName) ->
channel = new WsChannel(channelName)
getParticipants: -> _.clone(@participants)
getOtherParticipants: ->
@getParticipants().filter ({clientId}) => clientId isnt @clientId
subscribe: (name) ->
channel = new WsChannel({name, @port})
{@clientId} = channel
channel

View File

@@ -6,10 +6,11 @@ module.exports =
class WsChannel
_.extend @prototype, require('event-emitter')
constructor: (@name) ->
constructor: ({@name, @port}) ->
@port ?= 8080
@clientId = guid.create().toString()
token = keytar.getPassword('github.com', 'github')
@socket = new WebSocket("ws://localhost:8080?token=#{token}")
@socket = new WebSocket("ws://localhost:#{@port}?token=#{token}")
@socket.onopen = =>
@rawSend 'subscribe', @name, @clientId

View File

@@ -5,6 +5,8 @@ keytar = require 'keytar'
Server = require '../vendor/atom-collaboration-server'
Session = require '../lib/session'
ServerPort = 8081
describe "Collaboration", ->
describe "when a host and a guest join a channel", ->
[server, hostSession, guestSession, repositoryMirrored, token, userDataByToken] = []
@@ -19,7 +21,7 @@ describe "Collaboration", ->
'octocat-token':
login: 'octocat'
server = new Server()
server = new Server(port: ServerPort)
spyOn(server, 'log')
spyOn(server, 'error')
spyOn(server, 'authenticate').andCallFake (token, callback) ->
@@ -33,8 +35,8 @@ describe "Collaboration", ->
server.start()
runs ->
hostSession = new Session(site: new Site(1))
guestSession = new Session(id: hostSession.getId())
hostSession = new Session(site: new Site(1), port: ServerPort)
guestSession = new Session(id: hostSession.getId(), port: ServerPort)
spyOn(hostSession, 'snapshotRepository').andCallFake (callback) ->
callback({url: 'git://server/repo.git'})
@@ -88,6 +90,8 @@ describe "Collaboration", ->
runs ->
expect(hostStartedHandler).toHaveBeenCalledWith [login: 'hubot', clientId: hostSession.clientId]
expect(hostSession.getParticipants()).toEqual [login: 'hubot', clientId: hostSession.clientId]
expect(hostSession.getOtherParticipants()).toEqual []
token = 'octocat-token'
guestSession.start()
@@ -98,11 +102,25 @@ describe "Collaboration", ->
{ login: 'hubot', clientId: hostSession.clientId }
{ login: 'octocat', clientId: guestSession.clientId }
]
expect(guestSession.getParticipants()).toEqual [
{ login: 'hubot', clientId: hostSession.clientId }
{ login: 'octocat', clientId: guestSession.clientId }
]
expect(guestSession.getOtherParticipants()).toEqual [
{ login: 'hubot', clientId: hostSession.clientId }
]
waitsFor "host to see guest enter", -> hostParticipantEnteredHandler.callCount > 0
runs ->
expect(hostParticipantEnteredHandler).toHaveBeenCalledWith(login: 'octocat', clientId: guestSession.clientId)
expect(hostSession.getParticipants()).toEqual [
{ login: 'hubot', clientId: hostSession.clientId }
{ login: 'octocat', clientId: guestSession.clientId }
]
expect(hostSession.getOtherParticipants()).toEqual [
{ login: 'octocat', clientId: guestSession.clientId }
]
guestSession.stop()
waitsFor "guest session to stop", -> guestStoppedHandler.callCount > 0
@@ -110,3 +128,5 @@ describe "Collaboration", ->
runs ->
expect(hostParticipantExitedHandler).toHaveBeenCalledWith(login: 'octocat', clientId: guestSession.clientId)
expect(hostSession.getParticipants()).toEqual [login: 'hubot', clientId: hostSession.clientId]
expect(hostSession.getOtherParticipants()).toEqual []