Skip to content

Commit

Permalink
feat: extension background storage (#98)
Browse files Browse the repository at this point in the history
* extension storage config, sync background storage with popup context storage

* code review updates

* fix storage import
  • Loading branch information
ionutanin authored Feb 19, 2024
1 parent 57a3291 commit b944898
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 8 deletions.
14 changes: 12 additions & 2 deletions src/background/Background.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
import { Runtime, runtime, tabs } from 'webextension-polyfill'
import browser, { Runtime, runtime, tabs } from 'webextension-polyfill'

import { PaymentFlowService } from '@/background/grantFlow'
import { defaultData } from '@/utils/storage'

import getSendingPaymentPointerHandler from '../messageHandlers/getSendingPaymentPointerHandler'
import getStorageData from '../messageHandlers/getStorageData'
import isMonetizationReadyHandler from '../messageHandlers/isMonetizationReadyHandler'
import setIncomingPointerHandler from '../messageHandlers/setIncomingPointerHandler'
import { tabChangeHandler, tabUpdateHandler } from './tabHandlers'

const storage = browser.storage.local

class Background {
private messageHandlers: any = [
isMonetizationReadyHandler,
setIncomingPointerHandler,
getSendingPaymentPointerHandler,
getStorageData,
]
private subscriptions: any = []
// TO DO: remove these from background into storage or state & use injection
grantFlow: PaymentFlowService | null = null
spentAmount: number = 0
paymentStarted = false

constructor() {}
constructor() {
storage
.set({ data: defaultData })
.then(() => console.log('Default data stored successfully'))
.catch((error: any) => console.error('Error storing data:', error))
}

subscribeToMessages() {
this.subscriptions = this.messageHandlers.map((handler: any) => {
Expand Down
5 changes: 4 additions & 1 deletion src/components/switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ export interface SwitchProps
extends VariantProps<typeof switchVariants>,
React.HTMLAttributes<HTMLInputElement> {
checked?: boolean
onChange?: (_event: React.ChangeEvent<HTMLInputElement>) => void
}

export const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(
{ size, className, ...props },
{ size, className, onChange = () => {}, ...props },
ref,
) {
return (
Expand All @@ -45,6 +46,8 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(
role="switch"
ref={ref}
type="checkbox"
checked={props.checked}
onChange={onChange}
{...props}
className="peer absolute opacity-0 -translate-x-[100%] pointer-events-none"
/>
Expand Down
13 changes: 13 additions & 0 deletions src/messageHandlers/getStorageData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import browser from 'webextension-polyfill'

const storage = browser.storage.local

const getStorageData = async () => {
const data = await storage.get('data')
return {
type: 'SUCCESS',
data,
}
}

export default { callback: getStorageData, type: 'GET_STORAGE_DATA' }
4 changes: 2 additions & 2 deletions src/messageHandlers/isMonetizationReadyHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ export type IsMonetizationReadyData = {
monetization: boolean
}

const isMometizationReadyCallback = async (data: IsMonetizationReadyData) => {
const isMonetizationReadyCallback = async (data: IsMonetizationReadyData) => {
await updateIcon(data.monetization)

return true
}

export default { callback: isMometizationReadyCallback, type: 'IS_MONETIZATION_READY' }
export default { callback: isMonetizationReadyCallback, type: 'IS_MONETIZATION_READY' }
1 change: 1 addition & 0 deletions src/popup/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const Home = () => {

const getSendingPaymentPointer = async () => {
const response = await sendMessage({ type: 'GET_SENDING_PAYMENT_POINTER' })
console.log('getSendingPaymentPointer', response)
setSendingPaymentPointer(response.data.sendingPaymentPointerUrl)

const { sendingPaymentPointerUrl: paymentPointer, amount } = response.data
Expand Down
9 changes: 9 additions & 0 deletions src/providers/__tests__/popup-context.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import React, { useContext } from 'react'

import { defaultData, PopupContext, PopupProvider } from '../popup.provider'

jest.mock('webextension-polyfill', () => ({
runtime: {
onMessage: {
addListener: jest.fn(),
removeListener: jest.fn(),
},
},
}))

const TestComponent = () => {
const { data, setData } = useContext(PopupContext)

Expand Down
13 changes: 12 additions & 1 deletion src/providers/popup.provider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React, { createContext, useState } from 'react'
import React, { createContext, useEffect, useState } from 'react'

import { getStorageData } from '@/utils/storage'

import { PopupContextValue, TPopupContext } from './providers.interface'

Expand Down Expand Up @@ -29,6 +31,15 @@ export const PopupContext = createContext<PopupContextValue>({
export const PopupProvider: React.FC<IProps> = ({ children }) => {
const [data, setData] = useState<TPopupContext>(defaultData)

useEffect(() => {
;(async () => {
const storageData = await getStorageData()
setData(storageData as TPopupContext)
})()

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

return <PopupContext.Provider value={{ data, setData }}>{children}</PopupContext.Provider>
}

Expand Down
2 changes: 2 additions & 0 deletions src/types/message.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ declare type EXTMessageType =
| 'PAYMENT_SUCCESS'
| 'PAUSE_PAYMENTS'
| 'LOAD'
| 'GET_STORAGE_DATA'
| 'SET_STORAGE_DATA'

declare type EXTMessage<T = any> = {
type: EXTMessageType
Expand Down
39 changes: 37 additions & 2 deletions src/utils/storage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
import { storage } from 'webextension-polyfill'
import { TPopupContext } from '@/providers/providers.interface'
import { sendMessage } from '@/utils/sendMessages'

export default storage.sync ? storage.sync : storage.local
export interface ExtensionStorageData {
amount: number
amountType: {
recurring: boolean
}
rateOfPay: number
wmEnabled: boolean
accessTokenQuote: string
accessTokenOutgoing: string
refreshToken: string
manageUrl: string
}

export const defaultData: ExtensionStorageData = {
amount: 0,
amountType: {
recurring: true,
},
rateOfPay: 0.36,
wmEnabled: true,
accessTokenQuote: '',
accessTokenOutgoing: '',
refreshToken: '',
manageUrl: '',
}

export const getStorageData = async () => {
try {
const response = await sendMessage({ type: 'GET_STORAGE_DATA' })
return response?.data as TPopupContext
} catch (error) {
console.error('Error fetching storage data:', error)
return null
}
}

0 comments on commit b944898

Please sign in to comment.