feat: introduce notification system and claude notifications (#450)

* feat: introduce notification system and claude notifications

* fix(sw): prevent caching of API requests and WebSocket upgrades

* default to false for webpush notifications and translations for the button

* fix: notifications orchestrator and add a notification when  first enabled

* fix: remove unused state update and dependency in settings controller hook

* fix: show notifications settings tab

* fix: add notifications for response completion for all providers

* feat: show session name in notification and don't reload tab on clicking
--- the notification

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Haileyesus <something@gmail.com>
This commit is contained in:
Simos Mikelatos
2026-03-13 16:59:09 +01:00
committed by GitHub
parent 6f6dacad5e
commit 45e71a0e73
36 changed files with 1629 additions and 69 deletions

View File

@@ -9,9 +9,11 @@ import AgentsSettingsTab from '../view/tabs/agents-settings/AgentsSettingsTab';
import AppearanceSettingsTab from '../view/tabs/AppearanceSettingsTab';
import CredentialsSettingsTab from '../view/tabs/api-settings/CredentialsSettingsTab';
import GitSettingsTab from '../view/tabs/git-settings/GitSettingsTab';
import NotificationsSettingsTab from '../view/tabs/NotificationsSettingsTab';
import TasksSettingsTab from '../view/tabs/tasks-settings/TasksSettingsTab';
import PluginSettingsTab from '../../plugins/view/PluginSettingsTab';
import { useSettingsController } from '../hooks/useSettingsController';
import { useWebPush } from '../../../hooks/useWebPush';
import type { SettingsProps } from '../types/types';
function Settings({ isOpen, onClose, projects = [], initialTab = 'agents' }: SettingsProps) {
@@ -27,6 +29,8 @@ function Settings({ isOpen, onClose, projects = [], initialTab = 'agents' }: Set
updateCodeEditorSetting,
claudePermissions,
setClaudePermissions,
notificationPreferences,
setNotificationPreferences,
cursorPermissions,
setCursorPermissions,
codexPermissionMode,
@@ -70,6 +74,32 @@ function Settings({ isOpen, onClose, projects = [], initialTab = 'agents' }: Set
onClose,
});
const {
permission: pushPermission,
isSubscribed: isPushSubscribed,
isLoading: isPushLoading,
subscribe: pushSubscribe,
unsubscribe: pushUnsubscribe,
} = useWebPush();
const handleEnablePush = async () => {
await pushSubscribe();
// Server sets webPush: true in preferences on subscribe; sync local state
setNotificationPreferences({
...notificationPreferences,
channels: { ...notificationPreferences.channels, webPush: true },
});
};
const handleDisablePush = async () => {
await pushUnsubscribe();
// Server sets webPush: false in preferences on unsubscribe; sync local state
setNotificationPreferences({
...notificationPreferences,
channels: { ...notificationPreferences.channels, webPush: false },
});
};
if (!isOpen) {
return null;
}
@@ -161,6 +191,18 @@ function Settings({ isOpen, onClose, projects = [], initialTab = 'agents' }: Set
{activeTab === 'tasks' && <TasksSettingsTab />}
{activeTab === 'notifications' && (
<NotificationsSettingsTab
notificationPreferences={notificationPreferences}
onNotificationPreferencesChange={setNotificationPreferences}
pushPermission={pushPermission}
isPushSubscribed={isPushSubscribed}
isPushLoading={isPushLoading}
onEnablePush={handleEnablePush}
onDisablePush={handleDisablePush}
/>
)}
{activeTab === 'api' && <CredentialsSettingsTab />}
{activeTab === 'plugins' && <PluginSettingsTab />}