Skip to content

Commit

Permalink
download multiple files on safari ios
Browse files Browse the repository at this point in the history
  • Loading branch information
omohokcoj committed Jan 1, 2024
1 parent 30582b2 commit 4e7902b
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 30 deletions.
67 changes: 52 additions & 15 deletions app/javascript/elements/download_button.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,64 @@ export default targetable(class extends HTMLElement {
this.toggleState()

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

link.href = blobUrl
link.setAttribute('download', decodeURI(url.split('/').pop()))
if (isSafariIos && urls.length > 1) {
this.downloadSafariIos(urls)
} else {
this.downloadUrls(urls)
}
})
}

downloadUrls (urls) {
const fileRequests = urls.map((url) => {
return () => {
return fetch(url).then(async (resp) => {
const blobUrl = URL.createObjectURL(await resp.blob())
const link = document.createElement('a')

link.href = blobUrl
link.setAttribute('download', decodeURI(url.split('/').pop()))

link.click()

URL.revokeObjectURL(blobUrl)
})
}
})

link.click()
fileRequests.reduce(
(prevPromise, request) => prevPromise.then(() => request()),
Promise.resolve()
)

URL.revokeObjectURL(url)
})
}
this.toggleState()
}

downloadSafariIos (urls) {
const fileRequests = urls.map((url) => {
return fetch(url).then(async (resp) => {
const blob = await resp.blob()
const blobUrl = URL.createObjectURL(blob.slice(0, blob.size, 'application/octet-stream'))
const link = document.createElement('a')

link.href = blobUrl
link.setAttribute('download', decodeURI(url.split('/').pop()))

return link
})
})

fileRequests.reduce(
(prevPromise, request) => prevPromise.then(() => request()),
Promise.resolve()
)
Promise.all(fileRequests).then((links) => {
links.forEach((link, index) => {
setTimeout(() => {
link.click()

URL.revokeObjectURL(link.href)
}, index * 50)
})
}).finally(() => {
this.toggleState()
})
}
Expand Down
66 changes: 51 additions & 15 deletions app/javascript/submission_form/completed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -179,27 +179,63 @@ export default {
this.isDownloading = true
fetch(this.baseUrl + `/submitters/${this.submitterSlug}/download`).then((response) => response.json()).then((urls) => {
const fileRequests = urls.map((url) => {
return () => {
return fetch(url).then(async (resp) => {
const blobUrl = URL.createObjectURL(await resp.blob())
const link = document.createElement('a')
const isSafariIos = /iPhone|iPad|iPod/i.test(navigator.userAgent)
link.href = blobUrl
link.setAttribute('download', decodeURI(url.split('/').pop()))
if (isSafariIos && urls.length > 1) {
this.downloadSafariIos(urls)
} else {
this.downloadUrls(urls)
}
})
},
downloadUrls (urls) {
const fileRequests = urls.map((url) => {
return () => {
return fetch(url).then(async (resp) => {
const blob = await resp.blob()
const blobUrl = URL.createObjectURL(blob.slice(0, blob.size, 'application/octet-stream'))
const link = document.createElement('a')
link.href = blobUrl
link.setAttribute('download', decodeURI(url.split('/').pop()))
link.click()
URL.revokeObjectURL(blobUrl)
})
}
})
link.click()
fileRequests.reduce(
(prevPromise, request) => prevPromise.then(() => request()),
Promise.resolve()
)
URL.revokeObjectURL(url)
})
}
this.isDownloading = false
},
downloadSafariIos (urls) {
const fileRequests = urls.map((url) => {
return fetch(url).then(async (resp) => {
const blob = await resp.blob()
const blobUrl = URL.createObjectURL(blob.slice(0, blob.size, 'application/octet-stream'))
const link = document.createElement('a')
link.href = blobUrl
link.setAttribute('download', decodeURI(url.split('/').pop()))
return link
})
})
fileRequests.reduce(
(prevPromise, request) => prevPromise.then(() => request()),
Promise.resolve()
)
Promise.all(fileRequests).then((links) => {
links.forEach((link, index) => {
setTimeout(() => {
link.click()
URL.revokeObjectURL(link.href)
}, index * 50)
})
}).finally(() => {
this.isDownloading = false
})
}
Expand Down

0 comments on commit 4e7902b

Please sign in to comment.