From c14638877c0bb0533a72842ccc7c73d88f5122f0 Mon Sep 17 00:00:00 2001 From: Nina Pypchenko <22447785+nina-py@users.noreply.github.com> Date: Sun, 10 Jan 2021 19:14:49 +1100 Subject: [PATCH] Add "Crop image previews" setting to files Added a new user setting that toggles cropping on image previews in grid view. True (default value): crops each image to a square. False: keep original aspect ratio. Signed-off-by: Nina Pypchenko <22447785+nina-py@users.noreply.github.com> Closes #18439. Signed-off-by: npmbuildbot-nextcloud[bot] --- apps/files/appinfo/routes.php | 5 +++ apps/files/js/app.js | 32 ++++++++++++++++++- apps/files/js/filelist.js | 13 +++++++- apps/files/lib/Controller/ApiController.php | 14 ++++++++ apps/files/lib/Controller/ViewController.php | 2 ++ apps/files/templates/appnavigation.php | 5 +++ apps/files/templates/index.php | 1 + .../tests/Controller/ApiControllerTest.php | 13 ++++++++ .../tests/Controller/ViewControllerTest.php | 2 ++ 9 files changed, 85 insertions(+), 2 deletions(-) diff --git a/apps/files/appinfo/routes.php b/apps/files/appinfo/routes.php index d5edd068cd..65c8deb442 100644 --- a/apps/files/appinfo/routes.php +++ b/apps/files/appinfo/routes.php @@ -76,6 +76,11 @@ $application->registerRoutes( 'url' => '/api/v1/showhidden', 'verb' => 'POST' ], + [ + 'name' => 'API#cropImagePreviews', + 'url' => '/api/v1/cropimagepreviews', + 'verb' => 'POST' + ], [ 'name' => 'API#showGridView', 'url' => '/api/v1/showgridview', diff --git a/apps/files/js/app.js b/apps/files/js/app.js index 0946820527..8015f395b7 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -56,13 +56,18 @@ var showHidden = $('#showHiddenFiles').val() === "1"; this.$showHiddenFiles.prop('checked', showHidden); + // crop image previews + this.$cropImagePreviews = $('input#cropimagepreviewsToggle'); + var cropImagePreviews = $('#cropImagePreviews').val() === "1"; + this.$cropImagePreviews.prop('checked', cropImagePreviews); if ($('#fileNotFound').val() === "1") { OC.Notification.show(t('files', 'File could not be found'), {type: 'error'}); } this._filesConfig = new OC.Backbone.Model({ - showhidden: showHidden + showhidden: showHidden, + cropimagepreviews: cropImagePreviews, }); var urlParams = OC.Util.History.parseUrlQuery(); @@ -132,6 +137,7 @@ }); this._debouncedPersistShowHiddenFilesState = _.debounce(this._persistShowHiddenFilesState, 1200); + this._debouncedPersistCropImagePreviewsState = _.debounce(this._persistCropImagePreviewsState, 1200); if (sessionStorage.getItem('WhatsNewServerCheck') < (Date.now() - 3600*1000)) { OCP.WhatsNew.query(); // for Nextcloud server @@ -231,6 +237,7 @@ $('#app-navigation').on('itemChanged', _.bind(this._onNavigationChanged, this)); this.$showHiddenFiles.on('change', _.bind(this._onShowHiddenFilesChange, this)); + this.$cropImagePreviews.on('change', _.bind(this._onCropImagePreviewsChange, this)); }, /** @@ -256,6 +263,29 @@ }); }, + /** + * Toggle cropping image previews according to the settings checkbox + * + * @returns void + */ + _onCropImagePreviewsChange: function() { + var crop = this.$cropImagePreviews.is(':checked'); + this._filesConfig.set('cropimagepreviews', crop); + this._debouncedPersistCropImagePreviewsState(); + }, + + /** + * Persist crop image previews preference on the server + * + * @returns void + */ + _persistCropImagePreviewsState: function() { + var crop = this._filesConfig.get('cropimagepreviews'); + $.post(OC.generateUrl('/apps/files/api/v1/cropimagepreviews'), { + crop: crop + }); + }, + /** * Event handler for when the current navigation item has changed */ diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 30bc35551d..11d0bc4511 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -252,7 +252,8 @@ this._filesConfig = OCA.Files.App.getFilesConfig(); } else { this._filesConfig = new OC.Backbone.Model({ - 'showhidden': false + 'showhidden': false, + 'cropimagepreviews': true }); } @@ -291,6 +292,10 @@ } }); + this._filesConfig.on('change:cropimagepreviews', function() { + self.reload(); + }); + this.$el.toggleClass('hide-hidden-files', !this._filesConfig.get('showhidden')); } @@ -2215,6 +2220,12 @@ urlSpec.y = Math.ceil(urlSpec.y); urlSpec.forceIcon = 0; + /** + * Images are cropped to a square by default. Append a=1 to the URL + * if the user wants to see images with original aspect ratio. + */ + urlSpec.a = this._filesConfig.get('cropimagepreviews') ? 0 : 1; + if (typeof urlSpec.fileId !== 'undefined') { delete urlSpec.file; return OC.generateUrl('/core/preview?') + $.param(urlSpec); diff --git a/apps/files/lib/Controller/ApiController.php b/apps/files/lib/Controller/ApiController.php index a852be5dad..2b8d62efb7 100644 --- a/apps/files/lib/Controller/ApiController.php +++ b/apps/files/lib/Controller/ApiController.php @@ -280,6 +280,20 @@ class ApiController extends Controller { return new Response(); } + /** + * Toggle default for cropping preview images + * + * @NoAdminRequired + * + * @param bool $crop + * @return Response + * @throws \OCP\PreConditionNotMetException + */ + public function cropImagePreviews($crop) { + $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'crop_image_previews', (int)$crop); + return new Response(); + } + /** * Toggle default for files grid view * diff --git a/apps/files/lib/Controller/ViewController.php b/apps/files/lib/Controller/ViewController.php index 9107573752..364735437e 100644 --- a/apps/files/lib/Controller/ViewController.php +++ b/apps/files/lib/Controller/ViewController.php @@ -296,6 +296,8 @@ class ViewController extends Controller { $params['isIE'] = \OCP\Util::isIE(); $showHidden = (bool) $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_hidden', false); $params['showHiddenFiles'] = $showHidden ? 1 : 0; + $cropImagePreviews = (bool) $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'crop_image_previews', true); + $params['cropImagePreviews'] = $cropImagePreviews ? 1 : 0; $params['fileNotFound'] = $fileNotFound ? 1 : 0; $params['appNavigation'] = $nav; $params['appContents'] = $contentItems; diff --git a/apps/files/templates/appnavigation.php b/apps/files/templates/appnavigation.php index f57295e888..8e65456794 100644 --- a/apps/files/templates/appnavigation.php +++ b/apps/files/templates/appnavigation.php @@ -44,6 +44,11 @@ script(\OCA\Files\AppInfo\Application::APP_ID, 'dist/files-app-settings'); checked="checked" type="checkbox"> +
+ + +
diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 3ba0474daa..8b6e2b0b91 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -28,6 +28,7 @@ + $value) {?> diff --git a/apps/files/tests/Controller/ApiControllerTest.php b/apps/files/tests/Controller/ApiControllerTest.php index afef351aea..1fb6490f14 100644 --- a/apps/files/tests/Controller/ApiControllerTest.php +++ b/apps/files/tests/Controller/ApiControllerTest.php @@ -246,4 +246,17 @@ class ApiControllerTest extends TestCase { $this->assertEquals($expected, $actual); } + + public function testCropImagePreviews() { + $crop = true; + + $this->config->expects($this->once()) + ->method('setUserValue') + ->with($this->user->getUID(), 'files', 'crop_image_previews', $crop); + + $expected = new Http\Response(); + $actual = $this->apiController->cropImagePreviews($crop); + + $this->assertEquals($expected, $actual); + } } diff --git a/apps/files/tests/Controller/ViewControllerTest.php b/apps/files/tests/Controller/ViewControllerTest.php index 2b40697642..fc2b82de9c 100644 --- a/apps/files/tests/Controller/ViewControllerTest.php +++ b/apps/files/tests/Controller/ViewControllerTest.php @@ -135,6 +135,7 @@ class ViewControllerTest extends TestCase { [$this->user->getUID(), 'files', 'file_sorting', 'name', 'name'], [$this->user->getUID(), 'files', 'file_sorting_direction', 'asc', 'asc'], [$this->user->getUID(), 'files', 'show_hidden', false, false], + [$this->user->getUID(), 'files', 'crop_image_previews', true, true], [$this->user->getUID(), 'files', 'show_grid', true], ]); @@ -316,6 +317,7 @@ class ViewControllerTest extends TestCase { 'defaultFileSorting' => 'name', 'defaultFileSortingDirection' => 'asc', 'showHiddenFiles' => 0, + 'cropImagePreviews' => 1, 'fileNotFound' => 0, 'allowShareWithLink' => 'yes', 'appNavigation' => $nav,