mirror of
				https://github.com/zulip/zulip-desktop.git
				synced 2025-11-03 21:43:18 +00:00 
			
		
		
		
	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>
This commit is contained in:
		@@ -355,7 +355,7 @@ ${error}`
 | 
				
			|||||||
		AppMenu.setMenu(props);
 | 
							AppMenu.setMenu(props);
 | 
				
			||||||
		const activeTab = props.tabs[props.activeTabIndex];
 | 
							const activeTab = props.tabs[props.activeTabIndex];
 | 
				
			||||||
		if (activeTab) {
 | 
							if (activeTab) {
 | 
				
			||||||
			mainWindow.setTitle(`Zulip - ${activeTab.webview.props.name}`);
 | 
								mainWindow.setTitle(`Zulip - ${activeTab.webviewName}`);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ import {app, shell, BrowserWindow, Menu} from 'electron';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import AdmZip from 'adm-zip';
 | 
					import AdmZip from 'adm-zip';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type {ServerOrFunctionalTab} from '../renderer/js/main';
 | 
					import type {TabData} from '../renderer/js/main';
 | 
				
			||||||
import * as ConfigUtil from '../renderer/js/utils/config-util';
 | 
					import * as ConfigUtil from '../renderer/js/utils/config-util';
 | 
				
			||||||
import * as DNDUtil from '../renderer/js/utils/dnd-util';
 | 
					import * as DNDUtil from '../renderer/js/utils/dnd-util';
 | 
				
			||||||
import * as LinkUtil from '../renderer/js/utils/link-util';
 | 
					import * as LinkUtil from '../renderer/js/utils/link-util';
 | 
				
			||||||
@@ -11,7 +11,7 @@ import * as t from '../renderer/js/utils/translation-util';
 | 
				
			|||||||
import {appUpdater} from './autoupdater';
 | 
					import {appUpdater} from './autoupdater';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface MenuProps {
 | 
					export interface MenuProps {
 | 
				
			||||||
	tabs: ServerOrFunctionalTab[];
 | 
						tabs: TabData[];
 | 
				
			||||||
	activeTabIndex?: number;
 | 
						activeTabIndex?: number;
 | 
				
			||||||
	enableMenu?: boolean;
 | 
						enableMenu?: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -215,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[] = [{
 | 
						const initialSubmenu: Electron.MenuItemConstructorOptions[] = [{
 | 
				
			||||||
		label: t.__('Minimize'),
 | 
							label: t.__('Minimize'),
 | 
				
			||||||
		role: 'minimize'
 | 
							role: 'minimize'
 | 
				
			||||||
@@ -231,17 +231,17 @@ function getWindowSubmenu(tabs: ServerOrFunctionalTab[], activeTabIndex: number)
 | 
				
			|||||||
		});
 | 
							});
 | 
				
			||||||
		tabs.forEach(tab => {
 | 
							tabs.forEach(tab => {
 | 
				
			||||||
			// Do not add functional tab settings to list of windows in menu bar
 | 
								// 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;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			initialSubmenu.push({
 | 
								initialSubmenu.push({
 | 
				
			||||||
				label: tab.props.name,
 | 
									label: tab.name,
 | 
				
			||||||
				accelerator: tab.props.role === 'function' ? '' : `${ShortcutKey} + ${tab.props.index + 1}`,
 | 
									accelerator: tab.role === 'function' ? '' : `${ShortcutKey} + ${tab.index + 1}`,
 | 
				
			||||||
				checked: tab.props.index === activeTabIndex,
 | 
									checked: tab.index === activeTabIndex,
 | 
				
			||||||
				click(_item, focusedWindow) {
 | 
									click(_item, focusedWindow) {
 | 
				
			||||||
					if (focusedWindow) {
 | 
										if (focusedWindow) {
 | 
				
			||||||
						sendAction('switch-server-tab', tab.props.index);
 | 
											sendAction('switch-server-tab', tab.index);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				type: 'checkbox'
 | 
									type: 'checkbox'
 | 
				
			||||||
@@ -547,20 +547,20 @@ async function checkForUpdate(): Promise<void> {
 | 
				
			|||||||
	await appUpdater(true);
 | 
						await appUpdater(true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getNextServer(tabs: ServerOrFunctionalTab[], activeTabIndex: number): number {
 | 
					function getNextServer(tabs: TabData[], activeTabIndex: number): number {
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		activeTabIndex = (activeTabIndex + 1) % tabs.length;
 | 
							activeTabIndex = (activeTabIndex + 1) % tabs.length;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	while (tabs[activeTabIndex].props.role !== 'server');
 | 
						while (tabs[activeTabIndex].role !== 'server');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return activeTabIndex;
 | 
						return activeTabIndex;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getPreviousServer(tabs: ServerOrFunctionalTab[], activeTabIndex: number): number {
 | 
					function getPreviousServer(tabs: TabData[], activeTabIndex: number): number {
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		activeTabIndex = (activeTabIndex - 1 + tabs.length) % tabs.length;
 | 
							activeTabIndex = (activeTabIndex - 1 + tabs.length) % tabs.length;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	while (tabs[activeTabIndex].props.role !== 'server');
 | 
						while (tabs[activeTabIndex].role !== 'server');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return activeTabIndex;
 | 
						return activeTabIndex;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,14 @@ const logger = new Logger({
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const rendererDirectory = path.resolve(__dirname, '..');
 | 
					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 {
 | 
					class ServerManagerView {
 | 
				
			||||||
	$addServerButton: HTMLButtonElement;
 | 
						$addServerButton: HTMLButtonElement;
 | 
				
			||||||
@@ -592,19 +599,13 @@ class ServerManagerView {
 | 
				
			|||||||
	// not crash app when this.tabs is passed into
 | 
						// not crash app when this.tabs is passed into
 | 
				
			||||||
	// ipcRenderer. Something about webview, and props.webview
 | 
						// ipcRenderer. Something about webview, and props.webview
 | 
				
			||||||
	// properties in ServerTab causes the app to crash.
 | 
						// properties in ServerTab causes the app to crash.
 | 
				
			||||||
	get tabsForIpc(): ServerOrFunctionalTab[] {
 | 
						get tabsForIpc(): TabData[] {
 | 
				
			||||||
		const tabs: ServerOrFunctionalTab[] = [];
 | 
							return this.tabs.map(tab => ({
 | 
				
			||||||
		this.tabs.forEach((tab: ServerOrFunctionalTab) => {
 | 
								role: tab.props.role,
 | 
				
			||||||
			const proto = Object.create(Object.getPrototypeOf(tab));
 | 
								name: tab.props.name,
 | 
				
			||||||
			const tabClone = Object.assign(proto, tab);
 | 
								index: tab.props.index,
 | 
				
			||||||
 | 
								webviewName: tab.webview.props.name
 | 
				
			||||||
			tabClone.webview = {props: {}};
 | 
							}));
 | 
				
			||||||
			tabClone.webview.props.name = tab.webview.props.name;
 | 
					 | 
				
			||||||
			delete tabClone.props.webview;
 | 
					 | 
				
			||||||
			tabs.push(tabClone);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return tabs;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	activateTab(index: number, hideOldTab = true): void {
 | 
						activateTab(index: number, hideOldTab = true): void {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user