diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/settings/services/EditServiceForm.js | 7 | ||||
-rw-r--r-- | src/components/ui/Select.js | 9 | ||||
-rw-r--r-- | src/containers/settings/EditServiceScreen.js | 24 | ||||
-rw-r--r-- | src/containers/settings/EditSettingsScreen.js | 18 | ||||
-rw-r--r-- | src/helpers/i18n-helpers.js | 26 | ||||
-rw-r--r-- | src/models/Service.js | 3 | ||||
-rw-r--r-- | src/styles/select.scss | 4 | ||||
-rw-r--r-- | src/webview/plugin.js | 31 | ||||
-rw-r--r-- | src/webview/spellchecker.js | 2 |
9 files changed, 105 insertions, 19 deletions
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index d16ec35b8..0c869c16d 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -14,6 +14,7 @@ import Input from '../../ui/Input'; | |||
14 | import Toggle from '../../ui/Toggle'; | 14 | import Toggle from '../../ui/Toggle'; |
15 | import Button from '../../ui/Button'; | 15 | import Button from '../../ui/Button'; |
16 | import ImageUpload from '../../ui/ImageUpload'; | 16 | import ImageUpload from '../../ui/ImageUpload'; |
17 | import Select from '../../ui/Select'; | ||
17 | 18 | ||
18 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; | 19 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; |
19 | 20 | ||
@@ -333,6 +334,12 @@ export default @observer class EditServiceForm extends Component { | |||
333 | </div> | 334 | </div> |
334 | </div> | 335 | </div> |
335 | 336 | ||
337 | <PremiumFeatureContainer> | ||
338 | <div className="settings__settings-group"> | ||
339 | <Select field={form.$('spellcheckerLanguage')} /> | ||
340 | </div> | ||
341 | </PremiumFeatureContainer> | ||
342 | |||
336 | {isProxyFeatureEnabled && ( | 343 | {isProxyFeatureEnabled && ( |
337 | <PremiumFeatureContainer condition={isProxyFeaturePremiumFeature}> | 344 | <PremiumFeatureContainer condition={isProxyFeaturePremiumFeature}> |
338 | <div className="settings__settings-group"> | 345 | <div className="settings__settings-group"> |
diff --git a/src/components/ui/Select.js b/src/components/ui/Select.js index abcad417e..102737bec 100644 --- a/src/components/ui/Select.js +++ b/src/components/ui/Select.js | |||
@@ -9,12 +9,14 @@ export default @observer class Select extends Component { | |||
9 | field: PropTypes.instanceOf(Field).isRequired, | 9 | field: PropTypes.instanceOf(Field).isRequired, |
10 | className: PropTypes.string, | 10 | className: PropTypes.string, |
11 | showLabel: PropTypes.bool, | 11 | showLabel: PropTypes.bool, |
12 | disabled: PropTypes.bool, | ||
12 | }; | 13 | }; |
13 | 14 | ||
14 | static defaultProps = { | 15 | static defaultProps = { |
15 | className: null, | 16 | className: null, |
16 | focus: false, | 17 | focus: false, |
17 | showLabel: true, | 18 | showLabel: true, |
19 | disabled: false, | ||
18 | }; | 20 | }; |
19 | 21 | ||
20 | render() { | 22 | render() { |
@@ -22,13 +24,17 @@ export default @observer class Select extends Component { | |||
22 | field, | 24 | field, |
23 | className, | 25 | className, |
24 | showLabel, | 26 | showLabel, |
27 | disabled, | ||
25 | } = this.props; | 28 | } = this.props; |
26 | 29 | ||
30 | console.log('disabled', disabled); | ||
31 | |||
27 | return ( | 32 | return ( |
28 | <div | 33 | <div |
29 | className={classnames({ | 34 | className={classnames({ |
30 | 'franz-form__field': true, | 35 | 'franz-form__field': true, |
31 | 'has-error': field.error, | 36 | 'has-error': field.error, |
37 | 'is-disabled': disabled, | ||
32 | [`${className}`]: className, | 38 | [`${className}`]: className, |
33 | })} | 39 | })} |
34 | > | 40 | > |
@@ -45,12 +51,13 @@ export default @observer class Select extends Component { | |||
45 | id={field.id} | 51 | id={field.id} |
46 | defaultValue={field.value} | 52 | defaultValue={field.value} |
47 | className="franz-form__select" | 53 | className="franz-form__select" |
54 | disabled={field.disabled || disabled} | ||
48 | > | 55 | > |
49 | {field.options.map(type => ( | 56 | {field.options.map(type => ( |
50 | <option | 57 | <option |
51 | key={type.value} | 58 | key={type.value} |
52 | value={type.value} | 59 | value={type.value} |
53 | // selected={field.value === } | 60 | disabled={type.disabled} |
54 | > | 61 | > |
55 | {type.label} | 62 | {type.label} |
56 | </option> | 63 | </option> |
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index 639e8b070..f4915f68b 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js | |||
@@ -14,9 +14,12 @@ import { gaPage } from '../../lib/analytics'; | |||
14 | import ServiceError from '../../components/settings/services/ServiceError'; | 14 | import ServiceError from '../../components/settings/services/ServiceError'; |
15 | import EditServiceForm from '../../components/settings/services/EditServiceForm'; | 15 | import EditServiceForm from '../../components/settings/services/EditServiceForm'; |
16 | import { required, url, oneRequired } from '../../helpers/validation-helpers'; | 16 | import { required, url, oneRequired } from '../../helpers/validation-helpers'; |
17 | import { getSelectOptions } from '../../helpers/i18n-helpers'; | ||
17 | 18 | ||
18 | import { config as proxyFeature } from '../../features/serviceProxy'; | 19 | import { config as proxyFeature } from '../../features/serviceProxy'; |
19 | 20 | ||
21 | import { SPELLCHECKER_LOCALES } from '../../i18n/languages'; | ||
22 | |||
20 | const messages = defineMessages({ | 23 | const messages = defineMessages({ |
21 | name: { | 24 | name: { |
22 | id: 'settings.service.form.name', | 25 | id: 'settings.service.form.name', |
@@ -74,6 +77,14 @@ const messages = defineMessages({ | |||
74 | id: 'settings.service.form.proxy.password', | 77 | id: 'settings.service.form.proxy.password', |
75 | defaultMessage: '!!!Password', | 78 | defaultMessage: '!!!Password', |
76 | }, | 79 | }, |
80 | spellcheckerLanguage: { | ||
81 | id: 'settings.service.form.spellcheckerLanguage', | ||
82 | defaultMessage: '!!!Spell checking Language', | ||
83 | }, | ||
84 | spellcheckerSystemDefault: { | ||
85 | id: 'settings.service.form.spellcheckerLanguage.default', | ||
86 | defaultMessage: '!!!Use System Default ({default})', | ||
87 | }, | ||
77 | }); | 88 | }); |
78 | 89 | ||
79 | export default @inject('stores', 'actions') @observer class EditServiceScreen extends Component { | 90 | export default @inject('stores', 'actions') @observer class EditServiceScreen extends Component { |
@@ -101,6 +112,11 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
101 | } | 112 | } |
102 | 113 | ||
103 | prepareForm(recipe, service, proxy) { | 114 | prepareForm(recipe, service, proxy) { |
115 | const spellcheckerLanguage = getSelectOptions({ | ||
116 | locales: SPELLCHECKER_LOCALES, | ||
117 | resetToDefaultText: this.context.intl.formatMessage(messages.spellcheckerSystemDefault, { default: SPELLCHECKER_LOCALES[this.props.stores.settings.app.spellcheckerLanguage] }), | ||
118 | }); | ||
119 | |||
104 | const { intl } = this.context; | 120 | const { intl } = this.context; |
105 | const config = { | 121 | const config = { |
106 | fields: { | 122 | fields: { |
@@ -138,7 +154,13 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
138 | isDarkModeEnabled: { | 154 | isDarkModeEnabled: { |
139 | label: intl.formatMessage(messages.enableDarkMode), | 155 | label: intl.formatMessage(messages.enableDarkMode), |
140 | value: service.isDarkModeEnabled, | 156 | value: service.isDarkModeEnabled, |
141 | default: this.props.stores.settings.all.app.darkMode, | 157 | default: this.props.stores.settings.app.darkMode, |
158 | }, | ||
159 | spellcheckerLanguage: { | ||
160 | label: intl.formatMessage(messages.spellcheckerLanguage), | ||
161 | value: service.spellcheckerLanguage, | ||
162 | options: spellcheckerLanguage, | ||
163 | disabled: !this.props.stores.settings.app.enableSpellchecking, | ||
142 | }, | 164 | }, |
143 | }, | 165 | }, |
144 | }; | 166 | }; |
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index ea1d319d9..350bd9f8a 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js | |||
@@ -12,6 +12,8 @@ import { gaPage } from '../../lib/analytics'; | |||
12 | import { DEFAULT_APP_SETTINGS } from '../../config'; | 12 | import { DEFAULT_APP_SETTINGS } from '../../config'; |
13 | import { config as spellcheckerConfig } from '../../features/spellchecker'; | 13 | import { config as spellcheckerConfig } from '../../features/spellchecker'; |
14 | 14 | ||
15 | import { getSelectOptions } from '../../helpers/i18n-helpers'; | ||
16 | |||
15 | 17 | ||
16 | import EditSettingsForm from '../../components/settings/settings/EditSettingsForm'; | 18 | import EditSettingsForm from '../../components/settings/settings/EditSettingsForm'; |
17 | 19 | ||
@@ -116,20 +118,12 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
116 | const { app, settings, user } = this.props.stores; | 118 | const { app, settings, user } = this.props.stores; |
117 | const { intl } = this.context; | 119 | const { intl } = this.context; |
118 | 120 | ||
119 | const locales = []; | 121 | const locales = getSelectOptions({ |
120 | Object.keys(APP_LOCALES).sort(Intl.Collator().compare).forEach((key) => { | 122 | locales: APP_LOCALES, |
121 | locales.push({ | ||
122 | value: key, | ||
123 | label: APP_LOCALES[key], | ||
124 | }); | ||
125 | }); | 123 | }); |
126 | 124 | ||
127 | const spellcheckingLanguages = []; | 125 | const spellcheckingLanguages = getSelectOptions({ |
128 | Object.keys(SPELLCHECKER_LOCALES).sort(Intl.Collator().compare).forEach((key) => { | 126 | locales: SPELLCHECKER_LOCALES, |
129 | spellcheckingLanguages.push({ | ||
130 | value: key, | ||
131 | label: SPELLCHECKER_LOCALES[key], | ||
132 | }); | ||
133 | }); | 127 | }); |
134 | 128 | ||
135 | const config = { | 129 | const config = { |
diff --git a/src/helpers/i18n-helpers.js b/src/helpers/i18n-helpers.js index 00a2061c1..026a220e0 100644 --- a/src/helpers/i18n-helpers.js +++ b/src/helpers/i18n-helpers.js | |||
@@ -25,3 +25,29 @@ export function getLocale({ locale, locales, defaultLocale, fallbackLocale }) { | |||
25 | 25 | ||
26 | return localeStr; | 26 | return localeStr; |
27 | } | 27 | } |
28 | |||
29 | export function getSelectOptions({ locales, resetToDefaultText = '' }) { | ||
30 | let options = []; | ||
31 | |||
32 | if (resetToDefaultText) { | ||
33 | options = [ | ||
34 | { | ||
35 | value: '', | ||
36 | label: resetToDefaultText, | ||
37 | }, { | ||
38 | value: '───', | ||
39 | label: '───', | ||
40 | disabled: true, | ||
41 | }, | ||
42 | ]; | ||
43 | } | ||
44 | |||
45 | Object.keys(locales).sort(Intl.Collator().compare).forEach((key) => { | ||
46 | options.push({ | ||
47 | value: key, | ||
48 | label: locales[key], | ||
49 | }); | ||
50 | }); | ||
51 | |||
52 | return options; | ||
53 | } | ||
diff --git a/src/models/Service.js b/src/models/Service.js index 41180dd76..deeb544d1 100644 --- a/src/models/Service.js +++ b/src/models/Service.js | |||
@@ -29,6 +29,7 @@ export default class Service { | |||
29 | @observable hasCustomUploadedIcon = false; | 29 | @observable hasCustomUploadedIcon = false; |
30 | @observable hasCrashed = false; | 30 | @observable hasCrashed = false; |
31 | @observable isDarkModeEnabled = false; | 31 | @observable isDarkModeEnabled = false; |
32 | @observable spellcheckerLanguage = null; | ||
32 | 33 | ||
33 | constructor(data, recipe) { | 34 | constructor(data, recipe) { |
34 | if (!data) { | 35 | if (!data) { |
@@ -71,6 +72,8 @@ export default class Service { | |||
71 | 72 | ||
72 | this.proxy = data.proxy !== undefined ? data.proxy : this.proxy; | 73 | this.proxy = data.proxy !== undefined ? data.proxy : this.proxy; |
73 | 74 | ||
75 | this.spellcheckerLanguage = data.spellcheckerLanguage !== undefined ? data.spellcheckerLanguage : this.spellcheckerLanguage; | ||
76 | |||
74 | this.recipe = recipe; | 77 | this.recipe = recipe; |
75 | 78 | ||
76 | autorun(() => { | 79 | autorun(() => { |
diff --git a/src/styles/select.scss b/src/styles/select.scss index ed0fc0fc2..513975f9c 100644 --- a/src/styles/select.scss +++ b/src/styles/select.scss | |||
@@ -20,4 +20,8 @@ $toggle: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj | |||
20 | min-width: 200px; | 20 | min-width: 200px; |
21 | padding: 10px; | 21 | padding: 10px; |
22 | -webkit-appearance: none; | 22 | -webkit-appearance: none; |
23 | |||
24 | &[disabled] { | ||
25 | opacity: 0.5; | ||
26 | } | ||
23 | } | 27 | } |
diff --git a/src/webview/plugin.js b/src/webview/plugin.js index 72530733d..6d4e65062 100644 --- a/src/webview/plugin.js +++ b/src/webview/plugin.js | |||
@@ -1,5 +1,6 @@ | |||
1 | import { ipcRenderer } from 'electron'; | 1 | import { ipcRenderer } from 'electron'; |
2 | import path from 'path'; | 2 | import path from 'path'; |
3 | import { observable } from 'mobx'; | ||
3 | 4 | ||
4 | import RecipeWebview from './lib/RecipeWebview'; | 5 | import RecipeWebview from './lib/RecipeWebview'; |
5 | 6 | ||
@@ -12,6 +13,8 @@ const debug = require('debug')('Franz:Plugin'); | |||
12 | 13 | ||
13 | window.franzSettings = {}; | 14 | window.franzSettings = {}; |
14 | let serviceData; | 15 | let serviceData; |
16 | let overrideSpellcheckerLanguage = false; | ||
17 | |||
15 | 18 | ||
16 | ipcRenderer.on('initializeRecipe', (e, data) => { | 19 | ipcRenderer.on('initializeRecipe', (e, data) => { |
17 | const modulePath = path.join(data.recipe.path, 'webview.js'); | 20 | const modulePath = path.join(data.recipe.path, 'webview.js'); |
@@ -28,6 +31,13 @@ ipcRenderer.on('initializeRecipe', (e, data) => { | |||
28 | injectDarkModeStyle(data.recipe.path); | 31 | injectDarkModeStyle(data.recipe.path); |
29 | debug('Add dark theme styles'); | 32 | debug('Add dark theme styles'); |
30 | } | 33 | } |
34 | |||
35 | if (data.spellcheckerLanguage) { | ||
36 | debug('Overriding spellchecker language to', data.spellcheckerLanguage); | ||
37 | switchDict(data.spellcheckerLanguage); | ||
38 | |||
39 | overrideSpellcheckerLanguage = true; | ||
40 | } | ||
31 | } catch (err) { | 41 | } catch (err) { |
32 | debug('Recipe initialization failed', err); | 42 | debug('Recipe initialization failed', err); |
33 | } | 43 | } |
@@ -42,10 +52,11 @@ ipcRenderer.on('initializeRecipe', (e, data) => { | |||
42 | ipcRenderer.on('settings-update', async (e, data) => { | 52 | ipcRenderer.on('settings-update', async (e, data) => { |
43 | debug('Settings update received', data); | 53 | debug('Settings update received', data); |
44 | 54 | ||
45 | if (data.enableSpellchecking) { | 55 | if (!data.enableSpellchecking) { |
46 | switchDict(data.spellcheckerLanguage); | ||
47 | } else { | ||
48 | disableSpellchecker(); | 56 | disableSpellchecker(); |
57 | } else if (!overrideSpellcheckerLanguage) { | ||
58 | debug('Setting spellchecker language based on app settings to', data.spellcheckerLanguage); | ||
59 | switchDict(data.spellcheckerLanguage); | ||
49 | } | 60 | } |
50 | 61 | ||
51 | window.franzSettings = data; | 62 | window.franzSettings = data; |
@@ -54,6 +65,8 @@ ipcRenderer.on('settings-update', async (e, data) => { | |||
54 | ipcRenderer.on('service-settings-update', (e, data) => { | 65 | ipcRenderer.on('service-settings-update', (e, data) => { |
55 | debug('Service settings update received', data); | 66 | debug('Service settings update received', data); |
56 | 67 | ||
68 | serviceData = data; | ||
69 | |||
57 | if (data.isDarkModeEnabled && !isDarkModeStyleInjected()) { | 70 | if (data.isDarkModeEnabled && !isDarkModeStyleInjected()) { |
58 | injectDarkModeStyle(serviceData.recipe.path); | 71 | injectDarkModeStyle(serviceData.recipe.path); |
59 | 72 | ||
@@ -63,6 +76,18 @@ ipcRenderer.on('service-settings-update', (e, data) => { | |||
63 | 76 | ||
64 | debug('Disable service dark mode'); | 77 | debug('Disable service dark mode'); |
65 | } | 78 | } |
79 | |||
80 | if (data.spellcheckerLanguage) { | ||
81 | debug('Overriding spellchecker language to', data.spellcheckerLanguage); | ||
82 | switchDict(data.spellcheckerLanguage); | ||
83 | |||
84 | overrideSpellcheckerLanguage = true; | ||
85 | } else { | ||
86 | debug('Going back to default spellchecker language to', window.franzSettings.spellcheckerLanguage); | ||
87 | switchDict(window.franzSettings.spellcheckerLanguage); | ||
88 | |||
89 | overrideSpellcheckerLanguage = false; | ||
90 | } | ||
66 | }); | 91 | }); |
67 | 92 | ||
68 | // Needed for current implementation of electrons 'login' event 🤦 | 93 | // Needed for current implementation of electrons 'login' event 🤦 |
diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js index ab0cc9a90..f1bae1cd7 100644 --- a/src/webview/spellchecker.js +++ b/src/webview/spellchecker.js | |||
@@ -13,9 +13,7 @@ let _isEnabled = false; | |||
13 | 13 | ||
14 | async function loadDictionary(locale) { | 14 | async function loadDictionary(locale) { |
15 | try { | 15 | try { |
16 | // Replacing app.asar is not beautiful but unforunately necessary | ||
17 | const fileLocation = path.join(DICTIONARY_PATH, `hunspell-dict-${locale}/${locale}`); | 16 | const fileLocation = path.join(DICTIONARY_PATH, `hunspell-dict-${locale}/${locale}`); |
18 | console.log(fileLocation, __dirname); | ||
19 | await provider.loadDictionary(locale, `${fileLocation}.dic`, `${fileLocation}.aff`); | 17 | await provider.loadDictionary(locale, `${fileLocation}.dic`, `${fileLocation}.aff`); |
20 | } catch (err) { | 18 | } catch (err) { |
21 | console.error('Could not load dictionary', err); | 19 | console.error('Could not load dictionary', err); |