Adds a feedback button and dialog.
This commit is contained in:
parent
2117aefacc
commit
73b1d3c7c2
4
Makefile
4
Makefile
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
28
css/main.css
28
css/main.css
|
@ -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;
|
||||
|
|
|
@ -14,7 +14,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,
|
||||
|
@ -218,8 +218,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>
|
||||
|
|
|
@ -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":
|
||||
{
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
||||
|
@ -423,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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
Loading…
Reference in New Issue