From 7dad49b24fe77a97455dabd6183992ef939580d9 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:54:53 +0530 Subject: [PATCH 01/12] refactor(content): move MessageManager to container Update MessageManager constructor to support awilix PROXY Co-authored-by: Radu-Cristian Popa --- src/background/lib/messages.ts | 4 +- src/content/container.ts | 6 ++ src/content/lib/messages.ts | 55 ---------------- src/content/messages.ts | 1 + src/content/services/frameManager.ts | 23 ++++--- .../services/monetizationTagManager.ts | 66 +++++++++++++------ src/popup/lib/messages.ts | 2 +- src/shared/messages.ts | 9 ++- 8 files changed, 79 insertions(+), 87 deletions(-) delete mode 100644 src/content/lib/messages.ts diff --git a/src/background/lib/messages.ts b/src/background/lib/messages.ts index c5183eb3..59a3301e 100644 --- a/src/background/lib/messages.ts +++ b/src/background/lib/messages.ts @@ -6,7 +6,9 @@ import { MessageManager } from '@/shared/messages' -export const message = new MessageManager(browser) +export const message = new MessageManager({ + browser +}) interface SendMonetizationEventParams { tabId: number diff --git a/src/content/container.ts b/src/content/container.ts index 0362b86c..3aad58d0 100644 --- a/src/content/container.ts +++ b/src/content/container.ts @@ -5,12 +5,17 @@ import { ContentScript } from './services/contentScript' import { MonetizationTagManager } from './services/monetizationTagManager' import { LOG_LEVEL } from '@/shared/defines' import { FrameManager } from './services/frameManager' +import { + type ContentToBackgroundMessage, + MessageManager +} from '@/shared/messages' export interface Cradle { logger: Logger browser: Browser document: Document window: Window + message: MessageManager monetizationTagManager: MonetizationTagManager frameManager: FrameManager contentScript: ContentScript @@ -28,6 +33,7 @@ export const configureContainer = () => { browser: asValue(browser), document: asValue(document), window: asValue(window), + message: asClass(MessageManager).singleton(), frameManager: asClass(FrameManager) .singleton() .inject(() => ({ diff --git a/src/content/lib/messages.ts b/src/content/lib/messages.ts deleted file mode 100644 index f40284f4..00000000 --- a/src/content/lib/messages.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { - MessageManager, - ContentToBackgroundAction, - ContentToBackgroundActionPayload, - type ContentToBackgroundMessage -} from '@/shared/messages' -import { WalletAddress } from '@interledger/open-payments/dist/types' -import browser from 'webextension-polyfill' - -export const message = new MessageManager(browser) - -export const checkWalletAddressUrlCall = async ( - payload: ContentToBackgroundActionPayload[ContentToBackgroundAction.CHECK_WALLET_ADDRESS_URL] -) => { - return await message.send({ - action: ContentToBackgroundAction.CHECK_WALLET_ADDRESS_URL, - payload - }) -} - -export const startMonetization = async ( - payload: ContentToBackgroundActionPayload[ContentToBackgroundAction.START_MONETIZATION] -) => { - if (!payload.length) return - return await message.send({ - action: ContentToBackgroundAction.START_MONETIZATION, - payload - }) -} - -export const stopMonetization = async ( - payload: ContentToBackgroundActionPayload[ContentToBackgroundAction.STOP_MONETIZATION] -) => { - if (!payload.length) return - return await message.send({ - action: ContentToBackgroundAction.STOP_MONETIZATION, - payload - }) -} - -export const resumeMonetization = async ( - payload: ContentToBackgroundActionPayload[ContentToBackgroundAction.RESUME_MONETIZATION] -) => { - if (!payload.length) return - return await message.send({ - action: ContentToBackgroundAction.RESUME_MONETIZATION, - payload - }) -} - -export const isWMEnabled = async () => { - return await message.send({ - action: ContentToBackgroundAction.IS_WM_ENABLED - }) -} diff --git a/src/content/messages.ts b/src/content/messages.ts index 1d745383..dac8f68e 100644 --- a/src/content/messages.ts +++ b/src/content/messages.ts @@ -1,3 +1,4 @@ +// TODO: Move to shared export enum ContentToContentAction { INITIALIZE_IFRAME = 'INITIALIZE_IFRAME', IS_MONETIZATION_ALLOWED_ON_START = 'IS_MONETIZATION_ALLOWED_ON_START', diff --git a/src/content/services/frameManager.ts b/src/content/services/frameManager.ts index f2cb8429..330302b1 100644 --- a/src/content/services/frameManager.ts +++ b/src/content/services/frameManager.ts @@ -1,9 +1,9 @@ -import { stopMonetization } from '../lib/messages' import { ContentToContentAction } from '../messages' -import type { - ResumeMonetizationPayload, - StartMonetizationPayload, - StopMonetizationPayload +import { + ContentToBackgroundAction, + type ResumeMonetizationPayload, + type StartMonetizationPayload, + type StopMonetizationPayload } from '@/shared/messages' import type { Cradle } from '@/content/container' @@ -11,6 +11,7 @@ export class FrameManager { private window: Cradle['window'] private document: Cradle['document'] private logger: Cradle['logger'] + private message: Cradle['message'] private documentObserver: MutationObserver private frameAllowAttrObserver: MutationObserver @@ -19,11 +20,12 @@ export class FrameManager { { frameId: string | null; requestIds: string[] } >() - constructor({ window, document, logger }: Cradle) { + constructor({ window, document, logger, message }: Cradle) { Object.assign(this, { window, document, - logger + logger, + message }) this.documentObserver = new MutationObserver((records) => @@ -107,7 +109,12 @@ export class FrameManager { requestId, intent: 'remove' })) || [] - stopMonetization(stopMonetizationTags) + if (stopMonetizationTags.length) { + this.message.send({ + action: ContentToBackgroundAction.STOP_MONETIZATION, + payload: stopMonetizationTags + }) + } this.frames.delete(frame) } diff --git a/src/content/services/monetizationTagManager.ts b/src/content/services/monetizationTagManager.ts index 084e4bdd..ea3493cb 100644 --- a/src/content/services/monetizationTagManager.ts +++ b/src/content/services/monetizationTagManager.ts @@ -4,18 +4,12 @@ import type { MonetizationTagDetails } from '../types' import type { WalletAddress } from '@interledger/open-payments/dist/types' import { checkWalletAddressUrlFormat } from '../utils' import { - checkWalletAddressUrlCall, - isWMEnabled, - resumeMonetization, - startMonetization, - stopMonetization -} from '../lib/messages' -import type { - EmitToggleWMPayload, - MonetizationEventPayload, - ResumeMonetizationPayload, - StartMonetizationPayload, - StopMonetizationPayload + ContentToBackgroundAction, + type EmitToggleWMPayload, + type MonetizationEventPayload, + type ResumeMonetizationPayload, + type StartMonetizationPayload, + type StopMonetizationPayload } from '@/shared/messages' import { ContentToContentAction } from '../messages' import type { Cradle } from '@/content/container' @@ -31,6 +25,7 @@ export class MonetizationTagManager extends EventEmitter { private window: Cradle['window'] private document: Cradle['document'] private logger: Cradle['logger'] + private message: Cradle['message'] private isTopFrame: boolean private isFirstLevelFrame: boolean @@ -39,12 +34,13 @@ export class MonetizationTagManager extends EventEmitter { private id: string private monetizationTags = new Map() - constructor({ window, document, logger }: Cradle) { + constructor({ window, document, logger, message }: Cradle) { super() Object.assign(this, { window, document, - logger + logger, + message }) this.documentObserver = new MutationObserver((records) => @@ -94,7 +90,9 @@ export class MonetizationTagManager extends EventEmitter { } private async resumeAllMonetization() { - const response = await isWMEnabled() + const response = await this.message.send({ + action: ContentToBackgroundAction.IS_WM_ENABLED + }) if (response.success && response.payload) { const resumeMonetizationTags: ResumeMonetizationPayload[] = [] @@ -463,7 +461,12 @@ export class MonetizationTagManager extends EventEmitter { if (!tags.length) return if (this.isTopFrame) { - startMonetization(tags) + if (tags.length) { + void this.message.send({ + action: ContentToBackgroundAction.START_MONETIZATION, + payload: tags + }) + } } else if (this.isFirstLevelFrame) { this.window.parent.postMessage( { @@ -478,12 +481,20 @@ export class MonetizationTagManager extends EventEmitter { private async sendStopMonetization(tags: StopMonetizationPayload[]) { if (!tags.length) return - await stopMonetization(tags) + await this.message.send({ + action: ContentToBackgroundAction.STOP_MONETIZATION, + payload: tags + }) } private sendResumeMonetization(tags: ResumeMonetizationPayload[]) { if (this.isTopFrame) { - resumeMonetization(tags) + if (tags.length) { + void this.message.send({ + action: ContentToBackgroundAction.RESUME_MONETIZATION, + payload: tags + }) + } } else if (this.isFirstLevelFrame) { this.window.parent.postMessage( { @@ -514,7 +525,10 @@ export class MonetizationTagManager extends EventEmitter { const walletAddressUrl = tag.href.trim() try { checkWalletAddressUrlFormat(walletAddressUrl) - const response = await checkWalletAddressUrlCall({ walletAddressUrl }) + const response = await this.message.send({ + action: ContentToBackgroundAction.CHECK_WALLET_ADDRESS_URL, + payload: { walletAddressUrl } + }) if (response.success === false) { throw new Error( @@ -539,10 +553,20 @@ export class MonetizationTagManager extends EventEmitter { switch (message) { case ContentToContentAction.START_MONETIZATION: - startMonetization(payload) + if (payload.length) { + void this.message.send({ + action: ContentToBackgroundAction.START_MONETIZATION, + payload + }) + } return case ContentToContentAction.RESUME_MONETIZATION: - resumeMonetization(payload) + if (payload.length) { + void this.message.send({ + action: ContentToBackgroundAction.RESUME_MONETIZATION, + payload + }) + } return default: return diff --git a/src/popup/lib/messages.ts b/src/popup/lib/messages.ts index f2c4cf7b..2c7d8d0f 100644 --- a/src/popup/lib/messages.ts +++ b/src/popup/lib/messages.ts @@ -10,7 +10,7 @@ import { PopupState } from '@/popup/lib/context' export const message = new MessageManager< PopupToBackgroundMessage | BackgroundToContentMessage ->(browser) +>({ browser }) export const getContextData = async () => { return await message.send({ diff --git a/src/shared/messages.ts b/src/shared/messages.ts index 440a0bec..151f9bff 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -168,11 +168,18 @@ export type BackgroundToContentBackgroundMessage = { > }[BackgroundToContentAction] +interface Cradle { + browser: Browser +} + export type ToContentMessage = BackgroundToContentBackgroundMessage // #endregion export class MessageManager { - constructor(private browser: Browser) {} + private browser: Cradle['browser'] + constructor({ browser }: Cradle) { + this.browser = browser + } async send( message: TMessages From ce42400139534a2ede31cc178dc94d840e662a61 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:14:49 +0530 Subject: [PATCH 02/12] use message.send directly everywhere Co-authored-by: Radu-Cristian Popa --- src/background/container.ts | 6 + src/background/lib/messages.ts | 37 ---- src/background/services/background.ts | 32 ++- src/background/services/monetization.ts | 13 +- src/background/services/paymentSession.ts | 68 ++++--- src/content/container.ts | 2 +- src/content/services/contentScript.ts | 9 +- src/content/services/frameManager.ts | 14 +- .../services/monetizationTagManager.ts | 47 ++--- src/popup/components/ConnectWalletForm.tsx | 4 +- src/popup/components/ErrorKeyRevoked.tsx | 4 +- src/popup/components/OutOfFunds.tsx | 2 +- src/popup/components/PayWebsiteForm.tsx | 4 +- src/popup/components/WalletInformation.tsx | 4 +- src/popup/lib/context.tsx | 4 +- src/popup/lib/messages.ts | 69 +------ src/popup/pages/ErrorKeyRevoked.tsx | 6 +- src/popup/pages/Home.tsx | 11 +- src/popup/pages/OutOfFunds_AddFunds.tsx | 4 +- src/shared/messages.ts | 191 ++++++++++-------- 20 files changed, 222 insertions(+), 309 deletions(-) delete mode 100644 src/background/lib/messages.ts diff --git a/src/background/container.ts b/src/background/container.ts index 3fa7ddd3..f88c001e 100644 --- a/src/background/container.ts +++ b/src/background/container.ts @@ -15,6 +15,10 @@ import { import { createLogger, Logger } from '@/shared/logger' import { LOG_LEVEL } from '@/shared/defines' import { tFactory, type Translation } from '@/shared/helpers' +import { + MessageManager, + type BackgroundToContentMessage +} from '@/shared/messages' export interface Cradle { logger: Logger @@ -24,6 +28,7 @@ export interface Cradle { storage: StorageService openPaymentsService: OpenPaymentsService monetizationService: MonetizationService + message: MessageManager sendToPopup: SendToPopup tabEvents: TabEvents background: Background @@ -64,6 +69,7 @@ export const configureContainer = () => { .inject(() => ({ logger: logger.getLogger('monetization') })), + message: asClass(MessageManager).singleton(), tabEvents: asClass(TabEvents).singleton(), sendToPopup: asClass(SendToPopup).singleton(), background: asClass(Background) diff --git a/src/background/lib/messages.ts b/src/background/lib/messages.ts deleted file mode 100644 index 59a3301e..00000000 --- a/src/background/lib/messages.ts +++ /dev/null @@ -1,37 +0,0 @@ -import browser from 'webextension-polyfill' -import { - BackgroundToContentMessage, - BackgroundToContentAction, - BackgroundToContentActionPayload, - MessageManager -} from '@/shared/messages' - -export const message = new MessageManager({ - browser -}) - -interface SendMonetizationEventParams { - tabId: number - frameId: number - payload: BackgroundToContentActionPayload[BackgroundToContentAction.MONETIZATION_EVENT] -} - -export const sendMonetizationEvent = async ({ - tabId, - frameId, - payload -}: SendMonetizationEventParams) => { - return await message.sendToTab(tabId, frameId, { - action: BackgroundToContentAction.MONETIZATION_EVENT, - payload - }) -} - -export const emitToggleWM = async ( - payload: BackgroundToContentActionPayload[BackgroundToContentAction.EMIT_TOGGLE_WM] -) => { - return await message.sendToActiveTab({ - action: BackgroundToContentAction.EMIT_TOGGLE_WM, - payload - }) -} diff --git a/src/background/services/background.ts b/src/background/services/background.ts index 433cd8dc..050a65e1 100644 --- a/src/background/services/background.ts +++ b/src/background/services/background.ts @@ -1,9 +1,5 @@ import type { Browser } from 'webextension-polyfill' -import { - type ToBackgroundMessage, - PopupToBackgroundAction, - ContentToBackgroundAction -} from '@/shared/messages' +import type { ToBackgroundMessage } from '@/shared/messages' import { failure, getNextOccurrence, @@ -135,24 +131,24 @@ export class Background { this.logger.debug('Received message', message) try { switch (message.action) { - case PopupToBackgroundAction.GET_CONTEXT_DATA: + case 'GET_CONTEXT_DATA': return success(await this.monetizationService.getPopupData()) - case PopupToBackgroundAction.CONNECT_WALLET: + case 'CONNECT_WALLET': await this.openPaymentsService.connectWallet(message.payload) if (message.payload.recurring) { this.scheduleResetOutOfFundsState() } return - case PopupToBackgroundAction.RECONNECT_WALLET: { + case 'RECONNECT_WALLET': { await this.openPaymentsService.reconnectWallet() await this.monetizationService.resumePaymentSessionActiveTab() await this.updateVisualIndicatorsForCurrentTab() return success(undefined) } - case PopupToBackgroundAction.ADD_FUNDS: + case 'ADD_FUNDS': await this.openPaymentsService.addFunds(message.payload) await this.browser.alarms.clear(ALARM_RESET_OUT_OF_FUNDS) if (message.payload.recurring) { @@ -160,56 +156,56 @@ export class Background { } return - case PopupToBackgroundAction.DISCONNECT_WALLET: + case 'DISCONNECT_WALLET': await this.openPaymentsService.disconnectWallet() await this.browser.alarms.clear(ALARM_RESET_OUT_OF_FUNDS) await this.updateVisualIndicatorsForCurrentTab() this.sendToPopup.send('SET_STATE', { state: {}, prevState: {} }) return - case PopupToBackgroundAction.TOGGLE_WM: { + case 'TOGGLE_WM': { await this.monetizationService.toggleWM() await this.updateVisualIndicatorsForCurrentTab() return } - case PopupToBackgroundAction.PAY_WEBSITE: + case 'PAY_WEBSITE': return success( await this.monetizationService.pay(message.payload.amount) ) - case ContentToBackgroundAction.CHECK_WALLET_ADDRESS_URL: + case 'CHECK_WALLET_ADDRESS_URL': return success( await getWalletInformation(message.payload.walletAddressUrl) ) - case ContentToBackgroundAction.START_MONETIZATION: + case 'START_MONETIZATION': await this.monetizationService.startPaymentSession( message.payload, sender ) return - case ContentToBackgroundAction.STOP_MONETIZATION: + case 'STOP_MONETIZATION': await this.monetizationService.stopPaymentSession( message.payload, sender ) return - case ContentToBackgroundAction.RESUME_MONETIZATION: + case 'RESUME_MONETIZATION': await this.monetizationService.resumePaymentSession( message.payload, sender ) return - case PopupToBackgroundAction.UPDATE_RATE_OF_PAY: + case 'UPDATE_RATE_OF_PAY': return success( await this.storage.updateRate(message.payload.rateOfPay) ) - case ContentToBackgroundAction.IS_WM_ENABLED: + case 'IS_WM_ENABLED': return success(await this.storage.getWMState()) default: diff --git a/src/background/services/monetization.ts b/src/background/services/monetization.ts index 6b268986..4b4e6537 100644 --- a/src/background/services/monetization.ts +++ b/src/background/services/monetization.ts @@ -5,7 +5,6 @@ import { StopMonetizationPayload } from '@/shared/messages' import { PaymentSession } from './paymentSession' -import { emitToggleWM } from '../lib/messages' import { computeRate, getCurrentActiveTab, getSender, getTabId } from '../utils' import { isOutOfBalanceError } from './openPayments' import { isOkState, removeQueryParams } from '@/shared/helpers' @@ -21,6 +20,7 @@ export class MonetizationService { private browser: Cradle['browser'] private events: Cradle['events'] private tabState: Cradle['tabState'] + private message: Cradle['message'] constructor({ logger, @@ -29,7 +29,8 @@ export class MonetizationService { storage, events, openPaymentsService, - tabState + tabState, + message }: Cradle) { Object.assign(this, { logger, @@ -38,7 +39,8 @@ export class MonetizationService { storage, browser, events, - tabState + tabState, + message }) this.registerEventListeners() @@ -98,7 +100,8 @@ export class MonetizationService { this.events, this.tabState, removeQueryParams(url!), - this.logger + this.logger, + this.message ) sessions.set(requestId, session) @@ -236,7 +239,7 @@ export class MonetizationService { async toggleWM() { const { enabled } = await this.storage.get(['enabled']) await this.storage.set({ enabled: !enabled }) - emitToggleWM({ enabled: !enabled }) + await this.message.sendToActiveTab('EMIT_TOGGLE_WM', { enabled: !enabled }) } async pay(amount: string) { diff --git a/src/background/services/paymentSession.ts b/src/background/services/paymentSession.ts index b4ec6fe1..dbc26f22 100644 --- a/src/background/services/paymentSession.ts +++ b/src/background/services/paymentSession.ts @@ -4,7 +4,6 @@ import { type OutgoingPayment, type WalletAddress } from '@interledger/open-payments/dist/types' -import { sendMonetizationEvent } from '../lib/messages' import { bigIntMax, convert } from '@/shared/helpers' import { transformBalance } from '@/popup/lib/utils' import { @@ -16,7 +15,12 @@ import { } from './openPayments' import { getNextSendableAmount } from '@/background/utils' import type { EventsService, OpenPaymentsService, TabState } from '.' -import type { MonetizationEventDetails } from '@/shared/messages' +import type { + BackgroundToContentMessage, + MessageManager, + MonetizationEventDetails, + MonetizationEventPayload +} from '@/shared/messages' import type { AmountValue } from '@/shared/types' import type { Logger } from '@/shared/logger' @@ -54,7 +58,8 @@ export class PaymentSession { private events: EventsService, private tabState: TabState, private url: string, - private logger: Logger + private logger: Logger, + private message: MessageManager ) {} async adjustAmount(rate: AmountValue): Promise { @@ -223,13 +228,9 @@ export class PaymentSession { this.debug(`Overpaying: waitTime=${waitTime}`) if (monetizationEvent && source !== 'tab-change') { - sendMonetizationEvent({ - tabId: this.tabId, - frameId: this.frameId, - payload: { - requestId: this.requestId, - details: monetizationEvent - } + this.sendMonetizationEvent({ + requestId: this.requestId, + details: monetizationEvent }) } @@ -278,6 +279,15 @@ export class PaymentSession { } } + private async sendMonetizationEvent(payload: MonetizationEventPayload) { + await this.message.sendToTab( + this.tabId, + this.frameId, + 'MONETIZATION_EVENT', + payload + ) + } + private get canContinuePayment() { return this.active && !this.isDisabled && !this.isInvalid } @@ -392,22 +402,18 @@ export class PaymentSession { if (outgoingPayment) { const { receiveAmount, receiver: incomingPayment } = outgoingPayment - sendMonetizationEvent({ - tabId: this.tabId, - frameId: this.frameId, - payload: { - requestId: this.requestId, - details: { - amountSent: { - currency: receiveAmount.assetCode, - value: transformBalance( - receiveAmount.value, - receiveAmount.assetScale - ) - }, - incomingPayment, - paymentPointer: this.receiver.id - } + this.sendMonetizationEvent({ + requestId: this.requestId, + details: { + amountSent: { + currency: receiveAmount.assetCode, + value: transformBalance( + receiveAmount.value, + receiveAmount.assetScale + ) + }, + incomingPayment, + paymentPointer: this.receiver.id } }) } @@ -439,13 +445,9 @@ export class PaymentSession { paymentPointer: this.receiver.id } - sendMonetizationEvent({ - tabId: this.tabId, - frameId: this.frameId, - payload: { - requestId: this.requestId, - details: monetizationEventDetails - } + this.sendMonetizationEvent({ + requestId: this.requestId, + details: monetizationEventDetails }) // TO DO: find a better source of truth for deciding if overpaying is applicable diff --git a/src/content/container.ts b/src/content/container.ts index 3aad58d0..069971f0 100644 --- a/src/content/container.ts +++ b/src/content/container.ts @@ -33,7 +33,7 @@ export const configureContainer = () => { browser: asValue(browser), document: asValue(document), window: asValue(window), - message: asClass(MessageManager).singleton(), + message: asClass(MessageManager).singleton(), frameManager: asClass(FrameManager) .singleton() .inject(() => ({ diff --git a/src/content/services/contentScript.ts b/src/content/services/contentScript.ts index 3866eabf..de615fb2 100644 --- a/src/content/services/contentScript.ts +++ b/src/content/services/contentScript.ts @@ -1,7 +1,4 @@ -import { - BackgroundToContentAction, - type ToContentMessage -} from '@/shared/messages' +import type { ToContentMessage } from '@/shared/messages' import { failure } from '@/shared/helpers' import type { Cradle } from '@/content/container' @@ -52,13 +49,13 @@ export class ContentScript { async (message: ToContentMessage) => { try { switch (message.action) { - case BackgroundToContentAction.MONETIZATION_EVENT: + case 'MONETIZATION_EVENT': this.monetizationTagManager.dispatchMonetizationEvent( message.payload ) return - case BackgroundToContentAction.EMIT_TOGGLE_WM: + case 'EMIT_TOGGLE_WM': this.monetizationTagManager.toggleWM(message.payload) return diff --git a/src/content/services/frameManager.ts b/src/content/services/frameManager.ts index 330302b1..d9870370 100644 --- a/src/content/services/frameManager.ts +++ b/src/content/services/frameManager.ts @@ -1,9 +1,8 @@ import { ContentToContentAction } from '../messages' -import { - ContentToBackgroundAction, - type ResumeMonetizationPayload, - type StartMonetizationPayload, - type StopMonetizationPayload +import type { + ResumeMonetizationPayload, + StartMonetizationPayload, + StopMonetizationPayload } from '@/shared/messages' import type { Cradle } from '@/content/container' @@ -110,10 +109,7 @@ export class FrameManager { intent: 'remove' })) || [] if (stopMonetizationTags.length) { - this.message.send({ - action: ContentToBackgroundAction.STOP_MONETIZATION, - payload: stopMonetizationTags - }) + this.message.send('STOP_MONETIZATION', stopMonetizationTags) } this.frames.delete(frame) diff --git a/src/content/services/monetizationTagManager.ts b/src/content/services/monetizationTagManager.ts index ea3493cb..197469ea 100644 --- a/src/content/services/monetizationTagManager.ts +++ b/src/content/services/monetizationTagManager.ts @@ -3,13 +3,12 @@ import { mozClone } from '../utils' import type { MonetizationTagDetails } from '../types' import type { WalletAddress } from '@interledger/open-payments/dist/types' import { checkWalletAddressUrlFormat } from '../utils' -import { - ContentToBackgroundAction, - type EmitToggleWMPayload, - type MonetizationEventPayload, - type ResumeMonetizationPayload, - type StartMonetizationPayload, - type StopMonetizationPayload +import type { + EmitToggleWMPayload, + MonetizationEventPayload, + ResumeMonetizationPayload, + StartMonetizationPayload, + StopMonetizationPayload } from '@/shared/messages' import { ContentToContentAction } from '../messages' import type { Cradle } from '@/content/container' @@ -90,9 +89,7 @@ export class MonetizationTagManager extends EventEmitter { } private async resumeAllMonetization() { - const response = await this.message.send({ - action: ContentToBackgroundAction.IS_WM_ENABLED - }) + const response = await this.message.send('IS_WM_ENABLED', undefined) if (response.success && response.payload) { const resumeMonetizationTags: ResumeMonetizationPayload[] = [] @@ -462,10 +459,7 @@ export class MonetizationTagManager extends EventEmitter { if (this.isTopFrame) { if (tags.length) { - void this.message.send({ - action: ContentToBackgroundAction.START_MONETIZATION, - payload: tags - }) + void this.message.send('START_MONETIZATION', tags) } } else if (this.isFirstLevelFrame) { this.window.parent.postMessage( @@ -481,19 +475,13 @@ export class MonetizationTagManager extends EventEmitter { private async sendStopMonetization(tags: StopMonetizationPayload[]) { if (!tags.length) return - await this.message.send({ - action: ContentToBackgroundAction.STOP_MONETIZATION, - payload: tags - }) + await this.message.send('STOP_MONETIZATION', tags) } private sendResumeMonetization(tags: ResumeMonetizationPayload[]) { if (this.isTopFrame) { if (tags.length) { - void this.message.send({ - action: ContentToBackgroundAction.RESUME_MONETIZATION, - payload: tags - }) + void this.message.send('RESUME_MONETIZATION', tags) } } else if (this.isFirstLevelFrame) { this.window.parent.postMessage( @@ -525,9 +513,8 @@ export class MonetizationTagManager extends EventEmitter { const walletAddressUrl = tag.href.trim() try { checkWalletAddressUrlFormat(walletAddressUrl) - const response = await this.message.send({ - action: ContentToBackgroundAction.CHECK_WALLET_ADDRESS_URL, - payload: { walletAddressUrl } + const response = await this.message.send('CHECK_WALLET_ADDRESS_URL', { + walletAddressUrl }) if (response.success === false) { @@ -554,18 +541,12 @@ export class MonetizationTagManager extends EventEmitter { switch (message) { case ContentToContentAction.START_MONETIZATION: if (payload.length) { - void this.message.send({ - action: ContentToBackgroundAction.START_MONETIZATION, - payload - }) + void this.message.send('START_MONETIZATION', payload) } return case ContentToContentAction.RESUME_MONETIZATION: if (payload.length) { - void this.message.send({ - action: ContentToBackgroundAction.RESUME_MONETIZATION, - payload - }) + void this.message.send('RESUME_MONETIZATION', payload) } return default: diff --git a/src/popup/components/ConnectWalletForm.tsx b/src/popup/components/ConnectWalletForm.tsx index c825d0bd..45cb55ba 100644 --- a/src/popup/components/ConnectWalletForm.tsx +++ b/src/popup/components/ConnectWalletForm.tsx @@ -4,7 +4,7 @@ import { Input } from '@/popup/components/ui/Input' import { Label } from '@/popup/components/ui/Label' import { Switch } from '@/popup/components/ui/Switch' import { Code } from '@/popup/components/ui/Code' -import { connectWallet } from '@/popup/lib/messages' +import { message } from '@/popup/lib/messages' import { debounceSync, getWalletInformation } from '@/shared/helpers' import { charIsNumber, @@ -107,7 +107,7 @@ export const ConnectWalletForm = ({ publicKey }: ConnectWalletFormProps) => { return (
{ - const response = await connectWallet({ + const response = await message.send('CONNECT_WALLET', { ...data, walletAddressUrl: toWalletAddressUrl(data.walletAddressUrl) }) diff --git a/src/popup/components/ErrorKeyRevoked.tsx b/src/popup/components/ErrorKeyRevoked.tsx index 3d83ab2c..b16a920c 100644 --- a/src/popup/components/ErrorKeyRevoked.tsx +++ b/src/popup/components/ErrorKeyRevoked.tsx @@ -11,8 +11,8 @@ import type { Response } from '@/shared/messages' interface Props { info: Pick - disconnectWallet: () => Promise - reconnectWallet: () => Promise + disconnectWallet: () => Promise> + reconnectWallet: () => Promise> onReconnect?: () => void onDisconnect?: () => void } diff --git a/src/popup/components/OutOfFunds.tsx b/src/popup/components/OutOfFunds.tsx index ca7367bd..a7be47f7 100644 --- a/src/popup/components/OutOfFunds.tsx +++ b/src/popup/components/OutOfFunds.tsx @@ -68,7 +68,7 @@ interface AddFundsProps { info: Pick recurring: boolean defaultAmount: AmountValue - requestAddFunds: (details: AddFundsPayload) => Promise + requestAddFunds: (details: AddFundsPayload) => Promise> } export function AddFunds({ diff --git a/src/popup/components/PayWebsiteForm.tsx b/src/popup/components/PayWebsiteForm.tsx index 993221ec..d4c08848 100644 --- a/src/popup/components/PayWebsiteForm.tsx +++ b/src/popup/components/PayWebsiteForm.tsx @@ -1,7 +1,7 @@ import { Button } from '@/popup/components/ui/Button' import { Input } from '@/popup/components/ui/Input' import { PopupStateContext } from '@/popup/lib/context' -import { payWebsite } from '@/popup/lib/messages' +import { message } from '@/popup/lib/messages' import { getCurrencySymbol, charIsNumber, @@ -44,7 +44,7 @@ export const PayWebsiteForm = () => { setButtonState('loading') - const response = await payWebsite(data) + const response = await message.send('PAY_WEBSITE', { amount: data.amount }) if (!response.success) { setButtonState('idle') diff --git a/src/popup/components/WalletInformation.tsx b/src/popup/components/WalletInformation.tsx index cb1cde07..3c6dcfce 100644 --- a/src/popup/components/WalletInformation.tsx +++ b/src/popup/components/WalletInformation.tsx @@ -4,7 +4,7 @@ import React from 'react' import { Code } from '@/popup/components/ui/Code' import { PopupStore } from '@/shared/types' import { Button } from '@/popup/components/ui/Button' -import { disconnectWallet } from '@/popup/lib/messages' +import { message } from '@/popup/lib/messages' import { useForm } from 'react-hook-form' interface WalletInformationProps { @@ -36,7 +36,7 @@ export const WalletInformation = ({ info }: WalletInformationProps) => { {/* TODO: Improve error handling */} { - await disconnectWallet() + await message.send('DISCONNECT_WALLET', undefined) window.location.reload() })} > diff --git a/src/popup/lib/context.tsx b/src/popup/lib/context.tsx index daeecdb1..c389e3b3 100644 --- a/src/popup/lib/context.tsx +++ b/src/popup/lib/context.tsx @@ -1,6 +1,6 @@ import React, { type PropsWithChildren } from 'react' import type { Browser } from 'webextension-polyfill' -import { getContextData } from '@/popup/lib/messages' +import { message } from '@/popup/lib/messages' import { tFactory, type Translation } from '@/shared/helpers' import type { DeepNonNullable, PopupStore } from '@/shared/types' import { @@ -108,7 +108,7 @@ export function PopupContextProvider({ children }: PopupContextProviderProps) { React.useEffect(() => { async function get() { - const response = await getContextData() + const response = await message.send('GET_CONTEXT_DATA', undefined) if (response.success) { dispatch({ type: ReducerActionType.SET_DATA, data: response.payload }) diff --git a/src/popup/lib/messages.ts b/src/popup/lib/messages.ts index 2c7d8d0f..df496814 100644 --- a/src/popup/lib/messages.ts +++ b/src/popup/lib/messages.ts @@ -1,74 +1,7 @@ import { - BackgroundToContentMessage, MessageManager, - PopupToBackgroundAction, - PopupToBackgroundActionPayload, type PopupToBackgroundMessage } from '@/shared/messages' import browser from 'webextension-polyfill' -import { PopupState } from '@/popup/lib/context' -export const message = new MessageManager< - PopupToBackgroundMessage | BackgroundToContentMessage ->({ browser }) - -export const getContextData = async () => { - return await message.send({ - action: PopupToBackgroundAction.GET_CONTEXT_DATA - }) -} - -// TBD: Save error message in storage and to discuss other alternatives -export const connectWallet = async ( - payload: PopupToBackgroundActionPayload[PopupToBackgroundAction.CONNECT_WALLET] -) => { - return await message.send({ - action: PopupToBackgroundAction.CONNECT_WALLET, - payload - }) -} - -export const addFunds = async ( - payload: PopupToBackgroundActionPayload[PopupToBackgroundAction.ADD_FUNDS] -) => { - return await message.send({ - action: PopupToBackgroundAction.ADD_FUNDS, - payload - }) -} - -export const reconnectWallet = async () => { - return await message.send({ - action: PopupToBackgroundAction.RECONNECT_WALLET - }) -} - -export const disconnectWallet = async () => { - return await message.send({ - action: PopupToBackgroundAction.DISCONNECT_WALLET - }) -} - -export const toggleWM = async () => { - return await message.send({ - action: PopupToBackgroundAction.TOGGLE_WM - }) -} - -export const updateRateOfPay = async ( - payload: PopupToBackgroundActionPayload[PopupToBackgroundAction.UPDATE_RATE_OF_PAY] -) => { - return await message.send({ - action: PopupToBackgroundAction.UPDATE_RATE_OF_PAY, - payload - }) -} - -export const payWebsite = async ( - payload: PopupToBackgroundActionPayload[PopupToBackgroundAction.PAY_WEBSITE] -) => { - return await message.send({ - action: PopupToBackgroundAction.PAY_WEBSITE, - payload - }) -} +export const message = new MessageManager({ browser }) diff --git a/src/popup/pages/ErrorKeyRevoked.tsx b/src/popup/pages/ErrorKeyRevoked.tsx index 4f43edd3..e05a82aa 100644 --- a/src/popup/pages/ErrorKeyRevoked.tsx +++ b/src/popup/pages/ErrorKeyRevoked.tsx @@ -1,7 +1,7 @@ import React from 'react' import { ErrorKeyRevoked } from '@/popup/components/ErrorKeyRevoked' import { PopupStateContext, ReducerActionType } from '@/popup/lib/context' -import { reconnectWallet, disconnectWallet } from '@/popup/lib/messages' +import { message } from '@/popup/lib/messages' import { useNavigate } from 'react-router-dom' import { ROUTES_PATH } from '@/popup/Popup' @@ -31,9 +31,9 @@ export const Component = () => { return ( message.send('RECONNECT_WALLET', undefined)} onReconnect={onReconnect} - disconnectWallet={disconnectWallet} + disconnectWallet={() => message.send('DISCONNECT_WALLET', undefined)} onDisconnect={onDisconnect} /> ) diff --git a/src/popup/pages/Home.tsx b/src/popup/pages/Home.tsx index 1cb8db40..ef904c11 100644 --- a/src/popup/pages/Home.tsx +++ b/src/popup/pages/Home.tsx @@ -2,7 +2,7 @@ import React from 'react' import { PopupStateContext, ReducerActionType } from '@/popup/lib/context' import { WarningSign } from '@/popup/components/Icons' import { Slider } from '../components/ui/Slider' -import { toggleWM, updateRateOfPay as updateRateOfPay_ } from '../lib/messages' +import { message } from '../lib/messages' import { Label } from '../components/ui/Label' import { formatNumber, @@ -15,7 +15,10 @@ import { debounceAsync } from '@/shared/helpers' import { Switch } from '../components/ui/Switch' import { AllSessionsInvalid } from '@/popup/components/AllSessionsInvalid' -const updateRateOfPay = debounceAsync(updateRateOfPay_, 1000) +const updateRateOfPay = debounceAsync( + (rateOfPay: string) => message.send('UPDATE_RATE_OF_PAY', { rateOfPay }), + 1000 +) export const Component = () => { const { @@ -54,7 +57,7 @@ export const Component = () => { rateOfPay } }) - const response = await updateRateOfPay({ rateOfPay }) + const response = await updateRateOfPay(rateOfPay) if (!response.success) { // TODO: Maybe reset to old state, but not while user is active (avoid // sluggishness in UI) @@ -62,7 +65,7 @@ export const Component = () => { } const onChangeWM = () => { - toggleWM() + message.send('TOGGLE_WM', undefined) dispatch({ type: ReducerActionType.TOGGLE_WM, data: {} }) } diff --git a/src/popup/pages/OutOfFunds_AddFunds.tsx b/src/popup/pages/OutOfFunds_AddFunds.tsx index 02d6c435..a89ce2e7 100644 --- a/src/popup/pages/OutOfFunds_AddFunds.tsx +++ b/src/popup/pages/OutOfFunds_AddFunds.tsx @@ -2,7 +2,7 @@ import React from 'react' import { useLocation } from 'react-router-dom' import { AddFunds } from '@/popup/components/OutOfFunds' import { usePopupState } from '@/popup/lib/context' -import { addFunds } from '@/popup/lib/messages' +import { message } from '@/popup/lib/messages' export type State = { recurring: boolean } @@ -21,7 +21,7 @@ export const Component = () => { defaultAmount={defaultAmount} recurring={state.recurring} requestAddFunds={async (data) => { - const res = await addFunds(data) + const res = await message.send('ADD_FUNDS', data) return res }} /> diff --git a/src/shared/messages.ts b/src/shared/messages.ts index 151f9bff..21d389fa 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -1,6 +1,7 @@ import type { WalletAddress, OutgoingPayment } from '@interledger/open-payments' import type { Browser } from 'webextension-polyfill' import type { AmountValue, Storage } from '@/shared/types' +import type { PopupState } from '@/popup/lib/context' export interface SuccessResponse { success: true @@ -24,16 +25,6 @@ export type MessageHKT< : { action: TAction; payload: TPayload } // #region Popup ↦ BG -export enum PopupToBackgroundAction { - GET_CONTEXT_DATA = 'GET_CONTEXT_DATA', - CONNECT_WALLET = 'CONNECT_WALLET', - ADD_FUNDS = 'ADD_FUNDS', - RECONNECT_WALLET = 'RECONNECT_WALLET', - DISCONNECT_WALLET = 'DISCONNECT_WALLET', - TOGGLE_WM = 'TOGGLE_WM', - PAY_WEBSITE = 'PAY_WEBSITE', - UPDATE_RATE_OF_PAY = 'UPDATE_RATE_OF_PAY' -} export interface ConnectWalletPayload { walletAddressUrl: string @@ -54,23 +45,40 @@ export interface UpdateRateOfPayPayload { rateOfPay: string } -export interface PopupToBackgroundActionPayload { - [PopupToBackgroundAction.GET_CONTEXT_DATA]: undefined - [PopupToBackgroundAction.CONNECT_WALLET]: ConnectWalletPayload - [PopupToBackgroundAction.RECONNECT_WALLET]: undefined - [PopupToBackgroundAction.ADD_FUNDS]: AddFundsPayload - [PopupToBackgroundAction.DISCONNECT_WALLET]: undefined - [PopupToBackgroundAction.TOGGLE_WM]: undefined - [PopupToBackgroundAction.PAY_WEBSITE]: PayWebsitePayload - [PopupToBackgroundAction.UPDATE_RATE_OF_PAY]: UpdateRateOfPayPayload -} - export type PopupToBackgroundMessage = { - [K in PopupToBackgroundAction]: MessageHKT< - K, - PopupToBackgroundActionPayload[K] - > -}[PopupToBackgroundAction] + GET_CONTEXT_DATA: { + input: void + output: PopupState + } + CONNECT_WALLET: { + input: ConnectWalletPayload + output: void + } + RECONNECT_WALLET: { + input: void + output: void + } + ADD_FUNDS: { + input: AddFundsPayload + output: void + } + DISCONNECT_WALLET: { + input: void + output: void + } + TOGGLE_WM: { + input: void + output: void + } + PAY_WEBSITE: { + input: PayWebsitePayload + output: void + } + UPDATE_RATE_OF_PAY: { + input: UpdateRateOfPayPayload + output: void + } +} // #endregion // #region Content ↦ BG @@ -104,42 +112,66 @@ export interface IsTabMonetizedPayload { value: boolean } -export interface ContentToBackgroundActionPayload { - [ContentToBackgroundAction.CHECK_WALLET_ADDRESS_URL]: CheckWalletAddressUrlPayload - [ContentToBackgroundAction.START_MONETIZATION]: StartMonetizationPayload[] - [ContentToBackgroundAction.STOP_MONETIZATION]: StopMonetizationPayload[] - [ContentToBackgroundAction.RESUME_MONETIZATION]: ResumeMonetizationPayload[] - [ContentToBackgroundAction.IS_WM_ENABLED]: undefined -} +type MessageMap = Record< + string, + { + input: unknown + output: unknown + } +> export type ContentToBackgroundMessage = { - [K in ContentToBackgroundAction]: MessageHKT< - K, - ContentToBackgroundActionPayload[K] - > -}[ContentToBackgroundAction] -// #endregion + CHECK_WALLET_ADDRESS_URL: { + input: CheckWalletAddressUrlPayload + output: WalletAddress + } + STOP_MONETIZATION: { + input: StopMonetizationPayload[] + output: void + } + START_MONETIZATION: { + input: StartMonetizationPayload[] + output: void + } + RESUME_MONETIZATION: { + input: ResumeMonetizationPayload[] + output: void + } + IS_WM_ENABLED: { + input: undefined + output: boolean + } +} -export type ToBackgroundMessage = - | PopupToBackgroundMessage - | ContentToBackgroundMessage - | BackgroundToContentMessage +// #endregion +type ToBackgroundMessageMap = PopupToBackgroundMessage & + ContentToBackgroundMessage & + BackgroundToContentMessage + +export type ToBackgroundMessage = { + [K in keyof ToBackgroundMessageMap]: { + action: K + payload: ToBackgroundMessageMap[K]['input'] + } +}[keyof ToBackgroundMessageMap] // #region BG ↦ Content -export type BackgroundToContentMessage = { - [K in BackgroundToContentAction]: MessageHKT< - K, - BackgroundToContentActionPayload[K] - > -}[BackgroundToContentAction] - -export interface BackgroundToContentActionPayload { - [BackgroundToContentAction.MONETIZATION_EVENT]: MonetizationEventPayload -} +export type ToContentMessage = { + [K in keyof BackgroundToContentMessage]: { + action: K + payload: BackgroundToContentMessage[K]['input'] + } +}[keyof BackgroundToContentMessage] -export enum BackgroundToContentAction { - MONETIZATION_EVENT = 'MONETIZATION_EVENT', - EMIT_TOGGLE_WM = 'EMIT_TOGGLE_WM' +export type BackgroundToContentMessage = { + MONETIZATION_EVENT: { + input: MonetizationEventPayload + output: void + } + EMIT_TOGGLE_WM: { + input: EmitToggleWMPayload + output: void + } } export interface MonetizationEventDetails { @@ -157,53 +189,54 @@ export interface EmitToggleWMPayload { enabled: boolean } -export interface BackgroundToContentActionPayload { - [BackgroundToContentAction.MONETIZATION_EVENT]: MonetizationEventPayload - [BackgroundToContentAction.EMIT_TOGGLE_WM]: EmitToggleWMPayload -} -export type BackgroundToContentBackgroundMessage = { - [K in BackgroundToContentAction]: MessageHKT< - K, - BackgroundToContentActionPayload[K] - > -}[BackgroundToContentAction] - interface Cradle { browser: Browser } -export type ToContentMessage = BackgroundToContentBackgroundMessage // #endregion -export class MessageManager { +export class MessageManager { private browser: Cradle['browser'] constructor({ browser }: Cradle) { this.browser = browser } - async send( - message: TMessages - ): Promise> { - return await this.browser.runtime.sendMessage(message) + async send( + action: T, + payload: TMessages[T]['input'] + ): Promise> { + return await this.browser.runtime.sendMessage({ action, payload }) } - async sendToTab( + async sendToTab( tabId: number, frameId: number, - message: TMessages - ): Promise> { + action: T, + payload: TMessages[T]['input'] + ): Promise< + TMessages[T]['output'] extends void + ? ErrorResponse + : Response + > { + const message = { action, payload } return await this.browser.tabs.sendMessage(tabId, message, { frameId }) } - async sendToActiveTab( - message: TMessages - ): Promise> { + async sendToActiveTab( + action: T, + payload: TMessages[T]['input'] + ): Promise< + TMessages[T]['output'] extends void + ? ErrorResponse + : Response + > { const window = await this.browser.windows.getCurrent() const activeTabs = await this.browser.tabs.query({ active: true, windowId: window.id }) const activeTab = activeTabs[0] + const message = { action, payload } return await this.browser.tabs.sendMessage(activeTab.id as number, message) } } From 8196d87f6a442a23ae468301df0b35e19673c662 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:27:13 +0530 Subject: [PATCH 03/12] cleanup messages --- src/shared/messages.ts | 163 ++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 93 deletions(-) diff --git a/src/shared/messages.ts b/src/shared/messages.ts index 21d389fa..5ca58b75 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -3,6 +3,7 @@ import type { Browser } from 'webextension-polyfill' import type { AmountValue, Storage } from '@/shared/types' import type { PopupState } from '@/popup/lib/context' +// #region MessageManager export interface SuccessResponse { success: true payload: TPayload @@ -17,15 +18,56 @@ export type Response = | SuccessResponse | ErrorResponse -export type MessageHKT< - TAction, - TPayload = undefined -> = TPayload extends undefined - ? { action: TAction } - : { action: TAction; payload: TPayload } +type MessageMap = Record -// #region Popup ↦ BG +export class MessageManager { + private browser: Browser + constructor({ browser }: { browser: Browser }) { + this.browser = browser + } + + async send( + action: T, + payload: TMessages[T]['input'] + ): Promise> { + return await this.browser.runtime.sendMessage({ action, payload }) + } + + async sendToTab( + tabId: number, + frameId: number, + action: T, + payload: TMessages[T]['input'] + ): Promise< + TMessages[T]['output'] extends void + ? ErrorResponse + : Response + > { + const message = { action, payload } + return await this.browser.tabs.sendMessage(tabId, message, { frameId }) + } + + async sendToActiveTab( + action: T, + payload: TMessages[T]['input'] + ): Promise< + TMessages[T]['output'] extends void + ? ErrorResponse + : Response + > { + const window = await this.browser.windows.getCurrent() + const activeTabs = await this.browser.tabs.query({ + active: true, + windowId: window.id + }) + const activeTab = activeTabs[0] + const message = { action, payload } + return await this.browser.tabs.sendMessage(activeTab.id as number, message) + } +} +// #endregion +// #region Popup ↦ BG export interface ConnectWalletPayload { walletAddressUrl: string amount: string @@ -82,14 +124,6 @@ export type PopupToBackgroundMessage = { // #endregion // #region Content ↦ BG -export enum ContentToBackgroundAction { - CHECK_WALLET_ADDRESS_URL = 'CHECK_WALLET_ADDRESS_URL', - START_MONETIZATION = 'START_MONETIZATION', - STOP_MONETIZATION = 'STOP_MONETIZATION', - RESUME_MONETIZATION = 'RESUME_MONETIZATION', - IS_WM_ENABLED = 'IS_WM_ENABLED' -} - export interface CheckWalletAddressUrlPayload { walletAddressUrl: string } @@ -112,14 +146,6 @@ export interface IsTabMonetizedPayload { value: boolean } -type MessageMap = Record< - string, - { - input: unknown - output: unknown - } -> - export type ContentToBackgroundMessage = { CHECK_WALLET_ADDRESS_URL: { input: CheckWalletAddressUrlPayload @@ -142,11 +168,11 @@ export type ContentToBackgroundMessage = { output: boolean } } - // #endregion + +// #region To BG type ToBackgroundMessageMap = PopupToBackgroundMessage & - ContentToBackgroundMessage & - BackgroundToContentMessage + ContentToBackgroundMessage export type ToBackgroundMessage = { [K in keyof ToBackgroundMessageMap]: { @@ -154,26 +180,9 @@ export type ToBackgroundMessage = { payload: ToBackgroundMessageMap[K]['input'] } }[keyof ToBackgroundMessageMap] +// #endregion // #region BG ↦ Content -export type ToContentMessage = { - [K in keyof BackgroundToContentMessage]: { - action: K - payload: BackgroundToContentMessage[K]['input'] - } -}[keyof BackgroundToContentMessage] - -export type BackgroundToContentMessage = { - MONETIZATION_EVENT: { - input: MonetizationEventPayload - output: void - } - EMIT_TOGGLE_WM: { - input: EmitToggleWMPayload - output: void - } -} - export interface MonetizationEventDetails { amountSent: PaymentCurrencyAmount incomingPayment: OutgoingPayment['receiver'] @@ -189,59 +198,29 @@ export interface EmitToggleWMPayload { enabled: boolean } -interface Cradle { - browser: Browser -} - -// #endregion - -export class MessageManager { - private browser: Cradle['browser'] - constructor({ browser }: Cradle) { - this.browser = browser - } - - async send( - action: T, - payload: TMessages[T]['input'] - ): Promise> { - return await this.browser.runtime.sendMessage({ action, payload }) +export type BackgroundToContentMessage = { + MONETIZATION_EVENT: { + input: MonetizationEventPayload + output: void } - - async sendToTab( - tabId: number, - frameId: number, - action: T, - payload: TMessages[T]['input'] - ): Promise< - TMessages[T]['output'] extends void - ? ErrorResponse - : Response - > { - const message = { action, payload } - return await this.browser.tabs.sendMessage(tabId, message, { frameId }) + EMIT_TOGGLE_WM: { + input: EmitToggleWMPayload + output: void } +} - async sendToActiveTab( - action: T, - payload: TMessages[T]['input'] - ): Promise< - TMessages[T]['output'] extends void - ? ErrorResponse - : Response - > { - const window = await this.browser.windows.getCurrent() - const activeTabs = await this.browser.tabs.query({ - active: true, - windowId: window.id - }) - const activeTab = activeTabs[0] - const message = { action, payload } - return await this.browser.tabs.sendMessage(activeTab.id as number, message) +export type ToContentMessage = { + [K in keyof BackgroundToContentMessage]: { + action: K + payload: BackgroundToContentMessage[K]['input'] } -} +}[keyof BackgroundToContentMessage] +// #endregion // #region BG ↦ Popup +export const BACKGROUND_TO_POPUP_CONNECTION_NAME = 'popup' + +// These methods are fire-and-forget, nothing is returned. export interface BackgroundToPopupMessagesMap { SET_BALANCE: Record<'recurring' | 'oneTime' | 'total', AmountValue> SET_IS_MONETIZED: boolean @@ -255,6 +234,4 @@ export type BackgroundToPopupMessage = { data: BackgroundToPopupMessagesMap[K] } }[keyof BackgroundToPopupMessagesMap] - -export const BACKGROUND_TO_POPUP_CONNECTION_NAME = 'popup' // #endregion From 63a6218d427703ed4e26c95965eff05f83b5ca14 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:31:13 +0530 Subject: [PATCH 04/12] group messages in background handler --- src/background/services/background.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/background/services/background.ts b/src/background/services/background.ts index 050a65e1..5919e11c 100644 --- a/src/background/services/background.ts +++ b/src/background/services/background.ts @@ -131,6 +131,7 @@ export class Background { this.logger.debug('Received message', message) try { switch (message.action) { + // region Popup case 'GET_CONTEXT_DATA': return success(await this.monetizationService.getPopupData()) @@ -169,11 +170,19 @@ export class Background { return } + case 'UPDATE_RATE_OF_PAY': + return success( + await this.storage.updateRate(message.payload.rateOfPay) + ) + case 'PAY_WEBSITE': return success( await this.monetizationService.pay(message.payload.amount) ) + // endregion + + // region Content case 'CHECK_WALLET_ADDRESS_URL': return success( await getWalletInformation(message.payload.walletAddressUrl) @@ -200,14 +209,11 @@ export class Background { ) return - case 'UPDATE_RATE_OF_PAY': - return success( - await this.storage.updateRate(message.payload.rateOfPay) - ) - case 'IS_WM_ENABLED': return success(await this.storage.getWMState()) + // endregion + default: return } From 27ef848e7d680714d2109c81b73f2130ab3b3960 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:53:04 +0530 Subject: [PATCH 05/12] avoid passing void to Response --- src/popup/components/ErrorKeyRevoked.tsx | 4 ++-- src/shared/messages.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/popup/components/ErrorKeyRevoked.tsx b/src/popup/components/ErrorKeyRevoked.tsx index b16a920c..3d83ab2c 100644 --- a/src/popup/components/ErrorKeyRevoked.tsx +++ b/src/popup/components/ErrorKeyRevoked.tsx @@ -11,8 +11,8 @@ import type { Response } from '@/shared/messages' interface Props { info: Pick - disconnectWallet: () => Promise> - reconnectWallet: () => Promise> + disconnectWallet: () => Promise + reconnectWallet: () => Promise onReconnect?: () => void onDisconnect?: () => void } diff --git a/src/shared/messages.ts b/src/shared/messages.ts index 5ca58b75..6b32f04a 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -4,7 +4,7 @@ import type { AmountValue, Storage } from '@/shared/types' import type { PopupState } from '@/popup/lib/context' // #region MessageManager -export interface SuccessResponse { +export interface SuccessResponse { success: true payload: TPayload } @@ -14,7 +14,7 @@ export interface ErrorResponse { message: string } -export type Response = +export type Response = | SuccessResponse | ErrorResponse @@ -164,7 +164,7 @@ export type ContentToBackgroundMessage = { output: void } IS_WM_ENABLED: { - input: undefined + input: void output: boolean } } From 2c178a023bf5c175caf12b548b4cd7c2e839bf63 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:32:55 +0530 Subject: [PATCH 06/12] don't require passing `undefined` to message.send when no input --- .../services/monetizationTagManager.ts | 2 +- src/popup/components/WalletInformation.tsx | 2 +- src/popup/lib/context.tsx | 2 +- src/popup/pages/ErrorKeyRevoked.tsx | 4 ++-- src/popup/pages/Home.tsx | 2 +- src/shared/messages.ts | 22 +++++++++++++++---- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/content/services/monetizationTagManager.ts b/src/content/services/monetizationTagManager.ts index 197469ea..7dd1cc6e 100644 --- a/src/content/services/monetizationTagManager.ts +++ b/src/content/services/monetizationTagManager.ts @@ -89,7 +89,7 @@ export class MonetizationTagManager extends EventEmitter { } private async resumeAllMonetization() { - const response = await this.message.send('IS_WM_ENABLED', undefined) + const response = await this.message.send('IS_WM_ENABLED') if (response.success && response.payload) { const resumeMonetizationTags: ResumeMonetizationPayload[] = [] diff --git a/src/popup/components/WalletInformation.tsx b/src/popup/components/WalletInformation.tsx index 3c6dcfce..30f7e5ed 100644 --- a/src/popup/components/WalletInformation.tsx +++ b/src/popup/components/WalletInformation.tsx @@ -36,7 +36,7 @@ export const WalletInformation = ({ info }: WalletInformationProps) => { {/* TODO: Improve error handling */} { - await message.send('DISCONNECT_WALLET', undefined) + await message.send('DISCONNECT_WALLET') window.location.reload() })} > diff --git a/src/popup/lib/context.tsx b/src/popup/lib/context.tsx index c389e3b3..3de0c07e 100644 --- a/src/popup/lib/context.tsx +++ b/src/popup/lib/context.tsx @@ -108,7 +108,7 @@ export function PopupContextProvider({ children }: PopupContextProviderProps) { React.useEffect(() => { async function get() { - const response = await message.send('GET_CONTEXT_DATA', undefined) + const response = await message.send('GET_CONTEXT_DATA') if (response.success) { dispatch({ type: ReducerActionType.SET_DATA, data: response.payload }) diff --git a/src/popup/pages/ErrorKeyRevoked.tsx b/src/popup/pages/ErrorKeyRevoked.tsx index e05a82aa..1bfd2756 100644 --- a/src/popup/pages/ErrorKeyRevoked.tsx +++ b/src/popup/pages/ErrorKeyRevoked.tsx @@ -31,9 +31,9 @@ export const Component = () => { return ( message.send('RECONNECT_WALLET', undefined)} + reconnectWallet={() => message.send('RECONNECT_WALLET')} onReconnect={onReconnect} - disconnectWallet={() => message.send('DISCONNECT_WALLET', undefined)} + disconnectWallet={() => message.send('DISCONNECT_WALLET')} onDisconnect={onDisconnect} /> ) diff --git a/src/popup/pages/Home.tsx b/src/popup/pages/Home.tsx index ef904c11..af2800c3 100644 --- a/src/popup/pages/Home.tsx +++ b/src/popup/pages/Home.tsx @@ -65,7 +65,7 @@ export const Component = () => { } const onChangeWM = () => { - message.send('TOGGLE_WM', undefined) + message.send('TOGGLE_WM') dispatch({ type: ReducerActionType.TOGGLE_WM, data: {} }) } diff --git a/src/shared/messages.ts b/src/shared/messages.ts index 6b32f04a..0969336c 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -19,6 +19,12 @@ export type Response = | ErrorResponse type MessageMap = Record +type MessagesWithInput = { + [K in keyof T as T[K]['input'] extends void ? never : K]: T[K] +} +type MessagesWithoutInput = { + [K in keyof T as T[K]['input'] extends void ? K : never]: T[K] +} export class MessageManager { private browser: Browser @@ -26,10 +32,18 @@ export class MessageManager { this.browser = browser } - async send( - action: T, - payload: TMessages[T]['input'] - ): Promise> { + async send, K extends keyof TT>( + action: K, + payload: TT[K]['input'] + ): Promise> + async send, K extends keyof TT>( + action: K, + payload?: never + ): Promise> + async send( + action: K, + payload?: TMessages[K]['input'] extends void ? never : TMessages[K]['input'] + ): Promise> { return await this.browser.runtime.sendMessage({ action, payload }) } From d1be8c037d654a92b5333fb5873367661714c5c2 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:29:29 +0530 Subject: [PATCH 07/12] use never instead of void --- src/shared/messages.ts | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/shared/messages.ts b/src/shared/messages.ts index 0969336c..d3c1e1c8 100644 --- a/src/shared/messages.ts +++ b/src/shared/messages.ts @@ -20,10 +20,10 @@ export type Response = type MessageMap = Record type MessagesWithInput = { - [K in keyof T as T[K]['input'] extends void ? never : K]: T[K] + [K in keyof T as T[K]['input'] extends never ? never : K]: T[K] } type MessagesWithoutInput = { - [K in keyof T as T[K]['input'] extends void ? K : never]: T[K] + [K in keyof T as T[K]['input'] extends never ? K : never]: T[K] } export class MessageManager { @@ -103,36 +103,36 @@ export interface UpdateRateOfPayPayload { export type PopupToBackgroundMessage = { GET_CONTEXT_DATA: { - input: void + input: never output: PopupState } CONNECT_WALLET: { input: ConnectWalletPayload - output: void + output: never } RECONNECT_WALLET: { - input: void - output: void + input: never + output: never } ADD_FUNDS: { input: AddFundsPayload - output: void + output: never } DISCONNECT_WALLET: { - input: void - output: void + input: never + output: never } TOGGLE_WM: { - input: void - output: void + input: never + output: never } PAY_WEBSITE: { input: PayWebsitePayload - output: void + output: never } UPDATE_RATE_OF_PAY: { input: UpdateRateOfPayPayload - output: void + output: never } } // #endregion @@ -167,18 +167,18 @@ export type ContentToBackgroundMessage = { } STOP_MONETIZATION: { input: StopMonetizationPayload[] - output: void + output: never } START_MONETIZATION: { input: StartMonetizationPayload[] - output: void + output: never } RESUME_MONETIZATION: { input: ResumeMonetizationPayload[] - output: void + output: never } IS_WM_ENABLED: { - input: void + input: never output: boolean } } @@ -215,11 +215,11 @@ export interface EmitToggleWMPayload { export type BackgroundToContentMessage = { MONETIZATION_EVENT: { input: MonetizationEventPayload - output: void + output: never } EMIT_TOGGLE_WM: { input: EmitToggleWMPayload - output: void + output: never } } From 273eb7aa3bd006b3da58c27e5f79f93d3ed63734 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:30:11 +0530 Subject: [PATCH 08/12] popup: add useMessage to sending messages --- src/popup/Popup.tsx | 13 +++++---- src/popup/components/ConnectWalletForm.tsx | 3 ++- src/popup/components/PayWebsiteForm.tsx | 3 ++- src/popup/components/WalletInformation.tsx | 3 ++- src/popup/lib/context.tsx | 25 +++++++++++++++-- src/popup/lib/messages.ts | 7 ----- src/popup/pages/ErrorKeyRevoked.tsx | 10 ++++--- src/popup/pages/Home.tsx | 31 +++++++++++++--------- src/popup/pages/OutOfFunds_AddFunds.tsx | 4 +-- 9 files changed, 64 insertions(+), 35 deletions(-) delete mode 100644 src/popup/lib/messages.ts diff --git a/src/popup/Popup.tsx b/src/popup/Popup.tsx index 19897e9d..8ff68902 100644 --- a/src/popup/Popup.tsx +++ b/src/popup/Popup.tsx @@ -1,6 +1,7 @@ import { MainLayout } from '@/popup/components/layout/MainLayout' import { BrowserContextProvider, + MessageContextProvider, PopupContextProvider, TranslationContextProvider } from './lib/context' @@ -70,11 +71,13 @@ export const Popup = () => { return ( - - - - - + + + + + + + ) diff --git a/src/popup/components/ConnectWalletForm.tsx b/src/popup/components/ConnectWalletForm.tsx index 45cb55ba..74c0825d 100644 --- a/src/popup/components/ConnectWalletForm.tsx +++ b/src/popup/components/ConnectWalletForm.tsx @@ -4,7 +4,6 @@ import { Input } from '@/popup/components/ui/Input' import { Label } from '@/popup/components/ui/Label' import { Switch } from '@/popup/components/ui/Switch' import { Code } from '@/popup/components/ui/Code' -import { message } from '@/popup/lib/messages' import { debounceSync, getWalletInformation } from '@/shared/helpers' import { charIsNumber, @@ -13,6 +12,7 @@ import { toWalletAddressUrl } from '@/popup/lib/utils' import { useForm } from 'react-hook-form' +import { useMessage } from '@/popup/lib/context' interface ConnectWalletFormInputs { walletAddressUrl: string @@ -25,6 +25,7 @@ interface ConnectWalletFormProps { } export const ConnectWalletForm = ({ publicKey }: ConnectWalletFormProps) => { + const message = useMessage() const { register, handleSubmit, diff --git a/src/popup/components/PayWebsiteForm.tsx b/src/popup/components/PayWebsiteForm.tsx index d4c08848..abfeede7 100644 --- a/src/popup/components/PayWebsiteForm.tsx +++ b/src/popup/components/PayWebsiteForm.tsx @@ -1,7 +1,7 @@ import { Button } from '@/popup/components/ui/Button' import { Input } from '@/popup/components/ui/Input' import { PopupStateContext } from '@/popup/lib/context' -import { message } from '@/popup/lib/messages' +import { useMessage } from '@/popup/lib/context' import { getCurrencySymbol, charIsNumber, @@ -25,6 +25,7 @@ const BUTTON_STATE = { } export const PayWebsiteForm = () => { + const message = useMessage() const [buttonState, setButtonState] = React.useState('idle') const isIdle = useMemo(() => buttonState === 'idle', [buttonState]) diff --git a/src/popup/components/WalletInformation.tsx b/src/popup/components/WalletInformation.tsx index 30f7e5ed..9e1e0673 100644 --- a/src/popup/components/WalletInformation.tsx +++ b/src/popup/components/WalletInformation.tsx @@ -4,7 +4,7 @@ import React from 'react' import { Code } from '@/popup/components/ui/Code' import { PopupStore } from '@/shared/types' import { Button } from '@/popup/components/ui/Button' -import { message } from '@/popup/lib/messages' +import { useMessage } from '@/popup/lib/context' import { useForm } from 'react-hook-form' interface WalletInformationProps { @@ -12,6 +12,7 @@ interface WalletInformationProps { } export const WalletInformation = ({ info }: WalletInformationProps) => { + const message = useMessage() const { handleSubmit, formState: { isSubmitting } diff --git a/src/popup/lib/context.tsx b/src/popup/lib/context.tsx index 3de0c07e..92b7e836 100644 --- a/src/popup/lib/context.tsx +++ b/src/popup/lib/context.tsx @@ -1,10 +1,11 @@ import React, { type PropsWithChildren } from 'react' import type { Browser } from 'webextension-polyfill' -import { message } from '@/popup/lib/messages' import { tFactory, type Translation } from '@/shared/helpers' import type { DeepNonNullable, PopupStore } from '@/shared/types' import { BACKGROUND_TO_POPUP_CONNECTION_NAME as CONNECTION_NAME, + MessageManager, + type PopupToBackgroundMessage, type BackgroundToPopupMessage } from '@/shared/messages' @@ -103,6 +104,7 @@ interface PopupContextProviderProps { export function PopupContextProvider({ children }: PopupContextProviderProps) { const browser = useBrowser() + const message = useMessage() const [isLoading, setIsLoading] = React.useState(true) const [state, dispatch] = React.useReducer(reducer, {} as PopupState) @@ -117,7 +119,7 @@ export function PopupContextProvider({ children }: PopupContextProviderProps) { } get() - }, []) + }, [message]) React.useEffect(() => { const port = browser.runtime.connect({ name: CONNECTION_NAME }) @@ -182,3 +184,22 @@ export const TranslationContextProvider = ({ children }: PropsWithChildren) => { export const useTranslation = () => React.useContext(TranslationContext) // #endregion + +// #region Translation +const MessageContext = React.createContext< + MessageManager +>({} as MessageManager) + +export const MessageContextProvider = ({ children }: PropsWithChildren) => { + const browser = useBrowser() + const message = new MessageManager({ browser }) + + return ( + + {children} + + ) +} + +export const useMessage = () => React.useContext(MessageContext) +// #endregion diff --git a/src/popup/lib/messages.ts b/src/popup/lib/messages.ts deleted file mode 100644 index df496814..00000000 --- a/src/popup/lib/messages.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { - MessageManager, - type PopupToBackgroundMessage -} from '@/shared/messages' -import browser from 'webextension-polyfill' - -export const message = new MessageManager({ browser }) diff --git a/src/popup/pages/ErrorKeyRevoked.tsx b/src/popup/pages/ErrorKeyRevoked.tsx index 1bfd2756..a3f6c7d1 100644 --- a/src/popup/pages/ErrorKeyRevoked.tsx +++ b/src/popup/pages/ErrorKeyRevoked.tsx @@ -1,15 +1,19 @@ import React from 'react' import { ErrorKeyRevoked } from '@/popup/components/ErrorKeyRevoked' -import { PopupStateContext, ReducerActionType } from '@/popup/lib/context' -import { message } from '@/popup/lib/messages' +import { + useMessage, + usePopupState, + ReducerActionType +} from '@/popup/lib/context' import { useNavigate } from 'react-router-dom' import { ROUTES_PATH } from '@/popup/Popup' export const Component = () => { + const message = useMessage() const { state: { publicKey, walletAddress }, dispatch - } = React.useContext(PopupStateContext) + } = usePopupState() const navigate = useNavigate() const onReconnect = () => { diff --git a/src/popup/pages/Home.tsx b/src/popup/pages/Home.tsx index af2800c3..a7202f8e 100644 --- a/src/popup/pages/Home.tsx +++ b/src/popup/pages/Home.tsx @@ -1,8 +1,11 @@ import React from 'react' -import { PopupStateContext, ReducerActionType } from '@/popup/lib/context' +import { + ReducerActionType, + usePopupState, + useMessage +} from '@/popup/lib/context' import { WarningSign } from '@/popup/components/Icons' import { Slider } from '../components/ui/Slider' -import { message } from '../lib/messages' import { Label } from '../components/ui/Label' import { formatNumber, @@ -15,12 +18,8 @@ import { debounceAsync } from '@/shared/helpers' import { Switch } from '../components/ui/Switch' import { AllSessionsInvalid } from '@/popup/components/AllSessionsInvalid' -const updateRateOfPay = debounceAsync( - (rateOfPay: string) => message.send('UPDATE_RATE_OF_PAY', { rateOfPay }), - 1000 -) - export const Component = () => { + const message = useMessage() const { state: { enabled, @@ -34,7 +33,7 @@ export const Component = () => { hasAllSessionsInvalid }, dispatch - } = React.useContext(PopupStateContext) + } = usePopupState() const rate = React.useMemo(() => { const r = Number(rateOfPay) / 10 ** walletAddress.assetScale @@ -49,6 +48,16 @@ export const Component = () => { return formatNumber(rounded, walletAddress.assetScale, true) }, [balance, walletAddress.assetScale]) + const updateRateOfPay = React.useRef( + debounceAsync(async (rateOfPay: string) => { + const response = await message.send('UPDATE_RATE_OF_PAY', { rateOfPay }) + if (!response.success) { + // TODO: Maybe reset to old state, but not while user is active (avoid + // sluggishness in UI) + } + }, 1000) + ) + const onRateChange = async (event: React.ChangeEvent) => { const rateOfPay = event.currentTarget.value dispatch({ @@ -57,11 +66,7 @@ export const Component = () => { rateOfPay } }) - const response = await updateRateOfPay(rateOfPay) - if (!response.success) { - // TODO: Maybe reset to old state, but not while user is active (avoid - // sluggishness in UI) - } + void updateRateOfPay.current(rateOfPay) } const onChangeWM = () => { diff --git a/src/popup/pages/OutOfFunds_AddFunds.tsx b/src/popup/pages/OutOfFunds_AddFunds.tsx index a89ce2e7..7847ffbb 100644 --- a/src/popup/pages/OutOfFunds_AddFunds.tsx +++ b/src/popup/pages/OutOfFunds_AddFunds.tsx @@ -1,12 +1,12 @@ import React from 'react' import { useLocation } from 'react-router-dom' import { AddFunds } from '@/popup/components/OutOfFunds' -import { usePopupState } from '@/popup/lib/context' -import { message } from '@/popup/lib/messages' +import { usePopupState, useMessage } from '@/popup/lib/context' export type State = { recurring: boolean } export const Component = () => { + const message = useMessage() const { state: { grants, walletAddress } } = usePopupState() From 754f895a7faa6de4d04bef7a96f852df460fb8cd Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:31:35 +0530 Subject: [PATCH 09/12] remove TODO --- src/content/messages.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/content/messages.ts b/src/content/messages.ts index dac8f68e..1d745383 100644 --- a/src/content/messages.ts +++ b/src/content/messages.ts @@ -1,4 +1,3 @@ -// TODO: Move to shared export enum ContentToContentAction { INITIALIZE_IFRAME = 'INITIALIZE_IFRAME', IS_MONETIZATION_ALLOWED_ON_START = 'IS_MONETIZATION_ALLOWED_ON_START', From 4c221fc8509256a38ab6690b5858c1f4b14157e3 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:32:52 +0530 Subject: [PATCH 10/12] cleanup --- src/popup/components/OutOfFunds.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/popup/components/OutOfFunds.tsx b/src/popup/components/OutOfFunds.tsx index a7be47f7..ca7367bd 100644 --- a/src/popup/components/OutOfFunds.tsx +++ b/src/popup/components/OutOfFunds.tsx @@ -68,7 +68,7 @@ interface AddFundsProps { info: Pick recurring: boolean defaultAmount: AmountValue - requestAddFunds: (details: AddFundsPayload) => Promise> + requestAddFunds: (details: AddFundsPayload) => Promise } export function AddFunds({ From 8a098cae66cc668f421586dc8bef22d18897cce7 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:36:11 +0530 Subject: [PATCH 11/12] usePopupContext in more places --- src/popup/components/PayWebsiteForm.tsx | 10 +++++----- src/popup/components/ProtectedRoute.tsx | 4 ++-- src/popup/components/layout/Header.tsx | 8 ++++---- src/popup/pages/Settings.tsx | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/popup/components/PayWebsiteForm.tsx b/src/popup/components/PayWebsiteForm.tsx index abfeede7..9807fba8 100644 --- a/src/popup/components/PayWebsiteForm.tsx +++ b/src/popup/components/PayWebsiteForm.tsx @@ -1,7 +1,6 @@ import { Button } from '@/popup/components/ui/Button' import { Input } from '@/popup/components/ui/Input' -import { PopupStateContext } from '@/popup/lib/context' -import { useMessage } from '@/popup/lib/context' +import { useMessage, usePopupState } from '@/popup/lib/context' import { getCurrencySymbol, charIsNumber, @@ -26,12 +25,13 @@ const BUTTON_STATE = { export const PayWebsiteForm = () => { const message = useMessage() + const { + state: { walletAddress, url } + } = usePopupState() const [buttonState, setButtonState] = React.useState('idle') const isIdle = useMemo(() => buttonState === 'idle', [buttonState]) - const { - state: { walletAddress, url } - } = React.useContext(PopupStateContext) + const { register, formState: { errors, isSubmitting }, diff --git a/src/popup/components/ProtectedRoute.tsx b/src/popup/components/ProtectedRoute.tsx index a5f3c4e1..bfc31b9c 100644 --- a/src/popup/components/ProtectedRoute.tsx +++ b/src/popup/components/ProtectedRoute.tsx @@ -1,10 +1,10 @@ -import { PopupStateContext } from '@/popup/lib/context' +import { usePopupState } from '@/popup/lib/context' import React from 'react' import { Navigate, Outlet } from 'react-router-dom' import { ROUTES_PATH } from '../Popup' export const ProtectedRoute = () => { - const { state } = React.useContext(PopupStateContext) + const { state } = usePopupState() if (state.state.missing_host_permissions) { return diff --git a/src/popup/components/layout/Header.tsx b/src/popup/components/layout/Header.tsx index eb6e1645..631f6eb7 100644 --- a/src/popup/components/layout/Header.tsx +++ b/src/popup/components/layout/Header.tsx @@ -1,15 +1,15 @@ -import React, { useContext, useMemo } from 'react' +import React from 'react' import { Link, useLocation } from 'react-router-dom' import { ArrowBack, Settings } from '../Icons' import { ROUTES_PATH } from '@/popup/Popup' -import { PopupStateContext, useBrowser } from '@/popup/lib/context' +import { useBrowser, usePopupState } from '@/popup/lib/context' const NavigationButton = () => { const location = useLocation() const { state: { connected } - } = useContext(PopupStateContext) - return useMemo(() => { + } = usePopupState() + return React.useMemo(() => { if (!connected) return null if (location.pathname.includes('/s/')) { diff --git a/src/popup/pages/Settings.tsx b/src/popup/pages/Settings.tsx index 6ed90990..3ade8d10 100644 --- a/src/popup/pages/Settings.tsx +++ b/src/popup/pages/Settings.tsx @@ -1,10 +1,10 @@ import { ConnectWalletForm } from '@/popup/components/ConnectWalletForm' import { WalletInformation } from '@/popup/components/WalletInformation' -import { PopupStateContext } from '@/popup/lib/context' +import { usePopupState } from '@/popup/lib/context' import React from 'react' export const Component = () => { - const { state } = React.useContext(PopupStateContext) + const { state } = usePopupState() if (state.connected) { return From 75d3b5ce292a2a42b25482b3df1f21917d69c7b9 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:37:50 +0530 Subject: [PATCH 12/12] nits --- src/popup/lib/context.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/popup/lib/context.tsx b/src/popup/lib/context.tsx index 92b7e836..c318a46f 100644 --- a/src/popup/lib/context.tsx +++ b/src/popup/lib/context.tsx @@ -63,9 +63,8 @@ export type ReducerActions = | UpdateRateOfPayAction | BackgroundToPopupAction -export const PopupStateContext = React.createContext( - {} as PopupContext -) +const PopupStateContext = React.createContext({} as PopupContext) + export const usePopupState = () => React.useContext(PopupStateContext) const reducer = (state: PopupState, action: ReducerActions): PopupState => { @@ -154,6 +153,8 @@ export function PopupContextProvider({ children }: PopupContextProviderProps) { // #region Browser const BrowserContext = React.createContext({} as Browser) +export const useBrowser = () => React.useContext(BrowserContext) + export const BrowserContextProvider = ({ browser, children @@ -165,12 +166,13 @@ export const BrowserContextProvider = ({ ) } -export const useBrowser = () => React.useContext(BrowserContext) // #endregion // #region Translation const TranslationContext = React.createContext((v: string) => v) +export const useTranslation = () => React.useContext(TranslationContext) + export const TranslationContextProvider = ({ children }: PropsWithChildren) => { const browser = useBrowser() const t = tFactory(browser) @@ -182,7 +184,6 @@ export const TranslationContextProvider = ({ children }: PropsWithChildren) => { ) } -export const useTranslation = () => React.useContext(TranslationContext) // #endregion // #region Translation @@ -190,6 +191,8 @@ const MessageContext = React.createContext< MessageManager >({} as MessageManager) +export const useMessage = () => React.useContext(MessageContext) + export const MessageContextProvider = ({ children }: PropsWithChildren) => { const browser = useBrowser() const message = new MessageManager({ browser }) @@ -201,5 +204,4 @@ export const MessageContextProvider = ({ children }: PropsWithChildren) => { ) } -export const useMessage = () => React.useContext(MessageContext) // #endregion