diff --git a/CHANGELOG b/CHANGELOG index 5683c42d4..b66b4e883 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -95,8 +95,7 @@ Other: - Added new caching system with support for Redis. - Support https as websocket protocol (wss). - Added migration path from 2.0. -- Add an api for apps to send data when the websocket connection is established. -- Used this api for all models expect of users to send all data to the client. +- Accelerated startup process (send all data to the client after login). Version 2.0 (2016-04-18) diff --git a/openslides/core/static/css/app.css b/openslides/core/static/css/app.css index 342d250c4..995e630b0 100644 --- a/openslides/core/static/css/app.css +++ b/openslides/core/static/css/app.css @@ -129,6 +129,25 @@ img { margin: 0 auto 0 auto; } +#startup-overlay { + display: table; + background-color: #fff; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; +} +#startup-overlay h1 { + font-size: 56px; + text-align: center; +} +#startup-overlay > div { + display: table-cell; + vertical-align: middle; +} + /** Header **/ #header { float: left; @@ -138,12 +157,6 @@ img { color: #999; } -#header div.unconnected { - border: 1px solid red; - position: fixed; - width: 100%; - z-index: 1000; -} #header a.headerlink { text-decoration: none; } diff --git a/openslides/core/static/js/core/base.js b/openslides/core/static/js/core/base.js index c30b81050..1dea1621a 100644 --- a/openslides/core/static/js/core/base.js +++ b/openslides/core/static/js/core/base.js @@ -53,13 +53,12 @@ angular.module('OpenSlidesApp.core', [ .factory('autoupdate', [ 'DS', - '$rootScope', 'REALM', 'ProjectorID', - function (DS, $rootScope, REALM, ProjectorID) { + '$q', + function (DS, REALM, ProjectorID, $q) { var socket = null; var recInterval = null; - $rootScope.connected = false; var websocketProtocol; if (location.protocol == 'https:') { @@ -79,6 +78,8 @@ angular.module('OpenSlidesApp.core', [ var Autoupdate = {}; Autoupdate.messageReceivers = []; + // We use later a promise to defer the first message of the established ws connection. + Autoupdate.firstMessageDeferred = $q.defer(); Autoupdate.onMessage = function (receiver) { Autoupdate.messageReceivers.push(receiver); }; @@ -90,11 +91,7 @@ angular.module('OpenSlidesApp.core', [ Autoupdate.newConnect = function () { socket = new WebSocket(websocketProtocol + '//' + location.host + websocketPath); clearInterval(recInterval); - socket.onopen = function () { - $rootScope.connected = true; - }; socket.onclose = function () { - $rootScope.connected = false; socket = null; recInterval = setInterval(function () { Autoupdate.newConnect(); @@ -104,12 +101,50 @@ angular.module('OpenSlidesApp.core', [ _.forEach(Autoupdate.messageReceivers, function (receiver) { receiver(event.data); }); + // The first message is done: resolve the promise. + // TODO: check whether the promise is already resolved. + Autoupdate.firstMessageDeferred.resolve(); }; }; return Autoupdate; } ]) +.factory('operator', [ + 'User', + 'Group', + function (User, Group) { + var operator = { + user: null, + perms: [], + isAuthenticated: function () { + return !!this.user; + }, + setUser: function(user_id, user_data) { + if (user_id && user_data) { + operator.user = User.inject(user_data); + operator.perms = operator.user.getPerms(); + } else { + operator.user = null; + operator.perms = Group.get(1).permissions; + } + }, + // Returns true if the operator has at least one perm of the perms-list. + hasPerms: function(perms) { + if (typeof perms === 'string') { + perms = perms.split(' '); + } + return _.intersection(perms, operator.perms).length > 0; + }, + // Returns true if the operator is a member of group. + isInGroup: function(group) { + return _.indexOf(operator.user.groups_id, group.id) > -1; + }, + }; + return operator; + } +]) + // gets all in OpenSlides available languages .factory('Languages', [ 'gettext', @@ -227,7 +262,7 @@ angular.module('OpenSlidesApp.core', [ var deletedElements = []; var collectionString = key; _.forEach(list, function(data) { - // uncomment this line for debugging to log all autoupdates: + // Uncomment this line for debugging to log all autoupdates: // console.log("Received object: " + data.collection + ", " + data.id); // remove (=eject) object from local DS store @@ -299,7 +334,6 @@ angular.module('OpenSlidesApp.core', [ ]) // Template hooks - .factory('templateHooks', [ function () { var hooks = {}; diff --git a/openslides/core/static/js/core/projector.js b/openslides/core/static/js/core/projector.js index 4e7bbb61d..264bd19a6 100644 --- a/openslides/core/static/js/core/projector.js +++ b/openslides/core/static/js/core/projector.js @@ -8,6 +8,13 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core']) // Can be used to find out if the projector or the side is used .constant('REALM', 'projector') +.run([ + 'autoupdate', + function (autoupdate) { + autoupdate.newConnect(); + } +]) + // Provider to register slides in a .config() statement. .provider('slides', [ function() { @@ -84,10 +91,8 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core']) '$scope', '$location', 'gettext', - 'loadGlobalData', 'Projector', - function($scope, $location, gettext, loadGlobalData, Projector) { - loadGlobalData(); + function($scope, $location, gettext, Projector) { $scope.error = ''; // watch for changes in Projector diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index 90a2aebef..2196f7833 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -5,6 +5,7 @@ // The core module for the OpenSlides site angular.module('OpenSlidesApp.core.site', [ 'OpenSlidesApp.core', + 'OpenSlidesApp.core.start', 'OpenSlidesApp.poll.majority', 'ui.router', 'angular-loading-bar', @@ -77,10 +78,7 @@ angular.module('OpenSlidesApp.core.site', [ this.$get = ['operator', function(operator) { return { registerScope: function (scope) { - var that = this; this.scope = scope; - this.updateMainMenu(); - // TODO: operator.onOperatorChange(function () {that.updateMainMenu();}); }, updateMainMenu: function () { this.scope.elements = this.getElements(); @@ -660,28 +658,6 @@ angular.module('OpenSlidesApp.core.site', [ } ]) -.directive('routeLoadingIndicator', [ - '$rootScope', - '$state', - 'gettext', - function($rootScope, $state, gettext) { - gettext('Loading ...'); - return { - restrict: 'E', - template: "

