From 0900a0139ebeac3f66b185c9f4271c93b498eb16 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 7 Feb 2019 20:48:57 +0100 Subject: Spellcheck language autodetection First prototype is based on slack --- src/webview/contextMenu.js | 11 +++++++++++ src/webview/recipe.js | 44 ++++++++++++++++++++++++++++++++++++++++++-- src/webview/spellchecker.js | 11 +++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/webview/contextMenu.js b/src/webview/contextMenu.js index a76c03e5a..7fadfa72b 100644 --- a/src/webview/contextMenu.js +++ b/src/webview/contextMenu.js @@ -237,6 +237,17 @@ const buildMenuTpl = (props, suggestions, isSpellcheckEnabled, defaultSpellcheck type: 'separator', visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, }, + { + id: 'automaticDetection', + label: 'Automatic language detection', + type: 'radio', + visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, + checked: spellcheckerLanguage === 'automatic', + click() { + debug('Detect spellchecker language automatically'); + ipcRenderer.sendToHost('set-service-spellchecker-language', 'automatic'); + }, + }, ...spellcheckingLanguages], }); diff --git a/src/webview/recipe.js b/src/webview/recipe.js index c718b348e..38a65276e 100644 --- a/src/webview/recipe.js +++ b/src/webview/recipe.js @@ -1,10 +1,12 @@ import { ipcRenderer } from 'electron'; import path from 'path'; import { autorun, computed, observable } from 'mobx'; +import { loadModule } from 'cld3-asm'; +import { debounce } from 'lodash'; import RecipeWebview from './lib/RecipeWebview'; -import spellchecker, { switchDict, disable as disableSpellchecker } from './spellchecker'; +import spellchecker, { switchDict, disable as disableSpellchecker, getSpellcheckerLocaleByFuzzyIdentifier } from './spellchecker'; import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode'; import contextMenu from './contextMenu'; import './notifications'; @@ -60,6 +62,39 @@ class RecipeController { ); autorun(() => this.update()); + + console.log(JSON.parse(JSON.stringify(this.settings))); + + const cldFactory = await loadModule(); + const identifier = cldFactory.create(0, 1000); + + window.addEventListener('keyup', debounce((e) => { + const elem = e.target; + + let value = ''; + if (elem.isContentEditable) { + value = elem.textContent; + } else { + // + } + + // Force a minimum length to get better detection results + if (value.length < 30) return; + + debug('Detecting language for', value); + const findResult = identifier.findLanguage(value); + + debug('Language detection result', findResult); + + if (findResult.is_reliable) { + debug('Language detected reliably, setting spellchecker language to', findResult.language); + const spellcheckerLocale = getSpellcheckerLocaleByFuzzyIdentifier(findResult.language); + debug('reported back', spellcheckerLocale); + if (spellcheckerLocale) { + switchDict(spellcheckerLocale); + } + } + }, 200)); } loadRecipeModule(event, config, recipe) { @@ -87,7 +122,12 @@ class RecipeController { if (this.settings.app.enableSpellchecking) { debug('Setting spellchecker language to', this.spellcheckerLanguage); - switchDict(this.spellcheckerLanguage); + let { spellcheckerLanguage } = this; + if (spellcheckerLanguage === 'automatic') { + debug('Found `automatic` locale, falling back to user locale until detected', this.settings.app.locale); + spellcheckerLanguage = this.settings.app.locale; + } + switchDict(spellcheckerLanguage); } else { debug('Disable spellchecker'); disableSpellchecker(); diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js index becaed449..c711382be 100644 --- a/src/webview/spellchecker.js +++ b/src/webview/spellchecker.js @@ -3,6 +3,7 @@ import { SpellCheckerProvider } from 'electron-hunspell'; import path from 'path'; import { DICTIONARY_PATH } from '../config'; +import { SPELLCHECKER_LOCALES } from '../i18n/languages'; const debug = require('debug')('Franz:spellchecker'); @@ -82,3 +83,13 @@ export function disable() { currentDict = null; } } + +export function getSpellcheckerLocaleByFuzzyIdentifier(identifier) { + const locales = Object.keys(SPELLCHECKER_LOCALES).filter(key => key.split('-')[0] === identifier); + + if (locales.length >= 1) { + return locales[0]; + } + + return null; +} -- cgit v1.2.3-54-g00ecf