chore: on android use notification to display file upload progress instead of toast (#2628) [skip e2e]

This commit is contained in:
Aman Harwara
2023-11-09 01:31:34 +05:30
committed by GitHub
parent 6a7c5277f8
commit 2d687d9786
12 changed files with 257 additions and 51 deletions

View File

@@ -291,6 +291,11 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
private async downloadFile(file: FileItem): Promise<void> {
let downloadingToastId = ''
let canShowProgressNotification = false
if (this.mobileDevice && this.platform === Platform.Android) {
canShowProgressNotification = await this.mobileDevice.canDisplayNotifications()
}
try {
const saver = StreamingFileSaver.available() ? new StreamingFileSaver(file.name) : new ClassicFileSaver()
@@ -301,11 +306,21 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
await saver.selectFileToSaveTo()
}
downloadingToastId = addToast({
type: ToastType.Progress,
message: `Downloading file "${file.name}" (0%)`,
progress: 0,
})
if (this.mobileDevice && canShowProgressNotification) {
downloadingToastId = await this.mobileDevice.displayNotification({
title: `Downloading file "${file.name}"`,
android: {
progress: { max: 100, current: 0, indeterminate: true },
onlyAlertOnce: true,
},
})
} else {
downloadingToastId = addToast({
type: ToastType.Progress,
message: `Downloading file "${file.name}" (0%)`,
progress: 0,
})
}
const decryptedBytesArray: Uint8Array[] = []
@@ -320,10 +335,23 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const progressPercent = Math.floor(progress.percentComplete)
updateToast(downloadingToastId, {
message: fileProgressToHumanReadableString(progress, file.name, { showPercent: true }),
progress: progressPercent,
})
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice
.displayNotification({
id: downloadingToastId,
title: `Downloading file "${file.name}"`,
android: {
progress: { max: 100, current: progressPercent, indeterminate: false },
onlyAlertOnce: true,
},
})
.catch(console.error)
} else {
updateToast(downloadingToastId, {
message: fileProgressToHumanReadableString(progress, file.name, { showPercent: true }),
progress: progressPercent,
})
}
lastProgress = progress
})
@@ -339,7 +367,6 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const blob = new Blob([finalBytes], {
type: file.mimeType,
})
// await downloadOrShareBlobBasedOnPlatform(this, blob, file.name, false)
await downloadOrShareBlobBasedOnPlatform({
archiveService: this.archiveService,
platform: this.platform,
@@ -351,12 +378,18 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
})
}
addToast({
type: ToastType.Success,
message: `Successfully downloaded file${
lastProgress && lastProgress.source === 'local' ? ' from local backup' : ''
}`,
})
if (this.mobileDevice && canShowProgressNotification) {
await this.mobileDevice.displayNotification({
title: `Successfully downloaded file "${file.name}"`,
})
} else {
addToast({
type: ToastType.Success,
message: `Successfully downloaded file${
lastProgress && lastProgress.source === 'local' ? ' from local backup' : ''
}`,
})
}
} catch (error) {
console.error(error)
@@ -366,8 +399,12 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
})
}
if (downloadingToastId.length > 0) {
dismissToast(downloadingToastId)
if (downloadingToastId) {
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice.cancelNotification(downloadingToastId).catch(console.error)
} else {
dismissToast(downloadingToastId)
}
}
}
@@ -412,6 +449,11 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const { showToast = true, note } = options
let toastId: string | undefined
let canShowProgressNotification = false
if (showToast && this.mobileDevice && this.platform === Platform.Android) {
canShowProgressNotification = await this.mobileDevice.canDisplayNotifications()
}
try {
const minimumChunkSize = this.files.minimumChunkSize()
@@ -449,11 +491,21 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const initialProgress = operation.getProgress().percentComplete
if (showToast) {
toastId = addToast({
type: ToastType.Progress,
message: `Uploading file "${fileToUpload.name}" (${initialProgress}%)`,
progress: initialProgress,
})
if (this.mobileDevice && canShowProgressNotification) {
toastId = await this.mobileDevice.displayNotification({
title: `Uploading file "${fileToUpload.name}"`,
android: {
progress: { max: 100, current: initialProgress, indeterminate: true },
onlyAlertOnce: true,
},
})
} else {
toastId = addToast({
type: ToastType.Progress,
message: `Uploading file "${fileToUpload.name}" (${initialProgress}%)`,
progress: initialProgress,
})
}
}
const onChunk: OnChunkCallbackNoProgress = async ({ data, index, isLast }) => {
@@ -461,10 +513,21 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
const percentComplete = Math.round(operation.getProgress().percentComplete)
if (toastId) {
updateToast(toastId, {
message: `Uploading file "${fileToUpload.name}" (${percentComplete}%)`,
progress: percentComplete,
})
if (this.mobileDevice && canShowProgressNotification) {
await this.mobileDevice.displayNotification({
id: toastId,
title: `Uploading file "${fileToUpload.name}"`,
android: {
progress: { max: 100, current: percentComplete, indeterminate: false },
onlyAlertOnce: true,
},
})
} else {
updateToast(toastId, {
message: `Uploading file "${fileToUpload.name}" (${percentComplete}%)`,
progress: percentComplete,
})
}
}
}
@@ -480,32 +543,54 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
if (uploadedFile instanceof ClientDisplayableError) {
addToast({
type: ToastType.Error,
message: 'Unable to close upload session',
message: uploadedFile.text,
})
throw new Error('Unable to close upload session')
throw new Error(uploadedFile.text)
}
if (toastId) {
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice.cancelNotification(toastId).catch(console.error)
}
dismissToast(toastId)
}
if (showToast) {
addToast({
type: ToastType.Success,
message: `Uploaded file "${uploadedFile.name}"`,
actions: [
{
label: 'Open',
handler: (toastId) => {
void this.handleFileAction({
type: FileItemActionType.PreviewFile,
payload: { file: uploadedFile },
})
dismissToast(toastId)
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice
.displayNotification({
id: uploadedFile.uuid,
title: `Uploaded file "${uploadedFile.name}"`,
android: {
actions: [
{
title: 'Open',
pressAction: {
id: 'open-file',
},
},
],
},
},
],
autoClose: true,
})
})
.catch(console.error)
} else {
addToast({
type: ToastType.Success,
message: `Uploaded file "${uploadedFile.name}"`,
actions: [
{
label: 'Open',
handler: (toastId) => {
void this.handleFileAction({
type: FileItemActionType.PreviewFile,
payload: { file: uploadedFile },
})
dismissToast(toastId)
},
},
],
autoClose: true,
})
}
}
return uploadedFile
@@ -513,12 +598,23 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
console.error(error)
if (toastId) {
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice.cancelNotification(toastId).catch(console.error)
}
dismissToast(toastId)
}
addToast({
type: ToastType.Error,
message: 'There was an error while uploading the file',
})
if (this.mobileDevice && canShowProgressNotification) {
this.mobileDevice
.displayNotification({
title: 'There was an error while uploading the file',
})
.catch(console.error)
} else {
addToast({
type: ToastType.Error,
message: 'There was an error while uploading the file',
})
}
}
return undefined