Compare commits

..

26 Commits

Author SHA1 Message Date
akashnimare
7194e788e4 Add a setting option to control auto-updates 2017-09-12 21:43:53 +05:30
Akash Nimare
6dd79b205c Merge pull request #293 from cedricium/shortcut-settings
Adding keyboard shortcuts to Settings page
2017-09-11 20:23:11 +05:30
Cedricium
538c18fa90 Shorten 'Keyboard Shortcuts' to just 'Shortcuts' 2017-09-11 07:39:19 -07:00
Cedricium
29e347c511 List application-specific shortcuts only 2017-09-10 14:07:04 -07:00
Cedricium
ad37a5e0a6 Changed 'Ctrl/Cmd' to appropriate user OS key
If Windows or Linux, variable `userOSKey` will be 'Ctrl'. For Macs, `userOSKey`
will be '⌘' and these values will show up in place of the previous 'Ctrl/Cmd' keys.
2017-09-10 00:32:06 -07:00
Cedricium
352b775e27 Added all keyboard shortcuts
Finished adding all keyboard shortcuts to the Settings page. Styled the tables
such that they are uniform with their columns being the same
width.

At the bottom of the 'Keyboard Shortcuts' settings page, a link to the
complete keyboard shortcuts documentation
(https://chat.zulip.org/help/keyboard-shortcuts) was also added.
2017-09-09 22:39:34 -07:00
Cedricium
38cec25680 Adding keyboard shortcuts in Settings
This is the initial pass at adding keyboard shortcuts to the Settings page. In
this commit, the `ShortcutsSection` class has been created and is applied to a
newly-added 'Keyboard Shortcuts' nav item. The template for ShortcutsSection
is essentially multiple settings cards containing one table of keyboard short-
cuts organized by their underlying functionality.

The HTML `<kbd>` tag was defined in preference.css which styles the element to
look like a keyboard key, similar to StackOverflow or GitHub.
2017-09-09 19:11:19 -07:00
Akash Nimare
f77ab92202 Merge pull request #287 from vbNETonIce/patch-1
Windows set up instructions
2017-09-08 16:51:20 +05:30
Akash Nimare
e843a29316 Update Windows.md 2017-09-08 16:50:59 +05:30
akashnimare
85837242e7 Add back tray icon on windows #289 2017-09-08 05:17:14 +05:30
akashnimare
9f6da5712e Add show/hide desktop notification setting #192 2017-09-08 04:27:15 +05:30
akashnimare
158685a869 code refactor for mouse events 2017-09-07 22:50:20 +05:30
Akash Nimare
288b1cb3f2 Merge pull request #290 from zulip/clear-settings
Added Clear app settings menu item
2017-09-07 22:36:43 +05:30
akashnimare
e24a966d48 Add shortcut for clearing app data 2017-09-07 03:34:30 +05:30
akashnimare
306feb2eff reset window position 2017-09-07 03:29:04 +05:30
akashnimare
f426c932b0 Relaunch app on clearing app data 2017-09-06 16:23:56 +05:30
Akash Nimare
26172d8508 Merge pull request #288 from vbNETonIce/patch-2
tiny change in wording of new reset data option
2017-09-06 16:07:17 +05:30
vbNETonIce
99da0a338f tiny change in wording of new reset data option 2017-09-06 12:36:20 +02:00
akashnimare
9599249b31 Add reset app settings menu item #286 2017-09-06 15:23:22 +05:30
vbNETonIce
4bdd2564b7 Windows set up instructions 2017-09-06 08:57:13 +02:00
Akash Nimare
4dcf22a53c Merge pull request #285 from zulip/reset-data-setting
Add reset app data setting #192
2017-09-06 04:08:37 +05:30
akashnimare
0dc97648a0 code refactor 2017-09-06 03:54:25 +05:30
akashnimare
787f097cf3 style reset data button 2017-09-06 03:42:39 +05:30
akashnimare
5481d55c66 remove clear cache menu items 2017-09-06 03:26:56 +05:30
akashnimare
2a052b2c38 Added reset app data functionality [WIP] 2017-09-06 03:15:23 +05:30
akashnimare
bcabb615b4 clear app data setting option [WIP] 2017-08-29 04:26:16 +05:30
11 changed files with 568 additions and 35 deletions

View File

@@ -49,6 +49,10 @@ function createMainWindow() {
defaultWidth: 1000,
defaultHeight: 600
});
// Let's keep the window position global so that we can access it in other process
global.mainWindowState = mainWindowState;
const win = new electron.BrowserWindow({
// This settings needs to be saved in config
title: 'Zulip',
@@ -188,6 +192,12 @@ app.on('ready', () => {
page.send('destroytray');
});
ipcMain.on('clear-app-settings', () => {
global.mainWindowState.unmanage(mainWindow);
app.relaunch();
app.exit();
});
ipcMain.on('toggle-app', () => {
if (mainWindow.isVisible()) {
mainWindow.hide();

View File

@@ -1,6 +1,10 @@
'use strict';
const os = require('os');
const {dialog, app, shell, BrowserWindow, Menu} = require('electron');
const path = require('path');
const { app, shell, BrowserWindow, Menu } = require('electron');
const fs = require('fs-extra');
const ConfigUtil = require(__dirname + '/../renderer/js/utils/config-util.js');
@@ -164,7 +168,7 @@ class AppMenu {
}
getDarwinTpl(props) {
const {tabs, activeTabIndex} = props;
const { tabs, activeTabIndex } = props;
return [{
label: `${app.getName()}`,
@@ -196,9 +200,10 @@ class AppMenu {
}, {
type: 'separator'
}, {
label: 'Clear Cache',
label: 'Reset App Settings',
accelerator: 'Command+Shift+D',
click() {
AppMenu.clearCache();
AppMenu.resetAppSettings();
}
}, {
label: 'Log Out',
@@ -263,7 +268,7 @@ class AppMenu {
}
getOtherTpl(props) {
const {tabs, activeTabIndex} = props;
const { tabs, activeTabIndex } = props;
return [{
label: 'File',
@@ -297,9 +302,10 @@ class AppMenu {
}, {
type: 'separator'
}, {
label: 'Clear Cache',
label: 'Reset App Settings',
accelerator: 'Ctrl+Shift+D',
click() {
AppMenu.clearCache();
AppMenu.resetAppSettings();
}
}, {
label: 'Log Out',
@@ -363,11 +369,11 @@ class AppMenu {
win.webContents.send(action, ...params);
}
static clearCache() {
const win = BrowserWindow.getAllWindows()[0];
const ses = win.webContents.session;
ses.clearCache(() => {
dialog.showMessageBox({type: 'info', buttons: [], message: 'Cache cleared!'});
static resetAppSettings() {
const getAppPath = path.join(app.getPath('appData'), appName, 'window-state.json');
fs.unlink(getAppPath, () => {
setTimeout(() => AppMenu.sendAction('clear-app-data'), 1000);
});
}

View File

@@ -4,11 +4,49 @@ body {
margin: 0;
cursor: default;
user-select: none;
font-family: menu, "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 14px;
color: #333;
background: #efefef;
}
kbd {
padding: 0.1em 0.6em;
border: 1px solid #ccc;
font-size: 12px;
font-family: Arial,Helvetica,sans-serif;
background-color: #f7f7f7;
color: #333;
-moz-box-shadow: 0 1px 0px rgba(0, 0, 0, 0.2),0 0 0 2px #ffffff inset;
-webkit-box-shadow: 0 1px 0px rgba(0, 0, 0, 0.2),0 0 0 2px #ffffff inset;
box-shadow: 0 1px 0px rgba(0, 0, 0, 0.2),0 0 0 2px #ffffff inset;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
display: inline-block;
margin: 0 0.1em;
text-shadow: 0 1px 0 #fff;
line-height: 1.4;
white-space: nowrap;
}
table, th, td {
border: 1px solid #ddd;
border-collapse: collapse;
}
table { width: 85%; }
table tr:nth-child(even) { background-color: #f2f2f2; }
td { padding: 5px; }
td:nth-child(odd) {
text-align: right;
width: 50%;
}
@font-face {
font-family: 'Material Icons';
font-style: normal;
@@ -247,4 +285,30 @@ i.open-tab-button {
padding: 0 5px;
font-size: 18px;
cursor: pointer;
}
.reset-data-button {
display: inline-block;
width: 120px;
cursor: pointer;
font-size: 11px;
transition: background-color 0.2s ease;
text-decoration: none;
}
.reset-data-button:hover {
background-color: #32a692;
color: #fff;
}
#open-shortcuts-url {
color: #08c;
cursor: pointer;
text-decoration: none;
}
#open-shortcuts-url:hover {
color: #005580;;
text-decoration: underline;
}

View File

@@ -1,9 +1,9 @@
'use strict';
require(__dirname + '/js/tray.js');
const {ipcRenderer, remote} = require('electron');
const { ipcRenderer, remote } = require('electron');
const {session} = remote;
const { session } = remote;
const DomainUtil = require(__dirname + '/js/utils/domain-util.js');
const WebView = require(__dirname + '/js/components/webview.js');
@@ -116,17 +116,17 @@ class ServerManagerView {
this.$settingsButton.addEventListener('click', () => {
this.openSettings('General');
});
this.$reloadButton.addEventListener('mouseover', () => {
this.$reloadTooltip.removeAttribute('style');
this.sidebarHoverEvent(this.$settingsButton, this.$settingsTooltip);
this.sidebarHoverEvent(this.$reloadButton, this.$reloadTooltip);
}
sidebarHoverEvent(SidebarButton, SidebarTooltip) {
SidebarButton.addEventListener('mouseover', () => {
SidebarTooltip.removeAttribute('style');
});
this.$reloadButton.addEventListener('mouseout', () => {
this.$reloadTooltip.style.display = 'none';
});
this.$settingsButton.addEventListener('mouseover', () => {
this.$settingsTooltip.removeAttribute('style');
});
this.$settingsButton.addEventListener('mouseout', () => {
this.$settingsTooltip.style.display = 'none';
SidebarButton.addEventListener('mouseout', () => {
SidebarTooltip.style.display = 'none';
});
}
@@ -301,6 +301,10 @@ class ServerManagerView {
ipcRenderer.send('reload-full-app');
});
ipcRenderer.on('clear-app-data', () => {
ipcRenderer.send('clear-app-settings');
});
ipcRenderer.on('switch-server-tab', (event, index) => {
this.activateTab(index);
});

View File

@@ -1,6 +1,6 @@
'use strict';
const {remote} = require('electron');
const { remote } = require('electron');
const ConfigUtil = require(__dirname + '/utils/config-util.js');
@@ -12,11 +12,13 @@ app.setAppUserModelId('org.zulip.zulip-electron');
const NativeNotification = window.Notification;
class SilentNotification extends NativeNotification {
class baseNotification extends NativeNotification {
constructor(title, opts) {
opts.silent = ConfigUtil.getConfigItem('silent') || false;
super(title, opts);
// calling super without passing arguments will fail to constuct Notification
// and will result in no notification. It's a hack (not an ideal way) for deleting the window notification
ConfigUtil.getConfigItem('showNotification') ? super(title, opts) : super(); // eslint-disable-line no-unused-expressions
}
}
window.Notification = SilentNotification;
window.Notification = baseNotification;

View File

@@ -1,5 +1,10 @@
'use strict';
const path = require('path');
const { ipcRenderer } = require('electron');
const { app, dialog } = require('electron').remote;
const fs = require('fs-extra');
const BaseSection = require(__dirname + '/base-section.js');
const ConfigUtil = require(__dirname + '/../../utils/config-util.js');
@@ -29,9 +34,13 @@ class GeneralSection extends BaseSection {
</div>
</div>
<div class="title">Desktop Notification</div>
<div class="settings-card">
<div class="settings-card">
<div class="setting-row" id="show-notification-option">
<div class="setting-description">Show Desktop Notifications</div>
<div class="setting-control"></div>
</div>
<div class="setting-row" id="silent-option">
<div class="setting-description">Mute all sounds from Zulip (requires reload)</div>
<div class="setting-description">Mute all sounds from Zulip</div>
<div class="setting-control"></div>
</div>
</div>
@@ -41,6 +50,10 @@ class GeneralSection extends BaseSection {
<div class="setting-description">Get beta updates</div>
<div class="setting-control"></div>
</div>
<div class="setting-row" id="autoupdate-option">
<div class="setting-description">Automatically install new updates</div>
<div class="setting-control"></div>
</div>
</div>
<div class="title">Functionality</div>
<div class="settings-card">
@@ -49,6 +62,14 @@ class GeneralSection extends BaseSection {
<div class="setting-control"></div>
</div>
</div>
<div class="title">Reset Application Data</div>
<div class="settings-card">
<div class="setting-row" id="resetdata-option">
<div class="setting-description">This will delete all application data including all added accounts and preferences
</div>
<button class="reset-data-button green">Reset App Data</button>
</div>
</div>
</div>
`;
}
@@ -58,9 +79,12 @@ class GeneralSection extends BaseSection {
this.updateTrayOption();
this.updateBadgeOption();
this.updateUpdateOption();
this.updateAutoUpdateOption();
this.updateSilentOption();
this.updateSidebarOption();
this.updateStartAtLoginOption();
this.updateResetDataOption();
this.showDesktopNotification();
}
updateTrayOption() {
@@ -101,6 +125,18 @@ class GeneralSection extends BaseSection {
});
}
updateAutoUpdateOption() {
this.generateSettingOption({
$element: document.querySelector('#autoupdate-option .setting-control'),
value: ConfigUtil.getConfigItem('autoUpdate', true),
clickHandler: () => {
const newValue = !ConfigUtil.getConfigItem('autoUpdate');
ConfigUtil.setConfigItem('autoUpdate', newValue);
this.updateAutoUpdateOption();
}
});
}
updateSilentOption() {
this.generateSettingOption({
$element: document.querySelector('#silent-option .setting-control'),
@@ -113,6 +149,18 @@ class GeneralSection extends BaseSection {
});
}
showDesktopNotification() {
this.generateSettingOption({
$element: document.querySelector('#show-notification-option .setting-control'),
value: ConfigUtil.getConfigItem('showNotification', true),
clickHandler: () => {
const newValue = !ConfigUtil.getConfigItem('showNotification', true);
ConfigUtil.setConfigItem('showNotification', newValue);
this.showDesktopNotification();
}
});
}
updateSidebarOption() {
this.generateSettingOption({
$element: document.querySelector('#sidebar-option .setting-control'),
@@ -139,6 +187,31 @@ class GeneralSection extends BaseSection {
});
}
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());
dialog.showMessageBox({
type: 'warning',
buttons: ['YES', 'NO'],
defaultId: 0,
message: 'Are you sure',
detail: clearAppDataMessage
}, response => {
if (response === 0) {
fs.remove(getAppPath);
setTimeout(() => ipcRenderer.send('forward-message', 'hard-reload'), 1000);
}
});
}
updateResetDataOption() {
const resetDataButton = document.querySelector('#resetdata-option .reset-data-button');
resetDataButton.addEventListener('click', () => {
this.clearAppDataDialog();
});
}
}
module.exports = GeneralSection;

View File

@@ -8,7 +8,7 @@ class PreferenceNav extends BaseComponent {
this.props = props;
this.navItems = ['General', 'Network', 'Servers'];
this.navItems = ['General', 'Network', 'Servers', 'Shortcuts'];
this.init();
}

View File

@@ -7,6 +7,7 @@ const Nav = require(__dirname + '/js/pages/preference/nav.js');
const ServersSection = require(__dirname + '/js/pages/preference/servers-section.js');
const GeneralSection = require(__dirname + '/js/pages/preference/general-section.js');
const NetworkSection = require(__dirname + '/js/pages/preference/network-section.js');
const ShortcutsSection = require(__dirname + '/js/pages/preference/shortcuts-section.js');
class PreferenceView extends BaseComponent {
constructor() {
@@ -56,6 +57,12 @@ class PreferenceView extends BaseComponent {
});
break;
}
case 'Shortcuts': {
this.section = new ShortcutsSection({
$root: this.$settingsContainer
});
break;
}
default: break;
}
this.section.init();

View File

@@ -0,0 +1,311 @@
'use strict';
const BaseSection = require(__dirname + '/base-section.js');
class ShortcutsSection extends BaseSection {
constructor(props) {
super();
this.props = props;
}
templateMac() {
const userOSKey = '⌘';
return `
<div class="settings-pane">
<div class="title">Application Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>,</kbd></td>
<td>Settings</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>K</kbd></td>
<td>Keyboard Shortcuts</td>
</tr>
<tr>
<td><kbd>Shift</kbd><kbd>${userOSKey}</kbd><kbd>D</kbd></td>
<td>Reset App Settings</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>L</kbd></td>
<td>Log Out</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>H</kbd></td>
<td>Hide Zulip</td>
</tr>
<tr>
<td><kbd>Option</kbd><kbd>${userOSKey}</kbd><kbd>H</kbd></td>
<td>Hide Others</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>Q</kbd></td>
<td>Quit Zulip</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
<div class="title">Edit Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>Z</kbd></td>
<td>Undo</td>
</tr>
<tr>
<td><kbd>Shift</kbd><kbd>${userOSKey}</kbd><kbd>Z</kbd></td>
<td>Redo</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>X</kbd></td>
<td>Cut</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>C</kbd></td>
<td>Copy</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>V</kbd></td>
<td>Paste</td>
</tr>
<tr>
<td><kbd>Shift</kbd><kbd>${userOSKey}</kbd><kbd>V</kbd></td>
<td>Paste and Match Style</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>A</kbd></td>
<td>Select All</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>F</kbd></td>
<td>Find</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>G</kbd></td>
<td>Find Next</td>
</tr>
<tr>
<td><kbd>Control</kbd><kbd>${userOSKey}</kbd><kbd>Space</kbd></td>
<td>Emoji & Symbols</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
<div class="title">View Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>R</kbd></td>
<td>Reload</td>
</tr>
<tr>
<td><kbd>Shift</kbd><kbd>${userOSKey}</kbd><kbd>R</kbd></td>
<td>Hard Reload</td>
</tr>
<tr>
<td><kbd>Control</kbd><kbd>${userOSKey}</kbd><kbd>F</kbd></td>
<td>Enter Full Screen</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>=</kbd></td>
<td>Zoom In</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>-</kbd></td>
<td>Zoom Out</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>0</kbd></td>
<td>Actual Size</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>S</kbd></td>
<td>Toggle Sidebar</td>
</tr>
<tr>
<td><kbd>Option</kbd><kbd>${userOSKey}</kbd><kbd>I</kbd></td>
<td>Toggle DevTools for Zulip App</td>
</tr>
<tr>
<td><kbd>Option</kbd><kbd>${userOSKey}</kbd><kbd>U</kbd></td>
<td>Toggle DevTools for Active Tab</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
<div class="title">History Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>←</kbd></td>
<td>Back</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>→</kbd></td>
<td>Forward</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
<div class="title">Window Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>M</kbd></td>
<td>Minimize</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd><kbd>W</kbd></td>
<td>Close</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
</div>
`;
}
templateWinLin() {
const userOSKey = 'Ctrl';
return `
<div class="settings-pane">
<div class="title">Application Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>,</kbd></td>
<td>Settings</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>K</kbd></td>
<td>Keyboard Shortcuts</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>L</kbd></td>
<td>Log Out</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>Q</kbd></td>
<td>Quit Zulip</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
<div class="title">Edit Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>Z</kbd></td>
<td>Undo</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>Y</kbd></td>
<td>Redo</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>X</kbd></td>
<td>Cut</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>C</kbd></td>
<td>Copy</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>V</kbd></td>
<td>Paste</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd></td>
<td>Paste and Match Style</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>A</kbd></td>
<td>Select All</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
<div class="title">View Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>R</kbd></td>
<td>Reload</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>R</kbd></td>
<td>Hard Reload</td>
</tr>
<tr>
<td><kbd>F11</kbd></td>
<td>Toggle Full Screen</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>=</kbd></td>
<td>Zoom In</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>-</kbd></td>
<td>Zoom Out</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>0</kbd></td>
<td>Actual Size</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>S</kbd></td>
<td>Toggle Sidebar</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>I</kbd></td>
<td>Toggle DevTools for Zulip App</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>U</kbd></td>
<td>Toggle DevTools for Active Tab</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
<div class="title">History Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>Alt</kbd> + <kbd>←</kbd></td>
<td>Back</td>
</tr>
<tr>
<td><kbd>Alt</kbd> + <kbd>→</kbd></td>
<td>Forward</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
<div class="title">Window Shortcuts</div>
<div class="settings-card">
<table>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>M</kbd></td>
<td>Minimize</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>W</kbd></td>
<td>Close</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
</div>
`;
}
init() {
this.props.$root.innerHTML = (process.platform === 'darwin') ?
this.templateMac() : this.templateWinLin();
}
}
module.exports = ShortcutsSection;

View File

@@ -180,11 +180,10 @@ ipcRenderer.on('tray', (event, arg) => {
if (!window.tray) {
return;
}
// We don't want to create tray from unread messages on windows and macOS since these systems already have dock badges and taskbar overlay icon.
if (process.platform === 'linux') {
// We don't want to create tray from unread messages on macOS since it already has dock badges.
if (process.platform === 'linux' || process.platform === 'win32') {
if (arg === 0) {
unread = arg;
// Message Count // console.log("message count is zero.");
window.tray.setImage(iconPath());
window.tray.setToolTip('No unread messages');
} else {
@@ -206,7 +205,7 @@ function toggleTray() {
ConfigUtil.setConfigItem('trayIcon', false);
} else {
createTray();
if (process.platform === 'linux') {
if (process.platform === 'linux' || process.platform === 'win32') {
renderNativeImage(unread).then(image => {
window.tray.setImage(image);
window.tray.setToolTip(unread + ' unread messages');

View File

@@ -1 +1,58 @@
** Windows Set up instructions **
## Prerequisites
* [Git](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [Node.js](https://nodejs.org) >= v6.9.0
* [python](https://www.python.org/downloads/release/python-2713/) (v2.7.x recommended)
* [node-gyp](https://github.com/nodejs/node-gyp#installation) (installed via powershell)
## System specific dependencies
* use only 32bit or 64bit for all of the installers, do not mix architectures
* install using default settings
* open Windows Powershell as Admin
```powershell
C:\Windows\system32> npm install --global --production windows-build-tools
```
## Installation
Clone the source locally:
```sh
$ git clone https://github.com/zulip/zulip-electron
$ cd zulip-electron
```
Install project dependencies:
```sh
$ npm install
```
Start the app:
```sh
$ npm start
```
Start and watch changes
```sh
$ npm run dev
```
### Making a release
To package app into an installer use command:
```
npm run pack
npm run dist
```
It will start the packaging process. The ready for distribution file (e.g. dmg, windows installer, deb package) will be outputted to the `dist` directory.
# Troubleshooting
If you have any problems running the app please see the [most common issues](./troubleshooting.md).