Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/jsxc.nextcloud.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsualko <github@spam.herberth.eu>2013-12-10 20:41:38 +0400
committersualko <github@spam.herberth.eu>2013-12-10 20:41:38 +0400
commitbb5569d03fcaf7069bc7f2555f693b26e3c4addc (patch)
tree6745398e2890983a9213b81aa94898515693367f
parent5eb22f0a3613b884e952fcc561402944a5eeb6f0 (diff)
bump version
-rw-r--r--CHANGELOG.md18
-rw-r--r--README.md107
-rwxr-xr-xappinfo/info.xml6
-rwxr-xr-xappinfo/version2
-rw-r--r--build/appinfo/app.php2
-rw-r--r--build/appinfo/info.xml6
-rw-r--r--build/appinfo/version2
-rw-r--r--build/css/main.css2
-rw-r--r--build/css/webrtc.css3
-rw-r--r--build/js/lib/jsxc.lib.js269
-rw-r--r--build/js/lib/jsxc.lib.webrtc.js142
-rw-r--r--build/js/ojsxc.js6
-rw-r--r--css/webrtc.css3
-rw-r--r--documentation/screenshot_1.pngbin0 -> 156755 bytes
-rw-r--r--documentation/screenshot_2.pngbin0 -> 30489 bytes
-rw-r--r--documentation/screenshot_3.pngbin0 -> 191292 bytes
-rwxr-xr-xjs/lib/jsxc.lib.js2
-rw-r--r--js/lib/jsxc.lib.webrtc.js126
-rw-r--r--js/ojsxc.js6
19 files changed, 425 insertions, 277 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d281282..46c889d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+v0.4 / 2013-12-10
+===
+- display notification request only for incoming messages
+- update ui if we lost the trust state
+- display allow dialog
+- fix chrome notification issue
+- fix ringing dialog
+- init grunt/jshint
+- lot of code clean up and commenting
+- set focus to password field
+- display minimized roster if no connection is found
+- porting to OC6 (replace fancybox with colorbox)
+- add webrtc info dialog (ip, fingerprint)
+- use git submodules for OTR and strophe.jingle
+- update README
+
v0.3 / 2013-10-28
===
- use lowercase jid
@@ -7,4 +23,4 @@ v0.3 / 2013-10-28
- fix notification with multiple tabs
- reorganize files
- add MIT license
-- minor fixes \ No newline at end of file
+- minor fixes
diff --git a/README.md b/README.md
index 3a222b1..577f786 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,102 @@
-Owncloud JavaScript Xmpp Client
-=====
+# Owncloud JavaScript Xmpp Client
-User notes
---
+__Beware! This is a beta software.__
-Developer notes
---
+## General
-You need the following libraries in the "/js" directory:
+_TODO insert short description_
-- https://github.com/sualko/otr
-- https://github.com/ESTOS/strophe.jingle \ No newline at end of file
+### Features
+- integration into existing ui
+- one-to-one conversation (XMPP)
+- encrypted one-to-one conversation (OTR)
+.- use of whitespace tags to start a OTR session
+- user verification (SMP)
+- encrypted one-to-one video call (WebRTC)
+.- [TURN REST API](http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00)
+.- fullscreen mode
+.- snapshots
+- auto link-detection
+- emotions
+- roster management
+- multi-language support (de, en)
+- multi tab support
+
+### Supported protocols
+- XMPP Core (RFC6120)
+- XMPP IM (RFC6121)
+- Bidirectional-streams Over Synchronous HTTP (XEP-0124)
+- XMPP Over BOSH (XEP-0206)
+- Service Discovery (XEP-0030)
+- CAP (XEP-0127)
+- Jingle (XEP-0166)
+- Jingle RTP Sessions (XEP-0167)
+
+### Supported browsers
+- Full support for __Chrome__ and __Firefox__.
+- __IE__ doesn't support multi tabs, WebRTC and Notifications.
+- __Safari__ doesn't support WebRTC and Notifications.
+
+### Planned features
+- multi user chat
+- video conference
+- encrypted file transfer
+
+## User notes
+
+Please download the latest version from https://github.com/sualko/ojsxc/releases and copy the "build" folder to your app directory and rename it to "ojsxc". Now go into your app menu and enable the "JavaScript Xmpp Chat".
+
+### Configuration
+
+You can oJSXC in the admin panel of owncloud.
+
+<dl>
+ <dt>BOSH url</dt>
+ <dd>The url to your bosh server. Please beware of the SOP. Use the Apache ProxyRequest or modify the CSP.</dd>
+
+ <dt>XMPP domain</dt>
+ <dd>The domain of your Jabber ID.</dd>
+
+ <dt>XMPP resource</dt>
+ <dd>The resource of your JID. If you leaf this field blank a random resource is generated.</dd>
+
+ <dt>TURN url</dt>
+ <dd>The url to your TURN server. You get a free account on http://numb.viagenie.ca</dd>
+
+ <dt>TURN username</dt>
+ <dd>If no username is set, the TURN REST API is used.</dd>
+
+ <dt>TURN credential</dt>
+ <dd>If no credential is set, the TURN REST API is used.</dd>
+
+ <dt>TURN secret</dt>
+ <dd>Secret for TURN REST API.</dd>
+
+ <dt>TURN ttl</dt>
+ <dd>Lifetime of credentials.</dd>
+</dl>
+
+### Screenshots
+
+![Screenshot 1](https://raw.github.com/sualko/ojsxc/master/documentation/screenshot_1.png)
+![Screenshot 2](https://raw.github.com/sualko/ojsxc/master/documentation/screenshot_2.png)
+![Screenshot 3](https://raw.github.com/sualko/ojsxc/master/documentation/screenshot_3.png)
+
+## Developer notes
+
+Please execude the following commands to get a copy of the code:
+
+```
+git clone https://github.com/sualko/ojsxc/
+git submodule update --init
+```
+
+### Libaries
+- jQuery (http://jquery.com/)
+- Strophe.js (http://strophe.im/strophejs/)
+- Strophe.js Plugins (https://github.com/strophe/strophejs-plugins)
+- OTR (https://github.com/arlolra/otr)
+- strophe.jingle (https://github.com/ESTOS/strophe.jingle)
+
+### Events
+coming soon...
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 4308c90..4f8ebd8 100755
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -3,8 +3,8 @@
<id>ojsxc</id>
<name>JavaScript XMPP Chat</name>
<description>XMPP Chat with OTR</description>
- <version>0.1</version>
- <licence>AGPL</licence>
+ <version>0.4</version>
+ <licence>MIT</licence>
<author>Klaus Herberth</author>
- <require>4</require>
+ <require>6</require>
</info>
diff --git a/appinfo/version b/appinfo/version
index 49d5957..bd73f47 100755
--- a/appinfo/version
+++ b/appinfo/version
@@ -1 +1 @@
-0.1
+0.4
diff --git a/build/appinfo/app.php b/build/appinfo/app.php
index db35529..4660319 100644
--- a/build/appinfo/app.php
+++ b/build/appinfo/app.php
@@ -31,7 +31,7 @@ OCP\Util::addScript ( 'ojsxc', 'otr/build/dep/eventemitter' );
OCP\Util::addScript ( 'ojsxc', 'otr/build/otr' );
OCP\Util::addScript ( 'ojsxc', 'lib/jsxc.lib' );
OCP\Util::addScript ( 'ojsxc', 'lib/jsxc.lib.webrtc' );
-OCP\Util::addScript ( 'ojsxc', 'lib/jsxc.lib.muc' );
+// OCP\Util::addScript ( 'ojsxc', 'lib/jsxc.lib.muc' );
OCP\Util::addScript ( 'ojsxc', 'ojsxc' );
diff --git a/build/appinfo/info.xml b/build/appinfo/info.xml
index 4308c90..4f8ebd8 100644
--- a/build/appinfo/info.xml
+++ b/build/appinfo/info.xml
@@ -3,8 +3,8 @@
<id>ojsxc</id>
<name>JavaScript XMPP Chat</name>
<description>XMPP Chat with OTR</description>
- <version>0.1</version>
- <licence>AGPL</licence>
+ <version>0.4</version>
+ <licence>MIT</licence>
<author>Klaus Herberth</author>
- <require>4</require>
+ <require>6</require>
</info>
diff --git a/build/appinfo/version b/build/appinfo/version
index 49d5957..bd73f47 100644
--- a/build/appinfo/version
+++ b/build/appinfo/version
@@ -1 +1 @@
-0.1
+0.4
diff --git a/build/css/main.css b/build/css/main.css
index c667b8a..d02b510 100644
--- a/build/css/main.css
+++ b/build/css/main.css
@@ -474,7 +474,7 @@ div.jsxc_transfer.jsxc_enc.jsxc_trust{
#jsxc_alt{
text-align:right;
- margin:10px;
+ margin:15px;
opacity:0.5;
font-style:italic;
padding-top:5px;
diff --git a/build/css/webrtc.css b/build/css/webrtc.css
index 4cbc58a..50ef20b 100644
--- a/build/css/webrtc.css
+++ b/build/css/webrtc.css
@@ -73,6 +73,9 @@ div:fullscreen.jsxc_localvideo{
border: 1px solid white;
}
+.jsxc_multi > div{
+ display:none;
+}
.jsxc_snapshotbar{
width:100%;
display:none;
diff --git a/build/js/lib/jsxc.lib.js b/build/js/lib/jsxc.lib.js
index 0c7a51f..1727017 100644
--- a/build/js/lib/jsxc.lib.js
+++ b/build/js/lib/jsxc.lib.js
@@ -6,7 +6,7 @@
*
* @file Mainscript of the javascript xmpp client
* @author Klaus Herberth <klaus@jsxc.org>
- * @version 0.3
+ * @version 0.4
* @requires [1] {@link https://github.com/sualko/strophejs/|Strophe.js}
* @requires [2] {@link https://github.com/arlolra/otr/|OTR}
*/
@@ -41,7 +41,7 @@ var jsxc;
keepalive: null,
/** list of otr objects */
- buddyList: [],
+ buddyList: {},
/** True if last activity was 10 min ago */
restore: false,
@@ -165,8 +165,7 @@ var jsxc;
jsxc.gui.showWaitAlert(jsxc.l.please_wait_until_we_logged_you_in);
- jsxc.options.xmpp.jid = jsxc.options.loginForm.preJid($(jsxc.options.loginForm.jid)
- .val());
+ jsxc.options.xmpp.jid = jsxc.options.loginForm.preJid($(jsxc.options.loginForm.jid).val());
jsxc.options.xmpp.password = $(jsxc.options.loginForm.pass).val();
jsxc.triggeredFromForm = true;
@@ -598,14 +597,7 @@ var jsxc;
*/
jsxc.gui = {
/** Smilie token to file mapping */
- emotions: [
- [ ':-) :)', 'smile.png' ], [ ':-D :D', 'grin.png' ], [ ':-( :(', 'sad.png' ],
- [ ';-) ;)', 'wink.png' ], [ ':-P :P', 'tonguesmile.png' ], [ '=-O', 'surprised.png' ],
- [ ':kiss: :-*', 'kiss.png' ], [ '8-) :cool:', 'sunglassess.png' ],
- [ ':\'-(', 'crysad.png' ], [ ':-/', 'doubt.png' ], [ 'O:-) O:)', 'angel.png' ],
- [ ':-X :X', 'zip.png' ], [ '>:o', 'angry.png' ], [ ':yes:', 'thumbsup.png' ],
- [ ':beer:', 'beer.png' ], [ ':devil:', 'devil.png' ], [ ':kissing:', 'kissing.png' ],
- [ ':love:', 'love.png' ], [ ':zzz:', 'tired.png' ] ],
+ emotions: [ [ ':-) :)', 'smile.png' ], [ ':-D :D', 'grin.png' ], [ ':-( :(', 'sad.png' ], [ ';-) ;)', 'wink.png' ], [ ':-P :P', 'tonguesmile.png' ], [ '=-O', 'surprised.png' ], [ ':kiss: :-*', 'kiss.png' ], [ '8-) :cool:', 'sunglassess.png' ], [ ':\'-(', 'crysad.png' ], [ ':-/', 'doubt.png' ], [ 'O:-) O:)', 'angel.png' ], [ ':-X :X', 'zip.png' ], [ '>:o', 'angry.png' ], [ ':yes:', 'thumbsup.png' ], [ ':beer:', 'beer.png' ], [ ':devil:', 'devil.png' ], [ ':kissing:', 'kissing.png' ], [ ':love:', 'love.png' ], [ ':zzz:', 'tired.png' ] ],
/**
* Creates application skeleton.
@@ -620,7 +612,7 @@ var jsxc;
// prepare regexp for emotions
$.each(jsxc.gui.emotions, function(i, val) {
var reg = val[0].replace(/(\/|\||\*|\.|\+|\?|\^|\$|\(|\)|\[|\]|\{|\})/g, '\\$1');
- reg = '\\(' + reg.split(' ').join('\\)\\|\\(') + '\\)';
+ reg = '(' + reg.split(' ').join(')|(') + ')';
jsxc.gui.emotions[i][2] = new RegExp(reg, 'g');
});
@@ -650,45 +642,40 @@ var jsxc;
ri.data(data);
// Add online status
- ue.removeClass('jsxc_' + jsxc.CONST.STATUS.join(' jsxc_'))
- .addClass('jsxc_' + jsxc.CONST.STATUS[data.status]);
+ ue.removeClass('jsxc_' + jsxc.CONST.STATUS.join(' jsxc_')).addClass('jsxc_' + jsxc.CONST.STATUS[data.status]);
// Change name and add title
- ue.find('.jsxc_name').text(data.name)
- .attr('title', 'is ' + jsxc.CONST.STATUS[data.status]);
+ ue.find('.jsxc_name').text(data.name).attr('title', 'is ' + jsxc.CONST.STATUS[data.status]);
// Update gui according to encryption state
switch (data.msgstate) {
case 0:
- we.find('.jsxc_transfer').removeClass('jsxc_enc jsxc_fin')
- .attr('title', jsxc.l.your_connection_is_unencrypted);
+ we.find('.jsxc_transfer').removeClass('jsxc_enc jsxc_fin').attr('title', jsxc.l.your_connection_is_unencrypted);
we.find('.jsxc_settings .jsxc_verification').addClass('jsxc_disabled');
we.find('.jsxc_settings .jsxc_transfer').text(jsxc.l.start_private);
break;
case 1:
- we.find('.jsxc_transfer').addClass('jsxc_enc')
- .attr('title', jsxc.l.your_connection_is_encrypted);
+ we.find('.jsxc_transfer').addClass('jsxc_enc').attr('title', jsxc.l.your_connection_is_encrypted);
we.find('.jsxc_settings .jsxc_verification').removeClass('jsxc_disabled');
we.find('.jsxc_settings .jsxc_transfer').text(jsxc.l.close_private);
break;
case 2:
we.find('.jsxc_settings .jsxc_verification').addClass('jsxc_disabled');
- we.find('.jsxc_transfer').removeClass('jsxc_enc').addClass('jsxc_fin')
- .attr('title', jsxc.l.your_buddy_closed_the_private_connection);
+ we.find('.jsxc_transfer').removeClass('jsxc_enc').addClass('jsxc_fin').attr('title', jsxc.l.your_buddy_closed_the_private_connection);
we.find('.jsxc_settings .jsxc_transfer').text(jsxc.l.close_private);
break;
}
// update gui according to verification state
if (data.trust) {
- we.find('.jsxc_transfer').addClass('jsxc_trust')
- .attr('title', jsxc.l.your_buddy_is_verificated);
+ we.find('.jsxc_transfer').addClass('jsxc_trust').attr('title', jsxc.l.your_buddy_is_verificated);
+ } else {
+ we.find('.jsxc_transfer').removeClass('jsxc_trust').attr('title', '');
}
// update gui according to subscription state
if (data.sub && data.sub !== 'both') {
- ri.addClass('jsxc_oneway').find('.jsxc_name')
- .attr('title', jsxc.l.you_have_only_a_subscription_in_one_way);
+ ri.addClass('jsxc_oneway').find('.jsxc_name').attr('title', jsxc.l.you_have_only_a_subscription_in_one_way);
} else {
ri.removeClass('jsxc_oneway');
}
@@ -785,7 +772,11 @@ var jsxc;
$('#jsxc_facebox > div:gt(0)').hide();
$('#jsxc_facebox select').change(function() {
$('#jsxc_facebox > div:gt(0)').hide();
- $('#jsxc_facebox > div:eq(' + $(this).prop('selectedIndex') + ')').slideDown();
+ $('#jsxc_facebox > div:eq(' + $(this).prop('selectedIndex') + ')').slideDown({
+ complete: function() {
+ jsxc.gui.dialog.resize();
+ }
+ });
});
// Manual
@@ -1005,7 +996,12 @@ var jsxc;
});
if (confirm) {
- $('#jsxc_dialog .creation').click(confirm);
+ $('#jsxc_dialog .creation').click(function() {
+ confirm.call();
+ jsxc.gui.dialog.open(jsxc.gui.template.get('pleaseAccept'), {
+ noClose: true
+ });
+ });
}
if (dismiss) {
@@ -1063,8 +1059,7 @@ var jsxc;
*/
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');
+ var bud = jsxc.gui.buddyTemplate.clone().attr('id', cid).attr('data-type', data.type || 'chat');
jsxc.gui.roster.insert(cid, bud);
@@ -1107,19 +1102,18 @@ var jsxc;
// Insert buddy with no mutual friendship to the end
var status = (data.sub === 'both') ? data.status : -1;
- listElements
- .each(function() {
+ listElements.each(function() {
- var thisStatus = ($(this).data('sub') === 'both') ? $(this).data('status') : -1;
+ var thisStatus = ($(this).data('sub') === 'both') ? $(this).data('status') : -1;
- if (($(this).data('name').toLowerCase() > data.name.toLowerCase() && thisStatus === status) || thisStatus < status) {
+ if (($(this).data('name').toLowerCase() > data.name.toLowerCase() && thisStatus === status) || thisStatus < status) {
- $(this).before(li);
- insert = true;
+ $(this).before(li);
+ insert = true;
- return false;
- }
- });
+ return false;
+ }
+ });
if (!insert) {
li.appendTo('#jsxc_buddylist');
@@ -1260,11 +1254,9 @@ var jsxc;
$('#jsxc_roster .slimScrollDiv').remove();
$('#jsxc_menu').remove();
- $('#jsxc_roster').append($(document.createElement('p')).text(jsxc.l.no_connection)
- .append($(document.createElement('a')).attr('href', '#').text(jsxc.l.relogin)
- .click(function() {
- jsxc.gui.showLoginBox();
- })));
+ $('#jsxc_roster').append($(document.createElement('p')).text(jsxc.l.no_connection).append($(document.createElement('a')).attr('href', '#').text(jsxc.l.relogin).click(function() {
+ jsxc.gui.showLoginBox();
+ })));
}
};
@@ -1326,6 +1318,13 @@ var jsxc;
close: function() {
jsxc.debug('close dialog');
$.colorbox.close();
+ },
+
+ /**
+ * Resizes current dialog.
+ */
+ resize: function() {
+ $.colorbox.resize();
}
};
@@ -1347,8 +1346,7 @@ var jsxc;
return jsxc.gui.getWindow(cid);
}
- var win = jsxc.gui.windowTemplate.clone().attr('id', 'jsxc_window_' + cid).hide()
- .appendTo('#jsxc_windowList > ul').show('slow');
+ var win = jsxc.gui.windowTemplate.clone().attr('id', 'jsxc_window_' + cid).hide().appendTo('#jsxc_windowList > ul').show('slow');
var data = jsxc.storage.getUserItem('buddy_' + cid);
// Attach jid to window
@@ -1537,7 +1535,7 @@ var jsxc;
win.find('.jsxc_textinput').focus();
- win.trigger('show');
+ win.trigger('show.window.jsxc');
},
/**
@@ -1558,7 +1556,7 @@ var jsxc;
*/
_hide: function(cid) {
$('#jsxc_window_' + cid + ' .jsxc_window').slideUp();
- jsxc.gui.getWindow(cid).trigger('hide');
+ jsxc.gui.getWindow(cid).trigger('hide.window.jsxc');
},
/**
@@ -1666,14 +1664,11 @@ var jsxc;
return '<a href="' + href + '" target="_blank">' + url + '</a>';
});
- $
- .each(jsxc.gui.emotions, function(i, val) {
- msg = msg
- .replace(val[2], '<img alt="$1" title="$1" src="' + jsxc.options.root + '/img/emotions/' + val[1] + '"/>');
- });
+ $.each(jsxc.gui.emotions, function(i, val) {
+ msg = msg.replace(val[2], '<img alt="$1" title="$1" src="' + jsxc.options.root + '/img/emotions/' + val[1] + '"/>');
+ });
- $('#jsxc_window_' + cid + ' .jsxc_textarea')
- .append("<div class='jsxc_chatmessage jsxc_" + direction + "'>" + msg + "</div>");
+ $('#jsxc_window_' + cid + ' .jsxc_textarea').append("<div class='jsxc_chatmessage jsxc_" + direction + "'>" + msg + "</div>");
jsxc.gui.window.scrollDown(cid);
@@ -1741,8 +1736,7 @@ var jsxc;
// common placeholder
var ph = {
- my_priv_fingerprint: jsxc.storage.getUserItem('priv_fingerprint') ? jsxc.storage
- .getUserItem('priv_fingerprint').replace(/(.{8})/g, '$1 ') : jsxc.l.no_available,
+ my_priv_fingerprint: jsxc.storage.getUserItem('priv_fingerprint') ? jsxc.storage.getUserItem('priv_fingerprint').replace(/(.{8})/g, '$1 ') : jsxc.l.no_available,
my_jid: jsxc.storage.getItem('jid'),
root: jsxc.options.root
};
@@ -1751,13 +1745,11 @@ var jsxc;
if (cid) {
var data = jsxc.storage.getUserItem('buddy_' + cid);
- $
- .extend(ph, {
- cid_priv_fingerprint: data.fingerprint ? data.fingerprint
- .replace(/(.{8})/g, '$1 ') : jsxc.l.no_available,
- cid_jid: data.jid,
- cid_name: data.name
- });
+ $.extend(ph, {
+ cid_priv_fingerprint: data.fingerprint ? data.fingerprint.replace(/(.{8})/g, '$1 ') : jsxc.l.no_available,
+ cid_jid: data.jid,
+ cid_name: data.name
+ });
}
// placeholder depending on msg
@@ -1794,7 +1786,7 @@ var jsxc;
<option>%%Secret%%</option>\
</select>\
</div>\
- <div>\
+ <div style="display:none">\
<p class=".jsxc_explanation">%%To_verify_the_fingerprint_%%</p>\
<p><strong>%%Your_fingerprint%%</strong><br />\
<span style="text-transform:uppercase">{{my_priv_fingerprint}}</span></p>\
@@ -1802,13 +1794,13 @@ var jsxc;
<span style="text-transform:uppercase">{{cid_priv_fingerprint}}</span></p><br />\
<p class="jsxc_right"><a href="#" class="jsxc_close button">%%Close%%</a> <a href="#" class="button creation">%%Compared%%</a></p>\
</div>\
- <div>\
+ <div style="display:none">\
<p class=".jsxc_explanation">%%To_authenticate_using_a_question_%%</p>\
<p><label for="jsxc_quest">%%Question%%:</label><input type="text" name="quest" id="jsxc_quest" /></p>\
<p><label for="jsxc_secret2">%%Secret%%:</label><input type="text" name="secret2" id="jsxc_secret2" /></p>\
<p class="jsxc_right"><a href="#" class="button jsxc_close">%%Close%%</a> <a href="#" class="button creation">%%Ask%%</a></p>\
</div>\
- <div>\
+ <div style="display:none">\
<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>\
@@ -1905,7 +1897,8 @@ var jsxc;
<p class="jsxc_right">\
<button class="button jsxc_cancel jsxc_close">%%Dismiss%%</button>\
<button class="button creation">%%Confirm%%</button>\
- </p>'
+ </p>',
+ pleaseAccept: '<p>%%Please_accept_%%</p>'
};
/**
@@ -2641,15 +2634,13 @@ var jsxc;
if (typeof (variable) === 'object') {
- $
- .each(variable, function(key, val) {
- if (typeof (data[key]) === 'undefined') {
- jsxc
- .debug('Variable ' + key + ' doesn\'t exist in ' + variable + '. It was created.');
- }
+ $.each(variable, function(key, val) {
+ if (typeof (data[key]) === 'undefined') {
+ jsxc.debug('Variable ' + key + ' doesn\'t exist in ' + variable + '. It was created.');
+ }
- data[key] = val;
- });
+ data[key] = val;
+ });
} else {
if (typeof (data[variable]) === 'undefined') {
jsxc.debug('Variable ' + variable + ' doesn\'t exist. It was created.');
@@ -2908,9 +2899,7 @@ var jsxc;
// reset timeout
window.clearTimeout(jsxc.to);
- jsxc.to = window
- .setTimeout(jsxc.checkChief, ((key === 'alive') ? jsxc.options.timeout : jsxc.options.busyTimeout) + jsxc
- .random(60));
+ jsxc.to = window.setTimeout(jsxc.checkChief, ((key === 'alive') ? jsxc.options.timeout : jsxc.options.busyTimeout) + jsxc.random(60));
// only call the first time
if (!jsxc.role_allocation) {
@@ -2996,48 +2985,42 @@ var jsxc;
jsxc.buddyList[cid] = new OTR(jsxc.options.otr);
- jsxc.buddyList[cid]
- .on('status', function(status) {
- switch (status) {
- case OTR.CONST.STATUS_SEND_QUERY:
- jsxc.gui.window
- .postMessage(cid, 'sys', jsxc.l.trying_to_start_private_conversation);
- break;
- case OTR.CONST.STATUS_AKE_SUCCESS:
- jsxc.storage
- .updateUserItem('buddy_' + cid, 'fingerprint', jsxc.buddyList[cid].their_priv_pk
- .fingerprint());
- jsxc.storage.updateUserItem('buddy_' + cid, 'msgstate', 1);
- jsxc.gui.window
- .postMessage(cid, 'sys', (jsxc.buddyList[cid].trust ? jsxc.l.Verified : jsxc.l.Unverified) + ' ' + jsxc.l.private_conversation_started);
- break;
- case OTR.CONST.STATUS_END_OTR:
- jsxc.storage.updateUserItem('buddy_' + cid, 'fingerprint', null);
-
- if (jsxc.buddyList[cid].msgstate === 0) { // we
- // abort the private conversation
-
- jsxc.storage.updateUserItem('buddy_' + cid, 'msgstate', 0);
- jsxc.gui.window
- .postMessage(cid, 'sys', jsxc.l.private_conversation_aborted);
-
- } else { // the buddy abort the private conversation
-
- jsxc.storage.updateUserItem('buddy_' + cid, 'msgstate', 2);
- jsxc.gui.window
- .postMessage(cid, 'sys', jsxc.l.your_buddy_closed_the_private_conversation_you_should_do_the_same);
- }
- break;
- case OTR.CONST.STATUS_SMP_HANDLE:
- jsxc.keepBusyAlive();
- break;
+ jsxc.buddyList[cid].on('status', function(status) {
+ switch (status) {
+ case OTR.CONST.STATUS_SEND_QUERY:
+ jsxc.gui.window.postMessage(cid, 'sys', jsxc.l.trying_to_start_private_conversation);
+ break;
+ case OTR.CONST.STATUS_AKE_SUCCESS:
+ jsxc.storage.updateUserItem('buddy_' + cid, 'fingerprint', jsxc.buddyList[cid].their_priv_pk.fingerprint());
+ jsxc.storage.updateUserItem('buddy_' + cid, 'msgstate', 1);
+ jsxc.gui.window.postMessage(cid, 'sys', (jsxc.buddyList[cid].trust ? jsxc.l.Verified : jsxc.l.Unverified) + ' ' + jsxc.l.private_conversation_started);
+ break;
+ case OTR.CONST.STATUS_END_OTR:
+ jsxc.storage.updateUserItem('buddy_' + cid, 'fingerprint', null);
+
+ if (jsxc.buddyList[cid].msgstate === 0) { // we
+ // abort the private conversation
+
+ jsxc.storage.updateUserItem('buddy_' + cid, 'msgstate', 0);
+ jsxc.gui.window.postMessage(cid, 'sys', jsxc.l.private_conversation_aborted);
+
+ } else { // the buddy abort the private conversation
+
+ jsxc.storage.updateUserItem('buddy_' + cid, 'msgstate', 2);
+ jsxc.gui.window.postMessage(cid, 'sys', jsxc.l.your_buddy_closed_the_private_conversation_you_should_do_the_same);
}
+ break;
+ case OTR.CONST.STATUS_SMP_HANDLE:
+ jsxc.keepBusyAlive();
+ break;
+ }
- // for encryption and verification state
- jsxc.gui.update(cid);
- });
+ // for encryption and verification state
+ jsxc.gui.update(cid);
+ });
- jsxc.buddyList[cid].on('smp', function(type, data) {
+ jsxc.buddyList[cid].on('smp', function(type, data, data2) {
+ console.log(type, data, data2);
switch (type) {
case 'question': // verification request received
jsxc.otr.onSmpQuestion(cid, data);
@@ -3046,10 +3029,12 @@ var jsxc;
});
break;
case 'trust': // verification completed
- if (jsxc.buddyList[cid].trust) {
- jsxc.otr.backup(cid);
- jsxc.storage.updateUserItem('buddy_' + cid, 'trust', true);
- jsxc.gui.update(cid);
+ jsxc.buddyList[cid].trust = data;
+ jsxc.storage.updateUserItem('buddy_' + cid, 'trust', data);
+ jsxc.otr.backup(cid);
+ jsxc.gui.update(cid);
+
+ if (data) {
jsxc.gui.window.postMessage(cid, 'sys', jsxc.l.conversation_is_now_verified);
} else {
jsxc.gui.window.postMessage(cid, 'sys', jsxc.l.verification_fails);
@@ -3093,16 +3078,14 @@ var jsxc;
$('#jsxc_facebox select').prop('selectedIndex', (data ? 2 : 3)).change();
$('#jsxc_facebox > div:eq(0)').hide();
+ console.log(data);
+
if (data) {
$('#jsxc_facebox > div:eq(2)').find('#jsxc_quest').val(data).prop('disabled', true);
$('#jsxc_facebox > div:eq(2)').find('.creation').text('Answer');
- $('#jsxc_facebox > div:eq(2)')
- .find('.jsxc_explanation')
- .text(jsxc.l.your_buddy_is_attempting_to_determine_ + ' ' + jsxc.l.to_authenticate_to_your_buddy + jsxc.l.enter_the_answer_and_click_answer);
+ $('#jsxc_facebox > div:eq(2)').find('.jsxc_explanation').text(jsxc.l.your_buddy_is_attempting_to_determine_ + ' ' + jsxc.l.to_authenticate_to_your_buddy + jsxc.l.enter_the_answer_and_click_answer);
} else {
- $('#jsxc_facebox > div:eq(3)')
- .find('.jsxc_explanation')
- .text(jsxc.l.your_buddy_is_attempting_to_determine_ + ' ' + jsxc.l.to_authenticate_to_your_buddy + jsxc.l.enter_the_secret);
+ $('#jsxc_facebox > div:eq(3)').find('.jsxc_explanation').text(jsxc.l.your_buddy_is_attempting_to_determine_ + ' ' + jsxc.l.to_authenticate_to_your_buddy + jsxc.l.enter_the_secret);
}
$('#jsxc_facebox a[rel=close]').click(function() {
@@ -3124,6 +3107,7 @@ var jsxc;
*/
sendSmpReq: function(cid, sec, quest) {
jsxc.keepBusyAlive();
+ console.log("Sec: ", sec);
jsxc.buddyList[cid].smpSecret(sec, quest);
},
@@ -3186,11 +3170,7 @@ var jsxc;
}
// all variables which should be saved
- var savekey = [
- 'our_instance_tag', 'msgstate', 'authstate', 'fragment', 'their_y', 'their_old_y',
- 'their_keyid', 'their_instance_tag', 'our_dh', 'our_old_dh', 'our_keyid',
- 'sessKeys', 'storedMgs', 'oldMacKeys', 'trust', 'transmittedRS', 'ssid',
- 'receivedPlaintext', 'authstate', 'send_interval' ];
+ var savekey = [ 'our_instance_tag', 'msgstate', 'authstate', 'fragment', 'their_y', 'their_old_y', 'their_keyid', 'their_instance_tag', 'our_dh', 'our_old_dh', 'our_keyid', 'sessKeys', 'storedMgs', 'oldMacKeys', 'trust', 'transmittedRS', 'ssid', 'receivedPlaintext', 'authstate', 'send_interval' ];
var i;
for (i = 0; i < savekey.length; i++) {
@@ -3278,14 +3258,7 @@ var jsxc;
// start worker
worker.postMessage({
- imports: [
- jsxc.options.root + '/js/otr/vendor/salsa20.js',
- jsxc.options.root + '/js/otr/vendor/bigint.js',
- jsxc.options.root + '/js/otr/vendor/crypto.js',
- jsxc.options.root + '/js/otr/vendor/eventemitter.js',
- jsxc.options.root + '/js/otr/lib/const.js',
- jsxc.options.root + '/js/otr/lib/helpers.js',
- jsxc.options.root + '/js/otr/lib/dsa.js' ],
+ imports: [ jsxc.options.root + '/js/otr/vendor/salsa20.js', jsxc.options.root + '/js/otr/vendor/bigint.js', jsxc.options.root + '/js/otr/vendor/crypto.js', jsxc.options.root + '/js/otr/vendor/eventemitter.js', jsxc.options.root + '/js/otr/lib/const.js', jsxc.options.root + '/js/otr/lib/helpers.js', jsxc.options.root + '/js/otr/lib/dsa.js' ],
seed: BigInt.getSeed()
});
@@ -3415,6 +3388,10 @@ var jsxc;
}
window.Notification.permission = permission;
+ window.Notification.requestPermission = function(func) {
+ window.webkitNotifications.requestPermission(func);
+ };
+
return true;
} else if (Notification) {
return true;
@@ -3429,7 +3406,7 @@ var jsxc;
*/
prepareRequest: function() {
- $(document).one('message.jsxc', function() {
+ $(document).one('postmessagein.jsxc', function() {
jsxc.switchEvents({
'notificationready.jsxc': function() {
jsxc.gui.dialog.close();
@@ -3442,6 +3419,7 @@ var jsxc;
jsxc.storage.setUserItem('notification', false);
}
});
+
setTimeout(function() {
jsxc.gui.showConfirmDialog(jsxc.translate("%%Should we notify you_%%"), function() {
jsxc.notification.requestPermission();
@@ -3461,7 +3439,7 @@ var jsxc;
window.Notification.permission = status;
}
- if (jsxc.Notification.hasPermission()) {
+ if (jsxc.notification.hasPermission()) {
$(document).trigger('notificationready.jsxc');
} else {
$(document).trigger('notificationfailure.jsxc');
@@ -3556,7 +3534,8 @@ var jsxc;
Retry: 'Retry',
clear_history: 'Clear history',
New_message_from: 'New message from',
- Should_we_notify_you_: 'Should we notify you about new messages in the future?'
+ Should_we_notify_you_: 'Should we notify you about new messages in the future?',
+ Please_accept_: 'Please click the "Allow" button at the top.'
},
de: {
please_wait_until_we_logged_you_in: 'Bitte warte bis wir dich eingeloggt haben.',
diff --git a/build/js/lib/jsxc.lib.webrtc.js b/build/js/lib/jsxc.lib.webrtc.js
index f369f14..41b86c1 100644
--- a/build/js/lib/jsxc.lib.webrtc.js
+++ b/build/js/lib/jsxc.lib.webrtc.js
@@ -4,46 +4,48 @@
*
* @file WebRTC Plugin for the javascript xmpp client
* @author Klaus Herberth
- * @version 0.3
+ * @version 0.4
*/
/* jsxc, Strophe, SDPUtil, getUserMediaWithConstraints, setupRTC, jQuery */
var RTC = null, RTCPeerconnection = null;
-jsxc.gui.template.incomingCall = '<h3>%%Incoming_call%%</h3>\n\
- <p>%%Do_you_want_to_accept_the_call_from%% %%cid_name%%?</p>\n\
- <p class="jsxc_right">\n\
- <a href="#" class="button jsxc_reject">%%Reject%%</a> <a href="#" class="button creation jsxc_accept">%%Accept%%</a>\n\
+jsxc.gui.template.incomingCall = '<h3>%%Incoming_call%%</h3>\
+ <p>%%Do_you_want_to_accept_the_call_from%% {{cid_name}}?</p>\
+ <p class="jsxc_right">\
+ <a href="#" class="button jsxc_reject">%%Reject%%</a> <a href="#" class="button creation jsxc_accept">%%Accept%%</a>\
</p>';
-jsxc.gui.template.allowAccess = '<p>%%Please_allow_access_to_microphone_and_camera%%</p>';
-
-jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
- <div class="jsxc_videoContainer">\n\
- <video class="jsxc_localvideo" autoplay></video>\n\
- <video class="jsxc_remotevideo" autoplay></video>\n\
- <div class="jsxc_status"></div>\n\
- </div>\n\
- <div class="jsxc_controlbar">\n\
- <button type="button" class="jsxc_hangUp">%%hang_up%%</button>\n\
- <input type="range" class="jsxc_volume" min="0.0" max="1.0" step="0.05" value="0.5" />\n\
- <div class="jsxc_buttongroup">\n\
- <button type="button" class="jsxc_snapshot">%%snapshot%%</button><button type="button" class="jsxc_snapshots">&#9660;</button>\n\
- </div>\n\
- <!-- <button type="button" class="jsxc_mute_local">%%mute_my_audio%%</button>\n\
- <button type="button" class="jsxc_pause_local">%%pause_my_video%%</button> --> \n\
- <button type="button" class="jsxc_chat">%%chat%%</button>\n\
- <button type="button" class="jsxc_fullscreen">%%fullscreen%%</button>\n\
- <button type="button" class="jsxc_info">%%Info%%</button>\n\
- </div>\n\
- <div class="jsxc_snapshotbar">\n\
- <p>No pictures yet!</p>\n\
- </div>\n\
- <div class="jsxc_chatarea">\n\
- <ul></ul>\n\
- </div>\n\
- <div class="jsxc_infobar"></div>\n\
+jsxc.gui.template.allowMediaAccess = '<p>%%Please_allow_access_to_microphone_and_camera%%</p>';
+
+jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
+ <div class="jsxc_videoContainer">\
+ <video class="jsxc_localvideo" autoplay></video>\
+ <video class="jsxc_remotevideo" autoplay></video>\
+ <div class="jsxc_status"></div>\
+ </div>\
+ <div class="jsxc_controlbar">\
+ <button type="button" class="jsxc_hangUp">%%hang_up%%</button>\
+ <input type="range" class="jsxc_volume" min="0.0" max="1.0" step="0.05" value="0.5" />\
+ <div class="jsxc_buttongroup">\
+ <button type="button" class="jsxc_snapshot">%%snapshot%%</button><button type="button" class="jsxc_snapshots">&#9660;</button>\
+ </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_fullscreen">%%fullscreen%%</button>\
+ <button type="button" class="jsxc_info">%%Info%%</button>\
+ </div>\
+ <div class="jsxc_multi">\
+ <div class="jsxc_snapshotbar">\
+ <p>No pictures yet!</p>\
+ </div>\n\
+ <div class="jsxc_chatarea">\
+ <ul></ul>\
+ </div>\
+ <div class="jsxc_infobar"></div>\
+ </div>\
</div>';
(function($) {
@@ -249,7 +251,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
*/
setStatus: function(txt, d) {
var status = $('.jsxc_webrtc .jsxc_status');
- var duration = d || 4000;
+ var duration = (typeof d === 'undefined' || d === null) ? 4000 : d;
if (status.html()) {
// attach old messages
@@ -271,6 +273,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
clearTimeout(status.data('timeout'));
if (duration === 0) {
+ console.log('return');
return;
}
@@ -322,12 +325,12 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
var i;
for (i = 0; i < stream.getAudioTracks().length; i++) {
- this.setStatus((stream.getAudioTracks().length > 0) ? 'Use remote audio device.' : 'No remote audio device');
+ self.setStatus((stream.getAudioTracks().length > 0) ? 'Use local audio device.' : 'No local audio device.');
jsxc.debug('using audio device "' + stream.getAudioTracks()[i].label + '"');
}
for (i = 0; i < stream.getVideoTracks().length; i++) {
- this.setStatus((stream.getVideoTracks().length > 0) ? 'Use remote video device.' : 'No remote video device');
+ self.setStatus((stream.getVideoTracks().length > 0) ? 'Use local video device.' : 'No local video device.');
jsxc.debug('using video device "' + stream.getVideoTracks()[i].label + '"');
}
@@ -371,7 +374,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
jsxc.switchEvents({
'mediaready.jingle': function(event, stream) {
- this.setStatus('Accept call');
+ self.setStatus('Accept call');
sess.localStream = stream;
sess.peerconnection.addStream(stream);
@@ -390,7 +393,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
return;
}
- var dialog = jsxc.gui.dialog.open(jsxc.gui.template.get('incomingCall', jid));
+ var dialog = jsxc.gui.dialog.open(jsxc.gui.template.get('incomingCall', jsxc.jidToCid(jid)));
dialog.find('.jsxc_accept').click(function() {
self.reqUserMedia();
@@ -528,7 +531,14 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
}
}
- $('.jsxc_info').attr('title', jsxc.translate('%%Local IP%%: ') + sess.local_ip + '\n' + jsxc.translate('%%Remote IP%%: ') + sess.remote_ip + '\n' + jsxc.translate('%%Local Fingerprint%%: ') + sess.local_fp + '\n' + jsxc.translate('%%Remote Fingerprint%%: ') + sess.remote_fp);
+ var text = '<p>';
+ text += '<b>' + jsxc.translate('%%Local IP%%: ') + '</b>' + sess.local_ip + '<br />';
+ text += '<b>' + jsxc.translate('%%Remote IP%%: ') + '</b>' + sess.remote_ip + '<br />';
+ text += '<b>' + jsxc.translate('%%Local Fingerprint%%: ') + '</b>' + sess.local_fp + '<br />';
+ text += '<b>' + jsxc.translate('%%Remote Fingerprint%%: ') + '</b>' + sess.remote_fp;
+ text += '</p>';
+
+ $('#jsxc_dialog .jsxc_infobar').html(text);
}
},
@@ -584,7 +594,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
this.reqUserMedia();
},
-
+
/**
* Hang up the current call.
*
@@ -593,10 +603,10 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
hangUp: function() {
$(document).off('cleanup.dialog.jsxc');
- this.conn.jingle.terminate();
+ jsxc.webrtc.conn.jingle.terminate(null);
$(document).trigger('callterminated.jingle');
},
-
+
/**
* Request video and audio from local user.
*
@@ -607,17 +617,19 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
$(document).trigger('mediaready.jingle', [ this.localStream ]);
return;
}
-
- jsxc.gui.dialog.open(jsxc.gui.template.get('allowAccess'));
+
+ jsxc.gui.dialog.open(jsxc.gui.template.get('allowMediaAccess'), {
+ noClose: true
+ });
this.setStatus('please allow access to microphone and camera');
-
+
getUserMediaWithConstraints([ 'video', 'audio' ]);
},
-
+
/**
* Make a snapshot from a video stream and display it.
*
- * @memberOf
+ * @memberOf
* @param video Video stream
*/
snapshot: function(video) {
@@ -695,30 +707,44 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
RTC.attachMediaStream(rv, self.remoteStream);
}
+ var toggleMulti = function(elem, open) {
+ $('#jsxc_dialog .jsxc_multi > div').not(elem).slideUp();
+
+ var opt = {
+ complete: jsxc.gui.dialog.resize
+ };
+
+ if (open) {
+ elem.slideDown(opt);
+ } else {
+ elem.slideToggle(opt);
+ }
+ };
+
var win = jsxc.gui.window.open(jsxc.jidToCid(jid));
+ var winId = win.attr('id');
$('#jsxc_dialog .jsxc_chatarea ul').append(win.detach());
- $(document).one('cleanup.dialog.jsxc', function() {
- $('#jsxc_windowList > ul').prepend(win.detach());
- });
-
$('#jsxc_dialog .jsxc_hangUp').click(function() {
+ $('#jsxc_windowList > ul').prepend($('#' + winId).detach());
jsxc.webrtc.hangUp();
});
$('#jsxc_dialog .jsxc_snapshot').click(function() {
jsxc.webrtc.snapshot(rv);
- $('#jsxc_dialog .jsxc_snapshots').click();
+ toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'), true);
});
$('#jsxc_dialog .jsxc_snapshots').click(function() {
- $('#jsxc_dialog .jsxc_chatarea').slideUp();
- $('#jsxc_dialog .jsxc_snapshotbar').slideToggle();
+ toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'));
});
$('#jsxc_dialog .jsxc_chat').click(function() {
- $('#jsxc_dialog .jsxc_snapshotbar').slideUp();
- $('#jsxc_dialog .jsxc_chatarea').slideToggle();
+ toggleMulti($('#jsxc_dialog .jsxc_chatarea'));
+ });
+
+ $('#jsxc_dialog .jsxc_info').click(function() {
+ toggleMulti($('#jsxc_dialog .jsxc_infobar'));
});
$('#jsxc_dialog .jsxc_fullscreen').click(function() {
@@ -730,18 +756,18 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
});
$('#jsxc_dialog .jsxc_videoContainer').fullscreen();
- }
+ }
});
$('#jsxc_dialog .jsxc_volume').change(function() {
rv[0].volume = $(this).val();
});
-
+
$('#jsxc_dialog .jsxc_volume').dblclick(function() {
$(this).val(0.5);
});
});
-
+
jsxc.gui.dialog.open(jsxc.gui.template.get('videoWindow'), {
noClose: true
});
diff --git a/build/js/ojsxc.js b/build/js/ojsxc.js
index 519ceff..bd38b06 100644
--- a/build/js/ojsxc.js
+++ b/build/js/ojsxc.js
@@ -3,7 +3,7 @@
* Released under the MIT license
*
* @author Klaus Herberth
- * @version 0.3
+ * @version 0.4
*/
/* global jsxc, oc_appswebroots, OC, $ */
@@ -96,6 +96,10 @@ $(function() {
turnCredentialsPath: OC.filePath('ojsxc', 'ajax', 'getturncredentials.php'),
displayRosterMinimized: function() {
return OC.currentUser != null;
+ },
+ otr: {
+ SEND_WHITESPACE_TAG: true,
+ WHITESPACE_START_AKE: true
}
});
diff --git a/css/webrtc.css b/css/webrtc.css
index 4cbc58a..50ef20b 100644
--- a/css/webrtc.css
+++ b/css/webrtc.css
@@ -73,6 +73,9 @@ div:fullscreen.jsxc_localvideo{
border: 1px solid white;
}
+.jsxc_multi > div{
+ display:none;
+}
.jsxc_snapshotbar{
width:100%;
display:none;
diff --git a/documentation/screenshot_1.png b/documentation/screenshot_1.png
new file mode 100644
index 0000000..6e1fead
--- /dev/null
+++ b/documentation/screenshot_1.png
Binary files differ
diff --git a/documentation/screenshot_2.png b/documentation/screenshot_2.png
new file mode 100644
index 0000000..3790a6c
--- /dev/null
+++ b/documentation/screenshot_2.png
Binary files differ
diff --git a/documentation/screenshot_3.png b/documentation/screenshot_3.png
new file mode 100644
index 0000000..d381676
--- /dev/null
+++ b/documentation/screenshot_3.png
Binary files differ
diff --git a/js/lib/jsxc.lib.js b/js/lib/jsxc.lib.js
index 4530bcf..1727017 100755
--- a/js/lib/jsxc.lib.js
+++ b/js/lib/jsxc.lib.js
@@ -6,7 +6,7 @@
*
* @file Mainscript of the javascript xmpp client
* @author Klaus Herberth <klaus@jsxc.org>
- * @version 0.3
+ * @version 0.4
* @requires [1] {@link https://github.com/sualko/strophejs/|Strophe.js}
* @requires [2] {@link https://github.com/arlolra/otr/|OTR}
*/
diff --git a/js/lib/jsxc.lib.webrtc.js b/js/lib/jsxc.lib.webrtc.js
index 192e4c7..41b86c1 100644
--- a/js/lib/jsxc.lib.webrtc.js
+++ b/js/lib/jsxc.lib.webrtc.js
@@ -4,46 +4,48 @@
*
* @file WebRTC Plugin for the javascript xmpp client
* @author Klaus Herberth
- * @version 0.3
+ * @version 0.4
*/
/* jsxc, Strophe, SDPUtil, getUserMediaWithConstraints, setupRTC, jQuery */
var RTC = null, RTCPeerconnection = null;
-jsxc.gui.template.incomingCall = '<h3>%%Incoming_call%%</h3>\n\
- <p>%%Do_you_want_to_accept_the_call_from%% {{cid_name}}?</p>\n\
- <p class="jsxc_right">\n\
- <a href="#" class="button jsxc_reject">%%Reject%%</a> <a href="#" class="button creation jsxc_accept">%%Accept%%</a>\n\
+jsxc.gui.template.incomingCall = '<h3>%%Incoming_call%%</h3>\
+ <p>%%Do_you_want_to_accept_the_call_from%% {{cid_name}}?</p>\
+ <p class="jsxc_right">\
+ <a href="#" class="button jsxc_reject">%%Reject%%</a> <a href="#" class="button creation jsxc_accept">%%Accept%%</a>\
</p>';
jsxc.gui.template.allowMediaAccess = '<p>%%Please_allow_access_to_microphone_and_camera%%</p>';
-jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
- <div class="jsxc_videoContainer">\n\
- <video class="jsxc_localvideo" autoplay></video>\n\
- <video class="jsxc_remotevideo" autoplay></video>\n\
- <div class="jsxc_status"></div>\n\
- </div>\n\
- <div class="jsxc_controlbar">\n\
- <button type="button" class="jsxc_hangUp">%%hang_up%%</button>\n\
- <input type="range" class="jsxc_volume" min="0.0" max="1.0" step="0.05" value="0.5" />\n\
- <div class="jsxc_buttongroup">\n\
- <button type="button" class="jsxc_snapshot">%%snapshot%%</button><button type="button" class="jsxc_snapshots">&#9660;</button>\n\
- </div>\n\
- <!-- <button type="button" class="jsxc_mute_local">%%mute_my_audio%%</button>\n\
- <button type="button" class="jsxc_pause_local">%%pause_my_video%%</button> --> \n\
- <button type="button" class="jsxc_chat">%%chat%%</button>\n\
- <button type="button" class="jsxc_fullscreen">%%fullscreen%%</button>\n\
- <button type="button" class="jsxc_info">%%Info%%</button>\n\
- </div>\n\
- <div class="jsxc_snapshotbar">\n\
- <p>No pictures yet!</p>\n\
- </div>\n\
- <div class="jsxc_chatarea">\n\
- <ul></ul>\n\
- </div>\n\
- <div class="jsxc_infobar"></div>\n\
+jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
+ <div class="jsxc_videoContainer">\
+ <video class="jsxc_localvideo" autoplay></video>\
+ <video class="jsxc_remotevideo" autoplay></video>\
+ <div class="jsxc_status"></div>\
+ </div>\
+ <div class="jsxc_controlbar">\
+ <button type="button" class="jsxc_hangUp">%%hang_up%%</button>\
+ <input type="range" class="jsxc_volume" min="0.0" max="1.0" step="0.05" value="0.5" />\
+ <div class="jsxc_buttongroup">\
+ <button type="button" class="jsxc_snapshot">%%snapshot%%</button><button type="button" class="jsxc_snapshots">&#9660;</button>\
+ </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_fullscreen">%%fullscreen%%</button>\
+ <button type="button" class="jsxc_info">%%Info%%</button>\
+ </div>\
+ <div class="jsxc_multi">\
+ <div class="jsxc_snapshotbar">\
+ <p>No pictures yet!</p>\
+ </div>\n\
+ <div class="jsxc_chatarea">\
+ <ul></ul>\
+ </div>\
+ <div class="jsxc_infobar"></div>\
+ </div>\
</div>';
(function($) {
@@ -249,7 +251,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
*/
setStatus: function(txt, d) {
var status = $('.jsxc_webrtc .jsxc_status');
- var duration = (typeof d === 'undefined' || d === null)? 4000: d;
+ var duration = (typeof d === 'undefined' || d === null) ? 4000 : d;
if (status.html()) {
// attach old messages
@@ -270,7 +272,8 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
clearTimeout(status.data('timeout'));
- if (duration === 0) { console.log('return');
+ if (duration === 0) {
+ console.log('return');
return;
}
@@ -528,7 +531,14 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
}
}
- $('.jsxc_info').attr('title', jsxc.translate('%%Local IP%%: ') + sess.local_ip + '\n' + jsxc.translate('%%Remote IP%%: ') + sess.remote_ip + '\n' + jsxc.translate('%%Local Fingerprint%%: ') + sess.local_fp + '\n' + jsxc.translate('%%Remote Fingerprint%%: ') + sess.remote_fp);
+ var text = '<p>';
+ text += '<b>' + jsxc.translate('%%Local IP%%: ') + '</b>' + sess.local_ip + '<br />';
+ text += '<b>' + jsxc.translate('%%Remote IP%%: ') + '</b>' + sess.remote_ip + '<br />';
+ text += '<b>' + jsxc.translate('%%Local Fingerprint%%: ') + '</b>' + sess.local_fp + '<br />';
+ text += '<b>' + jsxc.translate('%%Remote Fingerprint%%: ') + '</b>' + sess.remote_fp;
+ text += '</p>';
+
+ $('#jsxc_dialog .jsxc_infobar').html(text);
}
},
@@ -584,7 +594,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
this.reqUserMedia();
},
-
+
/**
* Hang up the current call.
*
@@ -596,7 +606,7 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
jsxc.webrtc.conn.jingle.terminate(null);
$(document).trigger('callterminated.jingle');
},
-
+
/**
* Request video and audio from local user.
*
@@ -607,19 +617,19 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
$(document).trigger('mediaready.jingle', [ this.localStream ]);
return;
}
-
+
jsxc.gui.dialog.open(jsxc.gui.template.get('allowMediaAccess'), {
noClose: true
});
this.setStatus('please allow access to microphone and camera');
-
+
getUserMediaWithConstraints([ 'video', 'audio' ]);
},
-
+
/**
* Make a snapshot from a video stream and display it.
*
- * @memberOf
+ * @memberOf
* @param video Video stream
*/
snapshot: function(video) {
@@ -697,30 +707,44 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
RTC.attachMediaStream(rv, self.remoteStream);
}
+ var toggleMulti = function(elem, open) {
+ $('#jsxc_dialog .jsxc_multi > div').not(elem).slideUp();
+
+ var opt = {
+ complete: jsxc.gui.dialog.resize
+ };
+
+ if (open) {
+ elem.slideDown(opt);
+ } else {
+ elem.slideToggle(opt);
+ }
+ };
+
var win = jsxc.gui.window.open(jsxc.jidToCid(jid));
+ var winId = win.attr('id');
$('#jsxc_dialog .jsxc_chatarea ul').append(win.detach());
- $(document).one('cleanup.dialog.jsxc', function() {
- $('#jsxc_windowList > ul').prepend(win.detach());
- });
-
$('#jsxc_dialog .jsxc_hangUp').click(function() {
+ $('#jsxc_windowList > ul').prepend($('#' + winId).detach());
jsxc.webrtc.hangUp();
});
$('#jsxc_dialog .jsxc_snapshot').click(function() {
jsxc.webrtc.snapshot(rv);
- $('#jsxc_dialog .jsxc_snapshots').click();
+ toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'), true);
});
$('#jsxc_dialog .jsxc_snapshots').click(function() {
- $('#jsxc_dialog .jsxc_chatarea').slideUp();
- $('#jsxc_dialog .jsxc_snapshotbar').slideToggle();
+ toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'));
});
$('#jsxc_dialog .jsxc_chat').click(function() {
- $('#jsxc_dialog .jsxc_snapshotbar').slideUp();
- $('#jsxc_dialog .jsxc_chatarea').slideToggle();
+ toggleMulti($('#jsxc_dialog .jsxc_chatarea'));
+ });
+
+ $('#jsxc_dialog .jsxc_info').click(function() {
+ toggleMulti($('#jsxc_dialog .jsxc_infobar'));
});
$('#jsxc_dialog .jsxc_fullscreen').click(function() {
@@ -732,18 +756,18 @@ jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\n\
});
$('#jsxc_dialog .jsxc_videoContainer').fullscreen();
- }
+ }
});
$('#jsxc_dialog .jsxc_volume').change(function() {
rv[0].volume = $(this).val();
});
-
+
$('#jsxc_dialog .jsxc_volume').dblclick(function() {
$(this).val(0.5);
});
});
-
+
jsxc.gui.dialog.open(jsxc.gui.template.get('videoWindow'), {
noClose: true
});
diff --git a/js/ojsxc.js b/js/ojsxc.js
index 519ceff..bd38b06 100644
--- a/js/ojsxc.js
+++ b/js/ojsxc.js
@@ -3,7 +3,7 @@
* Released under the MIT license
*
* @author Klaus Herberth
- * @version 0.3
+ * @version 0.4
*/
/* global jsxc, oc_appswebroots, OC, $ */
@@ -96,6 +96,10 @@ $(function() {
turnCredentialsPath: OC.filePath('ojsxc', 'ajax', 'getturncredentials.php'),
displayRosterMinimized: function() {
return OC.currentUser != null;
+ },
+ otr: {
+ SEND_WHITESPACE_TAG: true,
+ WHITESPACE_START_AKE: true
}
});