diff --git a/customize.dist/loading.js b/customize.dist/loading.js index fe86bf266..dd269fa60 100644 --- a/customize.dist/loading.js +++ b/customize.dist/loading.js @@ -1,6 +1,6 @@ // dark #326599 // light #4591c4 -define([], function () { +define(['/customize/messages.js'], function (Messages) { var loadingStyle = (function(){/* #cp-loading { visibility: visible; @@ -199,6 +199,13 @@ p.cp-password-info{ white-space: nowrap; text-overflow: ellipsis; } +.cp-loading-progress-list li i { + width: 22px; +} +.cp-loading-progress-list li span{ + margin-left: 20px; +} + .cp-loading-progress-bar { height: 24px; background: white; @@ -257,9 +264,57 @@ button.primary:hover{ '
', '', '
', + '
', + '
', + '
', + '
', '

', '' ].join(''); + + // XXX + var types = ['less', 'drive', 'migrate', 'sf', 'team', 'pad']; + Messages.loading_state_0 = "Less"; + Messages.loading_state_1 = "Drive"; + Messages.loading_state_2 = "Migrate"; + Messages.loading_state_3 = "SF"; + Messages.loading_state_4 = "Team"; + Messages.loading_state_5 = "Pad"; + var current; + var makeList = function (data) { + var c = types.indexOf(data.type); + current = c; + var getLi = function (i) { + var check = (i < c || (i === c && data.progress === 100)) ? 'fa-check-square-o' + : 'fa-square-o'; + var percent = i < c ? '(100%)' : (i === c ? '('+Math.floor(data.progress)+'%)' : '(0%)'); + return '
  • '+Messages['loading_state_'+i]+'' + + ''+percent+''; + }; + var list = ''; + return list; + }; + var makeBar = function (data) { + var c = types.indexOf(data.type); + var l = types.length; + var p = (data.progress / l) + (100 * c / l); + var bar = '
    '+ + '
    '+ + '
    '; + return bar; + }; + + var updateLoadingProgress = function (data) { + var c = types.indexOf(data.type); + if (c < current) { return console.error(data); } + document.querySelector('.cp-loading-progress-list').innerHTML = makeList(data); + document.querySelector('.cp-loading-progress-container').innerHTML = makeBar(data); + }; + window.CryptPad_updateLoadingProgress = updateLoadingProgress; window.CryptPad_loadingError = function (err) { document.querySelector('.cp-loading-spinner-container').setAttribute('style', 'display:none;'); document.querySelector('#cp-loading-message').setAttribute('style', 'display:block;'); diff --git a/customize.dist/messages.js b/customize.dist/messages.js index 11d814540..40dbbfb95 100755 --- a/customize.dist/messages.js +++ b/customize.dist/messages.js @@ -52,13 +52,12 @@ require.config({ }); var req = [ - '/common/common-util.js', '/customize/application_config.js', '/customize/translations/messages.js' ]; if (language && map[language]) { req.push('/customize/translations/messages.' + language + '.js'); } -define(req, function(Util, AppConfig, Default, Language) { +define(req, function(AppConfig, Default, Language) { map.en = 'English'; var defaultLanguage = 'en'; @@ -78,15 +77,15 @@ define(req, function(Util, AppConfig, Default, Language) { var extend = function (a, b) { for (var k in b) { - if (Util.isObject(b[k])) { - a[k] = Util.isObject(a[k]) ? a[k] : {}; - extend(a[k], b[k]); - continue; - } if (Array.isArray(b[k])) { a[k] = b[k].slice(); continue; } + if (b[k] && typeof(b[k]) === "object") { + a[k] = (a[k] && typeof(a[k]) === "object" && !Array.isArray(a[k])) ? a[k] : {}; + extend(a[k], b[k]); + continue; + } a[k] = b[k] || a[k]; } }; diff --git a/www/common/LessLoader.js b/www/common/LessLoader.js index 2c3de14cc..0a8a1e914 100644 --- a/www/common/LessLoader.js +++ b/www/common/LessLoader.js @@ -150,6 +150,7 @@ define([ }).nThen(function () { cb(); }); }; + var idx = 0; module.exports.load = function (url /*:string*/, cb /*:()=>void*/, stack /*:?Array*/) { var btime = stack ? null : +new Date(); stack = stack || []; @@ -163,6 +164,12 @@ define([ cb(); }; stack.push(url); + if (window.CryptPad_updateLoadingProgress) { + window.CryptPad_updateLoadingProgress({ + type: 'less', + progress: idx++ + }); + } cacheGet(url, function (css) { if (css) { return void loadSubmodulesAndInject(css, url, done, stack); } console.debug('CACHE MISS ' + url); diff --git a/www/common/common-interface.js b/www/common/common-interface.js index 76dec3dd8..b6e58e527 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -888,6 +888,11 @@ define([ } }; UI.updateLoadingProgress = function (data, isDrive) { + if (window.CryptPad_updateLoadingProgress) { + window.CryptPad_updateLoadingProgress(data); + } + // XXX + /* var $loading = $('#' + LOADING); if (!$loading.length || loading.error) { return; } $loading.find('.cp-loading-progress').show(); @@ -939,6 +944,7 @@ define([ } } } + */ }; UI.removeLoadingScreen = function (cb) { // Release the test blocker, hopefully every test has been registered. diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index df05d8a3e..7e57398c5 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -1373,11 +1373,15 @@ define([ } } }; - var loadUniversal = function (Module, type, waitFor) { + var loadUniversal = function (Module, type, waitFor, clientId) { if (store.modules[type]) { return; } store.modules[type] = Module.init({ Store: Store, store: store, + updateLoadingProgress: function (data) { + data.type = "team"; + postMessage(clientId, 'LOADING_DRIVE', data); + }, updateMetadata: function () { broadcast([], "UPDATE_METADATA"); }, @@ -2480,9 +2484,6 @@ define([ addSharedFolderHandler(); nThen(function (waitFor) { - postMessage(clientId, 'LOADING_DRIVE', { - state: 2 - }); userObject.migrate(waitFor()); }).nThen(function (waitFor) { initAnonRpc(null, null, waitFor()); @@ -2490,22 +2491,25 @@ define([ }).nThen(function (waitFor) { Migrate(proxy, waitFor(), function (version, progress) { postMessage(clientId, 'LOADING_DRIVE', { - state: (2 + (version / 10)), + type: 'migrate', progress: progress }); }, store); }).nThen(function (waitFor) { - postMessage(clientId, 'LOADING_DRIVE', { - state: 3 - }); userObject.fixFiles(); - SF.loadSharedFolders(Store, store.network, store, userObject, waitFor); + SF.loadSharedFolders(Store, store.network, store, userObject, waitFor, function (obj) { + var data = { + type: 'sf', + progress: 100*obj.progress/obj.max + }; + postMessage(clientId, 'LOADING_DRIVE', data); + }); loadCursor(); loadOnlyOffice(); loadUniversal(Messenger, 'messenger', waitFor); store.messenger = store.modules['messenger']; loadUniversal(Profile, 'profile', waitFor); - loadUniversal(Team, 'team', waitFor); + loadUniversal(Team, 'team', waitFor, clientId); loadUniversal(History, 'history', waitFor); cleanFriendRequests(); }).nThen(function () { @@ -2607,6 +2611,12 @@ define([ if (!hash) { return void cb({error: '[Store.init] Unable to find or create a drive hash. Aborting...'}); } + + var updateProgress = function (data) { + data.type = 'drive'; + postMessage(clientId, 'LOADING_DRIVE', data); + }; + // No password for drive var secret = Hash.getSecrets('drive', hash); store.driveChannel = secret.channel; @@ -2620,6 +2630,7 @@ define([ userName: 'fs', logLevel: 1, ChainPad: ChainPad, + updateProgress: updateProgress, classic: true, }; var rt = window.rt = Listmap.create(listmapConfig); @@ -2643,7 +2654,6 @@ define([ && !drive['filesData']) { drive[Constants.oldStorageKey] = []; } - postMessage(clientId, 'LOADING_DRIVE', { state: 1 }); // Drive already exist: return the existing drive, don't load data from legacy store onReady(clientId, returned, cb); }) diff --git a/www/common/outer/sharedfolder.js b/www/common/outer/sharedfolder.js index f02ea9c5a..e34cd64df 100644 --- a/www/common/outer/sharedfolder.js +++ b/www/common/outer/sharedfolder.js @@ -320,9 +320,12 @@ define([ - userObject: userObject associated to the main drive - handler: a function (sfid, rt) called for each shared folder loaded */ - SF.loadSharedFolders = function (Store, network, store, userObject, waitFor) { + SF.loadSharedFolders = function (Store, network, store, userObject, waitFor, progress) { var shared = Util.find(store.proxy, ['drive', UserObject.SHARED_FOLDERS]) || {}; + var steps = Object.keys(shared).length; + var i = 1; var w = waitFor(); + progress = progress || function () {}; nThen(function (waitFor) { Object.keys(shared).forEach(function (id) { var sf = shared[id]; @@ -330,7 +333,13 @@ define([ network: network, store: store, isNewChannel: Store.isNewChannel - }, id, sf, waitFor()); + }, id, sf, waitFor(function () { + progress({ + progress: i, + max: steps + }); + i++; + })); }); }).nThen(function () { setTimeout(w); diff --git a/www/common/outer/team.js b/www/common/outer/team.js index 2ba4e30ee..e1a85d5d6 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -328,7 +328,13 @@ define([ ctx.teams[id] = team; registerChangeEvents(ctx, team, proxy); SF.checkMigration(team.secondaryKey, proxy, team.userObject, waitFor()); - SF.loadSharedFolders(ctx.Store, ctx.store.network, team, team.userObject, waitFor); + SF.loadSharedFolders(ctx.Store, ctx.store.network, team, + team.userObject, waitFor, function (data) { + ctx.progress += 70/(ctx.numberOfTeams * data.max); + ctx.updateProgress({ + progress: ctx.progress + }); + }); }).nThen(function () { if (!team.rpc) { return; } var list = getTeamChannelList(ctx, id); @@ -361,6 +367,9 @@ define([ }; + // Progress: + // One team = (30/(#teams))% + // One shared folder = (70/(#teams * #folders))% var openChannel = function (ctx, teamData, id, _cb) { var cb = Util.once(Util.mkAsync(_cb)); @@ -501,6 +510,10 @@ define([ waitFor.abort(); } }).nThen(function () { + ctx.progress += 30/ctx.numberOfTeams; + ctx.updateProgress({ + progress: ctx.progress + }); onReady(ctx, id, lm, roster, keys, null, cb); }); }; @@ -1653,10 +1666,13 @@ define([ emit: emit, onReadyHandlers: {}, teams: {}, - updateMetadata: cfg.updateMetadata + updateMetadata: cfg.updateMetadata, + updateProgress: cfg.updateLoadingProgress, + progress: 0 }; var teams = store.proxy.teams = store.proxy.teams || {}; + ctx.numberOfTeams = Object.keys(teams).length; // Listen for changes in our access rights (if another worker receives edit access) ctx.store.proxy.on('change', ['teams'], function (o, n, p) { diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index beaf20b10..3097cf6d2 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -441,9 +441,9 @@ define([ var versionHashEl; var onInit = function () { UI.updateLoadingProgress({ - state: 2, + type: 'pad', progress: 0.1 - }, false); + }); stateChange(STATE.INITIALIZING); if ($('.cp-help-container').length) { var privateDat = cpNfInner.metadataMgr.getPrivateData(); @@ -471,8 +471,6 @@ define([ var newContentStr = cpNfInner.chainpad.getUserDoc(); if (state === STATE.DELETED) { return; } - UI.updateLoadingProgress({ state: -1 }, false); - if (toolbar) { // Check if we have a new chainpad instance toolbar.resetChainpad(cpNfInner.chainpad); @@ -708,9 +706,6 @@ define([ nThen(function (waitFor) { UI.addLoadingScreen(); SFCommon.create(waitFor(function (c) { common = c; })); - UI.updateLoadingProgress({ - state: 1 - }, false); }).nThen(function (waitFor) { common.getSframeChannel().onReady(waitFor()); }).nThen(function (waitFor) { diff --git a/www/common/sframe-chainpad-netflux-inner.js b/www/common/sframe-chainpad-netflux-inner.js index b6f4c6aaf..8e8bb84f2 100644 --- a/www/common/sframe-chainpad-netflux-inner.js +++ b/www/common/sframe-chainpad-netflux-inner.js @@ -140,7 +140,7 @@ define([ chainpad.message(content); if (isHistory && updateLoadingProgress) { updateLoadingProgress({ - state: 2, + type: 'pad', progress: isHistory }, false); isHistory++; diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index bba393afb..165b0b6f7 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -131,13 +131,7 @@ define([ if (sframeChan) { sframeChan.event('EV_LOADING_INFO', data); } }); - Cryptpad.ready(waitFor(function () { - if (sframeChan) { - sframeChan.event('EV_LOADING_INFO', { - state: -1 - }); - } - }), { + Cryptpad.ready(waitFor(), { driveEvents: cfg.driveEvents, currentPad: currentPad }); diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 8d4898911..c5f0ad26a 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -686,7 +686,8 @@ define([ }); ctx.sframeChan.on('EV_LOADING_INFO', function (data) { - UI.updateLoadingProgress(data, 'drive'); + //UI.updateLoadingProgress(data, 'drive'); + UI.updateLoadingProgress(data); }); ctx.sframeChan.on('EV_NEW_VERSION', function () {