Skip to content

Instantly share code, notes, and snippets.

@zackster
Created November 15, 2019 04:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zackster/31fb5a983a33b303626cd8ae9dee3b94 to your computer and use it in GitHub Desktop.
Save zackster/31fb5a983a33b303626cd8ae9dee3b94 to your computer and use it in GitHub Desktop.
import React, { Component } from "react";
import { connect } from "react-redux";
import ChatHistoryDateHeader from "./ChatHistoryDateHeader";
import ChatHistoryNameLabel from "./ChatHistoryNameLabel";
import ChatHistoryMessage from "./ChatHistoryMessage";
import ChatHistoryCell from "./ChatHistoryCell";
import ReactProgressiveList from "./ReactProgressiveList";
import SentryErrorBoundary from "./SentryErrorBoundary";
import {AutoSizer, CellMeasurer, CellMeasurerCache, List} from 'react-virtualized';
const shortid = require("shortid");
class ChatHistory extends Component {
constructor() {
super()
this.state = {
render_count: 0,
storedListReferences: false,
storedMeasurerReferences: false
}
this.renderRow = this.renderRow.bind(this);
this.cache = new CellMeasurerCache({
defaultHeight: 54
});
}
componentDidMount() {
const { selectedThread} = this.props;
}
componentDidUpdate() {
if(typeof(this._list)!=='undefined') {
this._list.recomputeRowHeights();
}
const { selectedThread } = this.props;
if(selectedThread !== null && !this.state.storedListReferences) {
this._list.scrollToRow(selectedThread.chat_log.length - 1);
};
}
scrollToBottom() {
// if (this.messagesEnd) {
// this.messagesEnd.scrollIntoView({ behavior: "auto" });
// }
const {selectedThread } = this.props;
// if (this.virtualizedList) {
// this.virtualizedList.scrolToRow(selectedThread.chat_log.length - 1);
// }
}
renderRow = ({
key, // Unique key within array of rows
index, // Index of row within collection
isScrolling, // The List is currently being scrolled
isVisible, // This row is visible within the List (eg it is not an overscanned row)
style, // Style object to be applied to row (to position it)
parent, // presumably another var passed into the fxn?
}) => {
const { selectedThread } = this.props;
if(!selectedThread.chat_log[index]) {
return;
}
const message = selectedThread.chat_log[index];
return (
<CellMeasurer
cache={this.cache}
columnIndex={0}
key={`cell_measurer_${key}`}
parent={parent}
rowIndex={index}
ref={this._setMeasurerRef}
container={() => this._list}
>
{({ measure }) => (
<div style={style}>
<ChatHistoryCell keyProp={`chat_history_cell_${key}`} message={message} measure={measure} onLoad={measure}/>
</div>
)}
</CellMeasurer>
);
}
render() {
const { selectedThread, draft, windowWidth, windowHeight } = this.props;
let chatHistoryKey;
let chatHistoryChatKey;
if (selectedThread !== null) {
chatHistoryKey = `chathistorythread${selectedThread.thread_id}`;
chatHistoryChatKey = `chathistorychatthread${selectedThread.thread_id}`;
} else if (draft !== null && typeof draft !== "undefined") {
chatHistoryKey = `chathistorydraft${draft.id}`;
chatHistoryChatKey = `chathistorychatdraft${draft.id}`;
} else {
chatHistoryKey = `chathistoryundefined${shortid.generate()}`;
chatHistoryChatKey = `chathistorychatundefined${shortid.generate()}`;
}
const topbarHeight = 55;
const chatInputHeight = 30;
const sidebarWidth = 272;
const height = windowHeight - topbarHeight - chatInputHeight - 25;
const width = windowWidth - sidebarWidth;
console.log({
height, width, windowWidth, windowHeight
})
return (
<div className="chathistory" key={chatHistoryKey}>
<div className="chat" key={chatHistoryChatKey}>
{selectedThread === null
? null
:
(
<List
deferredMeasurementCache={this.cache}
width={width}
height={height}
rowCount={selectedThread.chat_log.length}
rowHeight={this.cache.rowHeight}
rowRenderer={this.renderRow}
ref={this._setListRef}
/>
)
}
<div
style={{ float: "left", clear: "both" }}
ref={(el) => {
this.messagesEnd = el;
}}
/>
</div>
</div>
);
}
_setMeasurerRef = ref => {
this._cellMeasurer = ref;
const { dispatch } = this.props;
if(this.state.storedMeasurerReferences !== true) {
this.setState({
storedMeasurerReferences: true
});
dispatch({
type: 'STORE_CELL_MEASURER_REFERENCE',
cell_measurer: this._cellMeasurer
})
dispatch({
type: 'STORE_CELL_MEASURER_CACHE_REFERENCE',
cache: this.cache
})
}
};
_setListRef = ref => {
this._list = ref;
const { dispatch, selectedThread } = this.props;
if(this.state.storedListReferences !== true) {
this.setState({
storedListReferences: true
})
dispatch({
type: 'STORE_LIST_REFERENCE',
list: this._list
})
}
};
}
function mapStateToProps(state) {
return {
selectedThread: state.message.selected_thread,
draft: state.message.draft,
windowWidth: state.message.width,
windowHeight: state.message.height
};
}
export default connect(mapStateToProps)(ChatHistory);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment