feat(settings): add auto-launch handling and UI toggle support (#29)

This commit is contained in:
Nexmoe
2025-11-15 16:16:16 +08:00
committed by GitHub
parent 6c3f070797
commit f84f3ef02a
6 changed files with 97 additions and 19 deletions

View File

@@ -13,6 +13,7 @@ import { subscriptionScheduler } from './lib/subscription-scheduler'
import { ytdlpManager } from './lib/ytdlp-manager'
import { settingsManager } from './settings'
import { createTray, destroyTray } from './tray'
import { applyAutoLaunchSetting } from './utils/auto-launch'
import { applyDockVisibility } from './utils/dock'
// Initialize electron-log for main process
@@ -216,6 +217,7 @@ app.whenReady().then(async () => {
}
applyDockVisibility(settingsManager.get('hideDockIcon'))
applyAutoLaunchSetting(settingsManager.get('launchAtLogin'))
createWindow()

View File

@@ -4,6 +4,7 @@ import { sanitizeFilenameTemplate } from '../../download-engine/args-builder'
import { subscriptionScheduler } from '../../lib/subscription-scheduler'
import { settingsManager } from '../../settings'
import { updateTrayMenu } from '../../tray'
import { applyAutoLaunchSetting } from '../../utils/auto-launch'
import { applyDockVisibility } from '../../utils/dock'
class SettingsService extends IpcService {
@@ -34,6 +35,10 @@ class SettingsService extends IpcService {
applyDockVisibility(value as AppSettings['hideDockIcon'])
}
if (key === 'launchAtLogin') {
applyAutoLaunchSetting(value as AppSettings['launchAtLogin'])
}
if (key === 'subscriptionCheckIntervalHours') {
subscriptionScheduler.refreshInterval()
}
@@ -67,6 +72,10 @@ class SettingsService extends IpcService {
applyDockVisibility(settings.hideDockIcon)
}
if (typeof settings.launchAtLogin === 'boolean') {
applyAutoLaunchSetting(settings.launchAtLogin)
}
if (settings.subscriptionCheckIntervalHours !== undefined) {
subscriptionScheduler.refreshInterval()
}
@@ -76,6 +85,7 @@ class SettingsService extends IpcService {
reset(_context: IpcContext): void {
settingsManager.reset()
applyDockVisibility(settingsManager.get('hideDockIcon'))
applyAutoLaunchSetting(settingsManager.get('launchAtLogin'))
subscriptionScheduler.refreshInterval()
}
}

View File

@@ -0,0 +1,38 @@
import { app } from 'electron'
import log from 'electron-log/main'
const SUPPORTED_PLATFORMS = new Set(['darwin', 'win32'])
export function isAutoLaunchSupported(): boolean {
return SUPPORTED_PLATFORMS.has(process.platform)
}
export function applyAutoLaunchSetting(enabled: boolean): void {
if (!isAutoLaunchSupported()) {
log.info('Auto launch is not supported on this platform, skipping setting update')
return
}
const updateSetting = () => {
try {
const options: Parameters<typeof app.setLoginItemSettings>[0] = {
openAtLogin: enabled
}
if (process.platform === 'darwin') {
options.openAsHidden = true
}
app.setLoginItemSettings(options)
log.info(`Auto launch ${enabled ? 'enabled' : 'disabled'}`)
} catch (error) {
log.error('Failed to update login item settings:', error)
}
}
if (app.isReady()) {
updateSetting()
} else {
app.once('ready', updateSetting)
}
}

View File

@@ -340,6 +340,9 @@
"light": "Light",
"hideDockIcon": "Hide Dock icon",
"hideDockIconDescription": "Remove VidBee from the macOS Dock. Use the menu bar or tray icon to reopen the app.",
"launchAtLogin": "Launch at startup",
"launchAtLoginDescription": "Open VidBee automatically after you sign in to your computer.",
"launchAtLoginUnsupported": "Auto launch is only available on macOS and Windows.",
"enableAnalytics": "Help improve VidBee",
"enableAnalyticsDescription": "Share anonymous usage data to help us understand how the app is used and prioritize improvements.",
"maxConcurrentDownloads": "Maximum number of active downloads",

View File

@@ -60,6 +60,8 @@ export function Settings() {
fetchPlatform()
}, [])
const autoLaunchSupported = platform === 'darwin' || platform === 'win32'
const handleSettingChange = async (
key: keyof typeof settings,
value: (typeof settings)[keyof typeof settings]
@@ -266,6 +268,46 @@ export function Settings() {
)}
</ItemGroup>
<ItemGroup>
{platform === 'darwin' && (
<>
<Item variant="muted">
<ItemContent>
<ItemTitle>{t('settings.hideDockIcon')}</ItemTitle>
<ItemDescription>{t('settings.hideDockIconDescription')}</ItemDescription>
</ItemContent>
<ItemActions>
<Switch
checked={settings.hideDockIcon}
onCheckedChange={(value) => handleSettingChange('hideDockIcon', value)}
/>
</ItemActions>
</Item>
<ItemSeparator />
</>
)}
<Item variant="muted">
<ItemContent>
<ItemTitle>{t('settings.launchAtLogin')}</ItemTitle>
<ItemDescription>
{autoLaunchSupported
? t('settings.launchAtLoginDescription')
: t('settings.launchAtLoginUnsupported')}
</ItemDescription>
</ItemContent>
<ItemActions>
<Switch
checked={settings.launchAtLogin}
onCheckedChange={(value) => handleSettingChange('launchAtLogin', value)}
disabled={!autoLaunchSupported}
/>
</ItemActions>
</Item>
</ItemGroup>
</TabsContent>
<TabsContent value="advanced" className="space-y-4 mt-2">
<ItemGroup>
<Item variant="muted">
<ItemContent>
@@ -280,25 +322,6 @@ export function Settings() {
</ItemActions>
</Item>
</ItemGroup>
</TabsContent>
<TabsContent value="advanced" className="space-y-4 mt-2">
{platform === 'darwin' && (
<ItemGroup>
<Item variant="muted">
<ItemContent>
<ItemTitle>{t('settings.hideDockIcon')}</ItemTitle>
<ItemDescription>{t('settings.hideDockIconDescription')}</ItemDescription>
</ItemContent>
<ItemActions>
<Switch
checked={settings.hideDockIcon}
onCheckedChange={(value) => handleSettingChange('hideDockIcon', value)}
/>
</ItemActions>
</Item>
</ItemGroup>
)}
<ItemGroup>
<Item variant="muted">

View File

@@ -265,6 +265,7 @@ export interface AppSettings {
oneClickQuality: OneClickQualityPreset
closeToTray: boolean
hideDockIcon: boolean
launchAtLogin: boolean
autoUpdate: boolean
subscriptionFilenameTemplate: string
subscriptionOnlyLatestDefault: boolean
@@ -288,6 +289,7 @@ export const defaultSettings: AppSettings = {
oneClickQuality: 'best',
closeToTray: false,
hideDockIcon: false,
launchAtLogin: false,
autoUpdate: true,
subscriptionFilenameTemplate: '%(uploader)s - %(title)s.%(ext)s',
subscriptionOnlyLatestDefault: true,