Browse Source

remove poll note

fix poll previews
imwald
Silberengel 4 months ago
parent
commit
9f5c607252
  1. 52
      src/components/ContentPreview/PollPreview.tsx
  2. 14
      src/components/PostEditor/PollEditor.tsx
  3. 1
      src/components/PostEditor/PostContent.tsx
  4. 49
      src/components/PostEditor/PostTextarea/Preview.tsx
  5. 6
      src/components/PostEditor/PostTextarea/index.tsx

52
src/components/ContentPreview/PollPreview.tsx

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
import { POLL_TYPE } from '@/constants'
import { useTranslatedEvent } from '@/hooks'
import { getPollMetadataFromEvent } from '@/lib/event-metadata'
import { getEmojiInfosFromEmojiTags } from '@/lib/tag'
import { cn } from '@/lib/utils'
import { Event } from 'nostr-tools'
@ -10,15 +12,53 @@ export default function PollPreview({ event, className }: { event: Event; classN @@ -10,15 +12,53 @@ export default function PollPreview({ event, className }: { event: Event; classN
const { t } = useTranslation()
const translatedEvent = useTranslatedEvent(event.id)
const emojiInfos = useMemo(() => getEmojiInfosFromEmojiTags(event.tags), [event])
const poll = useMemo(
() => getPollMetadataFromEvent(translatedEvent ?? event),
[event, translatedEvent]
)
const content = (translatedEvent?.content ?? event.content)?.trim()
return (
<div className={cn('pointer-events-none', className)}>
[{t('Poll')}]{' '}
<Content
content={translatedEvent?.content ?? event.content}
emojiInfos={emojiInfos}
className="italic pr-0.5"
/>
<div className="flex items-center gap-1 mb-1">
<span className="text-muted-foreground">[{t('Poll')}]</span>
{poll?.pollType === POLL_TYPE.MULTIPLE_CHOICE && (
<span className="text-xs text-muted-foreground">({t('Multiple choice')})</span>
)}
</div>
{content ? (
<div className="mb-1">
<Content
content={content}
emojiInfos={emojiInfos}
className="italic pr-0.5"
/>
</div>
) : null}
{poll && poll.options.length > 0 ? (
<div className="grid gap-2">
{poll.options.map((option) => (
<div
key={option.id}
className="relative w-full px-4 py-3 rounded-lg border border-border bg-background flex items-center gap-2 overflow-hidden"
>
<div className="flex items-center gap-2 flex-1 w-0 z-10">
<div className="line-clamp-2 text-left text-sm">
{option.label || t('Option')}
</div>
</div>
</div>
))}
</div>
) : poll ? (
<div className="text-sm text-muted-foreground italic">
{t('Poll with no options')}
</div>
) : (
<div className="text-sm text-muted-foreground italic">
{content || t('Poll')}
</div>
)}
</div>
)
}

14
src/components/PostEditor/PollEditor.tsx

@ -8,7 +8,6 @@ import dayjs from 'dayjs' @@ -8,7 +8,6 @@ import dayjs from 'dayjs'
import { Eraser, X } from 'lucide-react'
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import AlertCard from '../AlertCard'
export default function PollEditor({
pollCreateData,
@ -123,19 +122,6 @@ export default function PollEditor({ @@ -123,19 +122,6 @@ export default function PollEditor({
placeholder="wss://relay1.com, wss://relay2.com"
/>
</div>
<div className="grid gap-2">
<AlertCard
title={t('This is a poll note.')}
content={t(
'Unlike regular notes, polls are not widely supported and may not display on other clients.'
)}
/>
<Button variant="ghost-destructive" className="w-full" onClick={() => setIsPoll(false)}>
{t('Remove poll')}
</Button>
</div>
</div>
)
}

1
src/components/PostEditor/PostContent.tsx

@ -491,6 +491,7 @@ export default function PostContent({ @@ -491,6 +491,7 @@ export default function PostContent({
onUploadEnd={handleUploadEnd}
kind={isHighlight ? kinds.Highlights : isPublicMessage ? ExtendedKind.PUBLIC_MESSAGE : isPoll ? ExtendedKind.POLL : kinds.ShortTextNote}
highlightData={isHighlight ? highlightData : undefined}
pollCreateData={isPoll ? pollCreateData : undefined}
/>
{isPoll && (
<PollEditor

49
src/components/PostEditor/PostTextarea/Preview.tsx

@ -1,10 +1,14 @@ @@ -1,10 +1,14 @@
import { Card } from '@/components/ui/card'
import { ExtendedKind, POLL_TYPE } from '@/constants'
import { transformCustomEmojisInContent } from '@/lib/draft-event'
import { createFakeEvent } from '@/lib/event'
import { randomString } from '@/lib/random'
import { cleanUrl } from '@/lib/url'
import { cn } from '@/lib/utils'
import { TPollCreateData } from '@/types'
import { kinds, nip19 } from 'nostr-tools'
import { useMemo } from 'react'
import ContentPreview from '../../ContentPreview'
import Content from '../../Content'
import Highlight from '../../Note/Highlight'
import { HighlightData } from '../HighlightEditor'
@ -13,14 +17,16 @@ export default function Preview({ @@ -13,14 +17,16 @@ export default function Preview({
content,
className,
kind = 1,
highlightData
highlightData,
pollCreateData
}: {
content: string
className?: string
kind?: number
highlightData?: HighlightData
pollCreateData?: TPollCreateData
}) {
const { content: processedContent, emojiTags, highlightTags } = useMemo(
const { content: processedContent, emojiTags, highlightTags, pollTags } = useMemo(
() => {
// Clean tracking parameters from URLs in the preview
const cleanedContent = content.replace(
@ -70,19 +76,36 @@ export default function Preview({ @@ -70,19 +76,36 @@ export default function Preview({
}
}
// Build poll tags if this is a poll
let pollTags: string[][] = []
if (kind === ExtendedKind.POLL && pollCreateData) {
const validOptions = pollCreateData.options.filter((opt) => opt.trim())
pollTags.push(...validOptions.map((option) => ['option', randomString(9), option.trim()]))
pollTags.push(['polltype', pollCreateData.isMultipleChoice ? POLL_TYPE.MULTIPLE_CHOICE : POLL_TYPE.SINGLE_CHOICE])
if (pollCreateData.endsAt) {
pollTags.push(['endsAt', pollCreateData.endsAt.toString()])
}
if (pollCreateData.relays.length > 0) {
pollCreateData.relays.forEach((relay) => {
pollTags.push(['relay', relay])
})
}
}
return {
content: processed,
emojiTags: tags,
highlightTags
highlightTags,
pollTags
}
},
[content, kind, highlightData]
[content, kind, highlightData, pollCreateData]
)
// Combine emoji tags and highlight tags
// Combine emoji tags, highlight tags, and poll tags
const allTags = useMemo(() => {
return [...emojiTags, ...highlightTags]
}, [emojiTags, highlightTags])
return [...emojiTags, ...highlightTags, ...pollTags]
}, [emojiTags, highlightTags, pollTags])
const fakeEvent = useMemo(() => {
return createFakeEvent({
@ -92,6 +115,18 @@ export default function Preview({ @@ -92,6 +115,18 @@ export default function Preview({
})
}, [processedContent, allTags, kind])
// For polls, use ContentPreview to show poll properly
if (kind === ExtendedKind.POLL) {
return (
<Card className={cn('p-3', className)}>
<ContentPreview
event={fakeEvent}
className="pointer-events-none"
/>
</Card>
)
}
// For highlights, use the Highlight component for proper formatting
if (kind === kinds.Highlights) {
return (

6
src/components/PostEditor/PostTextarea/index.tsx

@ -43,6 +43,7 @@ const PostTextarea = forwardRef< @@ -43,6 +43,7 @@ const PostTextarea = forwardRef<
onUploadEnd?: (file: File) => void
kind?: number
highlightData?: HighlightData
pollCreateData?: import('@/types').TPollCreateData
}
>(
(
@ -57,7 +58,8 @@ const PostTextarea = forwardRef< @@ -57,7 +58,8 @@ const PostTextarea = forwardRef<
onUploadProgress,
onUploadEnd,
kind = 1,
highlightData
highlightData,
pollCreateData
},
ref
) => {
@ -173,7 +175,7 @@ const PostTextarea = forwardRef< @@ -173,7 +175,7 @@ const PostTextarea = forwardRef<
<EditorContent className="tiptap" editor={editor} />
</TabsContent>
<TabsContent value="preview">
<Preview content={text} className={className} kind={kind} highlightData={highlightData} />
<Preview content={text} className={className} kind={kind} highlightData={highlightData} pollCreateData={pollCreateData} />
</TabsContent>
</Tabs>
)

Loading…
Cancel
Save