mirror of
				https://github.com/zulip/zulip-desktop.git
				synced 2025-10-31 03:53:34 +00:00 
			
		
		
		
	Compare commits
	
		
			26 Commits
		
	
	
		
			v2.3.4-bet
			...
			v2.3.7-bet
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 50647e330b | ||
|  | 73dc3db436 | ||
|  | 09cf21bf49 | ||
|  | c30d0cc77b | ||
|  | 872ad4d3e7 | ||
|  | 6fd9e1be8b | ||
|  | 76c7f24161 | ||
|  | f9c270492c | ||
|  | 371c580934 | ||
|  | 3eec4c2209 | ||
|  | debbfb6b7d | ||
|  | 8bd1492586 | ||
|  | 1115c6d5c3 | ||
|  | 9ba279213c | ||
|  | 89c35cb1d4 | ||
|  | 21d6eb52c5 | ||
|  | aa1538837b | ||
|  | ea103380b6 | ||
|  | 60d10d88d1 | ||
|  | 124a842bbd | ||
|  | 7130103999 | ||
|  | 26a144e1c2 | ||
|  | a5c1ae8726 | ||
|  | ed5096840d | ||
|  | 3f6d256910 | ||
|  | 28421992ba | 
							
								
								
									
										23
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								README.md
									
									
									
									
									
								
							| @@ -2,31 +2,26 @@ | |||||||
