client: update layout

This commit is contained in:
fantasticit 2022-05-30 17:31:46 +08:00
parent 1c782e23ad
commit 19924b740b
1 changed files with 89 additions and 78 deletions

View File

@ -1,12 +1,12 @@
import { IconLink } from '@douyinfe/semi-icons'; import { IconLink } from '@douyinfe/semi-icons';
import { Button, Input, Modal, Toast, Typography } from '@douyinfe/semi-ui'; import { Button, Input, Popover, Space, Toast, Typography } from '@douyinfe/semi-ui';
import { isPublicDocument } from '@think/domains'; import { isPublicDocument } from '@think/domains';
import { DataRender } from 'components/data-render';
import { useDocumentDetail } from 'data/document'; import { useDocumentDetail } from 'data/document';
import { getDocumentShareURL } from 'helpers/url'; import { getDocumentShareURL } from 'helpers/url';
import { IsOnMobile } from 'hooks/use-on-mobile';
import { useToggle } from 'hooks/use-toggle'; import { useToggle } from 'hooks/use-toggle';
import { ShareIllustration } from 'illustrations/share'; import { ShareIllustration } from 'illustrations/share';
import React, { useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
interface IProps { interface IProps {
documentId: string; documentId: string;
@ -17,23 +17,104 @@ interface IProps {
const { Text } = Typography; const { Text } = Typography;
export const DocumentShare: React.FC<IProps> = ({ documentId, disabled = false, render }) => { export const DocumentShare: React.FC<IProps> = ({ documentId, disabled = false, render }) => {
const { isMobile } = IsOnMobile.useHook();
const ref = useRef<HTMLInputElement>();
const [visible, toggleVisible] = useToggle(false); const [visible, toggleVisible] = useToggle(false);
const { data, loading, error, toggleStatus } = useDocumentDetail(documentId, { enabled: visible }); const { data, loading, toggleStatus } = useDocumentDetail(documentId, { enabled: visible });
const [sharePassword, setSharePassword] = useState(''); const [sharePassword, setSharePassword] = useState('');
const isPublic = useMemo(() => data && isPublicDocument(data.document.status), [data]); const isPublic = useMemo(() => data && isPublicDocument(data.document.status), [data]);
const shareUrl = useMemo(() => data && getDocumentShareURL(data.document.id), [data]); const shareUrl = useMemo(() => data && getDocumentShareURL(data.document.id), [data]);
const handleOk = () => { const copyable = useMemo(
() => ({
onCopy: () => Toast.success({ content: '复制文本成功' }),
}),
[]
);
const prevent = useCallback((e) => {
e.stopPropagation();
}, []);
const viewUrl = useCallback(() => {
window.open(shareUrl, '_blank');
}, [shareUrl]);
const handleOk = useCallback(() => {
toggleStatus({ sharePassword: isPublic ? '' : sharePassword }); toggleStatus({ sharePassword: isPublic ? '' : sharePassword });
}; }, [isPublic, sharePassword, toggleStatus]);
useEffect(() => { useEffect(() => {
if (loading || !data) return; if (loading || !data) return;
setSharePassword(data.document && data.document.sharePassword); setSharePassword(data.document && data.document.sharePassword);
}, [loading, data]); }, [loading, data]);
useEffect(() => {
if (visible) {
setTimeout(() => ref.current?.focus(), 100);
}
}, [visible]);
return ( return (
<> <Popover
showArrow
visible={visible}
onVisibleChange={toggleVisible}
trigger="click"
position={isMobile ? 'top' : 'bottomLeft'}
style={{ width: 376, maxWidth: '80vw' }}
content={
<div
style={{
maxHeight: '70vh',
overflow: 'auto',
}}
onClick={prevent}
>
<div style={{ textAlign: 'center' }}>
<ShareIllustration />
</div>
{isPublic ? (
<Text
ellipsis
icon={<IconLink />}
copyable={copyable}
style={{
width: 240,
}}
>
{shareUrl}
</Text>
) : (
<Input
ref={ref}
mode="password"
placeholder="设置访问密码"
value={sharePassword}
onChange={setSharePassword}
></Input>
)}
<div style={{ marginTop: 16 }}>
<Text type="tertiary">
{isPublic
? '分享开启后,该页面包含的所有内容均可访问,请谨慎开启'
: ' 分享关闭后,其他人将不能继续访问该页面'}
</Text>
</div>
<Space style={{ width: '100%', justifyContent: 'end', margin: '12px 0' }}>
<Button onClick={() => toggleVisible(false)}></Button>
<Button theme="solid" type={isPublic ? 'danger' : 'primary'} onClick={handleOk}>
{isPublic ? '关闭分享' : '开启分享'}
</Button>
{isPublic && (
<Button theme="solid" type="primary" onClick={viewUrl}>
</Button>
)}
</Space>
</div>
}
>
{render ? ( {render ? (
render({ isPublic, disabled, toggleVisible }) render({ isPublic, disabled, toggleVisible })
) : ( ) : (
@ -41,76 +122,6 @@ export const DocumentShare: React.FC<IProps> = ({ documentId, disabled = false,
{isPublic ? '分享中' : '分享'} {isPublic ? '分享中' : '分享'}
</Button> </Button>
)} )}
<Modal </Popover>
title={isPublic ? '关闭分享' : '开启分享'}
okText={isPublic ? '关闭分享' : '开启分享'}
visible={visible}
onOk={handleOk}
onCancel={() => toggleVisible(false)}
style={{ maxWidth: '96vw' }}
footer={
<>
<Button onClick={() => toggleVisible(false)}></Button>
<Button theme="solid" type={isPublic ? 'danger' : 'primary'} onClick={handleOk}>
{isPublic ? '关闭分享' : '开启分享'}
</Button>
{isPublic && (
<Button
theme="solid"
type="primary"
onClick={() => {
window.open(shareUrl, '_blank');
}}
>
</Button>
)}
</>
}
>
<DataRender
loading={loading}
error={error}
normalContent={() => {
return (
<div>
<div style={{ textAlign: 'center' }}>
<ShareIllustration />
</div>
{isPublic ? (
<Text
ellipsis
icon={<IconLink />}
copyable={{
onCopy: () => Toast.success({ content: '复制文本成功' }),
}}
style={{
width: 320,
}}
>
{shareUrl}
</Text>
) : (
<Input
autofocus
mode="password"
placeholder="设置访问密码"
value={sharePassword}
onChange={setSharePassword}
></Input>
)}
<div style={{ marginTop: 16 }}>
<Text type="tertiary">
{isPublic
? '分享开启后,该页面包含的所有内容均可访问,请谨慎开启'
: ' 分享关闭后,其他人将不能继续访问该页面'}
</Text>
</div>
</div>
);
}}
/>
</Modal>
</>
); );
}; };