Skip to content

Commit 354485e

Browse files
devvaannshabose
authored andcommitted
feat: show downloading indicator when image is being downloaded
1 parent 76ec028 commit 354485e

File tree

1 file changed

+78
-3
lines changed

1 file changed

+78
-3
lines changed

src/LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,6 +2233,40 @@ function RemoteFunctions(config = {}) {
22332233
.phoenix-ribbon-thumb {
22342234
cursor: pointer !important;
22352235
}
2236+
2237+
.phoenix-ribbon-thumb.downloading {
2238+
opacity: 0.6 !important;
2239+
pointer-events: none !important;
2240+
}
2241+
2242+
.phoenix-download-indicator {
2243+
position: absolute !important;
2244+
top: 50% !important;
2245+
left: 50% !important;
2246+
transform: translate(-50%, -50%) !important;
2247+
background: rgba(0, 0, 0, 0.8) !important;
2248+
border-radius: 50% !important;
2249+
width: 40px !important;
2250+
height: 40px !important;
2251+
display: flex !important;
2252+
align-items: center !important;
2253+
justify-content: center !important;
2254+
z-index: 10 !important;
2255+
}
2256+
2257+
.phoenix-download-spinner {
2258+
width: 20px !important;
2259+
height: 20px !important;
2260+
border: 2px solid rgba(255, 255, 255, 0.3) !important;
2261+
border-top: 2px solid #fff !important;
2262+
border-radius: 50% !important;
2263+
animation: phoenix-spin 1s linear infinite !important;
2264+
}
2265+
2266+
@keyframes phoenix-spin {
2267+
0% { transform: rotate(0deg); }
2268+
100% { transform: rotate(360deg); }
2269+
}
22362270
</style>
22372271
<div class="phoenix-image-ribbon">
22382272
<div class="phoenix-ribbon-container">
@@ -2691,6 +2725,13 @@ function RemoteFunctions(config = {}) {
26912725
thumbDiv.addEventListener('click', (e) => {
26922726
e.stopPropagation();
26932727
e.preventDefault();
2728+
2729+
// prevent multiple downloads of the same image
2730+
if (thumbDiv.classList.contains('downloading')) { return; }
2731+
2732+
// show download indicator
2733+
this._showDownloadIndicator(thumbDiv);
2734+
26942735
const filename = this._generateFilename(image);
26952736
const extnName = ".jpg";
26962737

@@ -2700,7 +2741,7 @@ function RemoteFunctions(config = {}) {
27002741
const heightNum = parseInt(targetHeight);
27012742

27022743
const downloadUrl = image.url ? `${image.url}?w=${widthNum}&h=${heightNum}&fit=crop` : image.thumb_url;
2703-
this._useImage(downloadUrl, filename, extnName, false);
2744+
this._useImage(downloadUrl, filename, extnName, false, thumbDiv);
27042745
});
27052746

27062747
thumbDiv.appendChild(img);
@@ -2736,7 +2777,7 @@ function RemoteFunctions(config = {}) {
27362777
return `${cleanSearchTerm}-by-${cleanPhotographerName}`;
27372778
},
27382779

2739-
_useImage: function(imageUrl, filename, extnName, isLocalFile) {
2780+
_useImage: function(imageUrl, filename, extnName, isLocalFile, thumbDiv) {
27402781
// send the message to the editor instance to save the image and update the source code
27412782
const tagId = this.element.getAttribute("data-brackets-id");
27422783

@@ -2763,6 +2804,14 @@ function RemoteFunctions(config = {}) {
27632804
}
27642805

27652806
window._Brackets_MessageBroker.send(messageData);
2807+
2808+
// if thumbDiv is provided, hide the download indicator after a reasonable timeout
2809+
// this is to make sure that the indicator is always removed even if there's no explicit success callback
2810+
if (thumbDiv) {
2811+
setTimeout(() => {
2812+
this._hideDownloadIndicator(thumbDiv);
2813+
}, 3000);
2814+
}
27662815
},
27672816

27682817
_handleLocalImageSelection: function(file) {
@@ -2783,7 +2832,7 @@ function RemoteFunctions(config = {}) {
27832832
const filename = cleanName || 'selected-image';
27842833

27852834
// Use the unified _useImage method with isLocalFile flag
2786-
this._useImage(imageDataUrl, filename, extension, true);
2835+
this._useImage(imageDataUrl, filename, extension, true, null);
27872836

27882837
// Close the ribbon after successful selection
27892838
this.remove();
@@ -2824,6 +2873,32 @@ function RemoteFunctions(config = {}) {
28242873
window.document.body.removeChild(this.body);
28252874
this.body = null;
28262875
}
2876+
},
2877+
2878+
_showDownloadIndicator: function(thumbDiv) {
2879+
// add downloading class
2880+
thumbDiv.classList.add('downloading');
2881+
2882+
// create download indicator
2883+
const indicator = window.document.createElement('div');
2884+
indicator.className = 'phoenix-download-indicator';
2885+
2886+
const spinner = window.document.createElement('div');
2887+
spinner.className = 'phoenix-download-spinner';
2888+
2889+
indicator.appendChild(spinner);
2890+
thumbDiv.appendChild(indicator);
2891+
},
2892+
2893+
_hideDownloadIndicator: function(thumbDiv) {
2894+
// remove downloading class
2895+
thumbDiv.classList.remove('downloading');
2896+
2897+
// remove download indicator
2898+
const indicator = thumbDiv.querySelector('.phoenix-download-indicator');
2899+
if (indicator) {
2900+
indicator.remove();
2901+
}
28272902
}
28282903
};
28292904

0 commit comments

Comments
 (0)