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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import DictationSection from '../dictation/DictationSection';
import { SecurityToggle } from '../security/SecurityToggle';
import { ResponseStylesSection } from '../response_styles/ResponseStylesSection';
import { GoosehintsSection } from './GoosehintsSection';
import { SpellcheckToggle } from './SpellcheckToggle';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../ui/card';

export default function ChatSettingsSection() {
Expand Down Expand Up @@ -37,6 +38,7 @@ export default function ChatSettingsSection() {
<Card className="pb-2 rounded-lg">
<CardContent className="px-2">
<DictationSection />
<SpellcheckToggle />
</CardContent>
</Card>

Expand Down
33 changes: 33 additions & 0 deletions ui/desktop/src/components/settings/chat/SpellcheckToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { useState, useEffect } from 'react';
import { Switch } from '../../ui/switch';

export const SpellcheckToggle = () => {
const [enabled, setEnabled] = useState(true);

useEffect(() => {
const loadState = async () => {
const state = await window.electron.getSpellcheckState();
setEnabled(state);
};
loadState();
}, []);

const handleToggle = async (checked: boolean) => {
setEnabled(checked);
await window.electron.setSpellcheck(checked);
};

return (
<div className="flex items-center justify-between py-2 px-2 hover:bg-background-muted rounded-lg transition-all">
<div>
<h3 className="text-text-default">Enable Spellcheck</h3>
<p className="text-xs text-text-muted max-w-md mt-[2px]">
Check spelling in the chat input. Requires restart to take effect.
</p>
</div>
<div className="flex items-center">
<Switch checked={enabled} onCheckedChange={handleToggle} variant="mono" />
</div>
</div>
);
};
24 changes: 23 additions & 1 deletion ui/desktop/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ const createChat = async (
useContentSize: true,
icon: path.join(__dirname, '../images/icon.icns'),
webPreferences: {
spellcheck: true,
spellcheck: settings.spellcheckEnabled ?? true,
preload: path.join(__dirname, 'preload.js'),
webSecurity: true,
nodeIntegration: false,
Expand Down Expand Up @@ -1421,6 +1421,28 @@ ipcMain.handle('get-wakelock-state', () => {
}
});

ipcMain.handle('set-spellcheck', async (_event, enable: boolean) => {
try {
const settings = loadSettings();
settings.spellcheckEnabled = enable;
saveSettings(settings);
return true;
} catch (error) {
console.error('Error setting spellcheck:', error);
return false;
}
});

ipcMain.handle('get-spellcheck-state', () => {
try {
const settings = loadSettings();
return settings.spellcheckEnabled ?? true;
} catch (error) {
console.error('Error getting spellcheck state:', error);
return true;
}
});

// Add file/directory selection handler
ipcMain.handle('select-file-or-directory', async (_event, defaultPath?: string) => {
const dialogOptions: OpenDialogOptions = {
Expand Down
4 changes: 4 additions & 0 deletions ui/desktop/src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ type ElectronAPI = {
getGoosedHostPort: () => Promise<string | null>;
setWakelock: (enable: boolean) => Promise<boolean>;
getWakelockState: () => Promise<boolean>;
setSpellcheck: (enable: boolean) => Promise<boolean>;
getSpellcheckState: () => Promise<boolean>;
openNotificationsSettings: () => Promise<boolean>;
onMouseBackButtonClicked: (callback: () => void) => void;
offMouseBackButtonClicked: (callback: () => void) => void;
Expand Down Expand Up @@ -201,6 +203,8 @@ const electronAPI: ElectronAPI = {
getGoosedHostPort: () => ipcRenderer.invoke('get-goosed-host-port'),
setWakelock: (enable: boolean) => ipcRenderer.invoke('set-wakelock', enable),
getWakelockState: () => ipcRenderer.invoke('get-wakelock-state'),
setSpellcheck: (enable: boolean) => ipcRenderer.invoke('set-spellcheck', enable),
getSpellcheckState: () => ipcRenderer.invoke('get-spellcheck-state'),
openNotificationsSettings: () => ipcRenderer.invoke('open-notifications-settings'),
onMouseBackButtonClicked: (callback: () => void) => {
// Wrapper that ignores the event parameter.
Expand Down
2 changes: 2 additions & 0 deletions ui/desktop/src/utils/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface Settings {
showMenuBarIcon: boolean;
showDockIcon: boolean;
enableWakelock: boolean;
spellcheckEnabled: boolean;
externalGoosed?: ExternalGoosedConfig;
}

Expand All @@ -31,6 +32,7 @@ const defaultSettings: Settings = {
showMenuBarIcon: true,
showDockIcon: true,
enableWakelock: false,
spellcheckEnabled: true,
};

// Settings management
Expand Down
Loading