Skip to content

Commit

Permalink
fix: set focus to new app window upon creation (#202)
Browse files Browse the repository at this point in the history
refactor: move window creation to app window service

feat: set app window position to middle of current window
  • Loading branch information
kieranroneill authored Mar 8, 2024
1 parent 1389b6f commit f7b7577
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 82 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import browser, { Windows } from 'webextension-polyfill';

// constants
import { APP_WINDOW_KEY_PREFIX } from '@extension/constants';
import {
APP_WINDOW_KEY_PREFIX,
DEFAULT_POPUP_HEIGHT,
DEFAULT_POPUP_WIDTH,
} from '@extension/constants';

// enums
import { AppTypeEnum } from '@extension/enums';
Expand All @@ -12,7 +16,7 @@ import StorageManager from '../StorageManager';
// types
import type { ILogger } from '@common/types';
import type { IAppWindow } from '@extension/types';
import type { ICreateOptions } from './types';
import type { ICreateOptions, ICreateWindowOptions } from './types';

/**
* Manages app windows in storage.
Expand Down Expand Up @@ -45,6 +49,77 @@ export default class AppWindowManagerService {
* public functions
*/

public async createWindow({
left,
searchParams,
top,
type,
}: ICreateWindowOptions): Promise<Windows.Window | null> {
const _functionName: string = 'createWindow';
const currentWindow: Windows.Window = await browser.windows.getCurrent();
let appWindow: Windows.Window;
let defaultLeftPosition: number | undefined;
let defaultTopPosition: number | undefined;
let windowURL: string | null = null;

switch (type) {
case AppTypeEnum.BackgroundApp:
windowURL = 'background-app.html';
break;
case AppTypeEnum.MainApp:
windowURL = 'main-app.html';
break;
case AppTypeEnum.RegistrationApp:
windowURL = 'registration-app.html';
break;
default:
break;
}

if (!windowURL) {
this.logger?.debug(
`${AppWindowManagerService.name}#${_functionName}: unknown app type "${type}"`
);

return null;
}

defaultLeftPosition = currentWindow.width
? Math.round(currentWindow.width / 2 - DEFAULT_POPUP_WIDTH / 2)
: undefined;
defaultTopPosition = currentWindow.height
? Math.round(currentWindow.height / 2 - DEFAULT_POPUP_HEIGHT / 2)
: undefined;
appWindow = await browser.windows.create({
focused: true,
height: DEFAULT_POPUP_HEIGHT,
left: left ?? defaultLeftPosition,
top: top ?? defaultTopPosition,
type: 'popup',
url: `${windowURL}${searchParams ? `?${searchParams.toString()}` : ''}`,
width: DEFAULT_POPUP_WIDTH,
});

if (!appWindow.id) {
this.logger?.debug(
`${AppWindowManagerService.name}#${_functionName}: no window id for window "${type}"`
);

return null;
}

await this.storageManager.setItems({
[this.createAppWindowItemKey(appWindow.id)]: {
left: appWindow.left || 0,
top: appWindow.top || 0,
type,
windowId: appWindow.id,
},
});

return appWindow;
}

public async getAll(): Promise<IAppWindow[]> {
const items: Record<string, unknown> =
await this.storageManager.getAllItems();
Expand Down Expand Up @@ -104,22 +179,4 @@ export default class AppWindowManagerService {
appWindows.map((value) => this.createAppWindowItemKey(value.windowId))
);
}

public async saveByBrowserWindowAndType(
window: Windows.Window,
type: AppTypeEnum
): Promise<void> {
if (!window.id) {
return;
}

return await this.storageManager.setItems({
[this.createAppWindowItemKey(window.id)]: {
left: window.left || 0,
top: window.top || 0,
type,
windowId: window.id,
},
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// types
import { AppTypeEnum } from '@extension/enums';

interface ICreateWindowOptions {
left?: number;
searchParams?: URLSearchParams;
top?: number;
type: AppTypeEnum;
}

export default ICreateWindowOptions;
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export type { default as ICreateOptions } from './ICreateOptions';
export type { default as ICreateWindowOptions } from './ICreateWindowOptions';
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import browser, { Alarms, Tabs, Windows } from 'webextension-polyfill';

// constants
import {
DEFAULT_POPUP_HEIGHT,
DEFAULT_POPUP_WIDTH,
PASSWORD_LOCK_ALARM,
} from '@extension/constants';
import { PASSWORD_LOCK_ALARM } from '@extension/constants';

// enums
import { AppTypeEnum } from '@extension/enums';
Expand Down Expand Up @@ -119,9 +115,7 @@ export default class BackgroundEventListener {
const _functionName: string = 'onExtensionClick';
const isInitialized: boolean = await this.privateKeyService.isInitialized();
let mainAppWindows: IAppWindow[];
let mainWindow: Windows.Window;
let registrationAppWindows: IAppWindow[];
let registrationWindow: Windows.Window;

this.logger?.debug(
`${BackgroundEventListener.name}#${_functionName}(): browser extension clicked`
Expand Down Expand Up @@ -156,18 +150,9 @@ export default class BackgroundEventListener {
await this.storageManager.removeAll();

// if there is no registration app window up, we can open a new one
registrationWindow = await browser.windows.create({
height: DEFAULT_POPUP_HEIGHT,
type: 'popup',
url: 'registration-app.html',
width: DEFAULT_POPUP_WIDTH,
await this.appWindowManagerService.createWindow({
type: AppTypeEnum.RegistrationApp,
});

// save the registration window to storage
return await this.appWindowManagerService.saveByBrowserWindowAndType(
registrationWindow,
AppTypeEnum.RegistrationApp
);
}

mainAppWindows = await this.appWindowManagerService.getByType(
Expand All @@ -192,18 +177,9 @@ export default class BackgroundEventListener {
);

// if there is no main app window up, we can open the app
mainWindow = await browser.windows.create({
height: DEFAULT_POPUP_HEIGHT,
type: 'popup',
url: 'main-app.html',
width: DEFAULT_POPUP_WIDTH,
await this.appWindowManagerService.createWindow({
type: AppTypeEnum.MainApp,
});

// save the main app window to storage
await this.appWindowManagerService.saveByBrowserWindowAndType(
mainWindow,
AppTypeEnum.MainApp
);
}

public async onFocusChanged(windowId: number): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ import { networks } from '@extension/config';

// constants
import { HOST, ICON_URI } from '@common/constants';
import {
DEFAULT_POPUP_HEIGHT,
DEFAULT_POPUP_WIDTH,
} from '@extension/constants';

// enums
import {
Expand Down Expand Up @@ -75,7 +71,6 @@ import type {
IInternalRequestMessage,
INetwork,
ISession,
ISettings,
} from '@extension/types';

// utils
Expand Down Expand Up @@ -341,26 +336,16 @@ export default class BackgroundMessageHandler {
await this.appWindowManagerService.getByType(AppTypeEnum.MainApp);
const registrationAppWindows: IAppWindow[] =
await this.appWindowManagerService.getByType(AppTypeEnum.RegistrationApp);
let mainWindow: Windows.Window;

// if there is no main app windows, create a new one
if (mainAppWindows.length <= 0) {
mainWindow = await browser.windows.create({
height: DEFAULT_POPUP_HEIGHT,
type: 'popup',
url: 'main-app.html',
width: DEFAULT_POPUP_WIDTH,
await this.appWindowManagerService.createWindow({
type: AppTypeEnum.MainApp,
...(registrationAppWindows[0] && {
left: registrationAppWindows[0].left,
top: registrationAppWindows[0].top,
}),
});

// save to storage
await this.appWindowManagerService.saveByBrowserWindowAndType(
mainWindow,
AppTypeEnum.MainApp
);
}

// if registration app windows exist remove them
Expand Down Expand Up @@ -602,8 +587,6 @@ export default class BackgroundMessageHandler {
const isInitialized: boolean = await this.privateKeyService.isInitialized();
const mainAppWindows: IAppWindow[] =
await this.appWindowManagerService.getByType(AppTypeEnum.MainApp);
let backgroundWindow: Windows.Window;
let searchParams: URLSearchParams;

// not initialized, ignore it
if (!isInitialized) {
Expand Down Expand Up @@ -635,21 +618,12 @@ export default class BackgroundMessageHandler {
`${BackgroundMessageHandler.name}#${_functionName}(): main app window not open, opening background app window for "${event.type}" event`
);

searchParams = new URLSearchParams({
eventId: encodeURIComponent(event.id), // add the event id to the url search params, so the app knows which event to use
});
backgroundWindow = await browser.windows.create({
height: DEFAULT_POPUP_HEIGHT,
type: 'popup',
url: `background-app.html?${searchParams.toString()}`,
width: DEFAULT_POPUP_WIDTH,
await this.appWindowManagerService.createWindow({
searchParams: new URLSearchParams({
eventId: encodeURIComponent(event.id), // add the event id to the url search params, so the app knows which event to use
}),
type: AppTypeEnum.BackgroundApp,
});

// save to app window storage
await this.appWindowManagerService.saveByBrowserWindowAndType(
backgroundWindow,
AppTypeEnum.BackgroundApp
);
}

private async sendResponse(
Expand Down

0 comments on commit f7b7577

Please sign in to comment.