yay, they talk and they don't fight

This commit is contained in:
Caleb James DeLisle
2017-08-10 18:31:44 +02:00
parent e786a66ff3
commit 1e56fa31c0
7 changed files with 99 additions and 43 deletions

View File

@@ -1,24 +1,38 @@
define([], function () {
var UNINIT = 'uninitialized';
var create = function (sframeChan) {
var personalMetadata = 'uninitialized';
var myID = 'uninitialized';
var meta = UNINIT;
var myID = UNINIT;
var members = [];
var metadataObj = 'unintialized';
var metadataObj = UNINIT;
var dirty = true;
var changeHandlers = [];
var checkUpdate = function () {
if (!dirty) { return; }
if (metadataObj === 'uninitialized') { throw new Error(); }
if (myID === 'uninitialized') { throw new Error(); }
if (personalMetadata === 'uninitialized') { throw new Error(); }
if (meta === UNINIT) { throw new Error(); }
if (myID === UNINIT) { myID = meta.myID; }
if (metadataObj === UNINIT) {
metadataObj = {
defaultTitle: meta.doc.defaultTitle,
title: meta.doc.defaultTitle,
users: {}
};
}
var mdo = {};
Object.keys(metadataObj).forEach(function (x) {
// We don't want to add our user data to the object multiple times.
var containsYou = false;
console.log(metadataObj);
Object.keys(metadataObj.users).forEach(function (x) {
if (members.indexOf(x) === -1) { return; }
mdo[x] = metadataObj[x];
mdo[x] = metadataObj.users[x];
if (metadataObj.users[x].uid === meta.user.uid) {
console.log('document already contains you');
containsYou = true;
}
});
mdo[myID] = personalMetadata;
metadataObj = mdo;
if (!containsYou) { mdo[myID] = meta.user; }
metadataObj.users = mdo;
dirty = false;
changeHandlers.forEach(function (f) { f(); });
};
@@ -27,8 +41,8 @@ define([], function () {
setTimeout(checkUpdate);
};
sframeChan.on('EV_USERDATA_UPDATE', function (ev) {
personalMetadata = ev;
sframeChan.on('EV_METADATA_UPDATE', function (ev) {
meta = ev;
change();
});
sframeChan.on('EV_RT_CONNECT', function (ev) {
@@ -52,8 +66,9 @@ define([], function () {
});
return Object.freeze({
metadataChange: function (meta) {
metadataObj = meta;
updateMetadata: function (m) {
if (JSON.stringify(metadataObj) === JSON.stringify(m)) { return; }
metadataObj = m;
change();
},
getMetadata: function () {

View File

@@ -52,7 +52,7 @@ define([
onConnectionChange({ state: false });
});
sframeChan.on('EV_RT_CONNECT', function (content) {
content.members.forEach(userList.onJoin);
//content.members.forEach(userList.onJoin);
myID = content.myID;
isReady = false;
if (chainpad) {

View File

@@ -228,7 +228,9 @@ define([], function () {
return {
start: function (config) {
config.sframeChan.whenReg('EV_RT_READY', function () { start(config); });
config.sframeChan.whenReg('EV_RT_READY', function () {
start(config);
});
}
};
});

View File

@@ -18,6 +18,7 @@ define([
var chan = {};
// Send a query. channel.query('Q_SOMETHING', { args: "whatever" }, function (reply) { ... });
chan.query = function (q, content, cb) {
if (!otherWindow) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[q]) {
@@ -40,6 +41,7 @@ define([
}), '*');
};
// Fire an event. channel.event('EV_SOMETHING', { args: "whatever" });
var event = chan.event = function (e, content) {
if (!otherWindow) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[e]) {
@@ -51,13 +53,17 @@ define([
otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*');
};
// Be notified on query or event. channel.on('EV_SOMETHING', function (args, reply) { ... });
// If the type is a query, your handler will be invoked with a reply function that takes
// one argument (the content to reply with).
chan.on = function (queryType, handler, quiet) {
if (!otherWindow) { throw new Error('not yet initialized'); }
if (!otherWindow && !quiet) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[queryType]) {
throw new Error('please only register handlers which are defined in sframe-protocol.js');
}
(handlers[queryType] = handlers[queryType] || []).push(function (data, msg) {
handler(data.content, function (replyContent) {
if (queryType.indexOf('Q_') !== 0) { throw new Error("replies to events are invalid"); }
msg.source.postMessage(JSON.stringify({
txid: data.txid,
content: replyContent
@@ -69,25 +75,35 @@ define([
}
};
chan.whenReg = function (queryType, handler) {
// If a particular handler is registered, call the callback immediately, otherwise it will be called
// when that handler is first registered.
// channel.whenReg('Q_SOMETHING', function () { ...query Q_SOMETHING?... });
chan.whenReg = function (queryType, cb, always) {
if (!otherWindow) { throw new Error('not yet initialized'); }
if (!SFrameProtocol[queryType]) {
throw new Error('please only register handlers which are defined in sframe-protocol.js');
}
var reg = always;
if (insideHandlers.indexOf(queryType) > -1) {
handler();
cb();
} else {
(callWhenRegistered[queryType] = callWhenRegistered[queryType] || []).push(handler);
reg = true;
}
if (reg) {
(callWhenRegistered[queryType] = callWhenRegistered[queryType] || []).push(cb);
}
};
(handlers['EV_REGISTER_HANDLER'] = handlers['EV_REGISTER_HANDLER'] || []).push(function (data) {
if (callWhenRegistered[data.content]) {
callWhenRegistered[data.content].forEach(function (f) { f(); });
delete callWhenRegistered[data.content];
// Same as whenReg except it will invoke every time there is another registration, not just once.
chan.onReg = function (queryType, cb) { chan.whenReg(queryType, cb, true); };
chan.on('EV_REGISTER_HANDLER', function (content) {
if (callWhenRegistered[content]) {
callWhenRegistered[content].forEach(function (f) { f(); });
delete callWhenRegistered[content];
}
insideHandlers.push(data.content);
});
insideHandlers.push(content);
}, true);
var intr;
var txid;

View File

@@ -34,5 +34,5 @@ define({
// Called from the outside, this informs the inside whenever the user's data has been changed.
// The argument is the object representing the content of the user profile minus the netfluxID
// which changes per-reconnect.
'EV_USERDATA_UPDATE': true
'EV_METADATA_UPDATE': true
});