fix(desktop): restore correct filename in save dialog for attachment downloads#4296
fix(desktop): restore correct filename in save dialog for attachment downloads#4296niklaskie wants to merge 2 commits into
Conversation
…downloads Without a will-download handler, Electron derives the suggested filename from the URL path (/api/attachments/<id>/download → download.txt) and ignores the Content-Disposition header sent by the server. Adding the handler and forwarding item.getFilename() — which reads the Content-Disposition filename — restores the correct name and extension in the native save dialog. Fixes multica-ai#4153
|
Someone is attempting to deploy a commit to the IndexLabs Team on Vercel. A member of the Team first needs to authorize it. |
multica-eve
left a comment
There was a problem hiding this comment.
Thanks for tracking this down and sending the focused fix. The product behavior you are fixing is the right one: desktop downloads should suggest the attachment's real filename instead of download.txt, and your use of item.getFilename() is the right mechanism for getting the filename Electron parsed from Content-Disposition.
I need one change before we can merge this:
The new will-download listener is registered inside createWindow(), but window.webContents.session is a shared session. On macOS, app.on("activate") can call createWindow() again after all windows have been closed. Each recreated window would add another listener to the same shared session, so later downloads can trigger multiple handlers and eventually cause listener leaks / MaxListenersWarning.
Please move this to a one-time app/session setup, or guard it so each session only gets the handler once. For example, a module-level guard or WeakSet<Electron.Session> would work:
const downloadDialogSessions = new WeakSet<Electron.Session>();
function installDownloadSaveDialogHandler(window: BrowserWindow): void {
const { session } = window.webContents;
if (downloadDialogSessions.has(session)) return;
downloadDialogSessions.add(session);
session.on("will-download", (_event, item) => {
item.setSaveDialogOptions({
defaultPath: join(app.getPath("downloads"), item.getFilename()),
});
});
}After that, please also verify the close-window / reopen-window path: close all desktop windows, reopen the app, then download an attachment and confirm the save dialog still shows the correct filename without registering duplicate handlers.
…tration On macOS, app activate can call createWindow() again after all windows are closed. window.webContents.session is shared, so registering the will-download handler inside createWindow() would add duplicate listeners. Extract into installDownloadSaveDialogHandler() with a WeakSet guard so the handler is registered at most once per session.
Problem
Closes #4153
When downloading an attachment from the desktop app, the native save dialog always shows
download.txtas the filename — regardless of the actual file type or name.Root cause:
win.webContents.downloadURL()is called without awill-downloadsession handler. Without this handler, Electron derives the suggested filename from the URL path (/api/attachments/<id>/download→download.txt) and ignores theContent-Dispositionheader sent by the server.This does not affect the browser (web) version, which handles
Content-Dispositionnatively and works correctly.Fix
Add a
will-downloadevent listener onwindow.webContents.sessionthat reads the correct filename viaitem.getFilename()(which parsesContent-Disposition) and passes it tosetSaveDialogOptions. The user still gets the native save dialog — just with the correct default filename and extension.Testing
0.3.24download.txtfor all attachment typesIKS Logo Red.png,IKS RGB.ai)