Skip to content

Commit dcab45a

Browse files
committed
feat(App): Add option to enable/disable spell checker
1 parent 430e9a3 commit dcab45a

File tree

10 files changed

+149
-33
lines changed

10 files changed

+149
-33
lines changed

src/components/settings/navigation/SettingsNavigation.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ export default class SettingsNavigation extends Component {
7474
<Link
7575
to="/auth/logout"
7676
className="settings-navigation__link"
77-
activeClassName="is-active"
7877
>
7978
{intl.formatMessage(messages.logout)}
8079
</Link>

src/components/settings/settings/EditSettingsForm.js

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ const messages = defineMessages({
3030
id: 'settings.app.headlineAppearance',
3131
defaultMessage: '!!!Appearance',
3232
},
33-
headlineMessaging: {
34-
id: 'settings.app.headlineMessaging',
35-
defaultMessage: '!!!Messaging',
33+
headlineAdvanced: {
34+
id: 'settings.app.headlineAdvanced',
35+
defaultMessage: '!!!Advanced',
3636
},
3737
buttonSearchForUpdate: {
3838
id: 'settings.app.buttonSearchForUpdate',
@@ -58,6 +58,10 @@ const messages = defineMessages({
5858
id: 'settings.app.currentVersion',
5959
defaultMessage: '!!!Current version:',
6060
},
61+
restartRequired: {
62+
id: 'settings.app.restartRequired',
63+
defaultMessage: '!!!Changes require restart',
64+
},
6165
});
6266

6367
@observer
@@ -120,20 +124,31 @@ export default class EditSettingsForm extends Component {
120124
onChange={e => this.submit(e)}
121125
id="form"
122126
>
123-
<h2>{intl.formatMessage(messages.headlineGeneral)}</h2>
127+
{/* General */}
128+
<h2 id="general">{intl.formatMessage(messages.headlineGeneral)}</h2>
124129
<Toggle field={form.$('autoLaunchOnStart')} />
125130
<Toggle field={form.$('runInBackground')} />
126131
<Toggle field={form.$('enableSystemTray')} />
127132
{process.platform === 'win32' && (
128133
<Toggle field={form.$('minimizeToSystemTray')} />
129134
)}
130-
<h2>{intl.formatMessage(messages.headlineAppearance)}</h2>
135+
136+
{/* Appearance */}
137+
<h2 id="apperance">{intl.formatMessage(messages.headlineAppearance)}</h2>
131138
<Toggle field={form.$('showDisabledServices')} />
132-
<h2>{intl.formatMessage(messages.headlineMessaging)}</h2>
133-
<Toggle field={form.$('enableSpellchecking')} />
134-
<h2>{intl.formatMessage(messages.headlineLanguage)}</h2>
139+
140+
{/* Language */}
141+
<h2 id="language">{intl.formatMessage(messages.headlineLanguage)}</h2>
135142
<Select field={form.$('locale')} showLabel={false} />
136-
<h2>{intl.formatMessage(messages.headlineUpdates)}</h2>
143+
144+
{/* Advanced */}
145+
<h2 id="advanced">{intl.formatMessage(messages.headlineAdvanced)}</h2>
146+
<Toggle field={form.$('enableSpellchecking')} />
147+
<p className="settings__help">{intl.formatMessage(messages.restartRequired)}</p>
148+
{/* <Select field={form.$('spellcheckingLanguage')} /> */}
149+
150+
{/* Updates */}
151+
<h2 id="updates">{intl.formatMessage(messages.headlineUpdates)}</h2>
137152
{updateIsReadyToInstall ? (
138153
<Button
139154
label={intl.formatMessage(messages.buttonInstallUpdate)}

src/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const DEFAULT_APP_SETTINGS = {
1212
minimizeToSystemTray: false,
1313
showDisabledServices: true,
1414
enableSpellchecking: true,
15+
// spellcheckingLanguage: 'auto',
1516
locale: 'en-US',
1617
beta: false,
1718
isAppMuted: false,

src/containers/settings/EditSettingsScreen.js

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import AppStore from '../../stores/AppStore';
77
import SettingsStore from '../../stores/SettingsStore';
88
import UserStore from '../../stores/UserStore';
99
import Form from '../../lib/Form';
10-
import languages from '../../i18n/languages';
10+
import { APP_LOCALES } from '../../i18n/languages';
1111
import { gaPage } from '../../lib/analytics';
1212
import { DEFAULT_APP_SETTINGS } from '../../config';
1313

@@ -47,6 +47,14 @@ const messages = defineMessages({
4747
id: 'settings.app.form.enableSpellchecking',
4848
defaultMessage: '!!!Enable spell checking',
4949
},
50+
spellcheckingLanguage: {
51+
id: 'settings.app.form.spellcheckingLanguage',
52+
defaultMessage: '!!!Language for spell checking',
53+
},
54+
// spellcheckingAutomaticDetection: {
55+
// id: 'settings.app.form.spellcheckingAutomaticDetection',
56+
// defaultMessage: '!!!Detect language automatically',
57+
// },
5058
beta: {
5159
id: 'settings.app.form.beta',
5260
defaultMessage: '!!!Include beta versions',
@@ -78,6 +86,7 @@ export default class EditSettingsScreen extends Component {
7886
minimizeToSystemTray: settingsData.minimizeToSystemTray,
7987
showDisabledServices: settingsData.showDisabledServices,
8088
enableSpellchecking: settingsData.enableSpellchecking,
89+
// spellcheckingLanguage: settingsData.spellcheckingLanguage,
8190
locale: settingsData.locale,
8291
beta: settingsData.beta,
8392
},
@@ -94,14 +103,25 @@ export default class EditSettingsScreen extends Component {
94103
const { app, settings, user } = this.props.stores;
95104
const { intl } = this.context;
96105

97-
const options = [];
98-
Object.keys(languages).forEach((key) => {
99-
options.push({
106+
const locales = [];
107+
Object.keys(APP_LOCALES).forEach((key) => {
108+
locales.push({
100109
value: key,
101-
label: languages[key],
110+
label: APP_LOCALES[key],
102111
});
103112
});
104113

114+
// const spellcheckerLocales = [{
115+
// value: 'auto',
116+
// label: intl.formatMessage(messages.spellcheckingAutomaticDetection),
117+
// }];
118+
// Object.keys(SPELLCHECKER_LOCALES).forEach((key) => {
119+
// spellcheckerLocales.push({
120+
// value: key,
121+
// label: SPELLCHECKER_LOCALES[key],
122+
// });
123+
// });
124+
105125
const config = {
106126
fields: {
107127
autoLaunchOnStart: {
@@ -139,10 +159,16 @@ export default class EditSettingsScreen extends Component {
139159
value: settings.all.enableSpellchecking,
140160
default: DEFAULT_APP_SETTINGS.enableSpellchecking,
141161
},
162+
// spellcheckingLanguage: {
163+
// label: intl.formatMessage(messages.spellcheckingLanguage),
164+
// value: settings.all.spellcheckingLanguage,
165+
// options: spellcheckerLocales,
166+
// default: DEFAULT_APP_SETTINGS.spellcheckingLanguage,
167+
// },
142168
locale: {
143169
label: intl.formatMessage(messages.language),
144170
value: app.locale,
145-
options,
171+
options: locales,
146172
default: DEFAULT_APP_SETTINGS.locale,
147173
},
148174
beta: {

src/i18n/languages.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module.exports = {
1+
export const APP_LOCALES = {
22
'en-US': 'English',
33
'pt-BR': 'Portuguese (Brazil)',
44
'el-GR': 'Ελληνικά (Greece)',
@@ -15,3 +15,46 @@ module.exports = {
1515
'zh-Hant': 'Chinese (Traditional)',
1616
'nb-NO': 'Norsk',
1717
};
18+
19+
export default APP_LOCALES;
20+
21+
// export const SPELLCHECKER_LOCALES = {
22+
// af: 'Afrikaans',
23+
// sq: 'Albanian',
24+
// ar: 'Arabic',
25+
// bg: 'Bulgarian',
26+
// zh: 'Chinese',
27+
// hr: 'Croatian',
28+
// cs: 'Czech',
29+
// da: 'Danish',
30+
// nl: 'Dutch',
31+
// en: 'English',
32+
// 'en-AU': 'English (AU)',
33+
// 'en-CA': 'English (CA)',
34+
// 'en-GB': 'English (GB)',
35+
// fi: 'Finnish',
36+
// fr: 'French',
37+
// ka: 'Georgian',
38+
// de: 'German',
39+
// el: 'Greek, Modern',
40+
// hi: 'Hindi',
41+
// hu: 'Hungarian',
42+
// id: 'Indonesian',
43+
// it: 'Italian',
44+
// ja: 'Japanese',
45+
// jv: 'Javanese',
46+
// ko: 'Korean',
47+
// lt: 'Lithuanian',
48+
// lv: 'Latvian',
49+
// ms: 'Malay',
50+
// no: 'Norwegian',
51+
// pl: 'Polish',
52+
// pt: 'Portuguese',
53+
// ro: 'Romanian, Moldavian, Moldovan',
54+
// ru: 'Russian',
55+
// sk: 'Slovak',
56+
// es: 'Spanish',
57+
// sv: 'Swedish',
58+
// uk: 'Ukrainian',
59+
// vi: 'Vietnamese',
60+
// };

src/i18n/locales/en-US.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
"settings.app.headlineLanguage": "Language",
133133
"settings.app.headlineUpdates": "Updates",
134134
"settings.app.headlineAppearance": "Appearance",
135+
"settings.app.headlineAdvanced": "Advanced",
135136
"settings.app.buttonSearchForUpdate": "Check for updates",
136137
"settings.app.buttonInstallUpdate": "Restart & install update",
137138
"settings.app.updateStatusSearching": "Is searching for update",
@@ -143,9 +144,11 @@
143144
"settings.app.form.minimizeToSystemTray": "Minimize Franz to system tray",
144145
"settings.app.form.runInBackground": "Keep Franz in background when closing the window",
145146
"settings.app.form.language": "Language",
147+
"settings.app.form.enableSpellchecking": "Enable spell checking",
146148
"settings.app.form.showDisabledServices": "Display disabled services tabs",
147149
"settings.app.form.beta": "Include beta versions",
148150
"settings.app.currentVersion": "Current version:",
151+
"settings.app.restartRequired": "Changes require restart",
149152
"settings.user.form.firstname": "Firstname",
150153
"settings.user.form.lastname": "Lastname",
151154
"settings.user.form.email": "Email",

src/i18n/translations.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import languages from './languages';
1+
import { APP_LOCALES } from './languages';
22

33
const translations = [];
4-
Object.keys(languages).forEach((key) => {
4+
Object.keys(APP_LOCALES).forEach((key) => {
55
try {
66
const translation = require(`./locales/${key}.json`); // eslint-disable-line
77
translations[key] = translation;

src/stores/ServicesStore.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ export default class ServicesStore extends Store {
286286
if (channel === 'hello') {
287287
this._initRecipePolling(service.id);
288288
this._initializeServiceRecipeInWebview(serviceId);
289+
this._shareSettingsWithServiceProcess();
289290
} else if (channel === 'messages') {
290291
this.actions.service.setUnreadMessageCount({
291292
serviceId,

src/webview/plugin.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ import path from 'path';
33

44
import RecipeWebview from './lib/RecipeWebview';
55

6-
import './spellchecker.js';
6+
import Spellchecker from './spellchecker.js';
77
import './notifications.js';
88
import './ime.js';
99

10+
const spellchecker = new Spellchecker();
11+
1012
ipcRenderer.on('initializeRecipe', (e, data) => {
1113
const modulePath = path.join(data.recipe.path, 'webview.js');
1214
// Delete module from cache
@@ -20,7 +22,17 @@ ipcRenderer.on('initializeRecipe', (e, data) => {
2022
});
2123

2224
ipcRenderer.on('settings-update', (e, data) => {
23-
console.log(data);
25+
if (data.enableSpellchecking) {
26+
if (!spellchecker.isEnabled) {
27+
spellchecker.enable();
28+
29+
// TODO: this does not work yet, needs more testing
30+
// if (data.spellcheckingLanguage !== 'auto') {
31+
// console.log('set spellchecking language to', data.spellcheckingLanguage);
32+
// spellchecker.switchLanguage(data.spellcheckingLanguage);
33+
// }
34+
}
35+
}
2436
});
2537

2638
document.addEventListener('DOMContentLoaded', () => {

src/webview/spellchecker.js

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
import { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } from 'electron-spellchecker';
22

3-
window.spellCheckHandler = new SpellCheckHandler();
4-
setTimeout(() => {
5-
window.spellCheckHandler.attachToInput();
6-
}, 1000);
7-
8-
// TODO: should we set the language to user settings?
9-
// window.spellCheckHandler.switchLanguage('en-US');
10-
11-
const contextMenuBuilder = new ContextMenuBuilder(window.spellCheckHandler);
12-
const contextMenuListener = new ContextMenuListener((info) => { // eslint-disable-line
13-
contextMenuBuilder.showPopupMenu(info);
14-
});
3+
import { isMac } from '../environment';
4+
5+
export default class Spellchecker {
6+
isEnabled = false;
7+
spellchecker = null;
8+
9+
enable() {
10+
this.spellchecker = new SpellCheckHandler();
11+
if (!isMac) {
12+
this.spellchecker.attachToInput();
13+
this.spellchecker.switchLanguage(navigator.language);
14+
}
15+
16+
const contextMenuBuilder = new ContextMenuBuilder(this.spellchecker);
17+
18+
new ContextMenuListener((info) => { // eslint-disable-line
19+
contextMenuBuilder.showPopupMenu(info);
20+
});
21+
}
22+
23+
// TODO: this does not work yet, needs more testing
24+
// switchLanguage(language) {
25+
// if (language !== 'auto') {
26+
// this.spellchecker.switchLanguage(language);
27+
// }
28+
// }
29+
}
30+

0 commit comments

Comments
 (0)