cryptpad/www/common/metadata-manager.js

148 lines
5.8 KiB
JavaScript
Raw Normal View History

2017-08-30 10:26:11 +00:00
define(['json.sortify'], function (Sortify) {
2017-08-10 16:31:44 +00:00
var UNINIT = 'uninitialized';
2017-08-10 12:49:21 +00:00
var create = function (sframeChan) {
2017-08-10 16:31:44 +00:00
var meta = UNINIT;
2017-08-10 12:49:21 +00:00
var members = [];
2017-08-10 16:31:44 +00:00
var metadataObj = UNINIT;
2017-08-17 16:26:58 +00:00
// This object reflects the metadata which is in the document at this moment.
// Normally when a person leaves the pad, everybody sees them leave and updates
// their metadata, this causes everyone to fight to change the document and
// operational transform doesn't like it. So this is a lazy object which is
// only updated either:
// 1. On changes to the metadata that come in from someone else
// 2. On changes connects, disconnects or changes to your own metadata
var metadataLazyObj = UNINIT;
2017-08-17 14:25:25 +00:00
var priv = {};
2017-08-10 12:49:21 +00:00
var dirty = true;
var changeHandlers = [];
var lazyChangeHandlers = [];
var titleChangeHandlers = [];
var rememberedTitle;
2017-08-09 15:37:55 +00:00
var checkUpdate = function (lazy) {
2017-08-10 12:49:21 +00:00
if (!dirty) { return; }
2017-08-10 16:31:44 +00:00
if (meta === UNINIT) { throw new Error(); }
if (metadataObj === UNINIT) {
metadataObj = {
defaultTitle: meta.doc.defaultTitle,
//title: meta.doc.defaultTitle,
2017-08-10 19:40:34 +00:00
type: meta.doc.type,
2017-08-10 16:31:44 +00:00
users: {}
};
metadataLazyObj = JSON.parse(JSON.stringify(metadataObj));
2017-08-10 16:31:44 +00:00
}
2017-08-21 16:21:53 +00:00
if (!metadataObj.users) { metadataObj.users = {}; }
if (!metadataLazyObj.users) { metadataLazyObj.users = {}; }
2017-08-10 12:49:21 +00:00
var mdo = {};
2017-08-10 16:31:44 +00:00
// We don't want to add our user data to the object multiple times.
2017-08-17 12:55:44 +00:00
//var containsYou = false;
2017-08-10 19:40:34 +00:00
//console.log(metadataObj);
2017-08-10 16:31:44 +00:00
Object.keys(metadataObj.users).forEach(function (x) {
2017-08-10 12:49:21 +00:00
if (members.indexOf(x) === -1) { return; }
2017-08-10 16:31:44 +00:00
mdo[x] = metadataObj.users[x];
2017-08-17 12:55:44 +00:00
/*if (metadataObj.users[x].uid === meta.user.uid) {
2017-08-10 19:40:34 +00:00
//console.log('document already contains you');
2017-08-10 16:31:44 +00:00
containsYou = true;
2017-08-17 12:55:44 +00:00
}*/
2017-08-10 12:49:21 +00:00
});
2017-08-17 12:55:44 +00:00
//if (!containsYou) { mdo[meta.user.netfluxId] = meta.user; }
2017-08-28 13:13:16 +00:00
if (!priv.readOnly) {
mdo[meta.user.netfluxId] = meta.user;
}
2017-08-10 16:31:44 +00:00
metadataObj.users = mdo;
2017-08-17 16:26:58 +00:00
var lazyUserStr = JSON.stringify(metadataLazyObj.users[meta.user.netfluxId]);
dirty = false;
2017-08-17 16:26:58 +00:00
if (lazy || lazyUserStr !== JSON.stringify(meta.user)) {
metadataLazyObj = JSON.parse(JSON.stringify(metadataObj));
lazyChangeHandlers.forEach(function (f) { f(); });
}
if (metadataObj.title !== rememberedTitle) {
console.log("Title update\n" + metadataObj.title + '\n');
rememberedTitle = metadataObj.title;
titleChangeHandlers.forEach(function (f) { f(metadataObj.title); });
}
2017-08-17 12:55:44 +00:00
2017-08-10 12:49:21 +00:00
changeHandlers.forEach(function (f) { f(); });
};
var change = function (lazy) {
2017-08-10 12:49:21 +00:00
dirty = true;
setTimeout(function () {
checkUpdate(lazy);
});
2017-08-09 15:37:55 +00:00
};
2017-09-05 09:35:15 +00:00
console.log('here register');
2017-08-10 16:31:44 +00:00
sframeChan.on('EV_METADATA_UPDATE', function (ev) {
meta = ev;
2017-08-17 14:25:25 +00:00
if (ev.priv) {
priv = ev.priv;
}
change(true);
2017-08-10 12:49:21 +00:00
});
sframeChan.on('EV_RT_CONNECT', function (ev) {
2017-08-10 19:40:34 +00:00
meta.user.netfluxId = ev.myID;
2017-08-10 12:49:21 +00:00
members = ev.members;
change(true);
2017-08-10 12:49:21 +00:00
});
sframeChan.on('EV_RT_JOIN', function (ev) {
members.push(ev);
change(false);
2017-08-10 12:49:21 +00:00
});
sframeChan.on('EV_RT_LEAVE', function (ev) {
var idx = members.indexOf(ev);
if (idx === -1) { console.log('Error: ' + ev + ' not in members'); return; }
members.splice(idx, 1);
change(false);
2017-08-10 12:49:21 +00:00
});
sframeChan.on('EV_RT_DISCONNECT', function () {
members = [];
change(true);
2017-08-10 12:49:21 +00:00
});
2017-08-09 15:37:55 +00:00
2017-08-10 12:49:21 +00:00
return Object.freeze({
2017-08-10 16:31:44 +00:00
updateMetadata: function (m) {
2017-08-30 10:26:11 +00:00
// JSON.parse(JSON.stringify()) reorders the json, so we have to use sortify even
// if it's on our own computer
if (Sortify(metadataLazyObj) === Sortify(m)) { return; }
2017-08-17 16:26:58 +00:00
metadataObj = JSON.parse(JSON.stringify(m));
metadataLazyObj = JSON.parse(JSON.stringify(m));
change(false);
2017-08-10 12:49:21 +00:00
},
2017-08-17 17:01:03 +00:00
updateTitle: function (t) {
metadataObj.title = t;
change(true);
},
2017-08-10 12:49:21 +00:00
getMetadata: function () {
checkUpdate(false);
return Object.freeze(JSON.parse(JSON.stringify(metadataObj)));
2017-08-10 12:49:21 +00:00
},
getMetadataLazy: function () {
return metadataLazyObj;
},
onTitleChange: function (f) { titleChangeHandlers.push(f); },
2017-08-17 12:55:44 +00:00
onChange: function (f) { changeHandlers.push(f); },
onChangeLazy: function (f) { lazyChangeHandlers.push(f); },
isConnected : function () {
return members.indexOf(meta.user.netfluxId) !== -1;
2017-08-17 12:55:44 +00:00
},
getViewers : function () {
checkUpdate(false);
2017-08-17 12:55:44 +00:00
var list = members.slice().filter(function (m) { return m.length === 32; });
return list.length - Object.keys(metadataObj.users).length;
2017-08-17 14:25:25 +00:00
},
getPrivateData : function () {
2017-08-17 14:25:25 +00:00
return priv;
2017-08-18 08:47:30 +00:00
},
getUserData : function () {
return meta.user;
},
2017-08-18 08:47:30 +00:00
getNetfluxId : function () {
return meta.user.netfluxId;
2017-08-17 12:55:44 +00:00
}
2017-08-10 12:49:21 +00:00
});
};
return Object.freeze({ create: create });
2017-08-17 12:55:44 +00:00
});