151:0178573216e3
Anton Shestakov <av6@dwimlabs.net>, Thu, 14 Apr 2016 02:05:24 +0800
index: remove offline contacts only when they change to being offline Since new contacts are currently added while they still have the default presence of 'unavailable', add event sees them as offline and throws them away immediately, before their presence could change to something else.

next change 317:d7821033e3c0
previous change 134:46bc2e4d7a20

coffee/webrtc.coffee

Permissions: -rw-r--r--

Other formats: Feeds:
class Tram.WebRTCInterface
lstream: null
rstream: null
constructor: (@contact) ->
@peerJid = @contact.get('jid')
init: (@initiator, constraints) ->
if constraints.audio || constraints.video
navigator.getUserMedia(constraints, @connect, @fail)
else
@connect()
connect: (stream) =>
@call = calls.add(jid: @peerJid)
@pc = new RTCPeerConnection(iceServers: Tram.config.iceServers)
if stream?
@lstream = stream
@pc.addStream(stream)
@call.set('local/stream', stream)
@pc.onicecandidate = (event) =>
if event.candidate
@sendPayload(event.candidate, 'ice')
@pc.onaddstream = (event) =>
@rstream = event.stream
@call.set('remote/stream', event.stream)
@contact.set('callstate', 'established')
if @initiator
@sendIntent('initiate')
else
@createOffer()
onPayload: (stanza) ->
if not @call?
return
el = stanza.getElementsByTagNameNS(Tram.NS.WEBRTC, 'payload')[0]
signal = JSON.parse(el.firstChild.nodeValue)
if signal.sdp
if signal.type is 'offer'
@receiveOffer(signal)
else if signal.type is 'answer'
@receiveAnswer(signal)
else if signal.candidate
@pc.addIceCandidate(new RTCIceCandidate(signal))
sendPayload: (data, type) ->
payload = JSON.stringify(data)
msg = $msg(to: @peerJid, type: 'chat')
.c('payload', xmlns: Tram.NS.WEBRTC, type: type).t(payload)
X.conn.send(msg.tree())
sendIntent: (intent) ->
msg = $msg(to: @peerJid, type: 'chat')
.c('intent', xmlns: Tram.NS.WEBRTC).t(intent)
X.conn.send(msg.tree())
createOffer: ->
@pc.createOffer((offer) =>
@pc.setLocalDescription(offer, =>
@sendPayload(@pc.localDescription, 'offer')
, @fail)
, @fail)
receiveOffer: (offer) ->
@pc.setRemoteDescription(new RTCSessionDescription(offer), =>
@pc.createAnswer((answer) =>
@pc.setLocalDescription(answer, =>
@sendPayload(@pc.localDescription, 'answer')
, @fail)
, @fail)
, @fail)
receiveAnswer: (answer) ->
@pc.setRemoteDescription(new RTCSessionDescription(answer))
fail: =>
@disconnect()
@contact.unset('callstate')
disconnect: ->
if @call?
@call.unset('remote/stream')
@call.unset('local/stream')
calls.remove(@call)
if @rstream?
@stopStream(@rstream)
#@pc?.removeStream?(@rstream)
if @lstream?
@stopStream(@lstream)
#@pc?.removeStream?(@lstream)
if @pc?
@pc.close()
@pc = null
stopStream: (stream) ->
if stream.getAudioTracks?
for track in stream.getAudioTracks()
track.stop?()
if stream.getVideoTracks?
for track in stream.getVideoTracks()
track.stop?()
stream.stop?()