Browse Source

Merge branch 'release-0.23'

pull/175/head v0.23.3
Simon Eisenmann 11 years ago
parent
commit
3324a6fc08
  1. 19
      debian/changelog
  2. 5
      server.conf.in
  3. 5
      static/js/controllers/usersettingscontroller.js
  4. 1
      static/js/directives/page.js
  5. 2
      static/js/directives/presentation.js
  6. 9
      static/js/directives/roombar.js
  7. 2
      static/js/directives/settings.js
  8. 61
      static/js/libs/pdf/compatibility.js
  9. 1514
      static/js/libs/pdf/pdf.js
  10. 10600
      static/js/libs/pdf/pdf.worker.js
  11. 27
      static/js/mediastream/webrtc.js
  12. 34
      static/js/services/rooms.js
  13. 2
      static/partials/chatroom.html
  14. 2
      static/partials/page/welcome.html
  15. 7
      static/partials/roombar.html

19
debian/changelog vendored

@ -1,3 +1,22 @@ @@ -1,3 +1,22 @@
spreed-webrtc-server (0.23.3) precise; urgency=low
* Improved room bar room change and leave buttons.
* Never hide room bar completely.
* Stay in prior room when join fails.
* Stay in prior room when PIN prompt was aborted.
* Updated to PDF.js 1.0.907.
* Enhanced example CSP to support for PDF and WebODF presentations.
* Fixed Firefox screen sharing interop.
* Fixed Firefox file transfer interop.
* Fixed peer connection to create and offer when user media failed.
* Only show room bar when there is no peer.
* Hide welcome screen when there is a peer.
* Avoid dead ends in room join UI when connection is lost and reestablished.
* Avoid showing settings automatically when not connected or still in authorizing phase.
* Added some missing CSS classes to allow easier UI mods.
-- Simon Eisenmann <simon@struktur.de> Fri, 19 Dec 2014 17:15:10 +0100
spreed-webrtc-server (0.23.2) precise; urgency=low
* Do not build combined Javascript in strict mode to avoid compatibility issues.

5
server.conf.in

@ -107,8 +107,9 @@ serverRealm = local @@ -107,8 +107,9 @@ serverRealm = local
; The currently recommended CSP is:
; default-src 'self';
; style-src 'self' 'unsafe-inline';
; img-src 'self' data:;
; connect-src 'self' wss://server:port/ws;
; img-src 'self' data: blob:;
; connect-src 'self' wss://server:port/ws blob:;
; font-src 'self' data: blob:;
;contentSecurityPolicy =
; Content-Security-Policy-Report-Only HTTP response header value. Use this
; to test your CSP before putting it into production.

5
static/js/controllers/usersettingscontroller.js

