Unify guest and host sessions into single class

This commit is contained in:
Kevin Sawicki & Nathan Sobo
2013-07-25 12:56:38 -07:00
parent 241e787d0f
commit bb3cacf2cd
6 changed files with 96 additions and 214 deletions

View File

@@ -3,7 +3,7 @@ require 'window'
$ = require 'jquery'
{$$} = require 'space-pen'
GuestSession = require './guest-session'
Session = require './session'
window.setDimensions(width: 350, height: 125)
window.setUpEnvironment('editor')
@@ -22,7 +22,7 @@ updateProgressBar = (message, percentDone) ->
loadingView.find('.progress-bar-message').text("#{message}\u2026")
loadingView.find('.progress-bar').css('width', "#{percentDone}%")
guestSession = new GuestSession(sessionId)
guestSession = new Session(id: sessionId)
guestSession.on 'started', ->
atom.windowState = guestSession.getDocument().get('windowState')

View File

@@ -1,6 +1,6 @@
GuestView = require './guest-view'
HostView = require './host-view'
HostSession = require './host-session'
Session = require './session'
JoinPromptView = require './join-prompt-view'
{getSessionUrl} = require './session-utils'
@@ -11,7 +11,7 @@ module.exports =
if atom.getLoadSettings().sessionId
new GuestView(atom.guestSession)
else
hostSession = new HostSession(window.site)
hostSession = new Session(site: window.site)
copySession = ->
sessionId = hostSession.getId()

View File

@@ -1,104 +0,0 @@
_ = require 'underscore'
patrick = require 'patrick'
telepath = require 'telepath'
Project = require 'project'
MediaConnection = require './media-connection'
sessionUtils = require './session-utils'
Session = require './session'
module.exports =
class GuestSession extends Session
participants: null
peer: null
mediaConnection: null
constructor: (@hostId) ->
start: ->
@channel = @subscribe(@hostId)
@channel.on 'channel:subscribed', (participants) =>
@trigger 'started', participants
@channel.on 'channel:closed', => @trigger 'stopped'
@channel.one 'welcome', ({doc, siteId, repoSnapshot}) =>
@site = new telepath.Site(siteId)
@doc = @site.deserializeDocument(doc)
@connectDocument(@doc, @channel)
repoUrl = @doc.get('collaborationState.repositoryState.url')
@mirrorRepository repoUrl, repoSnapshot, => @trigger 'started'
stop: -> @channel.stop()
getSite: -> @site
getDocument: -> @doc
mirrorRepository: (repoUrl, repoSnapshot, callback) ->
repoPath = Project.pathForRepositoryUrl(repoUrl)
progressCallback = (args...) => @trigger 'mirror-progress', args...
patrick.mirror repoPath, repoSnapshot, {progressCallback}, (error) =>
if error?
console.error(error)
else
callback()
# id = @getId()
# email = project.getRepo().getConfigValue('user.email')
# @participants.push {id, email}
# @peer = sessionUtils.createPeer()
# connection = @peer.connect(sessionId, reliable: true)
# window.site = new telepath.Site(@getId())
#
# connection.on 'open', =>
# @trigger 'connection-opened'
#
# connection.once 'data', (data) =>
# @trigger 'connection-document-received'
#
# doc = @createTelepathDocument(data, connection)
# repoUrl = doc.get('collaborationState.repositoryState.url')
#
# @mirrorRepository(repoUrl, data.repoSnapshot)
#
# guest = doc.get('collaborationState.guest')
# host = doc.get('collaborationState.host')
# @mediaConnection = new MediaConnection(guest, host, isHost: false)
# @mediaConnection.start()
#
# waitForStream: (callback) ->
# @mediaConnection.waitForStream callback
#
# getId: -> @peer.id
#
# createTelepathDocument: (data, connection) ->
# doc = window.site.deserializeDocument(data.doc)
# sessionUtils.connectDocument(doc, connection)
#
# atom.windowState = doc.get('windowState')
#
# @participants = doc.get('collaborationState.participants')
# @participants.on 'changed', =>
# @trigger 'participants-changed', @participants.toObject()
#
# doc
#
# mirrorRepository: (repoUrl, repoSnapshot) ->
# repoPath = Project.pathForRepositoryUrl(repoUrl)
#
# progressCallback = (args...) => @trigger 'mirror-progress', args...
#
# patrick.mirror repoPath, repoSnapshot, {progressCallback}, (error) =>
# throw new Error(error) if error
#
# # 'started' will trigger window.startEditorWindow() which creates the git global
# @trigger 'started'
#
# id = @getId()
# email = project.getRepo().getConfigValue('user.email')
# @participants.push {id, email}

View File

