diff --git a/modules/backend/widgets/MediaManager.php b/modules/backend/widgets/MediaManager.php index 17cce9df7..b4a6a679a 100644 --- a/modules/backend/widgets/MediaManager.php +++ b/modules/backend/widgets/MediaManager.php @@ -209,7 +209,7 @@ class MediaManager extends WidgetBase $thumbnailInfo['lastModified'] = $lastModified; $thumbnailInfo['id'] = 'sidebar-thumbnail'; - return $this->generateThumbnail($thumbnailInfo, $thumbnailParams, true); + return $this->generateThumbnail($thumbnailInfo, $thumbnailParams); } /** @@ -1156,8 +1156,7 @@ class MediaManager extends WidgetBase protected function getThumbnailParams($viewMode = null) { $result = [ - 'mode' => 'crop', - 'ext' => 'png' + 'mode' => 'crop' ]; if ($viewMode) { @@ -1190,13 +1189,29 @@ class MediaManager extends WidgetBase $thumbnailParams['width'] . 'x' . $thumbnailParams['height'] . '_' . $thumbnailParams['mode'] . '.' . - $thumbnailParams['ext']; + $this->getThumbnailImageExtension($itemPath); $partition = implode('/', array_slice(str_split($itemSignature, 3), 0, 3)) . '/'; return $this->getThumbnailDirectory().$partition.$thumbFile; } + /** + * Preferred thumbnail image extension + * @param string $itemPath + * @return string + */ + protected function getThumbnailImageExtension($itemPath) + { + $extension = pathinfo($itemPath, PATHINFO_EXTENSION); + + if (in_array($extension, ['png', 'gif', 'webp'])) { + return $extension; + } + + return 'jpg'; + } + /** * Returns the URL to a thumbnail * @param string $imagePath @@ -1296,52 +1311,59 @@ class MediaManager extends WidgetBase $markup = null; try { - /* - * Get and validate input data - */ $path = $thumbnailInfo['path']; - $width = $thumbnailInfo['width']; - $height = $thumbnailInfo['height']; - $lastModified = $thumbnailInfo['lastModified']; - if (!is_numeric($width) || !is_numeric($height) || !is_numeric($lastModified)) { - throw new ApplicationException('Invalid input data'); + if ($this->isVector($path)) { + $markup = $this->makePartial('thumbnail-image', [ + 'isError' => false, + 'imageUrl' => Url::to(config('cms.storage.media.path') . $thumbnailInfo['path']) + ]); + } else { + /* + * Get and validate input data + */ + $width = $thumbnailInfo['width']; + $height = $thumbnailInfo['height']; + $lastModified = $thumbnailInfo['lastModified']; + + if (!is_numeric($width) || !is_numeric($height) || !is_numeric($lastModified)) { + throw new ApplicationException('Invalid input data'); + } + + if (!$thumbnailParams) { + $thumbnailParams = $this->getThumbnailParams(); + $thumbnailParams['width'] = $width; + $thumbnailParams['height'] = $height; + } + + $thumbnailPath = $this->getThumbnailImagePath($thumbnailParams, $path, $lastModified); + $fullThumbnailPath = temp_path(ltrim($thumbnailPath, '/')); + + /* + * Save the file locally + */ + $library = MediaLibrary::instance(); + $tempFilePath = $this->getLocalTempFilePath($path); + + if (!@File::put($tempFilePath, $library->get($path))) { + throw new SystemException('Error saving remote file to a temporary location'); + } + + /* + * Resize the thumbnail and save to the thumbnails directory + */ + $this->resizeImage($fullThumbnailPath, $thumbnailParams, $tempFilePath); + + /* + * Delete the temporary file + */ + File::delete($tempFilePath); + $markup = $this->makePartial('thumbnail-image', [ + 'isError' => false, + 'imageUrl' => $this->getThumbnailImageUrl($thumbnailPath) + ]); } - - if (!$thumbnailParams) { - $thumbnailParams = $this->getThumbnailParams(); - $thumbnailParams['width'] = $width; - $thumbnailParams['height'] = $height; - } - - $thumbnailPath = $this->getThumbnailImagePath($thumbnailParams, $path, $lastModified); - $fullThumbnailPath = temp_path(ltrim($thumbnailPath, '/')); - - /* - * Save the file locally - */ - $library = MediaLibrary::instance(); - $tempFilePath = $this->getLocalTempFilePath($path); - - if (!@File::put($tempFilePath, $library->get($path))) { - throw new SystemException('Error saving remote file to a temporary location'); - } - - /* - * Resize the thumbnail and save to the thumbnails directory - */ - $this->resizeImage($fullThumbnailPath, $thumbnailParams, $tempFilePath); - - /* - * Delete the temporary file - */ - File::delete($tempFilePath); - $markup = $this->makePartial('thumbnail-image', [ - 'isError' => false, - 'imageUrl' => $this->getThumbnailImageUrl($thumbnailPath) - ]); - } - catch (Exception $ex) { + } catch (Exception $ex) { if ($tempFilePath) { File::delete($tempFilePath); } @@ -1852,4 +1874,14 @@ class MediaManager extends WidgetBase 'folder' => $targetFolder ]; } + + /** + * Detect if image is vector graphic (SVG) + * @param string $path + * @return boolean + */ + protected function isVector($path) + { + return (pathinfo($path, PATHINFO_EXTENSION) == 'svg'); + } } diff --git a/modules/backend/widgets/mediamanager/assets/css/mediamanager.css b/modules/backend/widgets/mediamanager/assets/css/mediamanager.css index e2d4d6160..74e0a857a 100644 --- a/modules/backend/widgets/mediamanager/assets/css/mediamanager.css +++ b/modules/backend/widgets/mediamanager/assets/css/mediamanager.css @@ -23,8 +23,9 @@ div[data-control="media-manager"] .media-list li .image-placeholder[data-loading div[data-control="media-manager"] .media-list li .image-placeholder[data-loading]:after {background-image:url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');background-position:50% 50%;content:' ';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background-size:28px 28px;position:absolute;width:28px;height:28px;top:50%;left:50%;margin-top:-14px;margin-left:-14px} div[data-control="media-manager"] .media-list li i.icon-chain-broken {padding:0;color:#bdc3c7} div[data-control="media-manager"] .media-list li[data-item-type=folder] i {color:#4ea5e0} -div[data-control="media-manager"] .media-list.list li {height:75px;width:260px;border:1px solid #ecf0f1;background:#f6f8f9} +div[data-control="media-manager"] .media-list.list li {height:75px;width:260px;border:1px solid #ecf0f1;background:#f6f8f9;box-sizing:content-box} div[data-control="media-manager"] .media-list.list li .icon-container {border-right:1px solid #f6f8f9;width:75px;height:75px;float:left} +div[data-control="media-manager"] .media-list.list li .icon-container img {max-height:75px} div[data-control="media-manager"] .media-list.list li .icon-container i {font-size:35px} div[data-control="media-manager"] .media-list.list li .icon-container.image {border-right:1px solid #ecf0f1!important} div[data-control="media-manager"] .media-list.list li .icon-container p.thumbnail-error-message {display:none} @@ -43,7 +44,8 @@ div[data-control="media-manager"] .media-list.tiles li {width:167px;margin-botto div[data-control="media-manager"] .media-list.tiles .icon-wrapper {width:167px} div[data-control="media-manager"] .media-list.tiles li .image-placeholder {width:165px;height:165px} div[data-control="media-manager"] .media-list.tiles li .image-placeholder[data-loading]:after {background-image:url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');background-position:50% 50%;content:' ';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background-size:55px 55px;position:absolute;width:55px;height:55px;top:50%;left:50%;margin-top:-27.5px;margin-left:-27.5px} -div[data-control="media-manager"] .media-list.tiles li .icon-container {width:167px;height:167px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;border:1px solid #ecf0f1;overflow:hidden;background:#f6f8f9} +div[data-control="media-manager"] .media-list.tiles li .icon-container {width:165px;height:165px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;border:1px solid #ecf0f1;overflow:hidden;background:#f6f8f9;box-sizing:content-box} +div[data-control="media-manager"] .media-list.tiles li .icon-container img {max-height:165px} div[data-control="media-manager"] .media-list.tiles li .icon-container i {font-size:55px} div[data-control="media-manager"] .media-list.tiles li .icon-container p {font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"} div[data-control="media-manager"] .media-list.tiles li.selected .icon-container {background:#4ea5e0 !important;border-color:#2581b8} @@ -55,7 +57,7 @@ div[data-control="media-manager"] .media-list.tiles p.size {margin-bottom:0} div[data-control="media-manager"] [data-control="sidebar-labels"] {word-wrap:break-word} div[data-control="media-manager"] .sidebar-group {margin-bottom:20px} div[data-control="media-manager"] .sidebar-image-placeholder-container {display:table;width:100%} -div[data-control="media-manager"] .sidebar-image-placeholder {display:table-cell;height:225px;position:relative;vertical-align:middle;text-align:center;border-bottom:1px solid #ecf0f1} +div[data-control="media-manager"] .sidebar-image-placeholder {display:table-cell;height:225px;position:relative;vertical-align:middle;text-align:center;border-bottom:1px solid #ecf0f1;box-sizing:content-box} div[data-control="media-manager"] .sidebar-image-placeholder[data-loading] {background:#ecf0f1} div[data-control="media-manager"] .sidebar-image-placeholder[data-loading]:after {background-image:url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');background-position:50% 50%;content:' ';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background-size:62px 62px;position:absolute;width:62px;height:62px;top:50%;left:50%;margin-top:-31px;margin-left:-31px} div[data-control="media-manager"] .sidebar-image-placeholder i.icon-chain-broken, @@ -64,7 +66,7 @@ div[data-control="media-manager"] .sidebar-image-placeholder i.icon-asterisk, div[data-control="media-manager"] .sidebar-image-placeholder i.icon-level-up {color:#bdc3c7;font-size:55px} div[data-control="media-manager"] .sidebar-image-placeholder.no-border {border-bottom:none} div[data-control="media-manager"] .sidebar-image-placeholder p {font-size:12px;margin:10px;line-height:160%;color:#bdc3c7;margin-top:25px} -div[data-control="media-manager"] .sidebar-image-placeholder img {max-width:100%} +div[data-control="media-manager"] .sidebar-image-placeholder img {max-width:100%;max-height:225px} div[data-control="media-manager"] .list-container {position:relative;z-index:100} div[data-control="media-manager"] .list-container .no-data {font-size:13px} div[data-control="media-manager"] .list-container p.no-data {padding:0 20px 20px 20px} diff --git a/modules/backend/widgets/mediamanager/assets/less/mediamanager.less b/modules/backend/widgets/mediamanager/assets/less/mediamanager.less index 714fa51de..9ff16d393 100644 --- a/modules/backend/widgets/mediamanager/assets/less/mediamanager.less +++ b/modules/backend/widgets/mediamanager/assets/less/mediamanager.less @@ -198,6 +198,7 @@ div[data-control="media-manager"] { width: 260px; border: 1px solid #ecf0f1; background: #f6f8f9; + box-sizing: content-box; } li .icon-container { @@ -206,6 +207,10 @@ div[data-control="media-manager"] { height: 75px; float: left; + img { + max-height: 75px; + } + i { font-size: 35px; } @@ -269,12 +274,17 @@ div[data-control="media-manager"] { } li .icon-container { - width: 167px; - height: 167px; + width: 165px; + height: 165px; .border-radius(3px); border: 1px solid #ecf0f1; overflow: hidden; background: #f6f8f9; + box-sizing: content-box; + + img { + max-height: 165px; + } i { font-size: 55px; @@ -319,6 +329,7 @@ div[data-control="media-manager"] { vertical-align: middle; text-align: center; border-bottom: 1px solid #ecf0f1; + box-sizing: content-box; &[data-loading] { background: #ecf0f1; @@ -343,6 +354,7 @@ div[data-control="media-manager"] { img { max-width: 100%; + max-height: 225px; } }