aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2017-12-15 14:40:10 +0100
committerLibravatar GitHub <noreply@github.com>2017-12-15 14:40:10 +0100
commita8917ee619c972ea587446e4dde2ae3cacafb3a7 (patch)
tree3f852395fafab2897f78303c77432479b1ab99a2 /src
parentremove unecessary console logs (diff)
parentfix(Spell checker): Fixed issues with spell checker (diff)
downloadferdium-app-a8917ee619c972ea587446e4dde2ae3cacafb3a7.tar.gz
ferdium-app-a8917ee619c972ea587446e4dde2ae3cacafb3a7.tar.zst
ferdium-app-a8917ee619c972ea587446e4dde2ae3cacafb3a7.zip
Merge pull request #458 from meetfranz/feature/spellchecker-improvements
[PR] spellchecker improvements
Diffstat (limited to 'src')
-rw-r--r--src/api/server/LocalApi.js4
-rw-r--r--src/components/settings/settings/EditSettingsForm.js5
-rw-r--r--src/models/Settings.js6
-rw-r--r--src/stores/SettingsStore.js2
-rw-r--r--src/webview/plugin.js28
-rw-r--r--src/webview/spellchecker.js65
6 files changed, 71 insertions, 39 deletions
diff --git a/src/api/server/LocalApi.js b/src/api/server/LocalApi.js
index eba236f16..79ac6e12f 100644
--- a/src/api/server/LocalApi.js
+++ b/src/api/server/LocalApi.js
@@ -1,5 +1,3 @@
1import SettingsModel from '../../models/Settings';
2
3export default class LocalApi { 1export default class LocalApi {
4 // App 2 // App
5 async updateAppSettings(data) { 3 async updateAppSettings(data) {
@@ -15,7 +13,7 @@ export default class LocalApi {
15 async getAppSettings() { 13 async getAppSettings() {
16 const settingsString = localStorage.getItem('app'); 14 const settingsString = localStorage.getItem('app');
17 try { 15 try {
18 const settings = new SettingsModel(JSON.parse(settingsString) || {}); 16 const settings = JSON.parse(settingsString) || {};
19 console.debug('LocalApi::getAppSettings resolves', settings); 17 console.debug('LocalApi::getAppSettings resolves', settings);
20 18
21 return settings; 19 return settings;
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index 878e46d6d..ff398aa33 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -64,10 +64,6 @@ const messages = defineMessages({
64 id: 'settings.app.currentVersion', 64 id: 'settings.app.currentVersion',
65 defaultMessage: '!!!Current version:', 65 defaultMessage: '!!!Current version:',
66 }, 66 },
67 restartRequired: {
68 id: 'settings.app.restartRequired',
69 defaultMessage: '!!!Changes require restart',
70 },
71}); 67});
72 68
73@observer 69@observer
@@ -158,7 +154,6 @@ export default class EditSettingsForm extends Component {
158 {/* Advanced */} 154 {/* Advanced */}
159 <h2 id="advanced">{intl.formatMessage(messages.headlineAdvanced)}</h2> 155 <h2 id="advanced">{intl.formatMessage(messages.headlineAdvanced)}</h2>
160 <Toggle field={form.$('enableSpellchecking')} /> 156 <Toggle field={form.$('enableSpellchecking')} />
161 <p className="settings__help">{intl.formatMessage(messages.restartRequired)}</p>
162 {/* <Select field={form.$('spellcheckingLanguage')} /> */} 157 {/* <Select field={form.$('spellcheckingLanguage')} /> */}
163 158
164 {/* Updates */} 159 {/* Updates */}
diff --git a/src/models/Settings.js b/src/models/Settings.js
index 35bfe0d05..ca44da258 100644
--- a/src/models/Settings.js
+++ b/src/models/Settings.js
@@ -1,4 +1,4 @@
1import { observable } from 'mobx'; 1import { observable, extendObservable } from 'mobx';
2import { DEFAULT_APP_SETTINGS } from '../config'; 2import { DEFAULT_APP_SETTINGS } from '../config';
3 3
4export default class Settings { 4export default class Settings {
@@ -17,4 +17,8 @@ export default class Settings {
17 constructor(data) { 17 constructor(data) {
18 Object.assign(this, data); 18 Object.assign(this, data);
19 } 19 }
20
21 update(data) {
22 extendObservable(this, data);
23 }
20} 24}
diff --git a/src/stores/SettingsStore.js b/src/stores/SettingsStore.js
index 33473f16d..da99a720f 100644
--- a/src/stores/SettingsStore.js
+++ b/src/stores/SettingsStore.js
@@ -26,7 +26,7 @@ export default class SettingsStore extends Store {
26 } 26 }
27 27
28 @computed get all() { 28 @computed get all() {
29 return this.allSettingsRequest.result || new SettingsModel(); 29 return new SettingsModel(this.allSettingsRequest.result);
30 } 30 }
31 31
32 @action async _update({ settings }) { 32 @action async _update({ settings }) {
diff --git a/src/webview/plugin.js b/src/webview/plugin.js
index c877132b1..cf38169d3 100644
--- a/src/webview/plugin.js
+++ b/src/webview/plugin.js
@@ -1,14 +1,14 @@
1import { ipcRenderer } from 'electron'; 1import { ipcRenderer } from 'electron';
2import { ContextMenuListener, ContextMenuBuilder } from 'electron-spellchecker';
2import path from 'path'; 3import path from 'path';
3 4
5import { isDevMode } from '../environment';
4import RecipeWebview from './lib/RecipeWebview'; 6import RecipeWebview from './lib/RecipeWebview';
5 7
6import Spellchecker from './spellchecker.js'; 8import Spellchecker from './spellchecker.js';
7import './notifications.js'; 9import './notifications.js';
8import './ime.js'; 10import './ime.js';
9 11
10const spellchecker = new Spellchecker();
11
12ipcRenderer.on('initializeRecipe', (e, data) => { 12ipcRenderer.on('initializeRecipe', (e, data) => {
13 const modulePath = path.join(data.recipe.path, 'webview.js'); 13 const modulePath = path.join(data.recipe.path, 'webview.js');
14 // Delete module from cache 14 // Delete module from cache
@@ -21,20 +21,22 @@ ipcRenderer.on('initializeRecipe', (e, data) => {
21 } 21 }
22}); 22});
23 23
24const spellchecker = new Spellchecker();
25spellchecker.initialize();
26
27const contextMenuBuilder = new ContextMenuBuilder(spellchecker.handler, null, isDevMode);
28
29new ContextMenuListener((info) => { // eslint-disable-line
30 contextMenuBuilder.showPopupMenu(info);
31});
32
24ipcRenderer.on('settings-update', (e, data) => { 33ipcRenderer.on('settings-update', (e, data) => {
25 if (data.enableSpellchecking) { 34 console.log('settings-update', data);
26 if (!spellchecker.isEnabled) { 35 spellchecker.toggleSpellchecker(data.enableSpellchecking);
27 spellchecker.enable();
28
29 // TODO: this does not work yet, needs more testing
30 // if (data.spellcheckingLanguage !== 'auto') {
31 // console.log('set spellchecking language to', data.spellcheckingLanguage);
32 // spellchecker.switchLanguage(data.spellcheckingLanguage);
33 // }
34 }
35 }
36}); 36});
37 37
38// initSpellche
39
38document.addEventListener('DOMContentLoaded', () => { 40document.addEventListener('DOMContentLoaded', () => {
39 ipcRenderer.sendToHost('hello'); 41 ipcRenderer.sendToHost('hello');
40}, false); 42}, false);
diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js
index 5beb77e03..a504a4039 100644
--- a/src/webview/spellchecker.js
+++ b/src/webview/spellchecker.js
@@ -1,30 +1,63 @@
1import { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } from 'electron-spellchecker'; 1import { SpellCheckHandler } from 'electron-spellchecker';
2 2
3import { isMac } from '../environment'; 3import { isMac } from '../environment';
4 4
5export default class Spellchecker { 5export default class Spellchecker {
6 isEnabled = false; 6 isInitialized = false;
7 spellchecker = null; 7 handler = null;
8 initRetries = 0;
9 DOMCheckInterval = null;
10
11 get inputs() {
12 return document.querySelectorAll('input[type="text"], [contenteditable="true"], textarea');
13 }
14
15 initialize() {
16 this.handler = new SpellCheckHandler();
8 17
9 enable() {
10 this.spellchecker = new SpellCheckHandler();
11 if (!isMac) { 18 if (!isMac) {
12 this.spellchecker.attachToInput(); 19 this.attach();
13 this.spellchecker.switchLanguage(navigator.language); 20 } else {
21 this.isInitialized = true;
22 }
23 }
24
25 attach() {
26 let initFailed = false;
27
28 if (this.initRetries > 3) {
29 console.error('Could not initialize spellchecker');
30 return;
14 } 31 }
15 32
16 const contextMenuBuilder = new ContextMenuBuilder(this.spellchecker); 33 try {
34 this.handler.attachToInput();
35 this.handler.switchLanguage(navigator.language);
36 } catch (err) {
37 initFailed = true;
38 this.initRetries = +1;
39 setTimeout(() => { this.attach(); console.warn('Spellchecker init failed, trying again in 5s'); }, 5000);
40 }
17 41
18 new ContextMenuListener((info) => { // eslint-disable-line 42 if (!initFailed) {
19 contextMenuBuilder.showPopupMenu(info); 43 this.isInitialized = true;
44 }
45 }
46
47 toggleSpellchecker(enable = false) {
48 this.inputs.forEach((input) => {
49 input.setAttribute('spellcheck', enable);
20 }); 50 });
51
52 this.intervalHandler(enable);
21 } 53 }
22 54
23 // TODO: this does not work yet, needs more testing 55 intervalHandler(enable) {
24 // switchLanguage(language) { 56 clearInterval(this.DOMCheckInterval);
25 // if (language !== 'auto') { 57
26 // this.spellchecker.switchLanguage(language); 58 if (enable) {
27 // } 59 this.DOMCheckInterval = setInterval(() => this.toggleSpellchecker(enable), 30000);
28 // } 60 }
61 }
29} 62}
30 63