Files
ColdBreeze-chat-web/src/common/component/Message/index.js
T
2022-04-22 17:04:58 +08:00

147 lines
3.9 KiB
JavaScript

import React, { useRef, useState, useEffect } from "react";
import dayjs from "dayjs";
import isToday from "dayjs/plugin/isToday";
import isYesterday from "dayjs/plugin/isYesterday";
import { useSelector } from "react-redux";
import useInView from "./useInView";
import Tippy from "@tippyjs/react";
import Reaction from "./Reaction";
import Reply from "./Reply";
import Profile from "../Profile";
import Avatar from "../Avatar";
import StyledWrapper from "./styled";
import Commands from "./Commands";
import EditMessage from "./EditMessage";
import renderContent from "./renderContent";
import Tooltip from "../Tooltip";
dayjs.extend(isToday);
dayjs.extend(isYesterday);
function Message({
contextId = 0,
mid = "",
context = "user",
updateReadIndex,
read = true,
}) {
const inviewRef = useInView();
const [edit, setEdit] = useState(false);
const avatarRef = useRef(null);
const { message = {}, reactionMessageData, contactsData } = useSelector(
(store) => {
return {
reactionMessageData: store.reactionMessage,
message: store.message[mid] || {},
contactsData: store.contacts.byId,
};
}
);
const toggleEditMessage = () => {
setEdit((prev) => !prev);
};
const {
reply_mid,
from_uid: fromUid,
created_at: time,
sending = false,
content,
thumbnail,
download,
content_type = "text/plain",
edited,
properties,
} = message;
useEffect(() => {
if (!read) {
const data =
context == "user"
? { users: [{ uid: +contextId, mid }] }
: { groups: [{ gid: +contextId, mid }] };
updateReadIndex(data);
}
}, [mid, read]);
const reactions = reactionMessageData[mid];
const currUser = contactsData[fromUid] || {};
// if (!message) return null;
let timePrefix = null;
const dayjsTime = dayjs(time);
timePrefix = dayjsTime.isToday()
? "Today"
: dayjsTime.isYesterday()
? "Yesterday"
: null;
console.log("render message");
// return null;
return (
<StyledWrapper data-msg-mid={mid} ref={inviewRef} className={`message`}>
<Tippy
duration={0}
interactive
placement="left"
trigger="click"
content={<Profile uid={fromUid} type="card" />}
>
<div className="avatar" data-uid={fromUid} ref={avatarRef}>
<Avatar url={currUser.avatar} name={currUser.name} />
</div>
</Tippy>
<div className="details">
<div className="up">
<span className="name">{currUser.name}</span>
<Tooltip
delay={200}
disabled={!timePrefix}
placement="top"
tip={dayjsTime.format("YYYY-MM-DD h:mm:ss A")}
>
<i className="time">
{timePrefix
? `${timePrefix} ${dayjsTime.format("h:mm A")}`
: dayjsTime.format("YYYY-MM-DD h:mm:ss A")}
</i>
</Tooltip>
</div>
<div className={`down ${sending ? "sending" : ""}`}>
{reply_mid && <Reply mid={reply_mid} />}
{edit ? (
<EditMessage
content={content}
mid={mid}
cancelEdit={toggleEditMessage}
/>
) : (
renderContent({
context,
to: contextId,
from_uid: fromUid,
created_at: time,
content_type,
properties,
content,
thumbnail,
download,
edited,
})
)}
{reactions && <Reaction mid={mid} reactions={reactions} />}
</div>
</div>
{!edit && (
<Commands
contextId={contextId}
mid={mid}
from_uid={fromUid}
toggleEditMessage={toggleEditMessage}
/>
)}
</StyledWrapper>
);
}
export default React.memo(Message, (prevs, nexts) => {
return prevs.mid == nexts.mid;
});