Skip to content

Commit a48996b

Browse files
SDA-4847 - SDA-4848 - Optimize mini view and fix mini state (#2332)
* SDA-4847 - SDA-4848 - Optimize mini view and fix mini state * SDA-4847 - SDA-4848 - Refactor typo
1 parent 80009ac commit a48996b

8 files changed

+372
-140
lines changed

spec/appMenu.spec.ts

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import { AppMenu, menuSections } from '../src/app/app-menu';
22
import { autoLaunchInstance } from '../src/app/auto-launch-controller';
33
import { config } from '../src/app/config-handler';
4+
import { miniViewHandler } from '../src/app/mini-view-handler';
45
import { exportCrashDumps, exportLogs } from '../src/app/reports-handler';
5-
import {
6-
activateMiniView,
7-
deactivateMiniView,
8-
updateAlwaysOnTop,
9-
} from '../src/app/window-actions';
6+
import { updateAlwaysOnTop } from '../src/app/window-actions';
107
import { windowHandler } from '../src/app/window-handler';
118
import { zoomIn, zoomOut } from '../src/app/window-utils';
129
import { apiName } from '../src/common/api-interface';
@@ -136,6 +133,15 @@ jest.mock('../src/app/window-utils', () => {
136133
};
137134
});
138135

136+
jest.mock('../src/app/mini-view-handler', () => {
137+
return {
138+
miniViewHandler: {
139+
activateMiniView: jest.fn(),
140+
deactivateMiniView: jest.fn(),
141+
},
142+
};
143+
});
144+
139145
describe('app menu', () => {
140146
let appMenu;
141147
const updateUserFnLabel = 'updateUserConfig';
@@ -350,7 +356,7 @@ describe('app menu', () => {
350356

351357
const menuItem = findMenuItemBuildWindowMenu('Mini View');
352358
await menuItem.click(item);
353-
expect(activateMiniView).toHaveBeenCalled();
359+
expect(miniViewHandler.activateMiniView).toHaveBeenCalled();
354360
});
355361

356362
it('should deactivate mini view when "Exit Mini View" is clicked', async () => {
@@ -363,7 +369,7 @@ describe('app menu', () => {
363369

364370
const menuItem = findMenuItemBuildWindowMenu('Exit Mini View');
365371
await menuItem.click(item);
366-
expect(deactivateMiniView).toHaveBeenCalled();
372+
expect(miniViewHandler.deactivateMiniView).toHaveBeenCalled();
367373
});
368374

369375
it('should not show mini view options when feature is disabled', () => {

spec/miniViewHandler.spec.ts

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import { config } from '../src/app/config-handler';
2+
import { mainEvents } from '../src/app/main-event-handler';
3+
import {
4+
DEFAULT_MINI_VIEW_WINDOW_WIDTH,
5+
MINI_VIEW_THRESHOLD_WINDOW_WIDTH,
6+
miniViewHandler,
7+
} from '../src/app/mini-view-handler';
8+
import { windowHandler } from '../src/app/window-handler';
9+
10+
jest.mock('../src/app/config-handler', () => ({
11+
config: {
12+
getUserConfigFields: jest.fn(),
13+
updateUserConfig: jest.fn(),
14+
},
15+
}));
16+
17+
jest.mock('../src/app/main-event-handler', () => ({
18+
mainEvents: {
19+
publish: jest.fn(),
20+
},
21+
}));
22+
23+
jest.mock('../src/app/window-handler', () => ({
24+
windowHandler: {
25+
getMainWindow: jest.fn(),
26+
getMainWebContents: jest.fn(),
27+
setIsMiniViewEnabled: jest.fn(),
28+
setIsMiniViewFeatureEnabled: jest.fn(),
29+
setIsMiniViewTransition: jest.fn(),
30+
getIsMiniViewTransition: jest.fn(),
31+
},
32+
}));
33+
34+
jest.mock('../src/app/window-utils', () => {
35+
return {
36+
windowExists: jest.fn(() => true),
37+
};
38+
});
39+
40+
describe('MiniViewHandler', () => {
41+
let mockMainWindow: any;
42+
let mockMainWebContents: any;
43+
44+
beforeEach(() => {
45+
jest.clearAllMocks();
46+
47+
mockMainWindow = {
48+
setBounds: jest.fn(),
49+
getSize: jest.fn(() => [800, 600]),
50+
isFullScreen: jest.fn(() => false),
51+
isMaximized: jest.fn(() => false),
52+
setFullScreen: jest.fn(),
53+
unmaximize: jest.fn(),
54+
setSize: jest.fn(),
55+
setAlwaysOnTop: jest.fn(),
56+
};
57+
58+
mockMainWebContents = {
59+
send: jest.fn(),
60+
isDestroyed: jest.fn(() => false),
61+
};
62+
63+
(windowHandler.getMainWindow as jest.Mock).mockReturnValue(mockMainWindow);
64+
(windowHandler.getMainWebContents as jest.Mock).mockReturnValue(
65+
mockMainWebContents,
66+
);
67+
(windowHandler.setIsMiniViewTransition as jest.Mock).mockImplementation();
68+
(windowHandler.getIsMiniViewTransition as jest.Mock).mockImplementation(
69+
() => false,
70+
);
71+
(config.getUserConfigFields as jest.Mock).mockReturnValue({});
72+
(config.updateUserConfig as jest.Mock).mockResolvedValue(undefined);
73+
});
74+
75+
describe('activateMiniView', () => {
76+
it('should set correct bounds when mainWinPosInMiniView exists', () => {
77+
(config.getUserConfigFields as jest.Mock).mockReturnValue({
78+
mainWinPosInMiniView: { x: 10, y: 20, width: 500, height: 400 },
79+
});
80+
81+
miniViewHandler.activateMiniView();
82+
83+
expect(mockMainWindow.setBounds).toHaveBeenCalledWith({
84+
x: 10,
85+
y: 20,
86+
width: 500,
87+
height: 400,
88+
});
89+
});
90+
91+
it('should set default width and preserve height when mainWinPosInMiniView does not exist or has width > DEFAULT_MINI_VIEW_WINDOW_WIDTH', () => {
92+
(config.getUserConfigFields as jest.Mock).mockReturnValue({
93+
mainWinPosInMiniView: { x: 10, y: 20, width: 700, height: 400 },
94+
});
95+
miniViewHandler.activateMiniView();
96+
97+
expect(mockMainWindow.setSize).toHaveBeenCalledWith(
98+
DEFAULT_MINI_VIEW_WINDOW_WIDTH,
99+
600,
100+
);
101+
});
102+
103+
it('should call setIsMiniViewTransition and notifyClient with true', (done) => {
104+
jest.useFakeTimers();
105+
miniViewHandler.activateMiniView();
106+
107+
expect(windowHandler.setIsMiniViewTransition).toHaveBeenLastCalledWith(
108+
true,
109+
);
110+
111+
jest.runAllTimers();
112+
expect(windowHandler.setIsMiniViewTransition).toHaveBeenLastCalledWith(
113+
false,
114+
);
115+
expect(mockMainWebContents.send).toHaveBeenCalledWith(
116+
'set-mini-view',
117+
true,
118+
);
119+
done();
120+
});
121+
122+
it('should set fullscreen to false if currently is in fullscreen', () => {
123+
(mockMainWindow.isFullScreen as jest.Mock).mockReturnValue(true);
124+
miniViewHandler.activateMiniView();
125+
expect(mockMainWindow.setFullScreen).toHaveBeenCalledWith(false);
126+
});
127+
128+
it('should call unmaximize if currently is maximized', () => {
129+
(mockMainWindow.isMaximized as jest.Mock).mockReturnValue(true);
130+
miniViewHandler.activateMiniView();
131+
expect(mockMainWindow.unmaximize).toHaveBeenCalled();
132+
expect(mainEvents.publish).toHaveBeenCalledWith('unmaximize');
133+
});
134+
});
135+
136+
describe('deactivateMiniView', () => {
137+
it('should set correct bounds when mainWinPos exists and width > MINI_VIEW_THRESHOLD_WINDOW_WIDTH', () => {
138+
(config.getUserConfigFields as jest.Mock).mockReturnValue({
139+
mainWinPos: { x: 10, y: 20, width: 800, height: 400 },
140+
});
141+
142+
miniViewHandler.deactivateMiniView();
143+
144+
expect(mockMainWindow.setBounds).toHaveBeenCalledWith({
145+
x: 10,
146+
y: 20,
147+
width: 800,
148+
height: 400,
149+
});
150+
});
151+
152+
it('should set default width and preserve height when mainWinPos does not exist or has width <= MINI_VIEW_THRESHOLD_WINDOW_WIDTH', () => {
153+
(config.getUserConfigFields as jest.Mock).mockReturnValue({
154+
mainWinPos: { x: 10, y: 20, width: 600, height: 400 },
155+
});
156+
miniViewHandler.deactivateMiniView();
157+
158+
expect(mockMainWindow.setSize).toHaveBeenCalledWith(
159+
MINI_VIEW_THRESHOLD_WINDOW_WIDTH,
160+
600,
161+
);
162+
});
163+
164+
it('should call setIsMiniViewTransition and notifyClient with false', (done) => {
165+
jest.useFakeTimers();
166+
miniViewHandler.deactivateMiniView();
167+
168+
expect(windowHandler.setIsMiniViewTransition).toHaveBeenLastCalledWith(
169+
true,
170+
);
171+
jest.runAllTimers();
172+
expect(windowHandler.setIsMiniViewTransition).toHaveBeenLastCalledWith(
173+
false,
174+
);
175+
expect(mockMainWebContents.send).toHaveBeenCalledWith(
176+
'set-mini-view',
177+
false,
178+
);
179+
done();
180+
});
181+
});
182+
183+
describe('notifyClient', () => {
184+
it('should send set-mini-view message to main web contents', () => {
185+
miniViewHandler.notifyClient(true);
186+
187+
expect(mockMainWebContents.send).toHaveBeenCalledWith(
188+
'set-mini-view',
189+
true,
190+
);
191+
192+
miniViewHandler.notifyClient(false);
193+
expect(mockMainWebContents.send).toHaveBeenCalledWith(
194+
'set-mini-view',
195+
false,
196+
);
197+
});
198+
199+
it('should not send set-mini-view message if main web contents is destroyed', () => {
200+
(mockMainWebContents.isDestroyed as jest.Mock).mockReturnValue(true);
201+
202+
miniViewHandler.notifyClient(true);
203+
204+
expect(mockMainWebContents.send).not.toHaveBeenCalled();
205+
});
206+
});
207+
});

src/app/app-menu.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ import { CloudConfigDataTypes, config, IConfig } from './config-handler';
1717
import { restartDialog, titleBarChangeDialog } from './dialog-handler';
1818
import { exportCrashDumps, exportLogs } from './reports-handler';
1919
import {
20-
activateMiniView,
21-
deactivateMiniView,
2220
registerConsoleMessages,
2321
unregisterConsoleMessages,
2422
updateAlwaysOnTop,
@@ -43,6 +41,7 @@ import {
4341
AnalyticsElements,
4442
MenuActionTypes,
4543
} from './bi/interface';
44+
import { miniViewHandler } from './mini-view-handler';
4645
import { sdaMenuStore } from './stores';
4746

4847
export const menuSections = {
@@ -435,9 +434,9 @@ export class AppMenu {
435434
{
436435
click: async () => {
437436
if (windowHandler.getIsMiniViewEnabled()) {
438-
deactivateMiniView();
437+
miniViewHandler.deactivateMiniView();
439438
} else {
440-
activateMiniView();
439+
miniViewHandler.activateMiniView();
441440
}
442441
},
443442
accelerator: miniViewAccelerator,

src/app/main-api-handler.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ import {
4040
import { screenSnippet } from './screen-snippet-handler';
4141
import {
4242
activate,
43-
activateMiniView,
44-
deactivateMiniView,
4543
handleKeyPress,
4644
unMaximizeMainWindow,
4745
} from './window-actions';
@@ -65,6 +63,7 @@ import { getCommandLineArgs } from '../common/utils';
6563
import callNotificationHelper from '../renderer/call-notification-helper';
6664
import { autoUpdate, AutoUpdateTrigger } from './auto-update-handler';
6765
import { SDAUserSessionActionTypes } from './bi/interface';
66+
import { miniViewHandler } from './mini-view-handler';
6867
import { openfinHandler } from './openfin-handler';
6968
import { presenceStatus } from './presence-status-handler';
7069
import { appStats } from './stats';
@@ -527,10 +526,10 @@ ipcMain.on(
527526
windowHandler.setIsMiniViewEnabled(isMiniViewEnabled);
528527
break;
529528
case apiCmds.onEnterMiniView:
530-
activateMiniView();
529+
miniViewHandler.activateMiniView();
531530
break;
532531
case apiCmds.onExitMiniView:
533-
deactivateMiniView();
532+
miniViewHandler.deactivateMiniView();
534533
break;
535534
case apiCmds.connectCloud9Pipe:
536535
connectC9Pipe(event.sender, arg.pipe);

0 commit comments

Comments
 (0)