diff --git a/package.json b/package.json index 481c91b..35ee526 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,12 @@ "package.json", "LICENSE" ], + "protocols": { + "name": "Discord", + "schemes": [ + "discord" + ] + }, "beforePack": "scripts/build/sandboxFix.js", "linux": { "icon": "build/icon.icns", @@ -111,7 +117,8 @@ "GenericName": "Internet Messenger", "Type": "Application", "Categories": "Network;InstantMessaging;Chat;", - "Keywords": "discord;vencord;electron;chat;" + "Keywords": "discord;vencord;electron;chat;", + "MimeType": "x-scheme-handler/discord" } }, "mac": { diff --git a/src/main/index.ts b/src/main/index.ts index 2e0d6f7..0666fc1 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -11,7 +11,7 @@ import { autoUpdater } from "electron-updater"; import { DATA_DIR } from "./constants"; import { createFirstLaunchTour } from "./firstLaunch"; -import { createWindows, mainWin } from "./mainWindow"; +import { createWindows, restoreVesktop } from "./mainWindow"; import { registerMediaPermissionsHandler } from "./mediaPermissions"; import { registerScreenShareHandler } from "./screenShare"; import { Settings, State } from "./settings"; @@ -27,6 +27,8 @@ if (IS_DEV) { process.env.VENCORD_USER_DATA_DIR = DATA_DIR; function init() { + app.setAsDefaultProtocolClient("discord"); + const { disableSmoothScroll, hardwareAcceleration } = Settings.store; const enabledFeatures = app.commandLine.getSwitchValue("enable-features").split(","); @@ -67,12 +69,7 @@ function init() { if (isDeckGameMode) nativeTheme.themeSource = "dark"; app.on("second-instance", (_event, _cmdLine, _cwd, data: any) => { - if (data.IS_DEV) app.quit(); - else if (mainWin) { - if (mainWin.isMinimized()) mainWin.restore(); - if (!mainWin.isVisible()) mainWin.show(); - mainWin.focus(); - } + data.IS_DEV ? app.quit() : restoreVesktop(); }); app.whenReady().then(async () => { diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 4fa662c..a438206 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -18,7 +18,7 @@ import { IpcEvents } from "../shared/IpcEvents"; import { setBadgeCount } from "./appBadge"; import { autoStart } from "./autoStart"; import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants"; -import { mainWin } from "./mainWindow"; +import { loadUrl, mainWin } from "./mainWindow"; import { Settings, State } from "./settings"; import { handle, handleSync } from "./utils/ipcWrappers"; import { PopoutWindows } from "./utils/popout"; @@ -135,6 +135,11 @@ handle(IpcEvents.CLIPBOARD_COPY_IMAGE, async (_, buf: ArrayBuffer, src: string) }); }); +handle(IpcEvents.FOUROHFOUR_PAGE_HANDLER, _ => { + loadUrl(undefined); + console.warn("caught incomplete uri scheme. dumping to main app"); +}); + function readCss() { return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => ""); } diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 1292449..65eedd3 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -455,18 +455,34 @@ function createMainWindow() { win.webContents.setUserAgent(BrowserUserAgent); - const subdomain = - Settings.store.discordBranch === "canary" || Settings.store.discordBranch === "ptb" - ? `${Settings.store.discordBranch}.` - : ""; + let uriFiredDarwin = false; + app.on("open-url", (_, url) => { + uriFiredDarwin ? restoreVesktop() : loadUrl(url); + uriFiredDarwin = true; + }); - win.loadURL(`https://${subdomain}discord.com/app`); + const uri = process.argv.find(arg => arg.startsWith("discord://")); + uriFiredDarwin || loadUrl(uri); return win; } const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDesktopMain.js"))); +export function loadUrl(uri: string | undefined) { + const branch = Settings.store.discordBranch; + const subdomain = branch === "canary" || branch === "ptb" ? `${branch}.` : ""; + mainWin.loadURL(`https://${subdomain}discord.com/${uri?.replace(RegExp("^discord://[^/]*/?"), "") || "app"}`); +} + +export function restoreVesktop() { + if (mainWin) { + if (mainWin.isMinimized()) mainWin.restore(); + if (!mainWin.isVisible()) mainWin.show(); + mainWin.focus(); + } +} + export async function createWindows() { const startMinimized = process.argv.includes("--start-minimized"); const splash = createSplashWindow(startMinimized); diff --git a/src/preload/index.ts b/src/preload/index.ts index 75bf9cd..5aa63ad 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -24,6 +24,10 @@ const style = document.createElement("style"); style.id = "vcd-css-core"; style.textContent = readFileSync(rendererCss, "utf-8"); +document.addEventListener("DOMContentLoaded", () => { + if (document.title === "Page Not Found | Discord") ipcRenderer.invoke(IpcEvents.FOUROHFOUR_PAGE_HANDLER); +}); + if (document.readyState === "complete") { document.documentElement.appendChild(style); } else { diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index 51d2a28..0843a47 100644 --- a/src/shared/IpcEvents.ts +++ b/src/shared/IpcEvents.ts @@ -50,5 +50,7 @@ export const enum IpcEvents { ARRPC_ACTIVITY = "VCD_ARRPC_ACTIVITY", - CLIPBOARD_COPY_IMAGE = "VCD_CLIPBOARD_COPY_IMAGE" + CLIPBOARD_COPY_IMAGE = "VCD_CLIPBOARD_COPY_IMAGE", + + FOUROHFOUR_PAGE_HANDLER = "VCD_404_PAGE_HANDLER" }