Compare commits

..

101 Commits

Author SHA1 Message Date
Akash Nimare
6f74fea0f3 release: New release v3.0.0. 2019-05-21 02:58:23 +05:30
Akash Nimare
405d938223 Update docs and code to point to new repo url.
This is because we have changed the repo name to zulip-desktop.
2019-05-21 02:33:13 +05:30
ViPuL
c6b7e9a9ee settings: Add option to toggle Error Reporting.
Adds an option to enable or disable sentry error
reporting under Advanced section in General Settings. 
Handles both main and renderer processes.

Also, changes the domain used to resolve proxy
in proxy-util from google.com to example.com.

Fixes #702.
2019-05-15 15:00:22 +05:30
Akash Nimare
b4073ba7ac Update package.json 2019-05-12 03:24:23 +05:30
Akash Nimare
b504f31c26 config: Remove unused icon file. 2019-05-12 03:20:22 +05:30
Akash Nimare
f71660b3f0 builder: Update electron-builder to v20.40.2. 2019-05-12 03:16:38 +05:30
Akash Nimare
5d0516887d windows: Add a config for installer name.
There is a bug with electron-builder where it doesn't name the installer properly. 
Without this config, it always names the installer with spaces in between 
i.e. "Zulip Web Setup.exe".
2019-05-12 03:14:41 +05:30
ViPuL
0dd86f0814 nsis: Allow installing app without admin previliges.
Allow the nsis installer to install the app to
AppData for a single user so that administrator
previliges are not required while installing.

Fixes #720.
2019-05-12 02:46:19 +05:30
Rhythm Sharma
eaecc92055 spellchecker: Use server language for spellchecker for all platforms.
This is an experimental fix for spellchecker. Previously, we were only using this on macOS since on other platforms, the spellcheck-module claimed to auto-detect + switch language on the fly but looks like it's not working as expected.
2019-05-10 03:43:49 +05:30
ViPuL
4f65c36a72 menu: Remove minimize and close from File menu.
Remove duplicate entries of minimize and close from
File menu as they are already present in Window menu.
2019-05-04 14:57:58 +05:30
ViPuL
2380b650c9 focus: Fix focus after clicking back button.
Addresses the issue of the webview not being in focus
after the Back button is clicked. Now, the webview is focused
explicitly by calling focus() on click.
2019-05-03 22:03:03 +05:30
ViPuL
1d713f1df2 logs: Limit the number of lines in log files.
Limits the numbers of lines in log files to 500.

Fixes a part of #727.
2019-05-03 14:57:00 +05:30
ViPuL
7fa9c291cb lint: Implement HTML Linting with htmlhint and fix indent.
* lint: Implement HTML Linting with htmlhint and fix indent.

Implements HTML linting using htmlhint and uses
indentation rules of zulip webapp - 4 spaces.
Creates a separate file .htmlhintrc for the rules, most
of which are defaults. Also, fixes indentation in html
files and adds a missing title in about.html.

* deps: Change versioning of various dependencies to exact versions.

As we prefer to use exact working version
for dependencies, changed the versions to
exact versions.

Fixes #676.
2019-04-24 00:44:01 +05:30
ViPuL
8a40e36a63 lint: Update css lint config to match zulip config.
Updated .stylelintrc to match zulip webapp's
.stylelintrc file. Also, made the required changes
to all CSS files.

Fixes remaining CSS part of #676.
2019-04-21 17:10:26 +05:30
Kanishk Kakar
3456720135 Unify case across menus and settings.
* menu: Convert to title case.

Also, change corresponding shortcuts to title case.

* settings: Convert options to sentence case.
2019-04-18 19:38:01 +05:30
Abhigyan Khaund
43840a5245 webview: Add "role" key to webview property. 2019-04-18 19:35:21 +05:30
ViPuL
d99c29301e lint: Implement CSS linting with stylelint.
* lint: Implement CSS linting with stylelint.
* lint: Format CSS files according to lintconfig.

Adds CSS linting following the rules of zulip webapp.
Some rules have been ommitted because they required
significant changes in code. Also, creates a separate
.stylelintrc for storing css config.

Fixes CSS part of #676.
2019-04-15 16:54:02 +05:30
ViPuL
6e760973ff shortcut: Allow zoom options from numpad.
Numpad keys by default aren't supported by electron
for using in menu accelarators. Uses a workaround to
make zoom options work with Numpad keys.

Fixes: #344.
2019-04-12 17:16:04 +05:30
Rhythm Sharma
88c64e9dd6 docs: improve development guide.
Update development instructions for all the systems.
2019-04-12 17:11:08 +05:30
Rhythm Sharma
e9db11c156 shortcuts-section: Fix tip's place for Windows & Linux. 2019-04-12 17:03:15 +05:30
ViPuL
8e8de212d8 menu: Reorder file menu and add option to Add Organization.
Reorder the File Menu. Also, adds a new option to
add a new organization to the file menu.
2019-04-10 22:03:43 +05:30
Puneeth Chaganti
0e0d7e7c4a webview: Work around buggy focus switching in Electron 3.0.10.
This commit works around a couple of bugs, which seem to be upstream bugs in the
current version of Electron.

First, `webContents.isFocused()` seems to be true even if we just switched to
a tab, and are trying to set it as the focused element. To work around this, we
check if the `webview` element is the same as `document.activeElement`.

Also, as per https://github.com/electron/electron/issues/15718, it looks like
`blur` needs to be called on the currently active element, before switching
focus on another element i.e., calling `focus` on it.

Fixes: #634.
2019-04-05 15:34:39 +05:30
ViPuL
6b98a49245 webview: fix focus after soft reload.
Fixes: #697.
2019-04-04 20:35:31 +05:30
ViPuL
8e5c326d74 context-menu: Add option to copy zulip url.
Added, "copy Zulip URL" in 
* Context menu in left sidebar 
* Application menu item

Fixes: #649.
2019-04-04 00:35:23 +05:30
Rhythm Sharma
862e9e2c8c DND: Fix text for Toggle DND in sidebar on hover. 2019-04-04 00:21:59 +05:30
Akash Nimare
8a0b047d8f snap: Update snap config.
Updating the config as suggested by the snap community here - 
https://forum.snapcraft.io/t/snap-fails-to-load-error-minidump-segmentation-fault/8691/5

Should improve #593.
2019-04-03 16:37:33 +05:30
Akash Nimare
4a833ef603 docs: Fix typo error in issue template. 2019-04-02 16:13:44 +05:30
ViPuL
fefb7247d8 domain-util: add requestOptions to replace request instances.
This simplifies the request instances.

Fixes #603.
2019-04-02 16:11:23 +05:30
ViPuL
54a6903236 sidebar: Fix organization cycling using Ctrl+Tab.
This fixes two issues -
a) While on the first server, Ctrl+Shift+Tab doesn't work. This fixes that and now cycles to the last active webview.
b) Disable org cycling for non-server pages likes settings.

Fixes #691.
2019-04-01 17:34:08 +05:30
Rhythm Sharma
92ef1bd532 settings: Modify reset app data button. 2019-03-23 16:20:34 +05:30
Kanishk Kakar
bf2e04b3bb sidebar: Switch to next server on Ctrl+Tab.
* Adds a new option to the Window menu that allows users to change to the
next organization cyclically. Activated by Ctrl + Tab.
* Switch to the previous server on Ctrl + Shift + Tab.
2019-03-20 22:15:25 +05:30
ViPuL
3e389ea5db requests: Allow insecure requests on user request.
In certain requests like for fetching realm icons, request tries to verify server certificate and fails when the user has chosen to ignore cert warnings and has not uploaded the cert.
In those cases, we should mark that this server verification is ignored and ask request to ignore the cert verification bypassing that parameter.

Fixes #684.
2019-03-18 23:18:06 +05:30
SankalpSh
8edff28daa changelog: Fix grammatical errors. 2019-03-13 14:04:44 +05:30
Kanishk Kakar
ef6abbf49e settings: Default to starting app on login.
Acts on an observation that it is easier to turn off auto-start on login
than it is to turn on.
2019-03-12 20:35:20 +05:30
Ján Hrnko
0f638dd4b5 docs: Fix broken link.
Fix broken link http://jlord.us/essential-electron/ to https://jlord.dev/blog/essential-electron
2019-03-02 23:33:54 +05:30
Akash Nimare
92f0e46927 New beta release v2.5.0. 2019-03-01 18:51:38 +05:30
Rhythm Sharma
a0dd3832c2 settings: Shorcut section horizontal alignment fix. 2019-02-18 17:11:27 +05:30
ViPuL
a2e84595c9 pdf-viewer: disable pdf-viewer window.
Disable the pdf window for now since this is broken in v3
of electron.

Fixes #640.
2019-02-09 14:04:50 +05:30
Kanishk Kakar
9e33ebae62 context-menu: Fix context menu indexing.
Addresses a problem where the context menu would get the incorrect index
of server in sidebar and cause a crash when attempting to remove the
server.

Add comment justifying extra index parameter.
2019-01-30 12:22:36 +05:30
Abhigyan Khaund
9bdc5dd9e4 certificate: Use path.basename to get certificate file name. 2019-01-24 11:15:40 +05:30
Puneeth Chaganti
ac89ac1cb4 Browser-window: Change the window title to contain active Realm's name. 2019-01-23 13:35:18 +05:30
Abhigyan Khaund
31da1131a4 certificate: Use path.sep for path separator to support Windows.
Fixes the certificate path issue on Windows.
2019-01-21 21:44:23 +05:30
Priyank Patel
4980c71e5a notification: Ensure backward compatibilty when using narrow.by_topic.
We should ensure backward compatibilty when using narrow.by_topic since
the recent rename in the webapp of the function narrow.by_subject to
narrow.by_topic is only in master and not in any stable release yet it
could break the notification function for many people. Furthermore this ensure
general backward-compatibilty.
2019-01-08 21:57:13 +05:30
Akash Nimare
3e73511357 notification: Fix reply from notification.
The function "by_subject" is now being updated to the "by_topic" in
the webapp.

Fixes: #624.
2019-01-08 11:30:57 +05:30
Akash Nimare
5f23c8570b security: Update dependencies to fix minor dev security alerts. 2019-01-07 18:10:41 +05:30
Akash Nimare
12f79e18a1 test: Update test config files. 2019-01-07 12:27:20 +05:30
Akash Nimare
ad7f760444 windows: Install per user on Windows.
The official docs of the electron-builder says to install
the app per user on a particular system instead of all users.
2019-01-07 12:21:16 +05:30
Kanishk Kakar
7314c1f1dd context-menu: Fix Context Menu not working properly.
This fixes a case where the context menu doesn't work as expected. This used to happen when we
show the character icon.

Fixes: #608.
2018-12-30 20:48:38 +05:30
Akash Nimare
46c3d352a1 release: 🎉 new release v2.4.0. 2018-12-24 23:11:01 +05:30
Akash Nimare
cef8eadc8f sentry: Update electron-sentry to v0.14.0. 2018-12-24 23:08:49 +05:30
Akash Nimare
d3f742719c builder: Update electron builder to v20.38.4.
Also, updated electron-updater to v4.0.6.

Fixes: #618.
2018-12-24 20:17:18 +05:30
Priyank Patel
171d88755c electron: Update electron to v3.0.10.
* dependecies: Upgrade electron to v3.0.10.

This also makes sure we don't pass properties on this.tabs
that makes ipcRenderer crash on v3.x.x.

* tray: Use new way for using nativeImage.createFromBuffer.

The previous way of passing scaleFactor as a second argument
is now deprecated and will be a breaking change in 4.0

* app: Use new requestSingleInstanceLock api and remove deceprated makeSingleInstance.

* Update node-mac-notifier to v1.1.0.
2018-12-22 19:44:44 +05:30
ThePiyushGupta
09ac1bd338 setting: Minimize to tray on startup.
This hides the taskbar icon if the start to minimized setting is turned on.

Fixes: #565.
2018-12-22 19:19:24 +05:30
Akash Nimare
48dd12b738 request: Send user-agent with request.
We now send the user-agent with the request.
Fixes #611.
2018-12-19 12:23:18 +05:30
Akash Nimare
61bbd1cf22 electron: Update electron to v2.0.15. 2018-12-17 13:25:34 +05:30
Akash Nimare
bf722da390 git: Ignore unnecessary binary files. 2018-12-12 15:42:59 +05:30
Akash Nimare
c24f5b3e45 lint: Add eol for linebreaks on windows. 2018-12-10 18:36:44 +05:30
Akash Nimare
3d0f4d88af settings: Increase width of add a new org button. 2018-12-07 15:05:11 +05:30
Akash Nimare
a2f412c3de Improve wording of adding a new org button. 2018-12-06 18:14:55 +05:30
Akash Nimare
08559c2f4a setting: Improve organization page.
This adds a new button in the connected organization
page by which a user can quickly add a new Zulip organization.

Fixes: #607.
2018-12-05 23:00:07 +05:30
Akash Nimare
1f4509a6d2 codebase: Fix a typo. 2018-12-05 20:01:44 +05:30
Akash Nimare
06c8b2e8a2 context-menu: Fix context menu not working on adding new org.
Two changes -
* Fixes the context menu not working on adding a new org. This is
because previously the context menu listner only called when loading
the app. Updated the same to fix the issue.
* Refactor the codebase for left-sidebar.

Improves #599.
2018-12-05 19:55:56 +05:30
Kanishk Kakar
2aa15ee11a context-menu: Add context menu in left sidebar.
This adds a context menu in the left sidebar. For now, there is one sub-item called - Disconnect organization by which a user can delete an added org from the app.

Fixes: #599.
2018-12-05 19:42:47 +05:30
Akash Nimare
3c676672ec shortcut: Document show sidebar shortcut properly.
Fixes: #606.
2018-12-05 13:42:40 +05:30
Abhigyan Khaund
c937317ecf domain-util: Include certificates in all requests for icon.
Fixes: #463.
2018-12-05 12:43:34 +05:30
Akash Nimare
44dceda50e dependency: Update electron-window-state to v5.0.3.
Fixes: #231.
2018-11-30 21:37:02 +05:30
Akash Nimare
e1407cb6f7 dependency: Update electron-window-state to v5.0.2. 2018-11-22 20:37:19 +05:30
Michel Tomas
6899a6bc20 network: Fix request ecdhCurve mismatch errors.
The HTTP Node now uses auto for ecdhCurve for SSL connections. This fixes the SSL
handshake error while connecting to some Zulip instances. Setting the ecdhCurve to auto
is the recommended method for Node > 8.5, more info here -
https://github.com/nodejs/node/issues/16196

Fixes: #594.
2018-11-19 16:11:23 +05:30
Akash Nimare
925fec71d5 Add release notes for v2.3.82. 2018-11-05 00:24:25 +05:30
Akash Nimare
f847c565f9 menu: Update menu items on setting page.
This PR adds a functionality to update the menu items.
Some menu items like logout, shortcut etc are not needed
on setting page. We can control the same using this flag.

Fixes: #587.
2018-10-28 15:11:40 +05:30
Kanishk Kakar
c2a380d308 setting: Disable beta updates if auto updates disabled.
* Disable beta updates if auto updates disabled
2018-10-27 23:22:14 +05:30
Akash Nimare
ac6b206583 sentry: Update sentry to v0.12.1. 2018-10-24 19:27:38 +05:30
Akash Nimare
988405c665 dependency: Update node-json-db to v0.9.1. 2018-10-24 14:07:07 +05:30
Akash Nimare
a209804692 setting: Set custom css to false by default. 2018-10-23 15:09:28 +05:30
Akash Nimare
95c4df1898 network: Fix typo in network error message. 2018-10-23 14:56:56 +05:30
Rishi Gupta
1048c91d9e about: Remove Found bug button. 2018-10-21 05:05:44 +05:30
Akash Nimare
d723c5cd1c proxy: Do not reload app when turning off the SPS setting. 2018-10-17 16:58:26 +05:30
Akash Nimare
dcc7cd118c release: 🎉 new release v2.3.82. 2018-10-11 21:53:25 +05:30
Abhigyan Khaund
d2649dd5d7 native-menus: Add tools submenu and reword a few options.
Check for Updates → Move to Tools
Reset App Settings → Move to Tools, rename “Factory reset”
Both Dev Tools → Move to Tools
Download App Logs → Move to Tools
What’s new → Move to Tools, and rename “Release notes”.
2018-10-10 13:53:25 +05:30
Akash Nimare
25e6f6d482 sentry: Update Sentry to v0.11.0.
This could potentially fix #577 since the issue is caused by Sentry.
2018-10-09 13:51:12 +05:30
Akash Nimare
bd805b8324 native-menus: Rename a few options of the submenus. 2018-10-07 19:17:31 +05:30
Abhigyan Khaund
e1d98e0d8e native-menus: Rename a few options of the submenus. 2018-10-07 17:41:57 +05:30
Akash Nimare
89e5d2892b readme: Replace the word team with organizations. 2018-10-04 00:37:49 +05:30
Akash Nimare
ab28b56377 tray: Remove about menu item and rename focus. 2018-10-03 20:47:24 +05:30
Abhigyan Khaund
71aa7e28ba readme: Replace word team with organizations. 2018-10-02 13:50:57 +05:30
Akash Nimare
ba2bfba459 settings: Rename custom css section. 2018-10-01 18:10:40 +05:30
Akash Nimare
d181b0c2e5 settings: Move custom css section to advanced. 2018-10-01 18:07:20 +05:30
Akash Nimare
bda5c62928 settings: Put shortcut tip on the top. 2018-10-01 17:53:11 +05:30
Akash Nimare
b2b4fd1003 settings: UI fixes in general settings. 2018-09-28 21:03:49 +05:30
Akash Nimare
19770f5fbf settings: Update wordings of org settings. 2018-09-28 13:28:47 +05:30
Akash Nimare
4592396c4b settings: Update wordings of general settings. 2018-09-28 13:18:06 +05:30
Akash Nimare
19d3c0f5b5 left-sidebar: Update the border-radius of org icon.
Org icon now have rounded squares.

