import { getPagePath } from '@nanostores/router'
import { clsx } from 'clsx'
import { For, Show, Suspense, createMemo, createSignal, lazy } from 'solid-js'
import { useConfirm } from '../../../context/confirm'
import { useLocalize } from '../../../context/localize'
import { useReactions } from '../../../context/reactions'
import { useSession } from '../../../context/session'
import { useSnackbar } from '../../../context/snackbar'
import { Author, Reaction, ReactionKind } from '../../../graphql/schema/core.gen'
import { router } from '../../../stores/router'
import { AuthorLink } from '../../Author/AuthorLink'
import { Userpic } from '../../Author/Userpic'
import { Icon } from '../../_shared/Icon'
import { ShowIfAuthenticated } from '../../_shared/ShowIfAuthenticated'
import { CommentDate } from '../CommentDate'
import { CommentRatingControl } from '../CommentRatingControl'
import styles from './Comment.module.scss'
const SimplifiedEditor = lazy(() => import('../../Editor/SimplifiedEditor'))
type Props = {
comment: Reaction
compact?: boolean
isArticleAuthor?: boolean
sortedComments?: Reaction[]
lastSeen?: number
class?: string
showArticleLink?: boolean
clickedReply?: (id: number) => void
clickedReplyId?: number
onDelete?: (id: number) => void
}
export const Comment = (props: Props) => {
const { t } = useLocalize()
const [isReplyVisible, setIsReplyVisible] = createSignal(false)
const [loading, setLoading] = createSignal(false)
const [editMode, setEditMode] = createSignal(false)
const [clearEditor, setClearEditor] = createSignal(false)
const [editedBody, setEditedBody] = createSignal()
const { author, session } = useSession()
const { createReaction, deleteReaction, updateReaction } = useReactions()
const { showConfirm } = useConfirm()
const { showSnackbar } = useSnackbar()
const canEdit = createMemo(
() =>
Boolean(author()?.id) &&
(props.comment?.created_by?.slug === author()?.slug || session()?.user?.roles.includes('editor')),
)
const body = createMemo(() => (editedBody() ? editedBody().trim() : props.comment.body.trim() || ''))
const remove = async () => {
if (props.comment?.id) {
try {
const isConfirmed = await showConfirm({
confirmBody: t('Are you sure you want to delete this comment?'),
confirmButtonLabel: t('Delete'),
confirmButtonVariant: 'danger',
declineButtonVariant: 'primary',
})
if (isConfirmed) {
const { error } = await deleteReaction(props.comment.id)
const notificationType = error ? 'error' : 'success'
const notificationMessage = error
? t('Failed to delete comment')
: t('Comment successfully deleted')
await showSnackbar({ type: notificationType, body: notificationMessage })
if (!error && props.onDelete) {
props.onDelete(props.comment.id)
}
}
} catch (error) {
await showSnackbar({ body: 'error' })
console.error('[deleteReaction]', error)
}
}
}
const handleCreate = async (value) => {
try {
setLoading(true)
await createReaction({
kind: ReactionKind.Comment,
reply_to: props.comment.id,
body: value,
shout: props.comment.shout.id,
})
setClearEditor(true)
setIsReplyVisible(false)
setLoading(false)
} catch (error) {
console.error('[handleCreate reaction]:', error)
}
setClearEditor(false)
}
const toggleEditMode = () => {
setEditMode((oldEditMode) => !oldEditMode)
}
const handleUpdate = async (value) => {
setLoading(true)
try {
const reaction = await updateReaction({
id: props.comment.id,
kind: ReactionKind.Comment,
body: value,
shout: props.comment.shout.id,
})
if (reaction) {
setEditedBody(value)
}
setEditMode(false)
setLoading(false)
} catch (error) {
console.error('[handleCreate reaction]:', error)
}
}
return (
}>
handleCreate(value)}
submitByCtrlEnter={true}
/>
r.reply_to === props.comment.id)}>
{(c) => (
)}
)
}