From 7761aaa89f4abc3dfd4d6b47c0d7a1b38c4c1b81 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 16 Mar 2017 14:16:42 +0100 Subject: [PATCH 1/2] Add search UI --- customize.dist/translations/messages.fr.js | 3 + customize.dist/translations/messages.js | 3 + www/common/fileObject.js | 2 +- www/drive/file.css | 48 +++++++++++ www/drive/file.less | 55 ++++++++++++ www/drive/main.js | 99 +++++++++++++++++----- 6 files changed, 190 insertions(+), 20 deletions(-) diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 49f67664f..96e36a4b1 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -144,6 +144,8 @@ define(function () { out.fm_unsortedName = "Fichiers non triés"; out.fm_filesDataName = "Tous les fichiers"; out.fm_templateName = "Modèles"; + out.fm_searchName = "Recherche"; + out.fm_searchPlaceholder = "Rechercher..."; out.fm_newButton = "Nouveau"; out.fm_newButtonTitle = "Créer un nouveau pad ou un dossier"; out.fm_newFolder = "Nouveau dossier"; @@ -159,6 +161,7 @@ define(function () { out.fm_creation = "Création"; out.fm_forbidden = "Action interdite"; out.fm_originalPath = "Chemin d'origine"; + out.fm_openParent = "Montrer dans le dossier"; out.fm_noname = "Document sans titre"; out.fm_emptyTrashDialog = "Êtes-vous sûr de vouloir vider la corbeille ?"; out.fm_removeSeveralPermanentlyDialog = "Êtes-vous sûr de vouloir supprimer ces {0} éléments de manière permanente ?"; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index c928d6e19..b463b4853 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -146,6 +146,8 @@ define(function () { out.fm_unsortedName = "Unsorted files"; out.fm_filesDataName = "All files"; out.fm_templateName = "Templates"; + out.fm_searchName = "Search"; + out.fm_searchPlaceholder = "Search..."; out.fm_newButton = "New"; out.fm_newButtonTitle = "Create a new pad or folder"; out.fm_newFolder = "New folder"; @@ -161,6 +163,7 @@ define(function () { out.fm_creation = "Creation"; out.fm_forbidden = "Forbidden action"; out.fm_originalPath = "Original path"; + out.fm_openParent = "Show in folder"; out.fm_noname = "Untitled Document"; out.fm_emptyTrashDialog = "Are you sure you want to empty the trash?"; out.fm_removeSeveralPermanentlyDialog = "Are you sure you want to remove these {0} elements from the trash permanently?"; diff --git a/www/common/fileObject.js b/www/common/fileObject.js index 1ec755662..e822b9bd8 100644 --- a/www/common/fileObject.js +++ b/www/common/fileObject.js @@ -376,7 +376,7 @@ define([ var paths = findFile(l); ret.push({ paths: findFile(l), - data: getFileData(l) + data: exp.getFileData(l) }); }); return ret; diff --git a/www/drive/file.css b/www/drive/file.css index cd9f856e1..6f22515cc 100644 --- a/www/drive/file.css +++ b/www/drive/file.css @@ -138,6 +138,13 @@ span.fa-folder-open { min-width: 30px; cursor: pointer; } +#tree #searchContainer { + text-align: center; + padding: 5px 0; +} +#tree #searchContainer input { + width: 80%; +} #tree .fa.expcol { margin-left: -10px; font-size: 14px; @@ -238,6 +245,47 @@ span.fa-folder-open { #content li:not(.header):hover .name { /*text-decoration: underline;*/ } +#content #folderContent li.searchResult { + border-bottom: 1px solid #bbb; + display: block; +} +#content #folderContent li.searchResult:hover { + background-color: initial; +} +#content #folderContent li.searchResult table { + width: 100%; +} +#content #folderContent li.searchResult table .label2 { + width: 150px; + font-size: 15px; + text-align: right; + padding-right: 15px; +} +#content #folderContent li.searchResult table .openDir a { + cursor: pointer; + color: #41b7d8; +} +#content #folderContent li.searchResult table .openDir a:hover { + color: #014c8c; + text-decoration: underline; +} +#content #folderContent li.searchResult table .path { + font-style: italic; +} +#content #folderContent li.searchResult table .title { + font-weight: bold; + cursor: pointer; +} +#content #folderContent li.searchResult table .title:hover { + background-color: #eee; +} +#content #folderContent li.searchResult table .col2 { + width: 250px; +} +#content #folderContent li.searchResult table .icon { + width: 50px; + font-size: 40px; +} #content div.grid { padding: 20px; } diff --git a/www/drive/file.less b/www/drive/file.less index 42bfc94ed..f30289cc0 100644 --- a/www/drive/file.less +++ b/www/drive/file.less @@ -3,6 +3,7 @@ @tree-lines-col: #888; @drive-hover: #eee; +@drive-hover-light: lighten(@drive-hover, 20%); @content-bg: @tree-bg; @content-bg-ro: darken(@content-bg, 10%); @@ -174,6 +175,13 @@ span { } } } + #searchContainer { + text-align: center; + padding: 5px 0; + input { + width: 80%; + } + } .fa.expcol { margin-left: -10px; font-size: 14px; @@ -283,6 +291,53 @@ span { } } } + #folderContent { + li { + &.searchResult { + border-bottom: 1px solid @info-box-border; + display: block; + &:hover { + background-color: initial; + } + table { + width: 100%; + .label2 { + width: 150px; + font-size: 15px; + text-align: right; + padding-right: 15px; + } + .openDir { + a { + cursor: pointer; + color: #41b7d8; + &:hover { + color: #014c8c; + text-decoration: underline; + } + } + } + .path { + font-style: italic; + } + .title { + font-weight: bold; + cursor: pointer; + &:hover { + background-color: @drive-hover; + } + } + .col2 { + width: 250px; + } + .icon { + width: 50px; + font-size: 40px; + } + } + } + } + } div.grid { padding: 20px; li { diff --git a/www/drive/main.js b/www/drive/main.js index 3bcd4ec1b..a06ca36ec 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -39,6 +39,7 @@ define([ }; var SEARCH = "search"; + var SEARCH_NAME = Messages.fm_searchName; var ROOT = "root"; var ROOT_NAME = Messages.fm_rootName; var UNSORTED = "unsorted"; @@ -75,6 +76,7 @@ define([ return path; }; var setLastOpenedFolder = function (path) { + if (path[0] === SEARCH) { return; } localStorage[LOCALSTORAGE_LAST] = JSON.stringify(path); }; @@ -207,8 +209,8 @@ define([ // Categories dislayed in the menu // _WORKGROUP_ : do not display unsorted - var displayedCategories = [ROOT, UNSORTED, TRASH]; - if (isWorkgroup()) { displayedCategories = [ROOT, TRASH]; } + var displayedCategories = [ROOT, UNSORTED, TRASH, SEARCH]; + if (isWorkgroup()) { displayedCategories = [ROOT, TRASH, SEARCH]; } var lastSelectTime; var selectedElement; @@ -925,30 +927,34 @@ define([ case UNSORTED: pName = UNSORTED_NAME; break; case TEMPLATE: pName = TEMPLATE_NAME; break; case FILES_DATA: pName = FILES_DATA_NAME; break; + case SEARCH: pName = SEARCH_NAME; break; default: pName = name; } return pName; }; // Create the title block with the "parent folder" button - var createTitle = function (path) { + var createTitle = function (path, noStyle) { if (!path || path.length === 0) { return; } var isTrash = filesOp.isPathInTrash(path); var $title = $('', {'class': 'path unselectable'}); if (APP.mobile()) { return $title; } + path = path[0] === SEARCH ? path.slice(0,1) : path; path.forEach(function (p, idx) { if (isTrash && [2,3].indexOf(idx) !== -1) { return; } var $span = $('', {'class': 'element'}); if (idx < path.length - 1) { - $span.addClass('clickable'); - $span.click(function (e) { - var sliceEnd = idx + 1; - if (isTrash && idx === 1) { sliceEnd = 4; } // Make sure we don't show the index or 'element' and 'path' - module.displayDirectory(path.slice(0, sliceEnd)); - }); + if (!noStyle) { + $span.addClass('clickable'); + $span.click(function (e) { + var sliceEnd = idx + 1; + if (isTrash && idx === 1) { sliceEnd = 4; } // Make sure we don't show the index or 'element' and 'path' + module.displayDirectory(path.slice(0, sliceEnd)); + }); + } } var name = p; @@ -1421,7 +1427,40 @@ define([ var displaySearch = function ($list, value) { var filesList = filesOp.search(value); filesList.forEach(function (r) { - $('
  • ').text(JSON.stringify(r)).appendTo($list); + r.paths.forEach(function (path) { + var href = r.data.href; + var parsed = Cryptpad.parsePadUrl(href); + var $table = $(''); + var $icon = $('').append($icon).append($title).append($typeName).append($type).appendTo($table); + var $row2 = $('').append($path).append($atimeName).append($atime).appendTo($table); + var $row3 = $('').append($openDir).append($ctimeName).append($ctime).appendTo($table); + $('
  • ', {'class':'searchResult'}).append($table).appendTo($list); + }); }); }; @@ -1465,6 +1504,10 @@ define([ module.resetTree(); + if (isSearch) { + $tree.find('#searchInput').focus(); + } + if (!isWorkgroup()) { setLastOpenedFolder(path); } @@ -1474,13 +1517,15 @@ define([ var $dirContent = $('
    ', {id: FOLDER_CONTENT_ID}); $dirContent.data('path', path); - var mode = getViewMode(); - if (mode) { - $dirContent.addClass(getViewModeClass()); + if (!isSearch) { + var mode = getViewMode(); + if (mode) { + $dirContent.addClass(getViewModeClass()); + } + var $modeButton = createViewModeButton().appendTo($toolbar.find('.rightside')); } var $list = $('
      ').appendTo($dirContent); - var $modeButton = createViewModeButton().appendTo($toolbar.find('.rightside')); var $title = createTitle(path).appendTo($toolbar.find('.rightside')); updatePathSize(); @@ -1693,17 +1738,33 @@ define([ $container.append($trashList); }; + var search = APP.Search = {}; var createSearch = function ($container) { + var isInSearch = currentPath[0] === SEARCH; + var $div = $('
      ', {'id': 'searchContainer'}); var $input = $('', { + id: 'searchInput', type: 'text', - placeholder: 'Search...' + placeholder: Messages.fm_searchPlaceholder }).keyup(function (e) { + if (search.to) { window.clearTimeout(search.to); } + var isInSearchTmp = currentPath[0] === SEARCH; + if ($input.val().trim() === "") { + if (search.oldLocation.length) { displayDirectory(search.oldLocation); } + return; + } if (e.which === 13) { - var val = $(this).val(); - displayDirectory([SEARCH, val]); + if (!isInSearchTmp) { search.oldLocation = currentPath.slice(); } + displayDirectory([SEARCH, $input.val()]); + return; } - }); - $container.append($input); + search.to = window.setTimeout(function () { + if (!isInSearchTmp) { search.oldLocation = currentPath.slice(); } + displayDirectory([SEARCH, $input.val()]); + }, 500); + }).appendTo($div); + if (isInSearch) { $input.val(currentPath[1] || ''); } + $container.append($div); }; var resetTree = module.resetTree = function () { From f98c825dc37dad16f47b5a5501dc33e04f83973c Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 16 Mar 2017 14:43:00 +0100 Subject: [PATCH 2/2] Fix keyboard shortcuts not working in CryptDrive --- www/drive/inner.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/drive/inner.html b/www/drive/inner.html index 4ffe0c0f5..596b39e08 100644 --- a/www/drive/inner.html +++ b/www/drive/inner.html @@ -11,7 +11,7 @@
      -
      +
  • ', {'rowspan': '3', 'class': 'icon'}).append(getFileIcon(href)); + var $title = $('', {'class': 'col1 title'}).text(r.data.title).click(function (e) { + openFile(r.data.href); + }); + var $typeName = $('', {'class': 'label2'}).text(Messages.fm_type); + var $type = $('', {'class': 'col2'}).text(Messages.type[parsed.type] || parsed.type); + var $atimeName = $('', {'class': 'label2'}).text(Messages.fm_lastAccess); + var $atime = $('', {'class': 'col2'}).text(new Date(r.data.atime).toLocaleString()); + var $ctimeName = $('', {'class': 'label2'}).text(Messages.fm_creation); + var $ctime = $('', {'class': 'col2'}).text(new Date(r.data.ctime).toLocaleString()); + if (filesOp.isPathInHrefArray(path)) { + path.pop(); + path.push(r.data.title); + } + var $path = $('', {'class': 'col1 path'}).html(createTitle(path, true).html()); + var parentPath = path.slice(); + var $a; + if (parentPath) { + $a = $('').text(Messages.fm_openParent).click(function (e) { + e.preventDefault(); + parentPath.pop(); + module.displayDirectory(parentPath); + }); + } + var $openDir = $('', {'class': 'openDir'}).append($a); + var $row1 = $('