Skip to content

Commit

Permalink
refactor: create bound modal object (#9849)
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleBill authored Jun 15, 2023
1 parent 71a71dd commit 4fe9cf9
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 9 deletions.
44 changes: 44 additions & 0 deletions packages/shared-base/src/SingletonModal/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { describe, expect, it, vi, beforeAll } from 'vitest'
import { SingletonModal } from './index.js'

describe('SingletonModal', () => {
const modal = new SingletonModal<void, { closeProp: number }>()
const open = vi.fn()
const close = vi.fn()
const abort = vi.fn()
let closeCallback: (props: { closeProp: number }) => void
let rejectCallback: typeof modal.abort
beforeAll(() => {
modal.register((registerOnOpen, registerOnClose, registerOnAbort) => {
closeCallback = registerOnClose
rejectCallback = registerOnAbort
return {
open,
close,
abort,
}
})
})
it('should register successfully', () => {
open.mockReset()
modal.open()
expect(open).toBeCalledTimes(1)
})
it('can be called without object', () => {
open.mockReset()
;(0, modal.open)()
expect(open).toBeCalledTimes(1)
})

it('opens and waits for closing', async () => {
const promise = modal.openAndWaitForClose()
closeCallback({ closeProp: 1 })
expect(promise).resolves.toEqual({ closeProp: 1 })
})

it('gets rejected error', () => {
const promise = modal.openAndWaitForClose()
rejectCallback(new Error('Mock Error Message'))
expect(promise).rejects.toThrow('Mock Error Message')
})
})
8 changes: 8 additions & 0 deletions packages/shared-base/src/SingletonModal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ export class SingletonModal<
private dispatchClose: ReturnType<T>['close'] | undefined
private dispatchAbort: ReturnType<T>['abort'] | undefined

constructor() {
this.register = this.register.bind(this)
this.open = this.open.bind(this)
this.close = this.close.bind(this)
this.abort = this.abort.bind(this)
this.openAndWaitForClose = this.openAndWaitForClose.bind(this)
}

/**
* Register a React modal component that implemented a forwarded ref.
* The ref item should be fed with open and close methods.
Expand Down
17 changes: 9 additions & 8 deletions packages/shared/src/modals/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { SingletonModal } from '@masknet/shared-base'
import { WalletConnectQRCode, type WalletConnectQRCodeOpenProps } from './WalletConnectQRCodeDialog/index.js'
import { memo } from 'react'
import { SelectProviderModal, type SelectProviderDialogOpenProps } from './SelectProviderDialog/index.js'
import { WalletStatusModal, type WalletStatusModalOpenProps } from './WalletStatusDialog/index.js'
import { WalletConnectQRCode, type WalletConnectQRCodeOpenProps } from './WalletConnectQRCodeDialog/index.js'
import { WalletRiskWarningModal, type WalletRiskWarningModalOpenProps } from './WalletRiskWarningDialog/index.js'
import { WalletStatusModal, type WalletStatusModalOpenProps } from './WalletStatusDialog/index.js'

export const WalletConnectQRCodeDialog = new SingletonModal<WalletConnectQRCodeOpenProps>()
export const SelectProviderDialog = new SingletonModal<SelectProviderDialogOpenProps>()
export const WalletStatusDialog = new SingletonModal<WalletStatusModalOpenProps>()
export const WalletRiskWarningDialog = new SingletonModal<WalletRiskWarningModalOpenProps>()

export function Modals() {
export const Modals = memo(function Modals() {
return (
<>
<WalletConnectQRCode ref={WalletConnectQRCodeDialog.register.bind(WalletConnectQRCodeDialog)} />
<SelectProviderModal ref={SelectProviderDialog.register.bind(SelectProviderDialog)} />
<WalletStatusModal ref={WalletStatusDialog.register.bind(WalletStatusDialog)} />
<WalletRiskWarningModal ref={WalletRiskWarningDialog.register.bind(WalletRiskWarningDialog)} />
<WalletConnectQRCode ref={WalletConnectQRCodeDialog.register} />
<SelectProviderModal ref={SelectProviderDialog.register} />
<WalletStatusModal ref={WalletStatusDialog.register} />
<WalletRiskWarningModal ref={WalletRiskWarningDialog.register} />
</>
)
}
})
2 changes: 1 addition & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function createURL(pathToFile: string) {

export default defineConfig({
test: {
include: ['./packages/**/tests/**/*.ts'],
include: ['./packages/**/tests/**/*.ts', './packages/**/*.test.ts'],
alias: {
'@masknet/base': createURL('./packages/base/src/index.ts'),
'@masknet/flags': createURL('./packages/flags/src/index.ts'),
Expand Down

0 comments on commit 4fe9cf9

Please sign in to comment.