feat(post menu): add copy link button (share link)

This commit is contained in:
Tom (plebeius.eth)
2024-05-27 18:42:31 +02:00
parent 219c05b6d1
commit caacd77bba
2 changed files with 83 additions and 62 deletions
+82 -61
View File
@@ -3,13 +3,86 @@ import { autoUpdate, flip, FloatingFocusManager, offset, shift, useClick, useDis
import { Comment } from '@plebbit/plebbit-react-hooks';
import styles from './post-menu.module.css';
import { getCommentMediaInfo } from '../../../lib/utils/media-utils';
import { isValidURL } from '../../../lib/utils/url-utils';
import { copyShareLinkToClipboard, isValidURL } from '../../../lib/utils/url-utils';
const PostMenu = ({ post }: Comment) => {
const { cid, isDescription, isRules, link, subplebbitAddress } = post;
const [menuBtnRotated, setMenuBtnRotated] = useState(false);
const [isClientRedirectMenuOpen, setIsClientRedirectMenuOpen] = useState(false);
interface PostMenuProps {
cid: string;
isDescription?: boolean;
isRules?: boolean;
subplebbitAddress: string;
onClose: () => void;
}
const CopyLinkButton = ({ cid, subplebbitAddress, onClose }: PostMenuProps) => {
return (
<div
onClick={() => {
copyShareLinkToClipboard(subplebbitAddress, cid);
onClose();
}}
>
<div className={styles.postMenuItem}>Copy link</div>
</div>
);
};
const ImageSearchButton = ({ url, onClose }: { url: string; onClose: () => void }) => {
const [isImageSearchMenuOpen, setIsImageSearchMenuOpen] = useState(false);
return (
<div
className={`${styles.postMenuItem} ${styles.dropdown}`}
onMouseOver={() => setIsImageSearchMenuOpen(true)}
onMouseLeave={() => setIsImageSearchMenuOpen(false)}
onClick={onClose}
>
Image search »
{isImageSearchMenuOpen && (
<div className={styles.dropdownMenu}>
<a href={`https://lens.google.com/uploadbyurl?url=${url}`} target='_blank' rel='noreferrer'>
<div className={styles.postMenuItem}>Google</div>
</a>
<a href={`https://www.yandex.com/images/search?img_url=${url}&rpt=imageview`} target='_blank' rel='noreferrer'>
<div className={styles.postMenuItem}>Yandex</div>
</a>
<a href={`https://saucenao.com/search.php?url=${url}`} target='_blank' rel='noreferrer'>
<div className={styles.postMenuItem}>SauceNAO</div>
</a>
</div>
)}
</div>
);
};
const ViewOnButton = ({ cid, isDescription, isRules, subplebbitAddress, onClose }: PostMenuProps) => {
const [isClientRedirectMenuOpen, setIsClientRedirectMenuOpen] = useState(false);
const viewOnOtherClientLink = `p/${subplebbitAddress}${isDescription || isRules ? '' : `/c/${cid}`}`;
return (
<div
className={`${styles.postMenuItem} ${styles.dropdown}`}
onMouseOver={() => setIsClientRedirectMenuOpen(true)}
onMouseLeave={() => setIsClientRedirectMenuOpen(false)}
onClick={onClose}
>
View on »
{isClientRedirectMenuOpen && (
<div className={styles.dropdownMenu}>
<a href={`https://seedit.app/#/${viewOnOtherClientLink}`} target='_blank' rel='noreferrer'>
<div className={styles.postMenuItem}>Seedit</div>
</a>
<a href={`https://plebones.netlify.app/#/${viewOnOtherClientLink}`} target='_blank' rel='noreferrer'>
<div className={styles.postMenuItem}>Plebones</div>
</a>
</div>
)}
</div>
);
};
const PostMenu = ({ post }: { post: Comment }) => {
const { cid, isDescription, isRules, link, subplebbitAddress } = post;
const commentMediaInfo = getCommentMediaInfo(post);
const { thumbnail, type, url } = commentMediaInfo || {};
const [menuBtnRotated, setMenuBtnRotated] = useState(false);
const { refs, floatingStyles, context } = useFloating({
placement: 'bottom-start',
@@ -18,19 +91,13 @@ const PostMenu = ({ post }: Comment) => {
middleware: [offset({ mainAxis: 10, crossAxis: 5 }), flip({ fallbackAxisSideDirection: 'end' }), shift({ padding: 10 })],
whileElementsMounted: autoUpdate,
});
const click = useClick(context);
const dismiss = useDismiss(context);
const role = useRole(context);
const { getReferenceProps, getFloatingProps } = useInteractions([click, dismiss, role]);
const headingId = useId();
const viewOnOtherClientLink = `p/${subplebbitAddress}${isDescription || isRules ? '' : `/c/${cid}`}`;
const commentMediaInfo = getCommentMediaInfo(post);
const { thumbnail, type, url } = commentMediaInfo || {};
const handleClose = () => setMenuBtnRotated(false);
return (
<>
@@ -47,55 +114,9 @@ const PostMenu = ({ post }: Comment) => {
{menuBtnRotated && (
<FloatingFocusManager context={context} modal={false}>
<div className={styles.postMenu} ref={refs.setFloating} style={floatingStyles} aria-labelledby={headingId} {...getFloatingProps()}>
{link && isValidURL(link) && (type === 'image' || type === 'gif' || thumbnail) && (
<div
className={`${styles.postMenuItem} ${styles.dropdown}`}
onMouseOver={() => setIsImageSearchMenuOpen(true)}
onMouseLeave={() => setIsImageSearchMenuOpen(false)}
>
Image search »
{isImageSearchMenuOpen && (
<div className={styles.dropdownMenu}>
<div className={styles.postMenuItem}>
<a href={`https://lens.google.com/uploadbyurl?url=${url}`} target='_blank' rel='noreferrer'>
Google
</a>
</div>
<div className={styles.postMenuItem}>
<a href={`https://www.yandex.com/images/search?img_url=${url}&rpt=imageview`} target='_blank' rel='noreferrer'>
Yandex
</a>
</div>
<div className={styles.postMenuItem}>
<a href={`https://saucenao.com/search.php?url=${url}`} target='_blank' rel='noreferrer'>
SauceNAO
</a>
</div>
</div>
)}
</div>
)}
<div
className={`${styles.postMenuItem} ${styles.dropdown}`}
onMouseOver={() => setIsClientRedirectMenuOpen(true)}
onMouseLeave={() => setIsClientRedirectMenuOpen(false)}
>
View on »
{isClientRedirectMenuOpen && (
<div className={styles.dropdownMenu}>
<div className={styles.postMenuItem}>
<a href={`https://seedit.app/#/${viewOnOtherClientLink}`} target='_blank' rel='noreferrer'>
Seedit
</a>
</div>
<div className={styles.postMenuItem}>
<a href={`https://plebones.netlify.app/#/${viewOnOtherClientLink}`} target='_blank' rel='noreferrer'>
Plebones
</a>
</div>
</div>
)}
</div>
{cid && subplebbitAddress && <CopyLinkButton cid={cid} subplebbitAddress={subplebbitAddress} onClose={handleClose} />}
{link && isValidURL(link) && (type === 'image' || type === 'gif' || thumbnail) && url && <ImageSearchButton url={url} onClose={handleClose} />}
<ViewOnButton cid={cid} isDescription={isDescription} isRules={isRules} subplebbitAddress={subplebbitAddress} onClose={handleClose} />
</div>
</FloatingFocusManager>
)}
+1 -1
View File
@@ -16,7 +16,7 @@ export const isValidURL = (url: string) => {
};
export const copyShareLinkToClipboard = (subplebbitAddress: string, cid: string) => {
const shareLink = `https://pleb.bz/p/${subplebbitAddress}/c/${cid}`;
const shareLink = `https://pleb.bz/p/${subplebbitAddress}/c/${cid}?redirect=plebchan.eth.limo`;
if (navigator.clipboard) {
navigator.clipboard.writeText(shareLink);