diff --git a/src/main/autoStart.ts b/src/main/autoStart.ts new file mode 100644 index 0000000..e3fb17f --- /dev/null +++ b/src/main/autoStart.ts @@ -0,0 +1,42 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * Vencord Desktop, a desktop app aiming to give you a snappier Discord Experience + * Copyright (c) 2023 Vendicated and Vencord contributors + */ + +import { app } from "electron"; +import { existsSync, mkdirSync, rmSync, writeFileSync } from "fs"; +import { join } from "path"; + +function makeAutoStartLinux() { + const dir = join(process.env.HOME!, ".config", "autostart"); + const file = join(dir, "vencord.desktop"); + + return { + isEnabled: () => existsSync(file), + enable() { + const desktopFile = ` +[Desktop Entry] +Type=Application +Version=1.0 +Name=Vencord +Comment=Vencord autostart script +Exec=${process.execPath} +Terminal=false +StartupNotify=false +`.trim(); + + mkdirSync(dir, { recursive: true }); + writeFileSync(file, desktopFile); + }, + disable: () => rmSync(file, { force: true }) + }; +} + +const autoStartWindowsMac = { + isEnabled: () => app.getLoginItemSettings().openAtLogin, + enable: () => app.setLoginItemSettings({ openAtLogin: true }), + disable: () => app.setLoginItemSettings({ openAtLogin: false }) +}; + +export const autoStart = process.platform === "linux" ? makeAutoStartLinux() : autoStartWindowsMac; diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 5dc3479..617cccf 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -11,6 +11,7 @@ import { join } from "path"; import { debounce } from "shared/utils/debounce"; import { IpcEvents } from "../shared/IpcEvents"; +import { autoStart } from "./autoStart"; import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE } from "./constants"; import { mainWin } from "./mainWindow"; import { Settings } from "./settings"; @@ -39,6 +40,12 @@ ipcMain.on(IpcEvents.GET_VERSION, e => { e.returnValue = app.getVersion(); }); +ipcMain.on(IpcEvents.AUTOSTART_ENABLED, e => { + e.returnValue = autoStart.isEnabled(); +}); +ipcMain.handle(IpcEvents.ENABLE_AUTOSTART, autoStart.enable); +ipcMain.handle(IpcEvents.DISABLE_AUTOSTART, autoStart.disable); + ipcMain.handle(IpcEvents.SET_SETTINGS, (_, settings: typeof Settings.store, path?: string) => { Settings.setData(settings, path); }); diff --git a/src/preload/VencordDesktopNative.ts b/src/preload/VencordDesktopNative.ts index f6b0829..e0e2d1a 100644 --- a/src/preload/VencordDesktopNative.ts +++ b/src/preload/VencordDesktopNative.ts @@ -15,6 +15,11 @@ export const VencordDesktopNative = { relaunch: () => invoke(IpcEvents.RELAUNCH), getVersion: () => sendSync(IpcEvents.GET_VERSION) }, + autostart: { + isEnabled: () => sendSync(IpcEvents.AUTOSTART_ENABLED), + enable: () => invoke(IpcEvents.ENABLE_AUTOSTART), + disable: () => invoke(IpcEvents.DISABLE_AUTOSTART) + }, fileManager: { showItemInFolder: (path: string) => invoke(IpcEvents.SHOW_ITEM_IN_FOLDER, path), selectVencordDir: () => invoke>(IpcEvents.SELECT_VENCORD_DIR) diff --git a/src/renderer/components/Settings.tsx b/src/renderer/components/Settings.tsx index adb5dc6..1c43b79 100644 --- a/src/renderer/components/Settings.tsx +++ b/src/renderer/components/Settings.tsx @@ -7,12 +7,15 @@ import "./settings.css"; import { Margins } from "@vencord/types/utils"; -import { Button, Forms, Select, Switch, Text } from "@vencord/types/webpack/common"; +import { Button, Forms, Select, Switch, Text, useState } from "@vencord/types/webpack/common"; import { useSettings } from "renderer/settings"; export default function SettingsUi() { const Settings = useSettings(); + const { autostart } = VencordDesktopNative; + const [autoStartEnabled, setAutoStartEnabled] = useState(autostart.isEnabled()); + const switches: [keyof typeof Settings, string, string, boolean?, (() => boolean)?][] = [ ["tray", "Tray Icon", "Add a tray icon for Vencord Desktop", true], [ @@ -58,6 +61,17 @@ export default function SettingsUi() { + { + await autostart[v ? "enable" : "disable"](); + setAutoStartEnabled(v); + }} + note="Automatically start Vencord Desktop on computer start-up" + > + Start With System + + {switches.map(([key, text, note, def, predicate]) => (