Comparar commits
18 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 5056c45c5c | |||
| 3c5521d386 | |||
| 1f54406abd | |||
| a580cf49f0 | |||
| 33098bc4d5 | |||
| ab2d866ff9 | |||
| 3b7c7ffbed | |||
| 5b0f842c72 | |||
| d5bb8225cc | |||
| 6db4ce1242 | |||
| 0e197e22b3 | |||
| 13b018b053 | |||
| 181d586730 | |||
| 9a9cbfff5a | |||
| 32514ea25d | |||
| 1e074075e3 | |||
| f89a856b7e | |||
| 411baae280 |
@@ -1,3 +1,22 @@
|
||||
v0.6.0 / 2014-01-28
|
||||
===
|
||||
- add notice stack (for e.g. friendship requests)
|
||||
- add option to change presence
|
||||
- support all available presence states
|
||||
- display own avatar
|
||||
- fix issue with prosody
|
||||
- fix multi-tab support
|
||||
- fix chrome notifications
|
||||
- fix otr error handling
|
||||
- fix webrtc bug
|
||||
|
||||
v0.5.2 / 2014-01-28
|
||||
===
|
||||
- update strophe.js to v1.1.3
|
||||
- fix debug function (fix initial presence)
|
||||
- add debug log window
|
||||
- add warn|error debug functions
|
||||
|
||||
v0.5.1 / 2014-01-27
|
||||
===
|
||||
- fix chat window after call
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jsxc",
|
||||
"version": "0.5.1",
|
||||
"version": "0.6.0",
|
||||
"description": "Real-time chat app",
|
||||
"homepage": "http://jsxc.org/",
|
||||
"license": "MIT",
|
||||
|
||||
+403
-113
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* jsxc v0.5.1 - 2014-01-27
|
||||
* jsxc v0.6.0 - 2014-02-28
|
||||
*
|
||||
* Copyright (c) 2014 Klaus Herberth <klaus@jsxc.org> <br>
|
||||
* Released under the MIT license
|
||||
@@ -7,7 +7,7 @@
|
||||
* Please see http://jsxc.org/
|
||||
*
|
||||
* @author Klaus Herberth <klaus@jsxc.org>
|
||||
* @version 0.5.1
|
||||
* @version 0.6.0
|
||||
*/
|
||||
|
||||
var jsxc;
|
||||
@@ -22,7 +22,7 @@ var jsxc;
|
||||
*/
|
||||
jsxc = {
|
||||
/** Version of jsxc */
|
||||
version: '0.5.1',
|
||||
version: '0.6.0',
|
||||
|
||||
/** True if i'm the chief */
|
||||
chief: false,
|
||||
@@ -81,17 +81,61 @@ var jsxc;
|
||||
/** My css id */
|
||||
cid: null,
|
||||
|
||||
/** Shortcut for jsxc.options.debug */
|
||||
debug: null,
|
||||
|
||||
/** Some constants */
|
||||
CONST: {
|
||||
NOTIFICATION_DEFAULT: 'default',
|
||||
NOTIFICATION_GRANTED: 'granted',
|
||||
NOTIFICATION_DENIED: 'denied',
|
||||
STATUS: [ 'offline', 'away', 'online' ]
|
||||
STATUS: [ 'offline', 'dnd', 'xa', 'away', 'chat', 'online' ]
|
||||
},
|
||||
|
||||
/**
|
||||
* Write debug message to console and to log.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {String} msg Debug message
|
||||
* @param {Object} data
|
||||
* @param {String} Could be warn|error|null
|
||||
*/
|
||||
debug: function(msg, data, level) {
|
||||
if (level) {
|
||||
msg = '[' + level + '] ' + msg;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
console.log(msg, data);
|
||||
jsxc.log = jsxc.log + msg + ': ' + $("<span>").prepend($(data).clone()).html() + '\n';
|
||||
} else {
|
||||
console.log(msg);
|
||||
jsxc.log = jsxc.log + msg + '\n';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Write warn message.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {String} msg Warn message
|
||||
* @param {Object} data
|
||||
*/
|
||||
warn: function(msg, data) {
|
||||
jsxc.debug(msg, data, 'WARN');
|
||||
},
|
||||
|
||||
/**
|
||||
* Write error message.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {String} msg Error message
|
||||
* @param {Object} data
|
||||
*/
|
||||
error: function(msg, data) {
|
||||
jsxc.debug(msg, data, 'ERROR');
|
||||
},
|
||||
|
||||
/** debug log */
|
||||
log: '',
|
||||
|
||||
/**
|
||||
* Starts the action
|
||||
*
|
||||
@@ -114,9 +158,6 @@ var jsxc;
|
||||
jsxc.storage.updateUserItem('options', key, value);
|
||||
};
|
||||
|
||||
// Shortcut
|
||||
jsxc.debug = jsxc.options.debug;
|
||||
|
||||
jsxc.storageNotConform = jsxc.storage.getItem('storageNotConform') || 2;
|
||||
|
||||
// detect language
|
||||
@@ -174,7 +215,9 @@ var jsxc;
|
||||
|
||||
// create jquery object
|
||||
var form = jsxc.options.loginForm.form = $(jsxc.options.loginForm.form);
|
||||
var events = form.data('events') || {submit: []};
|
||||
var events = form.data('events') || {
|
||||
submit: []
|
||||
};
|
||||
var submits = [];
|
||||
|
||||
// save attached submit events and remove them. Will be reattached
|
||||
@@ -182,7 +225,7 @@ var jsxc;
|
||||
$.each(events.submit, function(index, val) {
|
||||
submits.push(val.handler);
|
||||
});
|
||||
|
||||
|
||||
form.data('submits', submits);
|
||||
form.off('submit');
|
||||
|
||||
@@ -314,8 +357,8 @@ var jsxc;
|
||||
* Checks if there is a chief
|
||||
*/
|
||||
checkChief: function() {
|
||||
jsxc.debug('checkChief');
|
||||
jsxc.to = window.setTimeout(jsxc.onChief, 500);
|
||||
jsxc.debug('check chief');
|
||||
jsxc.to = window.setTimeout(jsxc.onChief, jsxc.options.timeout);
|
||||
jsxc.storage.ink('alive');
|
||||
},
|
||||
|
||||
@@ -388,21 +431,6 @@ var jsxc;
|
||||
return cid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Send message to buddy and display this to the user
|
||||
*
|
||||
* @param {String} cid
|
||||
* @param {String} msg message to be send
|
||||
*/
|
||||
sendMessage: function(cid, msg) {
|
||||
|
||||
if (jsxc.chief) {
|
||||
jsxc.buddyList[cid].sendMsg(msg);
|
||||
}
|
||||
|
||||
jsxc.gui.window.postMessage(cid, 'out', msg);
|
||||
},
|
||||
|
||||
/**
|
||||
* Restore roster
|
||||
*/
|
||||
@@ -455,12 +483,12 @@ var jsxc;
|
||||
submitLoginForm: function() {
|
||||
var form = jsxc.options.loginForm.form.off('submit');
|
||||
|
||||
//Attach original events
|
||||
// Attach original events
|
||||
var submits = form.data('submits') || [];
|
||||
$.each(submits, function(index, val) {
|
||||
form.submit(val);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
if (form.find('#submit')) {
|
||||
form.find('#submit').click();
|
||||
} else {
|
||||
@@ -526,7 +554,7 @@ var jsxc;
|
||||
var k = key.replace(/ /gi, '_');
|
||||
|
||||
if (!jsxc.l[k]) {
|
||||
jsxc.debug('[WARN] No translation for: ' + k);
|
||||
jsxc.warn('No translation for: ' + k);
|
||||
}
|
||||
|
||||
return jsxc.l[k] || key.replace(/_/gi, ' ');
|
||||
@@ -672,6 +700,7 @@ var jsxc;
|
||||
var ri = $('#' + cid); // roster item from user
|
||||
var we = jsxc.gui.getWindow(cid); // window element from user
|
||||
var ue = $('#' + cid + ', #jsxc_window_' + cid + ', .jsxc_buddy_' + cid); // both
|
||||
var bullet = $('.jsxc_buddy_' + cid);
|
||||
|
||||
// Attach data to corresponding roster item
|
||||
ri.data(data);
|
||||
@@ -681,6 +710,7 @@ var jsxc;
|
||||
|
||||
// Change name and add title
|
||||
ue.find('.jsxc_name').text(data.name).attr('title', 'is ' + jsxc.CONST.STATUS[data.status]);
|
||||
bullet.attr('title', 'is ' + jsxc.CONST.STATUS[data.status]);
|
||||
|
||||
// Update gui according to encryption state
|
||||
switch (data.msgstate) {
|
||||
@@ -716,31 +746,46 @@ var jsxc;
|
||||
}
|
||||
|
||||
if (data.avatar && data.avatar.length > 0) {
|
||||
var avatarSrc = jsxc.storage.getUserItem('avatar_' + data.avatar);
|
||||
jsxc.gui.updateAvatar(ue, data.jid, data.avatar);
|
||||
}
|
||||
},
|
||||
|
||||
updateAvatar: function(el, jid, aid) {
|
||||
var avatarSrc = jsxc.storage.getUserItem('avatar_' + aid);
|
||||
|
||||
var setAvatar = function(src) {
|
||||
ue.find('.jsxc_avatar img').remove();
|
||||
var img = $('<img/>').attr('alt', 'Avatar').attr('src', src);
|
||||
ue.find('.jsxc_avatar').prepend(img);
|
||||
};
|
||||
var setAvatar = function(src) {
|
||||
if(src === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
el.find('.jsxc_avatar img').remove();
|
||||
var img = $('<img/>').attr('alt', 'Avatar').attr('src', src);
|
||||
el.find('.jsxc_avatar').prepend(img);
|
||||
};
|
||||
|
||||
if (avatarSrc !== null) {
|
||||
setAvatar(avatarSrc);
|
||||
} else {
|
||||
jsxc.xmpp.conn.vcard.get(function(stanza) {
|
||||
jsxc.debug('vCard', stanza);
|
||||
if (avatarSrc !== null) {
|
||||
setAvatar(avatarSrc);
|
||||
} else {
|
||||
jsxc.xmpp.conn.vcard.get(function(stanza) {
|
||||
jsxc.debug('vCard', stanza);
|
||||
|
||||
var vCard = $(stanza).find("vCard");
|
||||
var vCard = $(stanza).find("vCard > PHOTO");
|
||||
var src;
|
||||
|
||||
if(vCard.length === 0){
|
||||
jsxc.debug('No photo provided');
|
||||
src = 0;
|
||||
} else {
|
||||
var img = vCard.find('BINVAL').text();
|
||||
var type = vCard.find('TYPE').text();
|
||||
var src = 'data:' + type + ';base64,' + img;
|
||||
|
||||
jsxc.storage.setUserItem('avatar_' + data.avatar, src);
|
||||
setAvatar(src);
|
||||
}, Strophe.getBareJidFromJid(data.jid), function(msg) {
|
||||
jsxc.debug('Error', msg);
|
||||
});
|
||||
}
|
||||
src = 'data:' + type + ';base64,' + img;
|
||||
}
|
||||
|
||||
jsxc.storage.setUserItem('avatar_' + aid, src);
|
||||
setAvatar(src);
|
||||
}, Strophe.getBareJidFromJid(jid), function(msg) {
|
||||
jsxc.error('Could not load vcard.', msg);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -760,15 +805,33 @@ var jsxc;
|
||||
* @memberof jsxc.gui
|
||||
*/
|
||||
toggleList: function() {
|
||||
$(this).disableSelection();
|
||||
|
||||
var ul = $(this).find('ul');
|
||||
var slideUp = null;
|
||||
|
||||
slideUp = function() {
|
||||
ul.slideUp();
|
||||
$('body').off('click', null, slideUp);
|
||||
};
|
||||
|
||||
$(this).click(function() {
|
||||
|
||||
if(ul.is(":hidden")){
|
||||
// hide other lists
|
||||
$('body').click();
|
||||
$('body').one('click', slideUp);
|
||||
} else {
|
||||
$('body').off('click', null, slideUp);
|
||||
}
|
||||
|
||||
ul.slideToggle();
|
||||
|
||||
window.clearTimeout(ul.data('timer'));
|
||||
|
||||
return false;
|
||||
}).mouseleave(function() {
|
||||
ul.data('timer', window.setTimeout(function() {
|
||||
ul.slideUp();
|
||||
}, 2000));
|
||||
ul.data('timer', window.setTimeout(slideUp, 2000));
|
||||
}).mouseenter(function() {
|
||||
window.clearTimeout(ul.data('timer'));
|
||||
});
|
||||
@@ -820,9 +883,17 @@ var jsxc;
|
||||
*/
|
||||
showVerification: function(cid) {
|
||||
|
||||
// Check if there is a open dialog
|
||||
if($('#jsxc_dialog').length > 0) {
|
||||
setTimeout(function(){
|
||||
jsxc.gui.showVerification(cid);
|
||||
}, 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
// verification only possible if the connection is encrypted
|
||||
if (jsxc.storage.getUserItem('buddy_' + cid).msgstate !== OTR.CONST.MSGSTATE_ENCRYPTED) {
|
||||
jsxc.debug('Connection not encrypted');
|
||||
jsxc.warn('Connection not encrypted');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1083,6 +1154,71 @@ var jsxc;
|
||||
*/
|
||||
showAboutDialog: function() {
|
||||
jsxc.gui.dialog.open(jsxc.gui.template.get('aboutDialog'));
|
||||
|
||||
$('#jsxc_dialog .jsxc_debuglog').click(function() {
|
||||
jsxc.gui.showDebugLog();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Show debug log.
|
||||
*
|
||||
* @memberOf jsxc.gui
|
||||
*/
|
||||
showDebugLog: function() {
|
||||
var userInfo = '<h3>User information</h3>';
|
||||
|
||||
if (navigator) {
|
||||
var key;
|
||||
for (key in navigator) {
|
||||
if (navigator.hasOwnProperty(key) && typeof navigator[key] === 'string') {
|
||||
userInfo += '<b>' + key + ':</b> ' + navigator[key] + '<br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (window.screen) {
|
||||
userInfo += '<b>Height:</b> ' + window.screen.height + '<br />';
|
||||
userInfo += '<b>Width:</b> ' + window.screen.width + '<br />';
|
||||
}
|
||||
|
||||
userInfo += '<b>jsxc version:</b> ' + jsxc.version + '<br />';
|
||||
|
||||
jsxc.gui.dialog.open('<div class="jsxc_log">' + userInfo + '<h3>Log</h3><pre>' + jsxc.escapeHTML(jsxc.log) + '</pre></div>');
|
||||
},
|
||||
|
||||
/**
|
||||
* Change presence to pres.
|
||||
*
|
||||
* @memberOf jsxc.gui
|
||||
* @param pres {CONST.STATUS} New presence state
|
||||
* @param external {boolean} True if triggered from other tab.
|
||||
*/
|
||||
changePresence: function(pres, external){
|
||||
|
||||
if(external !== true){
|
||||
jsxc.storage.setUserItem('presence', pres);
|
||||
}
|
||||
|
||||
if(jsxc.chief){
|
||||
jsxc.xmpp.sendPres();
|
||||
}
|
||||
|
||||
$('#jsxc_presence > span').text($('#jsxc_presence > ul .jsxc_' + pres).text());
|
||||
|
||||
jsxc.gui.updatePresence('own', pres);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update all presence objects for given user.
|
||||
*
|
||||
* @memberOf jsxc.gui
|
||||
* @param cid CSS id of user.
|
||||
* @param {CONST.STATUS} pres New presence state.
|
||||
*/
|
||||
updatePresence: function(cid, pres) {
|
||||
|
||||
$('.jsxc_presence_' + cid).removeClass('jsxc_' + jsxc.CONST.STATUS.join(' jsxc_')).addClass('jsxc_' + pres);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1132,6 +1268,12 @@ var jsxc;
|
||||
$('#jsxc_toggleRoster').click(function() {
|
||||
jsxc.gui.roster.toggle();
|
||||
});
|
||||
|
||||
$('#jsxc_presence > ul > li').click(function(){
|
||||
var self = $(this);
|
||||
|
||||
jsxc.gui.changePresence(self.data('pres'));
|
||||
});
|
||||
|
||||
$('#jsxc_buddylist').slimScroll({
|
||||
distance: '3px',
|
||||
@@ -1141,12 +1283,20 @@ var jsxc;
|
||||
opacity: '0.5'
|
||||
});
|
||||
|
||||
jsxc.gui.toggleList.call($('#jsxc_menu'));
|
||||
$('#jsxc_roster > .jsxc_bottom > div').each(function() {
|
||||
jsxc.gui.toggleList.call($(this));
|
||||
});
|
||||
|
||||
if (jsxc.storage.getUserItem('roster') === 'hidden') {
|
||||
$('#jsxc_roster').css('right', '-200px');
|
||||
$('#jsxc_windowList > ul').css('paddingRight', '10px');
|
||||
}
|
||||
|
||||
var pres = jsxc.storage.getUserItem('presence') || 'online';
|
||||
$('#jsxc_presence > span').text($('#jsxc_presence > ul .jsxc_' + pres).text());
|
||||
jsxc.gui.updatePresence('own', pres);
|
||||
|
||||
jsxc.notice.load();
|
||||
|
||||
$(document).trigger('ready.roster.jsxc');
|
||||
},
|
||||
@@ -1156,7 +1306,7 @@ var jsxc;
|
||||
*
|
||||
* @param {String} cid CSS compatible jid
|
||||
*/
|
||||
add: function(cid) {
|
||||
add: function(cid) {
|
||||
var data = jsxc.storage.getUserItem('buddy_' + cid);
|
||||
var bud = jsxc.gui.buddyTemplate.clone().attr('id', cid).attr('data-type', data.type || 'chat');
|
||||
|
||||
@@ -1505,8 +1655,8 @@ var jsxc;
|
||||
if (ev.which !== 13 || !$(this).val()) {
|
||||
return;
|
||||
}
|
||||
|
||||
jsxc.sendMessage(cid, $(this).val());
|
||||
|
||||
jsxc.gui.window.postMessage(cid, 'out', $(this).val());
|
||||
|
||||
$(this).val('');
|
||||
});
|
||||
@@ -1577,9 +1727,9 @@ var jsxc;
|
||||
* @param {String} cid CSS compatible jid
|
||||
*/
|
||||
close: function(cid) {
|
||||
|
||||
|
||||
if (!jsxc.el_exists('#jsxc_window_' + cid)) {
|
||||
jsxc.debug('[Warning] Want to close a window, that is not open.');
|
||||
jsxc.warn('Want to close a window, that is not open.');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1653,7 +1803,7 @@ var jsxc;
|
||||
*
|
||||
* @param {String} cid
|
||||
*/
|
||||
hide: function(cid) {
|
||||
hide: function(cid) {
|
||||
jsxc.storage.updateUserItem('window_' + cid, 'minimize', true);
|
||||
|
||||
jsxc.gui.window._hide(cid);
|
||||
@@ -1664,7 +1814,7 @@ var jsxc;
|
||||
*
|
||||
* @param {String} cid
|
||||
*/
|
||||
_hide: function(cid) {
|
||||
_hide: function(cid) {
|
||||
$('#jsxc_window_' + cid + ' .jsxc_window').slideUp();
|
||||
jsxc.gui.getWindow(cid).trigger('hidden.window.jsxc');
|
||||
},
|
||||
@@ -1744,6 +1894,10 @@ var jsxc;
|
||||
if (direction === 'in') {
|
||||
$(document).trigger('postmessagein.jsxc', [ jsxc.jids[cid], html_msg ]);
|
||||
}
|
||||
|
||||
if (direction === 'out' && jsxc.chief) {
|
||||
jsxc.buddyList[cid].sendMsg(msg);
|
||||
}
|
||||
|
||||
jsxc.gui.window._postMessage(cid, direction, msg);
|
||||
},
|
||||
@@ -1857,7 +2011,7 @@ var jsxc;
|
||||
|
||||
$.extend(ph, {
|
||||
cid_priv_fingerprint: data.fingerprint ? data.fingerprint.replace(/(.{8})/g, '$1 ') : jsxc.l.no_available,
|
||||
cid_jid: data.jid,
|
||||
cid_jid: Strophe.getBareJidFromJid(data.jid),
|
||||
cid_name: data.name
|
||||
});
|
||||
}
|
||||
@@ -1884,8 +2038,7 @@ var jsxc;
|
||||
jsxc.debug('Template not available: ' + name);
|
||||
return name;
|
||||
},
|
||||
authenticationDialog: '<div id="jsxc_facebox">\
|
||||
<h3>Verification</h3>\
|
||||
authenticationDialog: '<h3>Verification</h3>\
|
||||
<p>%%Authenticating_a_buddy_helps_%%</p>\
|
||||
<div>\
|
||||
<p style="margin:0px;">%%How_do_you_want_to_authenticate_your_buddy%%</p>\
|
||||
@@ -1914,8 +2067,7 @@ var jsxc;
|
||||
<p class=".jsxc_explanation">%%To_authenticate_pick_a_secret_%%</p>\
|
||||
<p><label for="jsxc_secret">%%Secret%%:</label><input type="text" name="secret" id="jsxc_secret" /></p>\
|
||||
<p class="jsxc_right"><a href="#" class="button jsxc_close">%%Close%%</a> <a href="#" class="button creation">%%Compare%%</a></p>\
|
||||
</div>\
|
||||
</div>',
|
||||
</div>',
|
||||
fingerprintsDialog: '<div>\
|
||||
<p><strong>%%Your_fingerprint%%</strong><br />\
|
||||
<span style="text-transform:uppercase">{{my_priv_fingerprint}}</span></p>\
|
||||
@@ -1947,17 +2099,37 @@ var jsxc;
|
||||
</div>\
|
||||
</li>',
|
||||
roster: '<div id="jsxc_roster">\
|
||||
<ul id="jsxc_buddylist"></ul>\
|
||||
<div id="jsxc_menu">\
|
||||
%%Menu%%\
|
||||
<ul>\
|
||||
<li class="jsxc_addBuddy">%%Add_buddy%%</li>\
|
||||
<li class="jsxc_hideOffline">%%Hide offline%%</li>\
|
||||
<li class="jsxc_about">%%About%%</li>\
|
||||
</ul>\
|
||||
</div>\
|
||||
<div id="jsxc_toggleRoster"></div>\
|
||||
</div>',
|
||||
<ul id="jsxc_buddylist"></ul>\
|
||||
<div class="jsxc_bottom jsxc_presence_own">\
|
||||
<div id="jsxc_avatar">\
|
||||
<div class="jsxc_avatar">☺</div>\
|
||||
</div>\
|
||||
<div id="jsxc_menu">\
|
||||
<span>⚙</span>\
|
||||
<ul>\
|
||||
<li class="jsxc_addBuddy">%%Add_buddy%%</li>\
|
||||
<li class="jsxc_hideOffline">%%Hide offline%%</li>\
|
||||
<li class="jsxc_about">%%About%%</li>\
|
||||
</ul>\
|
||||
</div>\
|
||||
<div id="jsxc_notice">\
|
||||
<span></span>\
|
||||
<ul></ul>\
|
||||
</div>\
|
||||
<div id="jsxc_presence">\
|
||||
<span>%%Online%%</span>\
|
||||
<ul>\
|
||||
<li data-pres="online" class="jsxc_online">%%Online%%</li>\
|
||||
<li data-pres="chat" class="jsxc_chat">%%Chatty%%</li>\
|
||||
<li data-pres="away" class="jsxc_away">%%Away%%</li>\
|
||||
<li data-pres="xa" class="jsxc_xa">%%Extended away%%</li>\
|
||||
<li data-pres="dnd" class="jsxc_dnd">%%dnd%%</li>\
|
||||
<!-- <li data-pres="offline" class="jsxc_offline">%%Offline%%</li> -->\
|
||||
</ul>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div id="jsxc_toggleRoster"></div>\
|
||||
</div>',
|
||||
windowList: '<div id="jsxc_windowList">\
|
||||
<ul></ul>\
|
||||
</div>',
|
||||
@@ -2019,7 +2191,8 @@ var jsxc;
|
||||
<br />\
|
||||
Real-time chat app for OwnCloud. This app requires external<br /> XMPP server (openfire, ejabberd etc.).<br />\
|
||||
<br />\
|
||||
<i>Released under the MIT license</i></p>'
|
||||
<i>Released under the MIT license</i></p>\
|
||||
<p class="jsxc_right"><a class="button jsxc_debuglog" href="#">Show debug log</a></p>'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2052,14 +2225,14 @@ var jsxc;
|
||||
jsxc.xmpp.conn = new Strophe.Connection(url);
|
||||
|
||||
// jsxc.xmpp.conn.xmlInput = function(data) {
|
||||
// jsxc.debug('<', data);
|
||||
// console.log('<', data);
|
||||
// };
|
||||
// jsxc.xmpp.conn.xmlOutput = function(data) {
|
||||
// jsxc.debug('>', data);
|
||||
// console.log('>', data);
|
||||
// };
|
||||
//
|
||||
|
||||
// Strophe.log = function (level, msg) {
|
||||
// jsxc.debug(level + " " + msg);
|
||||
// console.log(level + " " + msg);
|
||||
// };
|
||||
|
||||
var callback = function(status, condition) {
|
||||
@@ -2071,7 +2244,7 @@ var jsxc;
|
||||
jsxc.cid = jsxc.jidToCid(jsxc.xmpp.conn.jid.toLowerCase());
|
||||
$(document).trigger('connected.jsxc');
|
||||
break;
|
||||
case Strophe.Status.ATTACHED:
|
||||
case Strophe.Status.ATTACHED:
|
||||
$(document).trigger('attached.jsxc');
|
||||
break;
|
||||
case Strophe.Status.DISCONNECTED:
|
||||
@@ -2142,7 +2315,7 @@ var jsxc;
|
||||
jsxc.xmpp.conn.pause();
|
||||
|
||||
// Save sid and jid
|
||||
jsxc.storage.setItem('sid', jsxc.xmpp.conn.sid);
|
||||
jsxc.storage.setItem('sid', jsxc.xmpp.conn._proto.sid);
|
||||
jsxc.storage.setItem('jid', jsxc.xmpp.conn.jid.toLowerCase());
|
||||
|
||||
jsxc.storage.setItem('lastActivity', (new Date()).getTime());
|
||||
@@ -2152,6 +2325,7 @@ var jsxc;
|
||||
|
||||
jsxc.storage.removeUserItem('windowlist');
|
||||
jsxc.storage.removeUserItem('own');
|
||||
jsxc.storage.removeUserItem('avatar_own');
|
||||
|
||||
// submit login form
|
||||
if (jsxc.triggeredFromForm) {
|
||||
@@ -2191,11 +2365,13 @@ var jsxc;
|
||||
}).c('query', {
|
||||
xmlns: 'jabber:iq:roster'
|
||||
});
|
||||
|
||||
|
||||
jsxc.xmpp.conn.sendIQ(iq, jsxc.xmpp.onRoster);
|
||||
} else {
|
||||
jsxc.xmpp.sendPres();
|
||||
}
|
||||
|
||||
jsxc.gui.updateAvatar($('#jsxc_avatar'), jsxc.storage.getItem('jid'), 'own');
|
||||
|
||||
jsxc.xmpp.connectionReady();
|
||||
},
|
||||
@@ -2218,14 +2394,25 @@ var jsxc;
|
||||
jsxc.xmpp.conn.disco.addFeature(Strophe.NS.DISCO_INFO);
|
||||
}
|
||||
|
||||
// send presence stanza
|
||||
// create presence stanza
|
||||
var pres = $pres();
|
||||
|
||||
if (jsxc.xmpp.conn.caps) {
|
||||
// attach caps
|
||||
pres.c('c', jsxc.xmpp.conn.caps.generateCapsAttrs());
|
||||
pres.c('c', jsxc.xmpp.conn.caps.generateCapsAttrs()).up();
|
||||
}
|
||||
|
||||
var presState = jsxc.storage.getUserItem('presence') || 'online';
|
||||
if(presState !== 'online'){
|
||||
pres.c('show').t(presState).up();
|
||||
}
|
||||
|
||||
var priority = jsxc.storage.getUserItem('priority');
|
||||
if(priority !== null){
|
||||
pres.c('priority').t(priority[presState]).up();
|
||||
}
|
||||
|
||||
jsxc.debug('Send presence', pres.toString());
|
||||
jsxc.xmpp.conn.send(pres);
|
||||
},
|
||||
|
||||
@@ -2241,6 +2428,7 @@ var jsxc;
|
||||
jsxc.storage.removeItem('rid');
|
||||
jsxc.storage.removeItem('lastActivity');
|
||||
jsxc.storage.removeItem('hidden');
|
||||
jsxc.storage.removeUserItem('avatar_own');
|
||||
|
||||
jsxc.xmpp.conn = null;
|
||||
|
||||
@@ -2325,9 +2513,8 @@ var jsxc;
|
||||
|
||||
jsxc.storage.setUserItem('buddylist', buddies);
|
||||
|
||||
$(document).trigger('rosterready.jsxc');
|
||||
|
||||
jsxc.debug('Roster ready');
|
||||
$(document).trigger('rosterready.jsxc');
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -2407,10 +2594,13 @@ var jsxc;
|
||||
* node='http://psi-im.org/caps' ver='caps-b75d8d2b25' ext='ca cs
|
||||
* ep-notify-2 html'/> </presence>
|
||||
*/
|
||||
jsxc.debug('onPresence', presence);
|
||||
|
||||
var ptype = $(presence).attr('type');
|
||||
var from = $(presence).attr('from');
|
||||
var jid = Strophe.getBareJidFromJid(from).toLowerCase();
|
||||
var to = Strophe.getBareJidFromJid($(presence).attr('to')).toLowerCase();
|
||||
var to = $(presence).attr('to');
|
||||
to = (to)? Strophe.getBareJidFromJid(to).toLowerCase(): jid;
|
||||
var r = Strophe.getResourceFromJid(from);
|
||||
var cid = jsxc.jidToCid(jid);
|
||||
var data = jsxc.storage.getUserItem('buddy_' + cid);
|
||||
@@ -2418,14 +2608,12 @@ var jsxc;
|
||||
var status = null;
|
||||
var xVCard = $(presence).find('x[xmlns="vcard-temp:x:update"]');
|
||||
|
||||
jsxc.debug('onPresence', presence);
|
||||
|
||||
if (jid === to) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ptype === 'error') {
|
||||
jsxc.debug('[XMPP ERROR] ' + $(presence).attr('code'));
|
||||
jsxc.error('[XMPP] ' + $(presence).attr('code'));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2435,17 +2623,17 @@ var jsxc;
|
||||
jid: jid,
|
||||
approve: -1
|
||||
});
|
||||
jsxc.gui.showApproveDialog(jid);
|
||||
jsxc.notice.add('Friendship request', 'from ' + jid, 'gui.showApproveDialog', [jid]);
|
||||
|
||||
return true;
|
||||
} else if (ptype === 'unavailable') {
|
||||
status = 0;
|
||||
status = jsxc.CONST.STATUS.indexOf('offline');
|
||||
} else {
|
||||
var show = $(presence).find('show').text();
|
||||
if (show === '' || show === 'chat') {
|
||||
status = 2;
|
||||
if (show === '') {
|
||||
status = jsxc.CONST.STATUS.indexOf('online');
|
||||
} else {
|
||||
status = 1;
|
||||
status = jsxc.CONST.STATUS.indexOf(show);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2456,7 +2644,7 @@ var jsxc;
|
||||
}
|
||||
|
||||
var maxVal = [];
|
||||
var max = 0, prop;
|
||||
var max = 0, prop = null;
|
||||
for (prop in res) {
|
||||
if (res.hasOwnProperty(prop)) {
|
||||
if (max <= res[prop]) {
|
||||
@@ -2515,7 +2703,7 @@ var jsxc;
|
||||
* <body>...</body> <active
|
||||
* xmlns='http://jabber.org/protocol/chatstates'/> </message>
|
||||
*/
|
||||
|
||||
|
||||
jsxc.debug('Incoming message', message);
|
||||
|
||||
var type = $(message).attr('type');
|
||||
@@ -2683,7 +2871,7 @@ var jsxc;
|
||||
jsxc.storage.setItem('storageNotConform', 0);
|
||||
}, 1000);
|
||||
}
|
||||
jsxc.debug('setItem: ' + key);
|
||||
|
||||
jsxc.ls.push(JSON.stringify({
|
||||
key: key,
|
||||
value: value
|
||||
@@ -2896,6 +3084,14 @@ var jsxc;
|
||||
|
||||
var cid = key.replace(/^[a-z]+_(.*)/i, '$1');
|
||||
|
||||
if (key.match(/^notices/)) {
|
||||
jsxc.notice.load();
|
||||
}
|
||||
|
||||
if (key.match(/^presence/)) {
|
||||
jsxc.gui.changePresence(e.newValue, true);
|
||||
}
|
||||
|
||||
if (key.match(/^hidden/)) {
|
||||
if (jsxc.chief) {
|
||||
clearTimeout(jsxc.toNotification);
|
||||
@@ -3030,6 +3226,8 @@ var jsxc;
|
||||
|
||||
// react if someone ask, if there is a chief
|
||||
if (jsxc.chief && key === 'alive') {
|
||||
jsxc.debug('Master request.');
|
||||
|
||||
jsxc.storage.ink('alive');
|
||||
return;
|
||||
}
|
||||
@@ -3205,8 +3403,7 @@ var jsxc;
|
||||
});
|
||||
|
||||
jsxc.buddyList[cid].on('error', function(err) {
|
||||
jsxc.debug('[OTR] ' + err);
|
||||
jsxc.gui.window.postMessage(cid, 'sys', '[OTR] ' + err);
|
||||
jsxc.error('[OTR] ' + err);
|
||||
});
|
||||
|
||||
jsxc.otr.restore(cid);
|
||||
@@ -3484,12 +3681,12 @@ var jsxc;
|
||||
* @param msg
|
||||
* @param d
|
||||
*/
|
||||
notify: function(title, msg, d) {
|
||||
notify: function(title, msg, d, force) {
|
||||
if (!jsxc.options.notification || !jsxc.notification.hasPermission()) {
|
||||
return; // notifications disabled
|
||||
}
|
||||
|
||||
if (!jsxc.isHidden()) {
|
||||
if (!jsxc.isHidden() && !force) {
|
||||
return; // Tab is visible
|
||||
}
|
||||
|
||||
@@ -3522,6 +3719,10 @@ var jsxc;
|
||||
window.Notification = function(title, opt) {
|
||||
var popup = window.webkitNotifications.createNotification(null, title, opt.body);
|
||||
popup.show();
|
||||
|
||||
popup.close = function() {
|
||||
popup.cancel();
|
||||
};
|
||||
|
||||
return popup;
|
||||
};
|
||||
@@ -3608,10 +3809,97 @@ var jsxc;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This namespace handle the notice system.
|
||||
*
|
||||
* @namspace jsxc.notice
|
||||
* @memberOf jsxc
|
||||
*/
|
||||
jsxc.notice = {
|
||||
/** Number of notices. */
|
||||
_num: 0,
|
||||
|
||||
/**
|
||||
* Loads the saved notices.
|
||||
*
|
||||
* @memberOf jsxc.notice
|
||||
*/
|
||||
load: function() {
|
||||
//reset list
|
||||
$('#jsxc_notice ul li').remove();
|
||||
$('#jsxc_notice > span').text('');
|
||||
jsxc.notice._num = 0;
|
||||
|
||||
var saved = jsxc.storage.getUserItem('notices') || [];
|
||||
var key = null;
|
||||
|
||||
for(key in saved){
|
||||
if(saved.hasOwnProperty(key)){
|
||||
var val = saved[key];
|
||||
|
||||
jsxc.notice.add(val.msg, val.description, val.fnName, val.fnParams, key);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a new notice to the stack;
|
||||
*
|
||||
* @memberOf jsxc.notice
|
||||
* @param msg Header message
|
||||
* @param description Notice description
|
||||
* @param fnName Function name to be called if you open the notice
|
||||
* @param fnParams Array of params for function
|
||||
* @param id Notice id
|
||||
*/
|
||||
add: function(msg, description, fnName, fnParams, id) {
|
||||
var nid = id || Date.now();
|
||||
var list = $('#jsxc_notice ul');
|
||||
var notice = $('<li/>');
|
||||
|
||||
notice.click(function() {
|
||||
$(this).remove();
|
||||
$('#jsxc_notice > span').text(--jsxc.notice._num || '');
|
||||
|
||||
var s = jsxc.storage.getUserItem('notices');
|
||||
delete s[nid];
|
||||
jsxc.storage.setUserItem('notices', s);
|
||||
|
||||
var fn = jsxc[fnName];
|
||||
|
||||
if(typeof fn === 'function'){
|
||||
fn.apply(null, fnParams);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
notice.text(msg);
|
||||
notice.attr('title', description || '');
|
||||
list.append(notice);
|
||||
|
||||
$('#jsxc_notice > span').text(++jsxc.notice._num);
|
||||
|
||||
if (!id) {
|
||||
var saved = jsxc.storage.getUserItem('notices') || {};
|
||||
saved[nid] = {
|
||||
msg: msg,
|
||||
description: description,
|
||||
fnName: fnName,
|
||||
fnParams: fnParams
|
||||
};
|
||||
jsxc.storage.setUserItem('notices', saved);
|
||||
|
||||
jsxc.notification.notify(msg, description || '', null, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains all available translations
|
||||
*
|
||||
* @namespace jsxc.l10n
|
||||
* @memberOf jsxc
|
||||
*/
|
||||
jsxc.l10n = {
|
||||
en: {
|
||||
@@ -3644,7 +3932,7 @@ var jsxc;
|
||||
enter_the_secret: 'enter the secret.',
|
||||
now_we_will_create_your_private_key_: 'Now we will create your private key. This can take some time.',
|
||||
Authenticating_a_buddy_helps_: 'Authenticating a buddy helps ensure that the person you are talking to is who he or she is saying.',
|
||||
How_do_you_want_to_authenticate_your_buddy: 'How do you want to authenticate your buddy?',
|
||||
How_do_you_want_to_authenticate_your_buddy: 'How do you want to authenticate {{cid_name}} (<b>{{cid_jid}}</b>)?',
|
||||
Select_method: 'Select method...',
|
||||
Manual: 'Manual',
|
||||
Question: 'Question',
|
||||
@@ -3686,7 +3974,8 @@ var jsxc;
|
||||
clear_history: 'Clear history',
|
||||
New_message_from: 'New message from',
|
||||
Should_we_notify_you_: 'Should we notify you about new messages in the future?',
|
||||
Please_accept_: 'Please click the "Allow" button at the top.'
|
||||
Please_accept_: 'Please click the "Allow" button at the top.',
|
||||
dnd: 'Do Not Disturb'
|
||||
},
|
||||
de: {
|
||||
please_wait_until_we_logged_you_in: 'Bitte warte bis wir dich eingeloggt haben.',
|
||||
@@ -3718,7 +4007,7 @@ var jsxc;
|
||||
enter_the_secret: 'gib das Geheimnis ein.',
|
||||
now_we_will_create_your_private_key_: 'Wir werden jetzt deinen privaten Schlüssel generieren. Das kann einige Zeit in Anspruch nehmen.',
|
||||
Authenticating_a_buddy_helps_: 'Einen Freund zu authentifizieren hilft sicher zustellen, dass die Person mit der du sprichst auch die ist die sie sagt.',
|
||||
How_do_you_want_to_authenticate_your_buddy: 'Wie willst du deinen Freund authentifizieren?',
|
||||
How_do_you_want_to_authenticate_your_buddy: 'Wie willst du {{cid_name}} (<b>{{cid_jid}}</b>) authentifizieren?',
|
||||
Select_method: 'Wähle...',
|
||||
Manual: 'Manual',
|
||||
Question: 'Frage',
|
||||
@@ -3764,7 +4053,8 @@ var jsxc;
|
||||
Menu: 'Menü',
|
||||
Hide_offline: 'Offline ausblenden',
|
||||
Show_offline: 'Offline einblenden',
|
||||
About: 'Über'
|
||||
About: 'Über',
|
||||
dd: 'Beschäftigt'
|
||||
}
|
||||
};
|
||||
}(jQuery));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* jsxc v0.5.1 - 2014-01-27
|
||||
* jsxc v0.6.0 - 2014-02-28
|
||||
*
|
||||
* Copyright (c) 2014 Klaus Herberth <klaus@jsxc.org> <br>
|
||||
* Released under the MIT license
|
||||
@@ -7,7 +7,7 @@
|
||||
* Please see http://jsxc.org/
|
||||
*
|
||||
* @author Klaus Herberth <klaus@jsxc.org>
|
||||
* @version 0.5.1
|
||||
* @version 0.6.0
|
||||
*/
|
||||
|
||||
/* jsxc, Strophe, SDPUtil, getUserMediaWithConstraints, setupRTC, jQuery */
|
||||
@@ -36,7 +36,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
|
||||
</div>\
|
||||
<!-- <button type="button" class="jsxc_mute_local">%%mute_my_audio%%</button>\
|
||||
<button type="button" class="jsxc_pause_local">%%pause_my_video%%</button> --> \
|
||||
<button type="button" class="jsxc_chat">%%chat%%</button>\
|
||||
<button type="button" class="jsxc_showchat">%%chat%%</button>\
|
||||
<button type="button" class="jsxc_fullscreen">%%fullscreen%%</button>\
|
||||
<button type="button" class="jsxc_info">%%Info%%</button>\
|
||||
</div>\
|
||||
@@ -462,7 +462,6 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
|
||||
*/
|
||||
onRemoteStreamAdded: function(event, data, sid) {
|
||||
this.setStatus('Remote stream for session ' + sid + ' added.');
|
||||
jsxc.debug('Stream data', data);
|
||||
|
||||
var stream = data.stream;
|
||||
this.remoteStream = stream;
|
||||
@@ -743,7 +742,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
|
||||
toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'));
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_chat').click(function() {
|
||||
$('#jsxc_dialog .jsxc_showchat').click(function() {
|
||||
toggleMulti($('#jsxc_dialog .jsxc_chatarea'));
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/* jshint -W117 */
|
||||
function TraceablePeerConnection(ice_config, constraints) {
|
||||
var setupRTC, getUserMediaWithConstraints, TraceablePeerConnection;
|
||||
|
||||
(function($){
|
||||
TraceablePeerConnection = function(ice_config, constraints) {
|
||||
var self = this;
|
||||
var RTCPeerconnection = navigator.mozGetUserMedia ? mozRTCPeerConnection : webkitRTCPeerConnection;
|
||||
this.peerconnection = new RTCPeerconnection(ice_config, constraints);
|
||||
@@ -176,7 +179,7 @@ TraceablePeerConnection.prototype.getStats = function(callback) {
|
||||
|
||||
|
||||
// mozilla chrome compat layer -- very similar to adapter.js
|
||||
function setupRTC() {
|
||||
setupRTC = function (){
|
||||
var RTC = null;
|
||||
if (navigator.mozGetUserMedia) {
|
||||
console.log('This appears to be Firefox');
|
||||
@@ -229,9 +232,9 @@ function setupRTC() {
|
||||
try { console.log('Browser does not appear to be WebRTC-capable'); } catch (e) { }
|
||||
}
|
||||
return RTC;
|
||||
}
|
||||
};
|
||||
|
||||
function getUserMediaWithConstraints(um, resolution, bandwidth, fps) {
|
||||
getUserMediaWithConstraints = function(um, resolution, bandwidth, fps) {
|
||||
var constraints = {audio: false, video: false};
|
||||
|
||||
if (um.indexOf('video') >= 0) {
|
||||
@@ -324,3 +327,4 @@ function getUserMediaWithConstraints(um, resolution, bandwidth, fps) {
|
||||
$(document).trigger('mediafailure.jingle');
|
||||
}
|
||||
}
|
||||
}(jQuery));
|
||||
@@ -1,4 +1,5 @@
|
||||
/* jshint -W117 */
|
||||
(function($){
|
||||
Strophe.addConnectionPlugin('jingle', {
|
||||
connection: null,
|
||||
sessions: {},
|
||||
@@ -257,3 +258,4 @@ Strophe.addConnectionPlugin('jingle', {
|
||||
// implement push?
|
||||
}
|
||||
});
|
||||
}(jQuery));
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/* jshint -W117 */
|
||||
var SDP;
|
||||
|
||||
(function($){
|
||||
// SDP STUFF
|
||||
function SDP(sdp) {
|
||||
SDP = function(sdp) {
|
||||
this.media = sdp.split('\r\nm=');
|
||||
for (var i = 1; i < this.media.length; i++) {
|
||||
this.media[i] = 'm=' + this.media[i];
|
||||
@@ -807,3 +810,4 @@ SDPUtil = {
|
||||
return line + '\r\n';
|
||||
}
|
||||
};
|
||||
}(jQuery));
|
||||
@@ -1,6 +1,9 @@
|
||||
/* jshint -W117 */
|
||||
// Jingle stuff
|
||||
function JingleSession(me, sid, connection) {
|
||||
var JingleSession;
|
||||
|
||||
(function($){
|
||||
JingleSession = function(me, sid, connection) {
|
||||
this.me = me;
|
||||
this.sid = sid;
|
||||
this.connection = connection;
|
||||
@@ -853,3 +856,4 @@ JingleSession.prototype.getStats = function (interval) {
|
||||
return this.statsinterval;
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
|
||||
+2166
-1229
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+400
-110
@@ -69,17 +69,61 @@ var jsxc;
|
||||
/** My css id */
|
||||
cid: null,
|
||||
|
||||
/** Shortcut for jsxc.options.debug */
|
||||
debug: null,
|
||||
|
||||
/** Some constants */
|
||||
CONST: {
|
||||
NOTIFICATION_DEFAULT: 'default',
|
||||
NOTIFICATION_GRANTED: 'granted',
|
||||
NOTIFICATION_DENIED: 'denied',
|
||||
STATUS: [ 'offline', 'away', 'online' ]
|
||||
STATUS: [ 'offline', 'dnd', 'xa', 'away', 'chat', 'online' ]
|
||||
},
|
||||
|
||||
/**
|
||||
* Write debug message to console and to log.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {String} msg Debug message
|
||||
* @param {Object} data
|
||||
* @param {String} Could be warn|error|null
|
||||
*/
|
||||
debug: function(msg, data, level) {
|
||||
if (level) {
|
||||
msg = '[' + level + '] ' + msg;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
console.log(msg, data);
|
||||
jsxc.log = jsxc.log + msg + ': ' + $("<span>").prepend($(data).clone()).html() + '\n';
|
||||
} else {
|
||||
console.log(msg);
|
||||
jsxc.log = jsxc.log + msg + '\n';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Write warn message.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {String} msg Warn message
|
||||
* @param {Object} data
|
||||
*/
|
||||
warn: function(msg, data) {
|
||||
jsxc.debug(msg, data, 'WARN');
|
||||
},
|
||||
|
||||
/**
|
||||
* Write error message.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {String} msg Error message
|
||||
* @param {Object} data
|
||||
*/
|
||||
error: function(msg, data) {
|
||||
jsxc.debug(msg, data, 'ERROR');
|
||||
},
|
||||
|
||||
/** debug log */
|
||||
log: '',
|
||||
|
||||
/**
|
||||
* Starts the action
|
||||
*
|
||||
@@ -102,9 +146,6 @@ var jsxc;
|
||||
jsxc.storage.updateUserItem('options', key, value);
|
||||
};
|
||||
|
||||
// Shortcut
|
||||
jsxc.debug = jsxc.options.debug;
|
||||
|
||||
jsxc.storageNotConform = jsxc.storage.getItem('storageNotConform') || 2;
|
||||
|
||||
// detect language
|
||||
@@ -162,7 +203,9 @@ var jsxc;
|
||||
|
||||
// create jquery object
|
||||
var form = jsxc.options.loginForm.form = $(jsxc.options.loginForm.form);
|
||||
var events = form.data('events') || {submit: []};
|
||||
var events = form.data('events') || {
|
||||
submit: []
|
||||
};
|
||||
var submits = [];
|
||||
|
||||
// save attached submit events and remove them. Will be reattached
|
||||
@@ -170,7 +213,7 @@ var jsxc;
|
||||
$.each(events.submit, function(index, val) {
|
||||
submits.push(val.handler);
|
||||
});
|
||||
|
||||
|
||||
form.data('submits', submits);
|
||||
form.off('submit');
|
||||
|
||||
@@ -302,8 +345,8 @@ var jsxc;
|
||||
* Checks if there is a chief
|
||||
*/
|
||||
checkChief: function() {
|
||||
jsxc.debug('checkChief');
|
||||
jsxc.to = window.setTimeout(jsxc.onChief, 500);
|
||||
jsxc.debug('check chief');
|
||||
jsxc.to = window.setTimeout(jsxc.onChief, jsxc.options.timeout);
|
||||
jsxc.storage.ink('alive');
|
||||
},
|
||||
|
||||
@@ -376,21 +419,6 @@ var jsxc;
|
||||
return cid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Send message to buddy and display this to the user
|
||||
*
|
||||
* @param {String} cid
|
||||
* @param {String} msg message to be send
|
||||
*/
|
||||
sendMessage: function(cid, msg) {
|
||||
|
||||
if (jsxc.chief) {
|
||||
jsxc.buddyList[cid].sendMsg(msg);
|
||||
}
|
||||
|
||||
jsxc.gui.window.postMessage(cid, 'out', msg);
|
||||
},
|
||||
|
||||
/**
|
||||
* Restore roster
|
||||
*/
|
||||
@@ -443,12 +471,12 @@ var jsxc;
|
||||
submitLoginForm: function() {
|
||||
var form = jsxc.options.loginForm.form.off('submit');
|
||||
|
||||
//Attach original events
|
||||
// Attach original events
|
||||
var submits = form.data('submits') || [];
|
||||
$.each(submits, function(index, val) {
|
||||
form.submit(val);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
if (form.find('#submit')) {
|
||||
form.find('#submit').click();
|
||||
} else {
|
||||
@@ -514,7 +542,7 @@ var jsxc;
|
||||
var k = key.replace(/ /gi, '_');
|
||||
|
||||
if (!jsxc.l[k]) {
|
||||
jsxc.debug('[WARN] No translation for: ' + k);
|
||||
jsxc.warn('No translation for: ' + k);
|
||||
}
|
||||
|
||||
return jsxc.l[k] || key.replace(/_/gi, ' ');
|
||||
@@ -660,6 +688,7 @@ var jsxc;
|
||||
var ri = $('#' + cid); // roster item from user
|
||||
var we = jsxc.gui.getWindow(cid); // window element from user
|
||||
var ue = $('#' + cid + ', #jsxc_window_' + cid + ', .jsxc_buddy_' + cid); // both
|
||||
var bullet = $('.jsxc_buddy_' + cid);
|
||||
|
||||
// Attach data to corresponding roster item
|
||||
ri.data(data);
|
||||
@@ -669,6 +698,7 @@ var jsxc;
|
||||
|
||||
// Change name and add title
|
||||
ue.find('.jsxc_name').text(data.name).attr('title', 'is ' + jsxc.CONST.STATUS[data.status]);
|
||||
bullet.attr('title', 'is ' + jsxc.CONST.STATUS[data.status]);
|
||||
|
||||
// Update gui according to encryption state
|
||||
switch (data.msgstate) {
|
||||
@@ -704,31 +734,46 @@ var jsxc;
|
||||
}
|
||||
|
||||
if (data.avatar && data.avatar.length > 0) {
|
||||
var avatarSrc = jsxc.storage.getUserItem('avatar_' + data.avatar);
|
||||
jsxc.gui.updateAvatar(ue, data.jid, data.avatar);
|
||||
}
|
||||
},
|
||||
|
||||
updateAvatar: function(el, jid, aid) {
|
||||
var avatarSrc = jsxc.storage.getUserItem('avatar_' + aid);
|
||||
|
||||
var setAvatar = function(src) {
|
||||
ue.find('.jsxc_avatar img').remove();
|
||||
var img = $('<img/>').attr('alt', 'Avatar').attr('src', src);
|
||||
ue.find('.jsxc_avatar').prepend(img);
|
||||
};
|
||||
var setAvatar = function(src) {
|
||||
if(src === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
el.find('.jsxc_avatar img').remove();
|
||||
var img = $('<img/>').attr('alt', 'Avatar').attr('src', src);
|
||||
el.find('.jsxc_avatar').prepend(img);
|
||||
};
|
||||
|
||||
if (avatarSrc !== null) {
|
||||
setAvatar(avatarSrc);
|
||||
} else {
|
||||
jsxc.xmpp.conn.vcard.get(function(stanza) {
|
||||
jsxc.debug('vCard', stanza);
|
||||
if (avatarSrc !== null) {
|
||||
setAvatar(avatarSrc);
|
||||
} else {
|
||||
jsxc.xmpp.conn.vcard.get(function(stanza) {
|
||||
jsxc.debug('vCard', stanza);
|
||||
|
||||
var vCard = $(stanza).find("vCard");
|
||||
var vCard = $(stanza).find("vCard > PHOTO");
|
||||
var src;
|
||||
|
||||
if(vCard.length === 0){
|
||||
jsxc.debug('No photo provided');
|
||||
src = 0;
|
||||
} else {
|
||||
var img = vCard.find('BINVAL').text();
|
||||
var type = vCard.find('TYPE').text();
|
||||
var src = 'data:' + type + ';base64,' + img;
|
||||
|
||||
jsxc.storage.setUserItem('avatar_' + data.avatar, src);
|
||||
setAvatar(src);
|
||||
}, Strophe.getBareJidFromJid(data.jid), function(msg) {
|
||||
jsxc.debug('Error', msg);
|
||||
});
|
||||
}
|
||||
src = 'data:' + type + ';base64,' + img;
|
||||
}
|
||||
|
||||
jsxc.storage.setUserItem('avatar_' + aid, src);
|
||||
setAvatar(src);
|
||||
}, Strophe.getBareJidFromJid(jid), function(msg) {
|
||||
jsxc.error('Could not load vcard.', msg);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -748,15 +793,33 @@ var jsxc;
|
||||
* @memberof jsxc.gui
|
||||
*/
|
||||
toggleList: function() {
|
||||
$(this).disableSelection();
|
||||
|
||||
var ul = $(this).find('ul');
|
||||
var slideUp = null;
|
||||
|
||||
slideUp = function() {
|
||||
ul.slideUp();
|
||||
$('body').off('click', null, slideUp);
|
||||
};
|
||||
|
||||
$(this).click(function() {
|
||||
|
||||
if(ul.is(":hidden")){
|
||||
// hide other lists
|
||||
$('body').click();
|
||||
$('body').one('click', slideUp);
|
||||
} else {
|
||||
$('body').off('click', null, slideUp);
|
||||
}
|
||||
|
||||
ul.slideToggle();
|
||||
|
||||
window.clearTimeout(ul.data('timer'));
|
||||
|
||||
return false;
|
||||
}).mouseleave(function() {
|
||||
ul.data('timer', window.setTimeout(function() {
|
||||
ul.slideUp();
|
||||
}, 2000));
|
||||
ul.data('timer', window.setTimeout(slideUp, 2000));
|
||||
}).mouseenter(function() {
|
||||
window.clearTimeout(ul.data('timer'));
|
||||
});
|
||||
@@ -808,9 +871,17 @@ var jsxc;
|
||||
*/
|
||||
showVerification: function(cid) {
|
||||
|
||||
// Check if there is a open dialog
|
||||
if($('#jsxc_dialog').length > 0) {
|
||||
setTimeout(function(){
|
||||
jsxc.gui.showVerification(cid);
|
||||
}, 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
// verification only possible if the connection is encrypted
|
||||
if (jsxc.storage.getUserItem('buddy_' + cid).msgstate !== OTR.CONST.MSGSTATE_ENCRYPTED) {
|
||||
jsxc.debug('Connection not encrypted');
|
||||
jsxc.warn('Connection not encrypted');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1071,6 +1142,71 @@ var jsxc;
|
||||
*/
|
||||
showAboutDialog: function() {
|
||||
jsxc.gui.dialog.open(jsxc.gui.template.get('aboutDialog'));
|
||||
|
||||
$('#jsxc_dialog .jsxc_debuglog').click(function() {
|
||||
jsxc.gui.showDebugLog();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Show debug log.
|
||||
*
|
||||
* @memberOf jsxc.gui
|
||||
*/
|
||||
showDebugLog: function() {
|
||||
var userInfo = '<h3>User information</h3>';
|
||||
|
||||
if (navigator) {
|
||||
var key;
|
||||
for (key in navigator) {
|
||||
if (navigator.hasOwnProperty(key) && typeof navigator[key] === 'string') {
|
||||
userInfo += '<b>' + key + ':</b> ' + navigator[key] + '<br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (window.screen) {
|
||||
userInfo += '<b>Height:</b> ' + window.screen.height + '<br />';
|
||||
userInfo += '<b>Width:</b> ' + window.screen.width + '<br />';
|
||||
}
|
||||
|
||||
userInfo += '<b>jsxc version:</b> ' + jsxc.version + '<br />';
|
||||
|
||||
jsxc.gui.dialog.open('<div class="jsxc_log">' + userInfo + '<h3>Log</h3><pre>' + jsxc.escapeHTML(jsxc.log) + '</pre></div>');
|
||||
},
|
||||
|
||||
/**
|
||||
* Change presence to pres.
|
||||
*
|
||||
* @memberOf jsxc.gui
|
||||
* @param pres {CONST.STATUS} New presence state
|
||||
* @param external {boolean} True if triggered from other tab.
|
||||
*/
|
||||
changePresence: function(pres, external){
|
||||
|
||||
if(external !== true){
|
||||
jsxc.storage.setUserItem('presence', pres);
|
||||
}
|
||||
|
||||
if(jsxc.chief){
|
||||
jsxc.xmpp.sendPres();
|
||||
}
|
||||
|
||||
$('#jsxc_presence > span').text($('#jsxc_presence > ul .jsxc_' + pres).text());
|
||||
|
||||
jsxc.gui.updatePresence('own', pres);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update all presence objects for given user.
|
||||
*
|
||||
* @memberOf jsxc.gui
|
||||
* @param cid CSS id of user.
|
||||
* @param {CONST.STATUS} pres New presence state.
|
||||
*/
|
||||
updatePresence: function(cid, pres) {
|
||||
|
||||
$('.jsxc_presence_' + cid).removeClass('jsxc_' + jsxc.CONST.STATUS.join(' jsxc_')).addClass('jsxc_' + pres);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1120,6 +1256,12 @@ var jsxc;
|
||||
$('#jsxc_toggleRoster').click(function() {
|
||||
jsxc.gui.roster.toggle();
|
||||
});
|
||||
|
||||
$('#jsxc_presence > ul > li').click(function(){
|
||||
var self = $(this);
|
||||
|
||||
jsxc.gui.changePresence(self.data('pres'));
|
||||
});
|
||||
|
||||
$('#jsxc_buddylist').slimScroll({
|
||||
distance: '3px',
|
||||
@@ -1129,12 +1271,20 @@ var jsxc;
|
||||
opacity: '0.5'
|
||||
});
|
||||
|
||||
jsxc.gui.toggleList.call($('#jsxc_menu'));
|
||||
$('#jsxc_roster > .jsxc_bottom > div').each(function() {
|
||||
jsxc.gui.toggleList.call($(this));
|
||||
});
|
||||
|
||||
if (jsxc.storage.getUserItem('roster') === 'hidden') {
|
||||
$('#jsxc_roster').css('right', '-200px');
|
||||
$('#jsxc_windowList > ul').css('paddingRight', '10px');
|
||||
}
|
||||
|
||||
var pres = jsxc.storage.getUserItem('presence') || 'online';
|
||||
$('#jsxc_presence > span').text($('#jsxc_presence > ul .jsxc_' + pres).text());
|
||||
jsxc.gui.updatePresence('own', pres);
|
||||
|
||||
jsxc.notice.load();
|
||||
|
||||
$(document).trigger('ready.roster.jsxc');
|
||||
},
|
||||
@@ -1144,7 +1294,7 @@ var jsxc;
|
||||
*
|
||||
* @param {String} cid CSS compatible jid
|
||||
*/
|
||||
add: function(cid) {
|
||||
add: function(cid) {
|
||||
var data = jsxc.storage.getUserItem('buddy_' + cid);
|
||||
var bud = jsxc.gui.buddyTemplate.clone().attr('id', cid).attr('data-type', data.type || 'chat');
|
||||
|
||||
@@ -1493,8 +1643,8 @@ var jsxc;
|
||||
if (ev.which !== 13 || !$(this).val()) {
|
||||
return;
|
||||
}
|
||||
|
||||
jsxc.sendMessage(cid, $(this).val());
|
||||
|
||||
jsxc.gui.window.postMessage(cid, 'out', $(this).val());
|
||||
|
||||
$(this).val('');
|
||||
});
|
||||
@@ -1565,9 +1715,9 @@ var jsxc;
|
||||
* @param {String} cid CSS compatible jid
|
||||
*/
|
||||
close: function(cid) {
|
||||
|
||||
|
||||
if (!jsxc.el_exists('#jsxc_window_' + cid)) {
|
||||
jsxc.debug('[Warning] Want to close a window, that is not open.');
|
||||
jsxc.warn('Want to close a window, that is not open.');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1641,7 +1791,7 @@ var jsxc;
|
||||
*
|
||||
* @param {String} cid
|
||||
*/
|
||||
hide: function(cid) {
|
||||
hide: function(cid) {
|
||||
jsxc.storage.updateUserItem('window_' + cid, 'minimize', true);
|
||||
|
||||
jsxc.gui.window._hide(cid);
|
||||
@@ -1652,7 +1802,7 @@ var jsxc;
|
||||
*
|
||||
* @param {String} cid
|
||||
*/
|
||||
_hide: function(cid) {
|
||||
_hide: function(cid) {
|
||||
$('#jsxc_window_' + cid + ' .jsxc_window').slideUp();
|
||||
jsxc.gui.getWindow(cid).trigger('hidden.window.jsxc');
|
||||
},
|
||||
@@ -1732,6 +1882,10 @@ var jsxc;
|
||||
if (direction === 'in') {
|
||||
$(document).trigger('postmessagein.jsxc', [ jsxc.jids[cid], html_msg ]);
|
||||
}
|
||||
|
||||
if (direction === 'out' && jsxc.chief) {
|
||||
jsxc.buddyList[cid].sendMsg(msg);
|
||||
}
|
||||
|
||||
jsxc.gui.window._postMessage(cid, direction, msg);
|
||||
},
|
||||
@@ -1845,7 +1999,7 @@ var jsxc;
|
||||
|
||||
$.extend(ph, {
|
||||
cid_priv_fingerprint: data.fingerprint ? data.fingerprint.replace(/(.{8})/g, '$1 ') : jsxc.l.no_available,
|
||||
cid_jid: data.jid,
|
||||
cid_jid: Strophe.getBareJidFromJid(data.jid),
|
||||
cid_name: data.name
|
||||
});
|
||||
}
|
||||
@@ -1872,8 +2026,7 @@ var jsxc;
|
||||
jsxc.debug('Template not available: ' + name);
|
||||
return name;
|
||||
},
|
||||
authenticationDialog: '<div id="jsxc_facebox">\
|
||||
<h3>Verification</h3>\
|
||||
authenticationDialog: '<h3>Verification</h3>\
|
||||
<p>%%Authenticating_a_buddy_helps_%%</p>\
|
||||
<div>\
|
||||
<p style="margin:0px;">%%How_do_you_want_to_authenticate_your_buddy%%</p>\
|
||||
@@ -1902,8 +2055,7 @@ var jsxc;
|
||||
<p class=".jsxc_explanation">%%To_authenticate_pick_a_secret_%%</p>\
|
||||
<p><label for="jsxc_secret">%%Secret%%:</label><input type="text" name="secret" id="jsxc_secret" /></p>\
|
||||
<p class="jsxc_right"><a href="#" class="button jsxc_close">%%Close%%</a> <a href="#" class="button creation">%%Compare%%</a></p>\
|
||||
</div>\
|
||||
</div>',
|
||||
</div>',
|
||||
fingerprintsDialog: '<div>\
|
||||
<p><strong>%%Your_fingerprint%%</strong><br />\
|
||||
<span style="text-transform:uppercase">{{my_priv_fingerprint}}</span></p>\
|
||||
@@ -1935,17 +2087,37 @@ var jsxc;
|
||||
</div>\
|
||||
</li>',
|
||||
roster: '<div id="jsxc_roster">\
|
||||
<ul id="jsxc_buddylist"></ul>\
|
||||
<div id="jsxc_menu">\
|
||||
%%Menu%%\
|
||||
<ul>\
|
||||
<li class="jsxc_addBuddy">%%Add_buddy%%</li>\
|
||||
<li class="jsxc_hideOffline">%%Hide offline%%</li>\
|
||||
<li class="jsxc_about">%%About%%</li>\
|
||||
</ul>\
|
||||
</div>\
|
||||
<div id="jsxc_toggleRoster"></div>\
|
||||
</div>',
|
||||
<ul id="jsxc_buddylist"></ul>\
|
||||
<div class="jsxc_bottom jsxc_presence_own">\
|
||||
<div id="jsxc_avatar">\
|
||||
<div class="jsxc_avatar">☺</div>\
|
||||
</div>\
|
||||
<div id="jsxc_menu">\
|
||||
<span>⚙</span>\
|
||||
<ul>\
|
||||
<li class="jsxc_addBuddy">%%Add_buddy%%</li>\
|
||||
<li class="jsxc_hideOffline">%%Hide offline%%</li>\
|
||||
<li class="jsxc_about">%%About%%</li>\
|
||||
</ul>\
|
||||
</div>\
|
||||
<div id="jsxc_notice">\
|
||||
<span></span>\
|
||||
<ul></ul>\
|
||||
</div>\
|
||||
<div id="jsxc_presence">\
|
||||
<span>%%Online%%</span>\
|
||||
<ul>\
|
||||
<li data-pres="online" class="jsxc_online">%%Online%%</li>\
|
||||
<li data-pres="chat" class="jsxc_chat">%%Chatty%%</li>\
|
||||
<li data-pres="away" class="jsxc_away">%%Away%%</li>\
|
||||
<li data-pres="xa" class="jsxc_xa">%%Extended away%%</li>\
|
||||
<li data-pres="dnd" class="jsxc_dnd">%%dnd%%</li>\
|
||||
<!-- <li data-pres="offline" class="jsxc_offline">%%Offline%%</li> -->\
|
||||
</ul>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div id="jsxc_toggleRoster"></div>\
|
||||
</div>',
|
||||
windowList: '<div id="jsxc_windowList">\
|
||||
<ul></ul>\
|
||||
</div>',
|
||||
@@ -2007,7 +2179,8 @@ var jsxc;
|
||||
<br />\
|
||||
Real-time chat app for OwnCloud. This app requires external<br /> XMPP server (openfire, ejabberd etc.).<br />\
|
||||
<br />\
|
||||
<i>Released under the MIT license</i></p>'
|
||||
<i>Released under the MIT license</i></p>\
|
||||
<p class="jsxc_right"><a class="button jsxc_debuglog" href="#">Show debug log</a></p>'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2040,14 +2213,14 @@ var jsxc;
|
||||
jsxc.xmpp.conn = new Strophe.Connection(url);
|
||||
|
||||
// jsxc.xmpp.conn.xmlInput = function(data) {
|
||||
// jsxc.debug('<', data);
|
||||
// console.log('<', data);
|
||||
// };
|
||||
// jsxc.xmpp.conn.xmlOutput = function(data) {
|
||||
// jsxc.debug('>', data);
|
||||
// console.log('>', data);
|
||||
// };
|
||||
//
|
||||
|
||||
// Strophe.log = function (level, msg) {
|
||||
// jsxc.debug(level + " " + msg);
|
||||
// console.log(level + " " + msg);
|
||||
// };
|
||||
|
||||
var callback = function(status, condition) {
|
||||
@@ -2059,7 +2232,7 @@ var jsxc;
|
||||
jsxc.cid = jsxc.jidToCid(jsxc.xmpp.conn.jid.toLowerCase());
|
||||
$(document).trigger('connected.jsxc');
|
||||
break;
|
||||
case Strophe.Status.ATTACHED:
|
||||
case Strophe.Status.ATTACHED:
|
||||
$(document).trigger('attached.jsxc');
|
||||
break;
|
||||
case Strophe.Status.DISCONNECTED:
|
||||
@@ -2130,7 +2303,7 @@ var jsxc;
|
||||
jsxc.xmpp.conn.pause();
|
||||
|
||||
// Save sid and jid
|
||||
jsxc.storage.setItem('sid', jsxc.xmpp.conn.sid);
|
||||
jsxc.storage.setItem('sid', jsxc.xmpp.conn._proto.sid);
|
||||
jsxc.storage.setItem('jid', jsxc.xmpp.conn.jid.toLowerCase());
|
||||
|
||||
jsxc.storage.setItem('lastActivity', (new Date()).getTime());
|
||||
@@ -2140,6 +2313,7 @@ var jsxc;
|
||||
|
||||
jsxc.storage.removeUserItem('windowlist');
|
||||
jsxc.storage.removeUserItem('own');
|
||||
jsxc.storage.removeUserItem('avatar_own');
|
||||
|
||||
// submit login form
|
||||
if (jsxc.triggeredFromForm) {
|
||||
@@ -2179,11 +2353,13 @@ var jsxc;
|
||||
}).c('query', {
|
||||
xmlns: 'jabber:iq:roster'
|
||||
});
|
||||
|
||||
|
||||
jsxc.xmpp.conn.sendIQ(iq, jsxc.xmpp.onRoster);
|
||||
} else {
|
||||
jsxc.xmpp.sendPres();
|
||||
}
|
||||
|
||||
jsxc.gui.updateAvatar($('#jsxc_avatar'), jsxc.storage.getItem('jid'), 'own');
|
||||
|
||||
jsxc.xmpp.connectionReady();
|
||||
},
|
||||
@@ -2206,14 +2382,25 @@ var jsxc;
|
||||
jsxc.xmpp.conn.disco.addFeature(Strophe.NS.DISCO_INFO);
|
||||
}
|
||||
|
||||
// send presence stanza
|
||||
// create presence stanza
|
||||
var pres = $pres();
|
||||
|
||||
if (jsxc.xmpp.conn.caps) {
|
||||
// attach caps
|
||||
pres.c('c', jsxc.xmpp.conn.caps.generateCapsAttrs());
|
||||
pres.c('c', jsxc.xmpp.conn.caps.generateCapsAttrs()).up();
|
||||
}
|
||||
|
||||
var presState = jsxc.storage.getUserItem('presence') || 'online';
|
||||
if(presState !== 'online'){
|
||||
pres.c('show').t(presState).up();
|
||||
}
|
||||
|
||||
var priority = jsxc.storage.getUserItem('priority');
|
||||
if(priority !== null){
|
||||
pres.c('priority').t(priority[presState]).up();
|
||||
}
|
||||
|
||||
jsxc.debug('Send presence', pres.toString());
|
||||
jsxc.xmpp.conn.send(pres);
|
||||
},
|
||||
|
||||
@@ -2229,6 +2416,7 @@ var jsxc;
|
||||
jsxc.storage.removeItem('rid');
|
||||
jsxc.storage.removeItem('lastActivity');
|
||||
jsxc.storage.removeItem('hidden');
|
||||
jsxc.storage.removeUserItem('avatar_own');
|
||||
|
||||
jsxc.xmpp.conn = null;
|
||||
|
||||
@@ -2313,9 +2501,8 @@ var jsxc;
|
||||
|
||||
jsxc.storage.setUserItem('buddylist', buddies);
|
||||
|
||||
$(document).trigger('rosterready.jsxc');
|
||||
|
||||
jsxc.debug('Roster ready');
|
||||
$(document).trigger('rosterready.jsxc');
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -2395,10 +2582,13 @@ var jsxc;
|
||||
* node='http://psi-im.org/caps' ver='caps-b75d8d2b25' ext='ca cs
|
||||
* ep-notify-2 html'/> </presence>
|
||||
*/
|
||||
jsxc.debug('onPresence', presence);
|
||||
|
||||
var ptype = $(presence).attr('type');
|
||||
var from = $(presence).attr('from');
|
||||
var jid = Strophe.getBareJidFromJid(from).toLowerCase();
|
||||
var to = Strophe.getBareJidFromJid($(presence).attr('to')).toLowerCase();
|
||||
var to = $(presence).attr('to');
|
||||
to = (to)? Strophe.getBareJidFromJid(to).toLowerCase(): jid;
|
||||
var r = Strophe.getResourceFromJid(from);
|
||||
var cid = jsxc.jidToCid(jid);
|
||||
var data = jsxc.storage.getUserItem('buddy_' + cid);
|
||||
@@ -2406,14 +2596,12 @@ var jsxc;
|
||||
var status = null;
|
||||
var xVCard = $(presence).find('x[xmlns="vcard-temp:x:update"]');
|
||||
|
||||
jsxc.debug('onPresence', presence);
|
||||
|
||||
if (jid === to) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ptype === 'error') {
|
||||
jsxc.debug('[XMPP ERROR] ' + $(presence).attr('code'));
|
||||
jsxc.error('[XMPP] ' + $(presence).attr('code'));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2423,17 +2611,17 @@ var jsxc;
|
||||
jid: jid,
|
||||
approve: -1
|
||||
});
|
||||
jsxc.gui.showApproveDialog(jid);
|
||||
jsxc.notice.add('Friendship request', 'from ' + jid, 'gui.showApproveDialog', [jid]);
|
||||
|
||||
return true;
|
||||
} else if (ptype === 'unavailable') {
|
||||
status = 0;
|
||||
status = jsxc.CONST.STATUS.indexOf('offline');
|
||||
} else {
|
||||
var show = $(presence).find('show').text();
|
||||
if (show === '' || show === 'chat') {
|
||||
status = 2;
|
||||
if (show === '') {
|
||||
status = jsxc.CONST.STATUS.indexOf('online');
|
||||
} else {
|
||||
status = 1;
|
||||
status = jsxc.CONST.STATUS.indexOf(show);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2444,7 +2632,7 @@ var jsxc;
|
||||
}
|
||||
|
||||
var maxVal = [];
|
||||
var max = 0, prop;
|
||||
var max = 0, prop = null;
|
||||
for (prop in res) {
|
||||
if (res.hasOwnProperty(prop)) {
|
||||
if (max <= res[prop]) {
|
||||
@@ -2503,7 +2691,7 @@ var jsxc;
|
||||
* <body>...</body> <active
|
||||
* xmlns='http://jabber.org/protocol/chatstates'/> </message>
|
||||
*/
|
||||
|
||||
|
||||
jsxc.debug('Incoming message', message);
|
||||
|
||||
var type = $(message).attr('type');
|
||||
@@ -2671,7 +2859,7 @@ var jsxc;
|
||||
jsxc.storage.setItem('storageNotConform', 0);
|
||||
}, 1000);
|
||||
}
|
||||
jsxc.debug('setItem: ' + key);
|
||||
|
||||
jsxc.ls.push(JSON.stringify({
|
||||
key: key,
|
||||
value: value
|
||||
@@ -2884,6 +3072,14 @@ var jsxc;
|
||||
|
||||
var cid = key.replace(/^[a-z]+_(.*)/i, '$1');
|
||||
|
||||
if (key.match(/^notices/)) {
|
||||
jsxc.notice.load();
|
||||
}
|
||||
|
||||
if (key.match(/^presence/)) {
|
||||
jsxc.gui.changePresence(e.newValue, true);
|
||||
}
|
||||
|
||||
if (key.match(/^hidden/)) {
|
||||
if (jsxc.chief) {
|
||||
clearTimeout(jsxc.toNotification);
|
||||
@@ -3018,6 +3214,8 @@ var jsxc;
|
||||
|
||||
// react if someone ask, if there is a chief
|
||||
if (jsxc.chief && key === 'alive') {
|
||||
jsxc.debug('Master request.');
|
||||
|
||||
jsxc.storage.ink('alive');
|
||||
return;
|
||||
}
|
||||
@@ -3193,8 +3391,7 @@ var jsxc;
|
||||
});
|
||||
|
||||
jsxc.buddyList[cid].on('error', function(err) {
|
||||
jsxc.debug('[OTR] ' + err);
|
||||
jsxc.gui.window.postMessage(cid, 'sys', '[OTR] ' + err);
|
||||
jsxc.error('[OTR] ' + err);
|
||||
});
|
||||
|
||||
jsxc.otr.restore(cid);
|
||||
@@ -3472,12 +3669,12 @@ var jsxc;
|
||||
* @param msg
|
||||
* @param d
|
||||
*/
|
||||
notify: function(title, msg, d) {
|
||||
notify: function(title, msg, d, force) {
|
||||
if (!jsxc.options.notification || !jsxc.notification.hasPermission()) {
|
||||
return; // notifications disabled
|
||||
}
|
||||
|
||||
if (!jsxc.isHidden()) {
|
||||
if (!jsxc.isHidden() && !force) {
|
||||
return; // Tab is visible
|
||||
}
|
||||
|
||||
@@ -3510,6 +3707,10 @@ var jsxc;
|
||||
window.Notification = function(title, opt) {
|
||||
var popup = window.webkitNotifications.createNotification(null, title, opt.body);
|
||||
popup.show();
|
||||
|
||||
popup.close = function() {
|
||||
popup.cancel();
|
||||
};
|
||||
|
||||
return popup;
|
||||
};
|
||||
@@ -3596,10 +3797,97 @@ var jsxc;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This namespace handle the notice system.
|
||||
*
|
||||
* @namspace jsxc.notice
|
||||
* @memberOf jsxc
|
||||
*/
|
||||
jsxc.notice = {
|
||||
/** Number of notices. */
|
||||
_num: 0,
|
||||
|
||||
/**
|
||||
* Loads the saved notices.
|
||||
*
|
||||
* @memberOf jsxc.notice
|
||||
*/
|
||||
load: function() {
|
||||
//reset list
|
||||
$('#jsxc_notice ul li').remove();
|
||||
$('#jsxc_notice > span').text('');
|
||||
jsxc.notice._num = 0;
|
||||
|
||||
var saved = jsxc.storage.getUserItem('notices') || [];
|
||||
var key = null;
|
||||
|
||||
for(key in saved){
|
||||
if(saved.hasOwnProperty(key)){
|
||||
var val = saved[key];
|
||||
|
||||
jsxc.notice.add(val.msg, val.description, val.fnName, val.fnParams, key);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a new notice to the stack;
|
||||
*
|
||||
* @memberOf jsxc.notice
|
||||
* @param msg Header message
|
||||
* @param description Notice description
|
||||
* @param fnName Function name to be called if you open the notice
|
||||
* @param fnParams Array of params for function
|
||||
* @param id Notice id
|
||||
*/
|
||||
add: function(msg, description, fnName, fnParams, id) {
|
||||
var nid = id || Date.now();
|
||||
var list = $('#jsxc_notice ul');
|
||||
var notice = $('<li/>');
|
||||
|
||||
notice.click(function() {
|
||||
$(this).remove();
|
||||
$('#jsxc_notice > span').text(--jsxc.notice._num || '');
|
||||
|
||||
var s = jsxc.storage.getUserItem('notices');
|
||||
delete s[nid];
|
||||
jsxc.storage.setUserItem('notices', s);
|
||||
|
||||
var fn = jsxc[fnName];
|
||||
|
||||
if(typeof fn === 'function'){
|
||||
fn.apply(null, fnParams);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
notice.text(msg);
|
||||
notice.attr('title', description || '');
|
||||
list.append(notice);
|
||||
|
||||
$('#jsxc_notice > span').text(++jsxc.notice._num);
|
||||
|
||||
if (!id) {
|
||||
var saved = jsxc.storage.getUserItem('notices') || {};
|
||||
saved[nid] = {
|
||||
msg: msg,
|
||||
description: description,
|
||||
fnName: fnName,
|
||||
fnParams: fnParams
|
||||
};
|
||||
jsxc.storage.setUserItem('notices', saved);
|
||||
|
||||
jsxc.notification.notify(msg, description || '', null, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains all available translations
|
||||
*
|
||||
* @namespace jsxc.l10n
|
||||
* @memberOf jsxc
|
||||
*/
|
||||
jsxc.l10n = {
|
||||
en: {
|
||||
@@ -3632,7 +3920,7 @@ var jsxc;
|
||||
enter_the_secret: 'enter the secret.',
|
||||
now_we_will_create_your_private_key_: 'Now we will create your private key. This can take some time.',
|
||||
Authenticating_a_buddy_helps_: 'Authenticating a buddy helps ensure that the person you are talking to is who he or she is saying.',
|
||||
How_do_you_want_to_authenticate_your_buddy: 'How do you want to authenticate your buddy?',
|
||||
How_do_you_want_to_authenticate_your_buddy: 'How do you want to authenticate {{cid_name}} (<b>{{cid_jid}}</b>)?',
|
||||
Select_method: 'Select method...',
|
||||
Manual: 'Manual',
|
||||
Question: 'Question',
|
||||
@@ -3674,7 +3962,8 @@ var jsxc;
|
||||
clear_history: 'Clear history',
|
||||
New_message_from: 'New message from',
|
||||
Should_we_notify_you_: 'Should we notify you about new messages in the future?',
|
||||
Please_accept_: 'Please click the "Allow" button at the top.'
|
||||
Please_accept_: 'Please click the "Allow" button at the top.',
|
||||
dnd: 'Do Not Disturb'
|
||||
},
|
||||
de: {
|
||||
please_wait_until_we_logged_you_in: 'Bitte warte bis wir dich eingeloggt haben.',
|
||||
@@ -3706,7 +3995,7 @@ var jsxc;
|
||||
enter_the_secret: 'gib das Geheimnis ein.',
|
||||
now_we_will_create_your_private_key_: 'Wir werden jetzt deinen privaten Schlüssel generieren. Das kann einige Zeit in Anspruch nehmen.',
|
||||
Authenticating_a_buddy_helps_: 'Einen Freund zu authentifizieren hilft sicher zustellen, dass die Person mit der du sprichst auch die ist die sie sagt.',
|
||||
How_do_you_want_to_authenticate_your_buddy: 'Wie willst du deinen Freund authentifizieren?',
|
||||
How_do_you_want_to_authenticate_your_buddy: 'Wie willst du {{cid_name}} (<b>{{cid_jid}}</b>) authentifizieren?',
|
||||
Select_method: 'Wähle...',
|
||||
Manual: 'Manual',
|
||||
Question: 'Frage',
|
||||
@@ -3752,7 +4041,8 @@ var jsxc;
|
||||
Menu: 'Menü',
|
||||
Hide_offline: 'Offline ausblenden',
|
||||
Show_offline: 'Offline einblenden',
|
||||
About: 'Über'
|
||||
About: 'Über',
|
||||
dd: 'Beschäftigt'
|
||||
}
|
||||
};
|
||||
}(jQuery));
|
||||
|
||||
@@ -24,7 +24,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
|
||||
</div>\
|
||||
<!-- <button type="button" class="jsxc_mute_local">%%mute_my_audio%%</button>\
|
||||
<button type="button" class="jsxc_pause_local">%%pause_my_video%%</button> --> \
|
||||
<button type="button" class="jsxc_chat">%%chat%%</button>\
|
||||
<button type="button" class="jsxc_showchat">%%chat%%</button>\
|
||||
<button type="button" class="jsxc_fullscreen">%%fullscreen%%</button>\
|
||||
<button type="button" class="jsxc_info">%%Info%%</button>\
|
||||
</div>\
|
||||
@@ -450,7 +450,6 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
|
||||
*/
|
||||
onRemoteStreamAdded: function(event, data, sid) {
|
||||
this.setStatus('Remote stream for session ' + sid + ' added.');
|
||||
jsxc.debug('Stream data', data);
|
||||
|
||||
var stream = data.stream;
|
||||
this.remoteStream = stream;
|
||||
@@ -731,7 +730,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
|
||||
toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'));
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_chat').click(function() {
|
||||
$('#jsxc_dialog .jsxc_showchat').click(function() {
|
||||
toggleMulti($('#jsxc_dialog .jsxc_chatarea'));
|
||||
});
|
||||
|
||||
|
||||
+1
-1
Submodule lib/strophe.jingle updated: 09bba9af8e...0c1544d6d7
+2166
-1229
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Referência em uma Nova Issue
Bloquear um usuário