Skip to content

Commit 55867de

Browse files
committed
download: Show in-app notification on downlaoding a file.
Fixes #1371. We do not accept a filePath from the web app when recieving the event to show the file in a folder, since that could introduce securithy vulnerabilies. We store the latest downloaded file path instead in a variable. Only one in-app notification is active at a time, so storing the latest file path is enough for out use case.
1 parent 3956252 commit 55867de

File tree

5 files changed

+53
-5
lines changed

5 files changed

+53
-5
lines changed

app/common/typed-ipc.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export type MainMessage = {
1313
"realm-icon-changed": (serverURL: string, iconURL: string) => void;
1414
"realm-name-changed": (serverURL: string, realmName: string) => void;
1515
"reload-full-app": () => void;
16+
"show-downloaded-file-in-folder": () => void;
1617
"save-last-tab": (index: number) => void;
1718
"switch-server-tab": (index: number) => void;
1819
"toggle-app": () => void;
@@ -59,6 +60,7 @@ export type RendererMessage = {
5960
"reload-proxy": (showAlert: boolean) => void;
6061
"reload-viewer": () => void;
6162
"render-taskbar-icon": (messageCount: number) => void;
63+
"show-download-success": (title: string, description: string) => void;
6264
"set-active": () => void;
6365
"set-idle": () => void;
6466
"show-keyboard-shortcuts": () => void;

app/main/handle-external-link.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ import * as t from "../common/translation-util.ts";
1515

1616
import {send} from "./typed-ipc-main.ts";
1717

18+
let latestDownloadPath: string | undefined;
19+
20+
export function getLatestDownloadPath(): string | undefined {
21+
return latestDownloadPath;
22+
}
23+
1824
function isUploadsUrl(server: string, url: URL): boolean {
1925
return url.origin === server && url.pathname.startsWith("/user_uploads/");
2026
}
@@ -125,16 +131,33 @@ export default function handleExternalLink(
125131
url: url.href,
126132
downloadPath,
127133
async completed(filePath: string, fileName: string) {
134+
const notificationTitle = t.__("Download complete");
135+
const notificationBody = t.__(
136+
"Click to view the folder where the file ({{{fileName}}}) was downloaded.",
137+
{
138+
fileName,
139+
},
140+
);
141+
// Show native notification
128142
const downloadNotification = new Notification({
129-
title: t.__("Download Complete"),
130-
body: t.__("Click to show {{{fileName}}} in folder", {fileName}),
143+
title: notificationTitle,
144+
body: notificationBody,
131145
silent: true, // We'll play our own sound - ding.ogg
132146
});
133147
downloadNotification.on("click", () => {
134148
// Reveal file in download folder
135149
shell.showItemInFolder(filePath);
136150
});
137151
downloadNotification.show();
152+
latestDownloadPath = filePath;
153+
// Event to show in-app notification in addition to the native
154+
// notification.
155+
send(
156+
contents,
157+
"show-download-success",
158+
notificationTitle,
159+
notificationBody,
160+
);
138161

139162
// Play sound to indicate download complete
140163
if (!ConfigUtil.getConfigItem("silent", false)) {
@@ -150,7 +173,7 @@ export default function handleExternalLink(
150173
if (state !== "cancelled") {
151174
if (ConfigUtil.getConfigItem("promptDownload", false)) {
152175
new Notification({
153-
title: t.__("Download Complete"),
176+
title: t.__("Download complete"),
154177
body: t.__("Download failed"),
155178
}).show();
156179
} else {

app/main/index.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {clipboard} from "electron/common";
1+
import {clipboard, shell} from "electron/common";
22
import {
33
BrowserWindow,
44
type IpcMainEvent,
@@ -25,7 +25,9 @@ import type {MenuProperties} from "../common/types.ts";
2525

2626
import {appUpdater, shouldQuitForUpdate} from "./autoupdater.ts";
2727
import * as BadgeSettings from "./badge-settings.ts";
28-
import handleExternalLink from "./handle-external-link.ts";
28+
import handleExternalLink, {
29+
getLatestDownloadPath,
30+
} from "./handle-external-link.ts";
2931
import * as AppMenu from "./menu.ts";
3032
import {_getServerSettings, _isOnline, _saveServerIcon} from "./request.ts";
3133
import {sentryInit} from "./sentry.ts";
@@ -452,6 +454,13 @@ function createMainWindow(): BrowserWindow {
452454
},
453455
);
454456

457+
ipcMain.on("show-downloaded-file-in-folder", () => {
458+
const filePath = getLatestDownloadPath();
459+
if (filePath !== undefined) {
460+
shell.showItemInFolder(filePath);
461+
}
462+
});
463+
455464
ipcMain.on("save-last-tab", (_event, index: number) => {
456465
ConfigUtil.setConfigItem("lastActiveTab", index);
457466
});

app/renderer/js/electron-bridge.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ bridgeEvents.addEventListener("realm_icon_url", (event) => {
103103
);
104104
});
105105

106+
bridgeEvents.addEventListener("show-downloaded-file-in-folder", (event) => {
107+
z.tuple([]).parse(z.instanceof(BridgeEvent).parse(event).arguments_);
108+
ipcRenderer.send("show-downloaded-file-in-folder");
109+
});
110+
106111
// Set user as active and update the time of last activity
107112
ipcRenderer.on("set-active", () => {
108113
idle = false;

app/renderer/js/preload.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ ipcRenderer.on("show-notification-settings", () => {
1818
bridgeEvents.dispatchEvent(new BridgeEvent("show-notification-settings"));
1919
});
2020

21+
ipcRenderer.on(
22+
"show-download-success",
23+
(_event, title: string, description: string) => {
24+
bridgeEvents.dispatchEvent(
25+
new BridgeEvent("show-download-success", [title, description]),
26+
);
27+
},
28+
);
29+
2130
window.addEventListener("load", () => {
2231
if (!location.href.includes("app/renderer/network.html")) {
2332
return;

0 commit comments

Comments
 (0)