diff options
author | Stefan Malzner <stefan@adlk.io> | 2019-02-07 20:48:57 +0100 |
---|---|---|
committer | Stefan Malzner <stefan@adlk.io> | 2019-02-07 20:48:57 +0100 |
commit | 0900a0139ebeac3f66b185c9f4271c93b498eb16 (patch) | |
tree | c772d7fbea7ec3fa16c0d23dd110330ed8f165b5 /src/webview | |
parent | fix(Service): Improve focus when switching services (diff) | |
download | ferdium-app-0900a0139ebeac3f66b185c9f4271c93b498eb16.tar.gz ferdium-app-0900a0139ebeac3f66b185c9f4271c93b498eb16.tar.zst ferdium-app-0900a0139ebeac3f66b185c9f4271c93b498eb16.zip |
Spellcheck language autodetection
First prototype is based on slack
Diffstat (limited to 'src/webview')
-rw-r--r-- | src/webview/contextMenu.js | 11 | ||||
-rw-r--r-- | src/webview/recipe.js | 44 | ||||
-rw-r--r-- | src/webview/spellchecker.js | 11 |
3 files changed, 64 insertions, 2 deletions
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 | |||
237 | type: 'separator', | 237 | type: 'separator', |
238 | visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, | 238 | visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, |
239 | }, | 239 | }, |
240 | { | ||
241 | id: 'automaticDetection', | ||
242 | label: 'Automatic language detection', | ||
243 | type: 'radio', | ||
244 | visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, | ||
245 | checked: spellcheckerLanguage === 'automatic', | ||
246 | click() { | ||
247 | debug('Detect spellchecker language automatically'); | ||
248 | ipcRenderer.sendToHost('set-service-spellchecker-language', 'automatic'); | ||
249 | }, | ||
250 | }, | ||
240 | ...spellcheckingLanguages], | 251 | ...spellcheckingLanguages], |
241 | }); | 252 | }); |
242 | 253 | ||
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 @@ | |||
1 | import { ipcRenderer } from 'electron'; | 1 | import { ipcRenderer } from 'electron'; |
2 | import path from 'path'; | 2 | import path from 'path'; |
3 | import { autorun, computed, observable } from 'mobx'; | 3 | import { autorun, computed, observable } from 'mobx'; |
4 | import { loadModule } from 'cld3-asm'; | ||
5 | import { debounce } from 'lodash'; | ||
4 | 6 | ||
5 | import RecipeWebview from './lib/RecipeWebview'; | 7 | import RecipeWebview from './lib/RecipeWebview'; |
6 | 8 | ||
7 | import spellchecker, { switchDict, disable as disableSpellchecker } from './spellchecker'; | 9 | import spellchecker, { switchDict, disable as disableSpellchecker, getSpellcheckerLocaleByFuzzyIdentifier } from './spellchecker'; |
8 | import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode'; | 10 | import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode'; |
9 | import contextMenu from './contextMenu'; | 11 | import contextMenu from './contextMenu'; |
10 | import './notifications'; | 12 | import './notifications'; |
@@ -60,6 +62,39 @@ class RecipeController { | |||
60 | ); | 62 | ); |
61 | 63 | ||
62 | autorun(() => this.update()); | 64 | autorun(() => this.update()); |
65 | |||
66 | console.log(JSON.parse(JSON.stringify(this.settings))); | ||
67 | |||
68 | const cldFactory = await loadModule(); | ||
69 | const identifier = cldFactory.create(0, 1000); | ||
70 | |||
71 | window.addEventListener('keyup', debounce((e) => { | ||
72 | const elem = e.target; | ||
73 | |||
74 | let value = ''; | ||
75 | if (elem.isContentEditable) { | ||
76 | value = elem.textContent; | ||
77 | } else { | ||
78 | // | ||
79 | } | ||
80 | |||
81 | // Force a minimum length to get better detection results | ||
82 | if (value.length < 30) return; | ||
83 | |||
84 | debug('Detecting language for', value); | ||
85 | const findResult = identifier.findLanguage(value); | ||
86 | |||
87 | debug('Language detection result', findResult); | ||
88 | |||
89 | if (findResult.is_reliable) { | ||
90 | debug('Language detected reliably, setting spellchecker language to', findResult.language); | ||
91 | const spellcheckerLocale = getSpellcheckerLocaleByFuzzyIdentifier(findResult.language); | ||
92 | debug('reported back', spellcheckerLocale); | ||
93 | if (spellcheckerLocale) { | ||
94 | switchDict(spellcheckerLocale); | ||
95 | } | ||
96 | } | ||
97 | }, 200)); | ||
63 | } | 98 | } |
64 | 99 | ||
65 | loadRecipeModule(event, config, recipe) { | 100 | loadRecipeModule(event, config, recipe) { |
@@ -87,7 +122,12 @@ class RecipeController { | |||
87 | 122 | ||
88 | if (this.settings.app.enableSpellchecking) { | 123 | if (this.settings.app.enableSpellchecking) { |
89 | debug('Setting spellchecker language to', this.spellcheckerLanguage); | 124 | debug('Setting spellchecker language to', this.spellcheckerLanguage); |
90 | switchDict(this.spellcheckerLanguage); | 125 | let { spellcheckerLanguage } = this; |
126 | if (spellcheckerLanguage === 'automatic') { | ||
127 | debug('Found `automatic` locale, falling back to user locale until detected', this.settings.app.locale); | ||
128 | spellcheckerLanguage = this.settings.app.locale; | ||
129 | } | ||
130 | switchDict(spellcheckerLanguage); | ||
91 | } else { | 131 | } else { |
92 | debug('Disable spellchecker'); | 132 | debug('Disable spellchecker'); |
93 | disableSpellchecker(); | 133 | 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'; | |||
3 | import path from 'path'; | 3 | import path from 'path'; |
4 | 4 | ||
5 | import { DICTIONARY_PATH } from '../config'; | 5 | import { DICTIONARY_PATH } from '../config'; |
6 | import { SPELLCHECKER_LOCALES } from '../i18n/languages'; | ||
6 | 7 | ||
7 | const debug = require('debug')('Franz:spellchecker'); | 8 | const debug = require('debug')('Franz:spellchecker'); |
8 | 9 | ||
@@ -82,3 +83,13 @@ export function disable() { | |||
82 | currentDict = null; | 83 | currentDict = null; |
83 | } | 84 | } |
84 | } | 85 | } |
86 | |||
87 | export function getSpellcheckerLocaleByFuzzyIdentifier(identifier) { | ||
88 | const locales = Object.keys(SPELLCHECKER_LOCALES).filter(key => key.split('-')[0] === identifier); | ||
89 | |||
90 | if (locales.length >= 1) { | ||
91 | return locales[0]; | ||
92 | } | ||
93 | |||
94 | return null; | ||
95 | } | ||