2021-06-20 17:09:18 -04:00
import Embed from "./embed/Embed" ;
2021-06-20 15:30:42 -04:00
import UserIcon from "../user/UserIcon" ;
import { Username } from "../user/UserShort" ;
2021-06-20 12:31:53 -04:00
import Markdown from "../../markdown/Markdown" ;
import { Children } from "../../../types/Preact" ;
2021-06-20 17:09:18 -04:00
import Attachment from "./attachments/Attachment" ;
2021-06-20 12:31:53 -04:00
import { attachContextMenu } from "preact-context-menu" ;
import { useUser } from "../../../context/revoltjs/hooks" ;
2021-06-22 05:59:06 -04:00
import { QueuedMessage } from "../../../redux/reducers/queue" ;
2021-06-20 12:31:53 -04:00
import { MessageObject } from "../../../context/revoltjs/util" ;
import MessageBase , { MessageContent , MessageDetail , MessageInfo } from "./MessageBase" ;
2021-06-22 05:59:06 -04:00
import Overline from "../../ui/Overline" ;
2021-06-22 08:28:03 -04:00
import { useContext } from "preact/hooks" ;
import { AppContext } from "../../../context/revoltjs/RevoltClient" ;
2021-06-23 11:14:46 -04:00
import { memo } from "preact/compat" ;
2021-06-23 13:26:41 -04:00
import { MessageReply } from "./attachments/MessageReply" ;
2021-06-20 12:31:53 -04:00
interface Props {
attachContext? : boolean
2021-06-22 05:59:06 -04:00
queued? : QueuedMessage
2021-06-20 12:31:53 -04:00
message : MessageObject
contrast? : boolean
content? : Children
head? : boolean
}
2021-06-23 11:14:46 -04:00
function Message ( { attachContext , message , contrast , content : replacement , head : preferHead , queued } : Props ) {
2021-06-20 12:31:53 -04:00
// TODO: Can improve re-renders here by providing a list
// TODO: of dependencies. We only need to update on u/avatar.
2021-06-22 08:28:03 -04:00
const user = useUser ( message . author ) ;
const client = useContext ( AppContext ) ;
2021-06-20 12:31:53 -04:00
2021-06-20 17:09:18 -04:00
const content = message . content as string ;
2021-06-23 13:26:41 -04:00
const head = preferHead || ( message . replies && message . replies . length > 0 ) ;
2021-06-24 11:43:37 -04:00
const userContext = attachContext ? attachContextMenu ( 'Menu' , { user : message.author , contextualChannel : message.channel } ) : undefined as any ; // ! FIXME: tell fatal to make this type generic
2021-06-20 12:31:53 -04:00
return (
2021-06-23 13:26:41 -04:00
< >
{ message . replies ? . map ( ( message_id , index ) = > < MessageReply index = { index } id = { message_id } channel = { message . channel } / > ) }
< MessageBase id = { message . _id }
head = { head && ! message . replies }
contrast = { contrast }
sending = { typeof queued !== 'undefined' }
mention = { message . mentions ? . includes ( client . user ! . _id ) }
failed = { typeof queued ? . error !== 'undefined' }
onContextMenu = { attachContext ? attachContextMenu ( 'Menu' , { message , contextualChannel : message.channel , queued } ) : undefined } >
< MessageInfo >
{ head ?
2021-06-24 11:43:37 -04:00
< UserIcon target = { user } size = { 36 } onContextMenu = { userContext } / > :
2021-06-23 13:26:41 -04:00
< MessageDetail message = { message } position = "left" / > }
< / MessageInfo >
< MessageContent >
2021-06-24 11:43:37 -04:00
{ head && < span className = "detail" >
< span className = "author" >
< Username user = { user } onContextMenu = { userContext } / >
< / span >
2021-06-23 13:26:41 -04:00
< MessageDetail message = { message } position = "top" / >
< / span > }
{ replacement ? ? < Markdown content = { content } / > }
{ queued ? . error && < Overline type = "error" error = { queued . error } / > }
{ message . attachments ? . map ( ( attachment , index ) = >
< Attachment key = { index } attachment = { attachment } hasContent = { index > 0 || content . length > 0 } / > ) }
{ message . embeds ? . map ( ( embed , index ) = >
< Embed key = { index } embed = { embed } / > ) }
< / MessageContent >
< / MessageBase >
< / >
2021-06-20 12:31:53 -04:00
)
}
2021-06-23 11:14:46 -04:00
export default memo ( Message ) ;