chore: fix issue with downloading multiple files on macOS
This commit is contained in:
Binary file not shown.
BIN
.yarn/cache/@types-wicg-file-system-access-npm-2023.10.4-96a8d75efc-bfbadfbddc.zip
vendored
Normal file
BIN
.yarn/cache/@types-wicg-file-system-access-npm-2023.10.4-96a8d75efc-bfbadfbddc.zip
vendored
Normal file
Binary file not shown.
@@ -29,7 +29,7 @@
|
|||||||
"@standardnotes/common": "^1.50.0",
|
"@standardnotes/common": "^1.50.0",
|
||||||
"@standardnotes/files": "workspace:*",
|
"@standardnotes/files": "workspace:*",
|
||||||
"@standardnotes/utils": "workspace:*",
|
"@standardnotes/utils": "workspace:*",
|
||||||
"@types/wicg-file-system-access": "^2020.9.5",
|
"@types/wicg-file-system-access": "^2023.10.4",
|
||||||
"reflect-metadata": "^0.1.13"
|
"reflect-metadata": "^0.1.13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ export class StreamingFileSaver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** This function must be called in response to a user interaction, otherwise, it will be rejected by the browser. */
|
/** This function must be called in response to a user interaction, otherwise, it will be rejected by the browser. */
|
||||||
async selectFileToSaveTo(): Promise<void> {
|
async selectFileToSaveTo(handle?: FileSystemFileHandle): Promise<void> {
|
||||||
this.log('Showing save file picker')
|
this.log('Showing save file picker')
|
||||||
|
|
||||||
const downloadHandle = await window.showSaveFilePicker({
|
const downloadHandle = handle
|
||||||
suggestedName: this.name,
|
? handle
|
||||||
})
|
: await window.showSaveFilePicker({
|
||||||
|
suggestedName: this.name,
|
||||||
|
})
|
||||||
|
|
||||||
this.writableStream = await downloadHandle.createWritable()
|
this.writableStream = await downloadHandle.createWritable()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
"@types/jest": "^29.2.4",
|
"@types/jest": "^29.2.4",
|
||||||
"@types/react": "^18.2.39",
|
"@types/react": "^18.2.39",
|
||||||
"@types/react-dom": "^18.2.17",
|
"@types/react-dom": "^18.2.17",
|
||||||
"@types/wicg-file-system-access": "^2020.9.5",
|
"@types/wicg-file-system-access": "^2023.10.4",
|
||||||
"@zip.js/zip.js": "^2.6.60",
|
"@zip.js/zip.js": "^2.6.60",
|
||||||
"autoprefixer": "^10.4.13",
|
"autoprefixer": "^10.4.13",
|
||||||
"babel-loader": "^9.1.2",
|
"babel-loader": "^9.1.2",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export type FileItemAction =
|
|||||||
>
|
>
|
||||||
payload: {
|
payload: {
|
||||||
file: FileItem
|
file: FileItem
|
||||||
|
directoryHandle?: FileSystemDirectoryHandle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
|||||||
showProtectedOverlay = false
|
showProtectedOverlay = false
|
||||||
fileContextMenuLocation: FileContextMenuLocation = { x: 0, y: 0 }
|
fileContextMenuLocation: FileContextMenuLocation = { x: 0, y: 0 }
|
||||||
|
|
||||||
shouldUseStreamingReader = StreamingFileSaver.available()
|
shouldUseStreamingAPI = StreamingFileSaver.available()
|
||||||
reader = this.shouldUseStreamingReader ? StreamingFileReader : ClassicFileReader
|
reader = this.shouldUseStreamingAPI ? StreamingFileReader : ClassicFileReader
|
||||||
maxFileSize = this.reader.maximumFileSize()
|
maxFileSize = this.reader.maximumFileSize()
|
||||||
|
|
||||||
override deinit(): void {
|
override deinit(): void {
|
||||||
@@ -251,7 +251,7 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
|||||||
await this.deleteFile(file)
|
await this.deleteFile(file)
|
||||||
break
|
break
|
||||||
case FileItemActionType.DownloadFile:
|
case FileItemActionType.DownloadFile:
|
||||||
await this.downloadFile(file)
|
await this.downloadFile(file, action.payload.directoryHandle)
|
||||||
break
|
break
|
||||||
case FileItemActionType.ToggleFileProtection: {
|
case FileItemActionType.ToggleFileProtection: {
|
||||||
const isProtected = await this.toggleFileProtection(file)
|
const isProtected = await this.toggleFileProtection(file)
|
||||||
@@ -289,7 +289,7 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private async downloadFile(file: FileItem): Promise<void> {
|
private async downloadFile(file: FileItem, directoryHandle?: FileSystemDirectoryHandle): Promise<void> {
|
||||||
let downloadingToastId = ''
|
let downloadingToastId = ''
|
||||||
let canShowProgressNotification = false
|
let canShowProgressNotification = false
|
||||||
|
|
||||||
@@ -298,12 +298,15 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const saver = StreamingFileSaver.available() ? new StreamingFileSaver(file.name) : new ClassicFileSaver()
|
const saver = this.shouldUseStreamingAPI ? new StreamingFileSaver(file.name) : new ClassicFileSaver()
|
||||||
|
|
||||||
const isUsingStreamingSaver = saver instanceof StreamingFileSaver
|
const isUsingStreamingSaver = saver instanceof StreamingFileSaver
|
||||||
|
|
||||||
if (isUsingStreamingSaver) {
|
if (isUsingStreamingSaver) {
|
||||||
await saver.selectFileToSaveTo()
|
const fileHandle = directoryHandle
|
||||||
|
? await directoryHandle.getFileHandle(file.name, { create: true })
|
||||||
|
: undefined
|
||||||
|
await saver.selectFileToSaveTo(fileHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.mobileDevice && canShowProgressNotification) {
|
if (this.mobileDevice && canShowProgressNotification) {
|
||||||
@@ -413,7 +416,7 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
|||||||
}
|
}
|
||||||
|
|
||||||
alertIfFileExceedsSizeLimit = (file: File): boolean => {
|
alertIfFileExceedsSizeLimit = (file: File): boolean => {
|
||||||
if (!this.shouldUseStreamingReader && this.maxFileSize && file.size >= this.maxFileSize) {
|
if (!this.shouldUseStreamingAPI && this.maxFileSize && file.size >= this.maxFileSize) {
|
||||||
this.alerts
|
this.alerts
|
||||||
.alert(
|
.alert(
|
||||||
`This file exceeds the limits supported in this browser. To upload files greater than ${
|
`This file exceeds the limits supported in this browser. To upload files greater than ${
|
||||||
@@ -465,7 +468,7 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
|||||||
const fileToUpload =
|
const fileToUpload =
|
||||||
fileOrHandle instanceof File
|
fileOrHandle instanceof File
|
||||||
? fileOrHandle
|
? fileOrHandle
|
||||||
: fileOrHandle instanceof FileSystemFileHandle && this.shouldUseStreamingReader
|
: fileOrHandle instanceof FileSystemFileHandle && this.shouldUseStreamingAPI
|
||||||
? await fileOrHandle.getFile()
|
? await fileOrHandle.getFile()
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
@@ -661,15 +664,41 @@ export class FilesController extends AbstractViewController<FilesControllerEvent
|
|||||||
void this.sync.sync()
|
void this.sync.sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDirectoryHandleForDownloads = async () => {
|
||||||
|
if (!this.shouldUseStreamingAPI) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const directoryHandle = await window.showDirectoryPicker({
|
||||||
|
startIn: 'downloads',
|
||||||
|
})
|
||||||
|
|
||||||
|
return directoryHandle
|
||||||
|
}
|
||||||
|
|
||||||
downloadFiles = async (files: FileItem[]) => {
|
downloadFiles = async (files: FileItem[]) => {
|
||||||
// macOS doesn't allow multiple calls to the filepicker at the
|
// macOS doesn't allow multiple calls to the filepicker at the
|
||||||
// same time, so we need to iterate one by one
|
// same time, so we need to iterate one by one
|
||||||
if (this.platform === Platform.MacDesktop || this.platform === Platform.MacWeb) {
|
if (this.platform === Platform.MacDesktop || this.platform === Platform.MacWeb) {
|
||||||
|
let directoryHandle: FileSystemDirectoryHandle | undefined
|
||||||
|
|
||||||
|
if (files.length > 1) {
|
||||||
|
try {
|
||||||
|
directoryHandle = await this.getDirectoryHandleForDownloads()
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof DOMException && error.name === 'AbortError') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
await this.handleFileAction({
|
await this.handleFileAction({
|
||||||
type: FileItemActionType.DownloadFile,
|
type: FileItemActionType.DownloadFile,
|
||||||
payload: {
|
payload: {
|
||||||
file,
|
file,
|
||||||
|
directoryHandle,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
12
yarn.lock
12
yarn.lock
@@ -6753,7 +6753,7 @@ __metadata:
|
|||||||
"@standardnotes/files": "workspace:*"
|
"@standardnotes/files": "workspace:*"
|
||||||
"@standardnotes/utils": "workspace:*"
|
"@standardnotes/utils": "workspace:*"
|
||||||
"@types/jest": ^29.2.3
|
"@types/jest": ^29.2.3
|
||||||
"@types/wicg-file-system-access": ^2020.9.5
|
"@types/wicg-file-system-access": ^2023.10.4
|
||||||
"@typescript-eslint/eslint-plugin": "*"
|
"@typescript-eslint/eslint-plugin": "*"
|
||||||
eslint: "*"
|
eslint: "*"
|
||||||
eslint-plugin-prettier: "*"
|
eslint-plugin-prettier: "*"
|
||||||
@@ -7519,7 +7519,7 @@ __metadata:
|
|||||||
"@types/jest": ^29.2.4
|
"@types/jest": ^29.2.4
|
||||||
"@types/react": ^18.2.39
|
"@types/react": ^18.2.39
|
||||||
"@types/react-dom": ^18.2.17
|
"@types/react-dom": ^18.2.17
|
||||||
"@types/wicg-file-system-access": ^2020.9.5
|
"@types/wicg-file-system-access": ^2023.10.4
|
||||||
"@zip.js/zip.js": ^2.6.60
|
"@zip.js/zip.js": ^2.6.60
|
||||||
autoprefixer: ^10.4.13
|
autoprefixer: ^10.4.13
|
||||||
babel-loader: ^9.1.2
|
babel-loader: ^9.1.2
|
||||||
@@ -8457,10 +8457,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/wicg-file-system-access@npm:^2020.9.5":
|
"@types/wicg-file-system-access@npm:^2023.10.4":
|
||||||
version: 2020.9.6
|
version: 2023.10.4
|
||||||
resolution: "@types/wicg-file-system-access@npm:2020.9.6"
|
resolution: "@types/wicg-file-system-access@npm:2023.10.4"
|
||||||
checksum: 2dbf33ee55684d4ed0607ae4b470e0147806b15ec047563c59d94e6ac13be7bed904cc7eece5e4be7c0d58a4de0b0635089f7cd5b7738372e436c760b0719241
|
checksum: bfbadfbddcdf04f600e0bb1b3dfe8dd79661c987ded487c2ac03670932e4ab9cd277c8b98d6229d10a910cb149c1bf956f43f189c4349f1c1a97cff310154aeb
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user