mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
feat(component): add private copy link button (#4508)
This commit is contained in:
@@ -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)',
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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', {
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user