@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
define([], function() {
// UsersettingsController
return ["$scope", "$element", "mediaStream", "safeApply", function($scope, $element, mediaStream, safeApply) {
return ["$scope", "$element", "mediaStream", "safeApply", "$window", function($scope, $element, mediaStream, safeApply, $window) {
$scope.withUsersForget = true;
@ -65,7 +65,10 @@ define([], function() { @@ -65,7 +65,10 @@ define([], function() {
this.forgetUserid = function() {
mediaStream.users.forget();
mediaStream.webrtc.doHangup("forgetUserid");
$window.setTimeout(function() {
mediaStream.connector.forgetAndReconnect();
}, 0);
};
}];

1
static/js/directives/page.js

@ -33,6 +33,7 @@ define(['text!partials/page.html', 'text!partials/page/welcome.html'], function( @@ -33,6 +33,7 @@ define(['text!partials/page.html', 'text!partials/page/welcome.html'], function(
});
$scope.$on("room.random", function(ev, roomdata) {
// Show welcome page on room random events.
$scope.layout.roombar = false;
$timeout(function() {
$scope.page = "page/welcome.html";
});

2
static/js/directives/presentation.js

@ -429,7 +429,7 @@ define(['jquery', 'underscore', 'text!partials/presentation.html', 'bigscreen'], @@ -429,7 +429,7 @@ define(['jquery', 'underscore', 'text!partials/presentation.html', 'bigscreen'],
};
var connector = function(token, peercall) {
console.log("XXX connector", token, peercall, peers);
//console.log("XXX connector", token, peercall, peers);
if (peers.hasOwnProperty(peercall.id)) {
// Already got a connection.
return;

9
static/js/directives/roombar.js

@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
define(['underscore', 'angular', 'text!partials/roombar.html'], function(_, angular, template) {
// roomBar
return ["$window", "rooms", function($window, rooms) {
return ["$window", "rooms", "$timeout", function($window, rooms, $timeout) {
var link = function($scope, $element) {
@ -33,7 +33,7 @@ define(['underscore', 'angular', 'text!partials/roombar.html'], function(_, angu @@ -33,7 +33,7 @@ define(['underscore', 'angular', 'text!partials/roombar.html'], function(_, angu
};
//console.log("roomBar directive link", arguments);
$scope.layout.roombar = true;
//$scope.layout.roombar = true;
$scope.save = function() {
if ($scope.roombarform.$invalid) {
@ -52,6 +52,9 @@ define(['underscore', 'angular', 'text!partials/roombar.html'], function(_, angu @@ -52,6 +52,9 @@ define(['underscore', 'angular', 'text!partials/roombar.html'], function(_, angu
$scope.$on("room.updated", function(ev, room) {
$scope.currentRoomName = $scope.newRoomName = room.Name;
if ($scope.currentRoomName && !$scope.peer) {
$scope.layout.roombar = true;
}
});
$scope.$on("room.left", clearRoomName);
@ -63,8 +66,10 @@ define(['underscore', 'angular', 'text!partials/roombar.html'], function(_, angu @@ -63,8 +66,10 @@ define(['underscore', 'angular', 'text!partials/roombar.html'], function(_, angu
});
$scope.$watch("layout.roombar", function(value) {
$timeout(function() {
$element.find("input").focus();
});
});
$scope.$watch("peer", function(peer) {
$scope.layout.roombar = !peer;

2
static/js/directives/settings.js

@ -146,7 +146,7 @@ define(['jquery', 'underscore', 'text!partials/settings.html'], function($, _, t @@ -146,7 +146,7 @@ define(['jquery', 'underscore', 'text!partials/settings.html'], function($, _, t
});
$scope.maybeShowSettings = function() {
if ($scope.autoshowSettings) {
if ($scope.autoshowSettings && mediaStream.connector.connected && !appData.authorizing()) {
$scope.autoshowSettings = false;
if (!$scope.loadedUser) {
$scope.layout.settings = true;

61
static/js/libs/pdf/compatibility.js

@ -167,26 +167,40 @@ if (typeof PDFJS === 'undefined') { @@ -167,26 +167,40 @@ if (typeof PDFJS === 'undefined') {
// The worker will be using XHR, so we can save time and disable worker.
PDFJS.disableWorker = true;
Object.defineProperty(xhrPrototype, 'responseType', {
get: function xmlHttpRequestGetResponseType() {
return this._responseType || 'text';
},
set: function xmlHttpRequestSetResponseType(value) {
if (value === 'text' || value === 'arraybuffer') {
this._responseType = value;
if (value === 'arraybuffer' &&
typeof this.overrideMimeType === 'function') {
this.overrideMimeType('text/plain; charset=x-user-defined');
}
}
}
});
// Support: IE9
if (typeof VBArray !== 'undefined') {
Object.defineProperty(xhrPrototype, 'response', {
get: function xmlHttpRequestResponseGet() {
if (this.responseType === 'arraybuffer') {
return new Uint8Array(new VBArray(this.responseBody).toArray());
} else {
return this.responseText;
}
}
});
return;
}
// other browsers
function responseTypeSetter() {
// will be only called to set "arraybuffer"
this.overrideMimeType('text/plain; charset=x-user-defined');
}
if (typeof xhr.overrideMimeType === 'function') {
Object.defineProperty(xhrPrototype, 'responseType',
{ set: responseTypeSetter });
Object.defineProperty(xhrPrototype, 'response', {
get: function xmlHttpRequestResponseGet() {
if (this.responseType !== 'arraybuffer') {
return this.responseText;
}
function responseGetter() {
var text = this.responseText;
var i, n = text.length;
var result = new Uint8Array(n);
@ -195,7 +209,7 @@ if (typeof PDFJS === 'undefined') { @@ -195,7 +209,7 @@ if (typeof PDFJS === 'undefined') {
}
return result.buffer;
}
Object.defineProperty(xhrPrototype, 'response', { get: responseGetter });
});
})();
// window.btoa (base64 encode function) ?
@ -237,7 +251,7 @@ if (typeof PDFJS === 'undefined') { @@ -237,7 +251,7 @@ if (typeof PDFJS === 'undefined') {
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
window.atob = function (input) {
input = input.replace(/=+$/, '');
if (input.length % 4 == 1) {
if (input.length % 4 === 1) {
throw new Error('bad atob input');
}
for (
@ -293,7 +307,7 @@ if (typeof PDFJS === 'undefined') { @@ -293,7 +307,7 @@ if (typeof PDFJS === 'undefined') {
var dataset = {};
for (var j = 0, jj = this.attributes.length; j < jj; j++) {
var attribute = this.attributes[j];
if (attribute.name.substring(0, 5) != 'data-') {
if (attribute.name.substring(0, 5) !== 'data-') {
continue;
}
var key = attribute.name.substring(5).replace(/\-([a-z])/g,
@ -416,7 +430,7 @@ if (typeof PDFJS === 'undefined') { @@ -416,7 +430,7 @@ if (typeof PDFJS === 'undefined') {
function isDisabled(node) {
return node.disabled || (node.parentNode && isDisabled(node.parentNode));
}
if (navigator.userAgent.indexOf('Opera') != -1) {
if (navigator.userAgent.indexOf('Opera') !== -1) {
// use browser detection since we cannot feature-check this bug
document.addEventListener('click', ignoreIfTargetDisabled, true);
}
@ -467,6 +481,7 @@ if (typeof PDFJS === 'undefined') { @@ -467,6 +481,7 @@ if (typeof PDFJS === 'undefined') {
if (isSafari || isOldAndroid) {
PDFJS.disableRange = true;
PDFJS.disableStream = true;
}
})();
@ -481,7 +496,7 @@ if (typeof PDFJS === 'undefined') { @@ -481,7 +496,7 @@ if (typeof PDFJS === 'undefined') {
}
})();
// Support: IE<11, Chrome<21, Android<4.4
// Support: IE<11, Chrome<21, Android<4.4, Safari<6
(function checkSetPresenceInImageData() {
// IE < 11 will use window.CanvasPixelArray which lacks set function.
if (window.CanvasPixelArray) {
@ -495,21 +510,21 @@ if (typeof PDFJS === 'undefined') { @@ -495,21 +510,21 @@ if (typeof PDFJS === 'undefined') {
} else {
// Old Chrome and Android use an inaccessible CanvasPixelArray prototype.
// Because we cannot feature detect it, we rely on user agent parsing.
var polyfill = false;
var polyfill = false, versionMatch;
if (navigator.userAgent.indexOf('Chrom') >= 0) {
var versionMatch = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
if (versionMatch && parseInt(versionMatch[2]) < 21) {
versionMatch = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
// Chrome < 21 lacks the set function.
polyfill = true;
}
polyfill = versionMatch && parseInt(versionMatch[2]) < 21;
} else if (navigator.userAgent.indexOf('Android') >= 0) {
// Android < 4.4 lacks the set function.
// Android >= 4.4 will contain Chrome in the user agent,
// thus pass the Chrome check above and not reach this block.
var isOldAndroid = /Android\s[0-4][^\d]/g.test(navigator.userAgent);
if (isOldAndroid) {
polyfill = true;
}
polyfill = /Android\s[0-4][^\d]/g.test(navigator.userAgent);
} else if (navigator.userAgent.indexOf('Safari') >= 0) {
versionMatch = navigator.userAgent.
match(/Version\/([0-9]+)\.([0-9]+)\.([0-9]+) Safari\//);
// Safari < 6 lacks the set function.
polyfill = versionMatch && parseInt(versionMatch[1]) < 6;
}
if (polyfill) {

1514
static/js/libs/pdf/pdf.js

File diff suppressed because it is too large Load Diff

10600
static/js/libs/pdf/pdf.worker.js vendored

File diff suppressed because it is too large Load Diff

27
static/js/mediastream/webrtc.js

@ -487,17 +487,12 @@ function($, _, PeerCall, PeerConference, PeerXfer, PeerScreenshare, UserMedia, u @@ -487,17 +487,12 @@ function($, _, PeerCall, PeerConference, PeerXfer, PeerScreenshare, UserMedia, u
// Connect.
xfer.setInitiate(true);
xfer.createPeerConnection(_.bind(function() {
xfer.createPeerConnection(_.bind(function(pc) {
xfer.e.on("negotiationNeeded", _.bind(function(event, currentxfer) {
this.sendOfferWhenNegotiationNeeded(currentxfer, id);
}, this));
_.defer(pc.negotiationNeeded);
}, this));
/*
xfer.createOffer(_.bind(function(sessionDescription, currentxfer) {
console.log("Sending xfer offer with sessionDescription", sessionDescription, currentxfer.id);
// TODO(longsleep): Support sending this through data channel too if we have one.
this.api.sendOffer(id, sessionDescription);
}, this));*/
};
@ -563,17 +558,12 @@ function($, _, PeerCall, PeerConference, PeerXfer, PeerScreenshare, UserMedia, u @@ -563,17 +558,12 @@ function($, _, PeerCall, PeerConference, PeerXfer, PeerScreenshare, UserMedia, u
// Connect.
peerscreenshare.setInitiate(true); //XXX(longsleep): This creates a data channel which is not needed.
peerscreenshare.createPeerConnection(_.bind(function() {
peerscreenshare.createPeerConnection(_.bind(function(pc) {
peerscreenshare.e.on("negotiationNeeded", _.bind(function(event, currentscreenshare) {
this.sendOfferWhenNegotiationNeeded(currentscreenshare, id);
}, this));
_.defer(pc.negotiationNeeded);
}, this));
/*
peerscreenshare.createOffer(_.bind(function(sessionDescription, currentscreenshare) {
console.log("Sending screen share offer with sessionDescription", sessionDescription, currentscreenshare.id);
// TODO(longsleep): Support sending this through data channel too if we have one.
this.api.sendOffer(id, sessionDescription);
}, this));*/
};
@ -653,14 +643,11 @@ function($, _, PeerCall, PeerConference, PeerXfer, PeerScreenshare, UserMedia, u @@ -653,14 +643,11 @@ function($, _, PeerCall, PeerConference, PeerXfer, PeerScreenshare, UserMedia, u
this.usermedia.applyAudioMute(this.audioMute);
this.e.triggerHandler("usermedia", [this.usermedia]);
this.usermedia.addToPeerConnection(peerconnection);
} else {
_.defer(peerconnection.negotiationNeeded);
}
this.started = true;
if (this.initiator) {
/*currentcall.createOffer(_.bind(function(sessionDescription, currentcall) {
console.log("Sending offer with sessionDescription", sessionDescription, currentcall.id);
this.api.sendOffer(currentcall.id, sessionDescription);
}, this));*/
} else {
if (!this.initiator) {
this.calleeStart();
}
currentcall.e.on("negotiationNeeded", _.bind(function(event, currentcall) {

34
static/js/services/rooms.js

@ -30,6 +30,7 @@ define([ @@ -30,6 +30,7 @@ define([
var url = restURL.api("rooms");
var requestedRoomName = "";
var priorRoomName = null;
var helloedRoomName = null;
var currentRoom = null;
var randomRoom = null;
@ -49,7 +50,7 @@ define([ @@ -49,7 +50,7 @@ define([
roompin.requestInteractively(requestedRoomName).then(joinRequestedRoom,
function() {
console.log("Authentication cancelled, try a different room.");
rooms.joinDefault();
rooms.joinPriorOrDefault(true);
});
break;
case "authorization_not_required":
@ -58,11 +59,8 @@ define([ @@ -58,11 +59,8 @@ define([
break;
case "room_join_requires_account":
console.log("Room join requires a logged in user.");
alertify.dialog.notify("", translation._("Please sign in to create rooms."), function() {
rooms.joinDefault();
}, function() {
rooms.joinDefault();
});
alertify.dialog.notify("", translation._("Please sign in to create rooms."));
rooms.joinPriorOrDefault(true);
break;
default:
console.log("Unknown error", error, "while joining room ", requestedRoomName);
@ -71,20 +69,24 @@ define([ @@ -71,20 +69,24 @@ define([
};
var joinRequestedRoom = function() {
if (appData.authorizing()) {
// Do nothing while authorizing.
if (!connector.connected || appData.authorizing()) {
// Do nothing while not connected or authorizing.
return;
}
if (!connector.connected || !currentRoom || requestedRoomName !== currentRoom.Name) {
if (!currentRoom || requestedRoomName !== currentRoom.Name) {
requestedRoomName = requestedRoomName ? requestedRoomName : "";
if (helloedRoomName !== requestedRoomName) {
console.log("Joining room", [requestedRoomName]);
helloedRoomName = requestedRoomName;
api.sendHello(requestedRoomName, roompin.get(requestedRoomName), function(room) {
var myHelloedRoomName = helloedRoomName;
_.defer(function() {
if (helloedRoomName === myHelloedRoomName) {
helloedRoomName = null;
}
});
console.log("Joining room", [requestedRoomName]);
api.sendHello(requestedRoomName, roompin.get(requestedRoomName), function(room) {
setCurrentRoom(room);
}, function(error) {
helloedRoomName = null;
joinFailed(error);
});
}
@ -98,6 +100,7 @@ define([ @@ -98,6 +100,7 @@ define([
var priorRoom = currentRoom;
currentRoom = room;
if (priorRoom) {
priorRoomName = priorRoom.Name;
console.log("Left room", priorRoom.Name);
$rootScope.$broadcast("room.left", priorRoom.Name);
}
@ -219,6 +222,13 @@ define([ @@ -219,6 +222,13 @@ define([
joinDefault: function(replace) {
return rooms.joinByName("", replace);
},
joinPriorOrDefault: function(replace) {
if (!priorRoomName || requestedRoomName === priorRoomName) {
rooms.joinDefault(replace);
} else {
rooms.joinByName(priorRoomName, replace);
}
},
link: function(room) {
var name = room ? room.Name : null;
if (!name) {

2
static/partials/chatroom.html

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
<div class="btn-group">
<button ng-if="!isgroupchat" class="btn btn-sm btn-primary" title="{{_('Start video call')}}" ng-click="doCall()"><i class="fa fa-phone fa-fw"></i></button>
<button class="btn btn-sm btn-primary btn-fileupload" title="{{_('Upload files')}}"><i class="fa fa-upload fa-fw"></i></button>
<button class="btn btn-sm btn-primary" title="{{_('Share my location')}}" ng-click="shareGeolocation()"><i class="fa fa-location-arrow fa-fw"></i></button>
<button class="btn btn-sm btn-primary btn-locationshare" title="{{_('Share my location')}}" ng-click="shareGeolocation()"><i class="fa fa-location-arrow fa-fw"></i></button>
</div>
<div class="btn-group pull-right">
<button class="btn btn-sm btn-default" title="{{_('Clear chat')}}" ng-click="doClear()"><i class="fa fa-eraser fa-fw"></i></button>

2
static/partials/page/welcome.html

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<div welcome ng-form="welcome" class="welcome container-fluid">
<div welcome ng-form="welcome" class="welcome container-fluid" ng-show="!peer">
<div class="welcome-logo"></div>
<div class="welcome-container" ng-controller="UsersettingsController as usersettings">
<h1>{{_("Enter a room name")}}</h1>

7
static/partials/roombar.html

@ -1,10 +1,13 @@ @@ -1,10 +1,13 @@
<div class="roombar overlaybar form-horizontal" ng-hide="currentRoomName===null" ng-class="{notvisible: !layout.roombar}">
<div class="roombar overlaybar form-horizontal" ng-class="{notvisible: !layout.roombar}">
<a class="overlaybar-button" ng-model="layout.roombar" btn-checkbox btn-checkbox-true="true" btn-checkbox-false="false" title="{{_('Change room')}}"><i class="fa fa-pencil-square-o"></i></a>
<form name="roombarform" class="overlaybar-content form-group">
<label class="pull-left control-label hidden-xs">{{_('Room')}}</label>
<div class="pull-left">
<span ng-if="currentRoomName"><a class="btn btn-danger btn-sm" title="{{_('Leave room')}}" ng-click="exit()"><i class="fa fa-sign-out"></i></a></span>
</div>
<div class="pull-left">
<div class="input-group">
<input class="form-control input-sm" ng-model="newRoomName" ng-maxlength="30" on-enter="save()" type="text" placeholder="{{_('Main')}}"></input><span ng-if="currentRoomName && roombarform.$pristine" class="input-group-btn"><a class="btn btn-default btn-sm" title="{{_('Leave room')}}" ng-click="exit()"><i class="fa fa-sign-out"></i></a></span><span ng-if="!currentRoomName || !roombarform.$pristine" class="input-group-btn"><a class="btn btn-default btn-sm" title="{{_('Change room')}}" ng-disabled="roombarform.$invalid" ng-click="save()"><i class="fa fa-sign-in"></i></a></span>
<input class="form-control input-sm" ng-model="newRoomName" ng-maxlength="30" on-enter="save()" type="text" placeholder="{{_('Main')}}"></input><span class="input-group-btn"><a class="btn btn-default btn-sm" title="{{_('Change room')}}" ng-disabled="roombarform.$invalid" ng-click="save()"><i class="fa fa-sign-in"></i></a></span>
</div>
</div>
<div class="pull-left">

Loading…
Cancel
Save