Fixes: #574.
2018-09-28 13:06:19 +05:30
Akash Nimare
af87789c7f feedback: Upgrade send feedback to latest. 2018-09-27 19:43:18 +05:30
Priyank Patel
36e710dbfe gitattributes: Mark package-lock.json files binary.
So they don't show up during `git diff`.
2018-09-26 20:46:36 -04:00
Priyank Patel
a6e1c93d81 dependencies: Upgrade send-feedback module to v1.0.8.
Fixes: https://github.com/zulip/zulip-electron/issues/569
2018-09-26 20:46:36 -04:00
Akash Nimare
684d88dd7f menus: Rename a few menu items. 2018-09-26 13:44:51 +05:30
Akash Nimare
45aedbd9db tray: Add a separator in tray before quit item. 2018-09-26 13:44:01 +05:30
Akash Nimare
6f411a819c menu: Remove whitespace from app version. 2018-09-26 12:27:09 +05:30
Rishi Gupta
097738332b tray: Remove separators. 2018-09-25 12:43:32 -07:00
Rishi Gupta
b777f8a50f menus: Rename a few menu items. 2018-09-25 09:51:01 -07:00
Akash Nimare
50f06239bb Add release notes for v2.3.8. 2018-09-25 18:58:19 +05:30
49 changed files with 4637 additions and 1817 deletions

17
.gitattributes vendored
View File

@@ -1 +1,16 @@
* text=auto
* text=auto eol=lf
package-lock.json binary
app/package-lock.json binary
*.gif binary
*.jpg binary
*.jpeg binary
*.eot binary
*.woff binary
*.woff2 binary
*.svg binary
*.ttf binary
*.png binary
*.otf binary
*.tif binary
*.ogg binary

View File

@@ -2,7 +2,7 @@
<!-- Please Include: -->
- **Operating System**:
- [ ] Windows
- [ ] Linux/Ubutnu
- [ ] Linux/Ubuntu
- [ ] macOS
- **Clear steps to reproduce the issue**:
- **Relevant error messages and/or screenshots**:

2
.gitignore vendored
View File

@@ -33,6 +33,6 @@ yarn-error.log*
config.gypi
# Test generated files
tests/package.json
# tests/package.json
.python-version

25
.htmlhintrc Normal file
View File

@@ -0,0 +1,25 @@
{
"tagname-lowercase": true,
"attr-lowercase": true,
"attr-value-double-quotes": true,
"attr-value-not-empty": false,
"attr-no-duplication": true,
"doctype-first": true,
"tag-pair": true,
"empty-tag-not-self-closed": true,
"spec-char-escape": true,
"id-unique": true,
"src-not-empty": true,
"title-require": true,
"alt-require": false,
"doctype-html5": true,
"id-class-value": "dash",
"style-disabled": false,
"inline-style-disabled": false,
"inline-script-disabled": false,
"space-tab-mixed-disabled": "space4",
"id-class-ad-disabled": false,
"href-abs-or-rel": false,
"attr-unsafe-chars": true,
"head-script-disabled": true
}

67
.stylelintrc Normal file
View File

@@ -0,0 +1,67 @@
{
"rules": {
# Stylistic rules for CSS.
"function-comma-space-after": "always",
"function-comma-space-before": "never",
"function-max-empty-lines": 0,
"function-whitespace-after": "always",
"value-keyword-case": "lower",
"value-list-comma-newline-after": "always-multi-line",
"value-list-comma-space-after": "always-single-line",
"value-list-comma-space-before": "never",
"value-list-max-empty-lines": 0,
"unit-case": "lower",
"property-case": "lower",
"color-hex-case": "lower",
"declaration-bang-space-before": "always",
"declaration-colon-newline-after": "always-multi-line",
"declaration-colon-space-after": "always-single-line",
"declaration-colon-space-before": "never",
"declaration-block-semicolon-newline-after": "always",
"declaration-block-semicolon-space-before": "never",
"declaration-block-trailing-semicolon": "always",
"block-closing-brace-empty-line-before": "never",
"block-closing-brace-newline-after": "always",
"block-closing-brace-newline-before": "always",
"block-opening-brace-newline-after": "always",
"block-opening-brace-space-before": "always",
"selector-attribute-brackets-space-inside": "never",
"selector-attribute-operator-space-after": "never",
"selector-attribute-operator-space-before": "never",
"selector-combinator-space-after": "always",
"selector-combinator-space-before": "always",
"selector-descendant-combinator-no-non-space": true,
"selector-pseudo-class-parentheses-space-inside": "never",
"selector-pseudo-element-case": "lower",
"selector-pseudo-element-colon-notation": "double",
"selector-type-case": "lower",
"selector-list-comma-newline-after": "always",
"selector-list-comma-space-before": "never",
"media-feature-colon-space-after": "always",
"media-feature-colon-space-before": "never",
"media-feature-name-case": "lower",
"media-feature-parentheses-space-inside": "never",
"media-feature-range-operator-space-after": "always",
"media-feature-range-operator-space-before": "always",
"media-query-list-comma-newline-after": "always",
"media-query-list-comma-space-before": "never",
"at-rule-name-case": "lower",
"at-rule-name-space-after": "always",
"at-rule-semicolon-newline-after": "always",
"at-rule-semicolon-space-before": "never",
"comment-whitespace-inside": "always",
"indentation": 4,
# Limit language features
"color-no-hex": true,
"color-named": "never",
}
}

View File

