mirror of
https://github.com/YunoHost-Apps/jappix_ynh.git
synced 2024-09-03 19:26:19 +02:00
329 lines
No EOL
7.8 KiB
JavaScript
Executable file
329 lines
No EOL
7.8 KiB
JavaScript
Executable file
/*
|
|
|
|
Jappix - An open social platform
|
|
Implementation of XEP-0313: Message Archive Management
|
|
|
|
-------------------------------------------------
|
|
|
|
License: AGPL
|
|
Author: Valérian Saliou
|
|
Last revision: 04/08/13
|
|
|
|
*/
|
|
|
|
|
|
/* -- MAM Constants -- */
|
|
// Note: Internet Explorer does not support 'const'
|
|
// We use vars as a fix...
|
|
var MAM_REQ_MAX = 25;
|
|
|
|
var MAM_PREF_DEFAULTS = {
|
|
'always' : 1,
|
|
'never' : 1,
|
|
'roster' : 1
|
|
};
|
|
|
|
|
|
/* -- MAM Variables -- */
|
|
var MAM_MAP_REQS = {};
|
|
var MAM_MAP_PENDING = {};
|
|
var MAM_MAP_STATES = {};
|
|
var MAM_MSG_QUEUE = {};
|
|
|
|
|
|
/* -- MAM Configuration -- */
|
|
|
|
// Gets the MAM configuration
|
|
function getConfigMAM() {
|
|
try {
|
|
// Lock the archiving options
|
|
$('#archiving').attr('disabled', true);
|
|
|
|
// Get the archiving configuration
|
|
var iq = new JSJaCIQ();
|
|
iq.setType('get');
|
|
|
|
iq.appendNode('prefs', { 'xmlns': NS_URN_MAM });
|
|
|
|
con.send(iq, handleConfigMAM);
|
|
} catch(e) {
|
|
logThis('getConfigMAM > ' + e, 1);
|
|
}
|
|
}
|
|
|
|
// Handles the MAM configuration
|
|
function handleConfigMAM(iq) {
|
|
try {
|
|
if(iq.getType() != 'error') {
|
|
// Read packet
|
|
var cur_default = $(iq.getNode()).find('prefs[xmlns="' + NS_URN_MAM + '"]').attr('default') || 'never';
|
|
|
|
if(!(cur_default in MAM_PREF_DEFAULTS)) {
|
|
cur_default = 'never';
|
|
}
|
|
|
|
// Apply value to options
|
|
$('#archiving').val(cur_default);
|
|
}
|
|
|
|
// Unlock the archiving option
|
|
$('#archiving').removeAttr('disabled');
|
|
|
|
// All done.
|
|
waitOptions('mam');
|
|
} catch(e) {
|
|
logThis('handleConfigMAM > ' + e, 1);
|
|
}
|
|
}
|
|
|
|
// Sets the MAM configuration
|
|
function setConfigMAM(pref_default) {
|
|
try {
|
|
// Check parameters
|
|
if(!(pref_default in MAM_PREF_DEFAULTS)) {
|
|
pref_default = 'never';
|
|
}
|
|
|
|
// Send new configuration
|
|
var iq = new JSJaCIQ();
|
|
iq.setType('set');
|
|
|
|
iq.appendNode('prefs', { 'xmlns': NS_URN_MAM, 'default': pref_default });
|
|
|
|
con.send(iq);
|
|
} catch(e) {
|
|
logThis('setConfigMAM > ' + e, 1);
|
|
}
|
|
}
|
|
|
|
|
|
/* -- MAM Purge -- */
|
|
|
|
// Removes all (or given) MAM archives
|
|
function purgeArchivesMAM(args) {
|
|
try {
|
|
if(typeof args != 'object') {
|
|
args = {};
|
|
}
|
|
|
|
var iq = new JSJaCIQ();
|
|
iq.setType('set');
|
|
|
|
var purge = iq.appendNode('purge', { 'xmlns': NS_URN_MAM });
|
|
|
|
for(c in args) {
|
|
if(args[c]) purge.appendChild(iq.buildNode(c, {'xmlns': NS_URN_MAM}, args[c]));
|
|
}
|
|
|
|
con.send(iq, function(iq) {
|
|
if(iq.getType() == 'result') {
|
|
logThis('Archives purged (MAM).', 3);
|
|
} else {
|
|
logThis('Error purging archives (MAM).', 1);
|
|
}
|
|
});
|
|
} catch(e) {
|
|
logThis('purgeArchivesMAM > ' + e, 1);
|
|
}
|
|
}
|
|
|
|
|
|
/* -- MAM Retrieval -- */
|
|
|
|
// Gets the MAM configuration
|
|
function getArchivesMAM(args, rsm_args, callback) {
|
|
try {
|
|
if(typeof args != 'object') {
|
|
args = {};
|
|
}
|
|
|
|
var req_id = genID();
|
|
|
|
if(args['with']) {
|
|
MAM_MAP_PENDING[args['with']] = 1;
|
|
MAM_MAP_REQS[req_id] = args['with'];
|
|
}
|
|
|
|
var iq = new JSJaCIQ();
|
|
iq.setType('get');
|
|
iq.setID(req_id);
|
|
|
|
var query = iq.setQuery(NS_URN_MAM);
|
|
|
|
for(c in args) {
|
|
if(args[c] != null) query.appendChild(iq.buildNode(c, {'xmlns': NS_URN_MAM}, args[c]));
|
|
}
|
|
|
|
if(rsm_args && typeof rsm_args == 'object') {
|
|
var rsm_set = query.appendChild(iq.buildNode('set', {'xmlns': NS_RSM}));
|
|
|
|
for(r in rsm_args) {
|
|
if(rsm_args[r] != null) rsm_set.appendChild(iq.buildNode(r, {'xmlns': NS_RSM}, rsm_args[r]));
|
|
}
|
|
}
|
|
|
|
con.send(iq, function(res_iq) {
|
|
handleArchivesMAM(res_iq, callback);
|
|
});
|
|
} catch(e) {
|
|
logThis('getArchivesMAM > ' + e, 1);
|
|
}
|
|
}
|
|
|
|
// Handles the MAM configuration
|
|
function handleArchivesMAM(iq, callback) {
|
|
try {
|
|
var res_id = iq.getID();
|
|
var res_with;
|
|
|
|
if(res_id && res_id in MAM_MAP_REQS) {
|
|
res_with = MAM_MAP_REQS[res_id];
|
|
}
|
|
|
|
if(iq.getType() != 'error') {
|
|
if(res_with) {
|
|
var res_sel = $(iq.getQuery());
|
|
var res_rsm_sel = res_sel.find('set[xmlns="' + NS_RSM + '"]');
|
|
|
|
// Store that data
|
|
MAM_MAP_STATES[res_with] = {
|
|
'date': {
|
|
'start': res_sel.find('start').eq(0).text(),
|
|
'end': res_sel.find('end').eq(0).text()
|
|
},
|
|
|
|
'rsm': {
|
|
'first': res_rsm_sel.find('first').eq(0).text(),
|
|
'last': res_rsm_sel.find('last').eq(0).text(),
|
|
'count': parseInt(res_rsm_sel.find('count').eq(0).text() || 0)
|
|
}
|
|
}
|
|
|
|
// Generate stamps for easy operations
|
|
var start_stamp = extractStamp(Date.jab2date(MAM_MAP_STATES[res_with]['date']['start']));
|
|
var start_end = extractStamp(Date.jab2date(MAM_MAP_STATES[res_with]['date']['end']));
|
|
|
|
// Create MAM messages target
|
|
var target_html = '<div class="mam-chunk" data-start="' + encodeQuotes(start_stamp) + '" data-end="' + encodeQuotes(start_end) + '"></div>';
|
|
|
|
var target_content_sel = $('#' + hex_md5(res_with) + ' .content');
|
|
var target_wait_sel = target_content_sel.find('.wait-mam');
|
|
|
|
if(target_wait_sel.size()) {
|
|
target_wait_sel.after(target_html);
|
|
} else {
|
|
target_content_sel.prepend(target_html);
|
|
}
|
|
|
|
// Any enqueued message to display?
|
|
if(typeof MAM_MSG_QUEUE[res_with] == 'object') {
|
|
for(i in MAM_MSG_QUEUE[res_with]) {
|
|
(MAM_MSG_QUEUE[res_with][i])();
|
|
}
|
|
|
|
delete MAM_MSG_QUEUE[res_with];
|
|
}
|
|
|
|
// Remove XID from pending list
|
|
if(res_with in MAM_MAP_PENDING) {
|
|
delete MAM_MAP_PENDING[res_with];
|
|
}
|
|
|
|
logThis('Got archives from: ' + res_with, 3);
|
|
} else {
|
|
logThis('Could not associate archive response with a known JID.', 2);
|
|
}
|
|
} else {
|
|
logThis('Error handing archives (MAM).', 1);
|
|
}
|
|
|
|
// Execute callback?
|
|
if(typeof callback == 'function') {
|
|
callback(iq);
|
|
}
|
|
} catch(e) {
|
|
logThis('handleArchivesMAM > ' + e, 1);
|
|
}
|
|
}
|
|
|
|
// Handles a MAM-forwarded message stanza
|
|
function handleMessageMAM(fwd_stanza, c_delay) {
|
|
try {
|
|
// Build message node
|
|
var c_message = fwd_stanza.find('message');
|
|
|
|
if(c_message[0]) {
|
|
// Re-build a proper JSJaC message stanza
|
|
var message = JSJaCPacket.wrapNode(c_message[0]);
|
|
|
|
// Check message type
|
|
var type = message.getType() || 'chat';
|
|
|
|
if(type == 'chat') {
|
|
// Read message data
|
|
var xid = bareXID(getStanzaFrom(message));
|
|
var id = message.getID();
|
|
var from_xid = xid;
|
|
var b_name = getBuddyName(xid);
|
|
var mode = (xid == getXID()) ? 'me': 'him';
|
|
|
|
// Refactor chat XID (in case we were the sender of the archived message)
|
|
if(mode == 'me') {
|
|
xid = bareXID(message.getTo())
|
|
}
|
|
|
|
var hash = hex_md5(xid);
|
|
var body = message.getBody();
|
|
|
|
// Read delay (required since we deal w/ a past message!)
|
|
var time, stamp;
|
|
var delay = c_delay.attr('stamp');
|
|
|
|
if(delay) {
|
|
time = relativeDate(delay);
|
|
stamp = extractStamp(Date.jab2date(delay));
|
|
}
|
|
|
|
// Last-minute checks before display
|
|
if(time && stamp && body) {
|
|
var mam_chunk_path = '#' + hash + ' .mam-chunk';
|
|
|
|
// No chat auto-scroll?
|
|
var no_scroll = exists(mam_chunk_path);
|
|
|
|
// Select the custom target
|
|
var c_target_sel = function() {
|
|
return $(mam_chunk_path).filter(function() {
|
|
return $(this).attr('data-start') <= stamp && $(this).attr('data-end') >= stamp
|
|
}).filter(':first');
|
|
};
|
|
|
|
// Display the message in that target
|
|
var c_msg_display = function() {
|
|
displayMessage(type, from_xid, hash, b_name.htmlEnc(), body, time, stamp, 'old-message', true, null, mode, null, c_target_sel(), no_scroll);
|
|
};
|
|
|
|
// Hack: do not display the message in case we would duplicate it w/ current session messages
|
|
// only used when initiating a new chat, avoids collisions
|
|
if(!(xid in MAM_MAP_STATES) && $('#' + hash).find('.one-line.user-message:last').text() == body) {
|
|
return;
|
|
}
|
|
|
|
if(c_target_sel().size()) {
|
|
// Display the message in that target
|
|
c_msg_display();
|
|
} else {
|
|
// Delay display (we may not have received the MAM reply ATM)
|
|
if(typeof MAM_MSG_QUEUE[xid] != 'object') {
|
|
MAM_MSG_QUEUE[xid] = [];
|
|
}
|
|
|
|
MAM_MSG_QUEUE[xid].push(c_msg_display);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch(e) {
|
|
logThis('handleMessageMAM > ' + e, 1);
|
|
}
|
|
} |