-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
173 lines (136 loc) · 3.8 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
var cuid = require('cuid');
var Observ = require('observ');
var ObservArray = require('observ-array');
var ObservStruct = require('observ-struct');
var extend = require('cog/extend');
/**
# observ-conference
An experimental implementation of an
[Observ](https://github.com/Raynos/Observ) that works with an
[rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect) conference
instance.
__NOTE:__ This was some early experimentation around combining rtc.io
packages and observables. We are working on an implementation which
is generally more useful...
## Example Usage
To be completed.
**/
module.exports = function(conference, opts) {
var peers = ObservArray([]);
var data = ObservStruct({
room: Observ(cuid()),
peers: peers
});
function findById(id) {
var idx = 0;
var len = peers.getLength();
var peer;
while (idx < len) {
peer = peers.get(idx);
if ((typeof peer.uid == 'function' && peer.uid() === id) || peer.id() === id) {
break;
}
idx++;
}
if (idx < len) {
return peers.get(idx);
}
}
function removePeer(id) {
peers.transaction(function(raw) {
var idx = 0;
while (idx < raw.length && raw[idx].id() !== id) {
idx++;
}
if (idx < raw.length) {
raw.splice(idx, 1);
}
});
}
function streamAdd(id, stream) {
var peer = findById(id);
if (peer) {
peer.streams.push(stream);
stream.addEventListener('ended', function() {
peer.streams.transaction(function(raw) {
var idx = raw.indexOf(stream);
if (idx >= 0) {
raw.splice(idx, 1);
}
});
});
}
}
function streamRemove(id) {
}
function updatePeer(id, data, connected) {
var p = {
id: id,
streams: ObservArray([]),
connected: Observ(connected)
};
peers.transaction(function(raw) {
var idx = 0;
var insertPeer = true;
var keys = Object.keys(data);
while (idx < raw.length && raw[idx].id() !== id) {
idx++;
}
if (idx < raw.length) {
insertPeer = keys.filter(function(key) {
var ob = raw[idx][key];
// if we don't have an observable for this attribute
// throw away the object and start again
if (typeof ob != 'function') {
return false;
}
if (ob() !== data[key]) {
ob.set(data[key]);
}
return true;
}).length !== keys.length;
// toggle the connection state
if (connected || raw[idx].connected()) {
p.connected.set(true);
raw[idx].connected.set(true);
}
if (insertPeer) {
raw.splice(idx, 1);
}
}
if (insertPeer) {
keys.forEach(function(key) {
p[key] = Observ(data[key]);
});
raw.push(ObservStruct(p));
}
raw.sort(function(a, b) {
return a.id().localeCompare(b.id());
});
});
}
conference.on('local:announce', function(data) {
updatePeer(data.id, extend({ local: true }, data), true);
});
conference.on('peer:announce', function(data) {
updatePeer(data.id, data);
});
conference.on('peer:update', function(data) {
updatePeer(data.id, data);
});
conference.on('call:started', function(id, pc, data) {
updatePeer(id, extend({ connection: pc }, data), true);
});
conference.on('stream:added', streamAdd);
conference.on('stream:removed', streamRemove);
conference.on('call:ended', removePeer);
// patch a findById function
peers.findById = findById;
// when the room changes announce
data.room(function(room) {
conference.announce({ room: room });
});
// announce in our autogenerated room
conference.announce({ room: data.room() });
return data;
};