Loading ...

", - link: function(scope, elem, attrs) { - scope.isRouteLoading = false; - $rootScope.$on('$stateChangeStart', function() { - scope.isRouteLoading = true; - }); - $rootScope.$on('$stateChangeSuccess', function() { - scope.isRouteLoading = false; - }); - } - }; - } -]) - /* This directive provides a csv import template. * Papa Parse is used to parse the csv file. Accepted attributes: * * change: diff --git a/openslides/core/static/js/core/start.js b/openslides/core/static/js/core/start.js index 3bbe85344..31586d133 100644 --- a/openslides/core/static/js/core/start.js +++ b/openslides/core/static/js/core/start.js @@ -10,8 +10,10 @@ angular.module('OpenSlidesApp.core.start', []) '$state', 'autoupdate', 'operator', - function($http, $rootScope, $state, autoupdate, operator) { - // Put the operator into the root scope + 'Group', + 'mainMenu', + function($http, $rootScope, $state, autoupdate, operator, Group, mainMenu) { + $rootScope.startupWaitingEnabled = true; $http.get('/users/whoami/').success(function(data) { $rootScope.guest_enabled = data.guest_enabled; if (data.user_id === null && !data.guest_enabled) { @@ -19,46 +21,15 @@ angular.module('OpenSlidesApp.core.start', []) $state.go('login', {guest_enabled: data.guest_enabled}); } else { autoupdate.newConnect(); - // TODO: Connect websocket - // Then operator.setUser(data.user_id, data.user); $rootScope.operator = operator; + autoupdate.firstMessageDeferred.promise.then(function () { + operator.setUser(data.user_id, data.user); + $rootScope.operator = operator; + mainMenu.updateMainMenu(); + $rootScope.startupWaitingEnabled = false; + }); } }); } -]) - -.factory('operator', [ - 'Group', - 'User', - function (User, Group) { - var operator = { - user: null, - perms: [], - isAuthenticated: function () { - return !!this.user; - }, - setUser: function(user_id, user_data) { - if (user_id && user_data) { - operator.user = User.inject(user_data); - operator.perms = operator.user.getPerms(); - } else { - operator.user = null; - operator.perms = Group.get(1).permissions; - } - }, - // Returns true if the operator has at least one perm of the perms-list. - hasPerms: function(perms) { - if (typeof perms === 'string') { - perms = perms.split(' '); - } - return _.intersection(perms, operator.perms).length > 0; - }, - // Returns true if the operator is a member of group. - isInGroup: function(group) { - return _.indexOf(operator.user.groups_id, group.id) > -1; - }, - }; - return operator; - } -]) +]); }()); diff --git a/openslides/core/static/templates/index.html b/openslides/core/static/templates/index.html index 14bcab87c..b2318cec7 100644 --- a/openslides/core/static/templates/index.html +++ b/openslides/core/static/templates/index.html @@ -20,9 +20,15 @@
+ +
+
+

+
+
+