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 {
field: PropTypes.instanceOf(Field).isRequired,
className: PropTypes.string,
showLabel: PropTypes.bool,
+ disabled: PropTypes.bool,
};
static defaultProps = {
className: null,
focus: false,
showLabel: true,
+ disabled: false,
};
render() {
@@ -22,13 +24,17 @@ export default @observer class Select extends Component {
field,
className,
showLabel,
+ disabled,
} = this.props;
+ console.log('disabled', disabled);
+
return (
@@ -45,12 +51,13 @@ export default @observer class Select extends Component {
id={field.id}
defaultValue={field.value}
className="franz-form__select"
+ disabled={field.disabled || disabled}
>
{field.options.map(type => (
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';
import ServiceError from '../../components/settings/services/ServiceError';
import EditServiceForm from '../../components/settings/services/EditServiceForm';
import { required, url, oneRequired } from '../../helpers/validation-helpers';
+import { getSelectOptions } from '../../helpers/i18n-helpers';
import { config as proxyFeature } from '../../features/serviceProxy';
+import { SPELLCHECKER_LOCALES } from '../../i18n/languages';
+
const messages = defineMessages({
name: {
id: 'settings.service.form.name',
@@ -74,6 +77,14 @@ const messages = defineMessages({
id: 'settings.service.form.proxy.password',
defaultMessage: '!!!Password',
},
+ spellcheckerLanguage: {
+ id: 'settings.service.form.spellcheckerLanguage',
+ defaultMessage: '!!!Spell checking Language',
+ },
+ spellcheckerSystemDefault: {
+ id: 'settings.service.form.spellcheckerLanguage.default',
+ defaultMessage: '!!!Use System Default ({default})',
+ },
});
export default @inject('stores', 'actions') @observer class EditServiceScreen extends Component {
@@ -101,6 +112,11 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex
}
prepareForm(recipe, service, proxy) {
+ const spellcheckerLanguage = getSelectOptions({
+ locales: SPELLCHECKER_LOCALES,
+ resetToDefaultText: this.context.intl.formatMessage(messages.spellcheckerSystemDefault, { default: SPELLCHECKER_LOCALES[this.props.stores.settings.app.spellcheckerLanguage] }),
+ });
+
const { intl } = this.context;
const config = {
fields: {
@@ -138,7 +154,13 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex
isDarkModeEnabled: {
label: intl.formatMessage(messages.enableDarkMode),
value: service.isDarkModeEnabled,
- default: this.props.stores.settings.all.app.darkMode,
+ default: this.props.stores.settings.app.darkMode,
+ },
+ spellcheckerLanguage: {
+ label: intl.formatMessage(messages.spellcheckerLanguage),
+ value: service.spellcheckerLanguage,
+ options: spellcheckerLanguage,
+ disabled: !this.props.stores.settings.app.enableSpellchecking,
},
},
};
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';
import { DEFAULT_APP_SETTINGS } from '../../config';
import { config as spellcheckerConfig } from '../../features/spellchecker';
+import { getSelectOptions } from '../../helpers/i18n-helpers';
+
import EditSettingsForm from '../../components/settings/settings/EditSettingsForm';
@@ -116,20 +118,12 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e
const { app, settings, user } = this.props.stores;
const { intl } = this.context;
- const locales = [];
- Object.keys(APP_LOCALES).sort(Intl.Collator().compare).forEach((key) => {
- locales.push({
- value: key,
- label: APP_LOCALES[key],
- });
+ const locales = getSelectOptions({
+ locales: APP_LOCALES,
});
- const spellcheckingLanguages = [];
- Object.keys(SPELLCHECKER_LOCALES).sort(Intl.Collator().compare).forEach((key) => {
- spellcheckingLanguages.push({
- value: key,
- label: SPELLCHECKER_LOCALES[key],
- });
+ const spellcheckingLanguages = getSelectOptions({
+ locales: SPELLCHECKER_LOCALES,
});
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 }) {
return localeStr;
}
+
+export function getSelectOptions({ locales, resetToDefaultText = '' }) {
+ let options = [];
+
+ if (resetToDefaultText) {
+ options = [
+ {
+ value: '',
+ label: resetToDefaultText,
+ }, {
+ value: '───',
+ label: '───',
+ disabled: true,
+ },
+ ];
+ }
+
+ Object.keys(locales).sort(Intl.Collator().compare).forEach((key) => {
+ options.push({
+ value: key,
+ label: locales[key],
+ });
+ });
+
+ return options;
+}
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 {
@observable hasCustomUploadedIcon = false;
@observable hasCrashed = false;
@observable isDarkModeEnabled = false;
+ @observable spellcheckerLanguage = null;
constructor(data, recipe) {
if (!data) {
@@ -71,6 +72,8 @@ export default class Service {
this.proxy = data.proxy !== undefined ? data.proxy : this.proxy;
+ this.spellcheckerLanguage = data.spellcheckerLanguage !== undefined ? data.spellcheckerLanguage : this.spellcheckerLanguage;
+
this.recipe = recipe;
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
min-width: 200px;
padding: 10px;
-webkit-appearance: none;
+
+ &[disabled] {
+ opacity: 0.5;
+ }
}
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 @@
import { ipcRenderer } from 'electron';
import path from 'path';
+import { observable } from 'mobx';
import RecipeWebview from './lib/RecipeWebview';
@@ -12,6 +13,8 @@ const debug = require('debug')('Franz:Plugin');
window.franzSettings = {};
let serviceData;
+let overrideSpellcheckerLanguage = false;
+
ipcRenderer.on('initializeRecipe', (e, data) => {
const modulePath = path.join(data.recipe.path, 'webview.js');
@@ -28,6 +31,13 @@ ipcRenderer.on('initializeRecipe', (e, data) => {
injectDarkModeStyle(data.recipe.path);
debug('Add dark theme styles');
}
+
+ if (data.spellcheckerLanguage) {
+ debug('Overriding spellchecker language to', data.spellcheckerLanguage);
+ switchDict(data.spellcheckerLanguage);
+
+ overrideSpellcheckerLanguage = true;
+ }
} catch (err) {
debug('Recipe initialization failed', err);
}
@@ -42,10 +52,11 @@ ipcRenderer.on('initializeRecipe', (e, data) => {
ipcRenderer.on('settings-update', async (e, data) => {
debug('Settings update received', data);
- if (data.enableSpellchecking) {
- switchDict(data.spellcheckerLanguage);
- } else {
+ if (!data.enableSpellchecking) {
disableSpellchecker();
+ } else if (!overrideSpellcheckerLanguage) {
+ debug('Setting spellchecker language based on app settings to', data.spellcheckerLanguage);
+ switchDict(data.spellcheckerLanguage);
}
window.franzSettings = data;
@@ -54,6 +65,8 @@ ipcRenderer.on('settings-update', async (e, data) => {
ipcRenderer.on('service-settings-update', (e, data) => {
debug('Service settings update received', data);
+ serviceData = data;
+
if (data.isDarkModeEnabled && !isDarkModeStyleInjected()) {
injectDarkModeStyle(serviceData.recipe.path);
@@ -63,6 +76,18 @@ ipcRenderer.on('service-settings-update', (e, data) => {
debug('Disable service dark mode');
}
+
+ if (data.spellcheckerLanguage) {
+ debug('Overriding spellchecker language to', data.spellcheckerLanguage);
+ switchDict(data.spellcheckerLanguage);
+
+ overrideSpellcheckerLanguage = true;
+ } else {
+ debug('Going back to default spellchecker language to', window.franzSettings.spellcheckerLanguage);
+ switchDict(window.franzSettings.spellcheckerLanguage);
+
+ overrideSpellcheckerLanguage = false;
+ }
});
// 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;
async function loadDictionary(locale) {
try {
- // Replacing app.asar is not beautiful but unforunately necessary
const fileLocation = path.join(DICTIONARY_PATH, `hunspell-dict-${locale}/${locale}`);
- console.log(fileLocation, __dirname);
await provider.loadDictionary(locale, `${fileLocation}.dic`, `${fileLocation}.aff`);
} catch (err) {
console.error('Could not load dictionary', err);