Skip to content

Commit 599e7e6

Browse files
committed
Fix download task cleanup & browser compatibility
Improve types
1 parent 78f623b commit 599e7e6

File tree

8 files changed

+8203
-28
lines changed

8 files changed

+8203
-28
lines changed

USERGUIDE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ We're looking into adding such capabilities to Image Downloader in the future. I
2222

2323
📝 Change Log
2424
━━━━━━━
25-
3.3.0:
25+
3.3.1:
2626
- Disable slider handles when the checkbox is unchecked
2727
- Add tooltips to slider handles, slider checkboxes, and the Download button
28+
- Fix some issues with downloads not being cleaned up
2829

2930
3.2.3:
3031
- Download in the background - you can now close the popup and the images will keep downloading!

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "Image Downloader",
33
"description": "Browse and download images on the web",
4-
"version": "3.3.0",
4+
"version": "3.3.1",
55
"minimum_chrome_version": "72",
66
"manifest_version": 2,
77
"icons": {

package-lock.json

Lines changed: 8161 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"private": true,
33
"name": "image-downloader",
4-
"version": "3.3.0",
4+
"version": "3.3.1",
55
"license": "MIT",
66
"scripts": {
77
"start": "npm run build && node scripts/watch.js",

src/Popup/AdvancedFilters.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,11 @@ const useSlider = (dimension, options, setOptions) => {
191191
}));
192192
});
193193

194-
return () => slider.noUiSlider?.destroy();
194+
return () => {
195+
if (slider.noUiSlider) {
196+
slider.noUiSlider.destroy();
197+
}
198+
};
195199
}, []);
196200

197201
useEffect(() => {
@@ -212,12 +216,18 @@ const useSlider = (dimension, options, setOptions) => {
212216
]);
213217

214218
useDisableSliderHandle(
215-
() => sliderRef.current?.querySelectorAll('.noUi-origin')[0],
219+
() =>
220+
sliderRef.current
221+
? sliderRef.current.querySelectorAll('.noUi-origin')[0]
222+
: undefined,
216223
options[`filter_min_${dimension}_enabled`]
217224
);
218225

219226
useDisableSliderHandle(
220-
() => sliderRef.current?.querySelectorAll('.noUi-origin')[1],
227+
() =>
228+
sliderRef.current
229+
? sliderRef.current.querySelectorAll('.noUi-origin')[1]
230+
: undefined,
221231
options[`filter_max_${dimension}_enabled`]
222232
);
223233

src/Popup/ImageActions.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ export const OpenImageButton = ({ imageUrl, onClick, ...props }) => {
2020
style=${{ backgroundImage: `url("/images/open.svg")` }}
2121
onClick=${(e) => {
2222
chrome.tabs.create({ url: imageUrl, active: false });
23-
onClick?.(e);
23+
if (onClick) {
24+
onClick(e);
25+
}
2426
}}
2527
...${props}
2628
/>
@@ -40,7 +42,9 @@ export const DownloadImageButton = ({
4042
style=${{ backgroundImage: `url("/images/download.svg")` }}
4143
onClick=${(e) => {
4244
actions.downloadImages([imageUrl], options);
43-
onClick?.(e);
45+
if (onClick) {
46+
onClick(e);
47+
}
4448
}}
4549
...${props}
4650
/>

src/background/downloadImages.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1-
/** @type {Set<{ numberOfProcessedImages: number, imagesToDownload: string[], options: any, next: () => void }>} */
1+
// @ts-check
2+
/** @typedef {{ numberOfProcessedImages: number, imagesToDownload: string[], options: any, next: () => void }} Task */
3+
4+
/** @type {Set<Task>} */
25
const tasks = new Set();
36

4-
// NOTE: Don't directly use an `async` function as a listener:
5-
// https://stackoverflow.com/a/56483156
67
chrome.runtime.onMessage.addListener(startDownload);
78
chrome.downloads.onDeterminingFilename.addListener(suggestNewFilename);
89

9-
function startDownload(message, sender, resolve) {
10-
if (message?.type !== 'downloadImages') return;
10+
// NOTE: Don't directly use an `async` function as a listener for `onMessage`:
11+
// https://stackoverflow.com/a/56483156
12+
// https://developer.chrome.com/docs/extensions/reference/runtime/#event-onMessage
13+
function startDownload(
14+
/** @type {any} */ message,
15+
/** @type {chrome.runtime.MessageSender} */ sender,
16+
/** @type {(response?: any) => void} */ resolve
17+
) {
18+
if (!(message && message.type === 'downloadImages')) return;
1119

1220
downloadImages({
1321
numberOfProcessedImages: 0,
@@ -21,22 +29,24 @@ function startDownload(message, sender, resolve) {
2129
},
2230
}).then(resolve);
2331

24-
return true;
32+
return true; // Keeps the message channel open until `resolve` is called
2533
}
2634

27-
async function downloadImages(task) {
35+
async function downloadImages(/** @type {Task} */ task) {
2836
tasks.add(task);
2937
for (const image of task.imagesToDownload) {
3038
await new Promise((resolve) => {
3139
chrome.downloads.download({ url: image }, resolve);
3240
});
3341
if (chrome.runtime.lastError) {
3442
console.error(`${chrome.runtime.lastError.message}: ${image}`);
35-
task.next();
3643
}
44+
task.next();
3745
}
3846
}
3947

48+
// https://developer.chrome.com/docs/extensions/reference/downloads/#event-onDeterminingFilename
49+
/** @type {Parameters<chrome.downloads.DownloadDeterminingFilenameEvent['addListener']>[0]} */
4050
function suggestNewFilename(item, suggest) {
4151
const task = [...tasks][0];
4252
if (!task) {
@@ -62,7 +72,6 @@ function suggestNewFilename(item, suggest) {
6272
}
6373

6474
suggest({ filename: normalizeSlashes(newFilename) });
65-
task.next();
6675
}
6776

6877
function normalizeSlashes(filename) {

src/background/handleUpdates.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// @ts-check
12
chrome.runtime.onInstalled.addListener((details) => {
23
if (details.reason === 'install') {
34
// Open the options page after install

0 commit comments

Comments
 (0)