diff --git a/app/src/components/composer-editor/spellcheck-plugins.tsx b/app/src/components/composer-editor/spellcheck-plugins.tsx index b6beb3e49..38425adc1 100644 --- a/app/src/components/composer-editor/spellcheck-plugins.tsx +++ b/app/src/components/composer-editor/spellcheck-plugins.tsx @@ -167,14 +167,6 @@ function onSpellcheckFocusedNode(editor) { function onSpellcheckFullDocument(editor) { const { value } = editor; - // re-determine the language the document is written in - if (value.focusBlock) { - const text = value.focusBlock.text; - if (text.length > 60) { - AppEnv.spellchecker.provideHintText(text.substr(text.length - 512, 512)); - } - } - // spellcheck all text nodes const texts = collectSpellcheckableTextNodes(value.document); const decorations = []; diff --git a/app/src/config-schema.ts b/app/src/config-schema.ts index 3b32ca2b2..1268e15ae 100644 --- a/app/src/config-schema.ts +++ b/app/src/config-schema.ts @@ -281,7 +281,7 @@ export default { ], title: localized('Spellcheck language'), note: localized( - 'If you write a draft in another language, Mailspring will auto-detect it and use the correct spelling dictionary after a few sentences.' + 'Windows and Linux only - on macOS, the spellcheck language is detected by the system as you type.' ), }, }, diff --git a/app/src/spellchecker.ts b/app/src/spellchecker.ts index dfac5ae72..1ddcfd746 100644 --- a/app/src/spellchecker.ts +++ b/app/src/spellchecker.ts @@ -1,5 +1,4 @@ -import { remote } from 'electron'; -import LRUCache from 'lru-cache'; +import { remote, webFrame } from 'electron'; import fs from 'fs'; import path from 'path'; import { localized } from './intl'; @@ -7,24 +6,17 @@ import { localized } from './intl'; const { app, MenuItem } = remote; const customDictFilePath = path.join(AppEnv.getConfigDirPath(), 'custom-dict.json'); -const { webFrame } = require('electron'); - class Spellchecker { - private _customDictLoaded = false; - private _saveOnLoad = false; - private _savingCustomDict = false; - private _saveAgain = false; - private _win; - private _customDict = {}; + private _session = remote.getCurrentWebContents().session; constructor() { + //this._session = ; // Nobody will notice if spellcheck isn't available for a few seconds and it // takes a considerable amount of time to startup (212ms in dev mode on my 2017 MBP) const initHandler = () => { - this._win = AppEnv.getCurrentWindow(); - this._loadCustomDict(); + this._migrateFromCustomDict(); const initialLanguage = AppEnv.config.get('core.composing.spellcheckDefaultLanguage'); this._switchToLanguage(initialLanguage); @@ -44,20 +36,15 @@ class Spellchecker { } - _switchToLanguage = lang => { + _switchToLanguage = (lang: string | undefined | null) => { if (lang === null || lang === undefined || lang === '') { lang = app.getLocale() || 'en-US'; } - // Only switch to a language that is supported by the system. - // Otherwise stay at the current language. Default language is the OS language. - if (this._win.webContents.session.availableSpellCheckerLanguages.includes(lang)) { - this._win.webContents.session.setSpellCheckerLanguages([lang]) - } + this._session.setSpellCheckerLanguages([lang]); }; - _loadCustomDict = () => { - /* + _migrateFromCustomDict = () => { fs.readFile(customDictFilePath, (err, data) => { let fileData: any = data; if (err) { @@ -70,78 +57,23 @@ class Spellchecker { } } const loadedDict = JSON.parse(fileData); - this._customDict = Object.assign(loadedDict, this._customDict); - this._customDictLoaded = true; - if (this._saveOnLoad) { - this._saveCustomDict(); - this._saveOnLoad = false; - } + Object.keys(loadedDict).forEach(word => this._session.addWordToSpellCheckerDictionary(word)); + fs.unlink(customDictFilePath, () => { }); }); - */ - }; + } - _saveCustomDict = () => { - /* - // If we haven't loaded the dict yet, saving could overwrite all the things. - // Wait until the loaded dict is merged with our working copy before saving - if (this._customDictLoaded) { - // Don't perform two writes at the same time, as this results in an overlaid - // version of the data. (This may or may not happen in practice, but was - // an issue with the tests) - if (this._savingCustomDict) { - this._saveAgain = true; - } else { - this._savingCustomDict = true; - fs.writeFile(customDictFilePath, JSON.stringify(this._customDict), err => { - if (err) { - AppEnv.reportError(err); - } - this._savingCustomDict = false; - if (this._saveAgain) { - this._saveAgain = false; - this._saveCustomDict(); - } - }); - } - } else { - this._saveOnLoad = true; - } - */ - }; - - provideHintText = text => { - /* - if (!this.handler) { - return false; - } - this.handler.provideHintText(text); - */ - }; isMisspelled = (word: string) => { - - if ({}.hasOwnProperty.call(this._customDict, word)) { - return false; - } - return webFrame.isWordMisspelled(word) - }; - learnWord = word => { - /* - this._customDict[word] = ''; - this._saveCustomDict(); - */ + learnWord = (word: string) => { + // TODO: Ensure that this work. Somehow on my Ubuntu 20.12., this does not add words to the custom dict. + this._session.addWordToSpellCheckerDictionary(word); }; - unlearnWord = word => { - /* - if (word in this._customDict) { - delete this._customDict[word]; - this._saveCustomDict(); - } - */ + unlearnWord = (word: string) => { + this._session.removeWordFromSpellCheckerDictionary(word); }; appendSpellingItemsToMenu = async ({ menu, word, onCorrect, onDidLearn }) => {