Skip to content

Commit

Permalink
Merge branch 'main' into setup-page/new-flow
Browse files Browse the repository at this point in the history
  • Loading branch information
sidvishnoi authored Sep 25, 2024
2 parents 0d2011d + 2325cb3 commit a01c5fd
Show file tree
Hide file tree
Showing 17 changed files with 441 additions and 146 deletions.
15 changes: 15 additions & 0 deletions src/background/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// cSpell:ignore newtab, webui, startpage

export const INTERNAL_PAGE_URL_PROTOCOLS = new Set([
'chrome:',
'about:',
'edge:',
]);

export const NEW_TAB_PAGES = [
'about:blank',
'chrome://newtab',
'about:newtab',
'edge://newtab',
'chrome://vivaldi-webui/startpage',
];
16 changes: 15 additions & 1 deletion src/background/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@ import {
Background,
TabEvents,
TabState,
WindowState,
SendToPopup,
EventsService,
Heartbeat,
Deduplicator,
} from './services';
import { createLogger, Logger } from '@/shared/logger';
import { LOG_LEVEL } from '@/shared/defines';
import { tFactory, type Translation } from '@/shared/helpers';
import {
getBrowserName,
tFactory,
type BrowserName,
type Translation,
} from '@/shared/helpers';
import {
MessageManager,
type BackgroundToContentMessage,
Expand All @@ -23,6 +29,7 @@ import {
export interface Cradle {
logger: Logger;
browser: Browser;
browserName: BrowserName;
events: EventsService;
deduplicator: Deduplicator;
storage: StorageService;
Expand All @@ -34,6 +41,7 @@ export interface Cradle {
background: Background;
t: Translation;
tabState: TabState;
windowState: WindowState;
heartbeat: Heartbeat;
}

Expand All @@ -47,6 +55,7 @@ export const configureContainer = () => {
container.register({
logger: asValue(logger),
browser: asValue(browser),
browserName: asValue(getBrowserName(browser, navigator.userAgent)),
t: asValue(tFactory(browser)),
events: asClass(EventsService).singleton(),
deduplicator: asClass(Deduplicator)
Expand Down Expand Up @@ -82,6 +91,11 @@ export const configureContainer = () => {
.inject(() => ({
logger: logger.getLogger('tab-state'),
})),
windowState: asClass(WindowState)
.singleton()
.inject(() => ({
logger: logger.getLogger('window-state'),
})),
heartbeat: asClass(Heartbeat).singleton(),
});

Expand Down
85 changes: 55 additions & 30 deletions src/background/services/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
success,
} from '@/shared/helpers';
import { OpenPaymentsClientError } from '@interledger/open-payments/dist/client/error';
import { getCurrentActiveTab, OPEN_PAYMENTS_ERRORS } from '@/background/utils';
import { getTab, OPEN_PAYMENTS_ERRORS } from '@/background/utils';
import { PERMISSION_HOSTS } from '@/shared/defines';
import type { Cradle } from '@/background/container';

Expand All @@ -22,6 +22,7 @@ export class Background {
private storage: Cradle['storage'];
private logger: Cradle['logger'];
private tabEvents: Cradle['tabEvents'];
private windowState: Cradle['windowState'];
private sendToPopup: Cradle['sendToPopup'];
private events: Cradle['events'];
private heartbeat: Cradle['heartbeat'];
Expand All @@ -33,6 +34,7 @@ export class Background {
storage,
logger,
tabEvents,
windowState,
sendToPopup,
events,
heartbeat,
Expand All @@ -44,6 +46,7 @@ export class Background {
storage,
sendToPopup,
tabEvents,
windowState,
logger,
events,
heartbeat,
Expand Down Expand Up @@ -93,6 +96,10 @@ export class Background {
}

async onStart() {
const activeWindow = await this.browser.windows.getLastFocused();
if (activeWindow.id) {
this.windowState.setCurrentWindowId(activeWindow.id);
}
await this.storage.populate();
await this.checkPermissions();
await this.scheduleResetOutOfFundsState();
Expand All @@ -118,36 +125,49 @@ export class Background {
}

bindWindowHandlers() {
this.browser.windows.onCreated.addListener(
this.windowState.onWindowCreated,
);

this.browser.windows.onRemoved.addListener(
this.windowState.onWindowRemoved,
);

let popupOpen = false;
this.browser.windows.onFocusChanged.addListener(async () => {
const windows = await this.browser.windows.getAll({
windowTypes: ['normal', 'panel', 'popup'],
windowTypes: ['normal'],
});
windows.forEach(async (w) => {
const activeTab = (
await this.browser.tabs.query({ windowId: w.id, active: true })
)[0];
if (!activeTab?.id) return;
if (this.sendToPopup.isPopupOpen) {
this.logger.debug('Popup is open, ignoring focus change');
return;
}
const popupWasOpen = popupOpen;
popupOpen = this.sendToPopup.isPopupOpen;
if (popupWasOpen || popupOpen) {
// This is intentionally called after windows.getAll, to add a little
// delay for popup port to open
this.logger.debug('Popup is open, ignoring focus change');
return;
}
for (const window of windows) {
const windowId = window.id!;

if (w.focused) {
this.logger.debug(
`Trying to resume monetization for window=${w.id}, activeTab=${activeTab.id} (URL: ${activeTab.url})`,
);
void this.monetizationService.resumePaymentSessionsByTabId(
activeTab.id,
const tabIds = await this.windowState.getTabsForCurrentView(windowId);
if (window.focused) {
this.windowState.setCurrentWindowId(windowId);
this.logger.info(
`[focus change] resume monetization for window=${windowId}, tabIds=${JSON.stringify(tabIds)}`,
);
for (const tabId of tabIds) {
await this.monetizationService.resumePaymentSessionsByTabId(tabId);
}
await this.updateVisualIndicatorsForCurrentTab();
} else {
this.logger.debug(
`Trying to pause monetization for window=${w.id}, activeTab=${activeTab.id} (URL: ${activeTab.url})`,
);
void this.monetizationService.stopPaymentSessionsByTabId(
activeTab.id,
this.logger.info(
`[focus change] stop monetization for window=${windowId}, tabIds=${JSON.stringify(tabIds)}`,
);
for (const tabId of tabIds) {
void this.monetizationService.stopPaymentSessionsByTabId(tabId);
}
}
});
}
});
}

Expand All @@ -166,7 +186,11 @@ export class Background {
switch (message.action) {
// region Popup
case 'GET_CONTEXT_DATA':
return success(await this.monetizationService.getPopupData());
return success(
await this.monetizationService.getPopupData(
await this.windowState.getCurrentTab(),
),
);

case 'CONNECT_WALLET':
await this.openPaymentsService.connectWallet(message.payload);
Expand Down Expand Up @@ -221,6 +245,10 @@ export class Background {
await getWalletInformation(message.payload.walletAddressUrl),
);

case 'TAB_FOCUSED':
await this.tabEvents.onFocussedTab(getTab(sender));
return;

case 'START_MONETIZATION':
await this.monetizationService.startPaymentSession(
message.payload,
Expand All @@ -242,9 +270,6 @@ export class Background {
);
return;

case 'IS_WM_ENABLED':
return success(await this.storage.getWMState());

// endregion

default:
Expand All @@ -269,9 +294,9 @@ export class Background {
}

private async updateVisualIndicatorsForCurrentTab() {
const activeTab = await getCurrentActiveTab(this.browser);
const activeTab = await this.windowState.getCurrentTab();
if (activeTab?.id) {
void this.tabEvents.updateVisualIndicators(activeTab.id, activeTab.url);
void this.tabEvents.updateVisualIndicators(activeTab);
}
}

Expand All @@ -288,7 +313,7 @@ export class Background {

this.events.on('monetization.state_update', async (tabId) => {
const tab = await this.browser.tabs.get(tabId);
void this.tabEvents.updateVisualIndicators(tabId, tab?.url);
void this.tabEvents.updateVisualIndicators(tab);
});

this.events.on('storage.balance_update', (balance) =>
Expand Down
1 change: 1 addition & 0 deletions src/background/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export { MonetizationService } from './monetization';
export { Background } from './background';
export { TabEvents } from './tabEvents';
export { TabState } from './tabState';
export { WindowState } from './windowState';
export { SendToPopup } from './sendToPopup';
export { EventsService } from './events';
export { Deduplicator } from './deduplicator';
Expand Down
43 changes: 10 additions & 33 deletions src/background/services/monetization.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import type { Runtime } from 'webextension-polyfill';
import type { Runtime, Tabs } from 'webextension-polyfill';
import {
ResumeMonetizationPayload,
StartMonetizationPayload,
StopMonetizationPayload,
} from '@/shared/messages';
import { PaymentSession } from './paymentSession';
import {
computeRate,
getCurrentActiveTab,
getSender,
getTabId,
} from '../utils';
import { computeRate, getSender, getTabId } from '../utils';
import { isOutOfBalanceError } from './openPayments';
import { isOkState, removeQueryParams } from '@/shared/helpers';
import { ALLOWED_PROTOCOLS } from '@/shared/defines';
import type { AmountValue, PopupStore, Storage } from '@/shared/types';
import type { Cradle } from '../container';

Expand All @@ -25,6 +19,7 @@ export class MonetizationService {
private browser: Cradle['browser'];
private events: Cradle['events'];
private tabState: Cradle['tabState'];
private windowState: Cradle['windowState'];
private message: Cradle['message'];

constructor({
Expand All @@ -35,6 +30,7 @@ export class MonetizationService {
events,
openPaymentsService,
tabState,
windowState,
message,
}: Cradle) {
Object.assign(this, {
Expand All @@ -45,6 +41,7 @@ export class MonetizationService {
browser,
events,
tabState,
windowState,
message,
});

Expand Down Expand Up @@ -236,7 +233,7 @@ export class MonetizationService {
}

async resumePaymentSessionActiveTab() {
const currentTab = await getCurrentActiveTab(this.browser);
const currentTab = await this.windowState.getCurrentTab();
if (!currentTab?.id) return;
await this.resumePaymentSessionsByTabId(currentTab.id);
}
Expand All @@ -253,7 +250,7 @@ export class MonetizationService {
}

async pay(amount: string) {
const tab = await getCurrentActiveTab(this.browser);
const tab = await this.windowState.getCurrentTab();
if (!tab || !tab.id) {
throw new Error('Unexpected error: could not find active tab.');
}
Expand Down Expand Up @@ -316,7 +313,7 @@ export class MonetizationService {
const tabIds = this.tabState.getAllTabs();

// Move the current active tab to the front of the array
const currentTab = await getCurrentActiveTab(this.browser);
const currentTab = await this.windowState.getCurrentTab();
if (currentTab?.id) {
const idx = tabIds.indexOf(currentTab.id);
if (idx !== -1) {
Expand Down Expand Up @@ -371,7 +368,7 @@ export class MonetizationService {
this.logger.debug(`All payment sessions stopped.`);
}

async getPopupData(): Promise<PopupStore> {
async getPopupData(tab: Pick<Tabs.Tab, 'id' | 'url'>): Promise<PopupStore> {
const storedData = await this.storage.get([
'enabled',
'connected',
Expand All @@ -385,37 +382,17 @@ export class MonetizationService {
'publicKey',
]);
const balance = await this.storage.getBalance();
const tab = await getCurrentActiveTab(this.browser);

const { oneTimeGrant, recurringGrant, ...dataFromStorage } = storedData;

let url;
if (tab && tab.url) {
try {
const tabUrl = new URL(tab.url);
if (ALLOWED_PROTOCOLS.includes(tabUrl.protocol)) {
// Do not include search params
url = `${tabUrl.origin}${tabUrl.pathname}`;
}
} catch {
// noop
}
}
const isSiteMonetized = this.tabState.isTabMonetized(tab.id!);
const hasAllSessionsInvalid = this.tabState.tabHasAllSessionsInvalid(
tab.id!,
);

return {
...dataFromStorage,
balance: balance.total.toString(),
url,
tab: this.tabState.getPopupTabData(tab),
grants: {
oneTime: oneTimeGrant?.amount,
recurring: recurringGrant?.amount,
},
isSiteMonetized,
hasAllSessionsInvalid,
};
}

Expand Down
Loading

0 comments on commit a01c5fd

Please sign in to comment.