Last active: 2 years ago
import { isMobile } from '@/data';
import openIcon from '@/projects/viewer/assets/images/navi-page/打开.png';
import closeIcon from '@/projects/viewer/assets/images/navi-page/收起.png';
import { useBoolean } from 'ahooks';
import { nanoid } from 'nanoid';
import { useCallback, useEffect, useMemo } from 'react';
import styled, { css } from 'styled-components';
const IntelligenceQA = () => {
// 控制 iframe opacity
const [showIframe, setShowIframe] = useBoolean(false);
// 控制 iframe display
const [display, setDisplay] = useBoolean(false);
const handleClose = () => {
if (showIframe) {
setShowIframe.toggle();
setTimeout(setDisplay.toggle, 300);
} else {
setDisplay.toggle();
// 在下个任务队列中设置 opacity 才能配合 display none 显示动画
setTimeout(setShowIframe.toggle, 0);
}
};
// 点击任意处关闭
const id = useMemo(() => nanoid(), []);
const clickToClose = useCallback((e: MouseEvent | TouchEvent) => {
if (parentIdChecker(e.target as HTMLElement)) return;
setShowIframe.setFalse();
setTimeout(setDisplay.setFalse, 300);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const parentIdChecker = (el: HTMLElement | null): boolean => {
if (!el) return false;
if (!el?.id) return parentIdChecker(el.parentElement);
return el.id === id || parentIdChecker(el.parentElement);
};
// iframe 内点击不会触发
useEffect(() => {
window.addEventListener('click', clickToClose, true);
window.addEventListener('touchstart', clickToClose, true);
return () => {
window.removeEventListener('click', clickToClose, true);
window.removeEventListener('touchstart', clickToClose, true);
};
}, [clickToClose]);
return (
<Wrapper id={id}>
<Icon onClick={handleClose} show={showIframe}>
<OpenWrapper show={showIframe}>
<span>我们聊会天吧…</span>
</OpenWrapper>
<CloseIcon src={closeIcon} show={showIframe} />
</Icon>
<Frame show={showIframe} display={display}>
<iframe title="QA" src="https://airobot.showinfo.com.cn/#/"></iframe>
</Frame>
</Wrapper>
);
};
export default IntelligenceQA;
export const Wrapper = styled.div`
position: fixed;
bottom: 0.4rem;
right: 0.4rem;
`;
export const Icon = styled.div<{ show: boolean }>`
cursor: pointer;
border-radius: 1rem;
overflow: hidden;
height: 0.52rem;
position: relative;
width: 2.08rem;
transition: all 0.3s ease;
${({ show }) =>
css`
max-width: ${!show ? '2.08rem' : '0.5rem'};
`}
`;
export const CloseIcon = styled.img<{ show: boolean }>`
width: 0.52rem;
height: 0.52rem;
position: absolute;
transition: all 0.3s ease;
${({ show }) =>
css`
opacity: ${show ? 1 : 0};
`}
`;
export const OpenWrapper = styled.div<{ show: boolean }>`
width: 2.08rem;
height: 0.52rem;
background-image: url(${openIcon});
background-position: center;
background-size: contain;
display: flex;
align-items: center;
font-size: 0.18rem;
color: #ea6307;
transition: all 0.3s ease;
position: absolute;
${({ show }) =>
css`
opacity: ${!show ? 1 : 0};
`}
span {
margin-left: 0.6rem;
}
`;
export const Frame = styled.div<{ show: boolean; display: boolean }>`
position: absolute;
right: 0;
height: ${isMobile ? '80vh' : '86vh'};
width: 4rem;
transition: all 0.3s ease;
@media screen and (orientation: portrait) {
height: 80vw;
}
& iframe {
width: 100%;
height: 100%;
border: none;
border-radius: 0.1rem;
}
${({ show, display }) => css`
bottom: ${show ? '110%' : '80%'};
opacity: ${show ? 1 : 0};
display: ${display ? 'block' : 'none'};
`}
`;