Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions ui/desktop/src/components/settings/app/AppSettingsSection.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { useState, useEffect, useRef } from 'react';
import { Switch } from '../../ui/switch';
import { Button } from '../../ui/button';
import { Settings } from 'lucide-react';
import Modal from '../../Modal';
import UpdateSection from './UpdateSection';
import { UPDATES_ENABLED } from '../../../updates';

Expand All @@ -12,6 +15,7 @@ export default function AppSettingsSection({ scrollToSection }: AppSettingsSecti
const [dockIconEnabled, setDockIconEnabled] = useState(true);
const [isMacOS, setIsMacOS] = useState(false);
const [isDockSwitchDisabled, setIsDockSwitchDisabled] = useState(false);
const [showNotificationModal, setShowNotificationModal] = useState(false);
const updateSectionRef = useRef<HTMLDivElement>(null);

// Check if running on macOS
Expand Down Expand Up @@ -90,6 +94,38 @@ export default function AppSettingsSection({ scrollToSection }: AppSettingsSecti
<div className="pb-8">
<p className="text-sm text-textStandard mb-6">Configure Goose app</p>
<div>
{/* Task Notifications */}
<div className="flex items-center justify-between mb-4">
<div>
<h3 className="text-textStandard">Notifications</h3>
<p className="text-xs text-textSubtle max-w-md mt-[2px]">
Notifications are managed by your OS{' - '}
<span
className="underline hover:cursor-pointer"
onClick={() => setShowNotificationModal(true)}
>
Configuration guide
</span>
</p>
</div>
<div className="flex items-center">
<Button
className="flex items-center gap-2 justify-center text-textStandard bg-bgApp border border-borderSubtle hover:border-borderProminent hover:bg-bgApp [&>svg]:!size-4"
onClick={async () => {
try {
await window.electron.openNotificationsSettings();
} catch (error) {
console.error('Failed to open notification settings:', error);
}
}}
>
<Settings />
Open Settings
</Button>
</div>
</div>

{/* Menu Bar */}
<div className="flex items-center justify-between mb-4">
<div>
<h3 className="text-textStandard">Menu Bar Icon</h3>
Expand All @@ -106,6 +142,7 @@ export default function AppSettingsSection({ scrollToSection }: AppSettingsSecti
</div>
</div>

{/* Dock Icon */}
{isMacOS && (
<div className="flex items-center justify-between mb-4">
<div>
Expand Down Expand Up @@ -157,6 +194,86 @@ export default function AppSettingsSection({ scrollToSection }: AppSettingsSecti
</div>
)}
</div>

{/* Notification Instructions Modal */}
{showNotificationModal && (
<Modal
onClose={() => setShowNotificationModal(false)}
footer={
<Button
onClick={() => setShowNotificationModal(false)}
variant="ghost"
className="w-full h-[60px] rounded-none hover:bg-bgSubtle text-textSubtle hover:text-textStandard text-md font-regular"
>
Close
</Button>
}
>
{/* Title and Icon */}
<div className="flex flex-col mb-6">
<div>
<Settings className="text-iconStandard" size={24} />
</div>
<div className="mt-2">
<h2 className="text-2xl font-regular text-textStandard">
How to Enable Notifications
</h2>
</div>
</div>

{/* Content */}
<div>
{isMacOS ? (
<div className="space-y-4">
<p className="text-textStandard">To enable notifications for Goose on macOS:</p>
<ol className="list-decimal list-inside space-y-3 text-textStandard ml-4">
<li>Click the "Open Settings" button</li>
<li>Find "Goose" in the list of applications</li>
<li>Click on "Goose" to open its notification settings</li>
<li>Toggle "Allow Notifications" to ON</li>
<li>Choose your preferred notification style</li>
</ol>
</div>
) : window.electron.platform === 'win32' ? (
<div className="space-y-4">
<p className="text-textStandard">To enable notifications for Goose on Windows:</p>
<ol className="list-decimal list-inside space-y-3 text-textStandard ml-4">
<li>Click the "Open Settings" button</li>
<li>
In the Notifications & actions settings, scroll down to "Get notifications from
these senders"
</li>
<li>Find "Goose" in the list of applications</li>
<li>Click on "Goose" to expand its notification settings</li>
<li>Toggle the main switch to ON to enable notifications</li>
<li>Customize notification banners, sounds, and other preferences as desired</li>
</ol>
</div>
) : (
<div className="space-y-4">
<p className="text-textStandard">To enable notifications for Goose on Linux:</p>
<ol className="list-decimal list-inside space-y-3 text-textStandard ml-4">
<li>Click the "Open Settings" button</li>
<li>
In the notification settings panel, look for application-specific settings
</li>
<li>Find "Goose" or "Electron" in the list of applications</li>
<li>Enable notifications for the application</li>
<li>Configure notification preferences such as sound and display options</li>
</ol>
<div className="mt-4 p-3 bg-bgSubtle rounded-md">
<p className="text-sm text-textSubtle">
<strong>Note:</strong> The exact steps may vary depending on your desktop
environment (GNOME, KDE, XFCE, etc.). If the "Open Settings" button doesn't
work, you can manually access notification settings through your system's
settings application.
</p>
</div>
</div>
)}
</div>
</Modal>
)}
</section>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export const all_tool_selection_strategies = [
{
key: 'vector',
label: 'Vector',
description:
'Filter tools based on vector similarity.',
description: 'Filter tools based on vector similarity.',
},
{
key: 'llm',
Expand Down Expand Up @@ -64,8 +63,8 @@ export const ToolSelectionStrategySection = ({
</div>
<div className="border-b border-borderSubtle pb-8">
<p className="text-sm text-textStandard mb-6">
Configure how Goose selects tools for your requests. Recommended when many extensions are enabled.
Available only with Claude models served on Databricks for now.
Configure how Goose selects tools for your requests. Recommended when many extensions are
enabled. Available only with Claude models served on Databricks for now.
</p>
<div>
{all_tool_selection_strategies.map((strategy) => (
Expand Down
56 changes: 56 additions & 0 deletions ui/desktop/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,62 @@ ipcMain.handle('get-dock-icon-state', () => {
}
});

// Handle opening system notifications preferences
ipcMain.handle('open-notifications-settings', async () => {
try {
if (process.platform === 'darwin') {
spawn('open', ['x-apple.systempreferences:com.apple.preference.notifications']);
return true;
} else if (process.platform === 'win32') {
// Windows: Open notification settings in Settings app
spawn('ms-settings:notifications', { shell: true });
return true;
} else if (process.platform === 'linux') {
// Linux: Try different desktop environments
// GNOME
try {
spawn('gnome-control-center', ['notifications']);
return true;
} catch (gnomeError) {
console.log('GNOME control center not found, trying other options');
}

// KDE Plasma
try {
spawn('systemsettings5', ['kcm_notifications']);
return true;
} catch (kdeError) {
console.log('KDE systemsettings5 not found, trying other options');
}

// XFCE
try {
spawn('xfce4-settings-manager', ['--socket-id=notifications']);
return true;
} catch (xfceError) {
console.log('XFCE settings manager not found, trying other options');
}

// Fallback: Try to open general settings
try {
spawn('gnome-control-center');
return true;
} catch (fallbackError) {
console.warn('Could not find a suitable settings application for Linux');
return false;
}
} else {
console.warn(
`Opening notification settings is not supported on platform: ${process.platform}`
);
return false;
}
} catch (error) {
console.error('Error opening notification settings:', error);
return false;
}
});

// Add file/directory selection handler
ipcMain.handle('select-file-or-directory', async () => {
const result = (await dialog.showOpenDialog({
Expand Down
2 changes: 2 additions & 0 deletions ui/desktop/src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type ElectronAPI = {
getMenuBarIconState: () => Promise<boolean>;
setDockIcon: (show: boolean) => Promise<boolean>;
getDockIconState: () => Promise<boolean>;
openNotificationsSettings: () => Promise<boolean>;
on: (
channel: string,
callback: (event: Electron.IpcRendererEvent, ...args: unknown[]) => void
Expand Down Expand Up @@ -138,6 +139,7 @@ const electronAPI: ElectronAPI = {
getMenuBarIconState: () => ipcRenderer.invoke('get-menu-bar-icon-state'),
setDockIcon: (show: boolean) => ipcRenderer.invoke('set-dock-icon', show),
getDockIconState: () => ipcRenderer.invoke('get-dock-icon-state'),
openNotificationsSettings: () => ipcRenderer.invoke('open-notifications-settings'),
on: (
channel: string,
callback: (event: Electron.IpcRendererEvent, ...args: unknown[]) => void
Expand Down
Loading