Skip to content

Spellchecker Improvements #322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"electron-is-dev": "0.3.0",
"electron-localshortcut": "2.0.2",
"electron-log": "2.2.7",
"electron-spellchecker": "1.2.0",
"electron-spellchecker": "1.1.2",
"electron-updater": "2.8.9",
"node-json-db": "0.7.3",
"request": "2.81.0",
Expand Down
17 changes: 17 additions & 0 deletions app/renderer/js/pages/preference/general-section.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class GeneralSection extends BaseSection {
<div class="setting-description">Start app at login</div>
<div class="setting-control"></div>
</div>
<div class="setting-row" id="enable-spellchecker-option">
<div class="setting-description">Enable Spellchecker (requires restart)</div>
<div class="setting-control"></div>
</div>
</div>
<div class="title">Reset Application Data</div>
<div class="settings-card">
Expand All @@ -80,6 +84,7 @@ class GeneralSection extends BaseSection {
this.updateStartAtLoginOption();
this.updateResetDataOption();
this.showDesktopNotification();
this.enableSpellchecker();
}

updateTrayOption() {
Expand Down Expand Up @@ -170,6 +175,18 @@ class GeneralSection extends BaseSection {
});
}

enableSpellchecker() {
this.generateSettingOption({
$element: document.querySelector('#enable-spellchecker-option .setting-control'),
value: ConfigUtil.getConfigItem('enableSpellchecker', true),
clickHandler: () => {
const newValue = !ConfigUtil.getConfigItem('enableSpellchecker');
ConfigUtil.setConfigItem('enableSpellchecker', newValue);
this.enableSpellchecker();
}
});
}

clearAppDataDialog() {
const clearAppDataMessage = 'By clicking proceed you will be removing all added accounts and preferences from Zulip. When the application restarts, it will be as if you are starting Zulip for the first time.';
const getAppPath = path.join(app.getPath('appData'), app.getName());
Expand Down
29 changes: 28 additions & 1 deletion app/renderer/js/pages/preference/preference.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
'use strict';

const BaseComponent = require(__dirname + '/js/components/base.js');
const {ipcRenderer} = require('electron');
const { ipcRenderer } = require('electron');

const ConfigUtil = require(__dirname + '/js/utils/config-util.js');

const Nav = require(__dirname + '/js/pages/preference/nav.js');
const ServersSection = require(__dirname + '/js/pages/preference/servers-section.js');
Expand All @@ -25,6 +27,7 @@ class PreferenceView extends BaseComponent {

this.setDefaultView();
this.registerIpcs();
this.setDefaultSettings();
}

setDefaultView() {
Expand All @@ -36,6 +39,30 @@ class PreferenceView extends BaseComponent {
this.handleNavigation(nav);
}

// Settings are initialized only when user clicks on General/Server/Network section settings
// In case, user doesn't visit these section, those values set to be null automatically
// This will make sure the default settings are correctly set to either true or false
setDefaultSettings() {
// Default settings which should be respected
const settingOptions = {
trayIcon: true,
useProxy: false,
showSidebar: true,
badgeOption: true,
startAtLogin: false,
enableSpellchecker: true,
showNotification: true,
betaUpdate: false,
silent: false
};

for (const i in settingOptions) {
if (ConfigUtil.getConfigItem(i) === null) {
ConfigUtil.setConfigItem(i, settingOptions[i]);
}
}
}

handleNavigation(navItem) {
this.nav.select(navItem);
switch (navItem) {
Expand Down
23 changes: 20 additions & 3 deletions app/renderer/js/preload.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
'use strict';

const { ipcRenderer } = require('electron');
const { spellChecker } = require('./spellchecker');
const SetupSpellChecker = require('./spellchecker');

const ConfigUtil = require(__dirname + '/utils/config-util.js');

// eslint-disable-next-line import/no-unassigned-import
require('./notification');

Expand Down Expand Up @@ -32,8 +35,15 @@ process.once('loaded', () => {

// To prevent failing this script on linux we need to load it after the document loaded
document.addEventListener('DOMContentLoaded', () => {
// Init spellchecker
spellChecker();
// Get the default language of the server
const serverLanguage = page_params.default_language; // eslint-disable-line no-undef, camelcase

if (serverLanguage) {
// Set spellcheker language
ConfigUtil.setConfigItem('spellcheckerLanguage', serverLanguage);
// Init spellchecker
SetupSpellChecker.init();
}

// redirect users to network troubleshooting page
const getRestartButton = document.querySelector('.restart_get_events_button');
Expand All @@ -43,3 +53,10 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
});

// Clean up spellchecker events after you navigate away from this page;
// otherwise, you may experience errors
window.addEventListener('beforeunload', () => {
SetupSpellChecker.unsubscribeSpellChecker();
});

77 changes: 52 additions & 25 deletions app/renderer/js/spellchecker.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,56 @@
'use strict';

const {SpellCheckHandler, ContextMenuListener, ContextMenuBuilder} = require('electron-spellchecker');

function spellChecker() {
// Implement spellcheck using electron api
window.spellCheckHandler = new SpellCheckHandler();
window.spellCheckHandler.attachToInput();

// Start off as US English
window.spellCheckHandler.switchLanguage('en-US');

const contextMenuBuilder = new ContextMenuBuilder(window.spellCheckHandler);
const contextMenuListener = new ContextMenuListener(info => {
contextMenuBuilder.showPopupMenu(info);
});

// Clean up events after you navigate away from this page;
// otherwise, you may experience errors
window.addEventListener('beforeunload', () => {
// eslint-disable-next-line no-undef
spellCheckHandler.unsubscribe();
contextMenuListener.unsubscribe();
});
const { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } = require('electron-spellchecker');

const ConfigUtil = require(__dirname + '/utils/config-util.js');

class SetupSpellChecker {
init() {
if (ConfigUtil.getConfigItem('enableSpellchecker')) {
this.enableSpellChecker();
}
this.enableContextMenu();
}

enableSpellChecker() {
try {
this.SpellCheckHandler = new SpellCheckHandler();
} catch (err) {
console.log(err);
}
}

enableContextMenu() {
if (this.SpellCheckHandler) {
this.SpellCheckHandler.attachToInput();

const userLanguage = ConfigUtil.getConfigItem('spellcheckerLanguage');

// eslint-disable-next-line no-unused-expressions
process.platform === 'darwin' ?
// On macOS, spellchecker fails to auto-detect the lanugage user is typing in
// that's why we need to mention it explicitly
this.SpellCheckHandler.switchLanguage(userLanguage) :
// On Linux and Windows, spellchecker can automatically detects the language the user is typing in
// and silently switches on the fly; thus we can start off as US English
this.SpellCheckHandler.switchLanguage('en-US');
}

const contextMenuBuilder = new ContextMenuBuilder(this.SpellCheckHandler);
this.contextMenuListener = new ContextMenuListener(info => {
contextMenuBuilder.showPopupMenu(info);
});
}

unsubscribeSpellChecker() {
// eslint-disable-next-line no-undef
if (this.SpellCheckHandler) {
this.SpellCheckHandler.unsubscribe();
}
if (this.contextMenuListener) {
this.contextMenuListener.unsubscribe();
}
}
}

module.exports = {
spellChecker
};
module.exports = new SetupSpellChecker();