Skip to content

Commit

Permalink
Merge branch 'main' into df--consistent-rate-of-pay
Browse files Browse the repository at this point in the history
  • Loading branch information
sidvishnoi authored Jul 31, 2024
2 parents c0ba3d9 + 54395d4 commit 1679f3b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 53 deletions.
17 changes: 11 additions & 6 deletions src/background/services/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ export class Background {
}

bindTabHandlers() {
this.browser.tabs.onRemoved.addListener(this.tabEvents.clearTabSessions)
this.browser.tabs.onUpdated.addListener(this.tabEvents.clearTabSessions)
this.browser.tabs.onRemoved.addListener(this.tabEvents.onRemovedTab)
this.browser.tabs.onUpdated.addListener(this.tabEvents.onUpdatedTab)
this.browser.tabs.onCreated.addListener(this.tabEvents.onCreatedTab)
this.browser.tabs.onActivated.addListener(this.tabEvents.onActivatedTab)
}
Expand All @@ -132,7 +132,7 @@ export class Background {
case PopupToBackgroundAction.RECONNECT_WALLET:
await this.openPaymentsService.reconnectWallet()
await this.monetizationService.resumePaymentSessionActiveTab()
await this.tabEvents.onUpdatedTab()
await this.tabEvents.onUpdatedTabUpdatedIndicator()
return success(undefined)

case PopupToBackgroundAction.ADD_FUNDS:
Expand All @@ -151,7 +151,7 @@ export class Background {

case PopupToBackgroundAction.TOGGLE_WM:
await this.monetizationService.toggleWM()
await this.tabEvents.onUpdatedTab()
await this.tabEvents.onUpdatedTabUpdatedIndicator()
return

case PopupToBackgroundAction.PAY_WEBSITE:
Expand Down Expand Up @@ -191,7 +191,10 @@ export class Background {
)

case ContentToBackgroundAction.IS_TAB_MONETIZED:
await this.tabEvents.onUpdatedTab(message.payload, sender)
await this.tabEvents.onUpdatedTabUpdatedIndicator(
message.payload,
sender
)
return

case ContentToBackgroundAction.IS_WM_ENABLED:
Expand Down Expand Up @@ -222,7 +225,9 @@ export class Background {
this.sendToPopup.send('SET_STATE', { state, prevState })

const isCurrentTabMonetized = true // TODO get from tabState
await this.tabEvents.onUpdatedTab({ value: isCurrentTabMonetized })
await this.tabEvents.onUpdatedTabUpdatedIndicator({
value: isCurrentTabMonetized
})
})

this.events.on('storage.balance_update', (balance) =>
Expand Down
18 changes: 0 additions & 18 deletions src/background/services/monetization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,24 +215,6 @@ export class MonetizationService {
emitToggleWM({ enabled: !enabled })
}

clearTabSessions(tabId: number) {
this.logger.debug(`Attempting to clear sessions for tab ${tabId}.`)
const sessions = this.tabState.getSessions(tabId)

if (!sessions.size) {
this.logger.debug(`No active sessions found for tab ${tabId}.`)
return
}

for (const session of sessions.values()) {
session.stop()
}

this.tabState.clearByTabId(tabId)

this.logger.debug(`Cleared ${sessions.size} sessions for tab ${tabId}.`)
}

async pay(amount: string) {
const tab = await getCurrentActiveTab(this.browser)
if (!tab || !tab.id) {
Expand Down
58 changes: 31 additions & 27 deletions src/background/services/tabEvents.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import browser from 'webextension-polyfill'
import type { Browser, Runtime, Tabs } from 'webextension-polyfill'
import type { Browser, Runtime } from 'webextension-polyfill'
import { IsTabMonetizedPayload } from '@/shared/messages'
import { getTabId } from '../utils'
import { isOkState, type Translation } from '@/shared/helpers'
import type {
MonetizationService,
SendToPopup,
StorageService,
TabState
} from '.'
import {
isOkState,
removeQueryParams,
type Translation
} from '@/shared/helpers'
import type { SendToPopup, StorageService, TabState } from '.'
import type { Storage, TabId } from '@/shared/types'

const runtime = browser.runtime
Expand Down Expand Up @@ -55,43 +54,48 @@ const ICONS = {
}
}

type CallbackTabOnActivated = Parameters<
Browser['tabs']['onActivated']['addListener']
>[0]
type CallbackTabOnCreated = Parameters<
Browser['tabs']['onCreated']['addListener']
>[0]
type CallbackTab<T extends Extract<keyof Browser['tabs'], `on${string}`>> =
Parameters<Browser['tabs'][T]['addListener']>[0]

export class TabEvents {
constructor(
private monetizationService: MonetizationService,
private storage: StorageService,
private tabState: TabState,
private sendToPopup: SendToPopup,
private t: Translation,
private browser: Browser
) {}
clearTabSessions = (
tabId: TabId,
changeInfo: Tabs.OnUpdatedChangeInfoType | Tabs.OnRemovedRemoveInfoType
) => {
if (
('status' in changeInfo && changeInfo.status === 'loading') ||
'isWindowClosing' in changeInfo
) {
this.monetizationService.clearTabSessions(tabId)

onUpdatedTab: CallbackTab<'onUpdated'> = (tabId, changeInfo, tab) => {
/**
* if loading and no url -> clear all sessions but not the overpaying state
* if loading and url -> we need to check if state keys include this url.
*/
if (changeInfo.status === 'loading') {
const url = tab.url ? removeQueryParams(tab.url) : ''
const clearOverpaying = this.tabState.shouldClearOverpaying(tabId, url)

this.tabState.clearSessionsByTabId(tabId)
if (clearOverpaying) {
this.tabState.clearOverpayingByTabId(tabId)
}
}
}

onActivatedTab: CallbackTabOnActivated = async (info) => {
onRemovedTab: CallbackTab<'onRemoved'> = (tabId, _removeInfo) => {
this.tabState.clearSessionsByTabId(tabId)
this.tabState.clearOverpayingByTabId(tabId)
}

onActivatedTab: CallbackTab<'onActivated'> = async (info) => {
await this.updateVisualIndicators(info.tabId)
}

onCreatedTab: CallbackTabOnCreated = async (tab) => {
onCreatedTab: CallbackTab<'onCreated'> = async (tab) => {
await this.updateVisualIndicators(tab.id)
}

onUpdatedTab = async (
onUpdatedTabUpdatedIndicator = async (
payload?: IsTabMonetizedPayload | null,
sender?: Runtime.MessageSender
) => {
Expand Down
22 changes: 20 additions & 2 deletions src/background/services/tabState.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { MonetizationEventDetails } from '@/shared/messages'
import type { TabId } from '@/shared/types'
import type { PaymentSession } from './paymentSession'
import type { Logger } from '@/shared/logger'

type State = {
monetizationEvent: MonetizationEventDetails
Expand All @@ -20,12 +21,18 @@ export class TabState {
private state = new Map<TabId, Map<string, State>>()
private sessions = new Map<TabId, Map<SessionId, PaymentSession>>()

constructor() {}
constructor(private logger: Logger) {}

private getOverpayingStateKey(url: string, walletAddressId: string): string {
return `${url}:${walletAddressId}`
}

shouldClearOverpaying(tabId: TabId, url: string): boolean {
const tabState = this.state.get(tabId)
if (!tabState?.size || !url) return false
return ![...tabState.keys()].some((key) => key.startsWith(`${url}:`))
}

getOverpayingDetails(
tabId: TabId,
url: string,
Expand Down Expand Up @@ -100,8 +107,19 @@ export class TabState {
return [...this.sessions.keys()]
}

clearByTabId(tabId: TabId) {
clearOverpayingByTabId(tabId: TabId) {
this.state.delete(tabId)
this.logger.debug(`Cleared overpaying state for tab ${tabId}.`)
}

clearSessionsByTabId(tabId: TabId) {
const sessions = this.getSessions(tabId)
if (!sessions.size) return

for (const session of sessions.values()) {
session.stop()
}
this.logger.debug(`Cleared ${sessions.size} sessions for tab ${tabId}.`)
this.sessions.delete(tabId)
}
}

0 comments on commit 1679f3b

Please sign in to comment.