112 lines
3.1 KiB
JavaScript
112 lines
3.1 KiB
JavaScript
import Icon from "@ant-design/icons";
|
|
import i18n from "i18next";
|
|
import moment from "moment";
|
|
import React, { useEffect, useRef } from "react";
|
|
import { MdDone, MdDoneAll } from "react-icons/md";
|
|
import {
|
|
AutoSizer,
|
|
CellMeasurer,
|
|
CellMeasurerCache,
|
|
List,
|
|
} from "react-virtualized";
|
|
import "./chat-message-list.styles.scss";
|
|
|
|
export default function ChatMessageListComponent({ messages }) {
|
|
const virtualizedListRef = useRef(null);
|
|
|
|
const _cache = new CellMeasurerCache({
|
|
fixedWidth: true,
|
|
// minHeight: 50,
|
|
defaultHeight: 100,
|
|
});
|
|
|
|
const scrollToBottom = (renderedrows) => {
|
|
//console.log("Scrolling to", messages.length);
|
|
// !!virtualizedListRef.current &&
|
|
// virtualizedListRef.current.scrollToRow(messages.length);
|
|
// Outstanding isue on virtualization: https://github.com/bvaughn/react-virtualized/issues/1179
|
|
//Scrolling does not work on this version of React.
|
|
};
|
|
|
|
useEffect(scrollToBottom, [messages]);
|
|
|
|
const _rowRenderer = ({ index, key, parent, style }) => {
|
|
return (
|
|
<CellMeasurer cache={_cache} key={key} rowIndex={index} parent={parent}>
|
|
{({ measure, registerChild }) => (
|
|
<div
|
|
ref={registerChild}
|
|
onLoad={measure}
|
|
style={style}
|
|
className={`${
|
|
messages[index].isoutbound ? "mine messages" : "yours messages"
|
|
}`}
|
|
>
|
|
<div className="message msgmargin">
|
|
{MessageRender(messages[index])}
|
|
{StatusRender(messages[index].status)}
|
|
</div>
|
|
{messages[index].isoutbound && (
|
|
<div style={{ fontSize: 10 }}>
|
|
{i18n.t("messaging.labels.sentby", {
|
|
by: messages[index].userid,
|
|
time: moment(messages[index].created_at).format(
|
|
"MM/DD/YYYY @ hh:mm a"
|
|
),
|
|
})}
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</CellMeasurer>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className="chat">
|
|
<AutoSizer>
|
|
{({ height, width }) => (
|
|
<List
|
|
ref={virtualizedListRef}
|
|
width={width}
|
|
height={height}
|
|
rowHeight={_cache.rowHeight}
|
|
rowRenderer={_rowRenderer}
|
|
rowCount={messages.length}
|
|
overscanRowCount={10}
|
|
estimatedRowSize={150}
|
|
scrollToIndex={messages.length}
|
|
/>
|
|
)}
|
|
</AutoSizer>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const MessageRender = (message) => {
|
|
return (
|
|
<div>
|
|
{message.image_path &&
|
|
message.image_path.map((i, idx) => (
|
|
<div key={idx} style={{ display: "flex", justifyContent: "center" }}>
|
|
<a href={i} target="__blank">
|
|
<img alt="Received" className="message-img" src={i} />
|
|
</a>
|
|
</div>
|
|
))}
|
|
<div>{message.text}</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const StatusRender = (status) => {
|
|
switch (status) {
|
|
case "sent":
|
|
return <Icon component={MdDone} className="message-icon" />;
|
|
case "delivered":
|
|
return <Icon component={MdDoneAll} className="message-icon" />;
|
|
default:
|
|
return null;
|
|
}
|
|
};
|