Skip to content

Commit 4e7902b

Browse files
committed
download multiple files on safari ios
1 parent 30582b2 commit 4e7902b

File tree

2 files changed

+103
-30
lines changed

2 files changed

+103
-30
lines changed

app/javascript/elements/download_button.js

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,64 @@ export default targetable(class extends HTMLElement {
1818
this.toggleState()
1919

2020
fetch(this.dataset.src).then((response) => response.json()).then((urls) => {
21-
const fileRequests = urls.map((url) => {
22-
return () => {
23-
return fetch(url).then(async (resp) => {
24-
const blobUrl = URL.createObjectURL(await resp.blob())
25-
const link = document.createElement('a')
21+
const isSafariIos = /iPhone|iPad|iPod/i.test(navigator.userAgent)
2622

27-
link.href = blobUrl
28-
link.setAttribute('download', decodeURI(url.split('/').pop()))
23+
if (isSafariIos && urls.length > 1) {
24+
this.downloadSafariIos(urls)
25+
} else {
26+
this.downloadUrls(urls)
27+
}
28+
})
29+
}
30+
31+
downloadUrls (urls) {
32+
const fileRequests = urls.map((url) => {
33+
return () => {
34+
return fetch(url).then(async (resp) => {
35+
const blobUrl = URL.createObjectURL(await resp.blob())
36+
const link = document.createElement('a')
37+
38+
link.href = blobUrl
39+
link.setAttribute('download', decodeURI(url.split('/').pop()))
40+
41+
link.click()
42+
43+
URL.revokeObjectURL(blobUrl)
44+
})
45+
}
46+
})
2947

30-
link.click()
48+
fileRequests.reduce(
49+
(prevPromise, request) => prevPromise.then(() => request()),
50+
Promise.resolve()
51+
)
3152

32-
URL.revokeObjectURL(url)
33-
})
34-
}
53+
this.toggleState()
54+
}
55+
56+
downloadSafariIos (urls) {
57+
const fileRequests = urls.map((url) => {
58+
return fetch(url).then(async (resp) => {
59+
const blob = await resp.blob()
60+
const blobUrl = URL.createObjectURL(blob.slice(0, blob.size, 'application/octet-stream'))
61+
const link = document.createElement('a')
62+
63+
link.href = blobUrl
64+
link.setAttribute('download', decodeURI(url.split('/').pop()))
65+
66+
return link
3567
})
68+
})
3669

37-
fileRequests.reduce(
38-
(prevPromise, request) => prevPromise.then(() => request()),
39-
Promise.resolve()
40-
)
70+
Promise.all(fileRequests).then((links) => {
71+
links.forEach((link, index) => {
72+
setTimeout(() => {
73+
link.click()
4174

75+
URL.revokeObjectURL(link.href)
76+
}, index * 50)
77+
})
78+
}).finally(() => {
4279
this.toggleState()
4380
})
4481
}

app/javascript/submission_form/completed.vue

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -179,27 +179,63 @@ export default {
179179
this.isDownloading = true
180180
181181
fetch(this.baseUrl + `/submitters/${this.submitterSlug}/download`).then((response) => response.json()).then((urls) => {
182-
const fileRequests = urls.map((url) => {
183-
return () => {
184-
return fetch(url).then(async (resp) => {
185-
const blobUrl = URL.createObjectURL(await resp.blob())
186-
const link = document.createElement('a')
182+
const isSafariIos = /iPhone|iPad|iPod/i.test(navigator.userAgent)
187183
188-
link.href = blobUrl
189-
link.setAttribute('download', decodeURI(url.split('/').pop()))
184+
if (isSafariIos && urls.length > 1) {
185+
this.downloadSafariIos(urls)
186+
} else {
187+
this.downloadUrls(urls)
188+
}
189+
})
190+
},
191+
downloadUrls (urls) {
192+
const fileRequests = urls.map((url) => {
193+
return () => {
194+
return fetch(url).then(async (resp) => {
195+
const blob = await resp.blob()
196+
const blobUrl = URL.createObjectURL(blob.slice(0, blob.size, 'application/octet-stream'))
197+
const link = document.createElement('a')
198+
199+
link.href = blobUrl
200+
link.setAttribute('download', decodeURI(url.split('/').pop()))
201+
202+
link.click()
203+
204+
URL.revokeObjectURL(blobUrl)
205+
})
206+
}
207+
})
190208
191-
link.click()
209+
fileRequests.reduce(
210+
(prevPromise, request) => prevPromise.then(() => request()),
211+
Promise.resolve()
212+
)
192213
193-
URL.revokeObjectURL(url)
194-
})
195-
}
214+
this.isDownloading = false
215+
},
216+
downloadSafariIos (urls) {
217+
const fileRequests = urls.map((url) => {
218+
return fetch(url).then(async (resp) => {
219+
const blob = await resp.blob()
220+
const blobUrl = URL.createObjectURL(blob.slice(0, blob.size, 'application/octet-stream'))
221+
const link = document.createElement('a')
222+
223+
link.href = blobUrl
224+
link.setAttribute('download', decodeURI(url.split('/').pop()))
225+
226+
return link
196227
})
228+
})
197229
198-
fileRequests.reduce(
199-
(prevPromise, request) => prevPromise.then(() => request()),
200-
Promise.resolve()
201-
)
230+
Promise.all(fileRequests).then((links) => {
231+
links.forEach((link, index) => {
232+
setTimeout(() => {
233+
link.click()
202234
235+
URL.revokeObjectURL(link.href)
236+
}, index * 50)
237+
})
238+
}).finally(() => {
203239
this.isDownloading = false
204240
})
205241
}

0 commit comments

Comments
 (0)