Skip to content

Commit

Permalink
feat(Service): Add option to change spellchecking language by service
Browse files Browse the repository at this point in the history
  • Loading branch information
adlk committed Dec 7, 2018
1 parent 1d192ca commit baf7d60
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 19 deletions.
7 changes: 7 additions & 0 deletions src/components/settings/services/EditServiceForm.js
Expand Up @@ -14,6 +14,7 @@ import Input from '../../ui/Input';
import Toggle from '../../ui/Toggle';
import Button from '../../ui/Button';
import ImageUpload from '../../ui/ImageUpload';
import Select from '../../ui/Select';

import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer';

Expand Down Expand Up @@ -333,6 +334,12 @@ export default @observer class EditServiceForm extends Component {
</div>
</div>

<PremiumFeatureContainer>
<div className="settings__settings-group">
<Select field={form.$('spellcheckerLanguage')} />
</div>
</PremiumFeatureContainer>

{isProxyFeatureEnabled && (
<PremiumFeatureContainer condition={isProxyFeaturePremiumFeature}>
<div className="settings__settings-group">
Expand Down
9 changes: 8 additions & 1 deletion src/components/ui/Select.js
Expand Up @@ -9,26 +9,32 @@ 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() {
const {
field,
className,
showLabel,
disabled,
} = this.props;

console.log('disabled', disabled);

return (
<div
className={classnames({
'franz-form__field': true,
'has-error': field.error,
'is-disabled': disabled,
[`${className}`]: className,
})}
>
Expand All @@ -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 => (
<option
key={type.value}
value={type.value}
// selected={field.value === }
disabled={type.disabled}
>
{type.label}
</option>
Expand Down
24 changes: 23 additions & 1 deletion src/containers/settings/EditServiceScreen.js
Expand Up @@ -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',
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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,
},
},
};
Expand Down
18 changes: 6 additions & 12 deletions src/containers/settings/EditSettingsScreen.js
Expand Up @@ -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';

Expand Down Expand Up @@ -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 = {
Expand Down
26 changes: 26 additions & 0 deletions src/helpers/i18n-helpers.js
Expand Up @@ -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;
}
3 changes: 3 additions & 0 deletions src/models/Service.js
Expand Up @@ -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) {
Expand Down Expand Up @@ -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(() => {
Expand Down
4 changes: 4 additions & 0 deletions src/styles/select.scss
Expand Up @@ -20,4 +20,8 @@ $toggle: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj
min-width: 200px;
padding: 10px;
-webkit-appearance: none;

&[disabled] {
opacity: 0.5;
}
}
31 changes: 28 additions & 3 deletions 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';

Expand All @@ -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');
Expand All @@ -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);
}
Expand All @@ -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;
Expand All @@ -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);

Expand All @@ -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 🤦‍
Expand Down
2 changes: 0 additions & 2 deletions src/webview/spellchecker.js
Expand Up @@ -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);
Expand Down

0 comments on commit baf7d60

Please sign in to comment.