diff --git a/src/components/comments/ViewComment.tsx b/src/components/comments/ViewComment.tsx index 22fd5370..24179401 100644 --- a/src/components/comments/ViewComment.tsx +++ b/src/components/comments/ViewComment.tsx @@ -122,7 +122,7 @@ export const ViewComment: FunctionComponent = ({ } /> - + } content={showEditForm ? setShowEditForm(false)}/> diff --git a/src/components/posts/MovePostLink.tsx b/src/components/posts/MovePostLink.tsx new file mode 100644 index 00000000..a3f0ca6e --- /dev/null +++ b/src/components/posts/MovePostLink.tsx @@ -0,0 +1,26 @@ +import React, { useState } from 'react' +import { Post } from '@subsocial/types/substrate/interfaces' +import { MoveModal } from 'src/components/posts/modals/MoveModal' + +type Props = { + post: Post +} + +export const MovePostLink = ({ post }: Props) => { + + const [ open, setOpen ] = useState() + const title = 'Move post' + + return <> + setOpen(true)} + title={title} + > + {title} + + setOpen(false)} /> + +} + +export default MovePostLink diff --git a/src/components/posts/ShareModal/index.module.sass b/src/components/posts/ShareModal/index.module.sass deleted file mode 100644 index 6ca402c6..00000000 --- a/src/components/posts/ShareModal/index.module.sass +++ /dev/null @@ -1,7 +0,0 @@ -@import 'src/styles/subsocial-vars.scss' - -.DfShareModal - margin-top: 3rem - min-width: $min_width_content - max-width: $max_width_content - width: $max_width_content !important \ No newline at end of file diff --git a/src/components/posts/modals/MoveModal.tsx b/src/components/posts/modals/MoveModal.tsx new file mode 100644 index 00000000..a192b688 --- /dev/null +++ b/src/components/posts/modals/MoveModal.tsx @@ -0,0 +1,128 @@ +import React, { useState } from 'react' +import { withCalls, withMulti, spacesQueryToProp } from 'src/components/substrate' +import { Modal } from 'antd' +import Button from 'antd/lib/button' +import { withMyAccount, MyAccountProps } from 'src/components/utils/MyAccount' +import { LabeledValue } from 'antd/lib/select' +import SelectSpacePreview from 'src/components/utils/SelectSpacePreview' +import BN from 'bn.js' +import { OptionId } from '@subsocial/types/substrate/classes' +import { TxFailedCallback, TxCallback } from 'src/components/substrate/SubstrateTxButton' +import dynamic from 'next/dynamic' +import { isEmptyArray, nonEmptyArr } from '@subsocial/utils'; +import { DynamicPostPreview } from 'src/components/posts/view-post/DynamicPostPreview' +import { CreateSpaceButton } from 'src/components/spaces/helpers' +import { useRouter } from 'next/router' +import { postUrl } from 'src/components/urls/subsocial' +import { Post, PostId, Space, SpaceId } from '@subsocial/types/substrate/interfaces' +import modalStyles from 'src/components/posts/modals/index.module.sass'; +import NoData from 'src/components/utils/EmptyList' + +const TxButton = dynamic(() => import('src/components/utils/TxButton'), { ssr: false }) + +type Props = MyAccountProps & { + post: Post + spaceIds?: BN[] + open: boolean + onClose: () => void +} + +const InnerMoveModal = (props: Props) => { + const { open, onClose, post, post: { id: postId } } = props + let { spaceIds } = props + + if (post.space_id.isSome && spaceIds) { + const postSpaceId = post.space_id.unwrap() + spaceIds = spaceIds.filter(spaceId => !spaceId.eq(postSpaceId)) + } + + if (!spaceIds) { + return null + } + + const router = useRouter() + + const [ spaceId, setSpaceId ] = useState(spaceIds[0]) + + const onTxFailed: TxFailedCallback = () => { + // TODO show a failure message + onClose() + } + + const onTxSuccess: TxCallback = () => { + // TODO show a success message + router.push( + '/[spaceId]/posts/[postId]', + postUrl( + { id: spaceId as SpaceId } as Space, + { id: postId as PostId }) + ) + onClose() + } + + const newTxParams = () => { + const spaceIdOption = new OptionId(spaceId) + return [ postId, spaceIdOption ] + } + + const renderTxButton = () => nonEmptyArr(spaceIds) + ? + : Create one more space + + const renderMovePostView = () => { + if (isEmptyArray(spaceIds)) { + return + } + + return
+ + + + +
+ +
+
+ } + + const saveSpace = (value: string | number | LabeledValue) => { + setSpaceId(new BN(value as string)) + } + + return + + {renderTxButton()} + + } + > + {renderMovePostView()} + +} + +export const MoveModal = withMulti( + InnerMoveModal, + withMyAccount, + withCalls( + spacesQueryToProp(`spaceIdsByOwner`, { paramName: 'address', propName: 'spaceIds' }) + ) +) diff --git a/src/components/posts/modals/ShareModal/index.module.sass b/src/components/posts/modals/ShareModal/index.module.sass new file mode 100644 index 00000000..efb3a4f1 --- /dev/null +++ b/src/components/posts/modals/ShareModal/index.module.sass @@ -0,0 +1,3 @@ +.DfShareModalMdEditor + .CodeMirror + height: 5rem diff --git a/src/components/posts/ShareModal/index.tsx b/src/components/posts/modals/ShareModal/index.tsx similarity index 70% rename from src/components/posts/ShareModal/index.tsx rename to src/components/posts/modals/ShareModal/index.tsx index 1b9479e2..3bea859b 100644 --- a/src/components/posts/ShareModal/index.tsx +++ b/src/components/posts/modals/ShareModal/index.tsx @@ -1,25 +1,27 @@ import React, { useState } from 'react'; -import { withCalls, withMulti, getTxParams, spacesQueryToProp } from '../../substrate'; +import { withCalls, withMulti, getTxParams, spacesQueryToProp } from 'src/components/substrate'; import { Modal } from 'antd'; import Button from 'antd/lib/button'; -import { withMyAccount, MyAccountProps } from '../../utils/MyAccount'; +import { withMyAccount, MyAccountProps } from 'src/components/utils/MyAccount'; import { LabeledValue } from 'antd/lib/select'; -import SelectSpacePreview from '../../utils/SelectSpacePreview'; +import SelectSpacePreview from 'src/components/utils/SelectSpacePreview'; import BN from 'bn.js'; import { PostExtension, SharedPost, IpfsContent } from '@subsocial/types/substrate/classes'; import { useForm, Controller, ErrorMessage } from 'react-hook-form'; -import { useSubsocialApi } from '../../utils/SubsocialApiContext'; +import { useSubsocialApi } from 'src/components/utils/SubsocialApiContext'; import { IpfsCid } from '@subsocial/types/substrate/interfaces'; import { TxFailedCallback, TxCallback } from 'src/components/substrate/SubstrateTxButton'; import dynamic from 'next/dynamic'; -import { buildSharePostValidationSchema } from '../PostValidation'; -import { isEmptyArray } from '@subsocial/utils'; -import DfMdEditor from '../../utils/DfMdEditor'; -import { DynamicPostPreview } from '../view-post/DynamicPostPreview'; -import { CreateSpaceButton } from '../../spaces/helpers'; +import { buildSharePostValidationSchema } from 'src/components/posts/PostValidation'; +import { isEmptyArray, nonEmptyArr } from '@subsocial/utils'; +import DfMdEditor from 'src/components/utils/DfMdEditor'; +import { DynamicPostPreview } from 'src/components/posts/view-post/DynamicPostPreview'; +import { CreateSpaceButton } from 'src/components/spaces/helpers'; import styles from './index.module.sass' +import modalStyles from 'src/components/posts/modals/index.module.sass' +import NoData from 'src/components/utils/EmptyList'; -const TxButton = dynamic(() => import('../../utils/TxButton'), { ssr: false }); +const TxButton = dynamic(() => import('src/components/utils/TxButton'), { ssr: false }); type Props = MyAccountProps & { postId: BN @@ -69,8 +71,8 @@ const InnerShareModal = (props: Props) => { return [ spaceId, extension, new IpfsContent(hash) ]; }; - const renderTxButton = () => - nonEmptyArr(spaceIds) + ? { successMessage='Shared to your space' failedMessage='Failed to share' /> + : Create my first space const renderShareView = () => { if (isEmptyArray(spaceIds)) { - return ( - - - Create my first space - - - ) + return } - return
- - Share the post to your space: - {' '} + return
+ -
+ } options={{ autofocus: true }} name={Fields.body} value={body} - className={errors[Fields.body] && 'error'} + className={`${errors[Fields.body] && 'error'} ${styles.DfShareModalMdEditor}`} />
@@ -135,7 +130,7 @@ const InnerShareModal = (props: Props) => { onCancel={onClose} visible={open} title={'Share post'} - className={styles.DfShareModal} + className={modalStyles.DfPostActionModal} footer={ <> diff --git a/src/components/posts/modals/index.module.sass b/src/components/posts/modals/index.module.sass new file mode 100644 index 00000000..9a3bb05e --- /dev/null +++ b/src/components/posts/modals/index.module.sass @@ -0,0 +1,11 @@ +@import 'src/styles/subsocial-vars.scss' + +.DfPostActionModal + width: $max_width_content !important + +.DfPostActionModalBody + \:global .DfSegment + margin: 0 + +.DfPostActionModalSelector + width: $max_width_content !important diff --git a/src/components/posts/share/SpaceShareLink.tsx b/src/components/posts/share/SpaceShareLink.tsx index ec53706f..82f04c1d 100644 --- a/src/components/posts/share/SpaceShareLink.tsx +++ b/src/components/posts/share/SpaceShareLink.tsx @@ -2,9 +2,10 @@ import React, { useState } from 'react' import { PostWithSomeDetails } from '@subsocial/types/dto'; import { PostExtension } from '@subsocial/types/substrate/classes'; import { EditOutlined } from '@ant-design/icons'; -import { ShareModal } from '../ShareModal' -import { isRegularPost } from '../view-post'; -import { IconWithLabel } from '../../utils'; +import { ShareModal } from 'src/components/posts/modals/ShareModal' +import { isRegularPost } from 'src/components/posts/view-post'; +import { IconWithLabel } from 'src/components/utils'; +import { useAuth } from 'src/components/auth/AuthContext'; type Props = { postDetails: PostWithSomeDetails @@ -19,6 +20,7 @@ export const SpaceShareLink = ({ } }: Props) => { + const { openSignInModal, state: { isSteps: { isSignIn } } } = useAuth() const [ open, setOpen ] = useState() const postId = isRegularPost(extension as PostExtension) ? id : ext && ext.post.struct.id const title = 'Write a post' @@ -26,7 +28,7 @@ export const SpaceShareLink = ({ return <> setOpen(true)} + onClick={() => isSignIn ? setOpen(true) : openSignInModal('AuthRequired')} title={title} > } label={title} /> diff --git a/src/components/posts/view-post/PostPage.tsx b/src/components/posts/view-post/PostPage.tsx index 66670e62..104dcc59 100644 --- a/src/components/posts/view-post/PostPage.tsx +++ b/src/components/posts/view-post/PostPage.tsx @@ -71,7 +71,7 @@ export const PostPage: NextPage = ({ postDetails: initialPost,

{titleMsg}

- +
diff --git a/src/components/posts/view-post/ViewSharedPreview.tsx b/src/components/posts/view-post/ViewSharedPreview.tsx index e3bd39d4..ca32748c 100644 --- a/src/components/posts/view-post/ViewSharedPreview.tsx +++ b/src/components/posts/view-post/ViewSharedPreview.tsx @@ -6,11 +6,10 @@ import { InnerPreviewProps } from '.'; export const SharedPreview: React.FunctionComponent = ({ postDetails, space, withActions, replies }) => { const [ commentsSection, setCommentsSection ] = useState(false) - const { struct } = postDetails.post return <>
- +
{withActions && setCommentsSection(!commentsSection)} preview />} diff --git a/src/components/posts/view-post/helpers.tsx b/src/components/posts/view-post/helpers.tsx index e5ef0164..6d928f0b 100644 --- a/src/components/posts/view-post/helpers.tsx +++ b/src/components/posts/view-post/helpers.tsx @@ -32,10 +32,11 @@ import { postUrl, editPostUrl, HasSpaceIdOrHandle, HasPostId } from 'src/compone import { ShareDropdown } from '../share/ShareDropdown'; import { ButtonLink } from 'src/components/utils/ButtonLink'; import { DfMd } from 'src/components/utils/DfMd'; +import MovePostLink from 'src/components/posts/MovePostLink'; type DropdownProps = { space: Space - post: Post + postDetails: PostWithSomeDetails withEditButton?: boolean } @@ -57,7 +58,8 @@ const ReactionModal = ({ postId }: ReactionModalProps) => { } export const PostDropDownMenu: React.FunctionComponent = (props) => { - const { space, post, withEditButton = false } = props + const { space, postDetails, withEditButton = false } = props + const { post: { struct: post } } = postDetails const isMyPost = isMyAddress(post.owner); const postId = post.id const postKey = `post-${postId.toString()}` @@ -77,6 +79,9 @@ export const PostDropDownMenu: React.FunctionComponent = (props) {isMyPost && } + {isMyPost && !isComment(post.extension) && + + } @@ -311,7 +316,7 @@ export const InfoPostPreview: React.FunctionComponent =
- +
diff --git a/src/styles/subsocial.scss b/src/styles/subsocial.scss index 77350b33..246b1ee7 100644 --- a/src/styles/subsocial.scss +++ b/src/styles/subsocial.scss @@ -623,28 +623,6 @@ hr { } } -.DfShareModalBody { - .DfSection { - margin-top: $space_huge; - margin-bottom: 0; - width: auto; - } - - .EditEntityBox { - width: 100%; - max-width: none; - } - - .ui.input>input, - .ui.selection.dropdown { - width: 100%; - } - - .DfSegment.DfPostPreview { - text-align: left; - } -} - .DfGreyLink { color: $color_muted !important; cursor: pointer; @@ -809,6 +787,7 @@ hr { .ProfileDetails.DfPreview { align-items: center; + height: stretch; } .DfPopup-handle {