fix: Fix downloads silently failing on Android

This commit is contained in:
Aman Harwara
2025-01-31 22:48:39 +05:30
parent 27aa7139cb
commit 42aedcdf84
2 changed files with 35 additions and 15 deletions

View File

@@ -21,17 +21,30 @@ export class StreamingFileSaver {
return window.showSaveFilePicker != undefined
}
/** This function must be called in response to a user interaction, otherwise, it will be rejected by the browser. */
async selectFileToSaveTo(handle?: FileSystemFileHandle): Promise<void> {
/**
* This function must be called in response to a user interaction, otherwise, it will be rejected by the browser.
* @returns Whether file was successfully selected or not.
*/
async selectFileToSaveTo(handle?: FileSystemFileHandle): Promise<boolean> {
this.log('Showing save file picker')
const downloadHandle = handle
? handle
: await window.showSaveFilePicker({
suggestedName: this.name,
})
try {
const downloadHandle = handle
? handle
: await window.showSaveFilePicker({
suggestedName: this.name,
})
this.writableStream = await downloadHandle.createWritable()
if (!downloadHandle) {
return false
}
this.writableStream = await downloadHandle.createWritable()
return true
} catch {
return false
}
}
async pushBytes(bytes: Uint8Array): Promise<void> {

View File

@@ -313,15 +313,18 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
}
try {
const saver = this.shouldUseStreamingAPI ? new StreamingFileSaver(file.name) : new ClassicFileSaver()
let saver = this.shouldUseStreamingAPI ? new StreamingFileSaver(file.name) : new ClassicFileSaver()
let didSelectFileToStreamTo = false
const isUsingStreamingSaver = saver instanceof StreamingFileSaver
if (isUsingStreamingSaver) {
if (isUsingStreamingSaver(saver)) {
const fileHandle = directoryHandle
? await directoryHandle.getFileHandle(file.name, { create: true })
: undefined
await saver.selectFileToSaveTo(fileHandle)
didSelectFileToStreamTo = await saver.selectFileToSaveTo(fileHandle)
}
if (isUsingStreamingSaver(saver) && !didSelectFileToStreamTo) {
saver = new ClassicFileSaver()
}
if (this.mobileDevice && canShowProgressNotification) {
@@ -345,7 +348,7 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
let lastProgress: FileDownloadProgress | undefined
const result = await this.files.downloadFile(file, async (decryptedBytes, progress) => {
if (isUsingStreamingSaver) {
if (isUsingStreamingSaver(saver)) {
await saver.pushBytes(decryptedBytes)
} else {
decryptedBytesArray.push(decryptedBytes)
@@ -378,7 +381,7 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
throw new Error(result.text)
}
if (isUsingStreamingSaver) {
if (isUsingStreamingSaver(saver)) {
await saver.finish()
} else {
const finalBytes = concatenateUint8Arrays(decryptedBytesArray)
@@ -850,3 +853,7 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
})
}
}
function isUsingStreamingSaver(saver: StreamingFileSaver | ClassicFileSaver): saver is StreamingFileSaver {
return saver instanceof StreamingFileSaver
}