Skip to content

Commit 28c0a66

Browse files
committed
feat(closable iframe): iframe closeable
1 parent 5b88f26 commit 28c0a66

File tree

1 file changed

+103
-25
lines changed

1 file changed

+103
-25
lines changed

src/utils/common.ts

Lines changed: 103 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import { Provider } from '../provider'
1111
/**
1212
* Check the window width to decide whether to show in full screen
1313
*/
14-
export const isPhone = () => {
15-
return window.screen.width < 500
14+
export const isFullScreen = () => {
15+
return window.innerWidth < 500
1616
}
1717

1818
/**
@@ -34,6 +34,88 @@ export interface IIframeOptions {
3434
waitResult?: boolean
3535
}
3636

37+
export const getIframe = async (
38+
url: string,
39+
onClose: () => void
40+
): Promise<HTMLDivElement> => {
41+
const div = document.createElement('div')
42+
const iframe = document.createElement('iframe')
43+
const button = document.createElement('div')
44+
const style = document.createElement('style')
45+
style.innerHTML = ` .iframe-contain {
46+
position: fixed;
47+
background: #FFFFFF;
48+
border: 1px solid #EAEAEA;
49+
z-index: 999999999;
50+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
51+
border-radius: 15px;
52+
width: 414px;
53+
height: 736px;
54+
transform: translate(-50%, -50%);
55+
top: 50%;
56+
left: 50%;
57+
}
58+
59+
.iframe {
60+
border-radius: 15px;
61+
height: 100%;
62+
width: 100%;
63+
z-index: 1;
64+
}
65+
66+
.iframe-contain-button {
67+
border-radius: 9px;
68+
background: rgba(130, 138, 147, 0.5);
69+
width: 18px;
70+
height: 18px;
71+
z-index: 2;
72+
position: absolute;
73+
top: ${isFullScreen() ? '0' : '-9px'};
74+
right: ${isFullScreen() ? '0' : '-9px'};
75+
cursor: pointer;
76+
}
77+
78+
.iframe-contain-button:before {
79+
position: absolute;
80+
content: '';
81+
width: 2px;
82+
height: 12px;
83+
background: black;
84+
top: 50%;
85+
left: 50%;
86+
transform: translate(-50%, -50%) rotate(45deg);
87+
}
88+
89+
.iframe-contain-button:after {
90+
content: '';
91+
position: absolute;
92+
width: 2px;
93+
height: 12px;
94+
background: black;
95+
transform: translate(-50%, -50%) rotate(-45deg);
96+
top: 50%;
97+
left: 50%;
98+
}
99+
`
100+
div.className = 'iframe-contain'
101+
button.className = 'iframe-contain-button'
102+
iframe.className = 'iframe'
103+
div.id = 'anyweb-iframe-contain'
104+
div.style.width = isFullScreen() ? '100%' : '414px'
105+
div.style.height = isFullScreen() ? '100%' : '736px'
106+
iframe.setAttribute('src', url)
107+
iframe.setAttribute('frameborder', '0')
108+
iframe.setAttribute('scrolling', 'none')
109+
div.insertBefore(iframe, div.firstElementChild)
110+
div.insertBefore(button, div.firstElementChild)
111+
button.onclick = () => {
112+
onClose()
113+
div.remove()
114+
}
115+
document.body.appendChild(style)
116+
document.body.insertBefore(div, document.body.firstElementChild)
117+
return div
118+
}
37119
export const callIframe = async (
38120
path: string,
39121
{
@@ -45,18 +127,9 @@ export const callIframe = async (
45127
waitResult = true,
46128
}: IIframeOptions
47129
) => {
48-
const hash = sha512(JSON.stringify({ appId, params }))
49-
const iframe = document.createElement('iframe')
50130
let serialNumber = ''
51-
iframe.style.width = isPhone() ? '100%' : '414px'
52-
iframe.style.height = isPhone() ? '100%' : '736px'
53-
iframe.style.position = 'fixed'
54-
iframe.style.top = '50%'
55-
iframe.style.left = '50%'
56-
iframe.style.zIndex = '9999'
57-
iframe.style.transform = 'translate(-50%, -50%)'
58-
iframe.style.background = 'white'
59-
iframe.id = 'anyweb'
131+
const hash = sha512(JSON.stringify({ appId, params }))
132+
60133
try {
61134
serialNumber = (
62135
await axios.post(`${API_BASE_URL}/open/serial/create`, {
@@ -67,18 +140,23 @@ export const callIframe = async (
67140
console.error('Get serialNumber error', e)
68141
throw new Error('Get serialNumber error')
69142
}
70-
iframe.setAttribute(
71-
'src',
72-
`${BASE_URL}${path}?appId=${appId}&authType=${authType}&serialNumber=${serialNumber}&hash=${hash}&random=${Math.floor(
73-
Math.random() * 1000
74-
)}&chainId=${chainId}&params=${params}&scope=${JSON.stringify(scope)}`
75-
)
76-
document.body.insertBefore(iframe, document.body.firstElementChild)
77143
if (waitResult) {
78144
return new Promise<unknown>(async (resolve, reject) => {
145+
let timer: NodeJS.Timeout | undefined = undefined
146+
const iframeContain = await getIframe(
147+
`${BASE_URL}${path}?appId=${appId}&authType=${authType}&serialNumber=${serialNumber}&hash=${hash}&random=${Math.floor(
148+
Math.random() * 1000
149+
)}&chainId=${chainId}&params=${params}&scope=${JSON.stringify(scope)}`,
150+
() => {
151+
if (timer) {
152+
clearTimeout(timer)
153+
reject(new Error('User cancel'))
154+
}
155+
}
156+
)
79157
const delay = 800
80158
const next = (i: number) => {
81-
const timer = setTimeout(async () => {
159+
timer = setTimeout(async () => {
82160
try {
83161
const data = (
84162
await axios.post(`${API_BASE_URL}/open/serial/read`, {
@@ -87,13 +165,13 @@ export const callIframe = async (
87165
})
88166
).data.data
89167
if (data && data !== 'false' && data !== false) {
90-
clearTimeout(timer)
91-
document.getElementById('anyweb')?.remove()
168+
timer && clearTimeout(timer)
169+
iframeContain.remove()
92170
resolve(JSON.parse(data))
93171
} else {
94172
if (i * delay > 10 * 60 * 1000) {
95-
document.getElementById('anyweb')?.remove()
96-
reject('time out')
173+
iframeContain.remove()
174+
reject(new Error('Timeout'))
97175
}
98176
next(i++)
99177
}

0 commit comments

Comments
 (0)