Closed Tzvetelin88 closed 1 year ago
No, it's not possible. to initiate the save dialog you actually have to start the download first.
It's however possible with the new file system access api await showSaveFilePicker()
but it's only avalible in Blink
I was experimenting and did "write: immediately after "getWriter" and then browser first displayed screen to save the file and then started to write(where as in the example above SockerIO is async and there is a time frame between "write" and "getWriter"), is this possible?
Example:
const fileStream = streamSaver.createWriteStream('test.txt', {
size: this.fileToDownload.size, // (optional filesize) Will show progress
});
this.fWriter = fileStream.getWriter();
this.fWriter.write(
new Uint8Array([
84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 85, 105, 110, 116, 56, 65,
114, 114, 97, 121, 32, 99, 111, 110, 118, 101, 114, 116, 101, 100, 32,
116, 111, 32, 97, 32, 115, 116, 114, 105, 110, 103,
])
);
this.fWriter.close();
P.S. I was thinking how for example OneDrive or GoogleDrive actually saving the files. They first ask to save file on Client side and then start writing.
Actually I found why above "seems to work". Data is too small, data is already written to memory and in the end browser saveAs is displayed, so yes... the same problem as firstly noticed.
Is this what you have mentioned - https://developer.mozilla.org/en-US/docs/Web/API/Window/showSaveFilePicker? Seems Chrome have it? In the dev console of Chrome, when i do showSaveFilePicker() it actually shows it
I did one quick implementation and seem to work. @jimmywarting let me know what do you think.
Code updated like this:
try {
// Show the file save dialog.
const handle = await window.showSaveFilePicker({
suggestedName: 'tes1200.txt',
});
// Write the blob to the file.
this.fWriter = await handle.createWritable();
} catch (err: any) {
// Fail silently if the user has simply canceled the dialog.
if (err.name !== 'AbortError') {
console.error(err.name, err.message);
return;
}
}
//Socket io section to stream data and use this.fWriter
await this.fWriter.write(new Uint8Array(data.bufferData))
// after file is streamed we close the stream
await this.fWriter.close()
I needed to install
yarn add -D @types/wicg-file-system-access
and to add
"types": ["@types/wicg-file-system-access"]
to "types": ["@types/wicg-file-system-access"]
https://user-images.githubusercontent.com/9692941/225993997-5cbf274e-3421-4bc1-9b99-b90dce5eecd8.mov
I attached a video.
Looks alright
Can we fist popup the screen on the Browser to tell where we want to save the file on the Client Side and then start write to it?
I first get data streamed to the Client, and few seconds later (even sometimes at the end) browser popups the screen to save the file on the Clients FS. I started this project with SocketIO.
In short I have this. Creating writeStream -> init getWriter -> socket emit "fileDownload" which creates createReadStream and sending chunks back to the client and client listen to them on "fileProgress".