@@ -2,20 +2,20 @@
Thanks for taking the time to contribute!
The following is a set of guidelines for contributing to Zulip Electron Desktop Client. These are just guidelines, not rules, so use your best judgement and feel free to propose changes to this document in a pull request.
The following is a set of guidelines for contributing to Zulip's desktop Client. These are just guidelines, not rules, so use your best judgement and feel free to propose changes to this document in a pull request.
## Getting Started
Zulip-Desktop app is built on top of [Electron](http://electron.atom.io/). If you are new to Electron, please head over to [this](http://jlord.us/essential-electron/) great article.
Zulip-Desktop app is built on top of [Electron](http://electron.atom.io/). If you are new to Electron, please head over to [this](https://jlord.dev/blog/essential-electron) great article.
## Community
* The whole Zulip documentation, such as setting up a development environment, setting up with the Zulip webapp project, and testing, can be read [here](https://zulip.readthedocs.io).
* If you have any questions regarding zulip-electron, open an [issue](https://github.com/zulip/zulip-electron/issues/new/) or ask it on [chat.zulip.org](https://chat.zulip.org/#narrow/stream/16-desktop).
* If you have any questions regarding zulip-desktop, open an [issue](https://github.com/zulip/zulip-desktop/issues/new/) or ask it on [chat.zulip.org](https://chat.zulip.org/#narrow/stream/16-desktop).
## Issue
Ensure the bug was not already reported by searching on GitHub under [issues](https://github.com/zulip/zulip-electron/issues). If you're unable to find an open issue addressing the bug, open a [new issue](https://github.com/zulip/zulip-electron/issues/new).
Ensure the bug was not already reported by searching on GitHub under [issues](https://github.com/zulip/zulip-desktop/issues). If you're unable to find an open issue addressing the bug, open a [new issue](https://github.com/zulip/zulip-desktop/issues/new).
The [zulipbot](https://github.com/zulip/zulipbot) helps to claim an issue by commenting the following in the comment section: "**@zulipbot** claim". **@zulipbot** will assign you to the issue and label the issue as **in progress**. For more details, check out [**@zulipbot**](https://github.com/zulip/zulipbot).
@@ -38,7 +38,7 @@ For example:
## Pull Requests
Pull Requests are always welcome.
Pull Requests are always welcome.
1. When you edit the code, please run `npm run test` to check the formatting of your code before you `git commit`.
2. Ensure the PR description clearly describes the problem and solution. It should include:

View File

@@ -1,6 +1,6 @@
# Zulip Desktop Client
[![Build Status](https://travis-ci.org/zulip/zulip-electron.svg?branch=master)](https://travis-ci.org/zulip/zulip-electron)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/zulip/zulip-electron?branch=master&svg=true)](https://ci.appveyor.com/project/akashnimare/zulip-electron/branch/master)
[![Build Status](https://travis-ci.org/zulip/zulip-desktop.svg?branch=master)](https://travis-ci.org/zulip/zulip-desktop)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/zulip/zulip-desktop?branch=master&svg=true)](https://ci.appveyor.com/project/zulip/zulip-desktop/branch/master)
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
[![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://chat.zulip.org)
@@ -12,7 +12,7 @@ Desktop client for Zulip. Available for Mac, Linux, and Windows.
Please see the [installation guide](https://zulipchat.com/help/desktop-app-install-guide).
# Features
* Sign in to multiple teams
* Sign in to multiple organizations
* Desktop notifications with inline reply
* Tray/dock integration
* Multi-language spell checker
@@ -20,7 +20,7 @@ Please see the [installation guide](https://zulipchat.com/help/desktop-app-insta
# Contribute
First, join us on the [Zulip community server](https://zulip.readthedocs.io/en/latest/contributing/chat-zulip-org.html)!
First, join us on the [Zulip community server](https://zulip.readthedocs.io/en/latest/contributing/chat-zulip-org.html)!
Also see our [contribution guidelines](./CONTRIBUTING.md) and our [development guide](./development.md).
# License

View File

@@ -32,18 +32,19 @@ let isQuitting = false;
// Load this url in main window
const mainURL = 'file://' + path.join(__dirname, '../renderer', 'main.html');
const isAlreadyRunning = app.makeSingleInstance(() => {
if (mainWindow) {
if (mainWindow.isMinimized()) {
mainWindow.restore();
const singleInstanceLock = app.requestSingleInstanceLock();
if (singleInstanceLock) {
app.on('second-instance', () => {
if (mainWindow) {
if (mainWindow.isMinimized()) {
mainWindow.restore();
}
mainWindow.show();
}
mainWindow.show();
}
});
if (isAlreadyRunning) {
return app.quit();
});
} else {
app.quit();
}
const APP_ICON = path.join(__dirname, '../resources', 'Icon');
@@ -85,14 +86,6 @@ function createMainWindow() {
win.webContents.send('focus');
});
win.once('ready-to-show', () => {
if (ConfigUtil.getConfigItem('startMinimized')) {
win.minimize();
} else {
win.show();
}
});
win.loadURL(mainURL);
// Keep the app running in background on close event
@@ -166,7 +159,10 @@ app.on('ready', () => {
}
// Initialize sentry for main process
sentryInit();
const errorReporting = ConfigUtil.getConfigItem('errorReporting');
if (errorReporting) {
sentryInit();
}
const isSystemProxy = ConfigUtil.getConfigItem('useSystemProxy');
@@ -178,7 +174,7 @@ app.on('ready', () => {
page.on('dom-ready', () => {
if (ConfigUtil.getConfigItem('startMinimized')) {
mainWindow.minimize();
mainWindow.hide();
} else {
mainWindow.show();
}
@@ -205,31 +201,31 @@ app.on('ready', () => {
app.quit();
});
// Show pdf in a new BrowserWindow
ipcMain.on('pdf-view', (event, url) => {
// Paddings for pdfWindow so that it fits into the main browserWindow
const paddingWidth = 55;
const paddingHeight = 22;
// Code to show pdf in a new BrowserWindow (currently commented out due to bug-upstream)
// ipcMain.on('pdf-view', (event, url) => {
// // Paddings for pdfWindow so that it fits into the main browserWindow
// const paddingWidth = 55;
// const paddingHeight = 22;
// Get the config of main browserWindow
const mainWindowState = global.mainWindowState;
// // Get the config of main browserWindow
// const mainWindowState = global.mainWindowState;
// Window to view the pdf file
const pdfWindow = new electron.BrowserWindow({
x: mainWindowState.x + paddingWidth,
y: mainWindowState.y + paddingHeight,
width: mainWindowState.width - paddingWidth,
height: mainWindowState.height - paddingHeight,
webPreferences: {
plugins: true,
partition: 'persist:webviewsession'
}
});
pdfWindow.loadURL(url);
// // Window to view the pdf file
// const pdfWindow = new electron.BrowserWindow({
// x: mainWindowState.x + paddingWidth,
// y: mainWindowState.y + paddingHeight,
// width: mainWindowState.width - paddingWidth,
// height: mainWindowState.height - paddingHeight,
// webPreferences: {
// plugins: true,
// partition: 'persist:webviewsession'
// }
// });
// pdfWindow.loadURL(url);
// We don't want to have the menu bar in pdf window
pdfWindow.setMenu(null);
});
// // We don't want to have the menu bar in pdf window
// pdfWindow.setMenu(null);
// });
// Reload full app not just webview, useful in debugging
ipcMain.on('reload-full-app', () => {
@@ -276,6 +272,10 @@ app.on('ready', () => {
ipcMain.on('update-menu', (event, props) => {
appMenu.setMenu(props);
const activeTab = props.tabs[props.activeTabIndex];
if (activeTab) {
mainWindow.setTitle(`Zulip - ${activeTab.webview.props.name}`);
}
});
ipcMain.on('toggleAutoLauncher', (event, AutoLaunchValue) => {
@@ -347,6 +347,12 @@ app.on('ready', () => {
ipcMain.on('realm-icon-changed', (event, serverURL, iconURL) => {
page.send('update-realm-icon', serverURL, iconURL);
});
// Using event.sender.send instead of page.send here to
// make sure the value of errorReporting is sent only once on load.
ipcMain.on('error-reporting', event => {
event.sender.send('error-reporting-val', errorReporting);
});
});
app.on('before-quit', () => {

View File

@@ -14,14 +14,15 @@ const logger = new Logger({
});
function linuxUpdateNotification() {
let url = 'https://api.github.com/repos/zulip/zulip-electron/releases';
let url = 'https://api.github.com/repos/zulip/zulip-desktop/releases';
url = ConfigUtil.getConfigItem('betaUpdate') ? url : url + '/latest';
const proxyEnabled = ConfigUtil.getConfigItem('useManualProxy') || ConfigUtil.getConfigItem('useSystemProxy');
const options = {
url,
headers: {'User-Agent': 'request'},
proxy: proxyEnabled ? ProxyUtil.getProxy(url) : ''
proxy: proxyEnabled ? ProxyUtil.getProxy(url) : '',
ecdhCurve: 'auto'
};
request(options, (error, response, body) => {

View File

@@ -39,6 +39,65 @@ class AppMenu {
}];
}
getToolsSubmenu() {
return [{
label: `Check for Updates`,
click() {
AppMenu.checkForUpdate();
}
},
{
label: `Release Notes`,
click() {
shell.openExternal(`https://github.com/zulip/zulip-desktop/releases/tag/v${app.getVersion()}`);
}
}, {
type: 'separator'
}, {
label: 'Factory Reset',
accelerator: process.platform === 'darwin' ? 'Command+Shift+D' : 'Ctrl+Shift+D',
click() {
AppMenu.resetAppSettings();
}
}, {
label: 'Download App Logs',
click() {
const zip = new AdmZip();
let date = new Date();
date = date.toLocaleDateString().replace(/\//g, '-');
// Create a zip file of all the logs and config data
zip.addLocalFolder(`${app.getPath('appData')}/${appName}/Logs`);
zip.addLocalFolder(`${app.getPath('appData')}/${appName}/config`);
// Put the log file in downloads folder
const logFilePath = `${app.getPath('downloads')}/Zulip-logs-${date}.zip`;
zip.writeZip(logFilePath);
// Open and select the log file
shell.showItemInFolder(logFilePath);
}
}, {
type: 'separator'
}, {
label: 'Toggle DevTools for Zulip App',
accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
click(item, focusedWindow) {
if (focusedWindow) {
focusedWindow.webContents.toggleDevTools();
}
}
}, {
label: 'Toggle DevTools for Active Tab',
accelerator: process.platform === 'darwin' ? 'Alt+Command+U' : 'Ctrl+Shift+U',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('tab-devtools');
}
}
}];
}
getViewSubmenu() {
return [{
label: 'Reload',
@@ -103,62 +162,30 @@ class AppMenu {
ConfigUtil.setConfigItem('showSidebar', newValue);
}
}
}, {
label: 'Toggle DevTools for Zulip App',
accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
click(item, focusedWindow) {
if (focusedWindow) {
focusedWindow.webContents.toggleDevTools();
}
}
}, {
label: 'Toggle DevTools for Active Tab',
accelerator: process.platform === 'darwin' ? 'Alt+Command+U' : 'Ctrl+Shift+U',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('tab-devtools');
}
}
}];
}
getHelpSubmenu() {
return [
{
label: `${appName + ' Desktop-'} v${app.getVersion()}`,
label: `${appName + ' Desktop'} v${app.getVersion()}`,
enabled: false
},
{
label: `What's New...`,
click() {
shell.openExternal(`https://github.com/zulip/zulip-electron/releases/tag/v${app.getVersion()}`);
label: 'About Zulip',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('open-about');
}
}
},
{
label: `${appName} Help`,
label: `Help Center`,
click() {
shell.openExternal('https://zulipchat.com/help/');
}
}, {
label: 'Show App Logs',
click() {
const zip = new AdmZip();
let date = new Date();
date = date.toLocaleDateString().replace(/\//g, '-');
// Create a zip file of all the logs and config data
zip.addLocalFolder(`${app.getPath('appData')}/${appName}/Logs`);
zip.addLocalFolder(`${app.getPath('appData')}/${appName}/config`);
// Put the log file in downloads folder
const logFilePath = `${app.getPath('downloads')}/Zulip-logs-${date}.zip`;
zip.writeZip(logFilePath);
// Open and select the log file
shell.showItemInFolder(logFilePath);
}
}, {
label: 'Report an Issue...',
label: 'Report an Issue',
click() {
// the goal is to notify the main.html BrowserWindow
// which may not be the focused window.
@@ -199,32 +226,55 @@ class AppMenu {
type: 'checkbox'
});
}
initialSubmenu.push({
type: 'separator'
});
initialSubmenu.push({
label: 'Switch to Next Organization',
accelerator: `Ctrl+Tab`,
enabled: tabs[activeTabIndex].props.role === 'server',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('switch-server-tab', AppMenu.getNextServer(tabs, activeTabIndex));
}
}
}, {
label: 'Switch to Previous Organization',
accelerator: `Ctrl+Shift+Tab`,
enabled: tabs[activeTabIndex].props.role === 'server',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('switch-server-tab', AppMenu.getPreviousServer(tabs, activeTabIndex));
}
}
});
}
return initialSubmenu;
}
getDarwinTpl(props) {
const { tabs, activeTabIndex } = props;
const { tabs, activeTabIndex, enableMenu } = props;
return [{
label: `${app.getName()}`,
submenu: [{
label: 'About Zulip',
label: 'Add Organization',
accelerator: 'Cmd+Shift+N',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('open-about');
AppMenu.sendAction('new-server');
}
}
}, {
label: `Check for Update`,
label: 'Toggle Do Not Disturb',
accelerator: 'Cmd+Shift+M',
click() {
AppMenu.checkForUpdate();
const dndUtil = DNDUtil.toggle();
AppMenu.sendAction('toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
}
}, {
type: 'separator'
}, {
label: 'Desktop App Settings',
label: 'Desktop Settings',
accelerator: 'Cmd+,',
click(item, focusedWindow) {
if (focusedWindow) {
@@ -234,6 +284,7 @@ class AppMenu {
}, {
label: 'Keyboard Shortcuts',
accelerator: 'Cmd+Shift+K',
enabled: enableMenu,
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('shortcut');
@@ -242,21 +293,17 @@ class AppMenu {
}, {
type: 'separator'
}, {
label: 'Toggle Do Not Disturb',
accelerator: 'Command+Shift+M',
click() {
const dndUtil = DNDUtil.toggle();
AppMenu.sendAction('toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
label: 'Copy Zulip URL',
accelerator: 'Cmd+Shift+C',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('copy-zulip-url');
}
}
}, {
label: 'Reset App Settings',
accelerator: 'Command+Shift+D',
click() {
AppMenu.resetAppSettings();
}
}, {
label: 'Log Out',
label: 'Log Out of Organization',
accelerator: 'Cmd+L',
enabled: enableMenu,
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('log-out');
@@ -296,8 +343,6 @@ class AppMenu {
role: 'paste'
}, {
role: 'pasteandmatchstyle'
}, {
role: 'delete'
}, {
role: 'selectall'
}]
@@ -310,6 +355,9 @@ class AppMenu {
}, {
label: 'Window',
submenu: this.getWindowSubmenu(tabs, activeTabIndex)
}, {
label: 'Tools',
submenu: this.getToolsSubmenu()
}, {
role: 'help',
submenu: this.getHelpSubmenu()
@@ -317,40 +365,16 @@ class AppMenu {
}
getOtherTpl(props) {
const { tabs, activeTabIndex } = props;
const { tabs, activeTabIndex, enableMenu } = props;
return [{
label: '&File',
submenu: [{
label: 'About Zulip',
label: 'Add Organization',
accelerator: 'Ctrl+Shift+N',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('open-about');
}
}
}, {
label: `Check for Update`,
click() {
AppMenu.checkForUpdate();
}
}, {
type: 'separator'
}, {
label: 'Desktop App Settings',
accelerator: 'Ctrl+,',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('open-settings');
}
}
}, {
type: 'separator'
}, {
label: 'Keyboard Shortcuts',
accelerator: 'Ctrl+Shift+K',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('shortcut');
AppMenu.sendAction('new-server');
}
}
}, {
@@ -363,14 +387,36 @@ class AppMenu {
AppMenu.sendAction('toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
}
}, {
label: 'Reset App Settings',
accelerator: 'Ctrl+Shift+D',
click() {
AppMenu.resetAppSettings();
label: 'Desktop Settings',
accelerator: 'Ctrl+,',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('open-settings');
}
}
}, {
label: 'Log Out',
label: 'Keyboard Shortcuts',
accelerator: 'Ctrl+Shift+K',
enabled: enableMenu,
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('shortcut');
}
}
}, {
type: 'separator'
}, {
label: 'Copy Zulip URL',
accelerator: 'Ctrl+Shift+C',
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('copy-zulip-url');
}
}
}, {
label: 'Log Out of Organization',
accelerator: 'Ctrl+L',
enabled: enableMenu,
click(item, focusedWindow) {
if (focusedWindow) {
AppMenu.sendAction('log-out');
@@ -398,8 +444,6 @@ class AppMenu {
role: 'paste'
}, {
role: 'pasteandmatchstyle'
}, {
role: 'delete'
}, {
type: 'separator'
}, {
@@ -414,6 +458,9 @@ class AppMenu {
}, {
label: '&Window',
submenu: this.getWindowSubmenu(tabs, activeTabIndex)
}, {
label: '&Tools',
submenu: this.getToolsSubmenu()
}, {
label: '&Help',
role: 'help',
@@ -434,6 +481,23 @@ class AppMenu {
static checkForUpdate() {
appUpdater(true);
}
static getNextServer(tabs, activeTabIndex) {
do {
activeTabIndex = (activeTabIndex + 1) % tabs.length;
}
while (tabs[activeTabIndex].props.role !== 'server');
return activeTabIndex;
}
static getPreviousServer(tabs, activeTabIndex) {
do {
activeTabIndex = (activeTabIndex - 1 + tabs.length) % tabs.length;
}
while (tabs[activeTabIndex].props.role !== 'server');
return activeTabIndex;
}
static resetAppSettings() {
const resetAppSettingsMessage = 'By proceeding you will be removing all connected organizations and preferences from Zulip.';

320
app/package-lock.json generated
View File

@@ -1,13 +1,13 @@
{
"name": "zulip",
"version": "2.3.8",
"version": "2.5.0-beta",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@electron-elements/send-feedback": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@electron-elements/send-feedback/-/send-feedback-1.0.7.tgz",
"integrity": "sha1-HmTsFMvNkmZAngeu1BDoUi45deA=",
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@electron-elements/send-feedback/-/send-feedback-1.0.8.tgz",
"integrity": "sha512-spIZIYSe0Bp028sbZ7bcGOaUYhMyFArk+Tv7kQ4XCRNuVWRkw3SfbR8zIljZAdUavJp0wX6prSWrqLL4Dpd3Fw==",
"requires": {
"@electron-elements/utils": "1.0.3"
}
@@ -37,91 +37,93 @@
}
},
"@sentry/browser": {
"version": "4.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-4.0.0-rc.1.tgz",
"integrity": "sha512-25OFHqY/qKA4W5xetljv0QL+HJM0OzbFOLjrnZ//+ugNQ0QKIM0oCq8gP18p3rwhQ/JbnTA6jSmyI7uHpLQ2Tg==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-4.3.4.tgz",
"integrity": "sha512-odRXxnhcSYzyR4YvTolNEyrz3fdDVw308l+9RBRJA9yOFVlezaz1mXH6Gv00F7cIj9yE/JtezDyhP339WsWy3w==",
"requires": {
"@sentry/core": "4.0.0-rc.1",
"@sentry/hub": "4.0.0-rc.1",
"@sentry/minimal": "4.0.0-rc.1",
"@sentry/types": "4.0.0-rc.1",
"@sentry/utils": "4.0.0-rc.1",
"md5": "2.2.1"
"@sentry/core": "4.3.4",
"@sentry/types": "4.3.4",
"@sentry/utils": "4.3.4",
"tslib": "^1.9.3"
}
},
"@sentry/core": {
"version": "4.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-4.0.0-rc.1.tgz",
"integrity": "sha512-ffaVGh41YwAKK8d2h6vYmVspDmAPfoo45rZzF9ygH5dxHu51eaFhSuQGNtYwD9at2l9kP8jd+4bsdPqPC6QTzQ==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-4.3.4.tgz",
"integrity": "sha512-KwolQmAnXiFMeXBuxPUM8fW+2bOICdHfpjdf83qD7WSeuKqGvXhxXyApWNSLE+l2DPO6/8UKnIGmR8bEn0G7QA==",
"requires": {
"@sentry/hub": "4.0.0-rc.1",
"@sentry/minimal": "4.0.0-rc.1",
"@sentry/types": "4.0.0-rc.1",
"@sentry/utils": "4.0.0-rc.1"
"@sentry/hub": "4.3.4",
"@sentry/minimal": "4.3.4",
"@sentry/types": "4.3.4",
"@sentry/utils": "4.3.4",
"tslib": "^1.9.3"
}
},
"@sentry/electron": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@sentry/electron/-/electron-0.9.0.tgz",
"integrity": "sha512-VeLXLMLp5JUj/TyF0t1U73qJt2nPbwa+XO8Sb9eNz/R+IoALyGugG2BtYMHGwvHitOvodNlzBNH/fFsrEkdLEg==",
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@sentry/electron/-/electron-0.14.0.tgz",
"integrity": "sha512-f0Aj2gKcX9LampOEFER0m6cC4etT1B3bsuY7E1R3vzZXcL7y5TaH2Omgk5atzAX5ycBk8LHxhVqUtE6fZBWlFA==",
"requires": {
"@sentry/browser": "4.0.0-rc.1",
"@sentry/core": "4.0.0-rc.1",
"@sentry/hub": "4.0.0-rc.1",
"@sentry/minimal": "4.0.0-rc.1",
"@sentry/node": "4.0.0-rc.1",
"@sentry/types": "4.0.0-rc.1",
"@sentry/utils": "4.0.0-rc.1",
"@sentry/browser": "~4.3.4",
"@sentry/core": "~4.3.4",
"@sentry/minimal": "~4.3.4",
"@sentry/node": "~4.3.4",
"@sentry/types": "~4.3.4",
"@sentry/utils": "~4.3.4",
"electron-fetch": "1.1.0",
"form-data": "2.3.2",
"util.promisify": "1.0.0"
}
},
"@sentry/hub": {
"version": "4.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-4.0.0-rc.1.tgz",
"integrity": "sha512-MxFiOTxkOBvEwviXAjEnJABicQJ14+FOxkcXCfOfDYdi3AhgDCW5qcRgmZLCUbqOQLKZ4LnOYnvbUld871+NGw==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-4.3.4.tgz",
"integrity": "sha512-vaBGCnhinLB8N4aQLMiPPhnlTkIUwU/dxWzw/xsuKY3MYWrmfMUyWgMZF60Mz3B4F0lW1lsg5jnJz9xPnjZowg==",
"requires": {
"@sentry/types": "4.0.0-rc.1",
"@sentry/utils": "4.0.0-rc.1"
"@sentry/types": "4.3.4",
"@sentry/utils": "4.3.4",
"tslib": "^1.9.3"
}
},
"@sentry/minimal": {
"version": "4.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-4.0.0-rc.1.tgz",
"integrity": "sha512-GxJdeRCgrrA/bWv1vBvQFUkIcY53xDRTxtHpoP5Mvid7AAW8sJaSZmllyFLn8m1izyIHrmVrHCIG5efo7d3mlA==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-4.3.4.tgz",
"integrity": "sha512-EBmQgdAQgxkhWFsBO4TmsP3cg5yTzg48HmPe3Dyt7PtF5Umw3DFW6qboAqnN1+KF+pHNuxkqevvgBTFp7b4Saw==",
"requires": {
"@sentry/hub": "4.0.0-rc.1",
"@sentry/types": "4.0.0-rc.1"
"@sentry/hub": "4.3.4",
"@sentry/types": "4.3.4",
"tslib": "^1.9.3"
}
},
"@sentry/node": {
"version": "4.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-4.0.0-rc.1.tgz",
"integrity": "sha512-syf8A6APBx2UDSRCmUIUOsWhNc0lGt+M6TJLh6iSvZtsuFQxEVusUH3SrbX9O3m1HQ6XSdUXUZ88hMM0/v/lGg==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-4.3.4.tgz",
"integrity": "sha512-4ro8eFnIuuYrF/TLw788xU10AYJl9HvOYC5G3jLrHXTjRNLp7jJo9lZrUexjCvwM2WF/srF3+Z0Pwr+HwdKVVw==",
"requires": {
"@sentry/core": "4.0.0-rc.1",
"@sentry/hub": "4.0.0-rc.1",
"@sentry/minimal": "4.0.0-rc.1",
"@sentry/types": "4.0.0-rc.1",
"@sentry/utils": "4.0.0-rc.1",
"@sentry/core": "4.3.4",
"@sentry/hub": "4.3.4",
"@sentry/types": "4.3.4",
"@sentry/utils": "4.3.4",
"@types/stack-trace": "0.0.29",
"cookie": "0.3.1",
"lsmod": "1.0.0",
"md5": "2.2.1",
"stack-trace": "0.0.10"
"stack-trace": "0.0.10",
"tslib": "^1.9.3"
}
},
"@sentry/types": {
"version": "4.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-4.0.0-rc.1.tgz",
"integrity": "sha512-WCIahta73omB4pYgzAZPCJ/IxyUhn10B8YOm0fKFOWDP1HmQlhpnF9RX/fjkq0LR7vQfOkVUU9dr61AEG+jrqw=="
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-4.3.4.tgz",
"integrity": "sha512-qsqrcyNilpbzYjqef+km0Grh5BckSFD4MUdJDNkUE5XU/ImniYddj18bMDlQxluJlTPDjUFQ37FXtEmxLeOwkQ=="
},
"@sentry/utils": {
"version": "4.0.0-rc.1",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-4.0.0-rc.1.tgz",
"integrity": "sha512-gRtEDh2Pz4UimeJzA1Wiv9bb2OrHouyZoCaFR6pe4I1VudchOTI6PXtAfyt7Yx8CWff7xfJUOiU3BZnT2QQ7Nw==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-4.3.4.tgz",
"integrity": "sha512-CMGMdIv5RHUCKRF4aWPZ/gFRTfBQpLVVJEGCeFGZLXHBdpgQac0lf3jlu8sND0KZ0S3C5x3tGS/eEqmOZRQ/pw==",
"requires": {
"@sentry/types": "4.0.0-rc.1"
"@sentry/types": "4.3.4",
"tslib": "^1.9.3"
}
},
"@sindresorhus/is": {
@@ -129,6 +131,11 @@
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
"integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow=="
},
"@types/stack-trace": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/stack-trace/-/stack-trace-0.0.29.tgz",
"integrity": "sha512-TgfOX+mGY/NyNxJLIbDWrO9DjGoVSW9+aB8H2yy1fy32jsvxijhmyJI9fDFgvz3YP4lvJaq9DzdR/M1bOgVc9g=="
},
"adm-zip": {
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz",
@@ -162,7 +169,7 @@
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"requires": {
"sprintf-js": "~1.0.2"
}
@@ -230,16 +237,16 @@
"optional": true
},
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
"integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk="
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
"integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw=="
},
"bluebird-lst": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
"integrity": "sha1-vryDAmt+kqcocaPcWZ4hnL+wAqk=",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.6.tgz",
"integrity": "sha512-CBWFoPuUPpcvMUxfyr8DKdI5d4kjxFl1h39+VbKxP3KJWJHEsLtuT4pPLkjpxCGU6Ask21tvbnftWXdqIxYldQ==",
"requires": {
"bluebird": "^3.5.1"
"bluebird": "^3.5.2"
}
},
"boom": {
@@ -265,23 +272,28 @@
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
},
"builder-util-runtime": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-4.4.1.tgz",
"integrity": "sha512-8L2pbL6D3VdI1f8OMknlZJpw0c7KK15BRz3cY77AOUElc4XlCv2UhVV01jJM7+6Lx7henaQh80ALULp64eFYAQ==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.1.0.tgz",
"integrity": "sha512-s1mlJ28mv+56Iebh6c9aXjVe11O3Z0cDTwAGeB0PCcUzHA37fDxGgS8ZGoYNMZP+rBHj21d/od1wuYofTVLaQg==",
"requires": {
"bluebird-lst": "^1.0.5",
"debug": "^3.1.0",
"fs-extra-p": "^4.6.1",
"bluebird-lst": "^1.0.6",
"debug": "^4.1.0",
"fs-extra-p": "^7.0.0",
"sax": "^1.2.4"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "2.0.0"
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
}
}
},
@@ -422,18 +434,12 @@
"mimic-response": "^1.0.0"
}
},
"deep-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
},
"define-properties": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
"integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
"requires": {
"foreach": "^2.0.5",
"object-keys": "^1.0.8"
"object-keys": "^1.0.12"
}
},
"delayed-stream": {
@@ -523,46 +529,35 @@
}
},
"electron-updater": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-3.1.2.tgz",
"integrity": "sha512-y3n37O01pdynMJHhJbOd2UVhVrmDW6zLvR2SOZ+gk3S6r16872+0nNbC48GXWwc26lTeus/Zja/XUpiqrvdw4A==",
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.0.6.tgz",
"integrity": "sha512-JPGLME6fxJcHG8hX7HWFl6Aew6iVm0DkcrENreKa5SUJCHG+uUaAhxDGDt+YGcNkyx1uJ6eBGMvFxDTLUv67pg==",
"requires": {
"bluebird-lst": "^1.0.5",
"builder-util-runtime": "~4.4.1",
"electron-is-dev": "^0.3.0",
"fs-extra-p": "^4.6.1",
"bluebird-lst": "^1.0.6",
"builder-util-runtime": "~8.1.0",
"fs-extra-p": "^7.0.0",
"js-yaml": "^3.12.0",
"lazy-val": "^1.0.3",
"lodash.isequal": "^4.5.0",
"semver": "^5.5.1",
"pako": "^1.0.7",
"semver": "^5.6.0",
"source-map-support": "^0.5.9"
},
"dependencies": {
"semver": {
"version": "5.5.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
"integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw=="
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
}
}
},
"electron-window-state": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-4.1.1.tgz",
"integrity": "sha1-azT9wxs4UU3+yLfI97XUrdtnYy0=",
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-5.0.3.tgz",
"integrity": "sha512-1mNTwCfkolXl3kMf50yW3vE2lZj0y92P/HYWFBrb+v2S/pCka5mdwN3cagKm458A7NjndSwijynXgcLWRodsVg==",
"requires": {
"deep-equal": "^1.0.1",
"jsonfile": "^2.2.3",
"jsonfile": "^4.0.0",
"mkdirp": "^0.5.1"
},
"dependencies": {
"jsonfile": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
"requires": {
"graceful-fs": "^4.1.6"
}
}
}
},
"encoding": {
@@ -574,9 +569,9 @@
}
},
"es-abstract": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz",
"integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==",
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
"integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
"requires": {
"es-to-primitive": "^1.1.1",
"function-bind": "^1.1.1",
@@ -586,13 +581,13 @@
}
},
"es-to-primitive": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
"integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"requires": {
"is-callable": "^1.1.1",
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.1"
"is-symbol": "^1.0.2"
}
},
"escape-html": {
@@ -601,9 +596,9 @@
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"esprima": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
"integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ="
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"event-kit": {
"version": "2.4.0",
@@ -636,11 +631,6 @@
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
},
"foreach": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
"integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@@ -666,9 +656,9 @@
}
},
"fs-extra": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
"integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
@@ -676,12 +666,12 @@
}
},
"fs-extra-p": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.6.1.tgz",
"integrity": "sha512-IsTMbUS0svZKZTvqF4vDS9c/L7Mw9n8nZQWWeSzAGacOSe+8CzowhUN0tdZEZFIJNP5HC7L9j3MMikz/G4hDeQ==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-7.0.0.tgz",
"integrity": "sha512-5tg5jBOd0xIXjwj4PDnafOXL5TyPVzjxLby4DPKev53wurEXp7IsojBaD4Lj5M5w7jxw0pbkEU0fFEPmcKoMnA==",
"requires": {
"bluebird-lst": "^1.0.5",
"fs-extra": "^6.0.1"
"bluebird-lst": "^1.0.6",
"fs-extra": "^7.0.0"
}
},
"fs.realpath": {
@@ -769,6 +759,11 @@
"resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
"integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw=="
},
"has-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
},
"has-to-string-tag-x": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
@@ -865,9 +860,9 @@
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
},
"is-callable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
"integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI="
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
},
"is-date-object": {
"version": "1.0.1",
@@ -927,9 +922,12 @@
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"is-symbol": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
"integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI="
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
"requires": {
"has-symbols": "^1.0.0"
}
},
"is-typedarray": {
"version": "1.0.0",
@@ -1029,7 +1027,7 @@
"lazy-val": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.3.tgz",
"integrity": "sha1-u5eyAO8AgB2UwxfincbtOeMcXtw="
"integrity": "sha512-pjCf3BYk+uv3ZcPzEVM0BFvO9Uw58TmlrU0oG5tTrr9Kcid3+kdKxapH8CjdYmVa2nO5wOoZn2rdvZx2PKj/xg=="
},
"lodash.assign": {
"version": "4.2.0",
@@ -1125,30 +1123,24 @@
"integrity": "sha1-ltDNYQ69WNS03pzAxoKM2pnHVI8="
},
"node-json-db": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/node-json-db/-/node-json-db-0.7.3.tgz",
"integrity": "sha1-v2Mf9NTPQhHL3/5srmqq/m7lTN8=",
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/node-json-db/-/node-json-db-0.9.1.tgz",
"integrity": "sha512-4BydUI7a10W8QBdHq/J3UBswU1i8WhCgTS4BZU0MjlUKrSU7cuUti71eojistgqe5hIrb4adj/wvAT5dw63NPg==",
"requires": {
"mkdirp": "0.5.x"
}
},
"node-mac-notifier": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/node-mac-notifier/-/node-mac-notifier-0.1.0.tgz",
"integrity": "sha512-K07p0jW6BhE4Jxpem4pcOdOCDgF/vy3xIqZoZpqme5JAfeW0cEkQ5Z3AmsM7fhJB59kDeOiouyykwPnvLV+hAg==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/node-mac-notifier/-/node-mac-notifier-1.1.0.tgz",
"integrity": "sha512-Fwv09eKMGkM4xn+Eby5g7lvmYF+1KYWX4V5QNn27l4cVFVS7MNYOxhbvGGHT5VuTWbWDQIi/Lr7l6so5vvmqVw==",
"optional": true,
"requires": {
"bindings": "^1.2.1",
"event-target-shim": "^1.1.1",
"node-uuid": "^1.4.7"
"uuid": "^3.3.2"
}
},
"node-uuid": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
"integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=",
"optional": true
},
"normalize-url": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
@@ -1237,6 +1229,11 @@
"p-finally": "^1.0.0"
}
},
"pako": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz",
"integrity": "sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ=="
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -1460,7 +1457,7 @@
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk="
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"semver": {
"version": "5.4.1",
@@ -1486,7 +1483,7 @@
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM="
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"source-map-support": {
"version": "0.5.9",
@@ -1568,6 +1565,11 @@
"punycode": "^1.4.1"
}
},
"tslib": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -1629,6 +1631,12 @@
"object.getownpropertydescriptors": "^2.0.3"
}
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
"optional": true
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",

View File

@@ -1,7 +1,7 @@
{
"name": "zulip",
"productName": "Zulip",
"version": "2.3.8",
"version": "3.0.0",
"description": "Zulip Desktop App",
"license": "Apache-2.0",
"copyright": "Kandra Labs, Inc.",
@@ -11,10 +11,10 @@
},
"repository": {
"type": "git",
"url": "https://github.com/zulip/zulip-electron.git"
"url": "https://github.com/zulip/zulip-desktop.git"
},
"bugs": {
"url": "https://github.com/zulip/zulip-electron/issues"
"url": "https://github.com/zulip/zulip-desktop/issues"
},
"main": "main/index.js",
"keywords": [
@@ -26,23 +26,23 @@
"InstantMessaging"
],
"dependencies": {
"@electron-elements/send-feedback": "1.0.7",
"@sentry/electron": "0.10.1",
"@electron-elements/send-feedback": "1.0.8",
"@sentry/electron": "0.14.0",
"adm-zip": "0.4.11",
"auto-launch": "5.0.5",
"electron-is-dev": "0.3.0",
"electron-log": "2.2.14",
"electron-spellchecker": "1.1.2",
"electron-updater": "3.1.2",
"electron-window-state": "4.1.1",
"electron-updater": "4.0.6",
"electron-window-state": "5.0.3",
"escape-html": "1.0.3",
"is-online": "7.0.0",
"node-json-db": "0.7.3",
"node-json-db": "0.9.1",
"request": "2.85.0",
"semver": "5.4.1",
"wurl": "2.5.0"
},
"optionalDependencies": {
"node-mac-notifier": "0.1.0"
"node-mac-notifier": "1.1.0"
}
}

View File

@@ -1,50 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="css/about.css">
</head>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="css/about.css">
<title>Zulip - About</title>
</head>
<body>
<div class="about">
<img class="logo" src="../resources/zulip.png" />
<p class="detail" id="version">v?.?.?</p>
<div class="maintenance-info">
<p class="detail maintainer">
Maintained by
<a onclick="linkInBrowser('website')">Zulip</a>
</p>
<p class="detail license">
Available under the
<a onclick="linkInBrowser('license')">Apache 2.0 License</a>
</p>
<a class="bug" onclick="linkInBrowser('bug')" href="#">Found bug?</a>
</div>
</div>
<script>
<body>
<div class="about">
<img class="logo" src="../resources/zulip.png" />
<p class="detail" id="version">v?.?.?</p>
<div class="maintenance-info">
<p class="detail maintainer">
Maintained by
<a onclick="linkInBrowser('website')">Zulip</a>
</p>
<p class="detail license">
Available under the
<a onclick="linkInBrowser('license')">Apache 2.0 License</a>
</p>
</div>
</div>
<script>
const { app } = require('electron').remote;
const { shell } = require('electron');
const version_tag = document.querySelector('#version');
version_tag.innerHTML = 'v' + app.getVersion();
const { app } = require('electron').remote;
const { shell } = require('electron');
const version_tag = document.querySelector('#version');
version_tag.innerHTML = 'v' + app.getVersion();
function linkInBrowser(type) {
let url;
switch (type) {
case 'website':
url = "https://zulipchat.com";
break;
case 'license':
url = "https://github.com/zulip/zulip-electron/blob/master/LICENSE";
break;
default:
url = 'https://github.com/zulip/zulip-electron/issues/new?body=' +
'%3C!--Please%20describe%20your%20issue%20and%20steps%20to%20reproduce%20it.--%3E';
}
shell.openExternal(url);
}
</script>
<script>require('./js/shared/preventdrag.js')</script>
</body>
function linkInBrowser(type) {
let url;
switch (type) {
case 'website':
url = "https://zulipchat.com";
break;
case 'license':
url = "https://github.com/zulip/zulip-desktop/blob/master/LICENSE";
break;
}
shell.openExternal(url);
}
</script>
<script>require('./js/shared/preventdrag.js')</script>
</body>
</html>

View File

@@ -1,82 +1,66 @@
body {
background: #fafafa;
font-family: menu, "Helvetica Neue", sans-serif;
-webkit-font-smoothing: subpixel-antialiased;
background: rgba(250, 250, 250, 1.000);
font-family: menu, "Helvetica Neue", sans-serif;
-webkit-font-smoothing: subpixel-antialiased;
}
.logo {
display: block;
margin: -40px auto;
display: block;
margin: -40px auto;
}
#version {
color: #444343;
font-size: 1.3em;
padding-top: 40px;
color: rgba(68, 67, 67, 1.000);
font-size: 1.3em;
padding-top: 40px;
}
.about {
margin: 25vh auto;
height: 25vh;
text-align: center;
margin: 25vh auto;
height: 25vh;
text-align: center;
}
.about p {
font-size: 20px;
color: rgba(0, 0, 0, 0.62);
font-size: 20px;
color: rgba(0, 0, 0, 0.62);
}
.about img {
width: 150px;
width: 150px;
}
.detail {
text-align: center;
text-align: center;
}
.detail.maintainer {
font-size: 1.2em;
font-weight: 500;
font-size: 1.2em;
font-weight: 500;
}
.detail.license {
font-size: 0.8em;
font-size: 0.8em;
}
.maintenance-info {
cursor: pointer;
position: absolute;
width: 100%;
left: 0px;
color: #444;
cursor: pointer;
position: absolute;
width: 100%;
left: 0px;
color: rgba(68, 68, 68, 1.000);
}
.maintenance-info p {
margin: 0;
font-size: 1em;
width: 100%;
}
.maintenance-info .bug {
display: inline-block;
padding: 8px 15px;
margin-top: 30px;
text-decoration: none;
background-color: #52c2af;
color: #fff;
border-radius: 4px;
transition: background-color 0.2s ease;
}
.maintenance-info .bug:hover {
background-color: #32a692;
margin: 0;
font-size: 1em;
width: 100%;
}
p.detail a {
color: #355f4c;
color: rgba(53, 95, 76, 1.000);
}
p.detail a:hover {
text-decoration: underline;
text-decoration: underline;
}

