Mailbox and notifications prototype
This commit is contained in:
@@ -1,30 +1,242 @@
|
||||
define([
|
||||
'/common/common-util.js',
|
||||
'/common/common-constants.js',
|
||||
'/common/common-realtime.js',
|
||||
'/customize/messages.js',
|
||||
'/bower_components/chainpad-netflux/chainpad-netflux.js',
|
||||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
], function (Util, Constants, Messages, CpNetflux, Crypto) {
|
||||
], function (Util, Constants, Realtime, Messages, CpNetflux, Crypto) {
|
||||
var Mailbox = {};
|
||||
|
||||
var TYPES = [
|
||||
'notifications'
|
||||
];
|
||||
var BLOCKING_TYPES = [
|
||||
];
|
||||
|
||||
/*
|
||||
proxy.mailboxes = {
|
||||
friends: {
|
||||
keys: '',
|
||||
channel: '',
|
||||
hash: '',
|
||||
lastKnownHash: '',
|
||||
viewed: []
|
||||
}
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
var isMessageNew = function (hash, m) {
|
||||
return (m.viewed || []).indexOf(hash) === -1 && hash !== m.lastKnownHash;
|
||||
};
|
||||
|
||||
var showMessage = function (ctx, type, msg, cId) {
|
||||
ctx.emit('MESSAGE', {
|
||||
type: type,
|
||||
content: msg
|
||||
}, cId ? [cId] : ctx.clients);
|
||||
};
|
||||
|
||||
var openChannel = function (ctx, type, m, onReady) {
|
||||
var box = ctx.boxes[type] = {
|
||||
queue: [],
|
||||
history: [],
|
||||
sendMessage: function (msg) { // To send a message to our box
|
||||
try {
|
||||
msg = JSON.stringify(msg);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
box.queue.push(msg);
|
||||
}
|
||||
};
|
||||
/*
|
||||
// XXX
|
||||
if (!Crypto.Mailbox) {
|
||||
return void console.error("chainpad-crypto is outdated and doesn't support mailboxes.");
|
||||
}
|
||||
var crypto = Crypto.Mailbox.createEncryptor();
|
||||
*/
|
||||
var crypto = {
|
||||
encrypt: function (x) { return x; },
|
||||
decrypt: function (x) { return x; }
|
||||
};
|
||||
var cfg = {
|
||||
network: ctx.store.network,
|
||||
channel: m.channel, // TODO
|
||||
noChainPad: true,
|
||||
crypto: crypto,
|
||||
owners: [ctx.store.proxy.edPublic],
|
||||
lastKnownHash: m.lastKnownHash
|
||||
};
|
||||
cfg.onConnect = function (wc, sendMessage) {
|
||||
// Send a message to our box?
|
||||
box.sendMessage = function (msg) {
|
||||
try {
|
||||
msg = JSON.stringify(msg);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
sendMessage(msg, function (err, hash) {
|
||||
if (m.viewed.indexOf(hash) === -1) {
|
||||
m.viewed.push(hash);
|
||||
}
|
||||
});
|
||||
};
|
||||
box.queue.forEach(function (msg) {
|
||||
box.sendMessage(msg);
|
||||
});
|
||||
box.queue = [];
|
||||
};
|
||||
cfg.onMessage = function (msg, user, vKey, isCpi, hash) {
|
||||
// TODO
|
||||
try {
|
||||
msg = JSON.parse(msg);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
if (isMessageNew(hash, m)) {
|
||||
// Message should be displayed
|
||||
var message = {
|
||||
msg: msg,
|
||||
hash: hash
|
||||
};
|
||||
box.history.push(message);
|
||||
showMessage(ctx, type, message);
|
||||
} else {
|
||||
// Message has already been viewer by the user
|
||||
if (history.length === 0) {
|
||||
m.lastKnownHash = hash;
|
||||
}
|
||||
console.log(hash + ' is not new');
|
||||
}
|
||||
};
|
||||
cfg.onReady = function () {
|
||||
onReady();
|
||||
};
|
||||
CpNetflux.start(cfg);
|
||||
};
|
||||
|
||||
// Send a message to someone else
|
||||
var sendTo = function () {
|
||||
|
||||
};
|
||||
|
||||
// Mark a message as read
|
||||
var dismiss = function (ctx, data, cId, cb) {
|
||||
var type = data.type;
|
||||
var hash = data.hash;
|
||||
var m = Util.find(ctx, ['store', 'proxy', 'mailboxes', type]);
|
||||
if (!m) { return void cb({error: 'NOT_FOUND'}); }
|
||||
var box = ctx.boxes[type];
|
||||
if (!box) { return void cb({error: 'NOT_LOADED'}); }
|
||||
|
||||
// If the hash in in our history, get the index from the history:
|
||||
// - if the index is 0, we can change our lastKnownHash
|
||||
// - otherwise, just push to view
|
||||
var idx;
|
||||
if (box.history.some(function (el, i) {
|
||||
if (hash === el.hash) {
|
||||
idx = i;
|
||||
return true;
|
||||
}
|
||||
})) {
|
||||
if (idx === 0) {
|
||||
m.lastKnownHash = hash;
|
||||
} else if (m.viewed.indexOf(hash) === -1) {
|
||||
m.viewed.push(hash);
|
||||
}
|
||||
}
|
||||
|
||||
// Check the "viewed" array to see if we're able to bump lastKnownhash more
|
||||
var sliceIdx;
|
||||
box.history.some(function (el, i) {
|
||||
var isViewed = m.viewed.indexOf(el.hash);
|
||||
if (isViewed !== -1) {
|
||||
sliceIdx = i + 1;
|
||||
m.viewed.splice(isViewed, 1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (sliceIdx) {
|
||||
box.history = box.history.slice(sliceIdx);
|
||||
}
|
||||
|
||||
Realtime.whenRealtimeSyncs(ctx.store.realtime, function () {
|
||||
cb();
|
||||
});
|
||||
};
|
||||
|
||||
var subscribe = function (ctx, data, cId, cb) {
|
||||
// Get existing notifications
|
||||
Object.keys(ctx.boxes).forEach(function (type) {
|
||||
ctx.boxes[type].history.forEach(function (obj) {
|
||||
showMessage(ctx, type, obj, cId);
|
||||
});
|
||||
});
|
||||
// Subscribe to new notifications
|
||||
var idx = ctx.clients.indexOf(cId);
|
||||
if (idx === -1) {
|
||||
ctx.clients.push(cId);
|
||||
}
|
||||
cb();
|
||||
};
|
||||
|
||||
var removeClient = function (ctx, cId) {
|
||||
var idx = ctx.clients.indexOf(cId);
|
||||
ctx.clients.splice(idx, 1);
|
||||
};
|
||||
|
||||
Mailbox.init = function (store, waitFor, emit) {
|
||||
var mailbox = {};
|
||||
var ctx = {
|
||||
store: store,
|
||||
emit: emit,
|
||||
clients: [],
|
||||
boxes: {}
|
||||
};
|
||||
|
||||
var mailboxes = store.proxy.mailboxes || {};
|
||||
Object.keys(mailboxes).forEach(function (key) {
|
||||
if (TYPES.indexOf(key) === -1) { return; }
|
||||
var m = mailboxes[key];
|
||||
|
||||
if (BLOCKING_TYPES.indexOf(key) === -1) {
|
||||
openChannel(ctx, key, m, function () {
|
||||
console.log(key + ' mailbox is ready');
|
||||
});
|
||||
} else {
|
||||
openChannel(ctx, key, m, waitFor(function () {
|
||||
console.log(key + ' mailbox is ready');
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
// XXX test function used to populate a mailbox, should be removed in prod
|
||||
mailbox.post = function (box, type, content) {
|
||||
var b = ctx.boxes[box];
|
||||
if (!b) { return; }
|
||||
b.sendMessage({
|
||||
type: type,
|
||||
content: content,
|
||||
sender: store.proxy.curvePublic
|
||||
});
|
||||
};
|
||||
|
||||
mailbox.removeClient = function (clientId) {
|
||||
// TODO
|
||||
//removeClient(ctx, clientId);
|
||||
};
|
||||
mailbox.leavePad = function (padChan) {
|
||||
// TODO
|
||||
//leaveChannel(ctx, padChan);
|
||||
removeClient(ctx, clientId);
|
||||
};
|
||||
mailbox.execCommand = function (clientId, obj, cb) {
|
||||
var cmd = obj.cmd;
|
||||
var data = obj.data;
|
||||
if (cmd === 'SUBSCRIBE') {
|
||||
return void subscribe(ctx, data, clientId, cb);
|
||||
}
|
||||
if (cmd === 'DISMISS') {
|
||||
return void dismiss(ctx, data, clientId, cb);
|
||||
}
|
||||
};
|
||||
|
||||
return mailbox;
|
||||
|
||||
Reference in New Issue
Block a user