Merge branch 'beta' of github.com:xwiki-labs/cryptpad into beta
This commit is contained in:
@@ -4,10 +4,9 @@ define([
|
||||
var ChainPad = window.ChainPad;
|
||||
var JsonOT = {};
|
||||
|
||||
/* FIXME
|
||||
resultOp after transform0() might be null, in which case you should return null
|
||||
because it is simply a transformation which yields a "do nothing" operation */
|
||||
var validate = JsonOT.validate = function (text, toTransform, transformBy) {
|
||||
var DEBUG = window.REALTIME_DEBUG = window.REALTIME_DEBUG || {};
|
||||
|
||||
var resultOp, text2, text3;
|
||||
try {
|
||||
// text = O (mutual common ancestor)
|
||||
@@ -28,7 +27,7 @@ define([
|
||||
return resultOp;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
var info = window.REALTIME_MODULE.ot_parseError = {
|
||||
var info = DEBUG.ot_parseError = {
|
||||
type: 'resultParseError',
|
||||
resultOp: resultOp,
|
||||
|
||||
@@ -40,11 +39,11 @@ define([
|
||||
text3: text3,
|
||||
error: e
|
||||
};
|
||||
console.log('Debugging info available at `window.REALTIME_MODULE.ot_parseError`');
|
||||
console.log('Debugging info available at `window.REALTIME_DEBUG.ot_parseError`');
|
||||
}
|
||||
} catch (x) {
|
||||
console.error(x);
|
||||
window.REALTIME_MODULE.ot_applyError = {
|
||||
window.DEBUG.ot_applyError = {
|
||||
type: 'resultParseError',
|
||||
resultOp: resultOp,
|
||||
|
||||
@@ -56,7 +55,7 @@ define([
|
||||
text3: text3,
|
||||
error: x
|
||||
};
|
||||
console.log('Debugging info available at `window.REALTIME_MODULE.ot_applyError`');
|
||||
console.log('Debugging info available at `window.REALTIME_DEBUG.ot_applyError`');
|
||||
}
|
||||
|
||||
// returning **null** breaks out of the loop
|
||||
|
||||
@@ -1,225 +1,291 @@
|
||||
/*global: WebSocket */
|
||||
define(() => {
|
||||
'use strict';
|
||||
const MAX_LAG_BEFORE_PING = 15000;
|
||||
const MAX_LAG_BEFORE_DISCONNECT = 30000;
|
||||
const PING_CYCLE = 5000;
|
||||
const REQUEST_TIMEOUT = 30000;
|
||||
define(function () {
|
||||
'use strict';
|
||||
|
||||
const now = () => new Date().getTime();
|
||||
var MAX_LAG_BEFORE_PING = 15000;
|
||||
var MAX_LAG_BEFORE_DISCONNECT = 30000;
|
||||
var PING_CYCLE = 5000;
|
||||
var REQUEST_TIMEOUT = 30000;
|
||||
|
||||
const networkSendTo = (ctx, peerId, content) => {
|
||||
const seq = ctx.seq++;
|
||||
ctx.ws.send(JSON.stringify([seq, 'MSG', peerId, content]));
|
||||
return new Promise((res, rej) => {
|
||||
ctx.requests[seq] = { reject: rej, resolve: res, time: now() };
|
||||
});
|
||||
};
|
||||
|
||||
const channelBcast = (ctx, chanId, content) => {
|
||||
const chan = ctx.channels[chanId];
|
||||
if (!chan) { throw new Error("no such channel " + chanId); }
|
||||
const seq = ctx.seq++;
|
||||
ctx.ws.send(JSON.stringify([seq, 'MSG', chanId, content]));
|
||||
return new Promise((res, rej) => {
|
||||
ctx.requests[seq] = { reject: rej, resolve: res, time: now() };
|
||||
});
|
||||
};
|
||||
|
||||
const channelLeave = (ctx, chanId, reason) => {
|
||||
const chan = ctx.channels[chanId];
|
||||
if (!chan) { throw new Error("no such channel " + chanId); }
|
||||
delete ctx.channels[chanId];
|
||||
ctx.ws.send(JSON.stringify([ctx.seq++, 'LEAVE', chanId, reason]));
|
||||
};
|
||||
|
||||
const makeEventHandlers = (ctx, mappings) => {
|
||||
return (name, handler) => {
|
||||
const handlers = mappings[name];
|
||||
if (!handlers) { throw new Error("no such event " + name); }
|
||||
handlers.push(handler);
|
||||
var now = function now() {
|
||||
return new Date().getTime();
|
||||
};
|
||||
};
|
||||
|
||||
const mkChannel = (ctx, id) => {
|
||||
const internal = {
|
||||
onMessage: [],
|
||||
onJoin: [],
|
||||
onLeave: [],
|
||||
members: [],
|
||||
jSeq: ctx.seq++
|
||||
};
|
||||
const chan = {
|
||||
_: internal,
|
||||
id: id,
|
||||
members: internal.members,
|
||||
bcast: (msg) => channelBcast(ctx, chan.id, msg),
|
||||
leave: (reason) => channelLeave(ctx, chan.id, reason),
|
||||
on: makeEventHandlers(ctx, { message:
|
||||
internal.onMessage, join: internal.onJoin, leave: internal.onLeave })
|
||||
};
|
||||
ctx.requests[internal.jSeq] = chan;
|
||||
ctx.ws.send(JSON.stringify([internal.jSeq, 'JOIN', id]));
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
chan._.resolve = res;
|
||||
chan._.reject = rej;
|
||||
})
|
||||
};
|
||||
|
||||
const mkNetwork = (ctx) => {
|
||||
const network = {
|
||||
webChannels: ctx.channels,
|
||||
getLag: () => (ctx.lag),
|
||||
sendto: (peerId, content) => (networkSendTo(ctx, peerId, content)),
|
||||
join: (chanId) => (mkChannel(ctx, chanId)),
|
||||
on: makeEventHandlers(ctx, { message: ctx.onMessage, disconnect: ctx.onDisconnect })
|
||||
};
|
||||
network.__defineGetter__("webChannels", () => {
|
||||
return Object.keys(ctx.channels).map((k) => (ctx.channels[k]));
|
||||
});
|
||||
return network;
|
||||
};
|
||||
|
||||
const onMessage = (ctx, evt) => {
|
||||
let msg;
|
||||
try { msg = JSON.parse(evt.data); } catch (e) { console.log(e.stack); return; }
|
||||
if (msg[0] !== 0) {
|
||||
const req = ctx.requests[msg[0]];
|
||||
if (!req) {
|
||||
console.log("error: " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
delete ctx.requests[msg[0]];
|
||||
if (msg[1] === 'ACK') {
|
||||
if (req.ping) { // ACK of a PING
|
||||
ctx.lag = now() - Number(req.ping);
|
||||
return;
|
||||
}
|
||||
req.resolve();
|
||||
} else if (msg[1] === 'JACK') {
|
||||
if (req._) {
|
||||
// Channel join request...
|
||||
if (!msg[2]) { throw new Error("wrong type of ACK for channel join"); }
|
||||
req.id = msg[2];
|
||||
ctx.channels[req.id] = req;
|
||||
return;
|
||||
}
|
||||
req.resolve();
|
||||
} else if (msg[1] === 'ERROR') {
|
||||
req.reject({ type: msg[2], message: msg[3] });
|
||||
} else {
|
||||
req.reject({ type: 'UNKNOWN', message: JSON.stringify(msg) });
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (msg[2] === 'IDENT') {
|
||||
ctx.uid = msg[3];
|
||||
|
||||
setInterval(() => {
|
||||
if (now() - ctx.timeOfLastMessage < MAX_LAG_BEFORE_PING) { return; }
|
||||
let seq = ctx.seq++;
|
||||
let currentDate = now();
|
||||
ctx.requests[seq] = {time: now(), ping: currentDate};
|
||||
ctx.ws.send(JSON.stringify([seq, 'PING', currentDate]));
|
||||
if (now() - ctx.timeOfLastMessage > MAX_LAG_BEFORE_DISCONNECT) {
|
||||
ctx.ws.close();
|
||||
}
|
||||
}, PING_CYCLE);
|
||||
|
||||
return;
|
||||
} else if (!ctx.uid) {
|
||||
// extranious message, waiting for an ident.
|
||||
return;
|
||||
}
|
||||
if (msg[2] === 'PING') {
|
||||
msg[2] = 'PONG';
|
||||
ctx.ws.send(JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg[2] === 'MSG') {
|
||||
let handlers;
|
||||
if (msg[3] === ctx.uid) {
|
||||
handlers = ctx.onMessage;
|
||||
} else {
|
||||
const chan = ctx.channels[msg[3]];
|
||||
if (!chan) {
|
||||
console.log("message to non-existant chan " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
handlers = chan._.onMessage;
|
||||
}
|
||||
handlers.forEach((h) => {
|
||||
try { h(msg[4], msg[1]); } catch (e) { console.error(e); }
|
||||
var networkSendTo = function networkSendTo(ctx, peerId, content) {
|
||||
var seq = ctx.seq++;
|
||||
ctx.ws.send(JSON.stringify([seq, 'MSG', peerId, content]));
|
||||
return new Promise(function (res, rej) {
|
||||
ctx.requests[seq] = { reject: rej, resolve: res, time: now() };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (msg[2] === 'LEAVE') {
|
||||
const chan = ctx.channels[msg[3]];
|
||||
var channelBcast = function channelBcast(ctx, chanId, content) {
|
||||
var chan = ctx.channels[chanId];
|
||||
if (!chan) {
|
||||
console.log("leaving non-existant chan " + JSON.stringify(msg));
|
||||
return;
|
||||
throw new Error("no such channel " + chanId);
|
||||
}
|
||||
chan._.onLeave.forEach((h) => {
|
||||
try { h(msg[1], msg[4]); } catch (e) { console.log(e.stack); }
|
||||
var seq = ctx.seq++;
|
||||
ctx.ws.send(JSON.stringify([seq, 'MSG', chanId, content]));
|
||||
return new Promise(function (res, rej) {
|
||||
ctx.requests[seq] = { reject: rej, resolve: res, time: now() };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (msg[2] === 'JOIN') {
|
||||
const chan = ctx.channels[msg[3]];
|
||||
var channelLeave = function channelLeave(ctx, chanId, reason) {
|
||||
var chan = ctx.channels[chanId];
|
||||
if (!chan) {
|
||||
console.log("ERROR: join to non-existant chan " + JSON.stringify(msg));
|
||||
throw new Error("no such channel " + chanId);
|
||||
}
|
||||
delete ctx.channels[chanId];
|
||||
ctx.ws.send(JSON.stringify([ctx.seq++, 'LEAVE', chanId, reason]));
|
||||
};
|
||||
|
||||
var makeEventHandlers = function makeEventHandlers(ctx, mappings) {
|
||||
return function (name, handler) {
|
||||
var handlers = mappings[name];
|
||||
if (!handlers) {
|
||||
throw new Error("no such event " + name);
|
||||
}
|
||||
handlers.push(handler);
|
||||
};
|
||||
};
|
||||
|
||||
var mkChannel = function mkChannel(ctx, id) {
|
||||
var internal = {
|
||||
onMessage: [],
|
||||
onJoin: [],
|
||||
onLeave: [],
|
||||
members: [],
|
||||
jSeq: ctx.seq++
|
||||
};
|
||||
var chan = {
|
||||
_: internal,
|
||||
time: now(),
|
||||
id: id,
|
||||
members: internal.members,
|
||||
bcast: function bcast(msg) {
|
||||
return channelBcast(ctx, chan.id, msg);
|
||||
},
|
||||
leave: function leave(reason) {
|
||||
return channelLeave(ctx, chan.id, reason);
|
||||
},
|
||||
on: makeEventHandlers(ctx, { message: internal.onMessage, join: internal.onJoin, leave: internal.onLeave })
|
||||
};
|
||||
ctx.requests[internal.jSeq] = chan;
|
||||
ctx.ws.send(JSON.stringify([internal.jSeq, 'JOIN', id]));
|
||||
|
||||
return new Promise(function (res, rej) {
|
||||
chan._.resolve = res;
|
||||
chan._.reject = rej;
|
||||
});
|
||||
};
|
||||
|
||||
var mkNetwork = function mkNetwork(ctx) {
|
||||
var network = {
|
||||
webChannels: ctx.channels,
|
||||
getLag: function getLag() {
|
||||
return ctx.lag;
|
||||
},
|
||||
sendto: function sendto(peerId, content) {
|
||||
return networkSendTo(ctx, peerId, content);
|
||||
},
|
||||
join: function join(chanId) {
|
||||
return mkChannel(ctx, chanId);
|
||||
},
|
||||
on: makeEventHandlers(ctx, { message: ctx.onMessage, disconnect: ctx.onDisconnect })
|
||||
};
|
||||
network.__defineGetter__("webChannels", function () {
|
||||
return Object.keys(ctx.channels).map(function (k) {
|
||||
return ctx.channels[k];
|
||||
});
|
||||
});
|
||||
return network;
|
||||
};
|
||||
|
||||
var onMessage = function onMessage(ctx, evt) {
|
||||
var msg = void 0;
|
||||
try {
|
||||
msg = JSON.parse(evt.data);
|
||||
} catch (e) {
|
||||
console.log(e.stack);return;
|
||||
}
|
||||
if (msg[0] !== 0) {
|
||||
var req = ctx.requests[msg[0]];
|
||||
if (!req) {
|
||||
console.log("error: " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
delete ctx.requests[msg[0]];
|
||||
if (msg[1] === 'ACK') {
|
||||
if (req.ping) {
|
||||
// ACK of a PING
|
||||
ctx.lag = now() - Number(req.ping);
|
||||
return;
|
||||
}
|
||||
req.resolve();
|
||||
} else if (msg[1] === 'JACK') {
|
||||
if (req._) {
|
||||
// Channel join request...
|
||||
if (!msg[2]) {
|
||||
throw new Error("wrong type of ACK for channel join");
|
||||
}
|
||||
req.id = msg[2];
|
||||
ctx.channels[req.id] = req;
|
||||
return;
|
||||
}
|
||||
req.resolve();
|
||||
} else if (msg[1] === 'ERROR') {
|
||||
req.reject({ type: msg[2], message: msg[3] });
|
||||
} else {
|
||||
req.reject({ type: 'UNKNOWN', message: JSON.stringify(msg) });
|
||||
}
|
||||
return;
|
||||
}
|
||||
// have we yet fully joined the chan?
|
||||
const synced = (chan._.members.indexOf(ctx.uid) !== -1);
|
||||
chan._.members.push(msg[1]);
|
||||
if (!synced && msg[1] === ctx.uid) {
|
||||
// sync the channel join event
|
||||
chan.myID = ctx.uid;
|
||||
chan._.resolve(chan);
|
||||
|
||||
if (msg[2] === 'IDENT') {
|
||||
ctx.uid = msg[3];
|
||||
|
||||
setInterval(function () {
|
||||
if (now() - ctx.timeOfLastMessage < MAX_LAG_BEFORE_PING) {
|
||||
return;
|
||||
}
|
||||
var seq = ctx.seq++;
|
||||
var currentDate = now();
|
||||
ctx.requests[seq] = { time: now(), ping: currentDate };
|
||||
ctx.ws.send(JSON.stringify([seq, 'PING', currentDate]));
|
||||
if (now() - ctx.timeOfLastMessage > MAX_LAG_BEFORE_DISCONNECT) {
|
||||
ctx.ws.close();
|
||||
}
|
||||
}, PING_CYCLE);
|
||||
|
||||
return;
|
||||
} else if (!ctx.uid) {
|
||||
// extranious message, waiting for an ident.
|
||||
return;
|
||||
}
|
||||
if (synced) {
|
||||
chan._.onJoin.forEach((h) => {
|
||||
try { h(msg[1]); } catch (e) { console.log(e.stack); }
|
||||
if (msg[2] === 'PING') {
|
||||
msg[2] = 'PONG';
|
||||
ctx.ws.send(JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg[2] === 'MSG') {
|
||||
var handlers = void 0;
|
||||
if (msg[3] === ctx.uid) {
|
||||
handlers = ctx.onMessage;
|
||||
} else {
|
||||
var chan = ctx.channels[msg[3]];
|
||||
if (!chan) {
|
||||
console.log("message to non-existant chan " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
handlers = chan._.onMessage;
|
||||
}
|
||||
handlers.forEach(function (h) {
|
||||
try {
|
||||
h(msg[4], msg[1]);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const connect = (websocketURL) => {
|
||||
let ctx = {
|
||||
ws: new WebSocket(websocketURL),
|
||||
seq: 1,
|
||||
lag: 0,
|
||||
uid: null,
|
||||
network: null,
|
||||
channels: {},
|
||||
onMessage: [],
|
||||
onDisconnect: [],
|
||||
requests: {}
|
||||
};
|
||||
setInterval(() => {
|
||||
for (let id in ctx.requests) {
|
||||
const req = ctx.requests[id];
|
||||
if (now() - req.time > REQUEST_TIMEOUT) {
|
||||
delete ctx.requests[id];
|
||||
if(typeof req.reject === "function") { req.reject({ type: 'TIMEOUT', message: 'waited ' + now() - req.time + 'ms' }); }
|
||||
if (msg[2] === 'LEAVE') {
|
||||
var _chan = ctx.channels[msg[3]];
|
||||
if (!_chan) {
|
||||
console.log("leaving non-existant chan " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
_chan._.onLeave.forEach(function (h) {
|
||||
try {
|
||||
h(msg[1], msg[4]);
|
||||
} catch (e) {
|
||||
console.log(e.stack);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (msg[2] === 'JOIN') {
|
||||
var _chan2 = ctx.channels[msg[3]];
|
||||
if (!_chan2) {
|
||||
console.log("ERROR: join to non-existant chan " + JSON.stringify(msg));
|
||||
return;
|
||||
}
|
||||
// have we yet fully joined the chan?
|
||||
var synced = _chan2._.members.indexOf(ctx.uid) !== -1;
|
||||
_chan2._.members.push(msg[1]);
|
||||
if (!synced && msg[1] === ctx.uid) {
|
||||
// sync the channel join event
|
||||
_chan2.myID = ctx.uid;
|
||||
_chan2._.resolve(_chan2);
|
||||
}
|
||||
if (synced) {
|
||||
_chan2._.onJoin.forEach(function (h) {
|
||||
try {
|
||||
h(msg[1]);
|
||||
} catch (e) {
|
||||
console.log(e.stack);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, 5000);
|
||||
ctx.network = mkNetwork(ctx);
|
||||
ctx.ws.onmessage = (msg) => (onMessage(ctx, msg));
|
||||
ctx.ws.onclose = (evt) => {
|
||||
ctx.onDisconnect.forEach((h) => {
|
||||
try { h(evt.reason); } catch (e) { console.log(e.stack); }
|
||||
};
|
||||
|
||||
var connect = function connect(websocketURL) {
|
||||
var ctx = {
|
||||
ws: new WebSocket(websocketURL),
|
||||
seq: 1,
|
||||
lag: 0,
|
||||
uid: null,
|
||||
network: null,
|
||||
channels: {},
|
||||
onMessage: [],
|
||||
onDisconnect: [],
|
||||
requests: {}
|
||||
};
|
||||
setInterval(function () {
|
||||
for (var id in ctx.requests) {
|
||||
var req = ctx.requests[id];
|
||||
if (now() - req.time > REQUEST_TIMEOUT) {
|
||||
delete ctx.requests[id];
|
||||
if (typeof req.reject === "function") {
|
||||
req.reject({ type: 'TIMEOUT', message: 'waited ' + (now() - req.time) + 'ms' });
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 5000);
|
||||
ctx.network = mkNetwork(ctx);
|
||||
ctx.ws.onmessage = function (msg) {
|
||||
return onMessage(ctx, msg);
|
||||
};
|
||||
ctx.ws.onclose = function (evt) {
|
||||
ctx.onDisconnect.forEach(function (h) {
|
||||
try {
|
||||
h(evt.reason);
|
||||
} catch (e) {
|
||||
console.log(e.stack);
|
||||
}
|
||||
});
|
||||
};
|
||||
return new Promise(function (resolve, reject) {
|
||||
ctx.ws.onopen = function () {
|
||||
var count = 0;
|
||||
var interval = 100;
|
||||
var checkIdent = function() {
|
||||
if(ctx.uid !== null) {
|
||||
return resolve(ctx.network);
|
||||
}
|
||||
else {
|
||||
if(count * interval > REQUEST_TIMEOUT) {
|
||||
return reject({ type: 'TIMEOUT', message: 'waited ' + (count * interval) + 'ms' });
|
||||
}
|
||||
setTimeout(checkIdent, 100);
|
||||
}
|
||||
}
|
||||
checkIdent();
|
||||
};
|
||||
});
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
ctx.ws.onopen = () => resolve(ctx.network);
|
||||
});
|
||||
};
|
||||
|
||||
return { connect: connect };
|
||||
});
|
||||
return { connect: connect };
|
||||
});
|
||||
@@ -15,16 +15,15 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
define([
|
||||
'/common/messages.js',
|
||||
'/common/netflux-client.js',
|
||||
'/common/crypto.js',
|
||||
'/common/es6-promise.min.js',
|
||||
'/common/chainpad.js',
|
||||
'/bower_components/jquery/dist/jquery.min.js',
|
||||
], function (Messages, Netflux, Crypto) {
|
||||
], function (Netflux) {
|
||||
var $ = window.jQuery;
|
||||
var ChainPad = window.ChainPad;
|
||||
var PARANOIA = true;
|
||||
var USE_HISTORY = true;
|
||||
var module = { exports: {} };
|
||||
|
||||
/**
|
||||
@@ -44,14 +43,14 @@ define([
|
||||
var websocketUrl = config.websocketURL;
|
||||
var userName = config.userName;
|
||||
var channel = config.channel;
|
||||
var chanKey = config.cryptKey;
|
||||
var chanKey = config.cryptKey || '';
|
||||
var Crypto = config.crypto;
|
||||
var cryptKey = Crypto.parseKey(chanKey).cryptKey;
|
||||
var passwd = 'y';
|
||||
|
||||
// make sure configuration is defined
|
||||
config = config || {};
|
||||
|
||||
var allMessages = [];
|
||||
var initializing = true;
|
||||
var recoverableErrorCount = 0; // unused
|
||||
var toReturn = {};
|
||||
@@ -99,6 +98,11 @@ define([
|
||||
};
|
||||
|
||||
var onReady = function(wc, network) {
|
||||
if(config.setMyID) {
|
||||
config.setMyID({
|
||||
myID: wc.myID
|
||||
});
|
||||
}
|
||||
// Trigger onJoining with our own Cryptpad username to tell the toolbar that we are synced
|
||||
onJoining(wc.myID);
|
||||
|
||||
@@ -127,11 +131,10 @@ define([
|
||||
var message = chainpadAdapter.msgIn(peer, msg);
|
||||
|
||||
verbose(message);
|
||||
allMessages.push(message);
|
||||
|
||||
if (!initializing) {
|
||||
if (toReturn.onLocal) {
|
||||
toReturn.onLocal();
|
||||
if (config.onLocal) {
|
||||
config.onLocal();
|
||||
}
|
||||
}
|
||||
// pass the message into Chainpad
|
||||
@@ -205,11 +208,6 @@ define([
|
||||
wc.on('join', onJoining);
|
||||
wc.on('leave', onLeaving);
|
||||
|
||||
if(config.setMyID) {
|
||||
config.setMyID({
|
||||
myID: wc.myID
|
||||
});
|
||||
}
|
||||
// Open a Chainpad session
|
||||
realtime = createRealtime();
|
||||
|
||||
@@ -249,14 +247,22 @@ define([
|
||||
});
|
||||
|
||||
// Get the channel history
|
||||
var hc;
|
||||
wc.members.forEach(function (p) {
|
||||
if (p.length === 16) { hc = p; }
|
||||
});
|
||||
wc.history_keeper = hc;
|
||||
if (hc) { network.sendto(hc, JSON.stringify(['GET_HISTORY', wc.id])); }
|
||||
if(USE_HISTORY) {
|
||||
var hc;
|
||||
|
||||
wc.members.forEach(function (p) {
|
||||
if (p.length === 16) { hc = p; }
|
||||
});
|
||||
wc.history_keeper = hc;
|
||||
|
||||
if (hc) { network.sendto(hc, JSON.stringify(['GET_HISTORY', wc.id])); }
|
||||
}
|
||||
|
||||
realtime.start();
|
||||
|
||||
if(!USE_HISTORY) {
|
||||
onReady(wc, network);
|
||||
}
|
||||
};
|
||||
|
||||
var findChannelById = function(webChannels, channelId) {
|
||||
|
||||
Reference in New Issue
Block a user