Edit posts (#859)
This commit is contained in:
		
							parent
							
								
									5547b30364
								
							
						
					
					
						commit
						d9bb7d1926
					
				| 
						 | 
					@ -1,12 +1,12 @@
 | 
				
			||||||
import { Page } from 'web/components/page'
 | 
					import { Page } from 'web/components/page'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { postPath, getPostBySlug } from 'web/lib/firebase/posts'
 | 
					import { postPath, getPostBySlug, updatePost } from 'web/lib/firebase/posts'
 | 
				
			||||||
import { Post } from 'common/post'
 | 
					import { Post } from 'common/post'
 | 
				
			||||||
import { Title } from 'web/components/title'
 | 
					import { Title } from 'web/components/title'
 | 
				
			||||||
import { Spacer } from 'web/components/layout/spacer'
 | 
					import { Spacer } from 'web/components/layout/spacer'
 | 
				
			||||||
import { Content } from 'web/components/editor'
 | 
					import { Content, TextEditor, useTextEditor } from 'web/components/editor'
 | 
				
			||||||
import { getUser, User } from 'web/lib/firebase/users'
 | 
					import { getUser, User } from 'web/lib/firebase/users'
 | 
				
			||||||
import { ShareIcon } from '@heroicons/react/solid'
 | 
					import { PencilIcon, ShareIcon } from '@heroicons/react/solid'
 | 
				
			||||||
import clsx from 'clsx'
 | 
					import clsx from 'clsx'
 | 
				
			||||||
import { Button } from 'web/components/button'
 | 
					import { Button } from 'web/components/button'
 | 
				
			||||||
import { useState } from 'react'
 | 
					import { useState } from 'react'
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,8 @@ import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns'
 | 
				
			||||||
import { groupBy, sortBy } from 'lodash'
 | 
					import { groupBy, sortBy } from 'lodash'
 | 
				
			||||||
import { PostCommentInput, PostCommentThread } from 'web/posts/post-comments'
 | 
					import { PostCommentInput, PostCommentThread } from 'web/posts/post-comments'
 | 
				
			||||||
import { useCommentsOnPost } from 'web/hooks/use-comments'
 | 
					import { useCommentsOnPost } from 'web/hooks/use-comments'
 | 
				
			||||||
 | 
					import { useUser } from 'web/hooks/use-user'
 | 
				
			||||||
 | 
					import { usePost } from 'web/hooks/use-post'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function getStaticProps(props: { params: { slugs: string[] } }) {
 | 
					export async function getStaticProps(props: { params: { slugs: string[] } }) {
 | 
				
			||||||
  const { slugs } = props.params
 | 
					  const { slugs } = props.params
 | 
				
			||||||
| 
						 | 
					@ -51,12 +53,14 @@ export default function PostPage(props: {
 | 
				
			||||||
  comments: PostComment[]
 | 
					  comments: PostComment[]
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  const [isShareOpen, setShareOpen] = useState(false)
 | 
					  const [isShareOpen, setShareOpen] = useState(false)
 | 
				
			||||||
  const { post, creator } = props
 | 
					  const { creator } = props
 | 
				
			||||||
 | 
					  const post = usePost(props.post.id) ?? props.post
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const tips = useTipTxns({ postId: post.id })
 | 
					  const tips = useTipTxns({ postId: post.id })
 | 
				
			||||||
  const shareUrl = `https://${ENV_CONFIG.domain}${postPath(post.slug)}`
 | 
					  const shareUrl = `https://${ENV_CONFIG.domain}${postPath(post.slug)}`
 | 
				
			||||||
  const updatedComments = useCommentsOnPost(post.id)
 | 
					  const updatedComments = useCommentsOnPost(post.id)
 | 
				
			||||||
  const comments = updatedComments ?? props.comments
 | 
					  const comments = updatedComments ?? props.comments
 | 
				
			||||||
 | 
					  const user = useUser()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (post == null) {
 | 
					  if (post == null) {
 | 
				
			||||||
    return <Custom404 />
 | 
					    return <Custom404 />
 | 
				
			||||||
| 
						 | 
					@ -104,7 +108,11 @@ export default function PostPage(props: {
 | 
				
			||||||
        <Spacer h={2} />
 | 
					        <Spacer h={2} />
 | 
				
			||||||
        <div className="rounded-lg bg-white px-6 py-4 sm:py-0">
 | 
					        <div className="rounded-lg bg-white px-6 py-4 sm:py-0">
 | 
				
			||||||
          <div className="form-control w-full py-2">
 | 
					          <div className="form-control w-full py-2">
 | 
				
			||||||
            <Content content={post.content} />
 | 
					            {user && user.id === post.creatorId ? (
 | 
				
			||||||
 | 
					              <RichEditPost post={post} />
 | 
				
			||||||
 | 
					            ) : (
 | 
				
			||||||
 | 
					              <Content content={post.content} />
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,3 +164,65 @@ export function PostCommentsActivity(props: {
 | 
				
			||||||
    </>
 | 
					    </>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function RichEditPost(props: { post: Post }) {
 | 
				
			||||||
 | 
					  const { post } = props
 | 
				
			||||||
 | 
					  const [editing, setEditing] = useState(false)
 | 
				
			||||||
 | 
					  const [isSubmitting, setIsSubmitting] = useState(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { editor, upload } = useTextEditor({
 | 
				
			||||||
 | 
					    defaultValue: post.content,
 | 
				
			||||||
 | 
					    disabled: isSubmitting,
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async function savePost() {
 | 
				
			||||||
 | 
					    if (!editor) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await updatePost(post, {
 | 
				
			||||||
 | 
					      content: editor.getJSON(),
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return editing ? (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      <TextEditor editor={editor} upload={upload} />
 | 
				
			||||||
 | 
					      <Spacer h={2} />
 | 
				
			||||||
 | 
					      <Row className="gap-2">
 | 
				
			||||||
 | 
					        <Button
 | 
				
			||||||
 | 
					          onClick={async () => {
 | 
				
			||||||
 | 
					            setIsSubmitting(true)
 | 
				
			||||||
 | 
					            await savePost()
 | 
				
			||||||
 | 
					            setEditing(false)
 | 
				
			||||||
 | 
					            setIsSubmitting(false)
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          Save
 | 
				
			||||||
 | 
					        </Button>
 | 
				
			||||||
 | 
					        <Button color="gray" onClick={() => setEditing(false)}>
 | 
				
			||||||
 | 
					          Cancel
 | 
				
			||||||
 | 
					        </Button>
 | 
				
			||||||
 | 
					      </Row>
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  ) : (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      <div className="relative">
 | 
				
			||||||
 | 
					        <div className="absolute top-0 right-0 z-10 space-x-2">
 | 
				
			||||||
 | 
					          <Button
 | 
				
			||||||
 | 
					            color="gray"
 | 
				
			||||||
 | 
					            size="xs"
 | 
				
			||||||
 | 
					            onClick={() => {
 | 
				
			||||||
 | 
					              setEditing(true)
 | 
				
			||||||
 | 
					              editor?.commands.focus('end')
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <PencilIcon className="inline h-4 w-4" />
 | 
				
			||||||
 | 
					            Edit
 | 
				
			||||||
 | 
					          </Button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Content content={post.content} />
 | 
				
			||||||
 | 
					        <Spacer h={2} />
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user