WebRTC audio/video call and conferencing server.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

265 lines
7.0 KiB

/*
* Spreed WebRTC.
* Copyright (C) 2013-2014 struktur AG
*
* This file is part of Spreed WebRTC.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
define([
'require',
'jquery',
'underscore',
'angular',
'modernizr',
'moment',
'services/services',
'directives/directives',
'filters/filters',
'controllers/controllers',
'translation/languages',
'ui-bootstrap',
'angular-sanitize',
'angular-animate',
'angular-humanize',
'angular-route',
'mobile-events'
], function(require, $, _, angular, modernizr, moment, services, directives, filters, controllers, languages) {
// Simple and fast split based URL query parser based on location.search. We require this before the
// angular App is bootstrap to control initialization parameters like translation based on URL parameters.
var urlQuery = (function() {
return (function(a) {
if (a === "") {
return {};
}
var b = {};
for (var i = 0; i < a.length; ++i) {
var p = a[i].split('=');
if (p.length != 2) {
continue;
}
b[p[0]] = window.decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split("&"));
}());
// Base application config shared during initialization.
var appConfig = {};
// Implement translation store.
var TranslationData = function(default_language) {
// Create data structure.
this.data = {
locale_data: {}
};
this.lang = this.default_lang = default_language;
};
TranslationData.prototype.language = function() {
// Return language.
return this.lang;
};
TranslationData.prototype.default_language = function() {
return this.default_lang;
};
TranslationData.prototype.add = function(domain, data) {
var src;
if (data && data.locale_data) {
src = data.locale_data[domain];
}
var dst = this.data.locale_data[domain];
if (!dst) {
dst = this.data.locale_data[domain] = {
"": {
"domain": domain,
"plural_forms": "nplurals=2; plural=(n != 1);"
}
}
}
_.extend(dst, src);
};
TranslationData.prototype.load = function(domain, url) {
var that = this;
return $.ajax({
dataType: "json",
url: url,
success: function(data) {
//console.log("loaded translation data", data);
that.add(domain, data);
},
error: function(err, textStatus, errorThrown) {
console.warn("Failed to load translation data: " + errorThrown);
that.add(domain, null);
}
});
};
TranslationData.prototype.get = function() {
return this.data;
};
var translationData = new TranslationData("en");
var create = function(ms) {
var modules = ['ui.bootstrap', 'ngSanitize', 'ngAnimate', 'ngHumanize', 'ngRoute'];
if (ms && ms.length) {
_.each(ms, function(module) {
modules.push(module);
});
}
var app = angular.module('app', modules);
services.initialize(app);
directives.initialize(app);
filters.initialize(app);
controllers.initialize(app);
app.config(["$compileProvider", "$locationProvider", "$routeProvider", function($compileProvider, $locationProvider, $routeProvider) {
// Allow angular to use filesystem: hrefs which would else be prefixed with unsafe:.
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|filesystem|blob):/);
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|filesystem|blob):|data:image\//);
// Setup routing
$routeProvider.when("/:room", {});
// Use HTML5 routing.
$locationProvider.html5Mode(true);
}]);
app.run(["$rootScope", "$timeout", "mediaStream", "translation", "continueConnector", function($rootScope, $timeout, mediaStream, translation, continueConnector) {
translation.inject($rootScope);
console.log("Initializing ...");
var initialize = continueConnector.defer();
mediaStream.initialize($rootScope, translation);
$timeout(function() {
console.log("Initializing complete.")
initialize.resolve();
}, 0);
}]);
app.constant("availableLanguages", languages);
app.provider("translationData", function translationDataProvider() {
// Make available functions for config phase.
this.add = _.bind(translationData.add, translationData);
this.load = _.bind(translationData.load, translationData);
this.language = _.bind(translationData.language, translationData);
this.default_language = _.bind(translationData.default_language, translationData);
// Out creater returns raw data.
this.$get = [function translationDataFactory() {
return translationData.get();
}];
});
app.directive("spreedWebrtc", [function() {
return {
restrict: "A",
controller: "MediastreamController"
}
}]);
return app;
};
var initialize = function(app) {
var deferred = $.Deferred();
var globalContext = JSON.parse($("#globalcontext").text());
app.constant("globalContext", globalContext);
// Configure language.
var lang = (function() {
var lang = "en";
var wanted = [];
var addLanguage = function(l) {
wanted.push(l);
if (l.indexOf("-") != -1) {
wanted.push(l.split("-")[0]);
}
};
// Get from storage.
if (modernizr.localstorage) {
var lsl = localStorage.getItem("mediastream-language");
if (lsl && lsl !== "undefined") {
wanted.push(lsl);
}
}
// Get from query.
var qsl = urlQuery.lang;
if (qsl) {
addLanguage(qsl);
}
// Get from server side configuration (As provided by browser).
_.each(globalContext.Languages, addLanguage);
// Loop through requested languages and use first one we have.
for (var i = 0; i < wanted.length; i++) {
if (languages.hasOwnProperty(wanted[i])) {
lang = wanted[i];
break;
}
}
// Storage at DOM.
var html = document.getElementsByTagName("html")[0];
html.setAttribute("lang", lang);
return lang;
}());
console.info("Selected language: "+lang);
// Set language and load default translations.
translationData.lang = lang;
var domain = "messages";
if (lang === translationData.default_lang) {
// No need to load default language as it is built in.
translationData.add(domain, null);
deferred.resolve();
} else {
// Load default translation catalog.
var url = require.toUrl('translation/' + domain + "-" + lang + '.json');
$.when(translationData.load(domain, url)).always(function() {
deferred.resolve();
});
}
// Set momemt language.
moment.lang(lang);
return deferred.promise();
};
return {
create: create,
initialize: initialize,
query: urlQuery,
config: appConfig,
translationData: translationData
};
});