From bb3cacf2cdf32acd43b31c226dd1231028696a99 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki & Nathan Sobo Date: Thu, 25 Jul 2013 12:56:38 -0700 Subject: [PATCH] Unify guest and host sessions into single class --- .../collaboration/lib/bootstrap.coffee | 4 +- .../collaboration/lib/collaboration.coffee | 4 +- .../collaboration/lib/guest-session.coffee | 104 ------------------ .../collaboration/lib/host-session.coffee | 97 ---------------- src/packages/collaboration/lib/session.coffee | 94 +++++++++++++++- .../spec/collaboration-spec.coffee | 7 +- 6 files changed, 96 insertions(+), 214 deletions(-) delete mode 100644 src/packages/collaboration/lib/guest-session.coffee delete mode 100644 src/packages/collaboration/lib/host-session.coffee diff --git a/src/packages/collaboration/lib/bootstrap.coffee b/src/packages/collaboration/lib/bootstrap.coffee index b8f5f2cae..af865524a 100644 --- a/src/packages/collaboration/lib/bootstrap.coffee +++ b/src/packages/collaboration/lib/bootstrap.coffee @@ -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') diff --git a/src/packages/collaboration/lib/collaboration.coffee b/src/packages/collaboration/lib/collaboration.coffee index 74c8e2bcd..7d287fb6d 100644 --- a/src/packages/collaboration/lib/collaboration.coffee +++ b/src/packages/collaboration/lib/collaboration.coffee @@ -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() diff --git a/src/packages/collaboration/lib/guest-session.coffee b/src/packages/collaboration/lib/guest-session.coffee deleted file mode 100644 index 67427e6ca..000000000 --- a/src/packages/collaboration/lib/guest-session.coffee +++ /dev/null @@ -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} diff --git a/src/packages/collaboration/lib/host-session.coffee b/src/packages/collaboration/lib/host-session.coffee deleted file mode 100644 index 93fcc9f33..000000000 --- a/src/packages/collaboration/lib/host-session.coffee +++ /dev/null @@ -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) diff --git a/src/packages/collaboration/lib/session.coffee b/src/packages/collaboration/lib/session.coffee index 9e2e33c2a..2f813c96e 100644 --- a/src/packages/collaboration/lib/session.coffee +++ b/src/packages/collaboration/lib/session.coffee @@ -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() diff --git a/src/packages/collaboration/spec/collaboration-spec.coffee b/src/packages/collaboration/spec/collaboration-spec.coffee index 4e8399a40..c38fb2273 100644 --- a/src/packages/collaboration/spec/collaboration-spec.coffee +++ b/src/packages/collaboration/spec/collaboration-spec.coffee @@ -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'})