| [](https://travis-ci.org/zulip/zulip-electron) | [](https://travis-ci.org/zulip/zulip-electron) | ||||||
| [](https://ci.appveyor.com/project/akashnimare/zulip-electron/branch/master) | [](https://ci.appveyor.com/project/akashnimare/zulip-electron/branch/master) | ||||||
| [](https://github.com/sindresorhus/xo) | [](https://github.com/sindresorhus/xo) | ||||||
|  | [](https://chat.zulip.org) | ||||||
|  |  | ||||||
| Desktop client for Zulip. Available for Mac, Linux and Windows. | Desktop client for Zulip. Available for Mac, Linux, and Windows. | ||||||
|  |  | ||||||
| <img src="http://i.imgur.com/ChzTq4F.png"/> | <img src="http://i.imgur.com/ChzTq4F.png"/> | ||||||
|  |  | ||||||
| # Download | # Download | ||||||
| Please see [installation guide](https://zulipchat.com/help/desktop-app-install-guide). | Please see the [installation guide](https://zulipchat.com/help/desktop-app-install-guide). | ||||||
|  |  | ||||||
| # Features | # Features | ||||||
| * Sign in to multiple teams | * Sign in to multiple teams | ||||||
| * Desktop Notifications with inline reply support | * Desktop notifications with inline reply | ||||||
| * Multilanguage SpellChecker | * Tray/dock integration | ||||||
| * OSX/Win/Linux installers | * Multi-language spell checker | ||||||
| * Automatic Updates (macOS/Windows/Linux) | * Automatic updates | ||||||
| * Keyboard shortcuts |  | ||||||
|  |  | ||||||
| # Development |  | ||||||
| Please see our [development guide](./development.md) to get started and run app locally. |  | ||||||
|  |  | ||||||
| # Contribute | # Contribute | ||||||
|  |  | ||||||
| If you want to contribute please make sure to read [our documentation about contributing](./CONTRIBUTING.md) first. | 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). | ||||||
| * [Issue Tracker](https://github.com/zulip/zulip-electron/issues) |  | ||||||
| * [Source Code](https://github.com/zulip/zulip-electron/) |  | ||||||
|  |  | ||||||
| # License | # License | ||||||
| Released under the [Apache-2.0](./LICENSE) license. | Released under the [Apache-2.0](./LICENSE) license. | ||||||
|   | |||||||
| @@ -73,7 +73,8 @@ function createMainWindow() { | |||||||
| 		minHeight: 400, | 		minHeight: 400, | ||||||
| 		webPreferences: { | 		webPreferences: { | ||||||
| 			plugins: true, | 			plugins: true, | ||||||
| 			nodeIntegration: true | 			nodeIntegration: true, | ||||||
|  | 			partition: 'persist:webviewsession' | ||||||
| 		}, | 		}, | ||||||
| 		show: false | 		show: false | ||||||
| 	}); | 	}); | ||||||
| @@ -175,7 +176,7 @@ app.on('ready', () => { | |||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	page.once('did-frame-finish-load', () => { | 	page.once('did-frame-finish-load', () => { | ||||||
| 		// Initate auto-updates on MacOS and Windows | 		// Initiate auto-updates on MacOS and Windows | ||||||
| 		if (ConfigUtil.getConfigItem('autoUpdate')) { | 		if (ConfigUtil.getConfigItem('autoUpdate')) { | ||||||
| 			appUpdater(); | 			appUpdater(); | ||||||
| 		} | 		} | ||||||
| @@ -195,6 +196,32 @@ app.on('ready', () => { | |||||||
| 		app.quit(); | 		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; | ||||||
|  |  | ||||||
|  | 		// 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); | ||||||
|  |  | ||||||
|  | 		// We don't want to have the menu bar in pdf window | ||||||
|  | 		pdfWindow.setMenu(null); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
| 	// Reload full app not just webview, useful in debugging | 	// Reload full app not just webview, useful in debugging | ||||||
| 	ipcMain.on('reload-full-app', () => { | 	ipcMain.on('reload-full-app', () => { | ||||||
| 		mainWindow.reload(); | 		mainWindow.reload(); | ||||||
| @@ -248,7 +275,7 @@ app.on('ready', () => { | |||||||
| 			item.setSavePath(filePath); | 			item.setSavePath(filePath); | ||||||
| 			item.on('updated', (event, state) => { | 			item.on('updated', (event, state) => { | ||||||
| 				switch (state) { | 				switch (state) { | ||||||
| 					case 'interrupted' : { | 					case 'interrupted': { | ||||||
| 						// Can interrupted to due to network error, cancel download then | 						// Can interrupted to due to network error, cancel download then | ||||||
| 						console.log('Download interrupted, cancelling and fallback to dialog download.'); | 						console.log('Download interrupted, cancelling and fallback to dialog download.'); | ||||||
| 						item.cancel(); | 						item.cancel(); | ||||||
| @@ -278,6 +305,10 @@ app.on('ready', () => { | |||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
|  | 	ipcMain.on('realm-icon-changed', (event, serverURL, iconURL) => { | ||||||
|  | 		page.send('update-realm-icon', serverURL, iconURL); | ||||||
|  | 	}); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| app.on('before-quit', () => { | app.on('before-quit', () => { | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ const { Notification } = require('electron'); | |||||||
| const request = require('request'); | const request = require('request'); | ||||||
| const semver = require('semver'); | const semver = require('semver'); | ||||||
| const ConfigUtil = require('../renderer/js/utils/config-util'); | const ConfigUtil = require('../renderer/js/utils/config-util'); | ||||||
|  | const ProxyUtil = require('../renderer/js/utils/proxy-util'); | ||||||
| const LinuxUpdateUtil = require('../renderer/js/utils/linux-update-util'); | const LinuxUpdateUtil = require('../renderer/js/utils/linux-update-util'); | ||||||
| const Logger = require('../renderer/js/utils/logger-util'); | const Logger = require('../renderer/js/utils/logger-util'); | ||||||
|  |  | ||||||
| @@ -15,10 +16,12 @@ const logger = new Logger({ | |||||||
| function linuxUpdateNotification() { | function linuxUpdateNotification() { | ||||||
| 	let	url = 'https://api.github.com/repos/zulip/zulip-electron/releases'; | 	let	url = 'https://api.github.com/repos/zulip/zulip-electron/releases'; | ||||||
| 	url = ConfigUtil.getConfigItem('betaUpdate') ? url : url + '/latest'; | 	url = ConfigUtil.getConfigItem('betaUpdate') ? url : url + '/latest'; | ||||||
|  | 	const proxyEnabled = ConfigUtil.getConfigItem('useManualProxy') || ConfigUtil.getConfigItem('useSystemProxy'); | ||||||
|  |  | ||||||
| 	const options = { | 	const options = { | ||||||
| 		url, | 		url, | ||||||
| 		headers: {'User-Agent': 'request'} | 		headers: {'User-Agent': 'request'}, | ||||||
|  | 		proxy: proxyEnabled ? ProxyUtil.getProxy(url) : '' | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	request(options, (error, response, body) => { | 	request(options, (error, response, body) => { | ||||||
|   | |||||||
							
								
								
									
										139
									
								
								app/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										139
									
								
								app/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "zulip", |   "name": "zulip", | ||||||
|   "version": "2.3.4-beta", |   "version": "2.3.6", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
| @@ -37,56 +37,91 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "@sentry/browser": { |     "@sentry/browser": { | ||||||
|       "version": "0.5.4", |       "version": "4.0.0-beta.12", | ||||||
|       "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-0.5.4.tgz", |       "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-4.0.0-beta.12.tgz", | ||||||
|       "integrity": "sha1-Yh/5chgrc7YoVlhLkvxl/elpBMw=", |       "integrity": "sha512-At8qp2aM4q4KnuIQuC6wbbQ6gLykmzwZdHwWRN99GS5TNC7kXJNgO9WgiMLadA4ph12JtC1petrUIgY8t+aoSA==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "@sentry/core": "0.5.4", |         "@sentry/core": "4.0.0-beta.12", | ||||||
|         "@sentry/shim": "0.5.4" |         "@sentry/hub": "4.0.0-beta.12", | ||||||
|  |         "@sentry/minimal": "4.0.0-beta.12", | ||||||
|  |         "@sentry/types": "4.0.0-beta.12", | ||||||
|  |         "@sentry/utils": "4.0.0-beta.12" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "@sentry/core": { |     "@sentry/core": { | ||||||
|       "version": "0.5.4", |       "version": "4.0.0-beta.12", | ||||||
|       "resolved": "https://registry.npmjs.org/@sentry/core/-/core-0.5.4.tgz", |       "resolved": "https://registry.npmjs.org/@sentry/core/-/core-4.0.0-beta.12.tgz", | ||||||
|       "integrity": "sha1-mwqEK0QhMbOAG65wviyk6cUQV04=", |       "integrity": "sha512-DGZqBOHejHPYP2I0MdF7APEaews7gLrfxHDh9rbwDLJJiuwPE/ridH97amxy/j2g4X4EZEc3sO3Ptv4nMaHK+Q==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "@sentry/shim": "0.5.4" |         "@sentry/hub": "4.0.0-beta.12", | ||||||
|  |         "@sentry/minimal": "4.0.0-beta.12", | ||||||
|  |         "@sentry/types": "4.0.0-beta.12", | ||||||
|  |         "@sentry/utils": "4.0.0-beta.12" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "@sentry/electron": { |     "@sentry/electron": { | ||||||
|       "version": "0.5.5", |       "version": "0.8.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@sentry/electron/-/electron-0.5.5.tgz", |       "resolved": "https://registry.npmjs.org/@sentry/electron/-/electron-0.8.1.tgz", | ||||||
|       "integrity": "sha1-kInWNC22xr1sCSpTdHcIAx1ft8M=", |       "integrity": "sha512-y3CJ7547Rhpg+6bnGP0mXLj9pgpjMLaRji704TdzTV0afr8KamBXySNhNHosHLaKm1OLg6p8U4pdVB7xQZ+X3g==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "@sentry/browser": "0.5.4", |         "@sentry/browser": "4.0.0-beta.12", | ||||||
|         "@sentry/core": "0.5.4", |         "@sentry/core": "4.0.0-beta.12", | ||||||
|         "@sentry/node": "0.5.4", |         "@sentry/hub": "4.0.0-beta.12", | ||||||
|         "@sentry/shim": "0.5.4", |         "@sentry/minimal": "4.0.0-beta.12", | ||||||
|         "@sentry/utils": "0.5.4", |         "@sentry/node": "4.0.0-beta.12", | ||||||
|  |         "@sentry/types": "4.0.0-beta.12", | ||||||
|  |         "@sentry/utils": "4.0.0-beta.12", | ||||||
|         "electron-fetch": "^1.1.0", |         "electron-fetch": "^1.1.0", | ||||||
|         "form-data": "^2.3.2", |         "form-data": "^2.3.2", | ||||||
|         "util.promisify": "^1.0.0" |         "util.promisify": "^1.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "@sentry/node": { |     "@sentry/hub": { | ||||||
|       "version": "0.5.4", |       "version": "4.0.0-beta.12", | ||||||
|       "resolved": "https://registry.npmjs.org/@sentry/node/-/node-0.5.4.tgz", |       "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-4.0.0-beta.12.tgz", | ||||||
|       "integrity": "sha1-s+c0nRs2EjmVkDbqrhnOvzVkw9M=", |       "integrity": "sha512-fmLaPaD6F/ViWDTz3hRVnNvqgnAmX0foDsUGVVp0Dt2lT9apM5NECKV6761XFVMrbGGulCg9fguv2KV5IbQcIw==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "@sentry/core": "0.5.4", |         "@sentry/types": "4.0.0-beta.12", | ||||||
|         "@sentry/shim": "0.5.4", |         "@sentry/utils": "4.0.0-beta.12" | ||||||
|         "raven": "^2.6.0" |  | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "@sentry/shim": { |     "@sentry/minimal": { | ||||||
|       "version": "0.5.4", |       "version": "4.0.0-beta.12", | ||||||
|       "resolved": "https://registry.npmjs.org/@sentry/shim/-/shim-0.5.4.tgz", |       "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-4.0.0-beta.12.tgz", | ||||||
|       "integrity": "sha1-y4JrGjR2WuXhsh5h3y3vL42pHcE=" |       "integrity": "sha512-1V3Lrm7wIOOqG+l1uyVZ7iQysPGXszwfsd6DTVDPT19PSey7+KbvPNcQfh+GqMRMz8jzyg9XlwUxckg7qbSztQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "@sentry/hub": "4.0.0-beta.12", | ||||||
|  |         "@sentry/types": "4.0.0-beta.12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "@sentry/node": { | ||||||
|  |       "version": "4.0.0-beta.12", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@sentry/node/-/node-4.0.0-beta.12.tgz", | ||||||
|  |       "integrity": "sha512-oekXtdaaElt/lSfyKtAyTLcTofciMRuptsGOTMX4qQ7hoHESB6DUw55Or/RRMaJYm/nckM2VFzWDATd20NVV4w==", | ||||||
|  |       "requires": { | ||||||
|  |         "@sentry/core": "4.0.0-beta.12", | ||||||
|  |         "@sentry/hub": "4.0.0-beta.12", | ||||||
|  |         "@sentry/minimal": "4.0.0-beta.12", | ||||||
|  |         "@sentry/types": "4.0.0-beta.12", | ||||||
|  |         "@sentry/utils": "4.0.0-beta.12", | ||||||
|  |         "cookie": "0.3.1", | ||||||
|  |         "lsmod": "1.0.0", | ||||||
|  |         "md5": "2.2.1", | ||||||
|  |         "stack-trace": "0.0.10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "@sentry/types": { | ||||||
|  |       "version": "4.0.0-beta.12", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@sentry/types/-/types-4.0.0-beta.12.tgz", | ||||||
|  |       "integrity": "sha512-xRsTfRcb8OvMbLjl64bPNv3feHiXBprtRZqTlVUbDJmSNrm8wg+tKIPYsP90dxKc50CZBk59urIbgvpPg0mCLw==" | ||||||
|     }, |     }, | ||||||
|     "@sentry/utils": { |     "@sentry/utils": { | ||||||
|       "version": "0.5.4", |       "version": "4.0.0-beta.12", | ||||||
|       "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-0.5.4.tgz", |       "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-4.0.0-beta.12.tgz", | ||||||
|       "integrity": "sha1-jt54rOlgIW3WMv1WHIP1AGLlruE=" |       "integrity": "sha512-lpTE2GlaztATlFfIWMN8RSQFP0z6PkPPoDz0KKRmK4ZxjPxVX2sAGbKJGCpf9fdUG23NVg3FNiqfpUbjhvd9YA==", | ||||||
|  |       "requires": { | ||||||
|  |         "@sentry/types": "4.0.0-beta.12" | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|     "@sindresorhus/is": { |     "@sindresorhus/is": { | ||||||
|       "version": "0.7.0", |       "version": "0.7.0", | ||||||
| @@ -437,9 +472,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "electron-fetch": { |     "electron-fetch": { | ||||||
|       "version": "1.1.0", |       "version": "1.2.1", | ||||||
|       "resolved": "https://registry.npmjs.org/electron-fetch/-/electron-fetch-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/electron-fetch/-/electron-fetch-1.2.1.tgz", | ||||||
|       "integrity": "sha512-eBtqbB522c/RJwC5v1yF/Y0SMVLiwel98BWGx050GucWbKlejHtPkfpq/vfMxCjg0SGpHGUISYUaMfu65QH+xg==", |       "integrity": "sha512-pQy0el/vxu30sL9JjXss8yZL+ztRnmioffPQsLL4UYnfSUFTuGBlgCPCxxKYJV7y52WfaIEZQ9tlbac1YHrH0w==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "encoding": "^0.1.12" |         "encoding": "^0.1.12" | ||||||
|       } |       } | ||||||
| @@ -538,9 +573,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "es-abstract": { |     "es-abstract": { | ||||||
|       "version": "1.12.0", |       "version": "1.11.0", | ||||||
|       "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", |       "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz", | ||||||
|       "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", |       "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "es-to-primitive": "^1.1.1", |         "es-to-primitive": "^1.1.1", | ||||||
|         "function-bind": "^1.1.1", |         "function-bind": "^1.1.1", | ||||||
| @@ -829,9 +864,9 @@ | |||||||
|       "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" |       "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" | ||||||
|     }, |     }, | ||||||
|     "is-callable": { |     "is-callable": { | ||||||
|       "version": "1.1.4", |       "version": "1.1.3", | ||||||
|       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", |       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", | ||||||
|       "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" |       "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" | ||||||
|     }, |     }, | ||||||
|     "is-date-object": { |     "is-date-object": { | ||||||
|       "version": "1.0.1", |       "version": "1.0.1", | ||||||
| @@ -1024,6 +1059,11 @@ | |||||||
|         "yallist": "^2.1.2" |         "yallist": "^2.1.2" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "lsmod": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz", | ||||||
|  |       "integrity": "sha1-mgD3bco26yP6BTUK/htYXUKZ5ks=" | ||||||
|  |     }, | ||||||
|     "md5": { |     "md5": { | ||||||
|       "version": "2.2.1", |       "version": "2.2.1", | ||||||
|       "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", |       "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", | ||||||
| @@ -1309,18 +1349,6 @@ | |||||||
|         "strict-uri-encode": "^1.0.0" |         "strict-uri-encode": "^1.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "raven": { |  | ||||||
|       "version": "2.6.3", |  | ||||||
|       "resolved": "https://registry.npmjs.org/raven/-/raven-2.6.3.tgz", |  | ||||||
|       "integrity": "sha512-bKre7qlDW+y1+G2bUtCuntdDYc8o5v1T233t0vmJfbj8ttGOgLrGRlYB8saelVMW9KUAJNLrhFkAKOwFWFJonw==", |  | ||||||
|       "requires": { |  | ||||||
|         "cookie": "0.3.1", |  | ||||||
|         "md5": "^2.2.1", |  | ||||||
|         "stack-trace": "0.0.10", |  | ||||||
|         "timed-out": "4.0.1", |  | ||||||
|         "uuid": "3.0.0" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "readable-stream": { |     "readable-stream": { | ||||||
|       "version": "2.3.6", |       "version": "2.3.6", | ||||||
|       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", |       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", | ||||||
| @@ -1600,11 +1628,6 @@ | |||||||
|         "object.getownpropertydescriptors": "^2.0.3" |         "object.getownpropertydescriptors": "^2.0.3" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "uuid": { |  | ||||||
|       "version": "3.0.0", |  | ||||||
|       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", |  | ||||||
|       "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" |  | ||||||
|     }, |  | ||||||
|     "verror": { |     "verror": { | ||||||
|       "version": "1.10.0", |       "version": "1.10.0", | ||||||
|       "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", |       "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| { | { | ||||||
|   "name": "zulip", |   "name": "zulip", | ||||||
|   "productName": "Zulip", |   "productName": "Zulip", | ||||||
|   "version": "2.3.4-beta", |   "version": "2.3.6", | ||||||
|   "description": "Zulip Desktop App", |   "description": "Zulip Desktop App", | ||||||
|   "license": "Apache-2.0", |   "license": "Apache-2.0", | ||||||
|   "copyright": "Kandra Labs, Inc.", |   "copyright": "Kandra Labs, Inc.", | ||||||
| @@ -27,7 +27,7 @@ | |||||||
|   ], |   ], | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@electron-elements/send-feedback": "1.0.7", |     "@electron-elements/send-feedback": "1.0.7", | ||||||
|     "@sentry/electron": "0.5.5", |     "@sentry/electron": "0.8.1", | ||||||
|     "adm-zip": "0.4.11", |     "adm-zip": "0.4.11", | ||||||
|     "auto-launch": "5.0.5", |     "auto-launch": "5.0.5", | ||||||
|     "electron-is-dev": "0.3.0", |     "electron-is-dev": "0.3.0", | ||||||
|   | |||||||
| @@ -388,8 +388,7 @@ i.open-tab-button { | |||||||
| .selected-css-path, | .selected-css-path, | ||||||
| .download-folder-path { | .download-folder-path { | ||||||
|     background: #eeeeee; |     background: #eeeeee; | ||||||
|     padding: 10px; |     padding: 5px 10px; | ||||||
|     margin-top: 10px; |  | ||||||
|     margin-right: 10px; |     margin-right: 10px; | ||||||
|     display: flex; |     display: flex; | ||||||
|     width: 90%; |     width: 90%; | ||||||
| @@ -565,7 +564,7 @@ input.toggle-round:checked+label:after { | |||||||
|  |  | ||||||
| .certificate-input { | .certificate-input { | ||||||
|      width:100%; |      width:100%; | ||||||
|      margin-top: 10px;  |      margin-top: 10px; | ||||||
|      display:inline-flex; |      display:inline-flex; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,24 +10,34 @@ function handleExternalLink(event) { | |||||||
| 	const { url } = event; | 	const { url } = event; | ||||||
| 	const domainPrefix = DomainUtil.getDomain(this.props.index).url; | 	const domainPrefix = DomainUtil.getDomain(this.props.index).url; | ||||||
| 	const downloadPath = ConfigUtil.getConfigItem('downloadsPath', `${app.getPath('downloads')}`); | 	const downloadPath = ConfigUtil.getConfigItem('downloadsPath', `${app.getPath('downloads')}`); | ||||||
|   // Whitelist URLs which are allowed to be opened in the app | 	const shouldShowInFolder = ConfigUtil.getConfigItem('showDownloadFolder', false); | ||||||
|  |  | ||||||
|  | 	// Whitelist URLs which are allowed to be opened in the app | ||||||
| 	const { | 	const { | ||||||
|     isInternalUrl: isWhiteListURL, | 		isInternalUrl: isWhiteListURL, | ||||||
|     isUploadsUrl: isUploadsURL | 		isUploadsUrl: isUploadsURL | ||||||
|   } = LinkUtil.isInternal(domainPrefix, url); | 	} = LinkUtil.isInternal(domainPrefix, url); | ||||||
|  |  | ||||||
| 	if (isWhiteListURL) { | 	if (isWhiteListURL) { | ||||||
| 		event.preventDefault(); | 		event.preventDefault(); | ||||||
|  |  | ||||||
|     // download txt, pdf, mp3, mp4 etc.. by using downloadURL in the | 		// Show pdf attachments in a new window | ||||||
|     // main process which allows the user to save the files to their desktop |  | ||||||
|     // and not trigger webview reload while image in webview will | 		if (LinkUtil.isPDF(url) && isUploadsURL) { | ||||||
|     // do nothing and will not save it | 			ipcRenderer.send('pdf-view', url); | ||||||
| 		if (!LinkUtil.isImage(url) && isUploadsURL) { | 			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) { | ||||||
| 			ipcRenderer.send('downloadFile', url, downloadPath); | 			ipcRenderer.send('downloadFile', url, downloadPath); | ||||||
| 			ipcRenderer.once('downloadFileCompleted', (event, filePath, fileName) => { | 			ipcRenderer.once('downloadFileCompleted', (event, filePath, fileName) => { | ||||||
| 				const downloadNotification = new Notification('Download Complete', { | 				const downloadNotification = new Notification('Download Complete', { | ||||||
| 					body: `Click to open ${fileName}`, | 					body: shouldShowInFolder ? `Click to show ${fileName} in folder` : `Click to open ${fileName}`, | ||||||
| 					silent: true // We'll play our own sound - ding.ogg | 					silent: true // We'll play our own sound - ding.ogg | ||||||
| 				}); | 				}); | ||||||
|  |  | ||||||
| @@ -37,7 +47,13 @@ function handleExternalLink(event) { | |||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				downloadNotification.onclick = () => { | 				downloadNotification.onclick = () => { | ||||||
| 					shell.openItem(filePath); | 					if (shouldShowInFolder) { | ||||||
|  | 						// Reveal file in download folder | ||||||
|  | 						shell.showItemInFolder(filePath); | ||||||
|  | 					} else { | ||||||
|  | 						// Open file in the default native app | ||||||
|  | 						shell.openItem(filePath); | ||||||
|  | 					} | ||||||
| 				}; | 				}; | ||||||
| 				ipcRenderer.removeAllListeners('downloadFileFailed'); | 				ipcRenderer.removeAllListeners('downloadFileFailed'); | ||||||
| 			}); | 			}); | ||||||
| @@ -51,7 +67,7 @@ function handleExternalLink(event) { | |||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|     // open internal urls inside the current webview. | 		// open internal urls inside the current webview. | ||||||
| 		this.$el.loadURL(url); | 		this.$el.loadURL(url); | ||||||
| 	} else { | 	} else { | ||||||
| 		event.preventDefault(); | 		event.preventDefault(); | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								app/renderer/js/electron-bridge.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/renderer/js/electron-bridge.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | const events = require('events'); | ||||||
|  | const { ipcRenderer } = require('electron'); | ||||||
|  |  | ||||||
|  | // we have and will have some non camelcase stuff | ||||||
|  | // while working with zulip so just turning the rule off | ||||||
|  | // for the whole file. | ||||||
|  | /* eslint-disable camelcase */ | ||||||
|  | class ElectronBridge extends events { | ||||||
|  | 	send_event(...args) { | ||||||
|  | 		this.emit(...args); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	on_event(...args) { | ||||||
|  | 		this.on(...args); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const electron_bridge = new ElectronBridge(); | ||||||
|  |  | ||||||
|  | electron_bridge.on('total_unread_count', (...args) => { | ||||||
|  | 	ipcRenderer.send('unread-count', ...args); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | electron_bridge.on('realm_name', (...args) => { | ||||||
|  | 	ipcRenderer.send('realm-name-changed', ...args); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | electron_bridge.on('realm_icon_url', iconURL => { | ||||||
|  | 	const serverURL = location.origin; | ||||||
|  | 	iconURL = iconURL.includes('http') ? iconURL : `${serverURL}${iconURL}`; | ||||||
|  | 	ipcRenderer.send('realm-icon-changed', serverURL, iconURL); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // this follows node's idiomatic implementation of event | ||||||
|  | // emitters to make event handling more simpler instead of using | ||||||
|  | // functions zulip side will emit event using ElectronBrigde.send_event | ||||||
|  | // which is alias of .emit and on this side we can handle the data by adding | ||||||
|  | // a listener for the event. | ||||||
|  | module.exports = electron_bridge; | ||||||
| @@ -14,9 +14,9 @@ const ConfigUtil = require(__dirname + '/js/utils/config-util.js'); | |||||||
| const DNDUtil = require(__dirname + '/js/utils/dnd-util.js'); | const DNDUtil = require(__dirname + '/js/utils/dnd-util.js'); | ||||||
| const ReconnectUtil = require(__dirname + '/js/utils/reconnect-util.js'); | const ReconnectUtil = require(__dirname + '/js/utils/reconnect-util.js'); | ||||||
| const Logger = require(__dirname + '/js/utils/logger-util.js'); | const Logger = require(__dirname + '/js/utils/logger-util.js'); | ||||||
| const { feedbackHolder } = require(__dirname + '/js/feedback.js'); | const CommonUtil = require(__dirname + '/js/utils/common-util.js'); | ||||||
|  |  | ||||||
| const escape = require('escape-html'); | const { feedbackHolder } = require(__dirname + '/js/feedback.js'); | ||||||
|  |  | ||||||
| const logger = new Logger({ | const logger = new Logger({ | ||||||
| 	file: 'errors.log', | 	file: 'errors.log', | ||||||
| @@ -117,7 +117,8 @@ class ServerManagerView { | |||||||
| 				showNotification: true, | 				showNotification: true, | ||||||
| 				silent: false | 				silent: false | ||||||
| 			}, | 			}, | ||||||
| 			downloadsPath: `${app.getPath('downloads')}` | 			downloadsPath: `${app.getPath('downloads')}`, | ||||||
|  | 			showDownloadFolder: false | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		// Platform specific settings | 		// Platform specific settings | ||||||
| @@ -178,7 +179,7 @@ class ServerManagerView { | |||||||
| 				index, | 				index, | ||||||
| 				tabIndex, | 				tabIndex, | ||||||
| 				url: server.url, | 				url: server.url, | ||||||
| 				name: server.alias, | 				name: CommonUtil.decodeString(server.alias), | ||||||
| 				isActive: () => { | 				isActive: () => { | ||||||
| 					return index === this.activeTabIndex; | 					return index === this.activeTabIndex; | ||||||
| 				}, | 				}, | ||||||
| @@ -252,7 +253,7 @@ class ServerManagerView { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	onHover(index, serverName) { | 	onHover(index, serverName) { | ||||||
| 		this.$serverIconTooltip[index].innerHTML = escape(serverName); | 		this.$serverIconTooltip[index].innerHTML = serverName; | ||||||
| 		this.$serverIconTooltip[index].removeAttribute('style'); | 		this.$serverIconTooltip[index].removeAttribute('style'); | ||||||
| 		// To handle position of servers' tooltip due to scrolling of list of organizations | 		// To handle position of servers' tooltip due to scrolling of list of organizations | ||||||
| 		// This could not be handled using CSS, hence the top of the tooltip is made same | 		// This could not be handled using CSS, hence the top of the tooltip is made same | ||||||
| @@ -396,6 +397,22 @@ class ServerManagerView { | |||||||
| 			const webContents = webview.getWebContents(); | 			const webContents = webview.getWebContents(); | ||||||
| 			webContents.send('toggle-dnd', state, newSettings); | 			webContents.send('toggle-dnd', state, newSettings); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
|  | 		ipcRenderer.on('update-realm-icon', (event, serverURL, iconURL) => { | ||||||
|  | 			DomainUtil.getDomains().forEach((domain, index) => { | ||||||
|  | 				if (domain.url.includes(serverURL)) { | ||||||
|  | 					DomainUtil.saveServerIcon(iconURL).then(localIconUrl => { | ||||||
|  | 						const serverImgsSelector = `.tab .server-icons`; | ||||||
|  | 						const serverImgs = document.querySelectorAll(serverImgsSelector); | ||||||
|  | 						serverImgs[index].src = localIconUrl; | ||||||
|  |  | ||||||
|  | 						domain.icon = localIconUrl; | ||||||
|  | 						DomainUtil.db.push(`/domains[${index}]`, domain, true); | ||||||
|  | 						DomainUtil.reloadDB(); | ||||||
|  | 					}); | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	destroyTab(name, index) { | 	destroyTab(name, index) { | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ const { | |||||||
|   remote: { app } |   remote: { app } | ||||||
| } = require('electron'); | } = require('electron'); | ||||||
|  |  | ||||||
|  | const params = require('../utils/params-util.js'); | ||||||
| const DefaultNotification = require('./default-notification'); | const DefaultNotification = require('./default-notification'); | ||||||
| const { appId, loadBots } = require('./helpers'); | const { appId, loadBots } = require('./helpers'); | ||||||
|  |  | ||||||
| @@ -19,9 +20,8 @@ if (process.platform === 'darwin') { | |||||||
| } | } | ||||||
|  |  | ||||||
| window.addEventListener('load', () => { | window.addEventListener('load', () => { | ||||||
| 	// Call this function only when user is logged in |  | ||||||
| 	// eslint-disable-next-line no-undef, camelcase | 	// eslint-disable-next-line no-undef, camelcase | ||||||
| 	if (page_params.realm_uri) { | 	if (params.isPageParams() && page_params.realm_uri) { | ||||||
| 		loadBots(); | 		loadBots(); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ class GeneralSection extends BaseSection { | |||||||
| 						<div class="setting-control"></div> | 						<div class="setting-control"></div> | ||||||
| 					</div> | 					</div> | ||||||
| 					<div class="setting-row" id="sidebar-option"> | 					<div class="setting-row" id="sidebar-option"> | ||||||
| 						<div class="setting-description">Show sidebar (<span class="code">Cmd Or Ctrl+S</span>)</div> | 						<div class="setting-description">Show sidebar (<span class="code">Cmd Or Ctrl+Shift+S</span>)</div> | ||||||
| 						<div class="setting-control"></div> | 						<div class="setting-control"></div> | ||||||
| 					</div> | 					</div> | ||||||
| 					<div class="setting-row" id="badge-option"> | 					<div class="setting-row" id="badge-option"> | ||||||
| @@ -97,6 +97,10 @@ class GeneralSection extends BaseSection { | |||||||
| 				</div> | 				</div> | ||||||
| 				<div class="title">Advanced</div> | 				<div class="title">Advanced</div> | ||||||
| 				<div class="settings-card"> | 				<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-control"></div> | ||||||
|  | 				</div> | ||||||
| 					<div class="setting-row" id="download-folder"> | 					<div class="setting-row" id="download-folder"> | ||||||
| 						<div class="setting-description"> | 						<div class="setting-description"> | ||||||
| 							Default download location | 							Default download location | ||||||
| @@ -108,6 +112,7 @@ class GeneralSection extends BaseSection { | |||||||
| 							<div class="download-folder-path">${ConfigUtil.getConfigItem('downloadsPath', `${app.getPath('downloads')}`)}</div> | 							<div class="download-folder-path">${ConfigUtil.getConfigItem('downloadsPath', `${app.getPath('downloads')}`)}</div> | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
|  |  | ||||||
| 				</div> | 				</div> | ||||||
| 				<div class="title">Reset Application Data</div> | 				<div class="title">Reset Application Data</div> | ||||||
|                 <div class="settings-card"> |                 <div class="settings-card"> | ||||||
| @@ -138,6 +143,7 @@ class GeneralSection extends BaseSection { | |||||||
| 		this.showCustomCSSPath(); | 		this.showCustomCSSPath(); | ||||||
| 		this.removeCustomCSS(); | 		this.removeCustomCSS(); | ||||||
| 		this.downloadFolder(); | 		this.downloadFolder(); | ||||||
|  | 		this.showDownloadFolder(); | ||||||
|  |  | ||||||
| 		// Platform specific settings | 		// Platform specific settings | ||||||
|  |  | ||||||
| @@ -385,6 +391,18 @@ class GeneralSection extends BaseSection { | |||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	showDownloadFolder() { | ||||||
|  | 		this.generateSettingOption({ | ||||||
|  | 			$element: document.querySelector('#show-download-folder .setting-control'), | ||||||
|  | 			value: ConfigUtil.getConfigItem('showDownloadFolder', false), | ||||||
|  | 			clickHandler: () => { | ||||||
|  | 				const newValue = !ConfigUtil.getConfigItem('showDownloadFolder'); | ||||||
|  | 				ConfigUtil.setConfigItem('showDownloadFolder', newValue); | ||||||
|  | 				this.showDownloadFolder(); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = GeneralSection; | module.exports = GeneralSection; | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ const SetupSpellChecker = require('./spellchecker'); | |||||||
|  |  | ||||||
| const ConfigUtil = require(__dirname + '/utils/config-util.js'); | const ConfigUtil = require(__dirname + '/utils/config-util.js'); | ||||||
| const LinkUtil = require(__dirname + '/utils/link-util.js'); | const LinkUtil = require(__dirname + '/utils/link-util.js'); | ||||||
|  | const params = require(__dirname + '/utils/params-util.js'); | ||||||
|  |  | ||||||
| // eslint-disable-next-line import/no-unassigned-import | // eslint-disable-next-line import/no-unassigned-import | ||||||
| require('./notification'); | require('./notification'); | ||||||
| @@ -12,6 +13,9 @@ require('./notification'); | |||||||
| // Prevent drag and drop event in main process which prevents remote code executaion | // Prevent drag and drop event in main process which prevents remote code executaion | ||||||
| require(__dirname + '/shared/preventdrag.js'); | require(__dirname + '/shared/preventdrag.js'); | ||||||
|  |  | ||||||
|  | // eslint-disable-next-line camelcase | ||||||
|  | window.electron_bridge = require('./electron-bridge'); | ||||||
|  |  | ||||||
| const logout = () => { | const logout = () => { | ||||||
| 	// Create the menu for the below | 	// Create the menu for the below | ||||||
| 	document.querySelector('.dropdown-toggle').click(); | 	document.querySelector('.dropdown-toggle').click(); | ||||||
| @@ -39,46 +43,44 @@ process.once('loaded', () => { | |||||||
|  |  | ||||||
| // To prevent failing this script on linux we need to load it after the document loaded | // To prevent failing this script on linux we need to load it after the document loaded | ||||||
| document.addEventListener('DOMContentLoaded', () => { | document.addEventListener('DOMContentLoaded', () => { | ||||||
|  | 	if (params.isPageParams()) { | ||||||
| 	// Get the default language of the server | 	// Get the default language of the server | ||||||
| 	const serverLanguage = page_params.default_language; // eslint-disable-line no-undef, camelcase | 		const serverLanguage = page_params.default_language; // eslint-disable-line no-undef, camelcase | ||||||
|  | 		if (serverLanguage) { | ||||||
|  | 			// Set spellcheker language | ||||||
|  | 			ConfigUtil.setConfigItem('spellcheckerLanguage', serverLanguage); | ||||||
|  | 			// Init spellchecker | ||||||
|  | 			SetupSpellChecker.init(); | ||||||
|  | 		} | ||||||
|  | 		// redirect users to network troubleshooting page | ||||||
|  | 		const getRestartButton = document.querySelector('.restart_get_events_button'); | ||||||
|  | 		if (getRestartButton) { | ||||||
|  | 			getRestartButton.addEventListener('click', () => { | ||||||
|  | 				ipcRenderer.send('forward-message', 'reload-viewer'); | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 		// Open image attachment link in the lightbox instead of opening in the default browser | ||||||
|  | 		const { $, lightbox } = window; | ||||||
|  | 		$('#main_div').on('click', '.message_content p a', function (e) { | ||||||
|  | 			const url = $(this).attr('href'); | ||||||
|  |  | ||||||
| 	if (serverLanguage) { | 			if (LinkUtil.isImage(url)) { | ||||||
| 		// Set spellcheker language | 				const $img = $(this).parent().siblings('.message_inline_image').find('img'); | ||||||
| 		ConfigUtil.setConfigItem('spellcheckerLanguage', serverLanguage); |  | ||||||
| 		// Init spellchecker |  | ||||||
| 		SetupSpellChecker.init(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// redirect users to network troubleshooting page | 				// prevent the image link from opening in a new page. | ||||||
| 	const getRestartButton = document.querySelector('.restart_get_events_button'); | 				e.preventDefault(); | ||||||
| 	if (getRestartButton) { | 				// prevent the message compose dialog from happening. | ||||||
| 		getRestartButton.addEventListener('click', () => { | 				e.stopPropagation(); | ||||||
| 			ipcRenderer.send('forward-message', 'reload-viewer'); |  | ||||||
|  | 				// Open image in the default browser if image preview is unavailable | ||||||
|  | 				if (!$img[0]) { | ||||||
|  | 					shell.openExternal(window.location.origin + url); | ||||||
|  | 				} | ||||||
|  | 				// Open image in lightbox | ||||||
|  | 				lightbox.open($img); | ||||||
|  | 			} | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Open image attachment link in the lightbox instead of opening in the default browser |  | ||||||
| 	const { $, lightbox } = window; |  | ||||||
|  |  | ||||||
| 	$('#main_div').on('click', '.message_content p a', function (e) { |  | ||||||
| 		const url = $(this).attr('href'); |  | ||||||
|  |  | ||||||
| 		if (LinkUtil.isImage(url)) { |  | ||||||
| 			const $img = $(this).parent().siblings('.message_inline_image').find('img'); |  | ||||||
|  |  | ||||||
| 			// prevent the image link from opening in a new page. |  | ||||||
| 			e.preventDefault(); |  | ||||||
| 			// prevent the message compose dialog from happening. |  | ||||||
| 			e.stopPropagation(); |  | ||||||
|  |  | ||||||
| 			// Open image in the default browser if image preview is unavailable |  | ||||||
| 			if (!$img[0]) { |  | ||||||
| 				shell.openExternal(window.location.origin + url); |  | ||||||
| 			} |  | ||||||
| 			// Open image in lightbox |  | ||||||
| 			lightbox.open($img); |  | ||||||
| 		} |  | ||||||
| 	}); |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // Clean up spellchecker events after you navigate away from this page; | // Clean up spellchecker events after you navigate away from this page; | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								app/renderer/js/utils/common-util.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/renderer/js/utils/common-util.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | 'use strict'; | ||||||
|  |  | ||||||
|  | let instance = null; | ||||||
|  |  | ||||||
|  | class CommonUtil { | ||||||
|  | 	constructor() { | ||||||
|  | 		if (instance) { | ||||||
|  | 			return instance; | ||||||
|  | 		} else { | ||||||
|  | 			instance = this; | ||||||
|  | 		} | ||||||
|  | 		return instance; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// unescape already encoded/escaped strings | ||||||
|  | 	decodeString(string) { | ||||||
|  | 		const parser = new DOMParser(); | ||||||
|  | 		const dom = parser.parseFromString( | ||||||
|  | 			'<!doctype html><body>' + string, | ||||||
|  | 			'text/html'); | ||||||
|  | 		return dom.body.textContent; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = new CommonUtil(); | ||||||
| @@ -10,6 +10,8 @@ const escape = require('escape-html'); | |||||||
| const Logger = require('./logger-util'); | const Logger = require('./logger-util'); | ||||||
|  |  | ||||||
| const CertificateUtil = require(__dirname + '/certificate-util.js'); | const CertificateUtil = require(__dirname + '/certificate-util.js'); | ||||||
|  | const ProxyUtil = require(__dirname + '/proxy-util.js'); | ||||||
|  | const ConfigUtil = require(__dirname + '/config-util.js'); | ||||||
|  |  | ||||||
| const logger = new Logger({ | const logger = new Logger({ | ||||||
| 	file: `domain-util.log`, | 	file: `domain-util.log`, | ||||||
| @@ -119,8 +121,16 @@ class DomainUtil { | |||||||
| 				logger.warn('Error while trying to get certificate: ' + 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 | 		// 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 | ||||||
| 		const checkDomain = (certificateLocation) ? ({url: domain + '/static/audio/zulip.ogg', ca: certificateLocation}) : domain + '/static/audio/zulip.ogg'; | 		// 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) : '' | ||||||
|  | 		}; | ||||||
|  |  | ||||||
| 		const serverConf = { | 		const serverConf = { | ||||||
| 			icon: defaultIconUrl, | 			icon: defaultIconUrl, | ||||||
| @@ -193,9 +203,13 @@ class DomainUtil { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	getServerSettings(domain) { | 	getServerSettings(domain) { | ||||||
| 		const serverSettingsUrl = domain + '/api/v1/server_settings'; | 		const proxyEnabled = ConfigUtil.getConfigItem('useManualProxy') || ConfigUtil.getConfigItem('useSystemProxy'); | ||||||
|  | 		const serverSettingsOptions = { | ||||||
|  | 			url: domain + '/api/v1/server_settings', | ||||||
|  | 			proxy: proxyEnabled ? ProxyUtil.getProxy(domain) : '' | ||||||
|  | 		}; | ||||||
| 		return new Promise((resolve, reject) => { | 		return new Promise((resolve, reject) => { | ||||||
| 			request(serverSettingsUrl, (error, response) => { | 			request(serverSettingsOptions, (error, response) => { | ||||||
| 				if (!error && response.statusCode === 200) { | 				if (!error && response.statusCode === 200) { | ||||||
| 					const data = JSON.parse(response.body); | 					const data = JSON.parse(response.body); | ||||||
| 					if (data.hasOwnProperty('realm_icon') && data.realm_icon) { | 					if (data.hasOwnProperty('realm_icon') && data.realm_icon) { | ||||||
| @@ -215,12 +229,17 @@ class DomainUtil { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	saveServerIcon(url) { | 	saveServerIcon(url) { | ||||||
|  | 		const proxyEnabled = ConfigUtil.getConfigItem('useManualProxy') || ConfigUtil.getConfigItem('useSystemProxy'); | ||||||
|  | 		const serverIconOptions = { | ||||||
|  | 			url, | ||||||
|  | 			proxy: proxyEnabled ? ProxyUtil.getProxy(url) : '' | ||||||
|  | 		}; | ||||||
| 		// The save will always succeed. If url is invalid, downgrade to default icon. | 		// The save will always succeed. If url is invalid, downgrade to default icon. | ||||||
| 		return new Promise(resolve => { | 		return new Promise(resolve => { | ||||||
| 			const filePath = this.generateFilePath(url); | 			const filePath = this.generateFilePath(url); | ||||||
| 			const file = fs.createWriteStream(filePath); | 			const file = fs.createWriteStream(filePath); | ||||||
| 			try { | 			try { | ||||||
| 				request(url).on('response', response => { | 				request(serverIconOptions).on('response', response => { | ||||||
| 					response.on('error', err => { | 					response.on('error', err => { | ||||||
| 						logger.log('Could not get server icon.'); | 						logger.log('Could not get server icon.'); | ||||||
| 						logger.log(err); | 						logger.log(err); | ||||||
|   | |||||||
| @@ -34,6 +34,12 @@ class LinkUtil { | |||||||
| 		const isImageUrl = /\.(bmp|gif|jpg|jpeg|png|webp)\?*.*$/i; | 		const isImageUrl = /\.(bmp|gif|jpg|jpeg|png|webp)\?*.*$/i; | ||||||
| 		return isImageUrl.test(url); | 		return isImageUrl.test(url); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	isPDF(url) { | ||||||
|  | 		// test for pdf extension | ||||||
|  | 		const isPDFUrl = /\.(pdf)\?*.*$/i; | ||||||
|  | 		return isPDFUrl.test(url); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = new LinkUtil(); | module.exports = new LinkUtil(); | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								app/renderer/js/utils/params-util.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/renderer/js/utils/params-util.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | // This util function returns the page params if they're present else returns null | ||||||
|  | function isPageParams() { | ||||||
|  | 	let webpageParams = null; | ||||||
|  | 	try { | ||||||
|  | 		// eslint-disable-next-line no-undef, camelcase | ||||||
|  | 		webpageParams = page_params; | ||||||
|  | 	} catch (err) { | ||||||
|  | 		webpageParams = null; | ||||||
|  | 	} | ||||||
|  | 	return webpageParams; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  | 	isPageParams | ||||||
|  | }; | ||||||
| @@ -1,5 +1,6 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
|  | const url = require('url'); | ||||||
| const ConfigUtil = require('./config-util.js'); | const ConfigUtil = require('./config-util.js'); | ||||||
|  |  | ||||||
| let instance = null; | let instance = null; | ||||||
| @@ -15,6 +16,39 @@ class ProxyUtil { | |||||||
| 		return instance; | 		return instance; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// Return proxy to be used for a particular uri, to be used for request | ||||||
|  | 	getProxy(uri) { | ||||||
|  | 		uri = url.parse(uri); | ||||||
|  | 		const proxyRules = ConfigUtil.getConfigItem('proxyRules', '').split(';'); | ||||||
|  | 		// If SPS is on and system uses no proxy then request should not try to use proxy from | ||||||
|  | 		// environment. NO_PROXY = '*' makes request ignore all environment proxy variables. | ||||||
|  | 		if (proxyRules[0] === '') { | ||||||
|  | 			process.env.NO_PROXY = '*'; | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		const proxyRule = {}; | ||||||
|  | 		if (uri.protocol === 'http:') { | ||||||
|  | 			proxyRules.forEach(proxy => { | ||||||
|  | 				if (proxy.includes('http=')) { | ||||||
|  | 					proxyRule.hostname = proxy.split('http=')[1].trim().split(':')[0]; | ||||||
|  | 					proxyRule.port = proxy.split('http=')[1].trim().split(':')[1]; | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 			return proxyRule; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (uri.protocol === 'https:') { | ||||||
|  | 			proxyRules.forEach(proxy => { | ||||||
|  | 				if (proxy.includes('https=')) { | ||||||
|  | 					proxyRule.hostname = proxy.split('https=')[1].trim().split(':')[0]; | ||||||
|  | 					proxyRule.port = proxy.split('https=')[1].trim().split(':')[1]; | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 			return proxyRule; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	resolveSystemProxy(mainWindow) { | 	resolveSystemProxy(mainWindow) { | ||||||
| 		const page = mainWindow.webContents; | 		const page = mainWindow.webContents; | ||||||
| 		const ses = page.session; | 		const ses = page.session; | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -4,6 +4,40 @@ | |||||||
|  |  | ||||||
| All notable changes to the Zulip desktop app are documented in this file. | All notable changes to the Zulip desktop app are documented in this file. | ||||||
|  |  | ||||||
|  | ### v2.3.6 --2018-08-27 | ||||||
|  |  | ||||||
|  | **New features**: | ||||||
|  | * Add proxy details while validating a server. This fixes the server validating issue for users who are using the proxy settings.  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | **Fixes**: | ||||||
|  |  | ||||||
|  | * Fix youtube video not playing in lightbox.  | ||||||
|  | * Fix realm name not escaped properly. | ||||||
|  |  | ||||||
|  | <hr> | ||||||
|  |  | ||||||
|  | ### v2.3.5 --2018-08-03 | ||||||
|  |  | ||||||
|  | **New features**: | ||||||
|  | * Add a setting option to show downloaded file in file manager. | ||||||
|  | * Added electron bridge to communicate with webapp in real time. | ||||||
|  |  | ||||||
|  | **Fixes**: | ||||||
|  |  | ||||||
|  | * Fix failing attached file downloads. | ||||||
|  | * Fix page_params error. | ||||||
|  | * gulpfile: Update syntax and methods for gulp v4.x. | ||||||
|  |  | ||||||
|  | <hr> | ||||||
|  |  | ||||||
|  | ### v2.3.4-beta --2018-07-24 | ||||||
|  |  | ||||||
|  | **Fixes**: | ||||||
|  | * Fix downloading functionality of file attachments. | ||||||
|  | * Fix null of downloadPath when settings.json fails. | ||||||
|  |  | ||||||
|  | <hr> | ||||||
|  |  | ||||||
| ### v2.3.3 --2018-07-14 | ### v2.3.3 --2018-07-14 | ||||||
|  |  | ||||||
| @@ -27,6 +61,7 @@ electron-builder: v20.20.4 | |||||||
|  |  | ||||||
| electron-updater: v2.23.3 | electron-updater: v2.23.3 | ||||||
|  |  | ||||||
|  | <hr> | ||||||
|  |  | ||||||
| ### v2.3.2 --2018-05-28 | ### v2.3.2 --2018-05-28 | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								gulpfile.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								gulpfile.js
									
									
									
									
									
								
							| @@ -10,11 +10,11 @@ gulp.task('dev', () => { | |||||||
|   // Start browser process |   // Start browser process | ||||||
| 	electron.start(); | 	electron.start(); | ||||||
|   // Restart browser process |   // Restart browser process | ||||||
| 	gulp.watch('app/main/*.js', ['restart:browser']); | 	gulp.watch('app/main/*.js', gulp.series('restart:browser')); | ||||||
|   // Reload renderer process |   // Reload renderer process | ||||||
| 	gulp.watch('app/renderer/css/*.css', ['reload:renderer']); | 	gulp.watch('app/renderer/css/*.css', gulp.series('reload:renderer')); | ||||||
| 	gulp.watch('app/renderer/*.html', ['reload:renderer']); | 	gulp.watch('app/renderer/*.html', gulp.series('reload:renderer')); | ||||||
| 	gulp.watch('app/renderer/js/**/*.js', ['reload:renderer']); | 	gulp.watch('app/renderer/js/**/*.js', gulp.series('reload:renderer')); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| gulp.task('restart:browser', done => { | gulp.task('restart:browser', done => { | ||||||
| @@ -36,4 +36,4 @@ gulp.task('test-e2e', () => { | |||||||
| 	})); | 	})); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| gulp.task('default', ['dev', 'test-e2e']); | gulp.task('default', gulp.parallel('dev', 'test-e2e')); | ||||||
|   | |||||||
							
								
								
									
										105
									
								
								help.md
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								help.md
									
									
									
									
									
								
							| @@ -1,105 +0,0 @@ | |||||||
| # User Guide |  | ||||||
|  |  | ||||||
| > Welcome! This guide will walk you through the basics of using Zulip Desktop. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Get Zulip Desktop |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Connect to a Server |  | ||||||
|  |  | ||||||
| ### Connect through a proxy |  | ||||||
|  |  | ||||||
| It's possible to connect to your server through a proxy.  |  | ||||||
| You can enter the proxy settings in the `Network` section of App Settings.  |  | ||||||
| There are three fields provided: |  | ||||||
| * `PAC script` - The URL associated with the PAC file. |  | ||||||
| * `Proxy rules` - Rules indicating which proxies to use. |  | ||||||
| * `Proxy bypass rules` - Rules indicating which URLs should |  | ||||||
|     bypass the proxy settings. |  | ||||||
| 	 |  | ||||||
| For a typical setup where internet access is required to use an HTTP proxy, |  | ||||||
| but URLs on the local network should be accessed directly, configure as follows: |  | ||||||
|  |  | ||||||
| `Proxy rules = proxy.example.com` |  | ||||||
|  |  | ||||||
| Your HTTP proxy server |  | ||||||
| `Proxy bypass rules = *.example.com;10.0.0.0/8` |  | ||||||
|  |  | ||||||
| Directly connect to your own domain and private IP subnet |  | ||||||
| for more complex setups, read below to configure complex proxy rules and proxy bypass rules. |  | ||||||
|  |  | ||||||
| ### Sets the proxy settings. |  | ||||||
|  |  | ||||||
| When `PAC script` and `Proxy rules` are provided together, the `Proxy rules` |  | ||||||
| option is ignored and `PAC script` configuration is applied. |  | ||||||
|  |  | ||||||
| The `Proxy rules` has to follow the rules below: |  | ||||||
|  |  | ||||||
| ``` |  | ||||||
| proxyRules = schemeProxies[";"<schemeProxies>] |  | ||||||
| schemeProxies = [<urlScheme>"="]<proxyURIList> |  | ||||||
| urlScheme = "http" | "https" | "ftp" | "socks" |  | ||||||
| proxyURIList = <proxyURL>[","<proxyURIList>] |  | ||||||
| proxyURL = [<proxyScheme>"://"]<proxyHost>[":"<proxyPort>] |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| For example: |  | ||||||
|  |  | ||||||
| * `http=foopy:80;ftp=foopy2` - Use HTTP proxy `foopy:80` for `http://` URLs, and |  | ||||||
|   HTTP proxy `foopy2:80` for `ftp://` URLs. |  | ||||||
| * `foopy:80` - Use HTTP proxy `foopy:80` for all URLs. |  | ||||||
| * `foopy:80,bar,direct://` - Use HTTP proxy `foopy:80` for all URLs, failing |  | ||||||
|   over to `bar` if `foopy:80` is unavailable, and after that using no proxy. |  | ||||||
| * `socks4://foopy` - Use SOCKS v4 proxy `foopy:1080` for all URLs. |  | ||||||
| * `http=foopy,socks5://bar.com` - Use HTTP proxy `foopy` for http URLs, and fail |  | ||||||
|   over to the SOCKS5 proxy `bar.com` if `foopy` is unavailable. |  | ||||||
| * `http=foopy,direct://` - Use HTTP proxy `foopy` for http URLs, and use no |  | ||||||
|   proxy if `foopy` is unavailable. |  | ||||||
| * `http=foopy;socks=foopy2` -  Use HTTP proxy `foopy` for http URLs, and use |  | ||||||
|   `socks4://foopy2` for all other URLs. |  | ||||||
|  |  | ||||||
| The `Proxy bypass rules` is a comma separated list of rules described below: |  | ||||||
|  |  | ||||||
| * `[ URL_SCHEME "://" ] HOSTNAME_PATTERN [ ":" <port> ]` |  | ||||||
|  |  | ||||||
|    Match all hostnames that match the pattern HOSTNAME_PATTERN. |  | ||||||
|  |  | ||||||
|    Examples: |  | ||||||
|      "foobar.com", "*foobar.com", "*.foobar.com", "*foobar.com:99", |  | ||||||
|      "https://x.*.y.com:99" |  | ||||||
|  |  | ||||||
|  * `"." HOSTNAME_SUFFIX_PATTERN [ ":" PORT ]` |  | ||||||
|  |  | ||||||
|    Match a particular domain suffix. |  | ||||||
|  |  | ||||||
|    Examples: |  | ||||||
|      ".google.com", ".com", "http://.google.com" |  | ||||||
|  |  | ||||||
| * `[ SCHEME "://" ] IP_LITERAL [ ":" PORT ]` |  | ||||||
|  |  | ||||||
|    Match URLs which are IP address literals. |  | ||||||
|  |  | ||||||
|    Examples: |  | ||||||
|      "127.0.1", "[0:0::1]", "[::1]", "http://[::1]:99" |  | ||||||
|  |  | ||||||
| *  `IP_LITERAL "/" PREFIX_LENGHT_IN_BITS` |  | ||||||
|  |  | ||||||
|    Match any URL that is to an IP literal that falls between the |  | ||||||
|    given range. IP range is specified using CIDR notation. |  | ||||||
|  |  | ||||||
|    Examples: |  | ||||||
|      "192.168.1.1/16", "fefe:13::abc/33". |  | ||||||
|  |  | ||||||
| *  `<local>` |  | ||||||
|  |  | ||||||
|    Match local addresses. The meaning of `<local>` is whether the |  | ||||||
|    host matches one of: "127.0.0.1", "::1", "localhost". |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Change App Preferences |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Reporting an Issue |  | ||||||
							
								
								
									
										14
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										14
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "zulip", |   "name": "zulip", | ||||||
|   "version": "2.3.4-beta", |   "version": "2.3.6", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
| @@ -11,9 +11,9 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "@types/node": { |     "@types/node": { | ||||||
|       "version": "8.10.21", |       "version": "8.10.26", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.21.tgz", |       "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.26.tgz", | ||||||
|       "integrity": "sha512-87XkD9qDXm8fIax+5y7drx84cXsu34ZZqfB7Cial3Q/2lxSoJ/+DRaWckkCbxP41wFSIrrb939VhzaNxj4eY1w==", |       "integrity": "sha512-opk6bLLErLSwyVVJeSH5Ek7ZWOBSsN0JrvXTNVGLXLAXKB9xlTYajrplR44xVyMrmbut94H6uJ9jqzM/12jxkA==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "abbrev": { |     "abbrev": { | ||||||
| @@ -2091,9 +2091,9 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "electron": { |     "electron": { | ||||||
|       "version": "2.0.1", |       "version": "2.0.8", | ||||||
|       "resolved": "https://registry.npmjs.org/electron/-/electron-2.0.1.tgz", |       "resolved": "https://registry.npmjs.org/electron/-/electron-2.0.8.tgz", | ||||||
|       "integrity": "sha512-piSwY2P7L6NWx672MNdSvtGPdQP/mhwAg8ICN6ofTTItPkd7D6kNHBPkq+DXwZcXVH1EifYR9yD/l3Xw1haVpQ==", |       "integrity": "sha512-pbeGFbwijb5V3Xy/KMcwIp59eA9igg2br+7EHbbwQoa3HRDF5JjTrciX7OiscCA52+ze2n4q38S4lXPqRitgIA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "@types/node": "^8.0.24", |         "@types/node": "^8.0.24", | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| { | { | ||||||
|   "name": "zulip", |   "name": "zulip", | ||||||
|   "productName": "Zulip", |   "productName": "Zulip", | ||||||
|   "version": "2.3.4-beta", |   "version": "2.3.6", | ||||||
|   "main": "./app/main", |   "main": "./app/main", | ||||||
|   "description": "Zulip Desktop App", |   "description": "Zulip Desktop App", | ||||||
|   "license": "Apache-2.0", |   "license": "Apache-2.0", | ||||||
| @@ -123,7 +123,7 @@ | |||||||
|     "assert": "1.4.1", |     "assert": "1.4.1", | ||||||
|     "cp-file": "^5.0.0", |     "cp-file": "^5.0.0", | ||||||
|     "devtron": "1.4.0", |     "devtron": "1.4.0", | ||||||
|     "electron": "2.0.1", |     "electron": "2.0.8", | ||||||
|     "electron-builder": "20.20.4", |     "electron-builder": "20.20.4", | ||||||
|     "electron-connect": "0.6.2", |     "electron-connect": "0.6.2", | ||||||
|     "electron-debug": "1.4.0", |     "electron-debug": "1.4.0", | ||||||
|   | |||||||
							
								
								
									
										185
									
								
								tests/e2e/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								tests/e2e/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,185 @@ | |||||||
|  | { | ||||||
|  |  "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" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |      "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 | ||||||
|  |       } | ||||||
|  |      ], | ||||||
|  |      "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/e2e/*.js", | ||||||
|  |    "tools/locale-helper/*.js" | ||||||
|  |   ], | ||||||
|  |   "envs": [ | ||||||
|  |    "node", | ||||||
|  |    "browser", | ||||||
|  |    "mocha" | ||||||
|  |   ] | ||||||
|  |  } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user