webapp/src/components/Inbox/Message.tsx

67 lines
2.1 KiB
TypeScript
Raw Normal View History

2022-12-13 11:10:54 +00:00
import { createEffect, createMemo, createSignal, Show } from 'solid-js'
2022-11-21 05:06:53 +00:00
import MarkdownIt from 'markdown-it'
2022-11-16 12:25:37 +00:00
import { clsx } from 'clsx'
import styles from './Message.module.scss'
2022-11-21 05:06:53 +00:00
import DialogAvatar from './DialogAvatar'
2022-12-05 05:41:53 +00:00
import type { Message, ChatMember } from '../../graphql/types.gen'
2022-12-06 05:47:02 +00:00
import formattedTime from '../../utils/formatDateTime'
2022-12-09 10:22:56 +00:00
import { Icon } from '../_shared/Icon'
2022-12-12 08:11:43 +00:00
import { MessageActionsPopup } from './MessageActionsPopup'
2022-12-12 09:58:54 +00:00
import QuotedMessage from './QuotedMessage'
2022-11-16 12:25:37 +00:00
type Props = {
2022-12-05 05:41:53 +00:00
content: Message
ownId: number
members: ChatMember[]
2022-12-09 15:30:20 +00:00
replyClick?: () => void
2022-12-12 09:58:54 +00:00
replyBody?: string
replyAuthor?: string
2022-11-16 12:25:37 +00:00
}
2022-11-21 05:06:53 +00:00
const md = new MarkdownIt({
2022-12-14 03:38:49 +00:00
linkify: true,
breaks: true
2022-11-21 05:06:53 +00:00
})
2022-11-16 12:25:37 +00:00
const Message = (props: Props) => {
2022-12-05 05:41:53 +00:00
const isOwn = props.ownId === Number(props.content.author)
2022-12-07 06:10:45 +00:00
const user = props.members?.find((m) => m.id === Number(props.content.author))
2022-12-13 11:10:54 +00:00
const [isPopupVisible, setIsPopupVisible] = createSignal<boolean>(false)
const handleMouseLeave = () => {
if (isPopupVisible()) setIsPopupVisible(false)
}
2022-11-16 12:25:37 +00:00
return (
2022-12-05 05:41:53 +00:00
<div class={clsx(styles.Message, isOwn && styles.own)}>
<Show when={!isOwn}>
2022-11-21 05:06:53 +00:00
<div class={styles.author}>
2022-12-06 05:47:02 +00:00
<DialogAvatar size="small" name={user.name} url={user.userpic} />
<div class={styles.name}>{user.name}</div>
2022-11-21 05:06:53 +00:00
</div>
</Show>
2022-12-13 11:10:54 +00:00
<div class={styles.body} onMouseLeave={handleMouseLeave}>
2022-12-09 12:19:30 +00:00
<div class={styles.text}>
<div class={styles.actions}>
2022-12-09 15:30:20 +00:00
<div onClick={props.replyClick}>
<Icon name="chat-reply" class={styles.reply} />
</div>
2022-12-13 11:10:54 +00:00
<MessageActionsPopup
forceHide={!isPopupVisible()}
onVisibilityChange={(isVisible) => setIsPopupVisible(isVisible)}
trigger={<Icon name="menu" />}
/>
2022-12-09 12:19:30 +00:00
</div>
2022-12-12 09:58:54 +00:00
<Show when={props.replyBody}>
<QuotedMessage body={props.replyBody} variant="inline" />
</Show>
2022-12-09 12:19:30 +00:00
<div innerHTML={md.render(props.content.body)} />
</div>
2022-11-21 05:06:53 +00:00
</div>
2022-12-06 05:47:02 +00:00
<div class={styles.time}>{formattedTime(props.content.createdAt)}</div>
2022-11-16 12:25:37 +00:00
</div>
)
}
export default Message