diff --git a/common/util/parse.ts b/common/util/parse.ts
index 21cf1760..acbf6c61 100644
--- a/common/util/parse.ts
+++ b/common/util/parse.ts
@@ -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)
}
diff --git a/functions/src/on-create-contract.ts b/functions/src/on-create-contract.ts
index 614a5c2a..28682793 100644
--- a/functions/src/on-create-contract.ts
+++ b/functions/src/on-create-contract.ts
@@ -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
)
})
diff --git a/web/components/contract/contract-description.tsx b/web/components/contract/contract-description.tsx
index 2c723c97..b932c41d 100644
--- a/web/components/contract/contract-description.tsx
+++ b/web/components/contract/contract-description.tsx
@@ -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('
')
+ .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
)}
>
-