fix: Ensure showTrayIcon is initialized from backend settings in App.tsx
The `showTrayIcon` user preference was not being explicitly passed from the `appReady()` command's results to the `settingsStore.initSettings()` call within `App.tsx`. This could lead to the frontend store not correctly reflecting the persisted value of `showTrayIcon` at startup. This commit updates `App.tsx` to include `showTrayIcon` in the settings object passed to `initSettings`, ensuring its value is derived from the backend configuration.
This commit is contained in:
parent
2144265b9c
commit
9e91e45c70
@ -195,6 +195,7 @@ function App() {
|
||||
isHistoryPanelVisibleOnly: settings.isHistoryPanelVisibleOnly?.valueBool,
|
||||
isSavedClipsPanelVisibleOnly: settings.isSavedClipsPanelVisibleOnly?.valueBool,
|
||||
isSimplifiedLayout: settings.isSimplifiedLayout?.valueBool ?? true,
|
||||
showTrayIcon: settings.showTrayIcon?.valueBool ?? true, // Added line
|
||||
isAppReady: true,
|
||||
})
|
||||
settingsStore.initConstants({
|
||||
|
@ -93,6 +93,8 @@ export default function UserPreferences() {
|
||||
setIsSavedClipsPanelVisibleOnly,
|
||||
isSimplifiedLayout,
|
||||
setIsSimplifiedLayout,
|
||||
showTrayIcon,
|
||||
setShowTrayIcon,
|
||||
} = useAtomValue(settingsStoreAtom)
|
||||
|
||||
const { setFontSize, fontSize, setIsSwapPanels, isSwapPanels, returnRoute, isMacOSX } =
|
||||
@ -117,6 +119,27 @@ export default function UserPreferences() {
|
||||
})
|
||||
}, [])
|
||||
|
||||
// macOS-specific logic for showTrayIcon
|
||||
useEffect(() => {
|
||||
if (isMacOSX && !showTrayIcon) {
|
||||
// If tray icon is hidden on macOS, force dock icon to be visible
|
||||
// and main window to show on restart.
|
||||
if (isHideMacOSDockIcon) {
|
||||
setIsHideMacOSDockIcon(false)
|
||||
}
|
||||
if (isKeepMainWindowClosedOnRestartEnabled) {
|
||||
setIsKeepMainWindowClosedOnRestartEnabled(false)
|
||||
}
|
||||
}
|
||||
}, [
|
||||
isMacOSX,
|
||||
showTrayIcon,
|
||||
isHideMacOSDockIcon,
|
||||
setIsHideMacOSDockIcon,
|
||||
isKeepMainWindowClosedOnRestartEnabled,
|
||||
setIsKeepMainWindowClosedOnRestartEnabled,
|
||||
])
|
||||
|
||||
const isDark = themeDark()
|
||||
|
||||
const [mainAppHotkey, setMainAppHotkey] = useState('')
|
||||
@ -267,10 +290,38 @@ export default function UserPreferences() {
|
||||
</Card>
|
||||
</Box>
|
||||
|
||||
<Box className="animate-in fade-in max-w-xl mt-4">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-1">
|
||||
<CardTitle className="animate-in fade-in text-md font-medium w-full">
|
||||
{t('Show System Tray Icon', { ns: 'settings2' })} {/* TODO: Add translation key */}
|
||||
</CardTitle>
|
||||
<Switch
|
||||
checked={showTrayIcon}
|
||||
className="ml-auto"
|
||||
onCheckedChange={() => {
|
||||
setShowTrayIcon(!showTrayIcon)
|
||||
}}
|
||||
/>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Text className="text-sm text-muted-foreground">
|
||||
{t(
|
||||
'Show the application icon in the system tray or menu bar. If disabled on macOS, the Dock icon will always be visible and the app window will show on startup.',
|
||||
{ ns: 'settings2' } // TODO: Add translation key
|
||||
)}
|
||||
</Text>
|
||||
<Text className="text-xs text-muted-foreground mt-2">
|
||||
({t('app_restart_required_tray', { ns: 'settings2' })}) {/* Placeholder for translation */}
|
||||
</Text>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Box>
|
||||
|
||||
<Box className="animate-in fade-in max-w-xl mt-4">
|
||||
<Card
|
||||
className={`${
|
||||
!isKeepMainWindowClosedOnRestartEnabled
|
||||
(!isKeepMainWindowClosedOnRestartEnabled || (isMacOSX && !showTrayIcon))
|
||||
? 'opacity-80 bg-gray-100 dark:bg-gray-900/80'
|
||||
: ''
|
||||
}`}
|
||||
@ -283,6 +334,7 @@ export default function UserPreferences() {
|
||||
</CardTitle>
|
||||
<Switch
|
||||
checked={isKeepMainWindowClosedOnRestartEnabled}
|
||||
disabled={isMacOSX && !showTrayIcon}
|
||||
className="ml-auto"
|
||||
onCheckedChange={() => {
|
||||
setIsKeepMainWindowClosedOnRestartEnabled(
|
||||
@ -297,6 +349,11 @@ export default function UserPreferences() {
|
||||
'Keep the main application window hidden when the app restarts. You can reopen it using the menu bar or taskbar menu, or using global hotkeys.',
|
||||
{ ns: 'settings2' }
|
||||
)}
|
||||
{isMacOSX && !showTrayIcon && (
|
||||
<Text className="text-xs text-amber-700 dark:text-amber-300 mt-1">
|
||||
({t('Disabled because "Show System Tray Icon" is off.', { ns: 'settings2' })}) {/* TODO: Add translation key */}
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@ -923,7 +980,7 @@ export default function UserPreferences() {
|
||||
<Box className="animate-in fade-in max-w-xl mt-4">
|
||||
<Card
|
||||
className={`${
|
||||
!isHideMacOSDockIcon &&
|
||||
(!isHideMacOSDockIcon || (isMacOSX && !showTrayIcon)) &&
|
||||
'opacity-80 bg-gray-100 dark:bg-gray-900/80'
|
||||
}`}
|
||||
>
|
||||
@ -940,6 +997,7 @@ export default function UserPreferences() {
|
||||
</CardTitle>
|
||||
<Switch
|
||||
checked={isHideMacOSDockIcon}
|
||||
disabled={isMacOSX && !showTrayIcon}
|
||||
className="ml-auto"
|
||||
onCheckedChange={() => {
|
||||
setIsHideMacOSDockIcon(!isHideMacOSDockIcon)
|
||||
@ -952,6 +1010,11 @@ export default function UserPreferences() {
|
||||
'Remove PasteBar app icon from the macOS Dock while keeping the app running in the background. The app remains accessible via the menu bar icon. Requires an app restart to take effect.',
|
||||
{ ns: 'settings2' }
|
||||
)}
|
||||
{isMacOSX && !showTrayIcon && (
|
||||
<Text className="text-xs text-amber-700 dark:text-amber-300 mt-1">
|
||||
({t('Disabled because "Show System Tray Icon" is off.', { ns: 'settings2' })}) {/* TODO: Add translation key */}
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
@ -96,6 +96,7 @@ type Settings = {
|
||||
isHistoryPanelVisibleOnly: boolean
|
||||
isSavedClipsPanelVisibleOnly: boolean
|
||||
isSimplifiedLayout: boolean
|
||||
showTrayIcon: boolean
|
||||
}
|
||||
|
||||
type Constants = {
|
||||
@ -178,6 +179,7 @@ export interface SettingsStoreState {
|
||||
setIsSavedClipsPanelVisibleOnly: (isVisible: boolean) => void
|
||||
setShowBothPanels: (isVisible: boolean) => void
|
||||
setIsSimplifiedLayout: (isEnabled: boolean) => void
|
||||
setShowTrayIcon: (showTrayIcon: boolean) => void
|
||||
hashPassword: (pass: string) => Promise<string>
|
||||
isNotTourCompletedOrSkipped: (tourName: string) => boolean
|
||||
verifyPassword: (pass: string, hash: string) => Promise<boolean>
|
||||
@ -269,6 +271,7 @@ const initialState: SettingsStoreState & Settings = {
|
||||
isHistoryPanelVisibleOnly: false,
|
||||
isSavedClipsPanelVisibleOnly: false,
|
||||
isSimplifiedLayout: true,
|
||||
showTrayIcon: true,
|
||||
CONST: {
|
||||
APP_DETECT_LANGUAGES_SUPPORTED: [],
|
||||
},
|
||||
@ -333,6 +336,7 @@ const initialState: SettingsStoreState & Settings = {
|
||||
setIsSavedClipsPanelVisibleOnly: () => {},
|
||||
setShowBothPanels: () => {},
|
||||
setIsSimplifiedLayout: () => {},
|
||||
setShowTrayIcon: () => {},
|
||||
initConstants: () => {},
|
||||
setAppDataDir: () => {}, // Keep if used for other general app data
|
||||
setCustomDbPath: () => {},
|
||||
@ -698,6 +702,10 @@ export const settingsStore = createStore<SettingsStoreState & Settings>()((set,
|
||||
setIsSimplifiedLayout: async (isEnabled: boolean) => {
|
||||
return get().updateSetting('isSimplifiedLayout', isEnabled)
|
||||
},
|
||||
setShowTrayIcon: async (showTrayIcon: boolean) => {
|
||||
// The backend will handle tray visibility on next startup based on this persisted setting.
|
||||
return get().updateSetting('showTrayIcon', showTrayIcon)
|
||||
},
|
||||
isNotTourCompletedOrSkipped: (tourName: string) => {
|
||||
const { appToursCompletedList, appToursSkippedList } = get()
|
||||
return (
|
||||
|
@ -75,7 +75,9 @@ use tauri::ClipboardManager;
|
||||
use tauri::Manager;
|
||||
use tauri::SystemTray;
|
||||
use tauri::SystemTrayEvent;
|
||||
use tauri::SystemTrayMenu; // Added for empty menu
|
||||
// use tauri_plugin_positioner::{Position, WindowExt};
|
||||
use crate::services::user_settings_service;
|
||||
|
||||
use fns::debounce;
|
||||
use inputbot::KeybdKey::*;
|
||||
@ -1079,19 +1081,30 @@ async fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
match menu::build_tray_menu(
|
||||
db_items_state_local,
|
||||
db_recent_history_items_state,
|
||||
app_settings,
|
||||
) {
|
||||
Ok(tray_menu) => {
|
||||
let menu = SystemTray::new().with_id(tray_id).with_menu(tray_menu);
|
||||
menu.build(app)?;
|
||||
// Determine if the tray icon should be shown
|
||||
let show_tray_icon_setting = user_settings_service::get_setting("showTrayIcon");
|
||||
let mut show_tray_icon_bool = true; // Default to true if not found or not a bool
|
||||
if let Some(value) = show_tray_icon_setting {
|
||||
if let serde_yaml::Value::Bool(b) = value {
|
||||
show_tray_icon_bool = b;
|
||||
}
|
||||
Err(error_msg) => {
|
||||
debug_output(|| {
|
||||
println!("Failed to build tray menu: {}", error_msg);
|
||||
});
|
||||
}
|
||||
|
||||
if show_tray_icon_bool {
|
||||
match menu::build_tray_menu(
|
||||
db_items_state_local,
|
||||
db_recent_history_items_state,
|
||||
app_settings,
|
||||
) {
|
||||
Ok(tray_menu) => {
|
||||
let menu = SystemTray::new().with_id(tray_id).with_menu(tray_menu);
|
||||
menu.build(app)?;
|
||||
}
|
||||
Err(error_msg) => {
|
||||
debug_output(|| {
|
||||
println!("Failed to build tray menu: {}", error_msg);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,23 +16,32 @@ pub struct UserConfig {
|
||||
|
||||
pub fn load_user_config() -> UserConfig {
|
||||
let path = get_config_file_path();
|
||||
if !path.exists() {
|
||||
return UserConfig::default();
|
||||
}
|
||||
|
||||
match std::fs::read_to_string(&path) {
|
||||
Ok(contents) => match serde_yaml::from_str::<UserConfig>(&contents) {
|
||||
Ok(cfg) => cfg,
|
||||
let mut cfg = if !path.exists() {
|
||||
UserConfig::default()
|
||||
} else {
|
||||
match std::fs::read_to_string(&path) {
|
||||
Ok(contents) => match serde_yaml::from_str::<UserConfig>(&contents) {
|
||||
Ok(parsed_cfg) => parsed_cfg,
|
||||
Err(e) => {
|
||||
eprintln!("Error parsing user config YAML: {:#}", e);
|
||||
UserConfig::default()
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("Error parsing user config YAML: {:#}", e);
|
||||
eprintln!("Error reading user config file: {:#}", e);
|
||||
UserConfig::default()
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("Error reading user config file: {:#}", e);
|
||||
UserConfig::default()
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure "showTrayIcon" is present
|
||||
if !cfg.data.contains_key("showTrayIcon") {
|
||||
cfg.data.insert(
|
||||
"showTrayIcon".to_string(),
|
||||
serde_yaml::Value::Bool(true),
|
||||
);
|
||||
}
|
||||
cfg
|
||||
}
|
||||
|
||||
/// Save the `UserConfig` back to `pastebar_settings.yaml`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user