From a1307bdd0b659481b6862bc0054ff931df115b76 Mon Sep 17 00:00:00 2001 From: Nexmoe <16796652+nexmoe@users.noreply.github.com> Date: Wed, 29 Oct 2025 20:32:03 +0800 Subject: [PATCH] feat: add hide-dock setting and fix about text handling (#3) - Add "hideDockIcon" setting label and description to English locale, enabling users to remove VidBee from the macOS Dock and rely on the menu bar/tray icon. - Apply dock visibility changes when settings change, when settings are loaded, and after settings are reset by calling applyDockVisibility from the settings service. - Update About page to use about.description for share text and display content, replacing the removed tagline key usage. - Remove unused "tagline" entries from multiple locale files (en, fr, it, pt, ja, zh) to keep translations in sync with UI text changes. These changes add OS integration for hiding the dock icon and ensure UI copy is consistent and correctly internationalized. --- src/main/index.ts | 4 +++ src/main/ipc/services/settings-service.ts | 10 +++++++ src/main/utils/dock.ts | 16 +++++++++++ src/renderer/src/locales/en.json | 3 +- src/renderer/src/locales/fr.json | 1 - src/renderer/src/locales/it.json | 1 - src/renderer/src/locales/ja.json | 1 - src/renderer/src/locales/ko.json | 1 - src/renderer/src/locales/pt.json | 1 - src/renderer/src/locales/zh-TW.json | 1 - src/renderer/src/locales/zh.json | 1 - src/renderer/src/pages/About.tsx | 9 ++---- src/renderer/src/pages/Settings.tsx | 34 ++++++++++++++++++++++- src/shared/types/index.ts | 2 ++ 14 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 src/main/utils/dock.ts diff --git a/src/main/index.ts b/src/main/index.ts index 3a29727..f718143 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -10,6 +10,7 @@ import { downloadEngine } from './lib/download-engine' import { ytdlpManager } from './lib/ytdlp-manager' import { settingsManager } from './settings' import { createTray, destroyTray } from './tray' +import { applyDockVisibility } from './utils/dock' // Initialize electron-log for main process log.initialize() @@ -27,6 +28,7 @@ export function createWindow(): void { height: 800, show: false, titleBarStyle: 'hidden', // Hide title bar on macOS + trafficLightPosition: { x: 12.5, y: 10 }, autoHideMenuBar: true, icon: appIcon, // Set application icon frame: false, @@ -183,6 +185,8 @@ app.whenReady().then(async () => { log.error('Failed to initialize yt-dlp:', error) } + applyDockVisibility(settingsManager.get('hideDockIcon')) + createWindow() initAutoUpdater() diff --git a/src/main/ipc/services/settings-service.ts b/src/main/ipc/services/settings-service.ts index cec5938..6c494e2 100644 --- a/src/main/ipc/services/settings-service.ts +++ b/src/main/ipc/services/settings-service.ts @@ -2,6 +2,7 @@ import { type IpcContext, IpcMethod, IpcService } from 'electron-ipc-decorator' import type { AppSettings } from '../../../shared/types' import { settingsManager } from '../../settings' import { updateTrayMenu } from '../../tray' +import { applyDockVisibility } from '../../utils/dock' class SettingsService extends IpcService { static readonly groupName = 'settings' @@ -18,6 +19,10 @@ class SettingsService extends IpcService { if (key === 'language') { updateTrayMenu() } + + if (key === 'hideDockIcon') { + applyDockVisibility(value as AppSettings['hideDockIcon']) + } } @IpcMethod() @@ -32,11 +37,16 @@ class SettingsService extends IpcService { if (settings.language) { updateTrayMenu() } + + if (typeof settings.hideDockIcon === 'boolean') { + applyDockVisibility(settings.hideDockIcon) + } } @IpcMethod() reset(_context: IpcContext): void { settingsManager.reset() + applyDockVisibility(settingsManager.get('hideDockIcon')) } } diff --git a/src/main/utils/dock.ts b/src/main/utils/dock.ts new file mode 100644 index 0000000..98acc83 --- /dev/null +++ b/src/main/utils/dock.ts @@ -0,0 +1,16 @@ +import { app } from 'electron' + +/** + * Apply Dock visibility preference on macOS. + */ +export function applyDockVisibility(hideDockIcon: boolean): void { + if (process.platform !== 'darwin' || !app.dock) { + return + } + + if (hideDockIcon) { + app.dock.hide() + } else { + app.dock.show() + } +} diff --git a/src/renderer/src/locales/en.json b/src/renderer/src/locales/en.json index d8d5502..26e4a76 100644 --- a/src/renderer/src/locales/en.json +++ b/src/renderer/src/locales/en.json @@ -60,7 +60,6 @@ "shareSupport": "Recommend VidBee to your friends to support our growth and updates.", "shareTitle": "Spread the word", "sourceCode": "Source Code is available", - "tagline": "An AI-friendly download helper for every creator", "title": "About", "version": "Version", "versionLabel": "v{{version}}", @@ -281,6 +280,8 @@ "general": "General", "language": "Language", "light": "Light", + "hideDockIcon": "Hide Dock icon", + "hideDockIconDescription": "Remove VidBee from the macOS Dock. Use the menu bar or tray icon to reopen the app.", "maxConcurrentDownloads": "Maximum number of active downloads", "maxConcurrentDownloadsDescription": "Maximum number of simultaneous downloads", "none": "None", diff --git a/src/renderer/src/locales/fr.json b/src/renderer/src/locales/fr.json index 87f2374..4d58102 100644 --- a/src/renderer/src/locales/fr.json +++ b/src/renderer/src/locales/fr.json @@ -60,7 +60,6 @@ "shareSupport": "Recommandez VidBee à vos amis pour soutenir notre croissance et nos mises à jour.", "shareTitle": "Faites passer le mot", "sourceCode": "Le code source est disponible", - "tagline": "Un assistant de téléchargement convivial pour l'IA pour chaque créateur", "title": "À propos", "version": "Version", "versionLabel": "v{{version}}", diff --git a/src/renderer/src/locales/it.json b/src/renderer/src/locales/it.json index 47c21e3..712aa2e 100644 --- a/src/renderer/src/locales/it.json +++ b/src/renderer/src/locales/it.json @@ -60,7 +60,6 @@ "shareSupport": "Raccomanda VidBee ai tuoi amici per sostenere la nostra crescita e aggiornamenti.", "shareTitle": "Passa parola", "sourceCode": "Il codice sorgente è disponibile", - "tagline": "Un assistente di download amichevole per l'IA per ogni creatore", "title": "Informazioni", "version": "Versione", "versionLabel": "v{{version}}", diff --git a/src/renderer/src/locales/ja.json b/src/renderer/src/locales/ja.json index 88925c1..719b444 100644 --- a/src/renderer/src/locales/ja.json +++ b/src/renderer/src/locales/ja.json @@ -60,7 +60,6 @@ "shareSupport": "私たちの成長とアップデートをサポートするために、友達にVidBeeを推奨してください。", "shareTitle": "口コミを広める", "sourceCode": "ソースコードが利用可能", - "tagline": "すべてのクリエイターのためのAIフレンドリーなダウンロードアシスタント", "title": "について", "version": "バージョン", "versionLabel": "v{{version}}", diff --git a/src/renderer/src/locales/ko.json b/src/renderer/src/locales/ko.json index 323b8af..d167184 100644 --- a/src/renderer/src/locales/ko.json +++ b/src/renderer/src/locales/ko.json @@ -60,7 +60,6 @@ "shareSupport": "우리의 성장과 업데이트를 지원하기 위해 친구들에게 VidBee를 추천하세요.", "shareTitle": "소문을 퍼뜨리세요", "sourceCode": "소스 코드 사용 가능", - "tagline": "모든 크리에이터를 위한 AI 친화적 다운로드 도우미", "title": "정보", "version": "버전", "versionLabel": "v{{version}}", diff --git a/src/renderer/src/locales/pt.json b/src/renderer/src/locales/pt.json index 17c1682..a07ed31 100644 --- a/src/renderer/src/locales/pt.json +++ b/src/renderer/src/locales/pt.json @@ -60,7 +60,6 @@ "shareSupport": "Recomende VidBee aos seus amigos para apoiar nosso crescimento e atualizações.", "shareTitle": "Espalhe a palavra", "sourceCode": "Código fonte disponível", - "tagline": "Um assistente de download amigável à IA para cada criador", "title": "Sobre", "version": "Versão", "versionLabel": "v{{version}}", diff --git a/src/renderer/src/locales/zh-TW.json b/src/renderer/src/locales/zh-TW.json index 242f319..f7a94a2 100644 --- a/src/renderer/src/locales/zh-TW.json +++ b/src/renderer/src/locales/zh-TW.json @@ -60,7 +60,6 @@ "shareSupport": "向您的朋友推薦 VidBee 以支援我們的成長和更新。", "shareTitle": "廣為宣傳", "sourceCode": "原始碼已開放", - "tagline": "面向每位創作者的 AI 友善下載助手", "title": "關於", "version": "版本", "versionLabel": "v{{version}}", diff --git a/src/renderer/src/locales/zh.json b/src/renderer/src/locales/zh.json index 4bc569e..4f6e2ac 100644 --- a/src/renderer/src/locales/zh.json +++ b/src/renderer/src/locales/zh.json @@ -52,7 +52,6 @@ "resourcesDescription": "了解 VidBee 并保持关注的实用链接。", "resourcesTitle": "资源", "sourceCode": "源代码已开放", - "tagline": "面向每位创作者的 AI 友好下载助手", "title": "关于", "version": "版本", "versionLabel": "v{{version}}", diff --git a/src/renderer/src/pages/About.tsx b/src/renderer/src/pages/About.tsx index 663144b..2c632cb 100644 --- a/src/renderer/src/pages/About.tsx +++ b/src/renderer/src/pages/About.tsx @@ -114,7 +114,7 @@ export function About() { const shareLinks = useMemo(() => { const encodedUrl = encodeURIComponent(shareTargetUrl) - const encodedText = encodeURIComponent(t('about.tagline')) + const encodedText = encodeURIComponent(t('about.description')) return { facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`, @@ -207,11 +207,6 @@ export function About() { return (
-
-

{t('about.title')}

-

{t('about.description')}

-
-
@@ -220,7 +215,7 @@ export function About() {

{t('about.appName')}

-

{t('about.tagline')}

+

{t('about.description')}

diff --git a/src/renderer/src/pages/Settings.tsx b/src/renderer/src/pages/Settings.tsx index 335f6a2..5502ed7 100644 --- a/src/renderer/src/pages/Settings.tsx +++ b/src/renderer/src/pages/Settings.tsx @@ -21,7 +21,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@renderer/components/u import type { OneClickQualityPreset } from '@shared/types' import { useAtom, useSetAtom } from 'jotai' import { useTheme } from 'next-themes' -import { useEffect } from 'react' +import { useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' import { loadSettingsAtom, saveSettingAtom, settingsAtom } from '../store/settings' @@ -32,11 +32,26 @@ export function Settings() { const [settings, _setSettings] = useAtom(settingsAtom) const loadSettings = useSetAtom(loadSettingsAtom) const saveSetting = useSetAtom(saveSettingAtom) + const [platform, setPlatform] = useState('') useEffect(() => { loadSettings() }, [loadSettings]) + useEffect(() => { + const fetchPlatform = async () => { + try { + const { ipcServices } = await import('../lib/ipc') + const platformInfo = await ipcServices.app.getPlatform() + setPlatform(platformInfo) + } catch (error) { + console.error('Failed to get platform info:', error) + } + } + + fetchPlatform() + }, []) + const handleSettingChange = async ( key: keyof typeof settings, value: (typeof settings)[keyof typeof settings] @@ -263,6 +278,23 @@ export function Settings() { + {platform === 'darwin' && ( + + + + {t('settings.hideDockIcon')} + {t('settings.hideDockIconDescription')} + + + handleSettingChange('hideDockIcon', value)} + /> + + + + )} + diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts index cbb1336..ca527d3 100644 --- a/src/shared/types/index.ts +++ b/src/shared/types/index.ts @@ -156,6 +156,7 @@ export interface AppSettings { oneClickDownloadType: 'video' | 'audio' oneClickQuality: OneClickQualityPreset closeToTray: boolean + hideDockIcon: boolean autoUpdate: boolean } @@ -174,5 +175,6 @@ export const defaultSettings: AppSettings = { oneClickDownloadType: 'video', oneClickQuality: 'auto', closeToTray: false, + hideDockIcon: false, autoUpdate: true }