Add option to set spell checking language (#58)

This commit is contained in:
Quang Lam 2019-11-30 20:34:45 -06:00 committed by GitHub
parent 351f2a9141
commit a3741b90e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 175 additions and 17 deletions

View file

@ -28,6 +28,66 @@ const getDefaultPauseNotificationsByScheduleTo = () => {
return d.toString();
};
const getDefaultSpellCheckerLanguages = () => {
const locale = app.getLocale();
if (!locale) return null;
// language code extracted from https://github.com/electron/electron/releases/download/v8.0.0-beta.3/hunspell_dictionaries.zip
const supportedLangs = [
'af-ZA',
'bg-BG',
'ca-ES',
'cs-CZ',
'cy-GB',
'da-DK',
'de-DE',
'el-GR',
'en-US', 'en-AU', 'en-CA', 'en-GB', // default to en-US
'es-ES',
'et-EE',
'fa-IR',
'fo-FO',
'fr-FR',
'he-IL',
'hi-IN',
'hr-HR',
'hu-HU',
'hy',
'id-ID',
'it-IT',
'ko',
'lt-LT',
'lv-LV',
'nb-NO',
'nl-NL',
'pl-PL',
'pt-PT', 'pt-BR', // default Portugese (Portugal)
'ro-RO',
'ru-RU',
'sh',
'sk-SK',
'sl-SI',
'sq',
'sr',
'sv-SE',
'ta-IN',
'tg-TG',
'tr-TR',
'uk-UA',
'vi-VN',
];
if (supportedLangs.indexOf(locale) > -1) return [locale];
// find first identical language (same language code, different country code)
const identicalLang = supportedLangs
.find((lang) => locale.substring(0, 2) === lang.substring(0, 2));
if (identicalLang) return [identicalLang];
return ['en-US'];
};
const defaultPreferences = {
askForDownloadPath: true,
attachToMenubar: false,
@ -43,17 +103,28 @@ const defaultPreferences = {
rememberLastPageVisited: false,
shareWorkspaceBrowsingData: false,
spellChecker: true,
spellCheckerLanguages: null,
swipeToNavigate: true,
theme: process.platform === 'darwin' ? 'automatic' : 'light',
unreadCountBadge: true,
};
const getPreferences = () => ({ ...defaultPreferences, ...settings.get(`preferences.${v}`) });
const getPreferences = () => {
// cannot init at launch as app.getLocale() is undefined before app.on('ready')
if (defaultPreferences.spellCheckerLanguages == null) {
defaultPreferences.spellCheckerLanguages = getDefaultSpellCheckerLanguages();
}
return { ...defaultPreferences, ...settings.get(`preferences.${v}`) };
};
const getPreference = (name) => {
if (settings.has(`preferences.${v}.${name}`)) {
return settings.get(`preferences.${v}.${name}`);
}
// cannot init at launch as app.getLocale() is undefined before app.on('ready')
if (name === 'spellCheckerLanguages' && defaultPreferences.spellCheckerLanguages == null) {
defaultPreferences.spellCheckerLanguages = getDefaultSpellCheckerLanguages();
}
return defaultPreferences[name];
};

View file

@ -40,11 +40,12 @@ window.onload = () => {
}
const spellChecker = ipcRenderer.sendSync('get-preference', 'spellChecker');
const spellCheckerLanguages = ipcRenderer.sendSync('get-preference', 'spellCheckerLanguages');
if (spellChecker) {
window.spellCheckHandler = new SpellCheckHandler();
setTimeout(() => window.spellCheckHandler.attachToInput(), 1000);
window.spellCheckHandler.switchLanguage('en-US');
window.spellCheckHandler.switchLanguage(spellCheckerLanguages[0]);
}
window.contextMenuBuilder = new ContextMenuBuilder(

View file

@ -69,6 +69,57 @@ const getOpenAtLoginString = (openAtLogin) => {
return 'No';
};
// language code extracted from https://github.com/electron/electron/releases/download/v8.0.0-beta.3/hunspell_dictionaries.zip
// languages name from http://www.lingoes.net/en/translator/langcode.htm & Chrome preferences
// sorted by name
const hunspellLanguagesMap = {
'af-ZA': 'Afrikaans',
sq: 'Albanian - shqip',
hy: 'Armenian - հայերեն',
'bg-BG': 'Bulgarian - български',
'ca-ES': 'Catalan - català',
'hr-HR': 'Croatian - hrvatski',
'cs-CZ': 'Czech - čeština',
'da-DK': 'Danish - dansk',
'nl-NL': 'Dutch - Nederlands',
'en-AU': 'English (Australia)',
'en-CA': 'English (Canada)',
'en-GB': 'English (United Kingdom)',
'en-US': 'English (United States)',
'et-EE': 'Estonian - eesti',
'fo-FO': 'Faroese - føroyskt',
'fr-FR': 'French - français',
'de-DE': 'German - Deutsch',
'el-GR': 'Greek - Ελληνικά',
'he-IL': 'Hebrew - ‎‫עברית‬‎',
'hi-IN': 'Hindi - हिन्दी',
'hu-HU': 'Hungarian - magyar',
'id-ID': 'Indonesian - Indonesia',
'it-IT': 'Italian - italiano',
ko: 'Korean - 한국어',
'lv-LV': 'Latvian - latviešu',
'lt-LT': 'Lithuanian - lietuvių',
'nb-NO': 'Norwegian Bokmål - norsk bokmål',
'fa-IR': 'Persian - ‎‫فارسی‬‎',
'pl-PL': 'Polish - polski',
'pt-BR': 'Portuguese (Brazil) - português (Brasil)',
'pt-PT': 'Portuguese (Portugal) - português (Portugal)',
'ro-RO': 'Romanian - română',
'ru-RU': 'Russian - русский',
sr: 'Serbian - српски',
sh: 'Serbo-Croatian - srpskohrvatski',
'sk-SK': 'Slovak - slovenčina',
'sl-SI': 'Slovenian - slovenščina',
'es-ES': 'Spanish - español',
'sv-SE': 'Swedish - svenska',
'tg-TG': 'Tajik - тоҷикӣ',
'ta-IN': 'Tamil - தமிழ்',
'tr-TR': 'Turkish - Türkçe',
'uk-UA': 'Ukrainian - українська',
'vi-VN': 'Vietnamese - Tiếng Việt',
'cy-GB': 'Welsh - Cymraeg',
};
const Preferences = ({
askForDownloadPath,
attachToMenubar,
@ -88,6 +139,7 @@ const Preferences = ({
rememberLastPageVisited,
shareWorkspaceBrowsingData,
spellChecker,
spellCheckerLanguages,
swipeToNavigate,
theme,
unreadCountBadge,
@ -193,6 +245,53 @@ const Preferences = ({
</List>
</Paper>
<Typography variant="subtitle2" className={classes.sectionTitle}>
Languages
</Typography>
<Paper className={classes.paper}>
<List dense>
<ListItem>
<ListItemText primary="Spell check" />
<Switch
color="primary"
checked={spellChecker}
onChange={(e) => {
requestSetPreference('spellChecker', e.target.checked);
requestShowRequireRestartDialog();
}}
classes={{
switchBase: classes.switchBase,
}}
/>
</ListItem>
<Divider />
<StatedMenu
id="spellcheckerLanguages"
buttonElement={(
<ListItem button>
<ListItemText
primary="Spell checking language"
secondary={spellCheckerLanguages.map((code) => hunspellLanguagesMap[code]).join(' | ')}
/>
<ChevronRightIcon color="action" />
</ListItem>
)}
>
{Object.keys(hunspellLanguagesMap).map((code) => (
<MenuItem
key={code}
onClick={() => {
requestSetPreference('spellCheckerLanguages', [code]);
requestShowRequireRestartDialog();
}}
>
{hunspellLanguagesMap[code]}
</MenuItem>
))}
</StatedMenu>
</List>
</Paper>
<Typography variant="subtitle2" className={classes.sectionTitle}>
Experience
</Typography>
@ -247,23 +346,8 @@ const Preferences = ({
}}
/>
</ListItem>
<Divider />
</>
)}
<ListItem>
<ListItemText primary="Use spell checker" />
<Switch
color="primary"
checked={spellChecker}
onChange={(e) => {
requestSetPreference('spellChecker', e.target.checked);
requestShowRequireRestartDialog();
}}
classes={{
switchBase: classes.switchBase,
}}
/>
</ListItem>
</List>
</Paper>
@ -483,6 +567,7 @@ Preferences.propTypes = {
rememberLastPageVisited: PropTypes.bool.isRequired,
shareWorkspaceBrowsingData: PropTypes.bool.isRequired,
spellChecker: PropTypes.bool.isRequired,
spellCheckerLanguages: PropTypes.arrayOf(PropTypes.string).isRequired,
swipeToNavigate: PropTypes.bool.isRequired,
theme: PropTypes.string.isRequired,
unreadCountBadge: PropTypes.bool.isRequired,
@ -504,6 +589,7 @@ const mapStateToProps = (state) => ({
rememberLastPageVisited: state.preferences.rememberLastPageVisited,
shareWorkspaceBrowsingData: state.preferences.shareWorkspaceBrowsingData,
spellChecker: state.preferences.spellChecker,
spellCheckerLanguages: state.preferences.spellCheckerLanguages,
swipeToNavigate: state.preferences.swipeToNavigate,
theme: state.preferences.theme,
unreadCountBadge: state.preferences.unreadCountBadge,