diff --git a/common/comment.ts b/common/comment.ts index cdb62fd3..6ace444a 100644 --- a/common/comment.ts +++ b/common/comment.ts @@ -1,5 +1,3 @@ -import type { JSONContent } from '@tiptap/core' - export type AnyCommentType = OnContract | OnGroup | OnPost // Currently, comments are created after the bet, not atomically with the bet. @@ -8,10 +6,7 @@ export type Comment = { id: string replyToCommentId?: string userId: string - - /** @deprecated - content now stored as JSON in content*/ - text?: string - content: JSONContent + content: string createdTime: number // Denormalized, for rendering comments diff --git a/common/contract.ts b/common/contract.ts index 248c9745..eed907be 100644 --- a/common/contract.ts +++ b/common/contract.ts @@ -1,6 +1,5 @@ import { Answer } from './answer' import { Fees } from './fees' -import { JSONContent } from '@tiptap/core' import { GroupLink } from 'common/group' export type AnyMechanism = DPM | CPMM @@ -28,7 +27,7 @@ export type Contract = { creatorAvatarUrl?: string question: string - description: string | JSONContent // More info about what the contract is about + description: string // More info about what the contract is about tags: string[] lowercaseTags: string[] visibility: visibility diff --git a/common/new-contract.ts b/common/new-contract.ts index 431f435e..d54ae3cb 100644 --- a/common/new-contract.ts +++ b/common/new-contract.ts @@ -69,7 +69,7 @@ export function getNewContract( creatorAvatarUrl: creator.avatarUrl, question: question.trim(), - description, + description: JSON.stringify(description), tags, lowercaseTags, visibility, diff --git a/common/post.ts b/common/post.ts index 05eab685..94fc58ff 100644 --- a/common/post.ts +++ b/common/post.ts @@ -1,9 +1,7 @@ -import { JSONContent } from '@tiptap/core' - export type Post = { id: string title: string - content: JSONContent + content: string creatorId: string // User id createdTime: number slug: string diff --git a/functions/src/create-post.ts b/functions/src/create-post.ts index 113a34bd..52901efb 100644 --- a/functions/src/create-post.ts +++ b/functions/src/create-post.ts @@ -57,7 +57,7 @@ export const createpost = newEndpoint({}, async (req, auth) => { slug, title, createdTime: Date.now(), - content: content, + content: JSON.stringify(content), } await postRef.create(post) diff --git a/functions/src/on-create-comment-on-contract.ts b/functions/src/on-create-comment-on-contract.ts index d1f0a503..648c1949 100644 --- a/functions/src/on-create-comment-on-contract.ts +++ b/functions/src/on-create-comment-on-contract.ts @@ -174,7 +174,8 @@ export const onCreateCommentOnContract = functions ? comments.find((c) => c.id === comment.replyToCommentId)?.userId : answer?.userId - const mentionedUsers = compact(parseMentions(comment.content)) + const parsedContent = JSON.parse(comment.content) + const mentionedUsers = compact(parseMentions(parsedContent)) const repliedUsers: replied_users_info = {} // The parent of the reply chain could be a comment or an answer @@ -210,7 +211,7 @@ export const onCreateCommentOnContract = functions 'created', commentCreator, eventId, - richTextToString(comment.content), + richTextToString(parsedContent), contract, { repliedUsersInfo: repliedUsers, diff --git a/functions/src/on-create-contract.ts b/functions/src/on-create-contract.ts index b613142b..6260c0ed 100644 --- a/functions/src/on-create-contract.ts +++ b/functions/src/on-create-contract.ts @@ -17,7 +17,7 @@ export const onCreateContract = functions const contractCreator = await getUser(contract.creatorId) if (!contractCreator) throw new Error('Could not find contract creator') - const desc = contract.description as JSONContent + const desc = JSON.parse(contract.description) as JSONContent const mentioned = parseMentions(desc) await addUserToContractFollowers(contract.id, contractCreator.id) diff --git a/web/components/comments-list.tsx b/web/components/comments-list.tsx index 0b1c3843..89d12ab8 100644 --- a/web/components/comments-list.tsx +++ b/web/components/comments-list.tsx @@ -8,7 +8,7 @@ import { Avatar } from './avatar' import { RelativeTimestamp } from './relative-timestamp' import { User } from 'common/user' import { Col } from './layout/col' -import { Content } from './editor' +import { RichContent } from './editor' import { LoadingIndicator } from './loading-indicator' import { UserLink } from 'web/components/user-link' import { PaginationNextPrev } from 'web/components/pagination' @@ -99,7 +99,7 @@ function ProfileCommentGroup(props: { function ProfileComment(props: { comment: ContractComment }) { const { comment } = props - const { text, content, userUsername, userName, userAvatarUrl, createdTime } = + const { content, userUsername, userName, userAvatarUrl, createdTime } = comment // TODO: find and attach relevant bets by comment betId at some point return ( @@ -114,7 +114,7 @@ function ProfileComment(props: { comment: ContractComment }) { />{' '}

