From 4bd73d74bf9d57845707818da2882167ff1eff91 Mon Sep 17 00:00:00 2001 From: jadapema Date: Thu, 31 Jul 2025 18:14:26 -0600 Subject: [PATCH 1/7] feat: added publication share button --- .../publication-detail-main/index.tsx | 2 + src/components/share-button.tsx | 228 +++++++++++++++++ src/sections/publication/CONSTANTS.ts | 31 +++ .../components/publication-share.tsx | 27 ++ .../user/components/profile-share.tsx | 231 ++---------------- 5 files changed, 304 insertions(+), 215 deletions(-) create mode 100644 src/components/share-button.tsx create mode 100644 src/sections/publication/components/publication-share.tsx diff --git a/src/components/publication-detail-main/index.tsx b/src/components/publication-detail-main/index.tsx index 2bb25f5a0..5b892013b 100644 --- a/src/components/publication-detail-main/index.tsx +++ b/src/components/publication-detail-main/index.tsx @@ -56,6 +56,7 @@ import { } from '@src/graphql/generated/hooks.tsx'; import { resolveSrc } from '@src/utils/image.ts'; import { useBookmarks } from '@src/hooks/use-bookmark.ts'; +import PublicationShare from '@src/sections/publication/components/publication-share.tsx'; // ---------------------------------------------------------------------- @@ -413,6 +414,7 @@ export default function PublicationDetailMain({ )} + diff --git a/src/components/share-button.tsx b/src/components/share-button.tsx new file mode 100644 index 000000000..3335e5923 --- /dev/null +++ b/src/components/share-button.tsx @@ -0,0 +1,228 @@ +import { FC, useCallback, useEffect, useRef, useState } from 'react'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; +import Popover from '@mui/material/Popover'; +import Stack from '@mui/material/Stack'; +import { SxProps, Theme } from '@mui/material/styles'; +import Iconify from '@src/components/iconify'; +import { notifyError, notifySuccess } from '@src/libs/notifications/internal-notifications.ts'; +import { SUCCESS } from '@src/libs/notifications/success.ts'; +import { ERRORS } from '@src/libs/notifications/errors'; + +// ---------------------------------------------------------------------- + +interface BaseLink { + icon: string; + label: string; + url: string; +} + +interface ExtraIcon { + key: string; + icon: string; +} + +interface ShareButtonProps { + placeholder: string; + pathPrefix: string; + targetId: string; + shareLinks: BaseLink[]; + socialMediaList?: ExtraIcon[]; + socialMediaUrls?: Record; + templateUrl: string; + buttonVariant?: 'text' | 'outlined'; + buttonSx?: SxProps; +} + +// ---------------------------------------------------------------------- + +const ShareButton: FC = ({ + placeholder, + pathPrefix, + targetId, + shareLinks, + templateUrl, + socialMediaList, + socialMediaUrls, + buttonVariant = 'outlined', + buttonSx, + }) => { + const [openTooltipShare, setOpenTooltipShare] = useState(false); + const navRefSocial = useRef(null); + + const [anchorEl, setAnchorEl] = useState(null); + const openPopover = Boolean(anchorEl); + + const replacePlaceholder = (url: string) => + url.replace(placeholder, `${pathPrefix}${targetId}`); + + const pageUrl = templateUrl.replace(placeholder, `${pathPrefix}${targetId}`); + + const handlePopoverOpen = (e: React.MouseEvent) => { + setAnchorEl(e.currentTarget); + }; + + const handlePopoverClose = () => setAnchorEl(null); + + const handleOpenShare = useCallback(() => setOpenTooltipShare(true), []); + const handleCloseShare = useCallback(() => setOpenTooltipShare(false), []); + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(pageUrl); + notifySuccess(SUCCESS.LINK_COPIED_TO_CLIPBOARD); + } catch { + notifyError(ERRORS.LINK_COPIED_ERROR); + } + }; + + useEffect(() => { + if (openPopover) handleCloseShare(); + }, [openPopover, handleCloseShare]); + + return ( + <> + {socialMediaList?.map( + ({ key, icon }) => + socialMediaUrls?.[key] && ( + + ), + )} + + + + Share + + + + + Share link to this page + + + + {shareLinks.map((item) => ( + + + + {item.label} + + + ))} + + + + + Copy + + + + + + ); +}; + +export default ShareButton; diff --git a/src/sections/publication/CONSTANTS.ts b/src/sections/publication/CONSTANTS.ts index dcd8ba0de..787ddc3cf 100644 --- a/src/sections/publication/CONSTANTS.ts +++ b/src/sections/publication/CONSTANTS.ts @@ -3,3 +3,34 @@ export const MAX_LINES = 5; export const PUBLICATION_NEW_WIZARD_STEPS = ['Movie Information', 'Media Assets & Technical Details', 'Distribution & Rights']; export const PUBLICATION_DESCRIPTION_MAX_LINES = 4; + +export const urlToShare = 'https://app.watchit.movie/publicationId'; + +export const shareLinks = [ + { + icon: 'mingcute:social-x-line', + label: 'X', + url: `https://x.com/share/?url=${encodeURIComponent( + urlToShare, + )}&text=Watch%20this%20movie%20on%20Watchit&hashtags=Watchit,Movie,Streaming`, + }, + { + icon: 'mdi:facebook', + label: 'Facebook', + url: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(urlToShare)}`, + }, + { + icon: 'mdi:telegram', + label: 'Telegram', + url: `https://telegram.me/share/?url=${encodeURIComponent( + urlToShare, + )}&text=Watch%20this%20movie%20on%20Watchit`, + }, +]; + +export const socialMedia = [ + { key: 'twitter', icon: 'mingcute:social-x-line' }, + { key: 'instagram', icon: 'mdi:instagram' }, + { key: 'orb', icon: 'mdi:instagram' }, + { key: 'farcaster', icon: 'mdi:instagram' }, +]; diff --git a/src/sections/publication/components/publication-share.tsx b/src/sections/publication/components/publication-share.tsx new file mode 100644 index 000000000..19a1527b3 --- /dev/null +++ b/src/sections/publication/components/publication-share.tsx @@ -0,0 +1,27 @@ +import { FC } from 'react'; +import ShareButton from '@src/components/share-button'; +import { shareLinks, urlToShare } from '@src/sections/publication/CONSTANTS'; +import { Post } from '@src/graphql/generated/graphql.ts'; + +interface Props { + post: Post; +} + +const PublicationShare: FC = ({ post }) => ( + +); + +export default PublicationShare; diff --git a/src/sections/user/components/profile-share.tsx b/src/sections/user/components/profile-share.tsx index ad2b6865e..97832838f 100644 --- a/src/sections/user/components/profile-share.tsx +++ b/src/sections/user/components/profile-share.tsx @@ -1,218 +1,19 @@ -import { FC, useCallback, useEffect, useRef, useState } from 'react'; -import Button from '@mui/material/Button'; -import Typography from '@mui/material/Typography'; -import Popover from '@mui/material/Popover'; -import Stack from '@mui/material/Stack'; -import Iconify from '@src/components/iconify'; -import { notifyError, notifySuccess } from '@src/libs/notifications/internal-notifications.ts'; -import { SUCCESS } from '@src/libs/notifications/success.ts'; -import { ERRORS } from '@src/libs/notifications/errors'; -import { ProfileShareProps, SocialMediaUrls } from '../types'; -import { shareLinks, socialMedia, urlToShare } from '../CONSTANTS' +import { FC } from 'react'; +import ShareButton from '@src/components/share-button'; +import { shareLinks, socialMedia, urlToShare } from '../CONSTANTS'; import { getSocialLinks } from '@src/utils/profile.ts'; - -const ProfileShare: FC = ({ profile }) => { - const [openTooltipShare, setOpenTooltipShare] = useState(false); - const navRefSocial = useRef(null); - const [anchorEl, setAnchorEl] = useState(null); - const open = Boolean(anchorEl); - const socialMediaUrls = getSocialLinks(profile); - - const prependProfileIdToUrl = (url: string, profileId: string) => { - return url.replace('profileId', 'profile/' + profileId); - }; - - const handlePopoverOpen = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - - const handleOpenShare = useCallback(() => { - setOpenTooltipShare(true); - }, []); - - const handleCloseShare = useCallback(() => { - setOpenTooltipShare(false); - }, []); - - const handlePopoverClose = () => { - setAnchorEl(null); - }; - - const handleCopy = async () => { - try { - await navigator.clipboard.writeText( - urlToShare.replace('profileId', 'profile/' + profile?.address) - ); - notifySuccess(SUCCESS.LINK_COPIED_TO_CLIPBOARD); - } catch (err) { - console.log('Error', err); - notifyError(ERRORS.LINK_COPIED_ERROR); - } - }; - - const handleClose = useCallback(() => { - setOpenTooltipShare(false); - }, []); - - useEffect(() => { - if (open) { - handleClose(); - } - }, [handleClose, open]); - - return ( - <> - {socialMedia.map( - ({ key, icon }) => - socialMediaUrls[key as keyof SocialMediaUrls] && ( - - ) - )} - - - - Share - - - - - Share link to this page - - - {shareLinks.map((item) => ( - - - - {item.label} - - - ))} - - - - Copy - - - - - - ); -}; +import { ProfileShareProps } from '../types'; + +const ProfileShare: FC = ({ profile }) => ( + +); export default ProfileShare; From 76ab52033e5d9c928a0525bd940e8b2c3f4bf11c Mon Sep 17 00:00:00 2001 From: jadapema Date: Fri, 1 Aug 2025 14:00:30 -0600 Subject: [PATCH 2/7] feat: measure --- index.html | 1 + src/components/app-ready.tsx | 6 ++++++ src/index.tsx | 2 ++ stats.html | 2 +- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 1bac71282..8c659d7f7 100644 --- a/index.html +++ b/index.html @@ -146,6 +146,7 @@
+