* #1960 fix unexpected top menu focus * #1960 test update * #1960 improved test * #1960 optimized algrithm to handle only Alt key to improve performance and avoid side effects * #1960 tests update * #1960 fixed 3 dit menu focus on workspace change with Alt+1, Alt+2 * #313 fix linter issue * #1960 fix linter issue * tests update
This commit is contained in:
@@ -35,6 +35,9 @@ describe('menu/menu', function desc() {
|
|||||||
const mainWindow = this.app.windows().find((window) => window.url().includes('index'));
|
const mainWindow = this.app.windows().find((window) => window.url().includes('index'));
|
||||||
mainWindow.should.not.be.null;
|
mainWindow.should.not.be.null;
|
||||||
|
|
||||||
|
await mainWindow.bringToFront();
|
||||||
|
await mainWindow.click('#app');
|
||||||
|
|
||||||
// Settings window should open if Alt works
|
// Settings window should open if Alt works
|
||||||
robot.keyTap('alt');
|
robot.keyTap('alt');
|
||||||
robot.keyTap('enter');
|
robot.keyTap('enter');
|
||||||
|
@@ -56,7 +56,8 @@ const tabView = new MessagingTabView(server);
|
|||||||
|
|
||||||
describe('main/views/MattermostView', () => {
|
describe('main/views/MattermostView', () => {
|
||||||
describe('load', () => {
|
describe('load', () => {
|
||||||
const mattermostView = new MattermostView(tabView, {}, {}, {});
|
const window = {on: jest.fn()};
|
||||||
|
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mattermostView.loadSuccess = jest.fn();
|
mattermostView.loadSuccess = jest.fn();
|
||||||
@@ -102,7 +103,8 @@ describe('main/views/MattermostView', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('retry', () => {
|
describe('retry', () => {
|
||||||
const mattermostView = new MattermostView(tabView, {}, {}, {});
|
const window = {on: jest.fn()};
|
||||||
|
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mattermostView.view.webContents.loadURL.mockImplementation(() => Promise.resolve());
|
mattermostView.view.webContents.loadURL.mockImplementation(() => Promise.resolve());
|
||||||
@@ -153,7 +155,8 @@ describe('main/views/MattermostView', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('loadSuccess', () => {
|
describe('loadSuccess', () => {
|
||||||
const mattermostView = new MattermostView(tabView, {}, {}, {});
|
const window = {on: jest.fn()};
|
||||||
|
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
@@ -173,7 +176,7 @@ describe('main/views/MattermostView', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('show', () => {
|
describe('show', () => {
|
||||||
const window = {addBrowserView: jest.fn(), removeBrowserView: jest.fn()};
|
const window = {addBrowserView: jest.fn(), removeBrowserView: jest.fn(), on: jest.fn()};
|
||||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -218,7 +221,7 @@ describe('main/views/MattermostView', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('destroy', () => {
|
describe('destroy', () => {
|
||||||
const window = {removeBrowserView: jest.fn()};
|
const window = {removeBrowserView: jest.fn(), on: jest.fn()};
|
||||||
const mattermostView = new MattermostView(tabView, {}, window, {});
|
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -245,10 +248,11 @@ describe('main/views/MattermostView', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('handleInputEvents', () => {
|
describe('handleInputEvents', () => {
|
||||||
const mattermostView = new MattermostView(tabView, {}, {}, {});
|
const window = {on: jest.fn()};
|
||||||
|
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||||
|
|
||||||
it('should open three dot menu on pressing Alt', () => {
|
it('should open three dot menu on pressing Alt', () => {
|
||||||
mattermostView.handleInputEvents(null, {key: 'Alt', type: 'keyDown'});
|
mattermostView.handleInputEvents(null, {key: 'Alt', type: 'keyDown', alt: true, shift: false, control: false, meta: false});
|
||||||
mattermostView.handleInputEvents(null, {key: 'Alt', type: 'keyUp'});
|
mattermostView.handleInputEvents(null, {key: 'Alt', type: 'keyUp'});
|
||||||
expect(WindowManager.focusThreeDotMenu).toHaveBeenCalled();
|
expect(WindowManager.focusThreeDotMenu).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@@ -268,7 +272,8 @@ describe('main/views/MattermostView', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('handleDidNavigate', () => {
|
describe('handleDidNavigate', () => {
|
||||||
const mattermostView = new MattermostView(tabView, {}, {}, {});
|
const window = {on: jest.fn()};
|
||||||
|
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mattermostView.setBounds = jest.fn();
|
mattermostView.setBounds = jest.fn();
|
||||||
@@ -286,7 +291,8 @@ describe('main/views/MattermostView', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('handleUpdateTarget', () => {
|
describe('handleUpdateTarget', () => {
|
||||||
const mattermostView = new MattermostView(tabView, {}, {}, {});
|
const window = {on: jest.fn()};
|
||||||
|
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mattermostView.emit = jest.fn();
|
mattermostView.emit = jest.fn();
|
||||||
@@ -310,7 +316,8 @@ describe('main/views/MattermostView', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('updateMentionsFromTitle', () => {
|
describe('updateMentionsFromTitle', () => {
|
||||||
const mattermostView = new MattermostView(tabView, {}, {}, {});
|
const window = {on: jest.fn()};
|
||||||
|
const mattermostView = new MattermostView(tabView, {}, window, {});
|
||||||
|
|
||||||
it('should parse mentions from title', () => {
|
it('should parse mentions from title', () => {
|
||||||
mattermostView.updateMentionsFromTitle('(7) Mattermost');
|
mattermostView.updateMentionsFromTitle('(7) Mattermost');
|
||||||
|
@@ -62,14 +62,14 @@ export class MattermostView extends EventEmitter {
|
|||||||
|
|
||||||
currentFavicon?: string;
|
currentFavicon?: string;
|
||||||
hasBeenShown: boolean;
|
hasBeenShown: boolean;
|
||||||
altTimeout?: number;
|
|
||||||
altLastPressed?: boolean;
|
|
||||||
contextMenu: ContextMenu;
|
contextMenu: ContextMenu;
|
||||||
|
|
||||||
status?: Status;
|
status?: Status;
|
||||||
retryLoad?: NodeJS.Timeout;
|
retryLoad?: NodeJS.Timeout;
|
||||||
maxRetries: number;
|
maxRetries: number;
|
||||||
|
|
||||||
|
private altPressStatus: boolean;
|
||||||
|
|
||||||
constructor(tab: TabView, serverInfo: ServerInfo, win: BrowserWindow, options: BrowserViewConstructorOptions) {
|
constructor(tab: TabView, serverInfo: ServerInfo, win: BrowserWindow, options: BrowserViewConstructorOptions) {
|
||||||
super();
|
super();
|
||||||
this.tab = tab;
|
this.tab = tab;
|
||||||
@@ -98,7 +98,6 @@ export class MattermostView extends EventEmitter {
|
|||||||
this.hasBeenShown = false;
|
this.hasBeenShown = false;
|
||||||
|
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
this.altLastPressed = false;
|
|
||||||
this.view.webContents.on('before-input-event', this.handleInputEvents);
|
this.view.webContents.on('before-input-event', this.handleInputEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +117,12 @@ export class MattermostView extends EventEmitter {
|
|||||||
|
|
||||||
this.contextMenu = new ContextMenu({}, this.view);
|
this.contextMenu = new ContextMenu({}, this.view);
|
||||||
this.maxRetries = MAX_SERVER_RETRIES;
|
this.maxRetries = MAX_SERVER_RETRIES;
|
||||||
|
|
||||||
|
this.altPressStatus = false;
|
||||||
|
|
||||||
|
this.window.on('blur', () => {
|
||||||
|
this.altPressStatus = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// use the same name as the server
|
// use the same name as the server
|
||||||
@@ -288,24 +293,27 @@ export class MattermostView extends EventEmitter {
|
|||||||
return this.view.webContents;
|
return this.view.webContents;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleInputEvents = (_: Event, input: Input) => {
|
private registerAltKeyPressed = (input: Input) => {
|
||||||
// Handler for pressing the Alt key to focus the 3-dot menu
|
const isAltPressed = input.key === 'Alt' && input.alt === true && input.control === false && input.shift === false && input.meta === false;
|
||||||
if (input.key === 'Alt' && input.type === 'keyUp' && this.altLastPressed) {
|
|
||||||
this.altLastPressed = false;
|
if (input.type === 'keyDown') {
|
||||||
clearTimeout(this.altTimeout);
|
this.altPressStatus = isAltPressed;
|
||||||
WindowManager.focusThreeDotMenu();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack to detect keyPress so that alt+<key> combinations don't default back to the 3-dot menu
|
if (input.key !== 'Alt') {
|
||||||
if (input.key === 'Alt' && input.type === 'keyDown') {
|
this.altPressStatus = false;
|
||||||
this.altLastPressed = true;
|
}
|
||||||
this.altTimeout = setTimeout(() => {
|
};
|
||||||
this.altLastPressed = false;
|
|
||||||
}, 500) as unknown as number;
|
private isAltKeyReleased = (input: Input) => {
|
||||||
} else {
|
return input.type === 'keyUp' && this.altPressStatus === true;
|
||||||
this.altLastPressed = false;
|
};
|
||||||
clearTimeout(this.altTimeout);
|
|
||||||
|
handleInputEvents = (_: Event, input: Input) => {
|
||||||
|
this.registerAltKeyPressed(input);
|
||||||
|
|
||||||
|
if (this.isAltKeyReleased(input)) {
|
||||||
|
WindowManager.focusThreeDotMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user