mirror of
https://github.com/YuzuZensai/Discord-Presence-Relay.git
synced 2026-09-13 17:01:36 +00:00
✨ feat: Add option to start app minimized to tray
This commit is contained in:
+87
-11
@@ -11,24 +11,73 @@ function settingsPath(): string {
|
||||
return join(app.getPath('userData'), 'settings.json')
|
||||
}
|
||||
|
||||
function loadDisabledMirrors(): number[] {
|
||||
interface Settings {
|
||||
disabledMirrors: number[]
|
||||
startMinimized: boolean
|
||||
}
|
||||
|
||||
function loadSettings(): Settings {
|
||||
try {
|
||||
const raw = fs.readFileSync(settingsPath(), 'utf8')
|
||||
const data = JSON.parse(raw)
|
||||
return Array.isArray(data?.disabledMirrors) ? data.disabledMirrors : []
|
||||
return {
|
||||
disabledMirrors: Array.isArray(data?.disabledMirrors) ? data.disabledMirrors : [],
|
||||
startMinimized: data?.startMinimized === true
|
||||
}
|
||||
} catch {
|
||||
return []
|
||||
return { disabledMirrors: [], startMinimized: false }
|
||||
}
|
||||
}
|
||||
|
||||
function saveDisabledMirrors(indices: number[]): void {
|
||||
fs.writeFileSync(settingsPath(), JSON.stringify({ disabledMirrors: indices }), 'utf8')
|
||||
function saveSettings(settings: Settings): void {
|
||||
fs.writeFileSync(settingsPath(), JSON.stringify(settings), 'utf8')
|
||||
}
|
||||
|
||||
const LINUX_AUTOSTART_DESKTOP_FILE = join(
|
||||
app.getPath('home'),
|
||||
'.config',
|
||||
'autostart',
|
||||
'cafe.kirameki.discord-rpc-relay.desktop'
|
||||
)
|
||||
|
||||
function getLinuxAutostart(): boolean {
|
||||
return fs.existsSync(LINUX_AUTOSTART_DESKTOP_FILE)
|
||||
}
|
||||
|
||||
function setLinuxAutostart(enabled: boolean, startMinimized: boolean): boolean {
|
||||
if (!enabled) {
|
||||
fs.rmSync(LINUX_AUTOSTART_DESKTOP_FILE, { force: true })
|
||||
return false
|
||||
}
|
||||
|
||||
const exe = process.env.APPIMAGE ?? app.getPath('exe')
|
||||
const exec = startMinimized ? `"${exe}" --hidden` : `"${exe}"`
|
||||
const desktopEntry = [
|
||||
'[Desktop Entry]',
|
||||
'Type=Application',
|
||||
'Name=Discord RPC Relay',
|
||||
`Exec=${exec}`,
|
||||
'Terminal=false',
|
||||
'X-GNOME-Autostart-enabled=true'
|
||||
].join('\n')
|
||||
|
||||
fs.mkdirSync(join(app.getPath('home'), '.config', 'autostart'), { recursive: true })
|
||||
fs.writeFileSync(LINUX_AUTOSTART_DESKTOP_FILE, desktopEntry + '\n', 'utf8')
|
||||
return true
|
||||
}
|
||||
|
||||
let mainWindow: BrowserWindow | null = null
|
||||
let tray: Tray | null = null
|
||||
let quitting = false
|
||||
|
||||
function shouldStartHidden(): boolean {
|
||||
if (process.argv.includes('--hidden')) return true
|
||||
if (process.platform === 'darwin') {
|
||||
return app.getLoginItemSettings().wasOpenedAtLogin && loadSettings().startMinimized
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function createWindow(): void {
|
||||
if (mainWindow) {
|
||||
mainWindow.show()
|
||||
@@ -50,7 +99,9 @@ function createWindow(): void {
|
||||
})
|
||||
|
||||
mainWindow.on('ready-to-show', () => {
|
||||
mainWindow?.show()
|
||||
if (!shouldStartHidden()) {
|
||||
mainWindow?.show()
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.on('close', (e) => {
|
||||
@@ -135,7 +186,8 @@ app.whenReady().then(() => {
|
||||
optimizer.watchWindowShortcuts(window)
|
||||
})
|
||||
|
||||
relay.setDisabledMirrors(loadDisabledMirrors())
|
||||
const settings = loadSettings()
|
||||
relay.setDisabledMirrors(settings.disabledMirrors)
|
||||
|
||||
ipcMain.handle('relay:get-version', () => ({
|
||||
version: app.getVersion(),
|
||||
@@ -144,14 +196,38 @@ app.whenReady().then(() => {
|
||||
ipcMain.handle('relay:get-status', () => relay.getStatus())
|
||||
ipcMain.handle('relay:start', () => relay.start())
|
||||
ipcMain.handle('relay:stop', () => relay.stop())
|
||||
ipcMain.handle('relay:get-autostart', () => app.getLoginItemSettings().openAtLogin)
|
||||
ipcMain.handle('relay:set-autostart', (_e, enabled: boolean) => {
|
||||
app.setLoginItemSettings({ openAtLogin: enabled })
|
||||
ipcMain.handle('relay:get-autostart', () => {
|
||||
if (process.platform === 'linux') return getLinuxAutostart()
|
||||
return app.getLoginItemSettings().openAtLogin
|
||||
})
|
||||
ipcMain.handle('relay:set-autostart', (_e, enabled: boolean) => {
|
||||
const current = loadSettings()
|
||||
if (process.platform === 'linux') {
|
||||
return setLinuxAutostart(enabled, current.startMinimized)
|
||||
}
|
||||
app.setLoginItemSettings({
|
||||
openAtLogin: enabled,
|
||||
args: current.startMinimized ? ['--hidden'] : []
|
||||
})
|
||||
return app.getLoginItemSettings().openAtLogin
|
||||
})
|
||||
ipcMain.handle('relay:get-start-minimized', () => loadSettings().startMinimized)
|
||||
ipcMain.handle('relay:set-start-minimized', (_e, enabled: boolean) => {
|
||||
const current = loadSettings()
|
||||
saveSettings({ ...current, startMinimized: enabled })
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
if (getLinuxAutostart()) setLinuxAutostart(true, enabled)
|
||||
} else if (app.getLoginItemSettings().openAtLogin) {
|
||||
app.setLoginItemSettings({ openAtLogin: true, args: enabled ? ['--hidden'] : [] })
|
||||
}
|
||||
|
||||
return enabled
|
||||
})
|
||||
ipcMain.handle('relay:set-mirror-enabled', (_e, index: number, enabled: boolean) => {
|
||||
const status = relay.setMirrorEnabled(index, enabled)
|
||||
saveDisabledMirrors(relay.getDisabledMirrors())
|
||||
const current = loadSettings()
|
||||
saveSettings({ ...current, disabledMirrors: relay.getDisabledMirrors() })
|
||||
return status
|
||||
})
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ const api = {
|
||||
getAutostart: (): Promise<boolean> => ipcRenderer.invoke('relay:get-autostart'),
|
||||
setAutostart: (enabled: boolean): Promise<boolean> =>
|
||||
ipcRenderer.invoke('relay:set-autostart', enabled),
|
||||
getStartMinimized: (): Promise<boolean> => ipcRenderer.invoke('relay:get-start-minimized'),
|
||||
setStartMinimized: (enabled: boolean): Promise<boolean> =>
|
||||
ipcRenderer.invoke('relay:set-start-minimized', enabled),
|
||||
setMirrorEnabled: (index: number, enabled: boolean): Promise<RelayStatus> =>
|
||||
ipcRenderer.invoke('relay:set-mirror-enabled', index, enabled),
|
||||
onStatus: (callback: (status: RelayStatus) => void): (() => void) => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { ChevronLeft, Settings } from 'lucide-react'
|
||||
import { ChevronLeft, Info, Settings } from 'lucide-react'
|
||||
import type { RelayStatus } from '../../main/relay'
|
||||
import { InstanceRow } from './components/InstanceRow'
|
||||
import { Toggle } from './components/Toggle'
|
||||
@@ -102,6 +102,7 @@ export function App(): React.JSX.Element {
|
||||
const [status, setStatus] = useState<RelayStatus>(EMPTY_STATUS)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [autostart, setAutostart] = useState(false)
|
||||
const [startMinimized, setStartMinimized] = useState(false)
|
||||
const [view, setView] = useState<'main' | 'settings'>('main')
|
||||
const [appVersion, setAppVersion] = useState<{ version: string; commit: string } | null>(null)
|
||||
|
||||
@@ -109,6 +110,7 @@ export function App(): React.JSX.Element {
|
||||
void (async () => {
|
||||
setStatus(await window.api.getStatus())
|
||||
setAutostart(await window.api.getAutostart())
|
||||
setStartMinimized(await window.api.getStartMinimized())
|
||||
setAppVersion(await window.api.getVersion())
|
||||
})()
|
||||
|
||||
@@ -138,6 +140,10 @@ export function App(): React.JSX.Element {
|
||||
setAutostart(await window.api.setAutostart(enabled))
|
||||
}
|
||||
|
||||
const onToggleStartMinimized = async (enabled: boolean): Promise<void> => {
|
||||
setStartMinimized(await window.api.setStartMinimized(enabled))
|
||||
}
|
||||
|
||||
if (status.unsupported) {
|
||||
return (
|
||||
<div className="flex flex-col h-screen items-center justify-center p-5 gap-3 text-center">
|
||||
@@ -170,6 +176,25 @@ export function App(): React.JSX.Element {
|
||||
<Toggle checked={autostart} onChange={onToggleAutostart} />
|
||||
</section>
|
||||
|
||||
<section className="rounded-xl bg-zinc-800/60 border border-zinc-700 p-4 flex items-center justify-between">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-sm">Start minimized</span>
|
||||
<span className="text-xs text-zinc-500">Open to the tray instead of a window</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{!autostart && (
|
||||
<Info className="w-4 h-4 text-zinc-400 hover:text-zinc-100 cursor-help transition-colors shrink-0">
|
||||
<title>Only applies when "Start on login" is enabled.</title>
|
||||
</Info>
|
||||
)}
|
||||
<Toggle
|
||||
checked={startMinimized}
|
||||
onChange={onToggleStartMinimized}
|
||||
disabled={!autostart}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{appVersion && (
|
||||
<p className="text-xs text-zinc-500 mt-auto">
|
||||
Version {appVersion.version} ({appVersion.commit})
|
||||
|
||||
Reference in New Issue
Block a user