aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2019-02-07 20:48:57 +0100
committerLibravatar Stefan Malzner <stefan@adlk.io>2019-02-07 20:48:57 +0100
commit0900a0139ebeac3f66b185c9f4271c93b498eb16 (patch)
treec772d7fbea7ec3fa16c0d23dd110330ed8f165b5 /src
parentfix(Service): Improve focus when switching services (diff)
downloadferdium-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')
-rw-r--r--src/webview/contextMenu.js11
-rw-r--r--src/webview/recipe.js44
-rw-r--r--src/webview/spellchecker.js11
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 @@
1import { ipcRenderer } from 'electron'; 1import { ipcRenderer } from 'electron';
2import path from 'path'; 2import path from 'path';
3import { autorun, computed, observable } from 'mobx'; 3import { autorun, computed, observable } from 'mobx';
4import { loadModule } from 'cld3-asm';
5import { debounce } from 'lodash';
4 6
5import RecipeWebview from './lib/RecipeWebview'; 7import RecipeWebview from './lib/RecipeWebview';
6 8
7import spellchecker, { switchDict, disable as disableSpellchecker } from './spellchecker'; 9import spellchecker, { switchDict, disable as disableSpellchecker, getSpellcheckerLocaleByFuzzyIdentifier } from './spellchecker';
8import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode'; 10import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode';
9import contextMenu from './contextMenu'; 11import contextMenu from './contextMenu';
10import './notifications'; 12import './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';
3import path from 'path'; 3import path from 'path';
4 4
5import { DICTIONARY_PATH } from '../config'; 5import { DICTIONARY_PATH } from '../config';
6import { SPELLCHECKER_LOCALES } from '../i18n/languages';
6 7
7const debug = require('debug')('Franz:spellchecker'); 8const 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
87export 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}