feat(component): add private copy link button (#4508)

This commit is contained in:
JimmFly
2023-09-27 12:54:02 +08:00
committed by GitHub
parent ddfa5d394d
commit 1df8b6edfb
5 changed files with 99 additions and 24 deletions

View File

@@ -1,4 +1,4 @@
import { style } from '@vanilla-extract/css';
import { globalStyle, style } from '@vanilla-extract/css';
export const menuItemStyle = style({
padding: '4px',
@@ -12,6 +12,7 @@ export const descriptionStyle = style({
lineHeight: '20px',
color: 'var(--affine-text-secondary-color)',
textAlign: 'left',
padding: '0 2px',
});
export const buttonStyle = style({
@@ -66,7 +67,7 @@ export const columnContainerStyle = style({
justifyContent: 'center',
padding: '0 4px',
width: '100%',
gap: '12px',
gap: '8px',
});
export const rowContainerStyle = style({
@@ -131,3 +132,18 @@ export const shareIconStyle = style({
display: 'flex',
alignItems: 'center',
});
export const shareLinkStyle = style({
padding: '4px',
fontSize: 'var(--affine-font-xs)',
fontWeight: 500,
lineHeight: '20px',
transform: 'translateX(-4px)',
gap: '4px',
});
globalStyle(`${shareLinkStyle} > span`, {
color: 'var(--affine-link-color)',
});
globalStyle(`${shareLinkStyle} > div > svg`, {
color: 'var(--affine-link-color)',
});

View File

@@ -1,4 +1,7 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { LinkIcon } from '@blocksuite/icons';
import { Button } from '@toeverything/components/button';
import { Divider } from '@toeverything/components/divider';
import {
ExportToHtmlMenuItem,
@@ -7,9 +10,19 @@ import {
ExportToPngMenuItem,
} from '../page-list/operation-menu-items/export';
import * as styles from './index.css';
import type { ShareMenuProps } from './share-menu';
import { useSharingUrl } from './use-share-url';
export const ShareExport = () => {
export const ShareExport = (props: ShareMenuProps) => {
const t = useAFFiNEI18N();
const workspaceId = props.workspace.id;
const pageId = props.currentPage.id;
const { onClickCopyLink } = useSharingUrl({
workspaceId,
pageId,
urlType: 'workspace',
});
return (
<>
<div className={styles.titleContainerStyle} style={{ fontWeight: '500' }}>
@@ -25,6 +38,17 @@ export const ShareExport = () => {
<div className={styles.descriptionStyle}>
{t['com.affine.share-menu.ShareViaExportDescription']()}
</div>
<Divider size="thinner" />
<div>
<Button
className={styles.shareLinkStyle}
onClick={onClickCopyLink}
icon={<LinkIcon />}
type="plain"
>
{t['Copy Link']()}
</Button>
</div>
</div>
</>
);

View File

@@ -13,7 +13,6 @@ import { Menu } from '@toeverything/components/menu';
import * as styles from './index.css';
import { ShareExport } from './share-export';
import { SharePage } from './share-page';
export interface ShareMenuProps<
Workspace extends AffineOfficialWorkspace =
| AffineCloudWorkspace
@@ -43,7 +42,7 @@ export const ShareMenu = (props: ShareMenuProps) => {
<div className={styles.columnContainerStyle}>
<Divider size="thinner" />
</div>
<ShareExport />
<ShareExport {...props} />
</div>
);
return (

View File

@@ -5,13 +5,14 @@ import { ArrowRightSmallIcon, WebIcon } from '@blocksuite/icons';
import { Button } from '@toeverything/components/button';
import { Menu, MenuItem, MenuTrigger } from '@toeverything/components/menu';
import { useState } from 'react';
import { useCallback, useMemo } from 'react';
import { useCallback } from 'react';
import Input from '../../ui/input';
import { toast } from '../../ui/toast';
import { PublicLinkDisableModal } from './disable-public-link';
import * as styles from './index.css';
import type { ShareMenuProps } from './share-menu';
import { useSharingUrl } from './use-share-url';
const CloudSvg = () => (
<svg
@@ -74,32 +75,19 @@ export const AffineSharePage = (props: ShareMenuProps) => {
workspace: { id: workspaceId },
currentPage: { id: pageId },
} = props;
const [isPublic, setIsPublic] = props.useIsSharedPage(workspaceId, pageId);
const [showDisable, setShowDisable] = useState(false);
const { sharingUrl, onClickCopyLink } = useSharingUrl({
workspaceId,
pageId,
urlType: 'share',
});
const t = useAFFiNEI18N();
const sharingUrl = useMemo(() => {
return `${runtimeConfig.serverUrlPrefix}/share/${workspaceId}/${pageId}`;
}, [workspaceId, pageId]);
const onClickCreateLink = useCallback(() => {
setIsPublic(true);
}, [setIsPublic]);
const onClickCopyLink = useCallback(() => {
navigator.clipboard
.writeText(sharingUrl)
.then(() => {
toast(t['Copied link to clipboard']());
})
.catch(err => {
console.error(err);
});
}, [sharingUrl, t]);
const onDisablePublic = useCallback(() => {
setIsPublic(false);
toast('Successfully disabled', {

View File

@@ -0,0 +1,48 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useCallback, useMemo } from 'react';
import { toast } from '../../ui/toast';
type UrlType = 'share' | 'workspace';
type UseSharingUrl = {
workspaceId: string;
pageId: string;
urlType: UrlType;
};
export const generateUrl = ({
workspaceId,
pageId,
urlType,
}: UseSharingUrl) => {
return `${runtimeConfig.serverUrlPrefix}/${urlType}/${workspaceId}/${pageId}`;
};
export const useSharingUrl = ({
workspaceId,
pageId,
urlType,
}: UseSharingUrl) => {
const t = useAFFiNEI18N();
const sharingUrl = useMemo(
() => generateUrl({ workspaceId, pageId, urlType }),
[urlType, workspaceId, pageId]
);
const onClickCopyLink = useCallback(() => {
navigator.clipboard
.writeText(sharingUrl)
.then(() => {
toast(t['Copied link to clipboard']());
})
.catch(err => {
console.error(err);
});
}, [sharingUrl, t]);
return {
sharingUrl,
onClickCopyLink,
};
};