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-07-02 08:35:50 -04:00
import { useIntermediate } from "../../../context/intermediate/Intermediate" ;
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-07-02 08:35:50 -04:00
const { openScreen } = useIntermediate ( ) ;
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-07-02 08:35:50 -04:00
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-07-02 08:35:50 -04:00
const openProfile = ( ) = > openScreen ( { id : 'profile' , user_id : message.author } ) ;
2021-06-24 11:43:37 -04:00
2021-06-20 12:31:53 -04:00
return (
2021-06-26 04:45:07 -04:00
< div id = { message . _id } >
2021-06-23 13:26:41 -04:00
{ message . replies ? . map ( ( message_id , index ) = > < MessageReply index = { index } id = { message_id } channel = { message . channel } / > ) }
2021-06-26 04:45:07 -04:00
< MessageBase
2021-06-24 12:06:16 -04:00
head = { head && ! ( message . replies && message . replies . length > 0 ) }
2021-06-23 13:26:41 -04:00
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-07-02 08:35:50 -04:00
< UserIcon target = { user } size = { 36 } onContextMenu = { userContext } onClick = { openProfile } / > :
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" >
2021-07-02 10:51:06 -04:00
< Username className = "author" user = { user } onContextMenu = { userContext } onClick = { openProfile } / >
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-26 04:45:07 -04:00
< / div >
2021-06-20 12:31:53 -04:00
)
}
2021-06-23 11:14:46 -04:00
export default memo ( Message ) ;