Integration of statistics module

This commit is contained in:
isymchych 2015-12-29 14:41:43 +02:00
parent 0fd0f5b633
commit a10f9437f1
12 changed files with 113 additions and 263 deletions

19
app.js
View File

@ -18,6 +18,10 @@ import RoomnameGenerator from './modules/util/RoomnameGenerator';
import CQEvents from './service/connectionquality/CQEvents'; import CQEvents from './service/connectionquality/CQEvents';
import UIEvents from './service/UI/UIEvents'; import UIEvents from './service/UI/UIEvents';
import UI from "./modules/UI/UI";
import statistics from "./modules/statistics/statistics";
import settings from "./modules/settings/Settings";
import {openConnection} from './modules/connection'; import {openConnection} from './modules/connection';
import AuthHandler from './modules/AuthHandler'; import AuthHandler from './modules/AuthHandler';
@ -80,6 +84,10 @@ function buildRoomName () {
const APP = { const APP = {
UI,
statistics,
settings,
init () { init () {
let roomName = buildRoomName(); let roomName = buildRoomName();
this.conference = { this.conference = {
@ -94,29 +102,28 @@ const APP = {
}, },
muteAudio (mute) { muteAudio (mute) {
APP.UI.eventEmitter.emit(UIEvents.AUDIO_MUTED, mute); APP.UI.eventEmitter.emit(UIEvents.AUDIO_MUTED, mute);
APP.statistics.onAudioMute(mute);
}, },
toggleAudioMuted () { toggleAudioMuted () {
this.muteAudio(!this.audioMuted); this.muteAudio(!this.audioMuted);
}, },
muteVideo (mute) { muteVideo (mute) {
APP.UI.eventEmitter.emit(UIEvents.VIDEO_MUTED, mute); APP.UI.eventEmitter.emit(UIEvents.VIDEO_MUTED, mute);
APP.statistics.onVideoMute(mute);
}, },
toggleVideoMuted () { toggleVideoMuted () {
this.muteVideo(!this.videoMuted); this.muteVideo(!this.videoMuted);
} }
}; };
this.UI = require("./modules/UI/UI");
this.API = require("./modules/API/API"); this.API = require("./modules/API/API");
this.connectionquality = this.connectionquality =
require("./modules/connectionquality/connectionquality"); require("./modules/connectionquality/connectionquality");
this.statistics = require("./modules/statistics/statistics");
this.desktopsharing = this.desktopsharing =
require("./modules/desktopsharing/desktopsharing"); require("./modules/desktopsharing/desktopsharing");
this.keyboardshortcut = this.keyboardshortcut =
require("./modules/keyboardshortcut/keyboardshortcut"); require("./modules/keyboardshortcut/keyboardshortcut");
this.translation = require("./modules/translation/translation"); this.translation = require("./modules/translation/translation");
this.settings = require("./modules/settings/Settings");
this.configFetch = require("./modules/config/HttpConfigFetch"); this.configFetch = require("./modules/config/HttpConfigFetch");
} }
}; };
@ -126,6 +133,7 @@ function initConference(localTracks, connection) {
openSctp: config.openSctp, openSctp: config.openSctp,
disableAudioLevels: config.disableAudioLevels disableAudioLevels: config.disableAudioLevels
}); });
APP.conference._room = room; // FIXME do not use this
const addTrack = (track) => { const addTrack = (track) => {
room.addTrack(track); room.addTrack(track);
@ -464,6 +472,8 @@ function initConference(localTracks, connection) {
window.location.pathname = "/"; window.location.pathname = "/";
}, 3000); }, 3000);
} }
}, function (err) {
console.error(err);
}); });
}); });
@ -598,6 +608,7 @@ function createLocalTracks () {
devices: ['audio', 'video'] devices: ['audio', 'video']
}).catch(function (err) { }).catch(function (err) {
console.error('failed to create local tracks', err); console.error('failed to create local tracks', err);
APP.statistics.onGetUserMediaFailed(err);
return []; return [];
}); });
} }
@ -688,7 +699,7 @@ $(document).ready(function () {
URLProcessor.setConfigParametersFromUrl(); URLProcessor.setConfigParametersFromUrl();
APP.init(); APP.init();
APP.translation.init(); APP.translation.init(settings.getLanguage());
if (APP.API.isEnabled()) { if (APP.API.isEnabled()) {
APP.API.init(); APP.API.init();

View File

@ -1,11 +1,10 @@
/* global $, config, interfaceConfig */ /* global $, APP, config, interfaceConfig */
/* /*
* Created by Yana Stamcheva on 2/10/15. * Created by Yana Stamcheva on 2/10/15.
*/ */
var messageHandler = require("./util/MessageHandler"); var messageHandler = require("./util/MessageHandler");
var callStats = require("../statistics/CallStats"); var callStats = require("../statistics/CallStats");
var APP = require("../../app");
/** /**
* Constructs the html for the overall feedback window. * Constructs the html for the overall feedback window.

View File

@ -16,16 +16,15 @@ import EtherpadManager from './etherpad/Etherpad';
import VideoLayout from "./videolayout/VideoLayout"; import VideoLayout from "./videolayout/VideoLayout";
import SettingsMenu from "./side_pannels/settings/SettingsMenu"; import SettingsMenu from "./side_pannels/settings/SettingsMenu";
import Settings from "./../settings/Settings";
var EventEmitter = require("events"); var EventEmitter = require("events");
var Settings = require("./../settings/Settings");
UI.messageHandler = require("./util/MessageHandler"); UI.messageHandler = require("./util/MessageHandler");
var messageHandler = UI.messageHandler; var messageHandler = UI.messageHandler;
var JitsiPopover = require("./util/JitsiPopover"); var JitsiPopover = require("./util/JitsiPopover");
var CQEvents = require("../../service/connectionquality/CQEvents"); var CQEvents = require("../../service/connectionquality/CQEvents");
var DesktopSharingEventTypes var DesktopSharingEventTypes
= require("../../service/desktopsharing/DesktopSharingEventTypes"); = require("../../service/desktopsharing/DesktopSharingEventTypes");
var StatisticsEvents = require("../../service/statistics/Events");
var Feedback = require("./Feedback"); var Feedback = require("./Feedback");
var eventEmitter = new EventEmitter(); var eventEmitter = new EventEmitter();
@ -611,8 +610,8 @@ UI.updateLocalStats = function (percent, stats) {
VideoLayout.updateLocalConnectionStats(percent, stats); VideoLayout.updateLocalConnectionStats(percent, stats);
}; };
UI.updateRemoteStats = function (jid, percent, stats) { UI.updateRemoteStats = function (id, percent, stats) {
VideoLayout.updateConnectionStats(jid, percent, stats); VideoLayout.updateConnectionStats(id, percent, stats);
}; };
UI.markVideoInterrupted = function (interrupted) { UI.markVideoInterrupted = function (interrupted) {

View File

@ -296,6 +296,12 @@ RemoteVideo.prototype.showPeerContainer = function (state) {
}; };
RemoteVideo.prototype.updateResolution = function (resolution) {
if (this.connectionIndicator) {
this.connectionIndicator.updateResolution(resolution);
}
};
RemoteVideo.prototype.removeConnectionIndicator = function () { RemoteVideo.prototype.removeConnectionIndicator = function () {
if (this.connectionIndicator) if (this.connectionIndicator)
this.connectionIndicator.remove(); this.connectionIndicator.remove();

View File

@ -733,23 +733,25 @@ var VideoLayout = {
* @param object * @param object
*/ */
updateLocalConnectionStats (percent, object) { updateLocalConnectionStats (percent, object) {
var resolution = null; let resolutions = {};
if (object.resolution !== null) { if (object.resolution !== null) {
resolution = object.resolution; resolutions = object.resolution;
object.resolution = resolution[APP.xmpp.myJid()]; object.resolution = resolutions[APP.conference.localId];
delete resolution[APP.xmpp.myJid()];
} }
localVideoThumbnail.updateStatsIndicator(percent, object); localVideoThumbnail.updateStatsIndicator(percent, object);
for (var jid in resolution) {
if (resolution[jid] === null) Object.keys(resolutions).forEach(function (id) {
continue; if (APP.conference.isLocalId(id)) {
var resourceJid = Strophe.getResourceFromJid(jid); return;
if (remoteVideos[resourceJid] &&
remoteVideos[resourceJid].connectionIndicator) {
remoteVideos[resourceJid].connectionIndicator.
updateResolution(resolution[jid]);
} }
}
let resolution = resolutions[id];
let remoteVideo = remoteVideos[id];
if (resolution && remoteVideo) {
remoteVideo.updateResolution(resolution);
}
});
}, },
/** /**

View File

@ -1,4 +1,4 @@
var UsernameGenerator = require('../util/UsernameGenerator'); import {generateUsername} from '../util/UsernameGenerator';
var email = ''; var email = '';
var displayName = ''; var displayName = '';
@ -32,7 +32,7 @@ if (supportsLocalStorage()) {
if (!window.localStorage.callStatsUserName) { if (!window.localStorage.callStatsUserName) {
window.localStorage.callStatsUserName window.localStorage.callStatsUserName
= UsernameGenerator.generateUsername(); = generateUsername();
console.log('generated callstats uid', console.log('generated callstats uid',
window.localStorage.callStatsUserName); window.localStorage.callStatsUserName);
@ -45,10 +45,10 @@ if (supportsLocalStorage()) {
} else { } else {
console.log("local storage is not supported"); console.log("local storage is not supported");
userId = generateUniqueId(); userId = generateUniqueId();
callStatsUserName = UsernameGenerator.generateUsername(); callStatsUserName = generateUsername();
} }
var Settings = { export default {
/** /**
* Sets the local user display name and saves it to local storage * Sets the local user display name and saves it to local storage
@ -99,10 +99,11 @@ var Settings = {
language: language language: language
}; };
}, },
getLanguage () {
return language;
},
setLanguage: function (lang) { setLanguage: function (lang) {
language = lang; language = lang;
window.localStorage.language = lang; window.localStorage.language = lang;
} }
}; };
module.exports = Settings;

View File

@ -1,15 +1,19 @@
function NoopAnalytics() {} class NoopAnalytics {
NoopAnalytics.prototype.sendEvent = function () {}; sendEvent () {}
function AnalyticsAdapter() {
var AnalyticsImpl = window.Analytics || NoopAnalytics;
this.analytics = new AnalyticsImpl();
} }
AnalyticsAdapter.prototype.sendEvent = function (action, data) { const AnalyticsImpl = window.Analytics || NoopAnalytics;
try {
this.analytics.sendEvent.apply(this.analytics, arguments);
} catch (ignored) {}
};
module.exports = new AnalyticsAdapter(); class AnalyticsAdapter {
constructor () {
this.analytics = new AnalyticsImpl();
}
sendEvent (...args) {
try {
this.analytics.sendEvent(...args);
} catch (ignored) {}
}
}
export default new AnalyticsAdapter();

View File

@ -1,128 +0,0 @@
/* global config, AudioContext */
/**
* Provides statistics for the local stream.
*/
var RTCBrowserType = require('../RTC/RTCBrowserType');
var StatisticsEvents = require('../../service/statistics/Events');
/**
* Size of the webaudio analyzer buffer.
* @type {number}
*/
var WEBAUDIO_ANALYZER_FFT_SIZE = 2048;
/**
* Value of the webaudio analyzer smoothing time parameter.
* @type {number}
*/
var WEBAUDIO_ANALYZER_SMOOTING_TIME = 0.8;
/**
* Converts time domain data array to audio level.
* @param samples the time domain data array.
* @returns {number} the audio level
*/
function timeDomainDataToAudioLevel(samples) {
var maxVolume = 0;
var length = samples.length;
for (var i = 0; i < length; i++) {
if (maxVolume < samples[i])
maxVolume = samples[i];
}
return parseFloat(((maxVolume - 127) / 128).toFixed(3));
}
/**
* Animates audio level change
* @param newLevel the new audio level
* @param lastLevel the last audio level
* @returns {Number} the audio level to be set
*/
function animateLevel(newLevel, lastLevel) {
var value = 0;
var diff = lastLevel - newLevel;
if(diff > 0.2) {
value = lastLevel - 0.2;
}
else if(diff < -0.4) {
value = lastLevel + 0.4;
}
else {
value = newLevel;
}
return parseFloat(value.toFixed(3));
}
/**
* <tt>LocalStatsCollector</tt> calculates statistics for the local stream.
*
* @param stream the local stream
* @param interval stats refresh interval given in ms.
* @constructor
*/
function LocalStatsCollector(stream, interval,
statisticsService, eventEmitter) {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
this.stream = stream;
this.intervalId = null;
this.intervalMilis = interval;
this.eventEmitter = eventEmitter;
this.audioLevel = 0;
this.statisticsService = statisticsService;
}
/**
* Starts the collecting the statistics.
*/
LocalStatsCollector.prototype.start = function () {
if (config.disableAudioLevels || !window.AudioContext ||
RTCBrowserType.isTemasysPluginUsed())
return;
var context = new AudioContext();
var analyser = context.createAnalyser();
analyser.smoothingTimeConstant = WEBAUDIO_ANALYZER_SMOOTING_TIME;
analyser.fftSize = WEBAUDIO_ANALYZER_FFT_SIZE;
var source = context.createMediaStreamSource(this.stream);
source.connect(analyser);
var self = this;
this.intervalId = setInterval(
function () {
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteTimeDomainData(array);
var audioLevel = timeDomainDataToAudioLevel(array);
if (audioLevel != self.audioLevel) {
self.audioLevel = animateLevel(audioLevel, self.audioLevel);
self.eventEmitter.emit(
StatisticsEvents.AUDIO_LEVEL,
self.statisticsService.LOCAL_JID,
self.audioLevel);
}
},
this.intervalMilis
);
};
/**
* Stops collecting the statistics.
*/
LocalStatsCollector.prototype.stop = function () {
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
};
module.exports = LocalStatsCollector;

View File

@ -385,7 +385,7 @@ StatsCollector.prototype.addStatsToBeLogged = function (reports) {
StatsCollector.prototype.logStats = function () { StatsCollector.prototype.logStats = function () {
if(!APP.xmpp.sendLogs(this.statsToBeLogged)) if(!APP.conference._room.xmpp.sendLogs(this.statsToBeLogged))
return; return;
// Reset the stats // Reset the stats
this.statsToBeLogged.stats = {}; this.statsToBeLogged.stats = {};
@ -501,7 +501,7 @@ StatsCollector.prototype.processStatsReport = function () {
var ssrc = getStatValue(now, 'ssrc'); var ssrc = getStatValue(now, 'ssrc');
if(!ssrc) if(!ssrc)
continue; continue;
var jid = APP.xmpp.getJidFromSSRC(ssrc); var jid = APP.conference._room.room.getJidBySSRC(ssrc);
if (!jid && (Date.now() - now.timestamp) < 3000) { if (!jid && (Date.now() - now.timestamp) < 3000) {
console.warn("No jid for ssrc: " + ssrc); console.warn("No jid for ssrc: " + ssrc);
continue; continue;
@ -647,12 +647,20 @@ StatsCollector.prototype.processStatsReport = function () {
upload: upload:
calculatePacketLoss(lostPackets.upload, totalPackets.upload) calculatePacketLoss(lostPackets.upload, totalPackets.upload)
}; };
let idResolution = {};
if (resolutions) { // use id instead of jid
Object.keys(resolutions).forEach(function (jid) {
let id = Strophe.getResourceFromJid(jid);
resolution[id] = resolutions[id];
});
}
this.eventEmitter.emit(StatisticsEvents.CONNECTION_STATS, this.eventEmitter.emit(StatisticsEvents.CONNECTION_STATS,
{ {
"bitrate": PeerStats.bitrate, "bitrate": PeerStats.bitrate,
"packetLoss": PeerStats.packetLoss, "packetLoss": PeerStats.packetLoss,
"bandwidth": PeerStats.bandwidth, "bandwidth": PeerStats.bandwidth,
"resolution": resolutions, "resolution": idResolution,
"transport": PeerStats.transport "transport": PeerStats.transport
}); });
PeerStats.transport = []; PeerStats.transport = [];
@ -681,7 +689,7 @@ StatsCollector.prototype.processAudioLevelReport = function () {
} }
var ssrc = getStatValue(now, 'ssrc'); var ssrc = getStatValue(now, 'ssrc');
var jid = APP.xmpp.getJidFromSSRC(ssrc); var jid = APP.conference._room.room.getJidBySSRC(ssrc);
if (!jid) { if (!jid) {
if((Date.now() - now.timestamp) < 3000) if((Date.now() - now.timestamp) < 3000)
console.warn("No jid for ssrc: " + ssrc); console.warn("No jid for ssrc: " + ssrc);
@ -713,7 +721,7 @@ StatsCollector.prototype.processAudioLevelReport = function () {
// but it seems to vary between 0 and around 32k. // but it seems to vary between 0 and around 32k.
audioLevel = audioLevel / 32767; audioLevel = audioLevel / 32767;
jidStats.setSsrcAudioLevel(ssrc, audioLevel); jidStats.setSsrcAudioLevel(ssrc, audioLevel);
if (jid != APP.xmpp.myJid()) { if (jid != APP.conference._room.room.myroomjid) {
this.eventEmitter.emit( this.eventEmitter.emit(
StatisticsEvents.AUDIO_LEVEL, jid, audioLevel); StatisticsEvents.AUDIO_LEVEL, jid, audioLevel);
} }

View File

@ -2,7 +2,6 @@
/** /**
* Created by hristo on 8/4/14. * Created by hristo on 8/4/14.
*/ */
var LocalStats = require("./LocalStatsCollector.js");
var RTPStats = require("./RTPStatsCollector.js"); var RTPStats = require("./RTPStatsCollector.js");
var EventEmitter = require("events"); var EventEmitter = require("events");
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js"); var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
@ -13,17 +12,8 @@ var StatisticsEvents = require("../../service/statistics/Events");
var eventEmitter = new EventEmitter(); var eventEmitter = new EventEmitter();
var localStats = null;
var rtpStats = null; var rtpStats = null;
function stopLocal() {
if (localStats) {
localStats.stop();
localStats = null;
}
}
function stopRemote() { function stopRemote() {
if (rtpStats) { if (rtpStats) {
rtpStats.stop(); rtpStats.stop();
@ -41,26 +31,15 @@ function startRemoteStats (peerconnection) {
rtpStats.start(); rtpStats.start();
} }
function onStreamCreated(stream) {
if(stream.getOriginalStream().getAudioTracks().length === 0) {
return;
}
localStats = new LocalStats(stream.getOriginalStream(), 200, statistics,
eventEmitter);
localStats.start();
}
function onDisposeConference(onUnload) { function onDisposeConference(onUnload) {
CallStats.sendTerminateEvent(); CallStats.sendTerminateEvent();
stopRemote(); stopRemote();
if(onUnload) { if (onUnload) {
stopLocal();
eventEmitter.removeAllListeners(); eventEmitter.removeAllListeners();
} }
} }
var statistics = { export default {
/** /**
* Indicates that this audio level is for local jid. * Indicates that this audio level is for local jid.
* @type {string} * @type {string}
@ -74,65 +53,61 @@ var statistics = {
eventEmitter.removeListener(type, listener); eventEmitter.removeListener(type, listener);
}, },
stop: function () { stop: function () {
stopLocal();
stopRemote(); stopRemote();
if(eventEmitter) if (eventEmitter) {
{
eventEmitter.removeAllListeners(); eventEmitter.removeAllListeners();
} }
}, },
stopRemoteStatistics: function() onAudioMute (mute) {
{ CallStats.sendMuteEvent(mute, "audio");
stopRemote(); },
onVideoMute (mute) {
CallStats.sendMuteEvent(mute, "video");
},
onGetUserMediaFailed (e) {
CallStats.sendGetUserMediaFailed(e);
}, },
start: function () { start: function () {
return; const xmpp = APP.conference._room.xmpp;
APP.RTC.addStreamListener(onStreamCreated, xmpp.addListener(
StreamEventTypes.EVENT_TYPE_LOCAL_CREATED); XMPPEvents.DISPOSE_CONFERENCE,
APP.xmpp.addListener(XMPPEvents.DISPOSE_CONFERENCE, onDisposeConference
onDisposeConference); );
//FIXME: we may want to change CALL INCOMING event to //FIXME: we may want to change CALL INCOMING event to
// onnegotiationneeded // onnegotiationneeded
APP.xmpp.addListener(XMPPEvents.CALL_INCOMING, function (event) { xmpp.addListener(XMPPEvents.CALL_INCOMING, function (event) {
startRemoteStats(event.peerconnection); startRemoteStats(event.peerconnection);
// CallStats.init(event); // CallStats.init(event);
}); });
APP.xmpp.addListener(XMPPEvents.PEERCONNECTION_READY, xmpp.addListener(
XMPPEvents.PEERCONNECTION_READY,
function (session) { function (session) {
CallStats.init(session); CallStats.init(session);
}); }
APP.RTC.addListener(RTCEvents.AUDIO_MUTE, function (mute) { );
CallStats.sendMuteEvent(mute, "audio"); xmpp.addListener(XMPPEvents.CONFERENCE_SETUP_FAILED, function () {
});
APP.xmpp.addListener(XMPPEvents.CONFERENCE_SETUP_FAILED, function () {
CallStats.sendSetupFailedEvent(); CallStats.sendSetupFailedEvent();
}); });
APP.RTC.addListener(RTCEvents.VIDEO_MUTE, function (mute) {
CallStats.sendMuteEvent(mute, "video");
});
APP.RTC.addListener(RTCEvents.GET_USER_MEDIA_FAILED, function (e) { xmpp.addListener(RTCEvents.CREATE_OFFER_FAILED, function (e, pc) {
CallStats.sendGetUserMediaFailed(e);
});
APP.xmpp.addListener(RTCEvents.CREATE_OFFER_FAILED, function (e, pc) {
CallStats.sendCreateOfferFailed(e, pc); CallStats.sendCreateOfferFailed(e, pc);
}); });
APP.xmpp.addListener(RTCEvents.CREATE_ANSWER_FAILED, function (e, pc) { xmpp.addListener(RTCEvents.CREATE_ANSWER_FAILED, function (e, pc) {
CallStats.sendCreateAnswerFailed(e, pc); CallStats.sendCreateAnswerFailed(e, pc);
}); });
APP.xmpp.addListener( xmpp.addListener(
RTCEvents.SET_LOCAL_DESCRIPTION_FAILED, RTCEvents.SET_LOCAL_DESCRIPTION_FAILED,
function (e, pc) { function (e, pc) {
CallStats.sendSetLocalDescFailed(e, pc); CallStats.sendSetLocalDescFailed(e, pc);
} }
); );
APP.xmpp.addListener( xmpp.addListener(
RTCEvents.SET_REMOTE_DESCRIPTION_FAILED, RTCEvents.SET_REMOTE_DESCRIPTION_FAILED,
function (e, pc) { function (e, pc) {
CallStats.sendSetRemoteDescFailed(e, pc); CallStats.sendSetRemoteDescFailed(e, pc);
} }
); );
APP.xmpp.addListener( xmpp.addListener(
RTCEvents.ADD_ICE_CANDIDATE_FAILED, RTCEvents.ADD_ICE_CANDIDATE_FAILED,
function (e, pc) { function (e, pc) {
CallStats.sendAddIceCandidateFailed(e, pc); CallStats.sendAddIceCandidateFailed(e, pc);
@ -140,8 +115,3 @@ var statistics = {
); );
} }
}; };
module.exports = statistics;

View File

@ -1,7 +1,6 @@
/* global $, require, config, interfaceConfig */ /* global $, require, config, interfaceConfig */
var i18n = require("i18next-client"); var i18n = require("i18next-client");
var languages = require("../../service/translation/languages"); var languages = require("../../service/translation/languages");
var Settings = require("../settings/Settings");
var DEFAULT_LANG = languages.EN; var DEFAULT_LANG = languages.EN;
i18n.addPostProcessor("resolveAppName", function(value, key, options) { i18n.addPostProcessor("resolveAppName", function(value, key, options) {
@ -68,7 +67,7 @@ function initCompleted(t) {
$("[data-i18n]").i18n(); $("[data-i18n]").i18n();
} }
function checkForParameter() { function getLangFromQuery() {
var query = window.location.search.substring(1); var query = window.location.search.substring(1);
var vars = query.split("&"); var vars = query.split("&");
for (var i=0;i<vars.length;i++) { for (var i=0;i<vars.length;i++) {
@ -82,27 +81,11 @@ function checkForParameter() {
} }
module.exports = { module.exports = {
init: function (lang) { init: function (settingsLang) {
var options = defaultOptions; let options = defaultOptions;
let lang = getLangFromQuery() || settingsLang || config.defaultLanguage;
if(!lang) if (lang) {
{
lang = checkForParameter();
if(!lang)
{
var settings = Settings.getSettings();
if(settings)
lang = settings.language;
if(!lang && config.defaultLanguage)
{
lang = config.defaultLanguage;
}
}
}
if(lang) {
options.lng = lang; options.lng = lang;
} }
@ -124,8 +107,7 @@ module.exports = {
}, },
generateTranslationHTML: function (key, options) { generateTranslationHTML: function (key, options) {
var str = "<span data-i18n=\"" + key + "\""; var str = "<span data-i18n=\"" + key + "\"";
if(options) if (options) {
{
str += " data-i18n-options=\"" + JSON.stringify(options) + "\""; str += " data-i18n-options=\"" + JSON.stringify(options) + "\"";
} }
str += ">"; str += ">";

View File

@ -1,4 +1,4 @@
var RandomUtil = require('./RandomUtil'); import RandomUtil from './RandomUtil';
/** /**
* from faker.js - Copyright (c) 2014-2015 Matthew Bergman & Marak Squires * from faker.js - Copyright (c) 2014-2015 Matthew Bergman & Marak Squires
@ -417,13 +417,9 @@ var names = [
* Generate random username. * Generate random username.
* @returns {string} random username * @returns {string} random username
*/ */
function generateUsername () { export function generateUsername () {
var name = RandomUtil.randomElement(names); var name = RandomUtil.randomElement(names);
var suffix = RandomUtil.randomAlphanumStr(3); var suffix = RandomUtil.randomAlphanumStr(3);
return name + '-' + suffix; return name + '-' + suffix;
} }
module.exports = {
generateUsername: generateUsername
};