Compare commits

...

12 Commits

Author SHA1 Message Date
Akash Nimare
cf1f659ebf release: New beta release v5.4.1-beta. 2020-07-29 13:40:59 +05:30
Akash Nimare
eb381a87bc electron-builder: Update builder to latest version. 2020-07-29 01:54:48 +05:30
Manav Mehta
68bc0ae4a0 readme: Add new screenshot URLs.
Update the screenshots to accomodate new Zulip logo and both the day and night modes
2020-07-29 01:31:57 +05:30
Manav Mehta
178bc7f401 macos: Update dock icon.
The icon in macOS was stretched to the boundaries making it larger than the other icons.
A padding of 30px on all sides makes it coherent with the others.

Fixes: #1003.
2020-07-27 01:12:27 +05:30
Anders Kaseorg
0f1245b975 Upgrade dependencies, including Electron 9.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-24 01:37:41 -07:00
Anders Kaseorg
960312a932 notification: Move loadBots call to preload, to break an import cycle.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-24 01:37:07 -07:00
Anders Kaseorg
0e00f3bbce Commit package-lock.json update missed in v5.4.0 release.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-24 00:50:45 -07:00
Anders Kaseorg
ec205f68a6 Send only needed data from tabs over IPC.
Fixes exceptions from the structured clone algorithm raised by
Electron 9.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-24 00:39:38 -07:00
Anders Kaseorg
5fe5989710 xo: Enable import/newline-after-import.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-23 23:18:25 -07:00
Anders Kaseorg
69141b5395 Remove spurious 'use-strict' [sic] directives.
The directive is 'use strict'.  It’s not necessary in TypeScript.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-23 23:09:12 -07:00
Anders Kaseorg
8d66f05924 xo: Sort imports with import/order.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-07-23 23:06:41 -07:00
Manav Mehta
e7330dbff8 Update changelog for v5.4.0 and the license year to 2020 (#1000)
Co-authored-by: Akash Nimare <akashnimare@users.noreply.github.com>
2020-07-21 22:05:04 +05:30
52 changed files with 1513 additions and 2200 deletions

View File

@@ -6,7 +6,8 @@
Desktop client for Zulip. Available for Mac, Linux, and Windows.
<img src="http://i.imgur.com/ChzTq4F.png"/>
<img src="https://i.imgur.com/s1o6TRA.png"/>
<img src="https://i.imgur.com/vekKnW4.png"/>
# Download
Please see the [installation guide](https://zulip.com/help/desktop-app-install-guide).

View File

@@ -1,13 +1,15 @@
import {app, dialog, session} from 'electron';
import {UpdateDownloadedEvent, UpdateInfo, autoUpdater} from 'electron-updater';
import util from 'util';
import {linuxUpdateNotification} from './linuxupdater'; // Required only in case of linux
import log from 'electron-log';
import isDev from 'electron-is-dev';
import log from 'electron-log';
import {UpdateDownloadedEvent, UpdateInfo, autoUpdater} from 'electron-updater';
import * as ConfigUtil from '../renderer/js/utils/config-util';
import * as LinkUtil from '../renderer/js/utils/link-util';
import {linuxUpdateNotification} from './linuxupdater'; // Required only in case of linux
const sleep = util.promisify(setTimeout);
export async function appUpdater(updateFromMenu = false): Promise<void> {

View File

@@ -1,18 +1,20 @@
import {sentryInit} from '../renderer/js/utils/sentry-util';
import {appUpdater} from './autoupdater';
import {setAutoLaunch} from './startup';
import electron, {app, dialog, ipcMain, session} from 'electron';
import fs from 'fs';
import path from 'path';
import windowStateKeeper from 'electron-window-state';
import path from 'path';
import fs from 'fs';
import electron, {app, dialog, ipcMain, session} from 'electron';
import * as AppMenu from './menu';
import * as BadgeSettings from '../renderer/js/pages/preference/badge-settings';
import * as CertificateUtil from '../renderer/js/utils/certificate-util';
import * as ConfigUtil from '../renderer/js/utils/config-util';
import * as ProxyUtil from '../renderer/js/utils/proxy-util';
import {sentryInit} from '../renderer/js/utils/sentry-util';
import {appUpdater} from './autoupdater';
import * as AppMenu from './menu';
import {_getServerSettings, _saveServerIcon, _isOnline} from './request';
import {setAutoLaunch} from './startup';
let mainWindowState: windowStateKeeper.State;
@@ -353,7 +355,7 @@ ${error}`
AppMenu.setMenu(props);
const activeTab = props.tabs[props.activeTabIndex];
if (activeTab) {
mainWindow.setTitle(`Zulip - ${activeTab.webview.props.name}`);
mainWindow.setTitle(`Zulip - ${activeTab.webviewName}`);
}
});

View File

@@ -2,9 +2,11 @@ import {app, Notification, net} from 'electron';
import getStream from 'get-stream';
import semver from 'semver';
import * as ConfigUtil from '../renderer/js/utils/config-util';
import * as LinuxUpdateUtil from '../renderer/js/utils/linux-update-util';
import Logger from '../renderer/js/utils/logger-util';
import {fetchResponse} from './request';
const logger = new Logger({

View File

@@ -1,15 +1,17 @@
import {app, shell, BrowserWindow, Menu} from 'electron';
import {appUpdater} from './autoupdater';
import AdmZip from 'adm-zip';
import * as DNDUtil from '../renderer/js/utils/dnd-util';
import type {TabData} from '../renderer/js/main';
import * as ConfigUtil from '../renderer/js/utils/config-util';
import * as DNDUtil from '../renderer/js/utils/dnd-util';
import * as LinkUtil from '../renderer/js/utils/link-util';
import * as t from '../renderer/js/utils/translation-util';
import type {ServerOrFunctionalTab} from '../renderer/js/main';
import {appUpdater} from './autoupdater';
export interface MenuProps {
tabs: ServerOrFunctionalTab[];
tabs: TabData[];
activeTabIndex?: number;
enableMenu?: boolean;
}
@@ -213,7 +215,7 @@ function getHelpSubmenu(): Electron.MenuItemConstructorOptions[] {
];
}
function getWindowSubmenu(tabs: ServerOrFunctionalTab[], activeTabIndex: number): Electron.MenuItemConstructorOptions[] {
function getWindowSubmenu(tabs: TabData[], activeTabIndex: number): Electron.MenuItemConstructorOptions[] {
const initialSubmenu: Electron.MenuItemConstructorOptions[] = [{
label: t.__('Minimize'),
role: 'minimize'
@@ -229,17 +231,17 @@ function getWindowSubmenu(tabs: ServerOrFunctionalTab[], activeTabIndex: number)
});
tabs.forEach(tab => {
// Do not add functional tab settings to list of windows in menu bar
if (tab.props.role === 'function' && tab.props.name === 'Settings') {
if (tab.role === 'function' && tab.name === 'Settings') {
return;
}
initialSubmenu.push({
label: tab.props.name,
accelerator: tab.props.role === 'function' ? '' : `${ShortcutKey} + ${tab.props.index + 1}`,
checked: tab.props.index === activeTabIndex,
label: tab.name,
accelerator: tab.role === 'function' ? '' : `${ShortcutKey} + ${tab.index + 1}`,
checked: tab.index === activeTabIndex,
click(_item, focusedWindow) {
if (focusedWindow) {
sendAction('switch-server-tab', tab.props.index);
sendAction('switch-server-tab', tab.index);
}
},
type: 'checkbox'
@@ -545,20 +547,20 @@ async function checkForUpdate(): Promise<void> {
await appUpdater(true);
}
function getNextServer(tabs: ServerOrFunctionalTab[], activeTabIndex: number): number {
function getNextServer(tabs: TabData[], activeTabIndex: number): number {
do {
activeTabIndex = (activeTabIndex + 1) % tabs.length;
}
while (tabs[activeTabIndex].props.role !== 'server');
while (tabs[activeTabIndex].role !== 'server');
return activeTabIndex;
}
function getPreviousServer(tabs: ServerOrFunctionalTab[], activeTabIndex: number): number {
function getPreviousServer(tabs: TabData[], activeTabIndex: number): number {
do {
activeTabIndex = (activeTabIndex - 1 + tabs.length) % tabs.length;
}
while (tabs[activeTabIndex].props.role !== 'server');
while (tabs[activeTabIndex].role !== 'server');
return activeTabIndex;
}

View File

@@ -3,12 +3,14 @@ import fs from 'fs';
import path from 'path';
import stream from 'stream';
import util from 'util';
import * as Messages from '../resources/messages';
import Logger from '../renderer/js/utils/logger-util';
import {ServerConf} from '../renderer/js/utils/domain-util';
import escape from 'escape-html';
import getStream from 'get-stream';
import {ServerConf} from '../renderer/js/utils/domain-util';
import Logger from '../renderer/js/utils/logger-util';
import * as Messages from '../resources/messages';
export async function fetchResponse(request: ClientRequest): Promise<IncomingMessage> {
return new Promise((resolve, reject) => {
request.on('response', resolve);

View File

@@ -2,6 +2,7 @@ import {app} from 'electron';
import AutoLaunch from 'auto-launch';
import isDev from 'electron-is-dev';
import * as ConfigUtil from '../renderer/js/utils/config-util';
export const setAutoLaunch = async (AutoLaunchValue: boolean): Promise<void> => {

View File

@@ -1,5 +1,5 @@
import {clipboard} from 'electron';
import crypto from 'crypto';
import {clipboard} from 'electron';
// This helper is exposed via electron_bridge for use in the social
// login flow.

View File

@@ -1,5 +1,7 @@
import {remote, ContextMenuParams} from 'electron';
import * as t from '../utils/translation-util';
const {clipboard, Menu} = remote;
export const contextMenu = (webContents: Electron.WebContents, event: Event, props: ContextMenuParams) => {

View File

@@ -1,7 +1,8 @@
import {ipcRenderer, remote} from 'electron';
import * as LinkUtil from '../utils/link-util';
import * as ConfigUtil from '../utils/config-util';
import * as LinkUtil from '../utils/link-util';
import type WebView from './webview';
const {shell, app} = remote;

View File

@@ -1,8 +1,9 @@
import {ipcRenderer} from 'electron';
import Tab, {TabProps} from './tab';
import * as SystemUtil from '../utils/system-util';
import Tab, {TabProps} from './tab';
export default class ServerTab extends Tab {
$badge: Element;

View File

@@ -1,5 +1,5 @@
import WebView from './webview';
import BaseComponent from './base';
import WebView from './webview';
export interface TabProps {
role: string;

View File

@@ -1,12 +1,13 @@
import {ipcRenderer, remote} from 'electron';
import path from 'path';
import fs from 'fs';
import path from 'path';
import * as ConfigUtil from '../utils/config-util';
import * as SystemUtil from '../utils/system-util';
import BaseComponent from './base';
import handleExternalLink from './handle-external-link';
import {contextMenu} from './context-menu';
import handleExternalLink from './handle-external-link';
const {app, dialog} = remote;

View File

@@ -1,5 +1,4 @@
import {ipcRenderer} from 'electron';
import {EventEmitter} from 'events';
import {ClipboardDecrypterImpl} from './clipboard-decrypter';

View File

@@ -1,8 +1,8 @@
import {remote} from 'electron';
import SendFeedback from '@electron-elements/send-feedback';
import path from 'path';
import fs from 'fs';
import path from 'path';
import SendFeedback from '@electron-elements/send-feedback';
const {app} = remote;

View File

@@ -1,27 +1,29 @@
import {ipcRenderer, remote, clipboard} from 'electron';
import {feedbackHolder} from './feedback';
import path from 'path';
import escape from 'escape-html';
import isDev from 'electron-is-dev';
const {session, app, Menu, dialog} = remote;
import escape from 'escape-html';
import * as Messages from '../../resources/messages';
import FunctionalTab from './components/functional-tab';
import ServerTab from './components/server-tab';
import WebView from './components/webview';
import {feedbackHolder} from './feedback';
import * as CommonUtil from './utils/common-util';
import * as ConfigUtil from './utils/config-util';
import * as DNDUtil from './utils/dnd-util';
import type {DNDSettings} from './utils/dnd-util';
import * as DomainUtil from './utils/domain-util';
import * as EnterpriseUtil from './utils/enterprise-util';
import * as LinkUtil from './utils/link-util';
import Logger from './utils/logger-util';
import ReconnectUtil from './utils/reconnect-util';
// eslint-disable-next-line import/no-unassigned-import
import './tray';
import * as DomainUtil from './utils/domain-util';
import WebView from './components/webview';
import ServerTab from './components/server-tab';
import FunctionalTab from './components/functional-tab';
import * as ConfigUtil from './utils/config-util';
import * as DNDUtil from './utils/dnd-util';
import ReconnectUtil from './utils/reconnect-util';
import Logger from './utils/logger-util';
import * as CommonUtil from './utils/common-util';
import * as EnterpriseUtil from './utils/enterprise-util';
import * as LinkUtil from './utils/link-util';
import * as Messages from '../../resources/messages';
import type {DNDSettings} from './utils/dnd-util';
const {session, app, Menu, dialog} = remote;
interface FunctionalTabProps {
name: string;
@@ -59,7 +61,14 @@ const logger = new Logger({
});
const rendererDirectory = path.resolve(__dirname, '..');
export type ServerOrFunctionalTab = ServerTab | FunctionalTab;
type ServerOrFunctionalTab = ServerTab | FunctionalTab;
export interface TabData {
role: string;
name: string;
index: number;
webviewName: string;
}
class ServerManagerView {
$addServerButton: HTMLButtonElement;
@@ -590,19 +599,13 @@ class ServerManagerView {
// 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(): ServerOrFunctionalTab[] {
const tabs: ServerOrFunctionalTab[] = [];
this.tabs.forEach((tab: ServerOrFunctionalTab) => {
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;
get tabsForIpc(): TabData[] {
return this.tabs.map(tab => ({
role: tab.props.role,
name: tab.props.name,
index: tab.props.index,
webviewName: tab.webview.props.name
}));
}
activateTab(index: number, hideOldTab = true): void {

View File

@@ -1,12 +1,14 @@
import {ipcRenderer} from 'electron';
import MacNotifier from 'node-mac-notifier';
import electron_bridge from '../electron-bridge';
import * as ConfigUtil from '../utils/config-util';
import {
appId, customReply, focusCurrentServer, parseReply
} from './helpers';
import MacNotifier from 'node-mac-notifier';
import * as ConfigUtil from '../utils/config-util';
import electron_bridge from '../electron-bridge';
type ReplyHandler = (response: string) => void;
type ClickHandler = () => void;
let replyHandler: ReplyHandler;

View File

@@ -1,8 +1,9 @@
import {ipcRenderer} from 'electron';
import {focusCurrentServer} from './helpers';
import * as ConfigUtil from '../utils/config-util';
import {focusCurrentServer} from './helpers';
const NativeNotification = window.Notification;
export default class BaseNotification extends NativeNotification {
constructor(title: string, options: NotificationOptions) {

View File

@@ -1,8 +1,8 @@
import {remote} from 'electron';
import electron_bridge from '../electron-bridge';
import {appId, loadBots} from './helpers';
import DefaultNotification from './default-notification';
import {appId} from './helpers';
const {app} = remote;
// From https://github.com/felixrieseberg/electron-windows-notifications#appusermodelid
@@ -67,7 +67,3 @@ export function newNotification(
actions: notification.actions
};
}
electron_bridge.once('zulip-loaded', async () => {
await loadBots();
});

View File

@@ -1,8 +1,6 @@
'use-strict';
import {remote, OpenDialogOptions} from 'electron';
import path from 'path';
import BaseComponent from '../../components/base';
import * as CertificateUtil from '../../utils/certificate-util';
import * as DomainUtil from '../../utils/domain-util';

View File

@@ -1,4 +1,5 @@
import {ipcRenderer} from 'electron';
import escape from 'escape-html';
import BaseComponent from '../../components/base';

View File

@@ -1,12 +1,13 @@
import {ipcRenderer} from 'electron';
import BaseSection from './base-section';
import * as DomainUtil from '../../utils/domain-util';
import ServerInfoForm from './server-info-form';
import AddCertificate from './add-certificate';
import FindAccounts from './find-accounts';
import * as t from '../../utils/translation-util';
import AddCertificate from './add-certificate';
import BaseSection from './base-section';
import FindAccounts from './find-accounts';
import ServerInfoForm from './server-info-form';
interface ConnectedOrgSectionProps {
$root: Element;
}

View File

@@ -1,5 +1,3 @@
'use-strict';
import BaseComponent from '../../components/base';
import * as LinkUtil from '../../utils/link-util';
import * as t from '../../utils/translation-util';

View File

@@ -1,18 +1,19 @@
import {ipcRenderer, remote, OpenDialogOptions} from 'electron';
import path from 'path';
import Tagify from '@yaireo/tagify';
import fs from 'fs-extra';
import ISO6391 from 'iso-639-1';
const {app, dialog, session} = remote;
const currentBrowserWindow = remote.getCurrentWindow();
import BaseSection from './base-section';
import supportedLocales from '../../../../translations/supported-locales.json';
import * as ConfigUtil from '../../utils/config-util';
import * as EnterpriseUtil from '../../utils/enterprise-util';
import * as t from '../../utils/translation-util';
import supportedLocales from '../../../../translations/supported-locales.json';
import Tagify from '@yaireo/tagify';
import ISO6391 from 'iso-639-1';
import BaseSection from './base-section';
const {app, dialog, session} = remote;
const currentBrowserWindow = remote.getCurrentWindow();
interface GeneralSectionProps {
$root: Element;

View File

@@ -1,9 +1,10 @@
import {ipcRenderer} from 'electron';
import BaseSection from './base-section';
import * as ConfigUtil from '../../utils/config-util';
import * as t from '../../utils/translation-util';
import BaseSection from './base-section';
interface NetworkSectionProps {
$root: Element;
}

View File

@@ -1,14 +1,15 @@
import {ipcRenderer} from 'electron';
import BaseComponent from '../../components/base';
import Nav from './nav';
import ServersSection from './servers-section';
import GeneralSection from './general-section';
import NetworkSection from './network-section';
import ConnectedOrgSection from './connected-org-section';
import ShortcutsSection from './shortcuts-section';
import type {DNDSettings} from '../../utils/dnd-util';
import ConnectedOrgSection from './connected-org-section';
import GeneralSection from './general-section';
import Nav from './nav';
import NetworkSection from './network-section';
import ServersSection from './servers-section';
import ShortcutsSection from './shortcuts-section';
type Section = ServersSection | GeneralSection | NetworkSection | ConnectedOrgSection | ShortcutsSection;
export default class PreferenceView extends BaseComponent {

View File

@@ -1,8 +1,8 @@
import {remote, ipcRenderer} from 'electron';
import * as Messages from '../../../../resources/messages';
import BaseComponent from '../../components/base';
import * as DomainUtil from '../../utils/domain-util';
import * as Messages from '../../../../resources/messages';
import * as t from '../../utils/translation-util';
const {dialog} = remote;

View File

@@ -1,6 +1,7 @@
import * as t from '../../utils/translation-util';
import BaseSection from './base-section';
import NewServerForm from './new-server-form';
import * as t from '../../utils/translation-util';
interface ServersSectionProps {
$root: Element;

View File

@@ -1,7 +1,8 @@
import BaseSection from './base-section';
import * as LinkUtil from '../../utils/link-util';
import * as t from '../../utils/translation-util';
import BaseSection from './base-section';
interface ShortcutsSectionProps {
$root: Element;
}

View File

@@ -3,18 +3,20 @@ import fs from 'fs';
import isDev from 'electron-is-dev';
import electron_bridge from './electron-bridge';
import {loadBots} from './notification/helpers';
import * as NetworkError from './pages/network';
// eslint-disable-next-line import/no-unassigned-import
import './notification';
// Prevent drag and drop event in main process which prevents remote code executaion
// eslint-disable-next-line import/no-unassigned-import
import './shared/preventdrag';
import electron_bridge from './electron-bridge';
contextBridge.exposeInMainWorld('raw_electron_bridge', electron_bridge);
electron_bridge.once('zulip-loaded', async () => {
await loadBots();
});
ipcRenderer.on('logout', () => {
// Create the menu for the below
const dropdown: HTMLElement = document.querySelector('.dropdown-toggle');

View File

@@ -1,6 +1,6 @@
import {ipcRenderer, remote, WebviewTag, NativeImage} from 'electron';
import path from 'path';
import * as ConfigUtil from './utils/config-util';
const {Tray, Menu, nativeImage, BrowserWindow} = remote;

View File

@@ -1,9 +1,10 @@
import electron from 'electron';
import {JsonDB} from 'node-json-db';
import {initSetUp} from './default-util';
import fs from 'fs';
import path from 'path';
import {JsonDB} from 'node-json-db';
import {initSetUp} from './default-util';
import Logger from './logger-util';
const {app, dialog} =

View File

@@ -1,10 +1,11 @@
import {JsonDB} from 'node-json-db';
import electron from 'electron';
import fs from 'fs';
import path from 'path';
import electron from 'electron';
import Logger from './logger-util';
import {JsonDB} from 'node-json-db';
import * as EnterpriseUtil from './enterprise-util';
import Logger from './logger-util';
const logger = new Logger({
file: 'config-util.log',

View File

@@ -1,12 +1,13 @@
import {JsonDB} from 'node-json-db';
import {remote, ipcRenderer} from 'electron';
import fs from 'fs';
import path from 'path';
import Logger from './logger-util';
import {remote, ipcRenderer} from 'electron';
import {JsonDB} from 'node-json-db';
import * as Messages from '../../../resources/messages';
import * as EnterpriseUtil from './enterprise-util';
import * as Messages from '../../../resources/messages';
import Logger from './logger-util';
const {app, dialog} = remote;

View File

@@ -1,9 +1,10 @@
import {shell} from 'electron';
import escape from 'escape-html';
import fs from 'fs';
import os from 'os';
import path from 'path';
import escape from 'escape-html';
export function isUploadsUrl(server: string, url: URL): boolean {
return url.origin === server && url.pathname.startsWith('/user_uploads/');
}
@@ -36,7 +37,7 @@ export async function openBrowser(url: URL): Promise<void> {
</body>
</html>
`);
shell.openItem(file);
await shell.openPath(file);
setTimeout(() => {
fs.unlinkSync(file);
fs.rmdirSync(dir);

View File

@@ -1,8 +1,9 @@
import {JsonDB} from 'node-json-db';
import electron from 'electron';
import fs from 'fs';
import path from 'path';
import electron from 'electron';
import {JsonDB} from 'node-json-db';
import Logger from './logger-util';
const remote =

View File

@@ -1,11 +1,12 @@
import {Console} from 'console'; // eslint-disable-line node/prefer-global/console
import {initSetUp} from './default-util';
import {sentryInit, captureException} from './sentry-util';
import electron from 'electron';
import fs from 'fs';
import os from 'os';
import isDev from 'electron-is-dev';
import electron from 'electron';
import {initSetUp} from './default-util';
import {sentryInit, captureException} from './sentry-util';
interface LoggerOptions {
timestamp?: true | (() => string);

View File

@@ -1,7 +1,9 @@
import {ipcRenderer} from 'electron';
import type WebView from '../components/webview';
import backoff from 'backoff';
import type WebView from '../components/webview';
import Logger from './logger-util';
const logger = new Logger({

View File

@@ -1,5 +1,4 @@
import {init} from '@sentry/electron';
import isDev from 'electron-is-dev';
export const sentryInit = (): void => {

View File

@@ -1,5 +1,4 @@
import {ipcRenderer} from 'electron';
import os from 'os';
export const connectivityERR: string[] = [

View File

@@ -1,5 +1,7 @@
import path from 'path';
import i18n from 'i18n';
import * as ConfigUtil from './config-util';
i18n.configure({

Binary file not shown.

Binary file not shown.

View File

@@ -2,6 +2,25 @@
All notable changes to the Zulip desktop app are documented in this file.
### v5.4.0 --2020-07-21
**New features**:
* Added support for certificates from system store.
* Added support for Slovak as application language.
**Fixes**:
* Fix bug in *Copy Link* and add *Copy Email* option in context menu.
* Enable *Copy* option in context menu only when copying is possible.
* Remove leading and trailing separators in context menu on non-mac systems.
* ignoreCerts: Accommodate WebSocket URLs in certificate-error handler.
**Dependencies**:
* Upgrade all dependencies, including Electron 8.4.0.
**Deprecations**:
* This release supports certificates from Zulip store as well as system store. Zulip certificate store will be deprecated in the next release.
Users are hereby requested to move to system store. For more information, please see the [documentation](https://zulip.com/help/custom-certificates).
### v5.3.0 --2020-06-24
**Security fixes**:

View File

@@ -1,16 +1,16 @@
'use strict';
const gulp = require('gulp');
const {execSync} = require('child_process');
const electron = require('electron-connect').server.create({
verbose: true
});
const tape = require('gulp-tape');
const tapColorize = require('tap-colorize');
const ts = require('gulp-typescript');
const tsProject = ts.createProject('tsconfig.json');
const glob = require('glob');
const {execSync} = require('child_process');
const gulp = require('gulp');
const tape = require('gulp-tape');
const ts = require('gulp-typescript');
const tapColorize = require('tap-colorize');
const tsProject = ts.createProject('tsconfig.json');
const baseFilePattern = 'app/+(main|renderer)/**/*';
const globOptions = {cwd: __dirname};
const jsFiles = glob.sync(baseFilePattern + '.js', globOptions);

3332
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": "5.4.0",
"version": "5.4.1-beta",
"main": "./app/main",
"description": "Zulip Desktop App",
"license": "Apache-2.0",
@@ -50,7 +50,7 @@
"files": [
"app/**/*"
],
"copyright": "©2019 Kandra Labs, Inc.",
"copyright": "©2020 Kandra Labs, Inc.",
"mac": {
"category": "public.app-category.productivity",
"target": [
@@ -146,8 +146,8 @@
],
"dependencies": {
"@electron-elements/send-feedback": "^2.0.3",
"@sentry/electron": "^1.4.0",
"@yaireo/tagify": "^3.15.3",
"@sentry/electron": "^1.5.0",
"@yaireo/tagify": "^3.15.4",
"adm-zip": "^0.4.16",
"auto-launch": "^5.0.5",
"backoff": "^2.5.0",
@@ -174,14 +174,14 @@
"@types/escape-html": "^1.0.0",
"@types/fs-extra": "^9.0.1",
"@types/i18n": "^0.8.6",
"@types/node": "^14.0.23",
"@types/node": "^14.0.25",
"@types/requestidlecallback": "^0.3.1",
"@typescript-eslint/eslint-plugin": "^3.6.1",
"@typescript-eslint/parser": "^3.6.1",
"@typescript-eslint/eslint-plugin": "^3.7.0",
"@typescript-eslint/parser": "^3.7.0",
"devtron": "^1.4.0",
"dotenv": "^8.2.0",
"electron": "^8.4.0",
"electron-builder": "^22.7.0",
"electron": "^9.1.1",
"electron-builder": "^22.8.0",
"electron-connect": "^0.6.3",
"electron-notarize": "^1.0.0",
"glob": "^7.1.6",
@@ -192,7 +192,7 @@
"nodemon": "^2.0.4",
"pre-commit": "^1.2.2",
"rimraf": "^3.0.2",
"spectron": "^10.0.1",
"spectron": "^11.1.0",
"stylelint": "^13.6.1",
"tap-colorize": "^1.2.0",
"tape": "^5.0.1",
@@ -204,6 +204,17 @@
"@typescript-eslint/no-dynamic-delete": "off",
"@typescript-eslint/prefer-readonly-parameter-types": "off",
"arrow-body-style": "error",
"import/first": "error",
"import/newline-after-import": "error",
"import/order": [
"error",
{
"alphabetize": {
"order": "asc"
},
"newlines-between": "always"
}
],
"import/unambiguous": "error",
"max-lines": [
"warn",

View File

@@ -1,11 +1,11 @@
'use strict';
const path = require('path');
const dotenv = require('dotenv');
const {notarize} = require('electron-notarize');
dotenv.config({path: path.join(__dirname, '/../.env')});
const {notarize} = require('electron-notarize');
exports.default = async function (context) {
const {electronPlatformName, appOutDir} = context;
if (electronPlatformName !== 'darwin') {

View File

@@ -1,5 +1,6 @@
'use strict';
const test = require('tape');
const setup = require('./setup');
test('app runs', async t => {

View File

@@ -1,8 +1,9 @@
'use strict';
const {Application} = require('spectron');
const fs = require('fs');
const path = require('path');
const rimraf = require('rimraf');
const {Application} = require('spectron');
const config = require('./config');

View File

@@ -1,5 +1,6 @@
'use strict';
const test = require('tape');
const setup = require('./setup');
test('add-organization', async t => {

View File

@@ -1,5 +1,6 @@
'use strict';
const test = require('tape');
const setup = require('./setup');
// Create new org link should open in the default browser [WIP]