define([ 'jquery', '/common/toolbar.js', '/common/drive-ui.js', '/common/common-util.js', '/common/common-hash.js', '/common/common-interface.js', '/common/common-ui-elements.js', '/common/common-feedback.js', '/common/common-constants.js', '/bower_components/nthen/index.js', '/common/sframe-common.js', '/common/proxy-manager.js', '/common/userObject.js', '/common/inner/common-mediatag.js', '/common/hyperscript.js', '/customize/application_config.js', '/common/messenger-ui.js', '/common/inner/invitation.js', '/common/make-backup.js', '/customize/messages.js', '/bower_components/file-saver/FileSaver.min.js', 'css!/bower_components/bootstrap/dist/css/bootstrap.min.css', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css', 'less!/teams/app-team.less', ], function ( $, Toolbar, DriveUI, Util, Hash, UI, UIElements, Feedback, Constants, nThen, SFCommon, ProxyManager, UserObject, MT, h, AppConfig, MessengerUI, InviteInner, Backup, Messages) { var APP = { teams: {} }; var driveAPP = {}; var saveAs = window.saveAs; //var SHARED_FOLDER_NAME = Messages.fm_sharedFolderName; var copyObjectValue = function (objRef, objToCopy) { for (var k in objRef) { delete objRef[k]; } $.extend(true, objRef, objToCopy); }; var updateSharedFolders = function (sframeChan, manager, drive, folders, cb) { if (!drive || !drive.sharedFolders) { return void cb(); } var r = drive.restrictedFolders = drive.restrictedFolders || {}; var oldIds = Object.keys(folders); nThen(function (waitFor) { Object.keys(drive.sharedFolders).forEach(function (fId) { var sfData = drive.sharedFolders[fId] || {}; var href = UserObject.getHref(sfData, APP.cryptor); var parsed = Hash.parsePadUrl(href); var secret = Hash.getSecrets('drive', parsed.hash, sfData.password); sframeChan.query('Q_DRIVE_GETOBJECT', { sharedFolder: fId }, waitFor(function (err, newObj) { if (newObj && newObj.restricted) { r[fId] = drive.sharedFolders[fId]; if (!r[fId].title) { r[fId].title = r[fId].lastTitle; } } if (newObj && (newObj.deprecated || newObj.restricted)) { delete folders[fId]; delete drive.sharedFolders[fId]; if (manager && manager.folders) { delete manager.folders[fId]; } return; } folders[fId] = folders[fId] || {}; copyObjectValue(folders[fId], newObj); folders[fId].readOnly = !secret.keys.secondaryKey; if (manager && oldIds.indexOf(fId) === -1) { manager.addProxy(fId, { proxy: folders[fId] }, null, secret.keys.secondaryKey); } var readOnly = !secret.keys.editKeyStr; if (!manager || !manager.folders[fId]) { return; } manager.folders[fId].userObject.setReadOnly(readOnly, secret.keys.secondaryKey); manager.folders[fId].offline = newObj.offline; })); }); // Remove from memory folders that have been deleted from the drive remotely oldIds.forEach(function (fId) { if (!drive.sharedFolders[fId]) { delete folders[fId]; delete drive.sharedFolders[fId]; if (manager && manager.folders) { delete manager.folders[fId]; } } }); }).nThen(function () { cb(); }); }; var updateObject = function (sframeChan, obj, cb) { sframeChan.query('Q_DRIVE_GETOBJECT', null, function (err, newObj) { copyObjectValue(obj, newObj); cb(); }); }; var setEditable = DriveUI.setEditable; var closeTeam = function (common, cb) { var sframeChan = common.getSframeChannel(); APP.module.execCommand('SUBSCRIBE', null, function () { sframeChan.query('Q_SET_TEAM', null, function (err) { if (err) { return void console.error(err); } if (APP.drive && APP.drive.close) { APP.drive.close(); } $('.cp-toolbar-title-value').text(Messages.type.teams); sframeChan.event('EV_SET_TAB_TITLE', Messages.type.teams); APP.team = null; APP.teamEdPublic = null; APP.drive = null; APP.cryptor = null; APP.toolbar.$bottomR.empty(); APP.toolbar.$bottomM.empty(); APP.toolbar.$bottomL.empty(); APP.buildUI(common); if (APP.usageBar) { APP.usageBar.stop(); APP.usageBar = null; } if (cb) { cb(common); } }); }); }; var mainCategories = { 'list': [ 'cp-team-list', ], 'create': [ 'cp-team-create', ], 'general': [ 'cp-team-info', ], 'link': [ 'cp-team-link', ], }; var teamCategories = { 'back': { onClick: function (common) { closeTeam(common); } }, 'drive': [ 'cp-team-drive' ], 'members': [ 'cp-team-roster' ], 'chat': [ 'cp-team-chat' ], 'admin': [ 'cp-team-edpublic', 'cp-team-name', 'cp-team-avatar', 'cp-team-export', 'cp-team-delete', ], }; var create = {}; // 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 = APP.createLeftSide = function (common, team, teamAdmin) { APP.$leftside.empty(); var $categories = $('
', {'class': 'cp-sidebarlayout-categories'}) .appendTo(APP.$leftside); var hash = common.getMetadataMgr().getPrivateData().teamInviteHash && mainCategories.link; var categories = team ? teamCategories : mainCategories; var active = team ? 'drive' : (hash ? 'link' : 'list'); if (team && APP.team) { var $category = $('
', {'class': 'cp-sidebarlayout-category cp-team-cat-header'}).appendTo($categories); var avatar = h('div.cp-avatar'); var $avatar = $(avatar); APP.module.execCommand('GET_TEAM_METADATA', { teamId: APP.team }, function (obj) { if (obj && obj.error) { return void UI.warn(Messages.error); } // Refresh offline state APP.teams[APP.team] = APP.teams[APP.team] || {}; APP.teams[APP.team].offline = obj.offline; common.displayAvatar($avatar, obj.avatar, obj.name); $category.append($avatar); $avatar.append(h('span.cp-sidebarlayout-category-name', obj.name)); }); } Object.keys(categories).forEach(function (key) { if (key === 'admin' && !teamAdmin) { return; } var $category = $('
', {'class': 'cp-sidebarlayout-category cp-team-cat-'+key}).appendTo($categories); if (key === 'general') { $category.append($('', {'class': 'fa fa-info-circle'})); } if (key === 'list') { $category.append($('', {'class': 'fa fa-list cp-team-cat-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 === 'chat') { $category.append($('', {'class': 'fa fa-comments'})); } if (key === 'drive') { $category.append($('', {'class': 'fa fa-hdd-o'})); } if (key === 'admin') { $category.append($('', {'class': 'fa fa-cogs'})); } if (key === 'link') { $category.append($('', {'class': 'fa fa-envelope'})); } if (key === active) { $category.addClass('cp-leftside-active'); } $category.click(function () { if (!Array.isArray(categories[key]) && categories[key].onClick) { categories[key].onClick(common); return; } if (active === key) { return; } active = key; if (key === 'drive' || key === 'chat') { APP.$rightside.addClass('cp-rightside-drive'); APP.$leftside.addClass('cp-leftside-narrow'); } else { APP.$rightside.removeClass('cp-rightside-drive'); APP.$leftside.removeClass('cp-leftside-narrow'); } if (key === 'chat') { $category.find('.cp-team-chat-notification').removeClass('cp-team-chat-notification'); } $categories.find('.cp-leftside-active').removeClass('cp-leftside-active'); $category.addClass('cp-leftside-active'); showCategories(categories[key]); }); $category.append(h('span.cp-sidebarlayout-category-name', Messages['team_cat_'+key] || key)); }); if (active === 'drive') { APP.$rightside.addClass('cp-rightside-drive'); APP.$leftside.addClass('cp-leftside-narrow'); } else { APP.$rightside.removeClass('cp-rightside-drive'); APP.$leftside.removeClass('cp-leftside-narrow'); } showCategories(categories[active]); }; var buildUI = APP.buildUI = function (common, team, teamAdmin) { 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(common, team, teamAdmin); }; // Team APP var loadTeam = function (common, id) { var metadataMgr = common.getMetadataMgr(); var privateData = metadataMgr.getPrivateData(); var sframeChan = common.getSframeChannel(); var proxy = {}; var folders = {}; nThen(function (waitFor) { updateObject(sframeChan, proxy, waitFor(function () { updateSharedFolders(sframeChan, null, proxy.drive, folders, waitFor()); })); }).nThen(function () { if (!proxy.drive || typeof(proxy.drive) !== 'object') { throw new Error("Corrupted drive"); } driveAPP.team = id; // Provide secondaryKey var teamData = (privateData.teams || {})[id] || {}; driveAPP.readOnly = !teamData.hasSecondaryKey; if (APP.usageBar) { APP.usageBar.stop(); } APP.usageBar = undefined; if (!driveAPP.readOnly) { APP.usageBar = common.createUsageBar(APP.team, function (err, $limitContainer) { if (err) { return void DriveUI.logError(err); } $limitContainer.attr('title', Messages.team_quota); }, true); } driveAPP.online = !teamData.offline; var drive = DriveUI.create(common, { proxy: proxy, folders: folders, updateObject: updateObject, updateSharedFolders: updateSharedFolders, $limit: APP.usageBar && APP.usageBar.$container, toolbar: APP.toolbar, APP: driveAPP, edPublic: APP.teamEdPublic, editKey: teamData.secondaryKey }); APP.drive = drive; driveAPP.refresh = drive.refresh; if (APP.teams[id] && APP.teams[id].offline) { setEditable(false); drive.refresh(); } }); }; var loadMain = function (common) { buildUI(common); UI.removeLoadingScreen(); }; // Rightside elements var makeBlock = function (key, getter, full) { var safeKey = key.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); create[key] = function (common) { var $div = $('
', {'class': 'cp-team-' + key + ' cp-sidebarlayout-element'}); if (full) { $('