Comparar commits

...

18 Commits

Autor SHA1 Mensagem Data
sualko 5056c45c5c bump version 2014-02-28 15:17:29 +01:00
sualko 3c5521d386 fix webrtc bug 2014-02-28 15:15:45 +01:00
sualko 1f54406abd fix otr error handling 2014-02-28 14:48:10 +01:00
sualko a580cf49f0 Display own avatar 2014-02-28 13:42:15 +01:00
sualko 33098bc4d5 Correct list toggle 2014-02-28 12:56:20 +01:00
sualko ab2d866ff9 Fix typo 2014-02-28 12:46:12 +01:00
sualko 3b7c7ffbed - Fix chrome notification
- Add multi tab support for notices
2014-02-28 12:43:59 +01:00
sualko 5b0f842c72 Fix master/slave negotiation 2014-02-28 12:07:56 +01:00
sualko d5bb8225cc Merge branch 'master' of https://github.com/sualko/jsxc 2014-02-28 11:04:32 +01:00
sualko 6db4ce1242 Add option to change presence state 2014-02-28 11:04:28 +01:00
Klaus 0e197e22b3 fix https://github.com/sualko/ojsxc/issues/4
Prosody didn't include the "to" attribute.
2014-01-31 21:36:10 +01:00
sualko 13b018b053 Add support for all available presence states 2014-01-29 17:48:04 +01:00
sualko 181d586730 - change roster bottom
- add notices
- don't interrupt active dialog (e.g. video session)
2014-01-29 15:17:26 +01:00
sualko 9a9cbfff5a update strophe.jingle 2014-01-28 15:08:04 +01:00
sualko 32514ea25d rebuild version 2014-01-28 14:56:13 +01:00
sualko 1e074075e3 bump version 2014-01-28 14:47:40 +01:00
sualko f89a856b7e - add debug log window
- fix debug function (fix https://github.com/sualko/ojsxc/issues/4)
2014-01-28 14:38:10 +01:00
sualko 411baae280 - Add debug log window
- Add more log functions with different levels
2014-01-28 10:57:56 +01:00
13 arquivos alterados com 5182 adições e 2697 exclusões
+19
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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));
+4 -5
Ver Arquivo
@@ -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));
+2
Ver Arquivo
@@ -1,4 +1,5 @@
/* jshint -W117 */
(function($){
Strophe.addConnectionPlugin('jingle', {
connection: null,
sessions: {},
@@ -257,3 +258,4 @@ Strophe.addConnectionPlugin('jingle', {
// implement push?
}
});
}(jQuery));
+5 -1
Ver Arquivo
@@ -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
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+400 -110
Ver Arquivo
@@ -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));
+2 -3
Ver Arquivo
@@ -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'));
});
+2166 -1229
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff