Merge remote-tracking branch 'upstream/master'

This commit is contained in:
luciash d' being 2015-11-06 04:55:26 +01:00
commit 46158cda4d
15 changed files with 356 additions and 97 deletions

View File

@ -3,12 +3,12 @@ BROWSERIFY = ./node_modules/.bin/browserify
UGLIFYJS = ./node_modules/.bin/uglifyjs
EXORCIST = ./node_modules/.bin/exorcist
CLEANCSS = ./node_modules/.bin/cleancss
CSS_FILES = font.css toastr.css main.css videolayout_default.css font-awesome.css jquery-impromptu.css modaldialog.css notice.css popup_menu.css login_menu.css popover.css jitsi_popover.css contact_list.css chat.css welcome_page.css settingsmenu.css
CSS_FILES = font.css toastr.css main.css videolayout_default.css font-awesome.css jquery-impromptu.css modaldialog.css notice.css popup_menu.css login_menu.css popover.css jitsi_popover.css contact_list.css chat.css welcome_page.css settingsmenu.css feedback.css
DEPLOY_DIR = libs
BROWSERIFY_FLAGS = -d
OUTPUT_DIR = .
all: compile uglify deploy clean
all: compile uglify deploy clean
compile:
$(NPM) update && $(BROWSERIFY) $(BROWSERIFY_FLAGS) -e app.js -s APP | $(EXORCIST) $(OUTPUT_DIR)/app.bundle.js.map > $(OUTPUT_DIR)/app.bundle.js

48
css/feedback.css Normal file
View File

@ -0,0 +1,48 @@
/**
* The feedback window inner div css.
*/
.feedback {
width: 450px;
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
font-size: 22px;
}
/**
* Style of the thank you text inside the feedback window.
*/
.feedbackTitle {
font-size: 22px;
color: #087dba;
}
/**
* Stars div css.
*/
#stars {
font-size: 30px;
}
/**
* Star css.
*/
#stars>a {
padding-right: 4px;
}
/**
* Mouse over a star.
*/
.starHover {
color: #087dba;
}
/**
* Detailed feedback section text area style.
*/
.feedbackDetails textarea {
resize: vertical;
min-height: 100px;
}

View File

@ -10,7 +10,7 @@ html, body{
font-family:'Helvetica Neue', Helvetica, sans-serif;
font-weight: 400;
background: #000000;
overflow-x: hidden;
overflow: hidden;
}
.right-panel {
@ -236,10 +236,34 @@ form {
bottom: 5;
left: 5;
overflow: visible;
z-index: 100;
color: rgba(255,255,255,.50);
}
#feedbackButton {
position: absolute;
bottom: 60;
left: 60;
overflow: visible;
color: rgba(255,255,255,.50);
}
div.feedbackButton {
position: absolute;
background-color: rgba(0,0,0,.50);
border-radius: 50%;
width: 100px;
height: 100px;
bottom: -50px;
left: -50px;
z-index: 100;
overflow: hidden;
transition: all .2s ease-in-out;
}
div.feedbackButton:hover {
transform: scale(1.3);
}
#bottomToolbar {
display:block;
position: absolute;

View File

@ -1,8 +1,8 @@
# Jitsi Meet quick install
This document describes the required steps for a quick Jitsi Meet installation on a Debian based GNU/Linux system.
This document describes the required steps for a quick Jitsi Meet installation on a Debian based GNU/Linux system. Debian 8 (Jessie) or later, and Ubuntu 14.04 or later are supported out-of-the-box.
Note: Some of the components of Jitsi-Meet will not run out-of-the-box on Debian Wheezy systems because of its libc version being too old. [See here](http://lists.jitsi.org/pipermail/users/2015-September/010064.html) for a possible solution.
Debian Wheezy and other older systems may require additional things to be done. Specifically for Wheezy, [libc needs to be updated](http://lists.jitsi.org/pipermail/users/2015-September/010064.html).
N.B.: All commands are supposed to be run by root. If you are logged in as a regular user with sudo rights, please prepend ___sudo___ to each of the commands.

View File

@ -18,7 +18,7 @@
<script src="https://api.callstats.io/static/callstats.min.js"></script>
<script src="config.js?v=15"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
<script src="interface_config.js?v=6"></script>
<script src="libs/app.bundle.min.js?v=138"></script>
<script src="libs/app.bundle.min.js?v=139"></script>
<script src="analytics.js?v=1"></script><!-- google analytics plugin -->
<!--
Link used for inline installation of chrome desktop streaming extension,
@ -224,8 +224,11 @@
</label>
</div>
<button id="updateSettings" data-i18n="settings.update"></button>
<a id="downloadlog" data-container="body" data-toggle="popover" data-placement="right" data-i18n="[data-content]downloadlogs" ><i class="fa fa-cloud-download"></i></a>
</div>
<div class="feedbackButton">
<a id="feedbackButton" data-container="body" data-toggle="popover" data-placement="right" data-i18n="[data-content]feedback"><i class="fa fa-heart"></i></a>
</div>
<a id="downloadlog" data-container="body" data-toggle="popover" data-placement="right" data-i18n="[data-content]downloadlogs" ><i class="fa fa-cloud-download"></i></a>
</div>
</body>
</html>

View File

@ -3,6 +3,7 @@
"connectionsettings": "Connection Settings",
"poweredby": "powered by",
"downloadlogs": "Download logs",
"feedback": "Give us your feedback",
"roomUrlDefaultMsg": "Your conference is currently being created...",
"participant": "Participant",
"me": "me",
@ -197,7 +198,10 @@
"tokenAuthFailed": "Failed to authenticate with XMPP server: invalid token",
"displayNameRequired": "Please enter your display name:",
"extensionRequired": "Extension required:",
"firefoxExtensionPrompt": "You need to install a Firefox extension in order to use screen sharing. Please try again after you <a href='__url__'>get it from here</a>!"
"firefoxExtensionPrompt": "You need to install a Firefox extension in order to use screen sharing. Please try again after you <a href='__url__'>get it from here</a>!",
"feedbackQuestion": "How was your call?",
"thankYou": "Thank you for using __appName__!",
"sorryFeedback": "We're sorry to hear that. Would you like to tell us more?"
},
"email":
{

214
modules/UI/Feedback.js Normal file
View File

@ -0,0 +1,214 @@
/**
* Created by ystamcheva on 2/10/15.
*/
/* jshint -W101 */
var messageHandler = require("./util/MessageHandler");
var callStats = require("../statistics/CallStats");
var APP = require("../../app");
/**
* Constructs the html for the overall feedback window.
*
* @returns {string} the constructed html string
*/
var constructOverallFeedbackHtml = function() {
var feedbackQuestion = (Feedback.feedbackScore < 0)
? '<br/><br/>' + APP.translation
.translateString("dialog.feedbackQuestion")
: '';
var message = '<div class="feedback"><div>' +
'<div class="feedbackTitle">' +
APP.translation.translateString("dialog.thankYou",
{appName:interfaceConfig.APP_NAME}) +
'</div>' +
feedbackQuestion +
'</div><br/><br/>' +
'<div id="stars">' +
'<a><i class="fa fa-star-o fa fa-star"></i></a>' +
'<a><i class="fa fa-star-o fa fa-star"></i></a>' +
'<a><i class="fa fa-star-o fa fa-star"></i></a>' +
'<a><i class="fa fa-star-o fa fa-star"></i></a>' +
'<a><i class="fa fa-star-o fa fa-star"></i></a>' +
'</div></div>';
return message;
};
/**
* Constructs the html for the detailed feedback window.
*
* @returns {string} the contructed html string
*/
var constructDetailedFeedbackHtml = function() {
// Construct the html, which will be served as a dialog message.
var message = '<div class="feedback">' +
'<div class="feedbackTitle">' +
APP.translation.translateString("dialog.sorryFeedback") +
'</div><br/><br/>' +
'<div class="feedbackDetails">' +
'<textarea id="feedbackTextArea" rows="10" cols="50" autofocus>' +
'</textarea>' +
'</div></div>';
return message;
};
/**
* The callback function corresponding to the openFeedbackWindow parameter.
*
* @type {function}
*/
var feedbackWindowCallback = null;
/**
* Defines all methods in connection to the Feedback window.
*
* @type {{feedbackScore: number, openFeedbackWindow: Function,
* toggleStars: Function, hoverStars: Function, unhoverStars: Function}}
*/
var Feedback = {
/**
* The feedback score. -1 indicates no score has been given for now.
*/
feedbackScore: -1,
/**
* Opens the feedback window.
*/
openFeedbackWindow: function (callback) {
feedbackWindowCallback = callback;
// Add all mouse and click listeners.
var onLoadFunction = function (event) {
$('#stars >a').each(function(index) {
// On star mouse over.
$(this).get(0).onmouseover = function(){
Feedback.hoverStars(index);
};
// On star mouse leave.
$(this).get(0).onmouseleave = function(){
Feedback.unhoverStars(index);
};
// On star click.
$(this).get(0).onclick = function(){
Feedback.toggleStars(index);
Feedback.feedbackScore = index+1;
// If the feedback is less than 3 stars we're going to
// ask the user for more information.
if (Feedback.feedbackScore > 3) {
callStats.sendFeedback(Feedback.feedbackScore, "");
if (feedbackWindowCallback)
feedbackWindowCallback();
else
APP.UI.messageHandler.closeDialog();
}
else {
feedbackDialog.goToState('detailed_feedback');
}
};
// Initialise stars to correspond to previously entered feedback.
if (Feedback.feedbackScore > 0
&& index < Feedback.feedbackScore) {
Feedback.hoverStars(index);
Feedback.toggleStars(index);
}
});
};
// Defines the different states of the feedback window.
var states = {
overall_feedback: {
html: constructOverallFeedbackHtml(),
persistent: true,
buttons: {},
closeText: '',
focus: "div[id='stars']",
position: {width: 500}
},
detailed_feedback: {
html: constructDetailedFeedbackHtml(),
buttons: {"Submit": true, "Cancel": false},
closeText: '',
focus: "textarea[id='feedbackTextArea']",
position: {width: 500},
submit: function(e,v,m,f) {
e.preventDefault();
if (v) {
var feedbackDetails
= document.getElementById("feedbackTextArea").value;
if (feedbackDetails && feedbackDetails.length > 0)
callStats.sendFeedback( Feedback.feedbackScore,
feedbackDetails);
if (feedbackWindowCallback)
feedbackWindowCallback();
else
APP.UI.messageHandler.closeDialog();
} else {
// User cancelled
if (feedbackWindowCallback)
feedbackWindowCallback();
else
APP.UI.messageHandler.closeDialog();
}
}
}
};
// Create the feedback dialog.
var feedbackDialog
= APP.UI.messageHandler.openDialogWithStates(
states,
{ persistent: true,
buttons: {},
closeText: '',
loaded: onLoadFunction,
position: {width: 500}}, null);
},
/**
* Toggles the appropriate css class for the given number of stars, to
* indicate that those stars have been clicked/selected.
*
* @param starCount the number of stars, for which to toggle the css class
*/
toggleStars: function (starCount)
{
$('#stars >a >i').each(function(index) {
if (index <= starCount) {
$(this).removeClass("fa-star-o");
}
else
$(this).addClass("fa-star-o");
});
},
/**
* Toggles the appropriate css class for the given number of stars, to
* indicate that those stars have been hovered.
*
* @param starCount the number of stars, for which to toggle the css class
*/
hoverStars: function (starCount)
{
$('#stars >a >i').each(function(index) {
if (index <= starCount)
$(this).addClass("starHover");
});
},
/**
* Toggles the appropriate css class for the given number of stars, to
* indicate that those stars have been un-hovered.
*
* @param starCount the number of stars, for which to toggle the css class
*/
unhoverStars: function (starCount)
{
$('#stars >a >i').each(function(index) {
if (index <= starCount && $(this).hasClass("fa-star-o"))
$(this).removeClass("starHover");
});
}
};
// Exports the Feedback class.
module.exports = Feedback;

View File

@ -33,6 +33,7 @@ var XMPPEvents = require("../../service/xmpp/XMPPEvents");
var StatisticsEvents = require("../../service/statistics/Events");
var UIEvents = require("../../service/UI/UIEvents");
var MemberEvents = require("../../service/members/Events");
var Feedback = require("./Feedback");
var eventEmitter = new EventEmitter();
var roomNode = null;
@ -302,17 +303,6 @@ function registerListeners() {
"dialog.internalError");
});
APP.xmpp.addListener(XMPPEvents.SET_LOCAL_DESCRIPTION_ERROR, function () {
messageHandler.showError("dialog.error",
"dialog.SLDFailure");
});
APP.xmpp.addListener(XMPPEvents.SET_REMOTE_DESCRIPTION_ERROR, function () {
messageHandler.showError("dialog.error",
"dialog.SRDFailure");
});
APP.xmpp.addListener(XMPPEvents.CREATE_ANSWER_ERROR, function () {
messageHandler.showError();
});
APP.xmpp.addListener(XMPPEvents.PROMPT_FOR_LOGIN, function (callback) {
// FIXME: re-use LoginDialog which supports retries
if (config.token) {
@ -434,11 +424,15 @@ UI.start = function (init) {
$("#downloadlog").click(function (event) {
dump(event.target);
});
$("#feedbackButton").click(function (event) {
Feedback.openFeedbackWindow();
});
}
else
{
$("#header").css("display", "none");
$("#bottomToolbar").css("display", "none");
$("#feedbackButton").css("display", "none");
$("#downloadlog").css("display", "none");
$("#remoteVideos").css("padding", "0px 0px 18px 0px");
$("#remoteVideos").css("right", "0px");
@ -899,4 +893,3 @@ UI.userAvatarChanged = function (resourceJid, thumbUrl, contactListUrl) {
UI.setVideoMute = setVideoMute;
module.exports = UI;

View File

@ -11,6 +11,7 @@ var UIUtil = require("../util/UIUtil");
var AuthenticationEvents
= require("../../../service/authentication/AuthenticationEvents");
var AnalyticsAdapter = require("../../statistics/AnalyticsAdapter");
var Feedback = require("../Feedback");
var roomUrl = null;
var sharedKey = '';
@ -135,41 +136,32 @@ var defaultToolbarButtons = {
'hangup': '#toolbar_button_hangup'
};
/**
* Hangs up this call.
*/
function hangup() {
APP.xmpp.disposeConference();
if(config.enableWelcomePage) {
setTimeout(function() {
window.localStorage.welcomePageDisabled = false;
window.location.pathname = "/";
}, 10000);
var conferenceDispose = function () {
APP.xmpp.disposeConference();
if (config.enableWelcomePage) {
setTimeout(function() {
window.localStorage.welcomePageDisabled = false;
window.location.pathname = "/";
}, 3000);
}
}
var title = APP.translation.generateTranslationHTML(
"dialog.sessTerminated");
var msg = APP.translation.generateTranslationHTML(
"dialog.hungUp");
var button = APP.translation.generateTranslationHTML(
"dialog.joinAgain");
var buttons = [];
buttons.push({title: button, value: true});
UI.messageHandler.openDialog(
title,
msg,
true,
buttons,
function(event, value, message, formVals) {
window.location.reload();
return false;
}
);
if (Feedback.feedbackScore > 0) {
Feedback.openFeedbackWindow();
conferenceDispose();
}
else
Feedback.openFeedbackWindow(conferenceDispose);
}
/**
* Starts or stops the recording for the conference.
*/
function toggleRecording(predefinedToken) {
APP.xmpp.toggleRecording(function (callback) {
if (predefinedToken) {

View File

@ -84,7 +84,8 @@ var messageHandler = (function(my) {
};
/**
* Shows a message to the user with two buttons: first is given as a parameter and the second is Cancel.
* Shows a message to the user with two buttons: first is given as a
* parameter and the second is Cancel.
*
* @param titleString the title of the message
* @param msgString the text of the message

View File

@ -130,6 +130,8 @@ LocalVideo.prototype.setDisplayName = function(displayName, key) {
};
LocalVideo.prototype.inputDisplayNameHandler = function (name) {
name = UIUtil.escapeHtml(name);
NicknameHandler.setNickname(name);
var localDisplayName = $('#localDisplayName');

View File

@ -77,7 +77,26 @@ var CallStats = {
}
callStats.sendFabricEvent(this.peerconnection,
callStats.fabricEvent.fabricSetupFailed, this.confID);
}
},
/**
* Sends the given feedback through CallStats.
*
* @param overallFeedback an integer between 1 and 5 indicating the
* user feedback
* @param detailedFeedback detailed feedback from the user. Not yet used
*/
sendFeedback: function(overallFeedback, detailedFeedback) {
if(!callStats) {
return;
}
var feedbackString = '{"userID":"' + this.userID + '"' +
', "overall":' + overallFeedback +
', "comment": "' + detailedFeedback + '"}';
var feedbackJSON = JSON.parse(feedbackString);
callStats.sendUserFeedback(
this.confID, feedbackJSON);
}
};
module.exports = CallStats;

View File

@ -17,20 +17,20 @@ var RandomUtil = {
/**
* Generates hex number with length 4
*/
random4digitsHex: function() {
return rangeRandomHex(4096, 65535);
random4digitsHex: function () {
return rangeRandomHex(0x1000, 0xFFFF);
},
/**
* Generates hex number with length 8
*/
random8digitsHex: function() {
return rangeRandomHex(268435456, 4294967295);
random8digitsHex: function () {
return rangeRandomHex(0x10000000, 0xFFFFFFFF);
},
/**
* Generates hex number with length 12
*/
random12digitsHex: function() {
return rangeRandomHex(17592186044416, 281474976710655);
random12digitsHex: function () {
return rangeRandomHex(0x100000000000, 0xFFFFFFFFFFFF);
}
};

View File

@ -1468,41 +1468,6 @@ JingleSessionPC.prototype.setLocalDescription = function () {
}
};
// an attempt to work around https://github.com/jitsi/jitmeet/issues/32
// TODO: is this hack (along with the XMPPEvent-s used only for it) still needed
// now that we announce an SSRC for receive-only streams?
function sendKeyframe(pc) {
console.log('sendkeyframe', pc.iceConnectionState);
if (pc.iceConnectionState !== 'connected') return; // safe...
pc.setRemoteDescription(
pc.remoteDescription,
function () {
pc.createAnswer(
function (modifiedAnswer) {
pc.setLocalDescription(
modifiedAnswer,
function () {
// noop
},
function (error) {
console.log('triggerKeyframe setLocalDescription failed', error);
eventEmitter.emit(XMPPEvents.SET_LOCAL_DESCRIPTION_ERROR);
}
);
},
function (error) {
console.log('triggerKeyframe createAnswer failed', error);
eventEmitter.emit(XMPPEvents.CREATE_ANSWER_ERROR);
}
);
},
function (error) {
console.log('triggerKeyframe setRemoteDescription failed', error);
eventEmitter.emit(XMPPEvents.SET_REMOTE_DESCRIPTION_ERROR);
}
);
}
/**
* Handles 'onaddstream' events from the RTCPeerConnection.
* @param event the 'onaddstream' event.

View File

@ -83,12 +83,6 @@ var XMPPEvents = {
RESERVATION_ERROR: "xmpp.room_reservation_error",
DISPOSE_CONFERENCE: "xmpp.dispose_conference",
GRACEFUL_SHUTDOWN: "xmpp.graceful_shutdown",
// TODO: only used in a hack, should probably be removed.
SET_LOCAL_DESCRIPTION_ERROR: 'xmpp.set_local_description_error',
// TODO: only used in a hack, should probably be removed.
SET_REMOTE_DESCRIPTION_ERROR: 'xmpp.set_remote_description_error',
// TODO: only used in a hack, should probably be removed.
CREATE_ANSWER_ERROR: 'xmpp.create_answer_error',
JINGLE_FATAL_ERROR: 'xmpp.jingle_fatal_error',
PROMPT_FOR_LOGIN: 'xmpp.prompt_for_login',
FOCUS_DISCONNECTED: 'xmpp.focus_disconnected',
@ -97,4 +91,4 @@ var XMPPEvents = {
// xmpp is connected and obtained user media
READY_TO_JOIN: 'xmpp.ready_to_join'
};
module.exports = XMPPEvents;
module.exports = XMPPEvents;