mirror of
https://github.com/filecoin-project/slate.git
synced 2024-11-23 14:07:20 +03:00
feat(CollectionSharingModal): remove Share modal
This commit is contained in:
parent
81b80b7495
commit
2bc7c10030
@ -51,7 +51,6 @@ import CTATransition from "~/components/core/CTATransition";
|
|||||||
import { GlobalModal } from "~/components/system/components/GlobalModal";
|
import { GlobalModal } from "~/components/system/components/GlobalModal";
|
||||||
import { OnboardingModal } from "~/components/core/OnboardingModal";
|
import { OnboardingModal } from "~/components/core/OnboardingModal";
|
||||||
import { SearchModal } from "~/components/core/SearchModal";
|
import { SearchModal } from "~/components/core/SearchModal";
|
||||||
import { CollectionSharingModal } from "~/components/core/ShareModals/CollectionSharingModal";
|
|
||||||
import { Alert } from "~/components/core/Alert";
|
import { Alert } from "~/components/core/Alert";
|
||||||
import { announcements } from "~/components/core/OnboardingModal";
|
import { announcements } from "~/components/core/OnboardingModal";
|
||||||
import { Logo } from "~/common/logo";
|
import { Logo } from "~/common/logo";
|
||||||
@ -519,7 +518,6 @@ export default class ApplicationPage extends React.Component {
|
|||||||
onAction={this._handleAction}
|
onAction={this._handleAction}
|
||||||
isMobile={this.props.isMobile}
|
isMobile={this.props.isMobile}
|
||||||
/>
|
/>
|
||||||
<CollectionSharingModal />
|
|
||||||
<CTATransition onAction={this._handleAction} />
|
<CTATransition onAction={this._handleAction} />
|
||||||
{/* {!this.state.loaded ? (
|
{/* {!this.state.loaded ? (
|
||||||
<div
|
<div
|
||||||
|
@ -3,7 +3,6 @@ import * as Styles from "~/common/styles";
|
|||||||
import * as SVG from "~/common/svg";
|
import * as SVG from "~/common/svg";
|
||||||
|
|
||||||
import { css } from "@emotion/react";
|
import { css } from "@emotion/react";
|
||||||
import { useCollectionSharingModal } from "~/components/core/ShareModals/CollectionSharingModal";
|
|
||||||
|
|
||||||
const STYLES_BUTTON = (theme) => css`
|
const STYLES_BUTTON = (theme) => css`
|
||||||
${Styles.BUTTON_RESET};
|
${Styles.BUTTON_RESET};
|
||||||
@ -28,15 +27,14 @@ const STYLES_BUTTON = (theme) => css`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export default function ShareButton({ user, collection, preview, ...props }) {
|
export default function ShareButton({ user, collection, preview, ...props }) {
|
||||||
const { openModal } = useCollectionSharingModal();
|
|
||||||
const handleOnClick = (e) => {
|
const handleOnClick = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
openModal({
|
// openModal({
|
||||||
user,
|
// user,
|
||||||
collection,
|
// collection,
|
||||||
preview,
|
// preview,
|
||||||
});
|
// });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,155 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import * as Events from "~/common/custom-events";
|
|
||||||
import * as Styles from "~/common/styles";
|
|
||||||
import * as SVG from "~/common/svg";
|
|
||||||
import * as Utilities from "~/common/utilities";
|
|
||||||
|
|
||||||
import { css } from "@emotion/react";
|
|
||||||
import { P3 } from "~/components/system/components/Typography";
|
|
||||||
import { Divider } from "~/components/system";
|
|
||||||
import { motion } from "framer-motion";
|
|
||||||
import { useEventListener, useTimeout } from "~/common/hooks";
|
|
||||||
import { ShareModalPrimitive } from "~/components/core/ShareModals/ShareModalPrimitive";
|
|
||||||
|
|
||||||
const STYLES_COPY_ACTIONS_WRAPPER = css`
|
|
||||||
border-radius: 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const STYLES_COPY_BUTTON = (theme) => css`
|
|
||||||
${Styles.BUTTON_RESET};
|
|
||||||
background-color: ${theme.system.white};
|
|
||||||
width: 100%;
|
|
||||||
padding: 9px 12px 11px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const formatDataSafely = ({ collection, user }) => {
|
|
||||||
if (typeof window === "undefined" || !collection || !user) return {};
|
|
||||||
const rootUrl = window?.location?.origin;
|
|
||||||
return {
|
|
||||||
id: collection.id,
|
|
||||||
title: collection?.name || collection?.slatename,
|
|
||||||
link: `${rootUrl}/${user.username}/${collection.slatename}`,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CollectionSharingModal = () => {
|
|
||||||
const [state, handlers] = useModalState();
|
|
||||||
const { open, user, collection, view, preview } = state;
|
|
||||||
const { closeModal, changeView, handleModalVisibility } = handlers;
|
|
||||||
|
|
||||||
const { id, title, link } = React.useMemo(() => formatDataSafely({ collection, user }), [
|
|
||||||
user,
|
|
||||||
collection,
|
|
||||||
]);
|
|
||||||
|
|
||||||
useEventListener("collection-sharing-modal", handleModalVisibility, []);
|
|
||||||
|
|
||||||
const handleTwitterSharing = () =>
|
|
||||||
window.open(
|
|
||||||
`https://twitter.com/intent/tweet?text=${title} by ${user.username} on Slate%0D&url=${link}`,
|
|
||||||
"_blank"
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleEmailSharing = () => {
|
|
||||||
window.open(`mailto: ?subject=${title} by ${user.username} on Slate&body=${link}`, "_b");
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleLinkCopy = () => (Utilities.copyToClipboard(link), changeView("LINK_COPIED"));
|
|
||||||
const handleIdCopy = () => (Utilities.copyToClipboard(id), changeView("ID_COPIED"));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ShareModalPrimitive
|
|
||||||
isOpen={open}
|
|
||||||
closeModal={closeModal}
|
|
||||||
title={title}
|
|
||||||
preview={preview}
|
|
||||||
description={`Collection @${user.username}`}
|
|
||||||
onEmailSharing={handleEmailSharing}
|
|
||||||
includeSocialSharing={!(view === "LINK_COPIED" || view === "ID_COPIED")}
|
|
||||||
onTwitterSharing={handleTwitterSharing}
|
|
||||||
>
|
|
||||||
{view === "initial" ? (
|
|
||||||
<div css={STYLES_COPY_ACTIONS_WRAPPER}>
|
|
||||||
<button css={STYLES_COPY_BUTTON} onClick={handleLinkCopy}>
|
|
||||||
<span css={Styles.HORIZONTAL_CONTAINER}>
|
|
||||||
<SVG.Link width={16} height={16} />
|
|
||||||
<P3 style={{ marginLeft: 8 }}>Copy Link</P3>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<Divider height={1} color="bgGrayLight" />
|
|
||||||
<button css={STYLES_COPY_BUTTON} onClick={handleIdCopy}>
|
|
||||||
<span css={Styles.HORIZONTAL_CONTAINER}>
|
|
||||||
<SVG.Hash width={16} height={16} />
|
|
||||||
<P3 style={{ marginLeft: 8 }}>Copy ID</P3>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<LinkCopiedScene closeModal={closeModal}>
|
|
||||||
{view === "LINK_COPIED" ? "Link copied to clipboard" : "ID copied to clipboard"}
|
|
||||||
</LinkCopiedScene>
|
|
||||||
)}
|
|
||||||
</ShareModalPrimitive>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const LinkCopiedScene = ({ closeModal, children }) => {
|
|
||||||
useTimeout(closeModal, 3000);
|
|
||||||
return (
|
|
||||||
<motion.div
|
|
||||||
initial={{ opacity: 0, y: 4 }}
|
|
||||||
animate={{ opacity: 1, y: 0 }}
|
|
||||||
transition={{ ease: "easeOut", duration: 0.3, delay: 0.4 }}
|
|
||||||
style={{ marginTop: 24 }}
|
|
||||||
css={Styles.CONTAINER_CENTERED}
|
|
||||||
>
|
|
||||||
<SVG.Clipboard />
|
|
||||||
<P3 style={{ marginLeft: 8 }} color="textBlack">
|
|
||||||
{children}
|
|
||||||
</P3>
|
|
||||||
</motion.div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const useModalState = () => {
|
|
||||||
const [state, setState] = React.useState({
|
|
||||||
open: false,
|
|
||||||
// NOTE(amine): INITIAL || LINK_COPIED || ID_COPIED
|
|
||||||
view: "initial",
|
|
||||||
user: {},
|
|
||||||
data: {},
|
|
||||||
preview: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
const handlers = React.useMemo(
|
|
||||||
() => ({
|
|
||||||
closeModal: () => setState((prev) => ({ ...prev, open: false })),
|
|
||||||
changeView: (view) => setState((prev) => ({ ...prev, view })),
|
|
||||||
handleModalVisibility: (e) =>
|
|
||||||
setState(() => ({
|
|
||||||
view: "initial",
|
|
||||||
open: e.detail.open,
|
|
||||||
user: e.detail.user,
|
|
||||||
collection: e.detail.collection,
|
|
||||||
preview: e.detail.preview,
|
|
||||||
})),
|
|
||||||
}),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
return [state, handlers];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useCollectionSharingModal = () => {
|
|
||||||
const openModal = ({ user, collection, preview }) =>
|
|
||||||
Events.dispatchCustomEvent({
|
|
||||||
name: "collection-sharing-modal",
|
|
||||||
detail: { open: true, user, collection, preview },
|
|
||||||
});
|
|
||||||
const closeModal = () =>
|
|
||||||
Events.dispatchCustomEvent({
|
|
||||||
name: "collection-sharing-modal",
|
|
||||||
detail: { open: false },
|
|
||||||
});
|
|
||||||
return { openModal, closeModal };
|
|
||||||
};
|
|
@ -1,185 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import * as Styles from "~/common/styles";
|
|
||||||
import * as SVG from "~/common/svg";
|
|
||||||
import * as Constants from "~/common/constants";
|
|
||||||
|
|
||||||
import { css } from "@emotion/react";
|
|
||||||
import { H5, P3 } from "~/components/system/components/Typography";
|
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import { useEscapeKey, useLockScroll } from "~/common/hooks";
|
|
||||||
import { Preview } from "~/components/core/CollectionPreviewBlock/components";
|
|
||||||
import { Symbol } from "~/common/logo";
|
|
||||||
|
|
||||||
const STYLES_OVERLAY = (theme) => css`
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 100vh;
|
|
||||||
width: 100%;
|
|
||||||
background-color: ${theme.semantic.bgBlurBlackTRN};
|
|
||||||
${Styles.CONTAINER_CENTERED};
|
|
||||||
z-index: ${theme.zindex.modal};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const STYLES_MODAL_WRAPPER = (theme) => css`
|
|
||||||
min-width: 400px;
|
|
||||||
padding: 24px;
|
|
||||||
border: 1px solid ${theme.semantic.bgGrayLight};
|
|
||||||
border-radius: 16px;
|
|
||||||
background: ${theme.system.white};
|
|
||||||
@supports ((-webkit-backdrop-filter: blur(75px)) or (backdrop-filter: blur(75px))) {
|
|
||||||
-webkit-backdrop-filter: blur(75px);
|
|
||||||
backdrop-filter: blur(75px);
|
|
||||||
background: linear-gradient(
|
|
||||||
120.84deg,
|
|
||||||
rgba(255, 255, 255, 0.85) 5.24%,
|
|
||||||
rgba(255, 255, 255, 0.544) 98.51%
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@media (max-width: ${theme.sizes.mobile}px) {
|
|
||||||
min-width: auto;
|
|
||||||
width: calc(100% - 32px);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const STYLES_PROFILE = css`
|
|
||||||
display: block;
|
|
||||||
${Styles.HORIZONTAL_CONTAINER};
|
|
||||||
align-items: flex-start;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const STYLES_DISMISS_BUTTON = (theme) => css`
|
|
||||||
${Styles.BUTTON_RESET};
|
|
||||||
color: ${theme.semantic.textGray};
|
|
||||||
`;
|
|
||||||
|
|
||||||
// NOTE(amine): social buttons styles
|
|
||||||
const STYLES_SOCIAL_BUTTON = (theme) => css`
|
|
||||||
${Styles.VERTICAL_CONTAINER_CENTERED}
|
|
||||||
padding: 16px;
|
|
||||||
border-radius: 12px;
|
|
||||||
box-shadow: ${theme.shadow.lightLarge};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const STYLES_TWITTER_BUTTON = css`
|
|
||||||
background-color: #58aee7;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const STYLES_EMAIL_BUTTON = (theme) => css`
|
|
||||||
background-color: ${theme.system.white};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const STYLES_TEXT_CENTER = css`
|
|
||||||
text-align: center;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const STYLES_PREVIEW = (theme) => css`
|
|
||||||
width: 48px;
|
|
||||||
max-width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
border-radius: 12px;
|
|
||||||
background-color: ${theme.semantic.bgLight};
|
|
||||||
${Styles.CONTAINER_CENTERED}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const EmptyFallbackPreview = () => {
|
|
||||||
return (
|
|
||||||
<div css={STYLES_PREVIEW}>
|
|
||||||
<Symbol style={{ height: 24, color: Constants.system.grayLight2 }} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOTE(amine): This modal will be a building block for both Object and Collection sharing modals
|
|
||||||
export const ShareModalPrimitive = ({
|
|
||||||
isOpen,
|
|
||||||
closeModal,
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
includeSocialSharing = true,
|
|
||||||
onTwitterSharing,
|
|
||||||
onEmailSharing,
|
|
||||||
preview,
|
|
||||||
children,
|
|
||||||
}) => {
|
|
||||||
useEscapeKey(closeModal);
|
|
||||||
useLockScroll({ lock: isOpen });
|
|
||||||
|
|
||||||
const handleModalClick = (e) => (e.preventDefault(), e.stopPropagation());
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AnimatePresence>
|
|
||||||
{isOpen ? (
|
|
||||||
<motion.div
|
|
||||||
exit={{ opacity: 0 }}
|
|
||||||
transition={{ duration: 0.35 }}
|
|
||||||
css={STYLES_OVERLAY}
|
|
||||||
onClick={closeModal}
|
|
||||||
>
|
|
||||||
<motion.div
|
|
||||||
layoutId
|
|
||||||
exit={{ y: 50 }}
|
|
||||||
transition={{ duration: 0.5, easings: "easeInOut" }}
|
|
||||||
css={STYLES_MODAL_WRAPPER}
|
|
||||||
onClick={handleModalClick}
|
|
||||||
>
|
|
||||||
<motion.div layout css={STYLES_PROFILE} style={{ alignItems: "flex-start" }}>
|
|
||||||
{/**TODO(amine): add dynamic preview to support collection and object previews */}
|
|
||||||
<Preview
|
|
||||||
file={preview.object}
|
|
||||||
type={preview.type}
|
|
||||||
EmptyFallback={EmptyFallbackPreview}
|
|
||||||
css={STYLES_PREVIEW}
|
|
||||||
placeholderRatio={2}
|
|
||||||
/>
|
|
||||||
<div style={{ marginLeft: 12, flexGrow: 1 }}>
|
|
||||||
<H5 color="textBlack" nbrOflines={1}>
|
|
||||||
{title}
|
|
||||||
</H5>
|
|
||||||
<P3 style={{ marginTop: 3 }} color="textGrayDark" nbrOflines={1}>
|
|
||||||
{description}
|
|
||||||
</P3>
|
|
||||||
</div>
|
|
||||||
<button css={STYLES_DISMISS_BUTTON} style={{ marginLeft: 13 }} onClick={closeModal}>
|
|
||||||
<span>
|
|
||||||
<SVG.Dismiss height={20} />
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</motion.div>
|
|
||||||
|
|
||||||
{includeSocialSharing && (
|
|
||||||
<div css={Styles.CONTAINER_CENTERED} style={{ marginTop: 24 }}>
|
|
||||||
<button css={Styles.BUTTON_RESET} onClick={onTwitterSharing}>
|
|
||||||
<span>
|
|
||||||
<div css={[STYLES_SOCIAL_BUTTON, STYLES_TWITTER_BUTTON]}>
|
|
||||||
<SVG.TwitterWhiteLogo style={{ display: "block" }} />
|
|
||||||
</div>
|
|
||||||
<P3 style={{ marginTop: 4 }} css={STYLES_TEXT_CENTER}>
|
|
||||||
Twitter
|
|
||||||
</P3>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
css={Styles.BUTTON_RESET}
|
|
||||||
style={{ marginLeft: 24 }}
|
|
||||||
onClick={onEmailSharing}
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<div css={[STYLES_SOCIAL_BUTTON, STYLES_EMAIL_BUTTON]}>
|
|
||||||
<SVG.Mail style={{ display: "block" }} />
|
|
||||||
</div>
|
|
||||||
<P3 style={{ marginTop: 4 }} css={STYLES_TEXT_CENTER}>
|
|
||||||
Email
|
|
||||||
</P3>
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div style={{ marginTop: 24 }}>{children}</div>
|
|
||||||
</motion.div>
|
|
||||||
</motion.div>
|
|
||||||
) : null}
|
|
||||||
</AnimatePresence>
|
|
||||||
);
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user