@@ -1,97 +0,0 @@
fs = require 'fs'
_ = require 'underscore'
guid = require 'guid'
patrick = require 'patrick'
telepath = require 'telepath'
MediaConnection = require './media-connection'
sessionUtils = require './session-utils'
Session = require './session'
module.exports =
class HostSession extends Session
participants: null
peer: null
mediaConnection: null
doc: null
constructor: (@site) ->
@id = guid.create().toString()
@nextGuestSiteId = @site.id + 1
getSite: -> @site
getDocument: -> @doc
createDocument: ->
@site.createDocument
windowState: atom.windowState
collaborationState:
guest: {description: '', candidate: '', ready: false}
host: {description: '', candidate: ''}
participants: []
repositoryState:
url: project.getRepo().getConfigValue('remote.origin.url')
branch: project.getRepo().getShortHead()
start: ->
return if @isSharing()
@doc = @createDocument()
channel = @subscribe(@id)
channel.on 'channel:subscribed', (participants) =>
@trigger 'started', participants
@connectDocument(@doc, channel)
channel.on 'channel:participant-entered', (participant) =>
@trigger 'participant-entered', participant
@snapshotRepository (repoSnapshot) =>
welcomePackage =
siteId: @nextGuestSiteId++
doc: @doc.serialize()
repoSnapshot: repoSnapshot
channel.send 'welcome', welcomePackage
channel.on 'channel:participant-exited', (participant) =>
@trigger 'participant-exited', participant
# host = @doc.get('collaborationState.host')
# guest = @doc.get('collaborationState.guest')
# @mediaConnection = new MediaConnection(host, guest, isHost: true)
# @mediaConnection.start()
@getId()
snapshotRepository: (callback) ->
patrick.snapshot project.getPath(), (error, repoSnapshot) =>
if error
console.error(error)
else
callback(repoSnapshot)
# @participants = @doc.get('collaborationState.participants')
# @participants.push
# id: @getId()
# email: project.getRepo().getConfigValue('user.email')
#
# @participants.on 'changed', =>
# @trigger 'participants-changed', @participants.toObject()
# connection.on 'close', =>
# @participants.each (participant, index) =>
# if connection.peer is participant.get('id')
# @participants.remove(index)
# @trigger 'stopped'
stop: ->
return unless @peer?
@peer.destroy()
@peer = null
waitForStream: (callback) ->
@mediaConnection.waitForStream callback
getId: -> @id
isSharing: ->
@peer? and not _.isEmpty(@peer.connections)

View File

@@ -1,20 +1,104 @@
_ = require 'underscore'
guid = require 'guid'
keytar = require 'keytar'
patrick = require 'patrick'
{Site} = require 'telepath'
Project = require 'project'
WsChannel = require './ws-channel'
module.exports =
class Session
_.extend @prototype, require('event-emitter')
constructor: ({@site, @id}) ->
if @site?
@id = guid.create().toString()
@leader = true
@nextGuestSiteId = @site.id + 1
else
@leader = false
isLeader: -> @leader
start: ->
@channel = @subscribe(@id)
@channel.on 'channel:closed', => @trigger 'stopped'
@channel.on 'channel:participant-exited', (participant) =>
@trigger 'participant-exited', participant
@channel.on 'channel:participant-entered', (participant) =>
@trigger 'participant-entered', participant
if @isLeader()
@snapshotRepository (repoSnapshot) =>
welcomePackage =
siteId: @nextGuestSiteId++
doc: @doc.serialize()
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 'welcome', ({doc, siteId, repoSnapshot}) =>
@site = new Site(siteId)
@doc = @site.deserializeDocument(doc)
@connectDocument()
repoUrl = @doc.get('collaborationState.repositoryState.url')
@mirrorRepository repoUrl, repoSnapshot, =>
@trigger 'started', participants
createDocument: ->
@site.createDocument
windowState: atom.windowState
collaborationState:
guest: {description: '', candidate: '', ready: false}
host: {description: '', candidate: ''}
repositoryState:
url: project.getRepo().getConfigValue('remote.origin.url')
branch: project.getRepo().getShortHead()
stop: -> @channel.stop()
getSite: -> @site
getDocument: -> @doc
getId: -> @id
subscribe: (channelName) ->
channel = new WsChannel(channelName)
{@clientId} = channel
channel
connectDocument: (doc, channel) ->
doc.on 'replicate-change', (event) ->
channel.send('document-changed', event)
connectDocument: ->
@doc.on 'replicate-change', (event) =>
@channel.send('document-changed', event)
channel.on 'document-changed', (event) ->
doc.applyRemoteChange(event)
@channel.on 'document-changed', (event) =>
@doc.applyRemoteChange(event)
snapshotRepository: (callback) ->
patrick.snapshot project.getPath(), (error, repoSnapshot) =>
if error
console.error(error)
else
callback(repoSnapshot)
mirrorRepository: (repoUrl, repoSnapshot, callback) ->
repoPath = Project.pathForRepositoryUrl(repoUrl)
progressCallback = (args...) => @trigger 'mirror-progress', args...
patrick.mirror repoPath, repoSnapshot, {progressCallback}, (error) =>
if error?
console.error(error)
else
callback()

View File

@@ -3,8 +3,7 @@ keytar = require 'keytar'
{Site} = require 'telepath'
Server = require '../vendor/atom-collaboration-server'
GuestSession = require '../lib/guest-session'
HostSession = require '../lib/host-session'
Session = require '../lib/session'
describe "Collaboration", ->
describe "when a host and a guest join a channel", ->
@@ -34,8 +33,8 @@ describe "Collaboration", ->
server.start()
runs ->
hostSession = new HostSession(new Site(1))
guestSession = new GuestSession(hostSession.getId())
hostSession = new Session(site: new Site(1))
guestSession = new Session(id: hostSession.getId())
spyOn(hostSession, 'snapshotRepository').andCallFake (callback) ->
callback({url: 'git://server/repo.git'})