diff options
author | 2019-02-08 11:32:20 +0100 | |
---|---|---|
committer | 2019-02-08 11:32:20 +0100 | |
commit | e2437f27ccd1c7646accc75b819fff3295c7a2e2 (patch) | |
tree | b291106a314e66fe77f11bb9026e12c1bb5839b0 | |
parent | Remove debugging output (diff) | |
download | ferdium-app-e2437f27ccd1c7646accc75b819fff3295c7a2e2.tar.gz ferdium-app-e2437f27ccd1c7646accc75b819fff3295c7a2e2.tar.zst ferdium-app-e2437f27ccd1c7646accc75b819fff3295c7a2e2.zip |
feat(Spell checking): Add option to automatically detect language
-rw-r--r-- | src/components/settings/services/EditServiceForm.js | 10 | ||||
-rw-r--r-- | src/containers/settings/EditServiceScreen.js | 40 | ||||
-rw-r--r-- | src/containers/settings/EditSettingsScreen.js | 16 | ||||
-rw-r--r-- | src/features/spellchecker/index.js | 8 | ||||
-rw-r--r-- | src/helpers/i18n-helpers.js | 27 | ||||
-rw-r--r-- | src/i18n/globalMessages.js | 16 | ||||
-rw-r--r-- | src/i18n/locales/en-US.json | 4 | ||||
-rw-r--r-- | src/webview/contextMenu.js | 11 | ||||
-rw-r--r-- | src/webview/recipe.js | 76 |
9 files changed, 132 insertions, 76 deletions
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index 468d85c45..21616b5de 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -128,7 +128,8 @@ export default @observer class EditServiceForm extends Component { | |||
128 | isSaving: PropTypes.bool.isRequired, | 128 | isSaving: PropTypes.bool.isRequired, |
129 | isDeleting: PropTypes.bool.isRequired, | 129 | isDeleting: PropTypes.bool.isRequired, |
130 | isProxyFeatureEnabled: PropTypes.bool.isRequired, | 130 | isProxyFeatureEnabled: PropTypes.bool.isRequired, |
131 | isProxyFeaturePremiumFeature: PropTypes.bool.isRequired, | 131 | isProxyPremiumFeature: PropTypes.bool.isRequired, |
132 | isSpellcheckerPremiumFeature: PropTypes.bool.isRequired, | ||
132 | }; | 133 | }; |
133 | 134 | ||
134 | static defaultProps = { | 135 | static defaultProps = { |
@@ -191,7 +192,8 @@ export default @observer class EditServiceForm extends Component { | |||
191 | isDeleting, | 192 | isDeleting, |
192 | onDelete, | 193 | onDelete, |
193 | isProxyFeatureEnabled, | 194 | isProxyFeatureEnabled, |
194 | isProxyFeaturePremiumFeature, | 195 | isProxyPremiumFeature, |
196 | isSpellcheckerPremiumFeature, | ||
195 | } = this.props; | 197 | } = this.props; |
196 | const { intl } = this.context; | 198 | const { intl } = this.context; |
197 | 199 | ||
@@ -339,14 +341,14 @@ export default @observer class EditServiceForm extends Component { | |||
339 | </div> | 341 | </div> |
340 | </div> | 342 | </div> |
341 | 343 | ||
342 | <PremiumFeatureContainer> | 344 | <PremiumFeatureContainer condition={isSpellcheckerPremiumFeature}> |
343 | <div className="settings__settings-group"> | 345 | <div className="settings__settings-group"> |
344 | <Select field={form.$('spellcheckerLanguage')} /> | 346 | <Select field={form.$('spellcheckerLanguage')} /> |
345 | </div> | 347 | </div> |
346 | </PremiumFeatureContainer> | 348 | </PremiumFeatureContainer> |
347 | 349 | ||
348 | {isProxyFeatureEnabled && ( | 350 | {isProxyFeatureEnabled && ( |
349 | <PremiumFeatureContainer condition={isProxyFeaturePremiumFeature}> | 351 | <PremiumFeatureContainer condition={isProxyPremiumFeature}> |
350 | <div className="settings__settings-group"> | 352 | <div className="settings__settings-group"> |
351 | <h3> | 353 | <h3> |
352 | {intl.formatMessage(messages.headlineProxy)} | 354 | {intl.formatMessage(messages.headlineProxy)} |
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index b46908344..d08f0a52e 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js | |||
@@ -19,9 +19,12 @@ import { required, url, oneRequired } from '../../helpers/validation-helpers'; | |||
19 | import { getSelectOptions } from '../../helpers/i18n-helpers'; | 19 | import { getSelectOptions } from '../../helpers/i18n-helpers'; |
20 | 20 | ||
21 | import { config as proxyFeature } from '../../features/serviceProxy'; | 21 | import { config as proxyFeature } from '../../features/serviceProxy'; |
22 | import { config as spellcheckerFeature } from '../../features/spellchecker'; | ||
22 | 23 | ||
23 | import { SPELLCHECKER_LOCALES } from '../../i18n/languages'; | 24 | import { SPELLCHECKER_LOCALES } from '../../i18n/languages'; |
24 | 25 | ||
26 | import globalMessages from '../../i18n/globalMessages'; | ||
27 | |||
25 | const messages = defineMessages({ | 28 | const messages = defineMessages({ |
26 | name: { | 29 | name: { |
27 | id: 'settings.service.form.name', | 30 | id: 'settings.service.form.name', |
@@ -83,14 +86,6 @@ const messages = defineMessages({ | |||
83 | id: 'settings.service.form.proxy.password', | 86 | id: 'settings.service.form.proxy.password', |
84 | defaultMessage: '!!!Password', | 87 | defaultMessage: '!!!Password', |
85 | }, | 88 | }, |
86 | spellcheckerLanguage: { | ||
87 | id: 'settings.service.form.spellcheckerLanguage', | ||
88 | defaultMessage: '!!!Spell checking Language', | ||
89 | }, | ||
90 | spellcheckerSystemDefault: { | ||
91 | id: 'settings.service.form.spellcheckerLanguage.default', | ||
92 | defaultMessage: '!!!Use System Default ({default})', | ||
93 | }, | ||
94 | }); | 89 | }); |
95 | 90 | ||
96 | export default @inject('stores', 'actions') @observer class EditServiceScreen extends Component { | 91 | export default @inject('stores', 'actions') @observer class EditServiceScreen extends Component { |
@@ -118,12 +113,26 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
118 | } | 113 | } |
119 | 114 | ||
120 | prepareForm(recipe, service, proxy) { | 115 | prepareForm(recipe, service, proxy) { |
116 | const { | ||
117 | intl, | ||
118 | } = this.context; | ||
119 | |||
120 | const { | ||
121 | stores, | ||
122 | } = this.props; | ||
123 | |||
124 | let defaultSpellcheckerLanguage = SPELLCHECKER_LOCALES[stores.settings.app.spellcheckerLanguage]; | ||
125 | |||
126 | if (stores.settings.app.spellcheckerLanguage === 'automatic') { | ||
127 | defaultSpellcheckerLanguage = intl.formatMessage(globalMessages.spellcheckerAutomaticDetectionShort); | ||
128 | } | ||
129 | |||
121 | const spellcheckerLanguage = getSelectOptions({ | 130 | const spellcheckerLanguage = getSelectOptions({ |
122 | locales: SPELLCHECKER_LOCALES, | 131 | locales: SPELLCHECKER_LOCALES, |
123 | resetToDefaultText: this.context.intl.formatMessage(messages.spellcheckerSystemDefault, { default: SPELLCHECKER_LOCALES[this.props.stores.settings.app.spellcheckerLanguage] }), | 132 | resetToDefaultText: intl.formatMessage(globalMessages.spellcheckerSystemDefault, { default: defaultSpellcheckerLanguage }), |
133 | automaticDetectionText: stores.settings.app.spellcheckerLanguage !== 'automatic' ? intl.formatMessage(globalMessages.spellcheckerAutomaticDetection) : '', | ||
124 | }); | 134 | }); |
125 | 135 | ||
126 | const { intl } = this.context; | ||
127 | const config = { | 136 | const config = { |
128 | fields: { | 137 | fields: { |
129 | name: { | 138 | name: { |
@@ -160,13 +169,13 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
160 | isDarkModeEnabled: { | 169 | isDarkModeEnabled: { |
161 | label: intl.formatMessage(messages.enableDarkMode), | 170 | label: intl.formatMessage(messages.enableDarkMode), |
162 | value: service.isDarkModeEnabled, | 171 | value: service.isDarkModeEnabled, |
163 | default: this.props.stores.settings.app.darkMode, | 172 | default: stores.settings.app.darkMode, |
164 | }, | 173 | }, |
165 | spellcheckerLanguage: { | 174 | spellcheckerLanguage: { |
166 | label: intl.formatMessage(messages.spellcheckerLanguage), | 175 | label: intl.formatMessage(globalMessages.spellcheckerLanguage), |
167 | value: service.spellcheckerLanguage, | 176 | value: service.spellcheckerLanguage, |
168 | options: spellcheckerLanguage, | 177 | options: spellcheckerLanguage, |
169 | disabled: !this.props.stores.settings.app.enableSpellchecking, | 178 | disabled: !stores.settings.app.enableSpellchecking, |
170 | }, | 179 | }, |
171 | }, | 180 | }, |
172 | }; | 181 | }; |
@@ -220,7 +229,7 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
220 | } | 229 | } |
221 | 230 | ||
222 | if (proxy.isEnabled) { | 231 | if (proxy.isEnabled) { |
223 | const serviceProxyConfig = this.props.stores.settings.proxy[service.id] || {}; | 232 | const serviceProxyConfig = stores.settings.proxy[service.id] || {}; |
224 | 233 | ||
225 | Object.assign(config.fields, { | 234 | Object.assign(config.fields, { |
226 | proxy: { | 235 | proxy: { |
@@ -326,7 +335,8 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
326 | onSubmit={d => this.onSubmit(d)} | 335 | onSubmit={d => this.onSubmit(d)} |
327 | onDelete={() => this.deleteService()} | 336 | onDelete={() => this.deleteService()} |
328 | isProxyFeatureEnabled={proxyFeature.isEnabled} | 337 | isProxyFeatureEnabled={proxyFeature.isEnabled} |
329 | isProxyFeaturePremiumFeature={proxyFeature.isPremium} | 338 | isProxyPremiumFeature={proxyFeature.isPremium} |
339 | isSpellcheckerPremiumFeature={spellcheckerFeature.isPremium} | ||
330 | /> | 340 | /> |
331 | </ErrorBoundary> | 341 | </ErrorBoundary> |
332 | ); | 342 | ); |
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index f1706a721..992c49b09 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js | |||
@@ -14,10 +14,11 @@ import { config as spellcheckerConfig } from '../../features/spellchecker'; | |||
14 | 14 | ||
15 | import { getSelectOptions } from '../../helpers/i18n-helpers'; | 15 | import { getSelectOptions } from '../../helpers/i18n-helpers'; |
16 | 16 | ||
17 | |||
18 | import EditSettingsForm from '../../components/settings/settings/EditSettingsForm'; | 17 | import EditSettingsForm from '../../components/settings/settings/EditSettingsForm'; |
19 | import ErrorBoundary from '../../components/util/ErrorBoundary'; | 18 | import ErrorBoundary from '../../components/util/ErrorBoundary'; |
20 | 19 | ||
20 | import globalMessages from '../../i18n/globalMessages'; | ||
21 | |||
21 | const messages = defineMessages({ | 22 | const messages = defineMessages({ |
22 | autoLaunchOnStart: { | 23 | autoLaunchOnStart: { |
23 | id: 'settings.app.form.autoLaunchOnStart', | 24 | id: 'settings.app.form.autoLaunchOnStart', |
@@ -63,10 +64,6 @@ const messages = defineMessages({ | |||
63 | id: 'settings.app.form.enableGPUAcceleration', | 64 | id: 'settings.app.form.enableGPUAcceleration', |
64 | defaultMessage: '!!!Enable GPU Acceleration', | 65 | defaultMessage: '!!!Enable GPU Acceleration', |
65 | }, | 66 | }, |
66 | spellcheckerLanguage: { | ||
67 | id: 'settings.app.form.spellcheckerLanguage', | ||
68 | defaultMessage: '!!!Language for spell checking', | ||
69 | }, | ||
70 | beta: { | 67 | beta: { |
71 | id: 'settings.app.form.beta', | 68 | id: 'settings.app.form.beta', |
72 | defaultMessage: '!!!Include beta versions', | 69 | defaultMessage: '!!!Include beta versions', |
@@ -125,6 +122,7 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
125 | 122 | ||
126 | const spellcheckingLanguages = getSelectOptions({ | 123 | const spellcheckingLanguages = getSelectOptions({ |
127 | locales: SPELLCHECKER_LOCALES, | 124 | locales: SPELLCHECKER_LOCALES, |
125 | automaticDetectionText: this.context.intl.formatMessage(globalMessages.spellcheckerAutomaticDetection), | ||
128 | }); | 126 | }); |
129 | 127 | ||
130 | const config = { | 128 | const config = { |
@@ -166,11 +164,11 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
166 | }, | 164 | }, |
167 | enableSpellchecking: { | 165 | enableSpellchecking: { |
168 | label: intl.formatMessage(messages.enableSpellchecking), | 166 | label: intl.formatMessage(messages.enableSpellchecking), |
169 | value: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremiumFeature ? false : settings.all.app.enableSpellchecking, | 167 | value: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremium ? false : settings.all.app.enableSpellchecking, |
170 | default: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremiumFeature ? false : DEFAULT_APP_SETTINGS.enableSpellchecking, | 168 | default: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremium ? false : DEFAULT_APP_SETTINGS.enableSpellchecking, |
171 | }, | 169 | }, |
172 | spellcheckerLanguage: { | 170 | spellcheckerLanguage: { |
173 | label: intl.formatMessage(messages.spellcheckerLanguage), | 171 | label: intl.formatMessage(globalMessages.spellcheckerLanguage), |
174 | value: settings.all.app.spellcheckerLanguage, | 172 | value: settings.all.app.spellcheckerLanguage, |
175 | options: spellcheckingLanguages, | 173 | options: spellcheckingLanguages, |
176 | default: DEFAULT_APP_SETTINGS.spellcheckerLanguage, | 174 | default: DEFAULT_APP_SETTINGS.spellcheckerLanguage, |
@@ -230,7 +228,7 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
230 | cacheSize={cacheSize} | 228 | cacheSize={cacheSize} |
231 | isClearingAllCache={isClearingAllCache} | 229 | isClearingAllCache={isClearingAllCache} |
232 | onClearAllCache={clearAllCache} | 230 | onClearAllCache={clearAllCache} |
233 | isSpellcheckerPremiumFeature={spellcheckerConfig.isPremiumFeature} | 231 | isSpellcheckerPremiumFeature={spellcheckerConfig.isPremium} |
234 | /> | 232 | /> |
235 | </ErrorBoundary> | 233 | </ErrorBoundary> |
236 | ); | 234 | ); |
diff --git a/src/features/spellchecker/index.js b/src/features/spellchecker/index.js index 63506103c..94883ad17 100644 --- a/src/features/spellchecker/index.js +++ b/src/features/spellchecker/index.js | |||
@@ -5,7 +5,7 @@ import { DEFAULT_FEATURES_CONFIG } from '../../config'; | |||
5 | const debug = require('debug')('Franz:feature:spellchecker'); | 5 | const debug = require('debug')('Franz:feature:spellchecker'); |
6 | 6 | ||
7 | export const config = observable({ | 7 | export const config = observable({ |
8 | isPremiumFeature: DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature, | 8 | isPremium: DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature, |
9 | }); | 9 | }); |
10 | 10 | ||
11 | export default function init(stores) { | 11 | export default function init(stores) { |
@@ -14,9 +14,11 @@ export default function init(stores) { | |||
14 | autorun(() => { | 14 | autorun(() => { |
15 | const { isSpellcheckerPremiumFeature } = stores.features.features; | 15 | const { isSpellcheckerPremiumFeature } = stores.features.features; |
16 | 16 | ||
17 | config.isPremiumFeature = isSpellcheckerPremiumFeature !== undefined ? isSpellcheckerPremiumFeature : DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature; | 17 | console.log('isSpellcheckerPremiumFeature', isSpellcheckerPremiumFeature); |
18 | 18 | ||
19 | if (!stores.user.data.isPremium && config.isPremiumFeature && stores.settings.app.enableSpellchecking) { | 19 | config.isPremium = isSpellcheckerPremiumFeature !== undefined ? isSpellcheckerPremiumFeature : DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature; |
20 | |||
21 | if (!stores.user.data.isPremium && config.isPremium && stores.settings.app.enableSpellchecking) { | ||
20 | debug('Override settings.spellcheckerEnabled flag to false'); | 22 | debug('Override settings.spellcheckerEnabled flag to false'); |
21 | 23 | ||
22 | Object.assign(stores.settings.app, { | 24 | Object.assign(stores.settings.app, { |
diff --git a/src/helpers/i18n-helpers.js b/src/helpers/i18n-helpers.js index 091b86b06..84146dd8c 100644 --- a/src/helpers/i18n-helpers.js +++ b/src/helpers/i18n-helpers.js | |||
@@ -28,22 +28,33 @@ export function getLocale({ | |||
28 | return localeStr; | 28 | return localeStr; |
29 | } | 29 | } |
30 | 30 | ||
31 | export function getSelectOptions({ locales, resetToDefaultText = '' }) { | 31 | export function getSelectOptions({ locales, resetToDefaultText = '', automaticDetectionText = '' }) { |
32 | let options = []; | 32 | const options = []; |
33 | 33 | ||
34 | if (resetToDefaultText) { | 34 | if (resetToDefaultText) { |
35 | options = [ | 35 | options.push( |
36 | { | 36 | { |
37 | value: '', | 37 | value: '', |
38 | label: resetToDefaultText, | 38 | label: resetToDefaultText, |
39 | }, { | ||
40 | value: '───', | ||
41 | label: '───', | ||
42 | disabled: true, | ||
43 | }, | 39 | }, |
44 | ]; | 40 | ); |
45 | } | 41 | } |
46 | 42 | ||
43 | if (automaticDetectionText) { | ||
44 | options.push( | ||
45 | { | ||
46 | value: 'automatic', | ||
47 | label: automaticDetectionText, | ||
48 | }, | ||
49 | ); | ||
50 | } | ||
51 | |||
52 | options.push({ | ||
53 | value: '───', | ||
54 | label: '───', | ||
55 | disabled: true, | ||
56 | }); | ||
57 | |||
47 | Object.keys(locales).sort(Intl.Collator().compare).forEach((key) => { | 58 | Object.keys(locales).sort(Intl.Collator().compare).forEach((key) => { |
48 | options.push({ | 59 | options.push({ |
49 | value: key, | 60 | value: key, |
diff --git a/src/i18n/globalMessages.js b/src/i18n/globalMessages.js index 2c724ff6f..7b1618602 100644 --- a/src/i18n/globalMessages.js +++ b/src/i18n/globalMessages.js | |||
@@ -13,4 +13,20 @@ export default defineMessages({ | |||
13 | id: 'global.notConnectedToTheInternet', | 13 | id: 'global.notConnectedToTheInternet', |
14 | defaultMessage: '!!!You are not connected to the internet.', | 14 | defaultMessage: '!!!You are not connected to the internet.', |
15 | }, | 15 | }, |
16 | spellcheckerLanguage: { | ||
17 | id: 'global.spellchecking.language', | ||
18 | defaultMessage: '!!!Spell checking language', | ||
19 | }, | ||
20 | spellcheckerSystemDefault: { | ||
21 | id: 'global.spellchecker.useDefault', | ||
22 | defaultMessage: '!!!Use System Default ({default})', | ||
23 | }, | ||
24 | spellcheckerAutomaticDetection: { | ||
25 | id: 'global.spellchecking.autodetect', | ||
26 | defaultMessage: '!!!Detect language automatically', | ||
27 | }, | ||
28 | spellcheckerAutomaticDetectionShort: { | ||
29 | id: 'global.spellchecking.autodetect.short', | ||
30 | defaultMessage: '!!!Automatic', | ||
31 | }, | ||
16 | }); | 32 | }); |
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 99df6a0ca..4e0c5575d 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -1,6 +1,10 @@ | |||
1 | { | 1 | { |
2 | "global.api.unhealthy": "Can't connect to Franz online services", | 2 | "global.api.unhealthy": "Can't connect to Franz online services", |
3 | "global.notConnectedToTheInternet": "You are not connected to the internet.", | 3 | "global.notConnectedToTheInternet": "You are not connected to the internet.", |
4 | "global.spellchecking.language": "Spell checking language", | ||
5 | "global.spellchecker.useDefault": "Use System Default ({default})", | ||
6 | "global.spellchecking.autodetect": "Detect language automatically", | ||
7 | "global.spellchecking.autodetect.short": "Automatic", | ||
4 | "welcome.signupButton": "Create a free account", | 8 | "welcome.signupButton": "Create a free account", |
5 | "welcome.loginButton": "Login to your account", | 9 | "welcome.loginButton": "Login to your account", |
6 | "welcome.slogan": "Messaging that works for you", | 10 | "welcome.slogan": "Messaging that works for you", |
diff --git a/src/webview/contextMenu.js b/src/webview/contextMenu.js index 75915851d..afb1d8912 100644 --- a/src/webview/contextMenu.js +++ b/src/webview/contextMenu.js | |||
@@ -232,20 +232,19 @@ const buildMenuTpl = (props, suggestions, isSpellcheckEnabled, defaultSpellcheck | |||
232 | }, | 232 | }, |
233 | }, | 233 | }, |
234 | { | 234 | { |
235 | type: 'separator', | ||
236 | visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, | ||
237 | }, | ||
238 | { | ||
239 | id: 'automaticDetection', | 235 | id: 'automaticDetection', |
240 | label: 'Automatic language detection', | 236 | label: 'Automatic language detection', |
241 | type: 'radio', | 237 | type: 'radio', |
242 | visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, | ||
243 | checked: spellcheckerLanguage === 'automatic', | 238 | checked: spellcheckerLanguage === 'automatic', |
244 | click() { | 239 | click() { |
245 | debug('Detect spellchecker language automatically'); | 240 | debug('Detect language automatically'); |
246 | ipcRenderer.sendToHost('set-service-spellchecker-language', 'automatic'); | 241 | ipcRenderer.sendToHost('set-service-spellchecker-language', 'automatic'); |
247 | }, | 242 | }, |
248 | }, | 243 | }, |
244 | { | ||
245 | type: 'separator', | ||
246 | visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, | ||
247 | }, | ||
249 | ...spellcheckingLanguages], | 248 | ...spellcheckingLanguages], |
250 | }); | 249 | }); |
251 | 250 | ||
diff --git a/src/webview/recipe.js b/src/webview/recipe.js index fa107ba1a..1e5d74b1f 100644 --- a/src/webview/recipe.js +++ b/src/webview/recipe.js | |||
@@ -42,6 +42,8 @@ class RecipeController { | |||
42 | return this.settings.service.spellcheckerLanguage || this.settings.app.spellcheckerLanguage; | 42 | return this.settings.service.spellcheckerLanguage || this.settings.app.spellcheckerLanguage; |
43 | } | 43 | } |
44 | 44 | ||
45 | cldIdentifier = null; | ||
46 | |||
45 | async initialize() { | 47 | async initialize() { |
46 | Object.keys(this.ipcEvents).forEach((channel) => { | 48 | Object.keys(this.ipcEvents).forEach((channel) => { |
47 | ipcRenderer.on(channel, (...args) => { | 49 | ipcRenderer.on(channel, (...args) => { |
@@ -62,37 +64,6 @@ class RecipeController { | |||
62 | ); | 64 | ); |
63 | 65 | ||
64 | autorun(() => this.update()); | 66 | autorun(() => this.update()); |
65 | |||
66 | const cldFactory = await loadModule(); | ||
67 | const identifier = cldFactory.create(0, 1000); | ||
68 | |||
69 | window.addEventListener('keyup', debounce((e) => { | ||
70 | const elem = e.target; | ||
71 | |||
72 | let value = ''; | ||
73 | if (elem.isContentEditable) { | ||
74 | value = elem.textContent; | ||
75 | } else { | ||
76 | // | ||
77 | } | ||
78 | |||
79 | // Force a minimum length to get better detection results | ||
80 | if (value.length < 40) return; | ||
81 | |||
82 | debug('Detecting language for', value); | ||
83 | const findResult = identifier.findLanguage(value); | ||
84 | |||
85 | debug('Language detection result', findResult); | ||
86 | |||
87 | if (findResult.is_reliable) { | ||
88 | debug('Language detected reliably, setting spellchecker language to', findResult.language); | ||
89 | const spellcheckerLocale = getSpellcheckerLocaleByFuzzyIdentifier(findResult.language); | ||
90 | debug('reported back', spellcheckerLocale); | ||
91 | if (spellcheckerLocale) { | ||
92 | switchDict(spellcheckerLocale); | ||
93 | } | ||
94 | } | ||
95 | }, 200)); | ||
96 | } | 67 | } |
97 | 68 | ||
98 | loadRecipeModule(event, config, recipe) { | 69 | loadRecipeModule(event, config, recipe) { |
@@ -122,13 +93,20 @@ class RecipeController { | |||
122 | debug('Setting spellchecker language to', this.spellcheckerLanguage); | 93 | debug('Setting spellchecker language to', this.spellcheckerLanguage); |
123 | let { spellcheckerLanguage } = this; | 94 | let { spellcheckerLanguage } = this; |
124 | if (spellcheckerLanguage === 'automatic') { | 95 | if (spellcheckerLanguage === 'automatic') { |
96 | this.automaticLanguageDetection(); | ||
125 | debug('Found `automatic` locale, falling back to user locale until detected', this.settings.app.locale); | 97 | debug('Found `automatic` locale, falling back to user locale until detected', this.settings.app.locale); |
126 | spellcheckerLanguage = this.settings.app.locale; | 98 | spellcheckerLanguage = this.settings.app.locale; |
99 | } else if (this.cldIdentifier) { | ||
100 | this.cldIdentifier.destroy(); | ||
127 | } | 101 | } |
128 | switchDict(spellcheckerLanguage); | 102 | switchDict(spellcheckerLanguage); |
129 | } else { | 103 | } else { |
130 | debug('Disable spellchecker'); | 104 | debug('Disable spellchecker'); |
131 | disableSpellchecker(); | 105 | disableSpellchecker(); |
106 | |||
107 | if (this.cldIdentifier) { | ||
108 | this.cldIdentifier.destroy(); | ||
109 | } | ||
132 | } | 110 | } |
133 | 111 | ||
134 | if (this.settings.service.isDarkModeEnabled) { | 112 | if (this.settings.service.isDarkModeEnabled) { |
@@ -151,6 +129,42 @@ class RecipeController { | |||
151 | serviceIdEcho(event) { | 129 | serviceIdEcho(event) { |
152 | event.sender.send('service-id', this.settings.service.id); | 130 | event.sender.send('service-id', this.settings.service.id); |
153 | } | 131 | } |
132 | |||
133 | async automaticLanguageDetection() { | ||
134 | const cldFactory = await loadModule(); | ||
135 | this.cldIdentifier = cldFactory.create(0, 1000); | ||
136 | |||
137 | window.addEventListener('keyup', debounce((e) => { | ||
138 | const element = e.target; | ||
139 | |||
140 | console.log(element); | ||
141 | |||
142 | if (!element) return; | ||
143 | |||
144 | let value = ''; | ||
145 | if (element.isContentEditable) { | ||
146 | value = element.textContent; | ||
147 | } else if (element.value) { | ||
148 | value = element.value; | ||
149 | } | ||
150 | |||
151 | // Force a minimum length to get better detection results | ||
152 | if (value.length < 30) return; | ||
153 | |||
154 | debug('Detecting language for', value); | ||
155 | const findResult = this.cldIdentifier.findLanguage(value); | ||
156 | |||
157 | debug('Language detection result', findResult); | ||
158 | |||
159 | if (findResult.is_reliable) { | ||
160 | const spellcheckerLocale = getSpellcheckerLocaleByFuzzyIdentifier(findResult.language); | ||
161 | debug('Language detected reliably, setting spellchecker language to', spellcheckerLocale); | ||
162 | if (spellcheckerLocale) { | ||
163 | switchDict(spellcheckerLocale); | ||
164 | } | ||
165 | } | ||
166 | }, 225)); | ||
167 | } | ||
154 | } | 168 | } |
155 | 169 | ||
156 | /* eslint-disable no-new */ | 170 | /* eslint-disable no-new */ |