View File

@@ -16,7 +16,7 @@ body {
}
.toggle-sidebar {
background: #222c31;
background: rgba(34, 44, 49, 1.000);
width: 54px;
padding: 27px 0 20px 0;
justify-content: space-between;
@@ -43,25 +43,25 @@ body {
}
#view-controls-container {
height: calc(100% - 208px);
overflow-y: hidden;
height: calc(100% - 208px);
overflow-y: hidden;
}
#view-controls-container:hover {
overflow-y: overlay;
overflow-y: overlay;
}
#view-controls-container::-webkit-scrollbar {
width: 4px;
width: 4px;
}
#view-controls-container::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}
#view-controls-container::-webkit-scrollbar-thumb {
background-color: darkgrey;
outline: 1px solid slategrey;
background-color: rgba(169, 169, 169, 1.000);
outline: 1px solid rgba(169, 169, 169, 1.000);
}
@font-face {
@@ -119,12 +119,12 @@ body {
}
.action-button i {
color: #6c8592;
color: rgba(108, 133, 146, 1.000);
font-size: 28px;
}
.action-button:hover i {
color: #98a9b3;
color: rgba(152, 169, 179, 1.000);
}
.action-button.disable {
@@ -136,22 +136,22 @@ body {
}
.action-button.disable:hover i {
color: #6c8592;
color: rgba(108, 133, 146, 1.000);
}
.action-button.active {
/* background-color: rgba(255, 255, 255, 0.25); */
background-color: #efefef;
background-color: rgba(239, 239, 239, 1.000);
opacity: 0.9;
padding-right: 14px;
}
.action-button.active i {
color: #1c262b;
color: rgba(28, 38, 43, 1.000);
}
.tab:first-child {
margin-top: 8px;
margin-top: 9px;
}
.tab {
@@ -165,35 +165,33 @@ body {
}
.tab .server-icons {
border-radius: 50%;
width: 30px;
padding: 3px;
height: 30px;
width: 35px;
vertical-align: top;
border-radius: 4px;
}
.tab .server-tab {
width: 100%;
height: 35px;
position: relative;
margin: 5px 0 2px 0;
margin-top: 5px;
z-index: 11;
line-height: 31px;
color: #eee;
color: rgba(238, 238, 238, 1.000);
text-align: center;
overflow: hidden;
opacity: 0.6;
padding: 2px 0;
padding: 6px 0;
}
.server-tab .alt-icon {
font-family: Verdana;
font-weight: 600;
font-size: 22px;
border: 2px solid #222c31;
border: 2px solid rgba(34, 44, 49, 1.000);
margin-left: 17%;
width: 33px;
border-radius: 50%;
width: 35px;
border-radius: 4px;
}
.tab .server-tab:hover {
@@ -218,7 +216,7 @@ body {
.tab.active .server-tab {
opacity: 1;
background-color: #648478;
background-color: rgba(100, 132, 120, 1.000);
}
.tab .server-tab-badge.active {
@@ -226,7 +224,7 @@ body {
min-width: 11px;
padding: 0 3px;
height: 17px;
background-color: #f44336;
background-color: rgba(244, 67, 54, 1.000);
font-size: 10px;
font-family: sans-serif;
position: absolute;
@@ -234,7 +232,7 @@ body {
z-index: 15;
top: 6px;
float: right;
color: #fff;
color: rgba(255, 255, 255, 1.000);
text-align: center;
line-height: 17px;
display: block;
@@ -262,7 +260,7 @@ body {
}
.tab .server-tab-shortcut {
color: #648478;
color: rgba(100, 132, 120, 1.000);
font-size: 12px;
text-align: center;
font-family: sans-serif;
@@ -280,19 +278,19 @@ body {
width: 100%;
}
/*Pseudo element for loading indicator*/
/* Pseudo element for loading indicator */
#webviews-container::before {
content: "";
position: absolute;
z-index: 1;
background: #fff url(../img/ic_loading.gif) no-repeat;
background: rgba(255, 255, 255, 1.000) url(../img/ic_loading.gif) no-repeat;
background-size: 60px 60px;
background-position: center;
width: 100%;
height: 100%;
}
/*When the active webview is loaded*/
/* When the active webview is loaded */
#webviews-container.loaded::before {
opacity: 0;
z-index: -1;
@@ -335,27 +333,27 @@ webview.focus {
#reload-tooltip,
#setting-tooltip {
font-family: sans-serif;
background: #222c31;
background: rgba(34, 44, 49, 1.000);
margin-left: 48px;
padding: 6px 8px;
position: absolute;
margin-top: 0px;
z-index: 1000;
color: white;
color: rgba(255, 255, 255, 1.000);
border-radius: 4px;
text-align: center;
width: 55px;
font-size: 14px;
}
#dnd-tooltip:after,
#back-tooltip:after,
#reload-tooltip:after,
#setting-tooltip:after {
#dnd-tooltip::after,
#back-tooltip::after,
#reload-tooltip::after,
#setting-tooltip::after {
content: " ";
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
border-right: 8px solid #222c31;
border-right: 8px solid rgba(34, 44, 49, 1.000);
position: absolute;
top: 7px;
right: 68px;
@@ -364,25 +362,25 @@ webview.focus {
#add-server-tooltip,
.server-tooltip {
font-family: 'arial';
background: #222c31;
background: rgba(34, 44, 49, 1.000);
left: 56px;
padding: 10px 20px;
position: fixed;
margin-top: 8px;
margin-top: 11px;
z-index: 5000 !important;
color: #fff;
color: rgba(255, 255, 255, 1.000);
border-radius: 4px;
text-align: center;
width: max-content;
font-size: 14px;
}
#add-server-tooltip:after,
.server-tooltip:after {
#add-server-tooltip::after,
.server-tooltip::after {
content: " ";
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
border-right: 8px solid #222c31;
border-right: 8px solid rgba(34, 44, 49, 1.000);
position: absolute;
top: 10px;
left: -5px;
@@ -394,14 +392,14 @@ webview.focus {
position: absolute;
width: 24px;
height: 24px;
background: #222c31;
background: rgba(34, 44, 49, 1.000);
border-radius: 20px;
cursor: pointer;
box-shadow: #999 1px 1px;
box-shadow: rgba(153, 153, 153, 1.000) 1px 1px;
}
#collapse-button i {
color: #efefef;
color: rgba(239, 239, 239, 1.000);
}
#main-container {
@@ -422,8 +420,8 @@ webview.focus {
.popup .popuptext {
visibility: hidden;
background-color: #555;
color: #fff;
background-color: rgba(85, 85, 85, 1.000);
color: rgba(255, 255, 255, 1.000);
text-align: center;
border-radius: 6px;
padding: 9px 0;
@@ -455,24 +453,24 @@ webview.focus {
}
send-feedback {
width: 60%;
height: 85%;
width: 60%;
height: 85%;
}
#feedback-modal {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(68, 67, 67, 0.81);
align-items: center;
justify-content: center;
z-index: 2;
transition: all 1s ease-out;
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(68, 67, 67, 0.81);
align-items: center;
justify-content: center;
z-index: 2;
transition: all 1s ease-out;
}
#feedback-modal.show {
display: flex;
display: flex;
}

View File

@@ -1,10 +1,11 @@
html, body {
html,
body {
margin: 0;
cursor: default;
font-size: 14px;
color: #333;
background: #fff;
user-select:none;
color: rgba(51, 51, 51, 1.000);
background: rgba(255, 255, 255, 1.000);
user-select: none;
}
#content {
@@ -27,8 +28,8 @@ html, body {
#reconnect {
font-size: 16px;
background: #009688;
color: #fff;
background: rgba(0, 150, 136, 1.000);
color: rgba(255, 255, 255, 1.000);
width: 84px;
height: 32px;
border-radius: 5px;

View File

@@ -7,25 +7,25 @@ body {
font-family: menu, "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 14px;
background: #efefef;
background: rgba(239, 239, 239, 1.000);
letter-spacing: -.08px;
line-height: 18px;
color: #8b8e8f;
color: rgba(139, 142, 143, 1.000);
}
kbd {
display: inline-block;
border: 1px solid #ccc;
border: 1px solid rgba(204, 204, 204, 1.000);
border-radius: 4px;
font-size: 15px;
font-family: Courier New, Courier, monospace;
font-weight: bold;
white-space: nowrap;
background-color: #f7f7f7;
color: #333;
background-color: rgba(247, 247, 247, 1.000);
color: rgba(51, 51, 51, 1.000);
margin: 0 0.1em;
padding: 0.3em 0.8em;
text-shadow: 0 1px 0 #fff;
text-shadow: 0 1px 0 rgba(255, 255, 255, 1.000);
line-height: 1.4;
}
@@ -33,7 +33,7 @@ table,
th,
td {
border-collapse: collapse;
color: #383430;
color: rgba(56, 52, 48, 1.000);
}
table {
@@ -43,11 +43,11 @@ table {
}
table tr:nth-child(even) {
background-color: #fafafa;
background-color: rgba(250, 250, 250, 1.000);
}
table tr:nth-child(odd) {
background-color: #fff;
background-color: rgba(255, 255, 255, 1.000);
}
td {
@@ -103,7 +103,7 @@ td:nth-child(odd) {
display: flex;
flex-direction: column;
font-size: 16px;
background: #f2f2f2;
background: rgba(242, 242, 242, 1.000);
}
#nav-container {
@@ -111,19 +111,19 @@ td:nth-child(odd) {
}
.nav {
padding: 5px 0;
color: #999;
padding: 7px 0;
color: rgba(153, 153, 153, 1.000);
cursor: pointer;
}
.nav.active {
color: #4ebfac;
color: rgba(78, 191, 172, 1.000);
cursor: default;
position: relative;
}
.nav.active::before {
background: #464e5a;
background: rgba(70, 78, 90, 1.000);
width: 3px;
height: 18px;
position: absolute;
@@ -139,7 +139,7 @@ td:nth-child(odd) {
#settings-header {
font-size: 22px;
color: #222c31;
color: rgba(34, 44, 49, 1.000);
font-weight: bold;
text-transform: uppercase;
}
@@ -159,11 +159,11 @@ td:nth-child(odd) {
.title {
font-weight: 500;
color: #222c31;
color: rgba(34, 44, 49, 1.000);
}
.page-title {
color: #222c31;
color: rgba(34, 44, 49, 1.000);
font-size: 15px;
font-weight: bold;
padding: 4px 0 6px 0;
@@ -182,13 +182,13 @@ td:nth-child(odd) {
.sub-title {
padding: 4px 0 6px 0;
font-weight: bold;
color: #616161;
color: rgba(97, 97, 97, 1.000);
}
img.server-info-icon {
width: 36px;
height: 36px;
padding: 4px;
padding: 4px 4px 4px 10px;
cursor: pointer;
vertical-align: middle;
}
@@ -249,14 +249,14 @@ img.server-info-icon {
font-size: 14px;
border-radius: 4px;
padding: 13px;
border: #ededed 2px solid;
border: rgba(237, 237, 237, 1.000) 2px solid;
outline-width: 0;
background: transparent;
max-width: 450px;
}
.setting-input-value:focus {
border: #4EBFAC 2px solid;
border: rgba(78, 191, 172, 1.000) 2px solid;
}
.manual-proxy-block {
@@ -266,7 +266,7 @@ img.server-info-icon {
.actions-container {
display: flex;
font-size: 14px;
color: #235d3a;
color: rgba(35, 93, 58, 1.000);
vertical-align: middle;
margin: 10px 0;
flex-wrap: wrap;
@@ -287,6 +287,7 @@ img.server-info-icon {
.settings-pane {
flex-grow: 1;
min-width: 550px;
}
.action:hover {
@@ -298,7 +299,7 @@ img.server-info-icon {
}
.action.disabled {
color: #999;
color: rgba(153, 153, 153, 1.000);
}
.settings-card {
@@ -306,7 +307,7 @@ img.server-info-icon {
flex-wrap: wrap;
padding: 12px 30px;
margin: 10px 0 20px 0;
background: #fff;
background: rgba(255, 255, 255, 1.000);
width: 80%;
transition: all 0.2s;
}
@@ -321,46 +322,59 @@ img.server-info-icon {
}
.red {
color: #ef5350;
padding: 8px;
border: rgba(239, 83, 80, 0.5) solid 1px;
border-radius: 4px;
border-color: #fff;
}
.red:hover {
background-color: rgba(230, 52, 49, 0.5);
color: #fff;
}
.green {
color: #fff;
background: #4EBFAC;
color: rgb(240, 148, 148);
background: rgba(255, 255, 255, 1.000);
border-radius: 4px;
display: inline-block;
border: none;
border: 2px solid rgb(240, 148, 148);
padding: 10px;
width: 110px;
width: 100px;
cursor: pointer;
font-size: 1rem;
font-weight: bold;
transition: background-color 0.2s ease;
text-decoration: none;
text-align: center;
}
.red:hover {
background-color: rgb(240, 148, 148);
color: rgba(255, 255, 255, 1.000);
}
.green {
color: rgba(255, 255, 255, 1.000);
background: rgba(78, 191, 172, 1.000);
border-radius: 4px;
display: inline-block;
border: none;
padding: 10px;
width: 100px;
cursor: pointer;
font-size: 1rem;
font-weight: bold;
transition: background-color 0.2s ease;
text-decoration: none;
text-align: center;
}
.green:hover {
background-color: #3c9f8d;
color: #fff;
background-color: rgba(60, 159, 141, 1.000);
color: rgba(255, 255, 255, 1.000);
}
.w-200 {
width: 200px;
.w-150 {
width: 150px;
}
.w-250 {
width: 250px;
}
.grey {
color: #9E9E9E;
background: #FAFAFA;
border: 1px solid #9E9E9E;
color: rgba(158, 158, 158, 1.000);
background: rgba(250, 250, 250, 1.000);
border: 1px solid rgba(158, 158, 158, 1.000);
}
.setting-row {
@@ -376,7 +390,7 @@ img.server-info-icon {
}
i.open-tab-button {
padding-left: 2px;
padding-left: 5px;
font-size: 19px;
cursor: pointer;
}
@@ -387,7 +401,7 @@ i.open-tab-button {
.selected-css-path,
.download-folder-path {
background: #eeeeee;
background: rgba(238, 238, 238, 1.000);
padding: 5px 10px;
margin-right: 10px;
display: flex;
@@ -400,7 +414,11 @@ i.open-tab-button {
}
#server-info-container {
min-height: calc(100% - 260px);
/* min-height: calc(100% - 260px); */
}
#new-org-button {
margin: 30px 0px 30px 0px;
}
#create-organization-container {
@@ -423,7 +441,7 @@ i.open-tab-button {
visibility: hidden;
}
.toggle+label {
.toggle + label {
display: block;
position: relative;
cursor: pointer;
@@ -431,16 +449,16 @@ i.open-tab-button {
user-select: none;
}
input.toggle-round+label {
input.toggle-round + label {
padding: 2px;
width: 50px;
height: 25px;
background-color: #dddddd;
background-color: rgba(221, 221, 221, 1.000);
border-radius: 25px;
}
input.toggle-round+label:before,
input.toggle-round+label:after {
input.toggle-round + label::before,
input.toggle-round + label::after {
display: block;
position: absolute;
top: 2px;
@@ -449,8 +467,8 @@ input.toggle-round+label:after {
content: "";
}
input.toggle-round+label:before {
background-color: #f1f1f1;
input.toggle-round + label::before {
background-color: rgba(241, 241, 241, 1.000);
border-radius: 25px;
top: 0;
right: 0px;
@@ -458,22 +476,22 @@ input.toggle-round+label:before {
bottom: 0px;
}
input.toggle-round+label:after {
input.toggle-round + label::after {
width: 25px;
height: 25px;
background-color: #fff;
background-color: rgba(255, 255, 255, 1.000);
border-radius: 100%;
}
input.toggle-round:checked+label:before {
background-color: #4EBFAC;
input.toggle-round:checked + label::before {
background-color: rgba(78, 191, 172, 1.000);
top: 0;
right: 0px;
left: 0px;
bottom: 0px;
}
input.toggle-round:checked+label:after {
input.toggle-round:checked + label::after {
margin-left: 25px;
}
@@ -490,17 +508,17 @@ input.toggle-round:checked+label:after {
width: 100%;
height: 100%;
/* background: rgba(61, 64, 67, 15); */
background: linear-gradient(35deg, #003b52, #45b59b);
background: linear-gradient(35deg, rgba(0, 59, 82, 1.000), rgba(69, 181, 155, 1.000));
overflow: auto;
}
/* Modal Content */
.modal-container {
background-color: #f4f7f8;
background-color: rgba(244, 247, 248, 1.000);
margin: auto;
padding: 57px;
border: #dae1e3 1px solid;
border: rgba(218, 225, 227, 1.000) 1px solid;
width: 550px;
height: 370px;
border-radius: 4px;
@@ -514,7 +532,7 @@ input.toggle-round:checked+label:after {
.divider {
margin-bottom: 30px;
margin-top: 30px;
color: #7d878a;
color: rgba(125, 135, 138, 1.000);
}
.divider hr {
@@ -545,8 +563,8 @@ input.toggle-round:checked+label:after {
margin: auto;
align-items: center;
text-align: center;
color: #fff;
background: #4EBFAC;
color: rgba(255, 255, 255, 1.000);
background: rgba(78, 191, 172, 1.000);
border-color: none;
border: none;
width: 98%;
@@ -556,15 +574,15 @@ input.toggle-round:checked+label:after {
}
.server-center button:hover {
background: #329588;
background: rgba(50, 149, 136, 1.000);
}
.server-center button:focus {
background: #329588;
background: rgba(50, 149, 136, 1.000);
}
.certificates-card {
width: 80%
width: 80%;
}
.certificate-input {
@@ -583,13 +601,16 @@ input.toggle-round:checked+label:after {
}
#add-certificate-button {
margin: 10px;
margin: 10px 10px 10px 37px;
}
.tip {
background-color: hsl(46, 63%, 95%);
border: 1px solid hsl(46, 63%, 84%);
border-radius: 4px;
background: none;
padding: 0;
}
.tip:hover {
box-shadow: none;
}
.md-14 {
@@ -664,4 +685,4 @@ input.toggle-round:checked+label:after {
.action {
margin-top: 10px;
}
}
}

View File

@@ -1,9 +1,9 @@
/* Override css rules */
.portico-wrap>.header {
.portico-wrap > .header {
display: none;
}
.portico-container>.footer {
.portico-container > .footer {
display: none;
}

View File

@@ -21,19 +21,21 @@ function handleExternalLink(event) {
if (isWhiteListURL) {
event.preventDefault();
// Code to show pdf in a new BrowserWindow (currently commented out due to bug-upstream)
// Show pdf attachments in a new window
if (LinkUtil.isPDF(url) && isUploadsURL) {
ipcRenderer.send('pdf-view', url);
return;
}
// if (LinkUtil.isPDF(url) && isUploadsURL) {
// ipcRenderer.send('pdf-view', url);
// return;
// }
// download txt, mp3, mp4 etc.. by using downloadURL in the
// main process which allows the user to save the files to their desktop
// and not trigger webview reload while image in webview will
// do nothing and will not save it
if (!LinkUtil.isImage(url) && !LinkUtil.isPDF(url) && isUploadsURL) {
// Code to show pdf in a new BrowserWindow (currently commented out due to bug-upstream)
// if (!LinkUtil.isImage(url) && !LinkUtil.isPDF(url) && isUploadsURL) {
if (!LinkUtil.isImage(url) && isUploadsURL) {
ipcRenderer.send('downloadFile', url, downloadPath);
ipcRenderer.once('downloadFileCompleted', (event, filePath, fileName) => {
const downloadNotification = new Notification('Download Complete', {

View File

@@ -95,6 +95,11 @@ class WebView extends BaseComponent {
}
this.loading = false;
this.show();
// Refocus text boxes after reload
// Remove when upstream issue https://github.com/electron/electron/issues/14474 is fixed
this.$el.blur();
this.$el.focus();
});
this.$el.addEventListener('did-fail-load', event => {
@@ -165,7 +170,13 @@ class WebView extends BaseComponent {
focus() {
// focus Webview and it's contents when Window regain focus.
const webContents = this.$el.getWebContents();
if (webContents && !webContents.isFocused()) {
// HACK: webContents.isFocused() seems to be true even without the element
// being in focus. So, we check against `document.activeElement`.
if (webContents && this.$el !== document.activeElement) {
// HACK: Looks like blur needs to be called on the previously focused
// element to transfer focus correctly, in Electron v3.0.10
// See https://github.com/electron/electron/issues/15718
document.activeElement.blur();
this.$el.focus();
webContents.focus();
}
@@ -214,6 +225,7 @@ class WebView extends BaseComponent {
back() {
if (this.$el.canGoBack()) {
this.$el.goBack();
this.focus();
}
}

View File

@@ -1,9 +1,9 @@
'use strict';
const { ipcRenderer, remote } = require('electron');
const { ipcRenderer, remote, clipboard } = require('electron');
const isDev = require('electron-is-dev');
const { session, app } = remote;
const { session, app, Menu, dialog } = remote;
const escape = require('escape-html');
require(__dirname + '/js/tray.js');
@@ -105,12 +105,14 @@ class ServerManagerView {
useSystemProxy: false,
showSidebar: true,
badgeOption: true,
startAtLogin: false,
startAtLogin: true,
startMinimized: false,
enableSpellchecker: true,
showNotification: true,
autoUpdate: true,
betaUpdate: false,
errorReporting: true,
customCSS: false,
silent: false,
lastActiveTab: 0,
dnd: false,
@@ -185,6 +187,7 @@ class ServerManagerView {
index,
tabIndex,
url: server.url,
role: 'server',
name: CommonUtil.decodeString(server.alias),
isActive: () => {
return index === this.activeTabIndex;
@@ -199,6 +202,24 @@ class ServerManagerView {
initActions() {
this.initDNDButton();
this.initServerActions();
this.initLeftSidebarEvents();
}
initServerActions() {
const $serverImgs = document.querySelectorAll('.server-icons');
$serverImgs.forEach(($serverImg, index) => {
this.addContextMenu($serverImg, index);
if ($serverImg.src.includes('img/icon.png')) {
this.displayInitialCharLogo($serverImg, index);
}
$serverImg.addEventListener('error', () => {
this.displayInitialCharLogo($serverImg, index);
});
});
}
initLeftSidebarEvents() {
this.$dndButton.addEventListener('click', () => {
const dndUtil = DNDUtil.toggle();
ipcRenderer.send('forward-message', 'toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
@@ -216,17 +237,6 @@ class ServerManagerView {
this.tabs[this.activeTabIndex].webview.back();
});
const $serverImgs = document.querySelectorAll('.server-icons');
$serverImgs.forEach($serverImg => {
if ($serverImg.src.includes('img/icon.png')) {
this.displayInitalCharLogo($serverImg);
}
$serverImg.addEventListener('error', () => {
this.displayInitalCharLogo($serverImg);
});
});
this.sidebarHoverEvent(this.$addServerButton, this.$addServerTooltip, true);
this.sidebarHoverEvent(this.$settingsButton, this.$settingsTooltip);
this.sidebarHoverEvent(this.$reloadButton, this.$reloadTooltip);
@@ -245,7 +255,12 @@ class ServerManagerView {
return currentIndex;
}
displayInitalCharLogo($img) {
displayInitialCharLogo($img, index) {
/*
index parameter needed because webview[data-tab-id] can increment
beyond size of sidebar org array and throw error
*/
const $altIcon = document.createElement('div');
const $parent = $img.parentElement;
const $container = $parent.parentElement;
@@ -264,6 +279,8 @@ class ServerManagerView {
$parent.removeChild($img);
$parent.appendChild($altIcon);
this.addContextMenu($altIcon, index);
}
sidebarHoverEvent(SidebarButton, SidebarTooltip, addServer = false) {
@@ -307,6 +324,7 @@ class ServerManagerView {
this.functionalTabs[tabProps.name] = this.tabs.length;
const tabIndex = this.getTabIndex();
this.tabs.push(new FunctionalTab({
role: 'function',
materialIcon: tabProps.materialIcon,
@@ -321,6 +339,7 @@ class ServerManagerView {
index: this.functionalTabs[tabProps.name],
tabIndex,
url: tabProps.url,
role: 'function',
name: tabProps.name,
isActive: () => {
return this.functionalTabs[tabProps.name] === this.activeTabIndex;
@@ -331,9 +350,11 @@ class ServerManagerView {
preload: false
})
}));
// To show loading indicator the first time a functional tab is opened, indicator is
// closed when the functional tab DOM is ready, handled in webview.js
this.$webviewsContainer.classList.remove('loaded');
this.activateTab(this.functionalTabs[tabProps.name]);
}
@@ -370,6 +391,25 @@ class ServerManagerView {
ConfigUtil.setConfigItem('lastActiveTab', index);
}
// returns this.tabs in an way that does
// not crash app when this.tabs is passed into
// ipcRenderer. Something about webview, and props.webview
// properties in ServerTab causes the app to crash.
get tabsForIpc() {
const tabs = [];
this.tabs.forEach(tab => {
const proto = Object.create(Object.getPrototypeOf(tab));
const tabClone = Object.assign(proto, tab);
tabClone.webview = { props: {} };
tabClone.webview.props.name = tab.webview.props.name;
delete tabClone.props.webview;
tabs.push(tabClone);
});
return tabs;
}
activateTab(index, hideOldTab = true) {
if (!this.tabs[index]) {
return;
@@ -396,8 +436,12 @@ class ServerManagerView {
this.tabs[index].activate();
ipcRenderer.send('update-menu', {
tabs: this.tabs,
activeTabIndex: this.activeTabIndex
// JSON stringify this.tabs to avoid a crash
// util.inspect is being used to handle circular references
tabs: this.tabsForIpc,
activeTabIndex: this.activeTabIndex,
// Following flag controls whether a menu item should be enabled or not
enableMenu: this.tabs[index].props.role === 'server'
});
}
@@ -439,6 +483,7 @@ class ServerManagerView {
// Destroy the current view and re-initiate it
this.destroyView();
this.initTabs();
this.initServerActions();
}
// This will trigger when pressed CTRL/CMD + R [WIP]
@@ -470,10 +515,42 @@ class ServerManagerView {
// Toggles the dnd button icon.
toggleDNDButton(alert) {
this.$dndTooltip.textContent = (alert ? 'Turn Off' : 'Enable') + ' Do Not Disturb';
this.$dndTooltip.textContent = (alert ? 'Disable' : 'Enable') + ' Do Not Disturb';
this.$dndButton.querySelector('i').textContent = alert ? 'notifications_off' : 'notifications';
}
addContextMenu($serverImg, index) {
$serverImg.addEventListener('contextmenu', e => {
e.preventDefault();
const template = [
{
label: 'Disconnect organization',
click: () => {
dialog.showMessageBox({
type: 'warning',
buttons: ['YES', 'NO'],
defaultId: 0,
message: 'Are you sure you want to disconnect this organization?'
}, response => {
if (response === 0) {
DomainUtil.removeDomain(index);
ipcRenderer.send('reload-full-app');
}
});
}
},
{
label: 'Copy Zulip URL',
click: () => {
clipboard.writeText(DomainUtil.getDomain(index).url);
}
}
];
const contextMenu = Menu.buildFromTemplate(template);
contextMenu.popup({ window: remote.getCurrentWindow() });
});
}
registerIpcs() {
const webviewListeners = {
'webview-reload': 'reload',
@@ -519,6 +596,10 @@ class ServerManagerView {
this.activateLastTab(index);
});
ipcRenderer.on('open-org-tab', () => {
this.openSettings('AddServer');
});
ipcRenderer.on('reload-proxy', (event, showAlert) => {
this.loadProxy().then(() => {
if (showAlert) {
@@ -576,7 +657,7 @@ class ServerManagerView {
DomainUtil.reloadDB();
// Update the realm name also on the Window menu
ipcRenderer.send('update-menu', {
tabs: this.tabs,
tabs: this.tabsForIpc,
activeTabIndex: this.activeTabIndex
});
}
@@ -652,6 +733,14 @@ class ServerManagerView {
ipcRenderer.on('open-feedback-modal', () => {
feedbackHolder.classList.add('show');
});
ipcRenderer.on('copy-zulip-url', () => {
clipboard.writeText(DomainUtil.getDomain(this.activeTabIndex).url);
});
ipcRenderer.on('new-server', () => {
this.openSettings('AddServer');
});
}
}

View File

@@ -141,7 +141,8 @@ function parseReply(reply) {
function setupReply(id) {
const { narrow } = window;
narrow.by_subject(id, { trigger: 'notification' });
const narrowByTopic = narrow.by_topic || narrow.by_subject;
narrowByTopic(id, { trigger: 'notification' });
}
module.exports = {

View File

@@ -1,6 +1,7 @@
'use-strict';
const { dialog } = require('electron').remote;
const path = require('path');
const BaseComponent = require(__dirname + '/../../components/base.js');
const CertificateUtil = require(__dirname + '/../../utils/certificate-util.js');
@@ -17,12 +18,12 @@ class AddCertificate extends BaseComponent {
return `
<div class="settings-card certificates-card">
<div class="certificate-input">
<div>Organization URL :</div>
<div>Organization URL</div>
<input class="setting-input-value" autofocus placeholder="your-organization.zulipchat.com or zulip.your-organization.com"/>
</div>
<div class="certificate-input">
<div>Custom CA's certificate file :</div>
<button class="green" id="add-certificate-button">Add</button>
<div>Certificate file</div>
<button class="green" id="add-certificate-button">Upload</button>
</div>
</div>
`;
@@ -41,7 +42,7 @@ class AddCertificate extends BaseComponent {
const serverUrl = this.serverUrl.value;
if (certificate !== '' && serverUrl !== '') {
const server = encodeURIComponent(DomainUtil.formatUrl(serverUrl));
const fileName = certificate.substring(certificate.lastIndexOf('/') + 1);
const fileName = path.basename(certificate);
const copy = CertificateUtil.copyCertificate(server, certificate, fileName);
if (!copy) {
return;

View File

@@ -17,7 +17,7 @@ class ConnectedOrgSection extends BaseSection {
<div class="page-title">Connected organizations</div>
<div class="title" id="existing-servers">All the connected orgnizations will appear here.</div>
<div id="server-info-container"></div>
<div id="new-org-button"><button class="green sea w-250">Connect to another organization</button></div>
<div class="page-title">Add Custom Certificates</div>
<div id="add-certificate-container"></div>
</div>
@@ -33,8 +33,11 @@ class ConnectedOrgSection extends BaseSection {
const servers = DomainUtil.getDomains();
this.props.$root.innerHTML = this.template();
this.$serverInfoContainer = document.getElementById('server-info-container');
this.$existingServers = document.getElementById('existing-servers');
this.$newOrgButton = document.getElementById('new-org-button');
this.$addCertificateContainer = document.getElementById('add-certificate-container');
const noServerText = 'All the connected orgnizations will appear here';
// Show noServerText if no servers are there otherwise hide it
@@ -49,7 +52,12 @@ class ConnectedOrgSection extends BaseSection {
}).init();
}
this.$addCertificateContainer = document.getElementById('add-certificate-container');
this.$newOrgButton.addEventListener('click', () => {
// We don't need to import this since it's already imported in other files
// eslint-disable-next-line no-undef
ipcRenderer.send('forward-message', 'open-org-tab');
});
this.initAddCertificate();
}

View File

@@ -24,11 +24,11 @@ class GeneralSection extends BaseSection {
<div class="setting-control"></div>
</div>
<div class="setting-row" id="menubar-option" style= "display:${process.platform === 'darwin' ? 'none' : ''}">
<div class="setting-description">Auto hide Menubar (Press Alt key to display)</div>
<div class="setting-description">Auto hide menu bar (Press Alt key to display)</div>
<div class="setting-control"></div>
</div>
<div class="setting-row" id="sidebar-option">
<div class="setting-description">Show sidebar (<span class="code">Cmd Or Ctrl+Shift+S</span>)</div>
<div class="setting-description">Show sidebar (<span class="code">${process.platform === 'darwin' ? 'Cmd+Shift+S' : 'Ctrl+Shift+S'}</span>)</div>
<div class="setting-control"></div>
</div>
<div class="setting-row" id="badge-option">
@@ -44,10 +44,10 @@ class GeneralSection extends BaseSection {
<div class="setting-control"></div>
</div>
</div>
<div class="title">Desktop Notification</div>
<div class="title">Desktop Notifications</div>
<div class="settings-card">
<div class="setting-row" id="show-notification-option">
<div class="setting-description">Show Desktop Notifications</div>
<div class="setting-description">Show desktop notifications</div>
<div class="setting-control"></div>
</div>
<div class="setting-row" id="silent-option">
@@ -77,39 +77,40 @@ class GeneralSection extends BaseSection {
<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-description">Enable spellchecker (requires restart)</div>
<div class="setting-control"></div>
</div>
</div>
<div class="title">Add custom CSS</div>
<div class="settings-card">
<div class="setting-row" id="add-custom-css">
<div class="setting-description">
This will inject the selected css stylesheet in all the added accounts
</div>
<button class="custom-css-button green">Add</button>
</div>
<div class="setting-row" id="remove-custom-css">
<div class="setting-description">
<div class="selected-css-path" id="custom-css-path">${ConfigUtil.getConfigItem('customCSS')}</div>
</div>
<div class="action red" id="css-delete-action">
<i class="material-icons">indeterminate_check_box</i>
<span>Delete</span>
</div>
</div>
</div>
<div class="title">Advanced</div>
<div class="settings-card">
<div class="setting-row" id="show-download-folder">
<div class="setting-description">Show downloaded file in the file manager</div>
<div class="setting-row" id="enable-error-reporting">
<div class="setting-description">Enable error reporting (requires restart)</div>
<div class="setting-control"></div>
</div>
<div class="setting-row" id="show-download-folder">
<div class="setting-description">Show downloaded files in file manager</div>
<div class="setting-control"></div>
</div>
<div class="setting-row" id="add-custom-css">
<div class="setting-description">
Add custom CSS
</div>
<button class="custom-css-button green">Upload</button>
</div>
<div class="setting-row" id="remove-custom-css">
<div class="setting-description">
<div class="selected-css-path" id="custom-css-path">${ConfigUtil.getConfigItem('customCSS')}</div>
</div>
<div class="action red" id="css-delete-action">
<i class="material-icons">indeterminate_check_box</i>
<span>Delete</span>
</div>
</div>
<div class="setting-row" id="download-folder">
<div class="setting-description">
Default download location
</div>
<button class="download-folder-button green">Choose</button>
<button class="download-folder-button green">Change</button>
</div>
<div class="setting-row">
<div class="setting-description">
@@ -123,7 +124,7 @@ class GeneralSection extends BaseSection {
<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 w-200">Reset App Data</button>
<button class="reset-data-button red w-150">Reset App Data</button>
</div>
</div>
</div>
@@ -148,6 +149,7 @@ class GeneralSection extends BaseSection {
this.removeCustomCSS();
this.downloadFolder();
this.showDownloadFolder();
this.enableErrorReporting();
// Platform specific settings
@@ -236,6 +238,10 @@ class GeneralSection extends BaseSection {
clickHandler: () => {
const newValue = !ConfigUtil.getConfigItem('autoUpdate');
ConfigUtil.setConfigItem('autoUpdate', newValue);
if (!newValue) {
ConfigUtil.setConfigItem('betaUpdate', false);
this.betaUpdateOption();
}
this.autoUpdateOption();
}
});
@@ -247,8 +253,10 @@ class GeneralSection extends BaseSection {
value: ConfigUtil.getConfigItem('betaUpdate', false),
clickHandler: () => {
const newValue = !ConfigUtil.getConfigItem('betaUpdate');
ConfigUtil.setConfigItem('betaUpdate', newValue);
this.betaUpdateOption();
if (ConfigUtil.getConfigItem('autoUpdate')) {
ConfigUtil.setConfigItem('betaUpdate', newValue);
this.betaUpdateOption();
}
}
});
}
@@ -316,6 +324,18 @@ class GeneralSection extends BaseSection {
});
}
enableErrorReporting() {
this.generateSettingOption({
$element: document.querySelector('#enable-error-reporting .setting-control'),
value: ConfigUtil.getConfigItem('errorReporting', true),
clickHandler: () => {
const newValue = !ConfigUtil.getConfigItem('errorReporting');
ConfigUtil.setConfigItem('errorReporting', newValue);
this.enableErrorReporting();
}
});
}
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());

View File

@@ -39,7 +39,6 @@ class NetworkSection extends BaseSection {
</div>
<div class="setting-row">
<div class="action green" id="proxy-save-action">
<i class="material-icons">check_box</i>
<span>Save</span>
</div>
</div>
@@ -100,7 +99,7 @@ class NetworkSection extends BaseSection {
if (newValue === false) {
// Remove proxy system proxy settings
ConfigUtil.setConfigItem('proxyRules', '');
ipcRenderer.send('forward-message', 'reload-proxy', true);
ipcRenderer.send('forward-message', 'reload-proxy', false);
}
ConfigUtil.setConfigItem('useSystemProxy', newValue);
this.updateProxyOption();

View File

@@ -14,6 +14,7 @@ class ShortcutsSection extends BaseSection {
return `
<div class="settings-pane">
<div class="settings-card tip"><p><b><i class="material-icons md-14">settings</i>Tip: </b>These desktop app shortcuts extend the Zulip webapp's <span id="open-hotkeys-link"> keyboard shortcuts</span>.</p></div>
<div class="title">Application Shortcuts</div>
<div class="settings-card">
<table>
@@ -129,6 +130,14 @@ class ShortcutsSection extends BaseSection {
<td><kbd>Option</kbd><kbd>${userOSKey}</kbd><kbd>U</kbd></td>
<td>Toggle DevTools for Active Tab</td>
</tr>
<tr>
<td><kbd>Ctrl</kbd> + <kbd>Tab</kbd></td>
<td>Switch to Next Organization</td>
</tr>
<tr>
<td><kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Tab</kbd></td>
<td>Switch to Previous Organization</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
@@ -160,7 +169,6 @@ class ShortcutsSection extends BaseSection {
</table>
<div class="setting-control"></div>
</div>
<div class="settings-card tip"><b><i class="material-icons md-14">settings</i>Tip: </b>These desktop app shortcuts extend the Zulip webapp's <span id="open-hotkeys-link">keyboard shortcuts</span>.</div>
</div>
`;
}
@@ -170,6 +178,7 @@ class ShortcutsSection extends BaseSection {
return `
<div class="settings-pane">
<div class="settings-card tip"><p><b><i class="material-icons md-14">settings</i>Tip: </b>These desktop app shortcuts extend the Zulip webapp's <span id="open-hotkeys-link"> keyboard shortcuts</span>.</p></div>
<div class="title">Application Shortcuts</div>
<div class="settings-card">
<table>
@@ -269,6 +278,14 @@ class ShortcutsSection extends BaseSection {
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>U</kbd></td>
<td>Toggle DevTools for Active Tab</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>Tab</kbd></td>
<td>Switch to Next Organization</td>
</tr>
<tr>
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>Tab</kbd></td>
<td>Switch to Previous Organization</td>
</tr>
</table>
<div class="setting-control"></div>
</div>
@@ -300,7 +317,6 @@ class ShortcutsSection extends BaseSection {
</table>
<div class="setting-control"></div>
</div>
<div class="tip"><b><i class="material-icons md-14">lightbulb_outline</i>Tip: </b>These desktop app shortcuts extend the Zulip webapp's <span id="open-hotkeys-link">keyboard shortcuts</span>.</div>
</div>
`;
}

View File

@@ -91,8 +91,15 @@ window.addEventListener('beforeunload', () => {
// electron's globalShortcut can cause unexpected results
// so adding the reload shortcut in the old-school way
// Zoom from numpad keys is not supported by electron, so adding it through listeners.
document.addEventListener('keydown', event => {
if (event.code === 'F5') {
ipcRenderer.send('forward-message', 'hard-reload');
} else if (event.ctrlKey && event.code === 'NumpadAdd') {
ipcRenderer.send('forward-message', 'zoomIn');
} else if (event.ctrlKey && event.code === 'NumpadSubtract') {
ipcRenderer.send('forward-message', 'zoomOut');
} else if (event.ctrlKey && event.code === 'Numpad0') {
ipcRenderer.send('forward-message', 'zoomActualSize');
}
});

View File

@@ -32,14 +32,7 @@ class SetupSpellChecker {
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');
this.SpellCheckHandler.switchLanguage(userLanguage);
}
const contextMenuBuilder = new ContextMenuBuilder(this.SpellCheckHandler);

View File

@@ -99,7 +99,9 @@ const renderNativeImage = function (arg) {
.then(() => renderCanvas(arg))
.then(canvas => {
const pngData = nativeImage.createFromDataURL(canvas.toDataURL('image/png')).toPNG();
return Promise.resolve(nativeImage.createFromBuffer(pngData, config.pixelRatio));
return Promise.resolve(nativeImage.createFromBuffer(pngData, {
scaleFactor: config.pixelRatio
}));
});
};
@@ -115,42 +117,29 @@ function sendAction(action) {
const createTray = function () {
window.tray = new Tray(iconPath());
const contextMenu = Menu.buildFromTemplate([{
label: 'About',
click() {
// We need to focus the main window first
ipcRenderer.send('focus-app');
sendAction('open-about');
const contextMenu = Menu.buildFromTemplate([
{
label: 'Zulip',
click() {
ipcRenderer.send('focus-app');
}
},
{
label: 'Settings',
click() {
ipcRenderer.send('focus-app');
sendAction('open-settings');
}
},
{
type: 'separator'
},
{
label: 'Quit',
click() {
ipcRenderer.send('quit-app');
}
}
},
{
type: 'separator'
},
{
label: 'Focus',
click() {
ipcRenderer.send('focus-app');
}
},
{
type: 'separator'
},
{
label: 'Settings',
click() {
ipcRenderer.send('focus-app');
sendAction('open-settings');
}
},
{
type: 'separator'
},
{
label: 'Quit',
click() {
ipcRenderer.send('quit-app');
}
}
]);
window.tray.setContextMenu(contextMenu);
if (process.platform === 'linux' || process.platform === 'win32') {

View File

@@ -9,9 +9,7 @@ const escape = require('escape-html');
const Logger = require('./logger-util');
const CertificateUtil = require(__dirname + '/certificate-util.js');
const ProxyUtil = require(__dirname + '/proxy-util.js');
const ConfigUtil = require(__dirname + '/config-util.js');
const RequestUtil = require(__dirname + '/../utils/request-util.js');
const logger = new Logger({
file: `domain-util.log`,
@@ -63,9 +61,10 @@ class DomainUtil {
}
addDomain(server) {
const ignoreCerts = server.ignoreCerts;
return new Promise(resolve => {
if (server.icon) {
this.saveServerIcon(server.icon).then(localIconUrl => {
this.saveServerIcon(server, ignoreCerts).then(localIconUrl => {
server.icon = localIconUrl;
this.db.push('/domains[]', server, true);
this.reloadDB();
@@ -102,40 +101,25 @@ class DomainUtil {
return false;
}
checkDomain(domain, silent = false) {
// ignoreCerts parameter helps in fetching server icon and
// other server details when user chooses to ignore certificate warnings
checkDomain(domain, ignoreCerts = false, silent = false) {
if (!silent && this.duplicateDomain(domain)) {
// Do not check duplicate in silent mode
return Promise.reject('This server has been added.');
}
domain = this.formatUrl(domain);
const certificate = CertificateUtil.getCertificate(encodeURIComponent(domain));
let certificateLocation = '';
if (certificate) {
// To handle case where certificate has been moved from the location in certificates.json
try {
certificateLocation = fs.readFileSync(certificate);
} catch (err) {
logger.warn('Error while trying to get certificate: ' + err);
}
}
const proxyEnabled = ConfigUtil.getConfigItem('useManualProxy') || ConfigUtil.getConfigItem('useSystemProxy');
// If certificate for the domain exists add it as a ca key in the request's parameter else consider only domain as the parameter for request
// Add proxy as a parameter if it sbeing used.
const checkDomain = {
url: domain + '/static/audio/zulip.ogg',
ca: (certificateLocation) ? certificateLocation : '',
proxy: proxyEnabled ? ProxyUtil.getProxy(domain) : ''
...RequestUtil.requestOptions(domain, ignoreCerts)
};
const serverConf = {
icon: defaultIconUrl,
url: domain,
alias: domain
alias: domain,
ignoreCerts
};
return new Promise((resolve, reject) => {
@@ -152,14 +136,14 @@ class DomainUtil {
const certsError = error.toString().includes('certificate');
if (!error && response.statusCode < 400) {
// Correct
this.getServerSettings(domain).then(serverSettings => {
this.getServerSettings(domain, serverConf.ignoreCerts).then(serverSettings => {
resolve(serverSettings);
}, () => {
resolve(serverConf);
});
} else if (domain.indexOf(whitelistDomains) >= 0 || certsError) {
if (silent) {
this.getServerSettings(domain).then(serverSettings => {
this.getServerSettings(domain, serverConf.ignoreCerts).then(serverSettings => {
resolve(serverSettings);
}, () => {
resolve(serverConf);
@@ -182,7 +166,9 @@ class DomainUtil {
detail: certErrorDetail
}, response => {
if (response === 0) {
this.getServerSettings(domain).then(serverSettings => {
// set ignoreCerts parameter to true in case user responds with yes
serverConf.ignoreCerts = true;
this.getServerSettings(domain, serverConf.ignoreCerts).then(serverSettings => {
resolve(serverSettings);
}, () => {
resolve(serverConf);
@@ -202,12 +188,12 @@ class DomainUtil {
});
}
getServerSettings(domain) {
const proxyEnabled = ConfigUtil.getConfigItem('useManualProxy') || ConfigUtil.getConfigItem('useSystemProxy');
getServerSettings(domain, ignoreCerts = false) {
const serverSettingsOptions = {
url: domain + '/api/v1/server_settings',
proxy: proxyEnabled ? ProxyUtil.getProxy(domain) : ''
...RequestUtil.requestOptions(domain, ignoreCerts)
};
return new Promise((resolve, reject) => {
request(serverSettingsOptions, (error, response) => {
if (!error && response.statusCode === 200) {
@@ -218,7 +204,8 @@ class DomainUtil {
// Following check handles both the cases
icon: data.realm_icon.startsWith('/') ? data.realm_uri + data.realm_icon : data.realm_icon,
url: data.realm_uri,
alias: escape(data.realm_name)
alias: escape(data.realm_name),
ignoreCerts
});
}
} else {
@@ -228,12 +215,15 @@ class DomainUtil {
});
}
saveServerIcon(url) {
const proxyEnabled = ConfigUtil.getConfigItem('useManualProxy') || ConfigUtil.getConfigItem('useSystemProxy');
saveServerIcon(server, ignoreCerts = false) {
const url = server.icon;
const domain = server.url;
const serverIconOptions = {
url,
proxy: proxyEnabled ? ProxyUtil.getProxy(url) : ''
...RequestUtil.requestOptions(domain, ignoreCerts)
};
// The save will always succeed. If url is invalid, downgrade to default icon.
return new Promise(resolve => {
const filePath = this.generateFilePath(url);
@@ -266,8 +256,9 @@ class DomainUtil {
updateSavedServer(url, index) {
// Does not promise successful update
this.checkDomain(url, true).then(newServerConf => {
this.saveServerIcon(newServerConf.icon).then(localIconUrl => {
const ignoreCerts = this.getDomain(index).ignoreCerts;
this.checkDomain(url, ignoreCerts, true).then(newServerConf => {
this.saveServerIcon(newServerConf, ignoreCerts).then(localIconUrl => {
newServerConf.icon = localIconUrl;
this.updateDomain(index, newServerConf);
this.reloadDB();

View File

@@ -1,14 +1,28 @@
const NodeConsole = require('console').Console;
const fs = require('fs');
const os = require('os');
const isDev = require('electron-is-dev');
const { initSetUp } = require('./default-util');
const { sentryInit, captureException } = require('./sentry-util');
initSetUp();
sentryInit();
let app = null;
let reportErrors = true;
if (process.type === 'renderer') {
app = require('electron').remote.app;
// Report Errors to Sentry only if it is enabled in settings
// Gets the value of reportErrors from config-util for renderer process
// For main process, sentryInit() is handled in index.js
const { ipcRenderer } = require('electron');
ipcRenderer.send('error-reporting');
ipcRenderer.on('error-reporting-val', (event, errorReporting) => {
reportErrors = errorReporting;
if (reportErrors) {
sentryInit();
}
});
} else {
app = require('electron').app;
}
@@ -30,6 +44,13 @@ class Logger {
timestamp = this.getTimestamp;
}
// Trim log according to type of process
if (process.type === 'renderer') {
requestIdleCallback(() => this.trimLog(file));
} else {
process.nextTick(() => this.trimLog(file));
}
const fileStream = fs.createWriteStream(file, { flags: 'a' });
const nodeConsole = new NodeConsole(fileStream);
@@ -86,7 +107,27 @@ class Logger {
}
reportSentry(err) {
captureException(err);
if (reportErrors) {
captureException(err);
}
}
trimLog(file) {
fs.readFile(file, 'utf8', (err, data) => {
if (err) {
throw err;
}
const MAX_LOG_FILE_LINES = 500;
const logs = data.split(os.EOL);
const logLength = logs.length - 1;
// Keep bottom MAX_LOG_FILE_LINES of each log instance
if (logLength > MAX_LOG_FILE_LINES) {
const trimmedLogs = logs.slice(logLength - MAX_LOG_FILE_LINES);
const toWrite = trimmedLogs.join(os.EOL);
fs.writeFileSync(file, toWrite);
}
});
}
}

View File

@@ -52,7 +52,7 @@ class ProxyUtil {
resolveSystemProxy(mainWindow) {
const page = mainWindow.webContents;
const ses = page.session;
const resolveProxyUrl = 'www.google.com';
const resolveProxyUrl = 'www.example.com';
// Check HTTP Proxy
const httpProxy = new Promise(resolve => {

View File

@@ -45,8 +45,8 @@ class ReconnectUtil {
const errMsgHolder = document.querySelector('#description');
if (errMsgHolder) {
errMsgHolder.innerHTML = `
<div>You internet connection does't seem to work properly!</div>
</div>Verify that it works and then click try again.</div>`;
<div>Your internet connection doesn't seem to work properly!</div>
<div>Verify that it works and then click try again.</div>`;
}
return resolve(false);
});

View File

@@ -0,0 +1,62 @@
const fs = require('fs');
const Logger = require('./logger-util');
const CertificateUtil = require(__dirname + '/certificate-util.js');
const ProxyUtil = require(__dirname + '/proxy-util.js');
const ConfigUtil = require(__dirname + '/config-util.js');
const SystemUtil = require(__dirname + '/../utils/system-util.js');
const logger = new Logger({
file: `request-util.log`,
timestamp: true
});
let instance = null;
class RequestUtil {
constructor() {
if (!instance) {
instance = this;
}
return instance;
}
// ignoreCerts parameter helps in fetching server icon and
// other server details when user chooses to ignore certificate warnings
requestOptions(domain, ignoreCerts) {
domain = this.formatUrl(domain);
const certificate = CertificateUtil.getCertificate(
encodeURIComponent(domain)
);
let certificateLocation = '';
if (certificate) {
// To handle case where certificate has been moved from the location in certificates.json
try {
certificateLocation = fs.readFileSync(certificate);
} catch (err) {
logger.warn('Error while trying to get certificate: ' + err);
}
}
const proxyEnabled = ConfigUtil.getConfigItem('useManualProxy') || ConfigUtil.getConfigItem('useSystemProxy');
// If certificate for the domain exists add it as a ca key in the request's parameter else consider only domain as the parameter for request
// Add proxy as a parameter if it is being used.
return {
ca: certificateLocation ? certificateLocation : '',
proxy: proxyEnabled ? ProxyUtil.getProxy(domain) : '',
ecdhCurve: 'auto',
headers: { 'User-Agent': SystemUtil.getUserAgent() },
rejectUnauthorized: !ignoreCerts
};
}
formatUrl(domain) {
const hasPrefix = (domain.indexOf('http') === 0);
if (hasPrefix) {
return domain;
} else {
return (domain.indexOf('localhost:') >= 0) ? `http://${domain}` : `https://${domain}`;
}
}
}
module.exports = new RequestUtil();

View File

@@ -1,56 +1,56 @@
<!DOCTYPE html>
<html lang="en" class="responsive desktop">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<title>Zulip</title>
<link rel="stylesheet" href="css/main.css" type="text/css" media="screen">
</head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<title>Zulip</title>
<link rel="stylesheet" href="css/main.css" type="text/css" media="screen">
</head>
<body>
<div id="content">
<div class="popup">
<span class="popuptext hidden" id="fullscreen-popup"></span>
</div>
<div id="sidebar" class="toggle-sidebar">
<div id="view-controls-container">
<div id="tabs-container"></div>
<div id="add-tab" class="tab functional-tab">
<div class="server-tab" id="add-action">
<i class="material-icons">add</i>
<body>
<div id="content">
<div class="popup">
<span class="popuptext hidden" id="fullscreen-popup"></span>
</div>
<div id="sidebar" class="toggle-sidebar">
<div id="view-controls-container">
<div id="tabs-container"></div>
<div id="add-tab" class="tab functional-tab">
<div class="server-tab" id="add-action">
<i class="material-icons">add</i>
</div>
<span id="add-server-tooltip" style="display:none">Add organization</span>
</div>
</div>
<div id="actions-container">
<div class="action-button" id="dnd-action">
<i class="material-icons md-48">notifications</i>
<span id="dnd-tooltip" style="display:none">Do Not Disturb</span>
</div>
<div class="action-button" id="reload-action">
<i class="material-icons md-48">refresh</i>
<span id="reload-tooltip" style="display:none">Reload</span>
</div>
<div class="action-button disable" id="back-action">
<i class="material-icons md-48">arrow_back</i>
<span id="back-tooltip" style="display:none">Go Back</span>
</div>
<div class="action-button" id="settings-action">
<i class="material-icons md-48">settings</i>
<span id="setting-tooltip" style="display:none">Settings</span>
</div>
</div>
</div>
<div id="main-container">
<div id="webviews-container"></div>
</div>
</div>
<span id="add-server-tooltip" style="display:none">Add organization</span>
</div>
</div>
<div id="actions-container">
<div class="action-button" id="dnd-action">
<i class="material-icons md-48">notifications</i>
<span id="dnd-tooltip" style="display:none">Do Not Disturb</span>
</div>
<div class="action-button" id="reload-action">
<i class="material-icons md-48">refresh</i>
<span id="reload-tooltip" style="display:none">Reload</span>
</div>
<div class="action-button disable" id="back-action">
<i class="material-icons md-48">arrow_back</i>
<span id="back-tooltip" style="display:none">Go Back</span>
</div>
<div class="action-button" id="settings-action">
<i class="material-icons md-48">settings</i>
<span id="setting-tooltip" style="display:none">Settings</span>
</div>
</div>
</div>
<div id="main-container">
<div id="webviews-container"></div>
</div>
</div>
<div id="feedback-modal">
<send-feedback></send-feedback>
</div>
</body>
<script src="js/main.js"></script>
<script>require('./js/shared/preventdrag.js')</script>
<div id="feedback-modal">
<send-feedback></send-feedback>
</div>
</body>
<script src="js/main.js"></script>
<script>require('./js/shared/preventdrag.js')</script>
</html>

View File

@@ -1,22 +1,22 @@
<!DOCTYPE html>
<html lang="en" class="responsive desktop">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<title>Zulip - Network Troubleshooting</title>
<link rel="stylesheet" href="css/network.css" type="text/css" media="screen">
</head>
<body>
<div id="content">
<div id="picture"><img src="img/zulip_network.png"></div>
<div id="title">Zulip can't connect</div>
<div id="description">
<div>Your computer seems to be offline.</div>
<div>We will keep trying to reconnect, or you can try now.</div>
</div>
<div id="reconnect">Try now</div>
</div>
</body>
<script src="js/pages/network.js"></script>
<script>require('./js/shared/preventdrag.js')</script>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<title>Zulip - Network Troubleshooting</title>
<link rel="stylesheet" href="css/network.css" type="text/css" media="screen">
</head>
<body>
<div id="content">
<div id="picture"><img src="img/zulip_network.png"></div>
<div id="title">Zulip can't connect</div>
<div id="description">
<div>Your computer seems to be offline.</div>
<div>We will keep trying to reconnect, or you can try now.</div>
</div>
<div id="reconnect">Try now</div>
</div>
</body>
<script src="js/pages/network.js"></script>
<script>require('./js/shared/preventdrag.js')</script>
</html>

View File

@@ -1,17 +1,17 @@
<!DOCTYPE html>
<html lang="en" class="responsive desktop">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<title>Zulip - Settings</title>
<link rel="stylesheet" href="css/preference.css" type="text/css" media="screen">
</head>
<body>
<div id="content">
<div id="sidebar"></div>
<div id="settings-container"></div>
</div>
</body>
<script src="js/pages/preference/preference.js"></script>
<script>require('./js/shared/preventdrag.js')</script>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<title>Zulip - Settings</title>
<link rel="stylesheet" href="css/preference.css" type="text/css" media="screen">
</head>
<body>
<div id="content">
<div id="sidebar"></div>
<div id="settings-container"></div>
</div>
</body>
<script src="js/pages/preference/preference.js"></script>
<script>require('./js/shared/preventdrag.js')</script>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -1,9 +1,39 @@
# Version History
All notable changes to the Zulip desktop app are documented in this file.
### v2.3.82 --2018-09-25
**New features**:
* UI enhancements.
* Updated some menu items.
**Fixes**:
* Fix about page not opening up.
<hr>
### v2.3.8 --2018-09-25
**New features**:
* Auto hide menubar on Windows/Linux. Add a setting option for the same.
* Improve design of setting page.
* Toggle app on clicking the tray icon (Linux).
* Update sidebar realm name when it's changed in webapp.
* left-sidebar: Add initial character of realm name instead of default icon.
**Fixes**:
* linux: Fix ALT+SHIFT opening menu items on Linux.
* sentry: Add ignore errors to sentry configuration.
* Linux: Add label for help menu item.
* file-attachments: Allow multiple downloads of same file name.
**Module Updates**
* electron: Update electron to v2.0.9.
<hr>
### v2.3.7-beta --2018-09-03
@@ -262,7 +292,7 @@ electron-updater - `v2.21.8`
* Setting page and left-sidebar UI improvements
* Other minor improvments
* Other minor improvements
@@ -389,7 +419,7 @@ electron-updater - `v2.21.8`
* Fixed a bug which was caused by app's shortcuts. From now on our shortcuts won't hijack other apps shortcuts
* Removed [electron-localshortcut](https://github.com/parro-it/electron-localshortcut) completely. Now we only depends on menu accelerators for keyboard shortcuts
* Removed [electron-localshortcut](https://github.com/parro-it/electron-localshortcut) completely. Now we only depend on menu accelerators for keyboard shortcuts
* Handle certificate issue properly
@@ -590,7 +620,7 @@ electron-updater - `v2.21.8`
* Properly signed app for macOS
* Toggle tray icon
* Better error handling when no internet connenction
* Better error handling when no internet connection
@@ -604,7 +634,7 @@ electron-updater - `v2.21.8`
### v0.5.8 --2017-02-13
**Enhacements**:
**Enhancements**:
Smaller Windows installer size
<hr>
@@ -620,7 +650,7 @@ Minor improvements
### v0.5.6 --2017-02-07
**Enhacements**:
**Enhancement**:
- Using NSIS instead of [Squirrel.Windows](https://github.com/Squirrel/Squirrel.Windows) on Windows
@@ -642,9 +672,9 @@ Minor improvements
**Fixes**:
- Fixed :
- Auto-updates
- Spellchecker
- Zooming functionality
- Auto-updates
- Spellchecker
- Zooming functionality
- Removed unused node modules
- Using stable version for node modules
@@ -688,7 +718,7 @@ Minor improvements
### v0.5.1 --2016-11-23
**Enhacements**:
**Enhancement**:
- Added Spellchecker support with correct spell suggestions
@@ -729,6 +759,6 @@ Minor improvements
### v0.0.1-alpha -- 2016-08-31
**Enhacements**:
**Enhancement**:
* Added DMG installer for macOS

View File

@@ -1,85 +1,152 @@
# Improve development guide
# Development setup
This is a guide to running the Zulip desktop app from a source tree,
in order to contribute to developing it.
This is a guide to running the Zulip desktop app from a source tree, in order to contribute to developing it. The Zulip electron development environment can be installed on **macOS, Windows, and Linux** (Debian or Ubuntu recommended). Youll need at least **2GB of available RAM**. Installing the Zulip electron development environment requires downloading several hundred megabytes of dependencies, so you will need an **active, reasonably fast, internet connection throughout the entire installation processes.**
## Prerequisites
# Set up Git & GitHub
To build and run the app from source, you'll need the following:
You can skip this step if you already have Git, GitHub.
* [Git](http://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [Node.js](https://nodejs.org) >= v6.9.0
* [NPM](https://www.npmjs.com/get-npm) and
[node-gyp](https://github.com/nodejs/node-gyp#installation),
if they don't come bundled with your Node.js installation
* [Python](https://www.python.org/downloads/release/python-2713/)
(v2.7.x recommended)
* A C++ compiler compatible with C++11
* Linux users also need [Snapcraft](https://snapcraft.io/)
* Development headers for the libXext, libXtst, and libxkbfile libraries
Follow our [Git Guide](https://zulip.readthedocs.io/en/latest/git/setup.html) in order to install Git, set up a GitHub account
### Debian/Ubuntu and friends
On a system running Debian, Ubuntu, or another Debian-based Linux
distribution, you can install all dependencies through the package
manager (see [here][nodesource-install] for more on the first command):
# Install Prerequisites
```sh
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
$ sudo apt install git nodejs python build-essential snapcraft libxext-dev libxtst-dev libxkbfile-dev libgconf-2-4
```
Jump to:
[nodesource-install]: https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions
- [MacOS](https://github.com/zulip/zulip-desktop/blob/master/development.md#macos)
- [Ubuntu/Debian](https://github.com/zulip/zulip-desktop/blob/master/development.md#ubuntudebian)
- [Windows](https://github.com/zulip/zulip-desktop/blob/master/development.md#windows)
### Other OSes
Other developers run the app on Windows, macOS, and possibly other OSes.
PRs to add specific instructions to this doc are welcome!
## MacOS
On Windows, your C++ compiler should be Visual Studio 2015 or later.
## Download, build, and run
**Node JS**
Go to the [Node.js Downloads page](https://nodejs.org/en/download/). Download Node.js for MacOS (`v6.9.0` or above recommended). Run the downloaded Node.js `.pkg` Installer. You're finished! To ensure Node.js has been installed, run `node -v` in your terminal - you should get something like `v6.9.0` or above
Clone the source locally:
```sh
$ git clone https://github.com/zulip/zulip-electron
$ cd zulip-electron
```
Install project dependencies:
```sh
$ npm install
```
**if** [**NPM**](https://www.npmjs.com/get-npm) **and** [**node-gyp**](https://github.com/nodejs/node-gyp#installation) **don't come bundled with your Node.js installation, Download manually**
Start the app:
```sh
$ npm start
```
Start and watch changes:
```sh
$ npm run dev
```
Now you are ready for next step [: Get Zulip Desktop Code.](https://github.com/zulip/zulip-desktop/blob/master/development.md#get-zulip-desktop-code)
## Troubleshooting
If you have any problems running the app, see the [most common
issues](./troubleshooting.md).
## Ubuntu/Debian
## Making a release
To package the app into an installer:
```
npm run dist
```
If youre in a hurry, you can copy and paste the following into your terminal
This command will produce distributable packages or installers for the
operating system you're running on:
* on Windows, a Windows installer file
* on macOS, a `.dmg` file
* on Linux, a plain `.zip` file as well as a `.deb` file, `.snap` file and an
`AppImage` file.
To generate all three types, you will need all three operating
systems.
sudo apt install git nodejs node-gyp python build-essential snapcraft libxext-dev libxtst-dev lib xkbfile-dev libgconf-2-4
The output files appear in the `dist/` directory.
after pasting you can jump to next step [: Get Zulip Desktop Code](https://github.com/zulip/zulip-desktop/blob/master/development.md#get-zulip-desktop-code).
**For a step-by-step explanation, read on.**
1. **Node JS**
`$ sudo apt-get install nodejs`
2. **Install** [**Node-gyp**](https://github.com/nodejs/node-gyp#installation)
3. **Python (v2.7.x recommended)**
`$ sudo apt install python2.7`
4. **C++ compiler compatible with C++11**
`$ sudo apt install build-essential`
5. **Snapcraft**
`$ sudo apt install snapcraft`
6. **Development** **headers**
`$ sudo apt install libxext-dev libxtst-dev libxkbfile-dev libgconf-2-4`
**if** [**NPM**](https://www.npmjs.com/get-npm) **don't come bundled with your Node.js installation, Download manually**
Now you are ready for next step [: Get Zulip Desktop Code.](https://github.com/zulip/zulip-desktop/blob/master/development.md#get-zulip-desktop-code)
## Windows
**Node JS**
Go to the [Node.js Downloads page](https://nodejs.org/en/download/). Download Node.js for windows (`v6.9.0` or above recommended). Run the downloaded Node.js `.msi` Installer. You're finished! To ensure Node.js has been installed, run `node -v` in your terminal - you should get something like `v6.9.0` or above
**Followings are optional yet recommended prerequisites -**
**Cmder**
1. Download the [latest release](https://github.com/cmderdev/cmder/releases/)
2. Extract the archive. *Note: This path should not be* `C:\Program Files` *or anywhere else that would require Administrator access for modifying configuration files*
3. (optional) Place your own executable files into the `%cmder_root%\bin` folder to be injected into your PATH.
4. Run `Cmder.exe`
**Chocolatey**
You can download chocolatey from here https://chocolatey.org/ and for Installing Chocolatey on your machine follow this steps
1. First, ensure that you are using an administrative shell.
2. Copy the text specific to your command shell - [cmd.exe](https://chocolatey.org/install#install-with-cmdexe) or [powershell.exe](https://chocolatey.org/install#install-with-powershellexe).
3. Paste the copied text into your shell and press Enter.
4. Wait a few seconds for the command to complete.
5. If you don't see any errors, you are ready to use Chocolatey! Type `choco` or `choco -?`
**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 and paste this
C:\Windows\system32> npm install --global --production windows-build-tools
**if** [**NPM**](https://www.npmjs.com/get-npm) **and** [**node-gyp**](https://github.com/nodejs/node-gyp#installation) **don't come bundled with your Node.js installation, Download manually**
Now you are ready for next step [: Get Zulip Desktop Code.](https://github.com/zulip/zulip-desktop/blob/master/development.md#get-zulip-desktop-code)
# Get Zulip Desktop Code
1. In your browser, visit https://github.com/zulip/zulip-desktop and click the `fork` button. You will need to be logged in to GitHub to do this.
2. Open Terminal (macOS/Ubuntu) or Git BASH (Windows; must **run as an Administrator**).
3. In Terminal/Git BASH, [clone your fork of the zulip-desktop repository](https://github.com/zulip/zulip-desktop/blob/master/development.md#clone-to-your-machine) and [connect the zulip-desktop upstream repository](https://github.com/zulip/zulip-desktop/blob/master/development.md#connect-your-fork-to-zulip-desktop-upstream)
## Clone to your machine
1. On GitHub, navigate to the main page of your fork repository.
2. Under the repository name, click **Clone or download**.
3. In the Clone with HTTPs section, click to copy the clone URL for the repository.
4. Open Terminal, Change the current working directory to the location where you want the cloned directory to be made.
git clone https://github.com/YOURUSERNAME/zulip-desktop.git
Dont forget to replace YOURUSERNAME with your git username
## Connect your fork to zulip-desktop upstream
cd zulip-desktop
git remote add -f upstream https://github.com/zulip/zulip-desktop.git
# build and run
## Install project dependencies:
$ npm install
## There two ways to start the app:
**vanilla method**
$ npm start
**start and watch changes recommended for devs**
$ npm run dev

View File

@@ -21,8 +21,8 @@ C:\Windows\system32> npm install --global --production windows-build-tools
Clone the source locally:
```sh
$ git clone https://github.com/zulip/zulip-electron
$ cd zulip-electron
$ git clone https://github.com/zulip/zulip-desktop
$ cd zulip-desktop
```
Install project dependencies:

View File

@@ -1,3 +1,3 @@
### Want to contribute to this Wiki?
[Edit `/docs` files and send a pull request.](https://github.com/zulip/zulip-electron/tree/master/docs)
[Edit `/docs` files and send a pull request.](https://github.com/zulip/zulip-desktop/tree/master/docs)

View File

@@ -1,10 +1,10 @@
# How to install
**Note:** If you download from the [releases page](https://github.com/zulip/zulip-electron/releases), be careful what version you pick. Releases that end with `-beta` are beta releases and the rest are stable.
**Note:** If you download from the [releases page](https://github.com/zulip/zulip-desktop/releases), be careful what version you pick. Releases that end with `-beta` are beta releases and the rest are stable.
- **beta:** these releases are the right balance between getting new features early while staying away from nasty bugs.
- **stable:** these releases are more thoroughly tested; they receive new features later, but there's a lower chance that things will go wrong.
[LR]: https://github.com/zulip/zulip-electron/releases
[LR]: https://github.com/zulip/zulip-desktop/releases
## OS X

3795
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "zulip",
"productName": "Zulip",
"version": "2.3.8",
"version": "3.0.0",
"main": "./app/main",
"description": "Zulip Desktop App",
"license": "Apache-2.0",
@@ -12,10 +12,10 @@
},
"repository": {
"type": "git",
"url": "https://github.com/zulip/zulip-electron.git"
"url": "https://github.com/zulip/zulip-desktop.git"
},
"bugs": {
"url": "https://github.com/zulip/zulip-electron/issues"
"url": "https://github.com/zulip/zulip-desktop/issues"
},
"engines": {
"node": ">=6.0.0"
@@ -24,7 +24,10 @@
"start": "electron app --disable-http-cache --no-electron-connect",
"reinstall": "node ./tools/reinstall-node-modules.js",
"postinstall": "electron-builder install-app-deps",
"test": "xo",
"lint-css": "stylelint app/renderer/css/*.css",
"lint-html": "./node_modules/.bin/htmlhint \"app/renderer/*.html\" ",
"lint-js": "xo",
"test": "npm run lint-html && npm run lint-css && npm run lint-js",
"test-e2e": "gulp test-e2e",
"dev": "gulp dev & nodemon --watch app/main --watch app/renderer --exec 'npm test' -e html,css,js",
"pack": "electron-builder --dir",
@@ -44,7 +47,7 @@
"!docs${/*}",
"!node_modules/@paulcbetts/cld/deps/cld${/*}"
],
"copyright": "©2017 Kandra Labs, Inc.",
"copyright": "©2019 Kandra Labs, Inc.",
"mac": {
"category": "public.app-category.productivity",
"artifactName": "${productName}-${version}-${arch}.${ext}"
@@ -59,7 +62,7 @@
"AppImage",
"snap"
],
"maintainer": "Akash Nimare <svnitakash@gmail.com>",
"maintainer": "Akash Nimare <akash@zulipchat.com>",
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"deb": {
@@ -103,12 +106,13 @@
}
],
"icon": "build/icon.ico",
"artifactName": "${productName}-Web-Setup-${version}.${ext}",
"publisherName": "Kandra Labs, Inc."
},
"nsis": {
"perMachine": true,
"allowToChangeInstallationDirectory": true,
"oneClick": false,
"allowToChangeInstallationDirectory": true
"perMachine": false
}
},
"keywords": [
@@ -121,21 +125,23 @@
],
"devDependencies": {
"assert": "1.4.1",
"cp-file": "^5.0.0",
"cp-file": "5.0.0",
"devtron": "1.4.0",
"electron": "2.0.9",
"electron-builder": "20.28.3",
"electron": "3.0.10",
"electron-builder": "20.40.2",
"electron-connect": "0.6.2",
"electron-debug": "1.4.0",
"google-translate-api": "2.3.0",
"gulp": "^4.0.0",
"gulp": "4.0.0",
"gulp-tape": "0.0.9",
"is-ci": "^1.0.10",
"nodemon": "^1.14.11",
"htmlhint": "0.11.0",
"is-ci": "1.0.10",
"nodemon": "1.14.11",
"pre-commit": "1.2.2",
"spectron": "3.8.0",
"tap-colorize": "^1.2.0",
"tape": "^4.8.0",
"spectron": "5.0.0",
"stylelint": "9.10.1",
"tap-colorize": "1.2.0",
"tape": "4.8.0",
"xo": "0.18.2"
},
"xo": {
@@ -153,7 +159,7 @@
"max-lines": [
"warn",
{
"max": 600,
"max": 700,
"skipBlankLines": true,
"skipComments": true
}

View File

@@ -1,5 +1,5 @@
name: zulip
version: 2.0.0
version: 2.3.82
summary: Zulip Desktop Client for Linux
description: Zulip combines the immediacy of Slack with an email threading model. With Zulip, you can catch up on important conversations while ignoring irrelevant ones.
confinement: strict
@@ -34,4 +34,4 @@ parts:
- libxtst6
source: dist/linux-unpacked
after:
- desktop-gtk2
- desktop-gtk3

View File

@@ -1,185 +1,183 @@
{
"name": "zulip",
"productName": "ZulipTest",
"version": "2.3.3",
"main": "../../app/main",
"description": "Zulip Desktop App",
"license": "Apache-2.0",
"copyright": "Kandra Labs, Inc.",
"author": {
"name": "Kandra Labs, Inc.",
"email": "support@zulipchat.com"
},
"repository": {
"type": "git",
"url": "https://github.com/zulip/zulip-electron.git"
},
"bugs": {
"url": "https://github.com/zulip/zulip-electron/issues"
},
"engines": {
"node": ">=6.0.0"
},
"scripts": {
"start": "electron app --disable-http-cache --no-electron-connect",
"reinstall": "node ./tools/reinstall-node-modules.js",
"postinstall": "electron-builder install-app-deps",
"test": "xo",
"test-e2e": "gulp test-e2e",
"dev": "gulp dev & nodemon --watch app/main --watch app/renderer --exec 'npm test' -e html,css,js",
"pack": "electron-builder --dir",
"dist": "electron-builder",
"mas": "electron-builder --mac mas",
"travis": "cd ./scripts && ./travis-build-test.sh",
"build-locales": "node tools/locale-helper"
},
"pre-commit": [
"test"
],
"build": {
"appId": "org.zulip.zulip-electron",
"asar": true,
"files": [
"**/*",
"!docs${/*}",
"!node_modules/@paulcbetts/cld/deps/cld${/*}"
],
"copyright": "©2017 Kandra Labs, Inc.",
"mac": {
"category": "public.app-category.productivity",
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"linux": {
"category": "Chat;GNOME;GTK;Network;InstantMessaging",
"packageCategory": "GNOME;GTK;Network;InstantMessaging",
"description": "Zulip Desktop Client for Linux",
"target": [
"deb",
"zip",
"AppImage",
"snap"
],
"maintainer": "Akash Nimare <svnitakash@gmail.com>",
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"deb": {
"synopsis": "Zulip Desktop App",
"afterInstall": "./scripts/debian-add-repo.sh",
"afterRemove": "./scripts/debian-uninstaller.sh"
},
"snap": {
"synopsis": "Zulip Desktop App"
},
"dmg": {
"background": "build/appdmg.png",
"icon": "build/icon.icns",
"iconSize": 100,
"contents": [
{
"x": 380,
"y": 280,
"type": "link",
"path": "/Applications"
"name": "zulip",
"productName": "Zulip",
"version": "2.4.0",
"main": "../../app/main",
"description": "Zulip Desktop App",
"license": "Apache-2.0",
"copyright": "Kandra Labs, Inc.",
"author": {
"name": "Kandra Labs, Inc.",
"email": "support@zulipchat.com"
},
{
"x": 110,
"y": 280,
"type": "file"
}
],
"window": {
"width": 500,
"height": 500
}
},
"win": {
"target": [
{
"target": "nsis-web",
"arch": [
"x64",
"ia32"
]
}
],
"icon": "build/icon.ico",
"publisherName": "Kandra Labs, Inc."
},
"nsis": {
"perMachine": true,
"oneClick": false,
"allowToChangeInstallationDirectory": true
}
},
"keywords": [
"Zulip",
"Group Chat app",
"electron-app",
"electron",
"Desktop app",
"InstantMessaging"
],
"devDependencies": {
"assert": "1.4.1",
"cp-file": "^5.0.0",
"devtron": "1.4.0",
"electron": "2.0.1",
"electron-builder": "20.20.4",
"electron-connect": "0.6.2",
"electron-debug": "1.4.0",
"google-translate-api": "2.3.0",
"gulp": "^4.0.0",
"gulp-tape": "0.0.9",
"is-ci": "^1.0.10",
"nodemon": "^1.14.11",
"pre-commit": "1.2.2",
"spectron": "3.8.0",
"tap-colorize": "^1.2.0",
"tape": "^4.8.0",
"xo": "0.18.2"
},
"xo": {
"parserOptions": {
"sourceType": "script",
"ecmaFeatures": {
"globalReturn": true
}
},
"esnext": true,
"overrides": [
{
"files": "app*/**/*.js",
"rules": {
"max-lines": [
"warn",
{
"max": 500,
"skipBlankLines": true,
"skipComments": true
"repository": {
"type": "git",
"url": "https://github.com/zulip/zulip-electron.git"
},
"bugs": {
"url": "https://github.com/zulip/zulip-electron/issues"
},
"engines": {
"node": ">=6.0.0"
},
"scripts": {
"start": "electron app --disable-http-cache --no-electron-connect",
"reinstall": "node ./tools/reinstall-node-modules.js",
"postinstall": "electron-builder install-app-deps",
"test": "xo",
"test-e2e": "gulp test-e2e",
"dev": "gulp dev & nodemon --watch app/main --watch app/renderer --exec 'npm test' -e html,css,js",
"pack": "electron-builder --dir",
"dist": "electron-builder",
"mas": "electron-builder --mac mas",
"travis": "cd ./scripts && ./travis-build-test.sh",
"build-locales": "node tools/locale-helper"
},
"pre-commit": [
"test"
],
"build": {
"appId": "org.zulip.zulip-electron",
"asar": true,
"files": [
"**/*",
"!docs${/*}",
"!node_modules/@paulcbetts/cld/deps/cld${/*}"
],
"copyright": "©2017 Kandra Labs, Inc.",
"mac": {
"category": "public.app-category.productivity",
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"linux": {
"category": "Chat;GNOME;GTK;Network;InstantMessaging",
"packageCategory": "GNOME;GTK;Network;InstantMessaging",
"description": "Zulip Desktop Client for Linux",
"target": [
"deb",
"zip",
"AppImage",
"snap"
],
"maintainer": "Akash Nimare <svnitakash@gmail.com>",
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"deb": {
"synopsis": "Zulip Desktop App",
"afterInstall": "./scripts/debian-add-repo.sh",
"afterRemove": "./scripts/debian-uninstaller.sh"
},
"snap": {
"synopsis": "Zulip Desktop App"
},
"dmg": {
"background": "build/appdmg.png",
"icon": "build/icon.icns",
"iconSize": 100,
"contents": [
{
"x": 380,
"y": 280,
"type": "link",
"path": "/Applications"
},
{
"x": 110,
"y": 280,
"type": "file"
}
],
"window": {
"width": 500,
"height": 500
}
},
"win": {
"target": [
{
"target": "nsis-web",
"arch": [
"x64",
"ia32"
]
}
],
"icon": "build/icon.ico",
"publisherName": "Kandra Labs, Inc."
},
"nsis": {
"allowToChangeInstallationDirectory": true
}
],
"no-warning-comments": 0,
"object-curly-spacing": 0,
"capitalized-comments": 0,
"no-else-return": 0,
"no-path-concat": 0,
"no-alert": 0,
"guard-for-in": 0,
"prefer-promise-reject-errors": 0,
"import/no-unresolved": 0,
"import/no-extraneous-dependencies": 0,
"no-prototype-builtins": 0
},
"keywords": [
"Zulip",
"Group Chat app",
"electron-app",
"electron",
"Desktop app",
"InstantMessaging"
],
"devDependencies": {
"assert": "1.4.1",
"cp-file": "^5.0.0",
"devtron": "1.4.0",
"electron": "3.0.10",
"electron-builder": "20.38.4",
"electron-connect": "0.6.2",
"electron-debug": "1.4.0",
"google-translate-api": "2.3.0",
"gulp": "^4.0.0",
"gulp-tape": "0.0.9",
"is-ci": "^1.0.10",
"nodemon": "^1.14.11",
"pre-commit": "1.2.2",
"spectron": "3.8.0",
"tap-colorize": "^1.2.0",
"tape": "^4.8.0",
"xo": "0.18.2"
},
"xo": {
"parserOptions": {
"sourceType": "script",
"ecmaFeatures": {
"globalReturn": true
}
},
"esnext": true,
"overrides": [
{
"files": "app*/**/*.js",
"rules": {
"max-lines": [
"warn",
{
"max": 600,
"skipBlankLines": true,
"skipComments": true
}
],
"no-warning-comments": 0,
"object-curly-spacing": 0,
"capitalized-comments": 0,
"no-else-return": 0,
"no-path-concat": 0,
"no-alert": 0,
"guard-for-in": 0,
"prefer-promise-reject-errors": 0,
"import/no-unresolved": 0,
"import/no-extraneous-dependencies": 0,
"no-prototype-builtins": 0
}
}
],
"ignore": [
"tests/*.js",
"tools/locale-helper/*.js"
],
"envs": [
"node",
"browser",
"mocha"
]
}
}
],
"ignore": [
"tests/e2e/*.js",
"tools/locale-helper/*.js"
],
"envs": [
"node",
"browser",
"mocha"
]
}
}
}

View File

@@ -48,10 +48,10 @@ envSetup()
# Set name of upstreamRemote
cd $workingDir
git remote -v | grep "github\.com.zulip.zulip-electron.git (fetch)" > /dev/null 2>&1
git remote -v | grep "github\.com.zulip.zulip-desktop.git (fetch)" > /dev/null 2>&1
if [ $? -eq 0 ]
then
upstreamRemote=`git remote -v | grep "github\.com.zulip.zulip-electron.git (fetch)" | awk '{ print $1 }'`
upstreamRemote=`git remote -v | grep "github\.com.zulip.zulip-desktop.git (fetch)" | awk '{ print $1 }'`
else
upstreamRemote="origin"
fi