Skip to content

Commit

Permalink
refactor: add t, useTranslation helpers to use translations (#395)
Browse files Browse the repository at this point in the history
  • Loading branch information
sidvishnoi committed Jul 5, 2024
1 parent 3beb361 commit 7f7d678
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 14 deletions.
7 changes: 7 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@
"react-hooks/exhaustive-deps": "error",
"react/react-in-jsx-scope": "off",
"react/jsx-uses-react": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
],
"@typescript-eslint/no-explicit-any": "off"
},
"overrides": [
Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"temp",
"*.svg",
"pnpm-lock.yaml",
".eslintrc.json",
"cspell-dictionary.txt"
]
}
3 changes: 3 additions & 0 deletions src/background/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from './services'
import { createLogger, Logger } from '@/shared/logger'
import { LOG_LEVEL } from '@/shared/defines'
import { tFactory, type Translation } from '@/shared/helpers'

interface Cradle {
logger: Logger
Expand All @@ -25,6 +26,7 @@ interface Cradle {
sendToPopup: SendToPopup
tabEvents: TabEvents
background: Background
t: Translation
tabState: TabState
}

Expand All @@ -38,6 +40,7 @@ export const configureContainer = () => {
container.register({
logger: asValue(logger),
browser: asValue(browser),
t: asValue(tFactory(browser)),
events: asClass(EventsService).singleton(),
deduplicator: asClass(Deduplicator)
.singleton()
Expand Down
8 changes: 5 additions & 3 deletions src/background/services/tabEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { MonetizationService } from './monetization'
import { StorageService } from './storage'
import { IsTabMonetizedPayload } from '@/shared/messages'
import { getTabId } from '../utils'
import type { Translation } from '@/shared/helpers'

const runtime = browser.runtime
const ICONS = {
Expand All @@ -29,6 +30,7 @@ export class TabEvents {
constructor(
private monetizationService: MonetizationService,
private storage: StorageService,
private t: Translation,
private browser: Browser
) {}
clearTabSessions = (
Expand Down Expand Up @@ -63,14 +65,14 @@ export class TabEvents {
) => {
const { enabled } = await this.storage.get(['enabled'])

let title = this.browser.i18n.getMessage('appName')
let title = this.t('appName')
let iconData = enabled ? ICONS.default : ICONS.warning
if (enabled && payload) {
const { value: isTabMonetized } = payload
iconData = isTabMonetized ? ICONS.active : ICONS.inactive
const tabStateText = isTabMonetized
? this.browser.i18n.getMessage('monetizationActiveShort')
: this.browser.i18n.getMessage('monetizationInactiveShort')
? this.t('monetizationActiveShort')
: this.t('monetizationInactiveShort')
title = `${title} - ${tabStateText}`
}
const tabId = sender && getTabId(sender)
Expand Down
11 changes: 7 additions & 4 deletions src/popup/Popup.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { MainLayout } from '@/popup/components/layout/MainLayout'
import { PopupContextProvider } from './lib/context'
import { PopupContextProvider, TranslationContextProvider } from './lib/context'
import { LazyMotion, domAnimation } from 'framer-motion'
import React from 'react'
import browser from 'webextension-polyfill'
import { ProtectedRoute } from '@/popup/components/ProtectedRoute'
import {
RouteObject,
Expand Down Expand Up @@ -49,9 +50,11 @@ const router = createMemoryRouter(routes)
export const Popup = () => {
return (
<LazyMotion features={domAnimation} strict>
<PopupContextProvider>
<RouterProvider router={router} />
</PopupContextProvider>
<TranslationContextProvider browser={browser}>
<PopupContextProvider>
<RouterProvider router={router} />
</PopupContextProvider>
</TranslationContextProvider>
</LazyMotion>
)
}
7 changes: 3 additions & 4 deletions src/popup/components/SiteNotMonetized.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import React from 'react'
import browser from 'webextension-polyfill'
import { WarningSign } from '@/popup/components/Icons'
import { useTranslation } from '@/popup/lib/context'

export const SiteNotMonetized = () => {
const t = useTranslation()
return (
<div className="flex h-full items-center justify-center gap-2 p-4 text-lg">
<div className="flex-shrink-0">
<WarningSign className="size-6 text-medium" />
</div>
<h3 className="text-medium">
{browser.i18n.getMessage('siteNotMonetized')}
</h3>
<h3 className="text-medium">{t('siteNotMonetized')}</h3>
</div>
)
}
25 changes: 23 additions & 2 deletions src/popup/lib/context.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react'
import browser from 'webextension-polyfill'
import browser, { type Browser } from 'webextension-polyfill'
import { getContextData } from '@/popup/lib/messages'
import { DeepNonNullable, PopupStore } from '@/shared/types'
import { tFactory, type Translation } from '@/shared/helpers'
import type { DeepNonNullable, PopupStore } from '@/shared/types'
import {
ContentToBackgroundAction,
type ContentToBackgroundMessage
Expand Down Expand Up @@ -161,3 +162,23 @@ export function PopupContextProvider({ children }: PopupContextProviderProps) {
</PopupStateContext.Provider>
)
}

const TranslationContext = React.createContext<Translation>((v: string) => v)

export const TranslationContextProvider = ({
browser,
children
}: {
browser: Browser
children: React.ReactNode
}) => {
const t = tFactory(browser)

return (
<TranslationContext.Provider value={t}>
{children}
</TranslationContext.Provider>
)
}

export const useTranslation = () => React.useContext(TranslationContext)
4 changes: 3 additions & 1 deletion src/popup/pages/MissingHostPermission.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import React from 'react'
import browser from 'webextension-polyfill'
import { PERMISSION_HOSTS } from '@/shared/defines'
import { WarningSign } from '@/popup/components/Icons'
import { useTranslation } from '@/popup/lib/context'

export const Component = () => {
const t = useTranslation()
return (
<div className="rounded-md bg-orange-50 p-4 text-sm">
<div className="flex">
Expand All @@ -13,7 +15,7 @@ export const Component = () => {
<div className="ml-3 flex flex-col gap-2">
<h3 className="font-medium text-orange-800">Permission needed</h3>
<div className="text-orange-700">
<p>{browser.i18n.getMessage('hostsPermissionsNeeded')}</p>
<p>{t('hostsPermissionsNeeded')}</p>
</div>
</div>
</div>
Expand Down
15 changes: 15 additions & 0 deletions src/shared/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SuccessResponse } from '@/shared/messages'
import { WalletAddress } from '@interledger/open-payments/dist/types'
import { cx, CxOptions } from 'class-variance-authority'
import { twMerge } from 'tailwind-merge'
import type { Browser } from 'webextension-polyfill'

export const cn = (...inputs: CxOptions) => {
return twMerge(cx(inputs))
Expand Down Expand Up @@ -193,6 +194,20 @@ export function bigIntMax(a: string, b: string) {
return BigInt(a) > BigInt(b) ? a : b
}

type TranslationKeys = keyof typeof import('../_locales/en/messages.json')

export type Translation = ReturnType<typeof tFactory>
export function tFactory(browser: Pick<Browser, 'i18n'>) {
/**
* Helper over calling cumbersome `this.browser.i18n.getMessage(key)` with
* added benefit that it type-checks if key exists in message.json
*/
return <T extends TranslationKeys>(
key: T,
substitutions?: string | string[]
) => browser.i18n.getMessage(key, substitutions)
}

type Primitive = string | number | boolean | null | undefined

// Warn: Not a nested object equals or a deepEquals function
Expand Down

0 comments on commit 7f7d678

Please sign in to comment.