Skip to content

Commit

Permalink
Add dynamic file extension icons to the MediaManager (#1061)
Browse files Browse the repository at this point in the history
Adds dynamic icons for file thumbnails in the Media Manager based on file extension.
  • Loading branch information
damsfx authored Mar 6, 2024
1 parent 4910a63 commit 9e8c043
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 7 deletions.
44 changes: 42 additions & 2 deletions modules/backend/widgets/mediamanager/assets/css/mediamanager.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,39 @@ div[data-control="media-manager"]:focus{outline:none}
div[data-control="media-manager"] audio,
div[data-control="media-manager"] video{width:100%}
div[data-control="media-manager"] video{background:#ecf0f1;max-height:225px}
div[data-control="media-manager"] .file-icon{fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2}
div[data-control="media-manager"] .file-icon-extension{font-family:'ArialMT','Arial',sans-serif;font-size:4em;font-weight:900;fill:#fff}
div[data-control="media-manager"] .file-icon-label{fill:#576D7E;fill-rule:nonzero}
div[data-control="media-manager"] .file-icon-css,
div[data-control="media-manager"] .file-icon-less,
div[data-control="media-manager"] .file-icon-scss{fill:#B73FD9}
div[data-control="media-manager"] .file-icon-html,
div[data-control="media-manager"] .file-icon-xml{fill:#EA9B47}
div[data-control="media-manager"] .file-icon-js,
div[data-control="media-manager"] .file-icon-json{fill:#A9A9A9}
div[data-control="media-manager"] .file-icon-pdf{fill:#E30713}
div[data-control="media-manager"] .file-icon-txt{fill:#248BD0}
div[data-control="media-manager"] .file-icon-ai{fill:#F29200}
div[data-control="media-manager"] .file-icon-eps{fill:#F9B234}
div[data-control="media-manager"] .file-icon-psd{fill:#2DAAE2}
div[data-control="media-manager"] .file-icon-ttf,
div[data-control="media-manager"] .file-icon-otf,
div[data-control="media-manager"] .file-icon-woff,
div[data-control="media-manager"] .file-icon-woff2{fill:#C4CA10}
div[data-control="media-manager"] .file-icon-doc,
div[data-control="media-manager"] .file-icon-docx,
div[data-control="media-manager"] .file-icon-rtf,
div[data-control="media-manager"] .file-icon-odt{fill:#0F70B7}
div[data-control="media-manager"] .file-icon-csv,
div[data-control="media-manager"] .file-icon-ods,
div[data-control="media-manager"] .file-icon-xls,
div[data-control="media-manager"] .file-icon-xlsx{fill:#3BAA34}
div[data-control="media-manager"] .file-icon-odp,
div[data-control="media-manager"] .file-icon-ppt,
div[data-control="media-manager"] .file-icon-pptx{fill:#D04526}
div[data-control="media-manager"] .file-icon-rar,
div[data-control="media-manager"] .file-icon-tar,
div[data-control="media-manager"] .file-icon-zip{fill:#363A56}
div[data-control="media-manager"] .media-player-fallback{font-size:13px;color:#95a5a6;background:#ecf0f1;line-height:180%}
div[data-control="media-manager"] .media-player-fallback.panel-embedded{padding:20px;margin:-20px -20px 0 -20px}
div[data-control="media-manager"] .empty-library{padding:20px;text-align:center}
Expand All @@ -27,6 +60,7 @@ div[data-control="media-manager"] .media-list.list li{height:75px;width:260px;bo
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 svg{max-height:44px}
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}
div[data-control="media-manager"] .media-list.list .icon-wrapper{width:75px}
Expand All @@ -47,6 +81,7 @@ div[data-control="media-manager"] .media-list.tiles li .image-placeholder[data-l
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 svg{max-height:65px}
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}
div[data-control="media-manager"] .media-list.tiles li.selected .icon-container i,
Expand All @@ -56,8 +91,11 @@ div[data-control="media-manager"] .media-list.tiles i.icon-chain-broken{margin-t
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;box-sizing:content-box}
div[data-control="media-manager"] .sidebar-image-placeholder-container,
div[data-control="media-manager"] .sidebar-document-placeholder-container{display:table;width:100%}
div[data-control="media-manager"] .sidebar-image-placeholder,
div[data-control="media-manager"] .sidebar-document-placeholder{display:table-cell;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{height:225px}
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,
Expand All @@ -67,6 +105,8 @@ div[data-control="media-manager"] .sidebar-image-placeholder i.icon-level-up{col
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%;max-height:225px}
div[data-control="media-manager"] .sidebar-document-placeholder{height:155px}
div[data-control="media-manager"] .sidebar-document-placeholder svg{width:100px;height:100px}
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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ for(var i=0,len=previewContainer.children.length;i<len;i++){previewContainer.rem
switch(documentType){case'audio':template=previewPanel.querySelector('[data-control="audio-template"]').innerHTML
break;case'video':template=previewPanel.querySelector('[data-control="video-template"]').innerHTML
break;case'image':template=previewPanel.querySelector('[data-control="image-template"]').innerHTML
break;case'document':template=previewPanel.querySelector('[data-control="document-template"]').innerHTML
break;}previewContainer.innerHTML=template.replace('{src}',item.getAttribute('data-public-url')).replace('{path}',item.getAttribute('data-path')).replace('{last-modified}',item.getAttribute('data-last-modified-ts'))
if(documentType=='document')this.loadSidebarDocumentIcon(item)
if(documentType=='image')this.loadSidebarThumbnail()}else if(items.length==1&&items[0].hasAttribute('data-root')){template=previewPanel.querySelector('[data-control="go-up"]').innerHTML
previewContainer.innerHTML=template}else if(items.length==0){template=previewPanel.querySelector('[data-control="no-selection-template"]').innerHTML
previewContainer.innerHTML=template}else{template=previewPanel.querySelector('[data-control="multi-selection-template"]').innerHTML
Expand All @@ -164,6 +166,8 @@ if(this.isSearchMode()){previewPanel.querySelector('[data-control="item-folder"]
var folderNode=previewPanel.querySelector('[data-label="folder"]')
folderNode.textContent=item.getAttribute('data-folder')
folderNode.setAttribute('data-path',item.getAttribute('data-folder'))}else{previewPanel.querySelector('[data-control="item-folder"]').setAttribute('class','hide')}}else{this.sidebarPreviewElement.querySelector('[data-control="sidebar-labels"]').setAttribute('class','hide')}this.updateSidebarMediaPreview(items)}
MediaManager.prototype.loadSidebarDocumentIcon=function(item){var sidebarDocument=this.sidebarPreviewElement.querySelector('[data-control="sidebar-document"]'),svg=item.querySelector('svg')
sidebarDocument.innerHTML=svg.outerHTML}
MediaManager.prototype.loadSidebarThumbnail=function(){if(this.sidebarThumbnailAjax){try{this.sidebarThumbnailAjax.abort()}catch(e){}this.sidebarThumbnailAjax=null}var sidebarThumbnail=this.sidebarPreviewElement.querySelector('[data-control="sidebar-thumbnail"]')
if(!sidebarThumbnail)return
var data={path:sidebarThumbnail.getAttribute('data-path'),lastModified:sidebarThumbnail.getAttribute('data-last-modified')}
Expand Down Expand Up @@ -536,4 +540,4 @@ case'undo-resizing':this.undoResizing()
break}}
MediaManagerImageCropPopup.prototype.onSelectionChanged=function(c){this.updateSelectionSizeLabel(c.w,c.h)}
MediaManagerImageCropPopup.DEFAULTS={alias:undefined,onDone:undefined}
$.wn.mediaManager.imageCropPopup=MediaManagerImageCropPopup}(window.jQuery);
$.wn.mediaManager.imageCropPopup=MediaManagerImageCropPopup}(window.jQuery);
13 changes: 13 additions & 0 deletions modules/backend/widgets/mediamanager/assets/js/mediamanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,13 +471,19 @@
case 'image' :
template = previewPanel.querySelector('[data-control="image-template"]').innerHTML
break;
case 'document' :
template = previewPanel.querySelector('[data-control="document-template"]').innerHTML
break;
}

previewContainer.innerHTML = template
.replace('{src}', item.getAttribute('data-public-url'))
.replace('{path}', item.getAttribute('data-path'))
.replace('{last-modified}', item.getAttribute('data-last-modified-ts'))

if (documentType == 'document')
this.loadSidebarDocumentIcon(item)

if (documentType == 'image')
this.loadSidebarThumbnail()
}
Expand Down Expand Up @@ -544,6 +550,13 @@
this.updateSidebarMediaPreview(items)
}

MediaManager.prototype.loadSidebarDocumentIcon = function(item) {
var sidebarDocument = this.sidebarPreviewElement.querySelector('[data-control="sidebar-document"]'),
svg = item.querySelector('svg')

sidebarDocument.innerHTML = svg.outerHTML
}

MediaManager.prototype.loadSidebarThumbnail = function() {
if (this.sidebarThumbnailAjax) {
try {
Expand Down
104 changes: 101 additions & 3 deletions modules/backend/widgets/mediamanager/assets/less/mediamanager.less
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,82 @@ div[data-control="media-manager"] {
max-height: 225px;
}

.file-icon {
fill-rule: evenodd;
clip-rule: evenodd;
stroke-linejoin: round;
stroke-miterlimit: 2;

&-extension {
font-family: 'ArialMT','Arial',sans-serif;
font-size: 4em;
font-weight: 900;
fill: #fff;
}

&-label {
fill: #576D7E; /* Default color */
fill-rule: nonzero;
}

&-css,
&-less,
&-scss {
fill: #B73FD9;
}
&-html,
&-xml {
fill: #EA9B47;
}
&-js,
&-json {
fill: #A9A9A9;
}
&-pdf {
fill: #E30713;
}
&-txt {
fill: #248BD0;
}
&-ai {
fill: #F29200;
}
&-eps {
fill: #F9B234;
}
&-psd {
fill: #2DAAE2;
}
&-ttf,
&-otf,
&-woff,
&-woff2 {
fill: #C4CA10;
}
&-doc,
&-docx,
&-rtf,
&-odt {
fill: #0F70B7;
}
&-csv,
&-ods,
&-xls,
&-xlsx {
fill: #3BAA34;
}
&-odp,
&-ppt,
&-pptx {
fill: #D04526;
}
&-rar,
&-tar,
&-zip {
fill: #363A56;
}
}

.media-player-fallback {
font-size: 13px;
color: #95a5a6;
Expand Down Expand Up @@ -215,6 +291,10 @@ div[data-control="media-manager"] {
font-size: 35px;
}

svg {
max-height: 44px;
}

&.image {
border-right: 1px solid #ecf0f1!important;
}
Expand Down Expand Up @@ -290,6 +370,10 @@ div[data-control="media-manager"] {
font-size: 55px;
}

svg {
max-height: 65px;
}

p {
font-family: @font-family-base;
}
Expand Down Expand Up @@ -317,19 +401,24 @@ div[data-control="media-manager"] {
margin-bottom: 20px;
}

.sidebar-image-placeholder-container {
.sidebar-image-placeholder-container,
.sidebar-document-placeholder-container {
display: table;
width: 100%;
}

.sidebar-image-placeholder {
.sidebar-image-placeholder,
.sidebar-document-placeholder {
display: table-cell;
height: 225px;
position: relative;
vertical-align: middle;
text-align: center;
border-bottom: 1px solid #ecf0f1;
box-sizing: content-box;
}

.sidebar-image-placeholder {
height: 225px;

&[data-loading] {
background: #ecf0f1;
Expand Down Expand Up @@ -358,6 +447,15 @@ div[data-control="media-manager"] {
}
}

.sidebar-document-placeholder {
height: 155px;

svg {
width: 100px;
height: 100px;
}
}

.list-container {
position: relative;
z-index: 100;
Expand Down
21 changes: 20 additions & 1 deletion modules/backend/widgets/mediamanager/partials/_item-icon.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
<div class="icon-container <?= $itemType ?>">
<div class="icon-wrapper"><i class="<?= $this->itemTypeToIconClass($item, $itemType) ?>"></i></div>
<div class="icon-wrapper">
<?php
$itemIconClass = $this->itemTypeToIconClass($item, $itemType);
$extension = substr(strtolower(pathinfo($item->path, PATHINFO_EXTENSION)), 0, 4) ?? '???';

if ($itemIconClass == 'icon-file'): ?>
<svg class="file-icon" viewBox="0 0 250 250" xml:space="preserve">
<path d="M62.5,0c-8.594,0 -15.625,7.031 -15.625,15.625l0,218.75c0,8.594 7.031,15.625 15.625,15.625l156.25,0c8.594,0 15.625,-7.031 15.625,-15.625l0,-171.875l-62.5,-62.5l-109.375,0Z" style="fill:#e2e5e7;fill-rule:nonzero;"/>
<path d="M187.5,62.5l46.875,0l-62.5,-62.5l0,46.875c0,8.594 7.031,15.625 15.625,15.625Z" style="fill:#b0b7bd;fill-rule:nonzero;"/>
<path d="M234.375,109.375l-46.875,-46.875l46.875,0l0,46.875Z" style="fill:#cad1d8;fill-rule:nonzero;"/>
<path d="M195.313,210.938l-148.438,-0.001l0,7.813l148.438,0c4.296,0 7.812,-3.516 7.812,-7.813l-0,-7.812c-0,4.297 -3.516,7.813 -7.813,7.813Z" style="fill:#cad1d8;fill-rule:nonzero;"/>
<!-- Colour label -->
<path class="file-icon-label file-icon-<?= $extension ?>" d="M203.125,203.125c0,4.297 -3.516,7.813 -7.813,7.813l-171.875,-0c-4.296,-0 -7.812,-3.516 -7.812,-7.813l-0,-78.125c-0,-4.297 3.516,-7.813 7.812,-7.813l171.875,0.001c4.297,-0.001 7.813,3.515 7.813,7.812l0,78.125Z"/>
<!-- Extension text node -->
<text class="file-icon-extension" x="43%" y="170px" dominant-baseline="middle" text-anchor="middle"><?= strtoupper($extension) ?></text>
</svg>
<?php else :?>
<i class="<?= $itemIconClass ?>"></i>
<?php endif ?>
</div>
<?php if (
$itemType == System\Classes\MediaLibraryItem::FILE_TYPE_IMAGE
&& $thumbnailUrl = $this->getResizedImageUrl($item->path, $thumbnailParams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
<div class="sidebar-image-placeholder-container"><div class="sidebar-image-placeholder" data-path="{path}" data-last-modified="{last-modified}" data-loading="true" data-control="sidebar-thumbnail"></div></div>
</script>

<script type="text/template" data-control="document-template">
<div class="sidebar-document-placeholder-container"><div class="sidebar-document-placeholder" data-path="{path}" data-last-modified="{last-modified}" data-control="sidebar-document"></div></div>
</script>

<script type="text/template" data-control="no-selection-template">
<div class="sidebar-image-placeholder-container">
<div class="sidebar-image-placeholder no-border">
Expand Down

0 comments on commit 9e8c043

Please sign in to comment.