diff --git a/customize.dist/src/less2/include/modal.less b/customize.dist/src/less2/include/modal.less index 21cc69e97..ed63ea6fd 100644 --- a/customize.dist/src/less2/include/modal.less +++ b/customize.dist/src/less2/include/modal.less @@ -15,3 +15,63 @@ } } } + +.cp-modal-container { + display: none; + + z-index: 100000; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: @colortheme_modal-dim; + + .cp-modal { + background-color: @colortheme_modal-bg; + color: @colortheme_modal-fg; + box-shadow: @colortheme_modal-shadow; + + padding: @colortheme_modal-padding; + + position: absolute; + top: 15vh; bottom: 15vh; + left: 10vw; right: 10vw; + + overflow: auto; + + font-family: @colortheme_font; + text-align: center; + + & > p { + margin-bottom: 1em; + } + + .cp-modal-form { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + } + + input { + background-color: @colortheme_modal-input; + color: @colortheme_modal-fg; + border: 0; + padding: 8px 12px; + margin: 1em; + width: 300px; + } + + .cp-modal-close { + text-shadow: none; + color: inherit; + + position: absolute; + top: 0; + right: 0; + margin: @colortheme_modal-padding; + cursor: pointer; + } + } +} diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index ed955b373..dfeb46371 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -301,6 +301,7 @@ define(function () { out.fm_filesDataName = "Tous les fichiers"; out.fm_templateName = "Modèles"; out.fm_searchName = "Recherche"; + out.fm_recentPadsName = "Pads récents"; out.fm_searchPlaceholder = "Rechercher..."; out.fm_newButton = "Nouveau"; out.fm_newButtonTitle = "Créer un nouveau pad ou un dossier, importer un fichier dans le dossier courant"; @@ -332,6 +333,7 @@ define(function () { out.fm_info_root = "Créez ici autant de dossiers que vous le souhaitez pour trier vos fichiers."; out.fm_info_unsorted = 'Contient tous les pads que vous avez ouvert et qui ne sont pas triés dans "Documents" ou déplacés vers la "Corbeille".'; // "My Documents" should match with the "out.fm_rootName" key, and "Trash" with "out.fm_trashName" out.fm_info_template = "Contient tous les fichiers que vous avez sauvés en tant que modèle afin de les réutiliser lors de la création d'un nouveau pad."; + out.fm_info_recent = "Liste les derniers pads que vous avez modifiés ou ouverts."; out.updated_0_fm_info_trash = "Vider la corbeille permet de libérer de l'espace dans votre CryptDrive"; out.fm_info_trash = out.updated_0_fm_info_trash; out.fm_info_allFiles = 'Contient tous les fichiers de "Documents", "Fichiers non triés" et "Corbeille". Vous ne pouvez pas supprimer ou déplacer des fichiers depuis cet endroit.'; // Same here diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index d5aa373df..661254f5d 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -303,6 +303,7 @@ define(function () { out.fm_filesDataName = "All files"; out.fm_templateName = "Templates"; out.fm_searchName = "Search"; + out.fm_recentPadsName = "Recent pads"; out.fm_searchPlaceholder = "Search..."; out.fm_newButton = "New"; out.fm_newButtonTitle = "Create a new pad or folder, import a file in the current folder"; @@ -334,6 +335,7 @@ define(function () { out.fm_info_root = "Create as many nested folders here as you want to sort your files."; out.fm_info_unsorted = 'Contains all the files you\'ve visited that are not yet sorted in "Documents" or moved to the "Trash".'; // "My Documents" should match with the "out.fm_rootName" key, and "Trash" with "out.fm_trashName" out.fm_info_template = 'Contains all the pads stored as templates and that you can re-use when you create a new pad.'; + out.fm_info_recent = "List the recently modified or opened pads."; out.updated_0_fm_info_trash = 'Empty your trash to free space in your CryptDrive.'; out.fm_info_trash = out.updated_0_fm_info_trash; out.fm_info_allFiles = 'Contains all the files from "Documents", "Unsorted" and "Trash". You can\'t move or remove files from here.'; // Same here diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 51a9d0dc7..a64110cea 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1427,23 +1427,37 @@ define([ return $icon; }; - common.createFileDialog = function (cfg) { + common.createModal = function (cfg) { var $body = cfg.$body || $('body'); - var $blockContainer = $body.find('#fileDialog'); + var $blockContainer = $body.find('#'+cfg.id); if (!$blockContainer.length) { - $blockContainer = $('
', {id: "fileDialog"}).appendTo($body); + $blockContainer = $('
', { + 'class': 'cp-modal-container', + 'id': cfg.id + }); } - $blockContainer.html(''); + $blockContainer.html('').appendTo($body); var $block = $('
', {'class': 'cp-modal'}).appendTo($blockContainer); $('', { - 'class': 'close fa fa-times', + 'class': 'cp-modal-close fa fa-times', 'title': Messages.filePicker_close }).click(function () { $blockContainer.hide(); }).appendTo($block); + $body.keydown(function (e) { + if (e.which === 27) { $blockContainer.hide(); } + }); + return $blockContainer; + }; + common.createFileDialog = function (cfg) { + var $blockContainer = common.createModal({ + id: 'fileDialog', + $body: cfg.$body + }); + var $block = $blockContainer.find('.cp-modal'); var $description = $('

').text(Messages.filePicker_description); $block.append($description); - var $filter = $('

', {'class': 'cp-form'}).appendTo($block); + var $filter = $('

', {'class': 'cp-modal-form'}).appendTo($block); var $container = $('', {'class': 'fileContainer'}).appendTo($block); var updateContainer = function () { $container.html(''); @@ -1483,9 +1497,6 @@ define([ $blockContainer.hide(); })); updateContainer(); - $body.keydown(function (e) { - if (e.which === 27) { $blockContainer.hide(); } - }); $blockContainer.show(); }; diff --git a/www/common/file-dialog.less b/www/common/file-dialog.less index 936152f8b..99bd49f0b 100644 --- a/www/common/file-dialog.less +++ b/www/common/file-dialog.less @@ -1,63 +1,8 @@ @import (once) '../customize/src/less2/include/colortheme.less'; +@import '../customize/src/less2/include/modal.less'; #fileDialog { - display: none; - - z-index: 100000; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: @colortheme_modal-dim; - .cp-modal { - background-color: @colortheme_modal-bg; - color: @colortheme_modal-fg; - box-shadow: @colortheme_modal-shadow; - - padding: @colortheme_modal-padding; - - position: absolute; - top: 15vh; bottom: 15vh; - left: 10vw; right: 10vw; - - overflow: auto; - - font-family: @colortheme_font; - text-align: center; - - & > p { - margin-bottom: 1em; - } - - .cp-form { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: center; - } - - input { - background-color: @colortheme_modal-input; - color: @colortheme_modal-fg; - border: 0; - padding: 8px 12px; - margin: 1em; - width: 300px; - } - - .close { - text-shadow: none; - color: inherit; - - position: absolute; - top: 0; - right: 0; - margin: @colortheme_modal-padding; - cursor: pointer; - } - .fileContainer { display: flex; flex-wrap: wrap; diff --git a/www/drive/file.less b/www/drive/file.less index 41896d755..7cb891419 100644 --- a/www/drive/file.less +++ b/www/drive/file.less @@ -506,9 +506,9 @@ span { } .fa { cursor: pointer; - font-size: 100px; - line-height: 140px; - margin: 0; + font-size: 90px; + margin-top: 5px; + margin-bottom: 0; } } } @@ -597,6 +597,34 @@ span { flex: 1; } +#addPadDialog.cp-modal-container { + .fileIcon; + + li:not(.selected):hover { + border: 1px solid white; + } + .cp-modal { + display: flex; + flex-flow: column; + li, li .fa { + cursor: pointer; + } + &> p { + margin: 50px; + } + &> div { + display: flex; + flex-wrap: wrap; + justify-content: center; + align-content: center; + .uploadFile { + break-after: always; + page-break-after: always; + } + } + } +} + /* Toolbar */ diff --git a/www/drive/main.js b/www/drive/main.js index 97d67a03d..e611579ca 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -52,7 +52,7 @@ define([ var TRASH = "trash"; var TRASH_NAME = Messages.fm_trashName; var RECENT = "recent"; - var RECENT_NAME = "Recent pads"; + var RECENT_NAME = Messages.fm_recentPadsName; var LOCALSTORAGE_LAST = "cryptpad-file-lastOpened"; var LOCALSTORAGE_OPENED = "cryptpad-file-openedFolders"; @@ -163,6 +163,7 @@ define([ //var $upIcon = $('', {"class": "fa fa-arrow-circle-up"}); var $unsortedIcon = $('', {"class": "fa fa-files-o"}); var $templateIcon = $('', {"class": "fa fa-cubes"}); + var $recentIcon = $('', {"class": "fa fa-clock-o"}); var $trashIcon = $('', {"class": "fa fa-trash-o"}); var $trashEmptyIcon = $('', {"class": "fa fa-trash-o"}); //var $collapseIcon = $('', {"class": "fa fa-minus-square-o expcol"}); @@ -1324,7 +1325,7 @@ define([ msg = Messages.fm_info_allFiles; break; case RECENT: - msg = Messages.fm_info_recent || 'TODO'; + msg = Messages.fm_info_recent; break; default: msg = undefined; @@ -1388,10 +1389,63 @@ define([ $container.append($listButton).append($gridButton); }; + var getNewPadTypes = function () { + var arr = []; + AppConfig.availablePadTypes.forEach(function (type) { + if (type === 'drive') { return; } + if (type === 'contacts') { return; } + if (type === 'todo') { return; } + if (type === 'file') { return; } + if (!Cryptpad.isLoggedIn() && AppConfig.registeredOnlyTypes && + AppConfig.registeredOnlyTypes.indexOf(type) !== -1) { + return; + } + arr.push(type); + }); + return arr; + }; + var addNewPadHandlers = function ($block, isInRoot) { + // Handlers + if (isInRoot) { + var onCreated = function (err, info) { + if (err) { + if (err === E_OVER_LIMIT) { + return void Cryptpad.alert(Messages.pinLimitDrive, null, true); + } + return void Cryptpad.alert(Messages.fm_error_cantPin); + } + module.newFolder = info.newPath; + refresh(); + }; + $block.find('a.newFolder, li.newFolder').click(function () { + filesOp.addFolder(currentPath, null, onCreated); + }); + $block.find('a.uploadFile, li.uploadFile').click(function () { + var $input = $('', { + 'type': 'file', + 'style': 'display: none;' + }).on('change', function (e) { + var file = e.target.files[0]; + var ev = { + target: $content[0] + }; + APP.FM.handleFile(file, ev); + }); + $input.click(); + }); + } + $block.find('a.newdoc, li.newdoc').click(function () { + var type = $(this).attr('data-type') || 'pad'; + sessionStorage[Cryptpad.newPadPathKey] = filesOp.isPathIn(currentPath, [TRASH]) ? '' : currentPath; + window.open('/' + type + '/'); + }); + }; var createNewButton = function (isInRoot, $container) { if (!APP.editable) { return; } if (!APP.loggedIn) { return; } // Anonymous users can use the + menu in the toolbar + if (!filesOp.isPathIn(currentPath, [ROOT, 'hrefArray'])) { return; } + // Create dropdown var options = []; if (isInRoot) { @@ -1408,13 +1462,7 @@ define([ }); options.push({tag: 'hr'}); } - AppConfig.availablePadTypes.forEach(function (type) { - if (type === 'drive') { return; } - if (type === 'contacts') { return; } - if (!Cryptpad.isLoggedIn() && AppConfig.registeredOnlyTypes && - AppConfig.registeredOnlyTypes.indexOf(type) !== -1) { - return; - } + getNewPadTypes().forEach(function (type) { var attributes = { 'class': 'newdoc', 'data-type': type, @@ -1440,40 +1488,7 @@ define([ $block.find('button').addClass('new'); $block.find('button').attr('title', Messages.fm_newButtonTitle); - // Handlers - if (isInRoot) { - var onCreated = function (err, info) { - if (err) { - if (err === E_OVER_LIMIT) { - return void Cryptpad.alert(Messages.pinLimitDrive, null, true); - } - return void Cryptpad.alert(Messages.fm_error_cantPin); - } - module.newFolder = info.newPath; - refresh(); - }; - $block.find('a.newFolder').click(function () { - filesOp.addFolder(currentPath, null, onCreated); - }); - $block.find('a.uploadFile').click(function () { - var $input = $('', { - 'type': 'file', - 'style': 'display: none;' - }).on('change', function (e) { - var file = e.target.files[0]; - var ev = { - target: $content[0] - }; - APP.FM.handleFile(file, ev); - }); - $input.click(); - }); - } - $block.find('a.newdoc').click(function () { - var type = $(this).attr('data-type') || 'pad'; - sessionStorage[Cryptpad.newPadPathKey] = filesOp.isPathIn(currentPath, [TRASH]) ? '' : currentPath; - window.open('/' + type + '/'); - }); + addNewPadHandlers($block, isInRoot); $container.append($block); }; @@ -1646,6 +1661,58 @@ define([ return keys; }; + // Create the ghost icon to add pads/folders + var createNewPadIcons = function ($block, isInRoot) { + var $container = $('

'); + if (isInRoot) { + // Folder + var $element1 = $('
  • ', { + 'class': 'newFolder element-row grid-element' + }).prepend($folderIcon.clone()).appendTo($container); + $element1.append($('', {'class': 'name'}).text(Messages.fm_folder)); + // File + var $element2 = $('
  • ', { + 'class': 'uploadFile element-row grid-element' + }).prepend(getIcon('file')).appendTo($container); + $element2.append($('', {'class': 'name'}).text(Messages.uploadButton)); + } + // Pads + getNewPadTypes().forEach(function (type) { + var $element = $('
  • ', { + 'class': 'newdoc element-row grid-element' + }).prepend(getIcon(type)).appendTo($container); + $element.append($('', {'class': 'name'}).text(Messages.type[type])); + $element.attr('data-type', type); + }); + + $container.find('.element-row').click(function () { + $block.hide(); + }); + return $container; + }; + var createGhostIcon = function ($list) { + var isInRoot = currentPath[0] === ROOT; + var $element = $('
  • ', { + 'class': 'element-row grid-element addpad' + }).prepend($addIcon.clone()).appendTo($list); + $element.append($('', {'class': 'name'}).text(Messages.fm_newFile)); + $element.attr('title', Messages.fm_newFile); + $element.click(function () { + var $modal = Cryptpad.createModal({ + id: 'addPadDialog', + $body: $iframe.find('body') + }); + var $title = $('

    ').text(Messages.fm_newFile); + var $description = $('

    ').text(Messages.fm_newButtonTitle); + $modal.find('.cp-modal').append($title); + $modal.find('.cp-modal').append($description); + var $content = createNewPadIcons($modal, isInRoot); + $modal.find('.cp-modal').append($content); + $modal.show(); + addNewPadHandlers($modal, isInRoot); + }); + }; + // Drive content toolbar var createToolbar = function () { var $toolbar = $driveToolbar; @@ -1704,6 +1771,7 @@ define([ } $container.append($element); }); + createGhostIcon($container); }; var displayAllFiles = function ($container) { @@ -1997,22 +2065,8 @@ define([ $element.appendTo($list); }); - var $element = $('

  • ', { - 'class': 'element-row grid-element addpad' - }).prepend($addIcon.clone()).appendTo($list); - $element.attr('title', "TODO: Add a pad"); - $element.click(function () { - window.setTimeout(function () { - $driveToolbar.find('.leftside .dropdown-bar-content').show(); - }); - /*var $content = $driveToolbar.find('.leftside .dropdown-bar-content').html(); - var $container = $('
    ').append($('
    ', {id:'cryptpad-add-pad'})); - Cryptpad.alert($container.html(),null,true); - var $c = $('body > .alertify').last().find('#cryptpad-add-pad'); - $c.append($content);*/ - }); + createGhostIcon($list); } - //$content.append($toolbar).append($title).append($info).append($dirContent); $content.append($info).append($dirContent); var $truncated = $('', {'class': 'truncated'}).text('...'); @@ -2168,7 +2222,7 @@ define([ }; var createRecent = function ($container, path) { - var $icon = $templateIcon.clone(); //TODO + var $icon = $recentIcon.clone(); var isOpened = filesOp.comparePath(path, currentPath); var $element = createTreeElement(RECENT_NAME, $icon, [RECENT], false, false, false, isOpened); $element.addClass('root');