diff --git a/src/browser/components/MainPage.jsx b/src/browser/components/MainPage.jsx index d0322dd8..a1d6bcf0 100644 --- a/src/browser/components/MainPage.jsx +++ b/src/browser/components/MainPage.jsx @@ -39,7 +39,9 @@ const MainPage = React.createClass({ onUnreadCountChange: React.PropTypes.func.isRequired, teams: React.PropTypes.array.isRequired, onTeamConfigChange: React.PropTypes.func.isRequired, - initialIndex: React.PropTypes.number.isRequired + initialIndex: React.PropTypes.number.isRequired, + useSpellChecker: React.PropTypes.bool.isRequired, + onSelectSpellCheckerLocale: React.PropTypes.func.isRequired }, getInitialState() { @@ -264,6 +266,8 @@ const MainPage = React.createClass({ key={id} id={id} withTab={this.props.teams.length > 1} + useSpellChecker={this.props.useSpellChecker} + onSelectSpellCheckerLocale={this.props.onSelectSpellCheckerLocale} src={team.url} name={team.name} onTargetURLChange={self.handleTargetURLChange} diff --git a/src/browser/components/MattermostView.jsx b/src/browser/components/MattermostView.jsx index 0359753d..667ac6d3 100644 --- a/src/browser/components/MattermostView.jsx +++ b/src/browser/components/MattermostView.jsx @@ -16,7 +16,9 @@ const MattermostView = React.createClass({ onUnreadCountChange: React.PropTypes.func, src: React.PropTypes.string, active: React.PropTypes.bool, - withTab: React.PropTypes.bool + withTab: React.PropTypes.bool, + useSpellChecker: React.PropTypes.bool, + onSelectSpellCheckerLocale: React.PropTypes.func }, getInitialState() { @@ -79,7 +81,15 @@ const MattermostView = React.createClass({ // webview.openDevTools(); if (!this.state.isContextMenuAdded) { - contextMenu.setup(webview); + contextMenu.setup(webview, { + useSpellChecker: this.props.useSpellChecker, + onSelectSpellCheckerLocale: (locale) => { + if (this.props.onSelectSpellCheckerLocale) { + this.props.onSelectSpellCheckerLocale(locale); + } + webview.send('set-spellcheker'); + } + }); this.setState({isContextMenuAdded: true}); } }); diff --git a/src/browser/components/SettingsPage.jsx b/src/browser/components/SettingsPage.jsx index 742aa4a7..f9307a97 100644 --- a/src/browser/components/SettingsPage.jsx +++ b/src/browser/components/SettingsPage.jsx @@ -1,6 +1,6 @@ const React = require('react'); const ReactDOM = require('react-dom'); -const {Button, Checkbox, Col, FormControl, FormGroup, Grid, HelpBlock, Navbar, Radio, Row} = require('react-bootstrap'); +const {Button, Checkbox, Col, FormGroup, Grid, HelpBlock, Navbar, Radio, Row} = require('react-bootstrap'); const {ipcRenderer, remote} = require('electron'); const AutoLaunch = require('auto-launch'); @@ -218,13 +218,6 @@ const SettingsPage = React.createClass({ setImmediate(this.startSaveConfig); }, - handleChangeSpellCheckerLocale(event) { - this.setState({ - spellCheckerLocale: event.target.value - }); - setImmediate(this.startSaveConfig); - }, - updateTeam(index, newData) { var teams = this.state.teams; teams[index] = newData; @@ -294,19 +287,6 @@ const SettingsPage = React.createClass({ {'Highlight misspelled words in your messages.'} {' Available for English, French, German, Spanish, and Dutch.'} - - - - - - - ); if (process.platform === 'darwin' || process.platform === 'win32') { diff --git a/src/browser/index.jsx b/src/browser/index.jsx index 43e7aab1..c702f2ec 100644 --- a/src/browser/index.jsx +++ b/src/browser/index.jsx @@ -90,6 +90,13 @@ function teamConfigChange(teams) { ipcRenderer.send('update-config'); } +function handleSelectSpellCheckerLocale(locale) { + console.log(locale); + AppConfig.set('spellCheckerLocale', locale); + ipcRenderer.send('update-config'); + ipcRenderer.send('update-dict'); +} + const parsedURL = url.parse(window.location.href, true); const initialIndex = parsedURL.query.index ? parseInt(parsedURL.query.index, 10) : 0; @@ -99,6 +106,8 @@ ReactDOM.render( initialIndex={initialIndex} onUnreadCountChange={showUnreadBadge} onTeamConfigChange={teamConfigChange} + useSpellChecker={AppConfig.data.useSpellChecker} + onSelectSpellCheckerLocale={handleSelectSpellCheckerLocale} />, document.getElementById('content') ); diff --git a/src/browser/js/contextMenu.js b/src/browser/js/contextMenu.js index 99afddf1..f7190fe8 100644 --- a/src/browser/js/contextMenu.js +++ b/src/browser/js/contextMenu.js @@ -10,14 +10,49 @@ function getSuggestionsMenus(win, suggestions) { })); } +function getSpellCheckerLocaleMenus(onSelectSpellCheckerLocale) { + const currentLocale = ipcRenderer.sendSync('get-spellchecker-locale'); + const locales = [ + {language: 'English', locale: 'en-US'}, + {language: 'French', locale: 'fr-FR'}, + {language: 'German', locale: 'de-DE'}, + {language: 'Spanish', locale: 'es-ES'}, + {language: 'Dutch', locale: 'nl-NL'} + ]; + return locales.map((l) => ({ + label: l.language, + type: 'checkbox', + checked: l.locale === currentLocale, + click() { + if (onSelectSpellCheckerLocale) { + onSelectSpellCheckerLocale(l.locale); + } + } + })); +} + module.exports = { - setup(win) { + setup(win, options) { + const defaultOptions = { + useSpellChecker: false, + onSelectSpellCheckerLocale: null + }; + const actualOptions = Object.assign({}, defaultOptions, options); electronContextMenu({ window: win, prepend(params) { - if (params.isEditable && params.misspelledWord !== '') { - const suggestions = ipcRenderer.sendSync('get-spelling-suggestions', params.misspelledWord); - return getSuggestionsMenus(win, suggestions); + if (actualOptions.useSpellChecker) { + const prependMenuItems = []; + if (params.isEditable && params.misspelledWord !== '') { + const suggestions = ipcRenderer.sendSync('get-spelling-suggestions', params.misspelledWord); + prependMenuItems.push(...getSuggestionsMenus(win, suggestions)); + } + if (params.isEditable) { + prependMenuItems.push( + {type: 'separator'}, + {label: 'Spelling Languages', submenu: getSpellCheckerLocaleMenus(actualOptions.onSelectSpellCheckerLocale)}); + } + return prependMenuItems; } return []; } diff --git a/src/browser/webview/mattermost.js b/src/browser/webview/mattermost.js index 7350621c..24e7c4a0 100644 --- a/src/browser/webview/mattermost.js +++ b/src/browser/webview/mattermost.js @@ -148,10 +148,14 @@ notification.override({ } }); -const spellCheckerLocale = ipc.sendSync('get-spellchecker-locale'); -webFrame.setSpellCheckProvider(spellCheckerLocale, false, { - spellCheck(text) { - const res = ipc.sendSync('checkspell', text); - return res === null ? true : res; - } -}); +function setSpellChecker() { + const spellCheckerLocale = ipc.sendSync('get-spellchecker-locale'); + webFrame.setSpellCheckProvider(spellCheckerLocale, false, { + spellCheck(text) { + const res = ipc.sendSync('checkspell', text); + return res === null ? true : res; + } + }); +} +setSpellChecker(); +ipc.on('set-spellcheker', setSpellChecker); diff --git a/src/common/settings.js b/src/common/settings.js index 7f001b35..18c47f8b 100644 --- a/src/common/settings.js +++ b/src/common/settings.js @@ -7,7 +7,7 @@ function merge(base, target) { return Object.assign({}, base, target); } -function loadDefault(version) { +function loadDefault(version, spellCheckerLocale) { var ver = version; if (version == null) { ver = settingsVersion; @@ -25,7 +25,7 @@ function loadDefault(version) { }, showUnreadBadge: true, useSpellChecker: false, - spellCheckerLocale: 'en-US' + spellCheckerLocale: spellCheckerLocale || 'en-US' }; default: return {}; diff --git a/src/main.js b/src/main.js index 47e2fd88..38195ce2 100644 --- a/src/main.js +++ b/src/main.js @@ -451,10 +451,10 @@ app.on('ready', () => { }); ipcMain.emit('update-menu', true, config); - ipcMain.on('update-dict', (event, locale) => { + ipcMain.on('update-dict', () => { if (config.useSpellChecker) { spellChecker = new SpellChecker( - locale, + config.spellCheckerLocale, path.resolve(app.getAppPath(), 'node_modules/simple-spellchecker/dict'), (err) => { if (err) { @@ -480,7 +480,7 @@ app.on('ready', () => { ipcMain.on('get-spellchecker-locale', (event) => { event.returnValue = config.spellCheckerLocale; }); - ipcMain.emit('update-dict', true, config.spellCheckerLocale); + ipcMain.emit('update-dict'); // Open the DevTools. // mainWindow.openDevTools(); diff --git a/src/main/SpellChecker.js b/src/main/SpellChecker.js index 115a5b3d..cea93d4b 100644 --- a/src/main/SpellChecker.js +++ b/src/main/SpellChecker.js @@ -66,4 +66,23 @@ class SpellChecker { } } +SpellChecker.getSpellCheckerLocale = (electronLocale) => { + if (electronLocale.match(/^en-?/)) { + return 'en-US'; + } + if (electronLocale.match(/^fr-?/)) { + return 'fr-FR'; + } + if (electronLocale.match(/^de-?/)) { + return 'de-DE'; + } + if (electronLocale.match(/^es-?/)) { + return 'es-ES'; + } + if (electronLocale.match(/^nl-?/)) { + return 'nl-NL'; + } + return 'en-US'; +}; + module.exports = SpellChecker; diff --git a/test/specs/browser/settings_test.js b/test/specs/browser/settings_test.js index 71591826..ddbba9bb 100644 --- a/test/specs/browser/settings_test.js +++ b/test/specs/browser/settings_test.js @@ -206,15 +206,13 @@ describe('browser/settings.html', function desc() { env.addClientCommands(this.app.client); return this.app.client. loadSettingsPage(). - isExisting('#selectSpellCheckerLocale').then((existing) => existing.should.equal(true)). - scroll('#selectSpellCheckerLocale'). + isExisting('#inputSpellChecker').then((existing) => existing.should.equal(true)). + scroll('#inputSpellChecker'). click('#inputSpellChecker'). - element('#selectSpellCheckerLocale').selectByVisibleText('French'). pause(700). then(() => { const config1 = JSON.parse(fs.readFileSync(env.configFilePath, 'utf-8')); config1.useSpellChecker.should.equal(true); - config1.spellCheckerLocale.should.equal('fr-FR'); }); }); });