Fix appending to description
This commit is contained in:
parent
12ec239b16
commit
129afebff6
|
@ -1,6 +1,23 @@
|
|||
import { MAX_TAG_LENGTH } from '../contract'
|
||||
import { generateText, JSONContent, Extension } from '@tiptap/core'
|
||||
import * as StarterKit from '@tiptap/starter-kit' // needed for cjs import to work on firebase
|
||||
import { generateText, JSONContent } from '@tiptap/core'
|
||||
// Tiptap starter extensions
|
||||
import { Blockquote } from '@tiptap/extension-blockquote'
|
||||
import { Bold } from '@tiptap/extension-bold'
|
||||
import { BulletList } from '@tiptap/extension-bullet-list'
|
||||
import { Code } from '@tiptap/extension-code'
|
||||
import { CodeBlock } from '@tiptap/extension-code-block'
|
||||
import { Document } from '@tiptap/extension-document'
|
||||
import { HardBreak } from '@tiptap/extension-hard-break'
|
||||
import { Heading } from '@tiptap/extension-heading'
|
||||
import { History } from '@tiptap/extension-history'
|
||||
import { HorizontalRule } from '@tiptap/extension-horizontal-rule'
|
||||
import { Italic } from '@tiptap/extension-italic'
|
||||
import { ListItem } from '@tiptap/extension-list-item'
|
||||
import { OrderedList } from '@tiptap/extension-ordered-list'
|
||||
import { Paragraph } from '@tiptap/extension-paragraph'
|
||||
import { Strike } from '@tiptap/extension-strike'
|
||||
import { Text } from '@tiptap/extension-text'
|
||||
// import * as StarterKit from '@tiptap/starter-kit'
|
||||
import { Image } from '@tiptap/extension-image'
|
||||
|
||||
export function parseTags(text: string) {
|
||||
|
@ -31,8 +48,30 @@ export function parseWordsAsTags(text: string) {
|
|||
return parseTags(taggedText)
|
||||
}
|
||||
|
||||
export function richTextToString(text: JSONContent | string) {
|
||||
return typeof text === 'string'
|
||||
? text
|
||||
: generateText(text, [StarterKit as unknown as Extension, Image])
|
||||
// can't just do [StarterKit, Image...] because it doesn't work with some imports
|
||||
// see
|
||||
export const exhibitExts = [
|
||||
Blockquote,
|
||||
Bold,
|
||||
BulletList,
|
||||
Code,
|
||||
CodeBlock,
|
||||
Document,
|
||||
HardBreak,
|
||||
Heading,
|
||||
History,
|
||||
HorizontalRule,
|
||||
Italic,
|
||||
ListItem,
|
||||
OrderedList,
|
||||
Paragraph,
|
||||
Strike,
|
||||
Text,
|
||||
|
||||
Image,
|
||||
]
|
||||
// export const exhibitExts = [StarterKit as unknown as Extension, Image]
|
||||
|
||||
export function richTextToString(text?: JSONContent) {
|
||||
return !text ? '' : generateText(text, exhibitExts)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { getUser } from './utils'
|
|||
import { createNotification } from './create-notification'
|
||||
import { Contract } from '../../common/contract'
|
||||
import { richTextToString } from '../../common/util/parse'
|
||||
import { JSONContent } from '@tiptap/core'
|
||||
|
||||
export const onCreateContract = functions.firestore
|
||||
.document('contracts/{contractId}')
|
||||
|
@ -19,7 +20,7 @@ export const onCreateContract = functions.firestore
|
|||
'created',
|
||||
contractCreator,
|
||||
eventId,
|
||||
richTextToString(contract.description),
|
||||
richTextToString(contract.description as JSONContent),
|
||||
contract
|
||||
)
|
||||
})
|
||||
|
|
|
@ -5,12 +5,13 @@ import Textarea from 'react-expanding-textarea'
|
|||
import { CATEGORY_LIST } from '../../../common/categories'
|
||||
|
||||
import { Contract } from 'common/contract'
|
||||
import { parseTags, richTextToString } from 'common/util/parse'
|
||||
import { parseTags, exhibitExts } from 'common/util/parse'
|
||||
import { useAdmin } from 'web/hooks/use-admin'
|
||||
import { updateContract } from 'web/lib/firebase/contracts'
|
||||
import { Row } from '../layout/row'
|
||||
import { TagsList } from '../tags-list'
|
||||
import { Content } from '../editor'
|
||||
import { Editor } from '@tiptap/react'
|
||||
|
||||
export function ContractDescription(props: {
|
||||
contract: Contract
|
||||
|
@ -21,24 +22,33 @@ export function ContractDescription(props: {
|
|||
const descriptionTimestamp = () => `${dayjs().format('MMM D, h:mma')}: `
|
||||
const isAdmin = useAdmin()
|
||||
|
||||
const desc = contract.description ?? ''
|
||||
|
||||
// Append the new description (after a newline)
|
||||
async function saveDescription(newText: string) {
|
||||
// TODO: implement appending rich text description
|
||||
const textDescription = richTextToString(contract.description)
|
||||
const newDescription = `${textDescription}\n\n${newText}`.trim()
|
||||
console.log(desc, exhibitExts)
|
||||
|
||||
const editor = new Editor({ content: desc, extensions: exhibitExts })
|
||||
editor
|
||||
.chain()
|
||||
.focus('end')
|
||||
.insertContent('<br /><br />')
|
||||
.insertContent(newText.trim())
|
||||
.run()
|
||||
|
||||
const tags = parseTags(
|
||||
`${newDescription} ${contract.tags.map((tag) => `#${tag}`).join(' ')}`
|
||||
`${editor.getText()} ${contract.tags.map((tag) => `#${tag}`).join(' ')}`
|
||||
)
|
||||
const lowercaseTags = tags.map((tag) => tag.toLowerCase())
|
||||
|
||||
await updateContract(contract.id, {
|
||||
description: newDescription,
|
||||
description: editor.getJSON(),
|
||||
tags,
|
||||
lowercaseTags,
|
||||
})
|
||||
}
|
||||
|
||||
if (!isCreator && !contract.description) return null
|
||||
if (!isCreator) return null
|
||||
|
||||
const { tags } = contract
|
||||
const categories = tags.filter((tag) =>
|
||||
|
@ -52,7 +62,7 @@ export function ContractDescription(props: {
|
|||
className
|
||||
)}
|
||||
>
|
||||
<Content content={contract.description} />
|
||||
<Content content={desc} />
|
||||
|
||||
{categories.length > 0 && (
|
||||
<div className="mt-4">
|
||||
|
|
|
@ -31,6 +31,8 @@ import { DAY_MS } from 'common/util/time'
|
|||
import { useGroupsWithContract } from 'web/hooks/use-group'
|
||||
import { ShareIconButton } from 'web/components/share-icon-button'
|
||||
import { useUser } from 'web/hooks/use-user'
|
||||
import { Editor } from '@tiptap/react'
|
||||
import { exhibitExts } from 'common/util/parse'
|
||||
|
||||
export type ShowTime = 'resolve-date' | 'close-date'
|
||||
|
||||
|
@ -268,13 +270,20 @@ function EditableCloseDate(props: {
|
|||
const newCloseTime = dayjs(closeDate).valueOf()
|
||||
if (newCloseTime === closeTime) setIsEditingCloseTime(false)
|
||||
else if (newCloseTime > Date.now()) {
|
||||
const { description } = contract
|
||||
const content = contract.description
|
||||
const formattedCloseDate = dayjs(newCloseTime).format('YYYY-MM-DD h:mm a')
|
||||
const newDescription = `${description}\n\nClose date updated to ${formattedCloseDate}`
|
||||
|
||||
const editor = new Editor({ content, extensions: exhibitExts })
|
||||
editor
|
||||
.chain()
|
||||
.focus('end')
|
||||
.insertContent('<br /><br />')
|
||||
.insertContent(`Close date updated to ${formattedCloseDate}`)
|
||||
.run()
|
||||
|
||||
updateContract(contract.id, {
|
||||
closeTime: newCloseTime,
|
||||
description: newDescription,
|
||||
description: editor.getJSON(),
|
||||
})
|
||||
|
||||
setIsEditingCloseTime(false)
|
||||
|
|
|
@ -8,6 +8,7 @@ import { useEffect } from 'react'
|
|||
import { Linkify } from './linkify'
|
||||
import { uploadImage } from 'web/lib/firebase/storage'
|
||||
import { useMutation } from 'react-query'
|
||||
import { exhibitExts } from 'common/util/parse'
|
||||
|
||||
const proseClass =
|
||||
'prose prose-sm prose-p:my-0 prose-li:my-0 prose-blockquote:not-italic max-w-none'
|
||||
|
@ -80,10 +81,12 @@ function RichContent(props: { content: JSONContent }) {
|
|||
const { content } = props
|
||||
const editor = useEditor({
|
||||
editorProps: { attributes: { class: proseClass } },
|
||||
extensions: [StarterKit, Image],
|
||||
extensions: exhibitExts,
|
||||
content,
|
||||
editable: false,
|
||||
})
|
||||
useEffect(() => void editor?.commands?.setContent(content), [editor, content])
|
||||
|
||||
return <EditorContent editor={editor} />
|
||||
}
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ export function ContractPageContent(
|
|||
{ogCardProps && (
|
||||
<SEO
|
||||
title={question}
|
||||
description={richTextToString(ogCardProps.description)}
|
||||
description={ogCardProps.description}
|
||||
url={`/${props.username}/${props.slug}`}
|
||||
ogCardProps={ogCardProps}
|
||||
/>
|
||||
|
@ -392,15 +392,18 @@ const getOpenGraphProps = (contract: Contract) => {
|
|||
creatorUsername,
|
||||
outcomeType,
|
||||
creatorAvatarUrl,
|
||||
description: desc,
|
||||
} = contract
|
||||
const probPercent =
|
||||
outcomeType === 'BINARY' ? getBinaryProbPercent(contract) : undefined
|
||||
|
||||
const stringDesc = typeof desc === 'string' ? desc : richTextToString(desc)
|
||||
|
||||
const description = resolution
|
||||
? `Resolved ${resolution}. ${contract.description}`
|
||||
? `Resolved ${resolution}. ${stringDesc}`
|
||||
: probPercent
|
||||
? `${probPercent} chance. ${contract.description}`
|
||||
: contract.description
|
||||
? `${probPercent} chance. ${stringDesc}`
|
||||
: stringDesc
|
||||
|
||||
return {
|
||||
question,
|
||||
|
|
Loading…
Reference in New Issue
Block a user