- + ) diff --git a/web/components/contract/contract-description.tsx b/web/components/contract/contract-description.tsx index 53557305..df797871 100644 --- a/web/components/contract/contract-description.tsx +++ b/web/components/contract/contract-description.tsx @@ -9,7 +9,7 @@ import { useAdmin } from 'web/hooks/use-admin' import { useUser } from 'web/hooks/use-user' import { updateContract } from 'web/lib/firebase/contracts' import { Row } from '../layout/row' -import { Content } from '../editor' +import { RichContent } from '../editor' import { TextEditor, useTextEditor } from 'web/components/editor' import { Button } from '../button' import { Spacer } from '../layout/spacer' @@ -29,7 +29,7 @@ export function ContractDescription(props: { {isCreator || isAdmin ? ( ) : ( - + )} ) @@ -60,7 +60,7 @@ function RichEditContract(props: { contract: Contract; isAdmin?: boolean }) { const lowercaseTags = tags.map((tag) => tag.toLowerCase()) await updateContract(contract.id, { - description: editor.getJSON(), + description: JSON.stringify(editor.getJSON()), tags, lowercaseTags, }) @@ -88,7 +88,7 @@ function RichEditContract(props: { contract: Contract; isAdmin?: boolean }) { ) : ( <> - + {isAdmin && 'Admin: '} @@ -139,9 +139,11 @@ function EditQuestion(props: { setEditing(false) await updateContract(contract.id, { question: newText, - description: joinContent( - contract.description, - questionChanged(contract.question, newText) + description: JSON.stringify( + joinContent( + JSON.parse(contract.description), + questionChanged(contract.question, newText) + ) ), }) } diff --git a/web/components/contract/contract-details.tsx b/web/components/contract/contract-details.tsx index 3525b9f9..ec94f733 100644 --- a/web/components/contract/contract-details.tsx +++ b/web/components/contract/contract-details.tsx @@ -380,7 +380,7 @@ function EditableCloseDate(props: { updateContract(contract.id, { closeTime: newCloseTime, - description: editor.getJSON(), + description: JSON.stringify(editor.getJSON()), }) setIsEditingCloseTime(false) diff --git a/web/components/editor.tsx b/web/components/editor.tsx index 95f18b3f..2c364734 100644 --- a/web/components/editor.tsx +++ b/web/components/editor.tsx @@ -14,7 +14,6 @@ import { Image } from '@tiptap/extension-image' import { Link } from '@tiptap/extension-link' import clsx from 'clsx' import { useEffect, useState } from 'react' -import { Linkify } from './linkify' import { uploadImage } from 'web/lib/firebase/storage' import { useMutation } from 'react-query' import { FileUploadButton } from './file-upload-button' @@ -316,6 +315,7 @@ export function RichContent(props: { smallImage?: boolean }) { const { className, content, smallImage } = props + const editor = useEditor({ editorProps: { attributes: { class: proseClass } }, extensions: [ @@ -341,23 +341,3 @@ export function RichContent(props: { return } - -// backwards compatibility: we used to store content as strings -export function Content(props: { - content: JSONContent | string - className?: string - smallImage?: boolean -}) { - const { className, content } = props - return typeof content === 'string' ? ( - - ) : ( - - ) -} diff --git a/web/components/feed/feed-comments.tsx b/web/components/feed/feed-comments.tsx index 1b62690b..a3cd6c32 100644 --- a/web/components/feed/feed-comments.tsx +++ b/web/components/feed/feed-comments.tsx @@ -15,7 +15,7 @@ import { Col } from 'web/components/layout/col' import { track } from 'web/lib/service/analytics' import { Tipper } from '../tipper' import { CommentTipMap, CommentTips } from 'web/hooks/use-tip-txns' -import { Content } from '../editor' +import { RichContent } from '../editor' import { Editor } from '@tiptap/react' import { UserLink } from 'web/components/user-link' import { CommentInput } from '../comment-input' @@ -76,7 +76,6 @@ export function FeedComment(props: { }) { const { contract, comment, tips, indent, onReplyClick } = props const { - text, content, userUsername, userName, @@ -163,9 +162,9 @@ export function FeedComment(props: { elementId={comment.id} /> - diff --git a/web/components/groups/group-about-post.tsx b/web/components/groups/group-about-post.tsx index 4d3046e9..7dcf8543 100644 --- a/web/components/groups/group-about-post.tsx +++ b/web/components/groups/group-about-post.tsx @@ -1,5 +1,5 @@ import { Row } from '../layout/row' -import { Content } from '../editor' +import { RichContent } from '../editor' import { TextEditor, useTextEditor } from 'web/components/editor' import { Button } from '../button' import { Spacer } from '../layout/spacer' @@ -24,7 +24,9 @@ export function GroupAboutPost(props: { return (
{isEditable && } - {!isEditable && post && } + {!isEditable && post && ( + + )}
) } @@ -56,7 +58,7 @@ function RichEditGroupAboutPost(props: { group: Group; post: Post | null }) { }) } else { await updatePost(post, { - content: newPost.content, + content: JSON.stringify(newPost.content), }) } } @@ -124,7 +126,7 @@ function RichEditGroupAboutPost(props: { group: Group; post: Post | null }) { - + )} diff --git a/web/lib/firebase/comments.ts b/web/lib/firebase/comments.ts index db4e8ede..22128f15 100644 --- a/web/lib/firebase/comments.ts +++ b/web/lib/firebase/comments.ts @@ -100,7 +100,7 @@ async function createComment( const comment = removeUndefinedProps({ id: ref.id, userId: user.id, - content: content, + content: JSON.stringify(content), createdTime: Date.now(), userName: user.name, userUsername: user.username, diff --git a/web/pages/api/v0/_types.ts b/web/pages/api/v0/_types.ts index ea2f053b..adf6bb59 100644 --- a/web/pages/api/v0/_types.ts +++ b/web/pages/api/v0/_types.ts @@ -53,7 +53,7 @@ export type FullMarket = LiteMarket & { bets: Bet[] comments: Comment[] answers?: ApiAnswer[] - description: string | JSONContent + description: JSONContent textDescription: string // string version of description } @@ -155,18 +155,15 @@ export function toFullMarket( ) : undefined - const { description } = contract + const parsedDescription = JSON.parse(contract.description) return { ...liteMarket, answers, comments, bets, - description, - textDescription: - typeof description === 'string' - ? description - : richTextToString(description), + description: parsedDescription, + textDescription: richTextToString(parsedDescription), } } diff --git a/web/pages/post/[...slugs]/index.tsx b/web/pages/post/[...slugs]/index.tsx index 6cd4408f..62089d1f 100644 --- a/web/pages/post/[...slugs]/index.tsx +++ b/web/pages/post/[...slugs]/index.tsx @@ -4,7 +4,7 @@ import { postPath, getPostBySlug, updatePost } from 'web/lib/firebase/posts' import { Post } from 'common/post' import { Title } from 'web/components/title' import { Spacer } from 'web/components/layout/spacer' -import { Content, TextEditor, useTextEditor } from 'web/components/editor' +import { RichContent, TextEditor, useTextEditor } from 'web/components/editor' import { getUser, User } from 'web/lib/firebase/users' import { PencilIcon, ShareIcon } from '@heroicons/react/solid' import clsx from 'clsx' @@ -110,7 +110,7 @@ export default function PostPage(props: { {user && user.id === post.creatorId ? ( ) : ( - + )} @@ -178,7 +178,7 @@ function RichEditPost(props: { post: Post }) { if (!editor) return await updatePost(post, { - content: editor.getJSON(), + content: JSON.stringify(editor.getJSON()), }) } @@ -219,7 +219,7 @@ function RichEditPost(props: { post: Post }) { - + diff --git a/web/posts/post-comments.tsx b/web/posts/post-comments.tsx index b98887bb..16b48be0 100644 --- a/web/posts/post-comments.tsx +++ b/web/posts/post-comments.tsx @@ -9,7 +9,7 @@ import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import { Avatar } from 'web/components/avatar' import { CommentInput } from 'web/components/comment-input' -import { Content } from 'web/components/editor' +import { RichContent } from 'web/components/editor' import { CopyLinkDateTimeComponent } from 'web/components/feed/copy-link-date-time' import { Col } from 'web/components/layout/col' import { Row } from 'web/components/layout/row' @@ -108,7 +108,7 @@ export function PostComment(props: { onReplyClick?: (comment: PostComment) => void }) { const { post, comment, tips, indent, onReplyClick } = props - const { text, content, userUsername, userName, userAvatarUrl, createdTime } = + const { content, userUsername, userName, userAvatarUrl, createdTime } = comment const [highlighted, setHighlighted] = useState(false) @@ -150,9 +150,9 @@ export function PostComment(props: { elementId={comment.id} /> -