Skip to content

Commit

Permalink
Fix: render mobile pairing correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
katspaugh committed Oct 31, 2023
1 parent 61f0568 commit fd3c087
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 79 deletions.
3 changes: 3 additions & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { WalletConnectProvider } from '@/services/walletconnect/WalletConnectCon
import useABTesting from '@/services/tracking/useAbTesting'
import { AbTest } from '@/services/tracking/abTesting'
import { useNotificationTracking } from '@/components/settings/PushNotifications/hooks/useNotificationTracking'
import MobilePairingModal from '@/services/pairing/QRModal'

const GATEWAY_URL = IS_PRODUCTION || cgwDebugStorage.get() ? GATEWAY_URL_PRODUCTION : GATEWAY_URL_STAGING

Expand Down Expand Up @@ -121,6 +122,8 @@ const WebCoreApp = ({
<CookieBanner />

<Notifications />

<MobilePairingModal />
</AppProviders>
</CacheProvider>
</StoreHydrator>
Expand Down
106 changes: 33 additions & 73 deletions src/services/pairing/QRModal.tsx
Original file line number Diff line number Diff line change
@@ -1,95 +1,55 @@
import { useState } from 'react'
import { Dialog, DialogContent, DialogTitle, IconButton } from '@mui/material'
import { createRoot } from 'react-dom/client'
import CloseIcon from '@mui/icons-material/Close'
import PairingQRCode from '@/components/common/PairingDetails/PairingQRCode'
import PairingDescription from '@/components/common/PairingDetails/PairingDescription'
import { StoreHydrator } from '@/store'
import { AppProviders } from '@/pages/_app'
import { PAIRING_MODULE_LABEL } from '@/services/pairing/module'
import css from './styles.module.css'
import PairingDeprecationWarning from '@/components/common/PairingDetails/PairingDeprecationWarning'
import ExternalStore from '@/services/ExternalStore'

const WRAPPER_ID = 'safe-mobile-qr-modal'
const QR_CODE_SIZE = 200
const { useStore: useCloseCallback, setStore: setCloseCallback } = new ExternalStore<() => void>()

const renderWrapper = () => {
if (typeof document === 'undefined') {
return
}

const wrapper = document.createElement('div')
wrapper.setAttribute('id', WRAPPER_ID)

document.body.appendChild(wrapper)

return wrapper
}

const open = (uri: string, cb: () => void) => {
const wrapper = renderWrapper()

if (!wrapper) {
return
}

const root = createRoot(wrapper)

root.render(<Modal uri={uri} cb={cb} />)
export const open = (cb: () => void) => {
setCloseCallback(() => cb)
}

const close = () => {
if (typeof document === 'undefined') {
return
}

const wrapper = document.getElementById(WRAPPER_ID)
if (wrapper) {
document.body.removeChild(wrapper)
document.body.style.overflow = ''
}
export const close = () => {
setCloseCallback(undefined)
}

const Modal = ({ uri, cb }: { uri: string; cb: () => void }) => {
const [open, setOpen] = useState(true)
const QRModal = () => {
const closeCallback = useCloseCallback()
const open = !!closeCallback

const handleClose = () => {
cb()
setOpen(false)
closeCallback?.()
setCloseCallback(undefined)
close()
}

if (!open) return null

return (
<StoreHydrator>
<AppProviders>
<Dialog open={open} onClose={handleClose} disablePortal className={css.modal}>
<DialogTitle sx={{ m: 0, p: 2, display: 'flex', justifyContent: 'space-between' }}>
{PAIRING_MODULE_LABEL}
<IconButton
onClick={handleClose}
size="small"
sx={{
color: 'border.main',
}}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 1 }}>
<PairingDeprecationWarning />
<PairingQRCode size={QR_CODE_SIZE} />
<br />
<PairingDescription />
</DialogContent>
</Dialog>
</AppProviders>
</StoreHydrator>
<Dialog open={open} onClose={handleClose} disablePortal sx={{ zIndex: 100000 }}>
<DialogTitle sx={{ m: 0, p: 2, display: 'flex', justifyContent: 'space-between' }}>
{PAIRING_MODULE_LABEL}
<IconButton
onClick={handleClose}
size="small"
sx={{
color: 'border.main',
}}
>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 1 }}>
<PairingDeprecationWarning />
<PairingQRCode size={200} />
<br />
<PairingDescription />
</DialogContent>
</Dialog>
)
}

const QRModal = {
open,
close,
}

export default QRModal
5 changes: 2 additions & 3 deletions src/services/pairing/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { ITxData } from '@walletconnect/types'
import { getPairingConnector, PAIRING_MODULE_STORAGE_ID } from '@/services/pairing/connector'
import local from '@/services/local-storage/local'
import { killPairingSession } from '@/services/pairing/utils'
import * as QRModal from '@/services/pairing/QRModal'

enum ProviderEvents {
ACCOUNTS_CHANGED = 'accountsChanged',
Expand Down Expand Up @@ -44,8 +45,6 @@ const pairingModule = (): WalletInit => {

const { default: WalletConnect } = await import('@walletconnect/client')

const { default: QRModal } = await import('@/services/pairing/QRModal')

const { Subject, fromEvent } = await import('rxjs')
const { takeUntil, take } = await import('rxjs/operators')

Expand Down Expand Up @@ -131,7 +130,7 @@ const pairingModule = (): WalletInit => {
return new Promise<ProviderAccounts>((resolve, reject) => {
if (!this.connector.connected) {
this.connector.createSession().then(() => {
QRModal.open(this.connector.uri, () =>
QRModal.open(() =>
reject(
new ProviderRpcError({
code: 4001,
Expand Down
3 changes: 0 additions & 3 deletions src/services/pairing/styles.module.css

This file was deleted.

0 comments on commit fd3c087

Please sign in to comment.