diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 653596c23..3ab4e406f 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -1883,6 +1883,7 @@ define([ If changes are made to your drive in the interim, they will trigger an update. */ + // NOTE: The callback must stay SYNCHRONOUS var LIMIT_REFRESH_RATE = 30000; // milliseconds UIElements.createUsageBar = function (common, cb) { if (AppConfig.hideUsageBar) { return cb('USAGE_BAR_HIDDEN'); } diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 147f0c05c..1d6b8850c 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -535,7 +535,6 @@ define([ // manager config.loggedIn = APP.loggedIn; config.sframeChan = sframeChan; - // XXX Teams. provide team id var manager = ProxyManager.createInner(files, sframeChan, edPublic, config); var LS = makeLS(teamId); @@ -585,7 +584,6 @@ define([ var virtualCategories = [SEARCH, RECENT, OWNED, TAGS]; - // XXX Teams. not logged in should not be allowe din the team APP if (!APP.loggedIn) { $tree.hide(); if (APP.newSharedFolder) { @@ -4318,7 +4316,6 @@ define([ refresh(); UI.removeLoadingScreen(); - // XXX Teams. should provide a team ID (or null for main drive) sframeChan.query('Q_DRIVE_GETDELETED', null, function (err, data) { var ids = manager.findChannels(data); var titles = []; @@ -4331,6 +4328,10 @@ define([ if (!titles.length) { return; } UI.log(Messages._getKey('fm_deletedPads', [titles.join(', ')])); }); + + return { + refresh: refresh + }; }; return { diff --git a/www/common/outer/team.js b/www/common/outer/team.js index 86551c4eb..2c3d59e1d 100644 --- a/www/common/outer/team.js +++ b/www/common/outer/team.js @@ -145,11 +145,10 @@ define([ })); Object.keys(teams).forEach(function (id) { - // XXX waitFor? // only if we want to make sure teams are loaded before remore the loading screen - openChannel(ctx, teams[id], id, function () { + openChannel(ctx, teams[id], id, waitFor(function () { console.error('team '+id+' ready'); - }); + })); }); team.getTeam = function (id) { @@ -169,6 +168,9 @@ define([ // Only the team app will subscribe to events? return void subscribe(ctx, data, clientId, cb); } + if (cmd === 'LIST_TEAMS') { + return void cb(ctx.teams); + } }; return team; diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 6b4fc96aa..2ac9bb07f 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -692,9 +692,10 @@ define([ }); ctx.sframeChan.ready(); - cb(funcs); Mailbox.create(funcs); + + cb(funcs); }); } }; }); diff --git a/www/drive/inner.js b/www/drive/inner.js index 99ce01f56..fd0101154 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -217,7 +217,7 @@ define([ if (!proxy.drive || typeof(proxy.drive) !== 'object') { throw new Error("Corrupted drive"); } - DriveUI.create(common, { + var drive = DriveUI.create(common, { proxy: proxy, folders: folders, updateObject: updateObject, @@ -228,13 +228,13 @@ define([ var onDisconnect = function (noAlert) { setEditable(false); - if (APP.refresh) { APP.refresh(); } + if (drive.refresh) { drive.refresh(); } APP.toolbar.failed(); if (!noAlert) { UI.alert(Messages.common_connectionLost, undefined, true); } }; var onReconnect = function (info) { setEditable(true); - if (APP.refresh) { APP.refresh(); } + if (drive.refresh) { drive.refresh(); } APP.toolbar.reconnecting(info.myId); UI.findOKButton().click(); }; diff --git a/www/team/app-team.less b/www/team/app-team.less index e2cf57fae..00f3e3b38 100644 --- a/www/team/app-team.less +++ b/www/team/app-team.less @@ -1,5 +1,6 @@ @import (reference) '../../customize/src/less2/include/framework.less'; @import (reference) '../../customize/src/less2/include/drive.less'; +@import (reference) '../../customize/src/less2/include/sidebar-layout.less'; &.cp-app-team { .framework_min_main( @@ -9,5 +10,21 @@ ); .drive_main(); + .sidebar-layout_main(); + + .cp-app-team-container { + flex: 1; + display: flex; + width: 100%; + flex-flow: row; + .cp-app-team-drive { + flex: 1; + display: flex; + &.hidden { + display: none; + } + } + + } } diff --git a/www/team/inner.html b/www/team/inner.html index 1c5e2b0bf..cd965c3c2 100644 --- a/www/team/inner.html +++ b/www/team/inner.html @@ -10,14 +10,19 @@ -
-
-
-
-
-
-
+
+
+
diff --git a/www/team/inner.js b/www/team/inner.js index 2a4a80d51..58139e6c9 100644 --- a/www/team/inner.js +++ b/www/team/inner.js @@ -28,6 +28,7 @@ define([ Messages) { var APP = {}; + var driveAPP = {}; var SHARED_FOLDER_NAME = Messages.fm_sharedFolderName; var copyObjectValue = function (objRef, objToCopy) { @@ -58,26 +59,155 @@ define([ var updateObject = function (sframeChan, obj, cb) { sframeChan.query('Q_DRIVE_GETOBJECT', null, function (err, newObj) { copyObjectValue(obj, newObj); - if (!APP.loggedIn && APP.newSharedFolder) { + if (!driveAPP.loggedIn && driveAPP.newSharedFolder) { obj.drive.sharedFolders = obj.drive.sharedFolders || {}; - obj.drive.sharedFolders[APP.newSharedFolder] = {}; + obj.drive.sharedFolders[driveAPP.newSharedFolder] = {}; } cb(); }); }; - var history = { - isHistoryMode: false, + var setEditable = DriveUI.setEditable; + + var mainCategories = { + 'general': [ + 'cp-team-info', + ], + 'list': [ + 'cp-team-list', + ], + 'create': [ + 'cp-team-create', + ], + }; + var teamCategories = { + 'back': [ + ], + 'drive': [ + ], + 'members': [ + ], }; - var setEditable = DriveUI.setEditable; + var create = {}; + + var makeBlock = function (key, getter) { + create[key] = function (common) { + var $div = $('
', {'class': 'cp-team-' + key + ' cp-sidebarlayout-element'}); + getter(common, function (content) { + $div.append(content); + }); + return $div; + }; + }; + + makeBlock('info', function (common, cb) { + cb([ + h('h3', 'Team application'), // XXX + h('p', 'From here you can ...') // XXX + ]); + }); + + makeBlock('list', function (common, cb) { + var content = []; + var sframeChan = common.getSframeChannel(); + APP.module.execCommand('LIST_TEAMS', null, function (obj) { + + }); + }); + + // Sidebar layout + + var hideCategories = function () { + APP.$rightside.find('> div').hide(); + }; + var showCategories = function (cat) { + hideCategories(); + cat.forEach(function (c) { + APP.$rightside.find('.'+c).show(); + }); + }; + var createLeftside = function (team) { + APP.$leftside.empty(); + var $categories = $('
', {'class': 'cp-sidebarlayout-categories'}) + .appendTo(APP.$leftside); + + var categories = team ? teamCategories : mainCategories; + var active = team ? 'drive' : 'general'; + + Object.keys(categories).forEach(function (key) { + var $category = $('
', {'class': 'cp-sidebarlayout-category'}).appendTo($categories); + if (key === 'general') { $category.append($('', {'class': 'fa fa-info-circle'})); } + if (key === 'list') { $category.append($('', {'class': 'fa fa-list'})); } + if (key === 'create') { $category.append($('', {'class': 'fa fa-plus-circle'})); } + if (key === 'back') { $category.append($('', {'class': 'fa fa-arrow-left'})); } + if (key === 'members') { $category.append($('', {'class': 'fa fa-users'})); } + if (key === 'drive') { $category.append($('', {'class': 'fa fa-hdd-o'})); } + + if (key === active) { + $category.addClass('cp-leftside-active'); + } + + $category.click(function () { + if (!Array.isArray(categories[key]) && categories[key].onClick) { + categories[key].onClick(); + return; + } + $categories.find('.cp-leftside-active').removeClass('cp-leftside-active'); + $category.addClass('cp-leftside-active'); + showCategories(categories[key]); + }); - var setHistory = function (bool, update) { - history.isHistoryMode = bool; - setEditable(!bool); - if (!bool && update) { - history.onLeaveHistory(); + $category.append(Messages['team_cat_'+key] || key); // XXX + }); + showCategories(categories[active]); + }; + + var buildUI = function (common, team) { + var $rightside = APP.$rightside; + $rightside.empty(); + var addItem = function (cssClass) { + var item = cssClass.slice(8); + if (typeof (create[item]) === "function") { + $rightside.append(create[item](common)); + } + }; + var categories = team ? teamCategories : mainCategories; + for (var cat in categories) { + if (!Array.isArray(categories[cat])) { continue; } + categories[cat].forEach(addItem); } + + createLeftside(team); + }; + + // Team APP + + var loadTeam = function (common) { + var sframeChan = common.getSframeChannel(); + nThen(function (waitFor) { + updateObject(sframeChan, proxy, waitFor(function () { + updateSharedFolders(sframeChan, null, proxy.drive, folders, waitFor()); + })); + }).nThen(function (waitFor) { + if (!proxy.drive || typeof(proxy.drive) !== 'object') { + throw new Error("Corrupted drive"); + } + var drive = DriveUI.create(common, { + proxy: proxy, + folders: folders, + updateObject: updateObject, + updateSharedFolders: updateSharedFolders, + APP: driveAPP + }); + driveAPP.refresh = drive.refresh; + }); + buildUI(common, true); + }; + + var loadMain = function (common) { + buildUI(common); + UI.removeLoadingScreen(); }; var main = function () { @@ -91,151 +221,86 @@ define([ UI.addLoadingScreen(); })); window.cryptpadStore.getAll(waitFor(function (val) { - APP.store = JSON.parse(JSON.stringify(val)); + driveAPP.store = JSON.parse(JSON.stringify(val)); })); SFCommon.create(waitFor(function (c) { common = c; })); }).nThen(function (waitFor) { - var privReady = Util.once(waitFor()); - var metadataMgr = common.getMetadataMgr(); - if (JSON.stringify(metadataMgr.getPrivateData()) !== '{}') { - privReady(); - return; - } - metadataMgr.onChange(function () { - if (typeof(metadataMgr.getPrivateData().readOnly) === 'boolean') { - readOnly = APP.readOnly = metadataMgr.getPrivateData().readOnly; - privReady(); - } - }); + APP.$container = $('#cp-sidebarlayout-container'); + APP.$leftside = $('
', {id: 'cp-sidebarlayout-leftside'}).appendTo(APP.$container); + APP.$rightside = $('
', {id: 'cp-sidebarlayout-rightside'}).appendTo(APP.$container); + sFrameChan = common.getSframeChannel(); + sFrameChan.onReady(waitFor()); }).nThen(function (waitFor) { - APP.loggedIn = common.isLoggedIn(); - if (!APP.loggedIn) { Feedback.send('ANONYMOUS_DRIVE'); } - APP.$body = $('body'); - APP.$bar = $('#cp-toolbar'); - - common.setTabTitle(Messages.type.drive); - + var sframeChan = common.getSframeChannel(); var metadataMgr = common.getMetadataMgr(); var privateData = metadataMgr.getPrivateData(); - if (privateData.newSharedFolder) { - APP.newSharedFolder = privateData.newSharedFolder; - } + readOnly = driveAPP.readOnly = metadataMgr.getPrivateData().readOnly; - var sframeChan = common.getSframeChannel(); - updateObject(sframeChan, proxy, waitFor(function () { - updateSharedFolders(sframeChan, null, proxy.drive, folders, waitFor()); - })); - }).nThen(function () { - var sframeChan = common.getSframeChannel(); + driveAPP.loggedIn = common.isLoggedIn(); + if (!driveAPP.loggedIn) { throw new Error('NOT_LOGGED_IN'); } + + common.setTabTitle('TEAMS'); // XXX + + // Drive data var metadataMgr = common.getMetadataMgr(); var privateData = metadataMgr.getPrivateData(); - - APP.disableSF = !privateData.enableSF && AppConfig.disableSharedFolders; - if (APP.newSharedFolder && !APP.loggedIn) { - readOnly = APP.readOnly = true; - var data = folders[APP.newSharedFolder]; - if (data) { - sframeChan.query('Q_SET_PAD_TITLE_IN_DRIVE', { - title: data.metadata && data.metadata.title, - }, function () {}); - } + if (privateData.newSharedFolder) { + driveAPP.newSharedFolder = privateData.newSharedFolder; } + driveAPP.disableSF = !privateData.enableSF && AppConfig.disableSharedFolders; - // ANON_SHARED_FOLDER - var pageTitle = (!APP.loggedIn && APP.newSharedFolder) ? SHARED_FOLDER_NAME : Messages.type.drive; - + // Toolbar + var $bar = $('#cp-toolbar'); var configTb = { displayed: ['useradmin', 'pageTitle', 'newpad', 'limit', 'notifications'], - pageTitle: pageTitle, + pageTitle: 'TEAMS', // XXX metadataMgr: metadataMgr, readOnly: privateData.readOnly, sfCommon: common, - $container: APP.$bar + $container: $bar }; - var toolbar = APP.toolbar = Toolbar.create(configTb); - - var $rightside = toolbar.$rightside; - $rightside.html(''); // Remove the drawer if we don't use it to hide the toolbar - APP.$displayName = APP.$bar.find('.' + Toolbar.constants.username); + var toolbar = Toolbar.create(configTb); + toolbar.$rightside.hide(); // hide the bottom part of the toolbar + // Update the name in the user menu + driveAPP.$displayName = $bar.find('.' + Toolbar.constants.username); + metadataMgr.onChange(function () { + var name = metadataMgr.getUserData().name || Messages.anonymous; + driveAPP.$displayName.text(name); + }); /* add the usage */ - if (APP.loggedIn) { + // XXX Teams + if (false) { + // Synchronous callback... common.createUsageBar(function (err, $limitContainer) { if (err) { return void DriveUI.logError(err); } - APP.$limit = $limitContainer; + driveAPP.$limit = $limitContainer; }, true); } - /* add a history button */ - APP.histConfig = { - onLocal: function () { - UI.addLoadingScreen({ loadingText: Messages.fm_restoreDrive }); - var data = {}; - if (history.sfId) { - copyObjectValue(folders[history.sfId], history.currentObj); - data.sfId = history.sfId; - data.drive = history.currentObj; - } else { - proxy.drive = history.currentObj.drive; - data.drive = history.currentObj.drive; - } - sframeChan.query("Q_DRIVE_RESTORE", data, function () { - UI.removeLoadingScreen(); - }, { - timeout: 5 * 60 * 1000 - }); - }, - onOpen: function () {}, - onRemote: function () {}, - setHistory: setHistory, - applyVal: function (val) { - var obj = JSON.parse(val || '{}'); - history.currentObj = obj; - history.onEnterHistory(obj); - }, - $toolbar: APP.$bar, - }; - - // Add a "Burn this drive" button - if (!APP.loggedIn) { - APP.$burnThisDrive = common.createButton(null, true).click(function () { - UI.confirm(Messages.fm_burnThisDrive, function (yes) { - if (!yes) { return; } - common.getSframeChannel().event('EV_BURN_ANON_DRIVE'); - }, null, true); - }).attr('title', Messages.fm_burnThisDriveButton) - .removeClass('fa-question') - .addClass('fa-ban'); - } - - metadataMgr.onChange(function () { - var name = metadataMgr.getUserData().name || Messages.anonymous; - APP.$displayName.text(name); + // Load the Team module + APP.module = common.makeUniversal('team', { + onEvent: onEvent }); $('body').css('display', ''); - if (!proxy.drive || typeof(proxy.drive) !== 'object') { - throw new Error("Corrupted drive"); + if (privateData.teamId) { + loadTeam(common, privateData.teamId); + } else { + loadMain(common); } - DriveUI.create(common, { - proxy: proxy, - folders: folders, - updateObject: updateObject, - updateSharedFolders: updateSharedFolders, - history: history, - APP: APP - }); + var onDisconnect = function (noAlert) { setEditable(false); - if (APP.refresh) { APP.refresh(); } - APP.toolbar.failed(); + if (driveAPP.refresh) { driveAPP.refresh(); } + toolbar.failed(); if (!noAlert) { UI.alert(Messages.common_connectionLost, undefined, true); } }; var onReconnect = function (info) { setEditable(true); - if (APP.refresh) { APP.refresh(); } - APP.toolbar.reconnecting(info.myId); + if (driveAPP.refresh) { driveAPP.refresh(); } + toolbar.reconnecting(info.myId); UI.findOKButton().click(); };