Skip to content

Instantly share code, notes, and snippets.

@JacobKnaack
Created June 14, 2019 09:41
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 JacobKnaack/59673ee3c1434e2295dca2226c272aad to your computer and use it in GitHub Desktop.
Save JacobKnaack/59673ee3c1434e2295dca2226c272aad to your computer and use it in GitHub Desktop.
Cosmic Messenger message list component
import React from 'react';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';
import Socket from '../../lib/socket.js';
import { IoIosPulse, IoMdChatbubbles } from 'react-icons/io';
const GET_MESSAGES = gql`
query MessageList($read_key: String!) {
objectsByType(bucket_slug: "cosmic-messenger", type_slug: "messages", read_key: $read_key ) {
_id
title
content
created_at
metadata
}
}
`
function sortArrayByDate(arr) {
return arr.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
}
class MessageList extends React.Component {
constructor() {
super();
this.state = {
messages: [],
}
this.scrollToBottom = this.scrollToBottom.bind(this);
}
componentDidMount() {
Socket.subscribeToMessages(this.props.data.refetch);
}
componentDidUpdate(prevProps) {
if (
!this.props.data.loading
|| prevProps.data.objectsByType.length !== this.props.data.objectByType.length
) {
this.scrollToBottom();
}
}
static getDerivedStateFromProps(props, state) {
const tempState = state;
if (props.data.objectsByType) {
tempState.messages = sortArrayByDate(props.data.objectsByType);
}
return tempState;
}
render() {
if (this.props.data.loading) {
return (
<div className="loading-container">
<IoIosPulse style={{ fontSize: '200%' }} />
<p>Loading Messages</p>
</div>
)
} else if (!this.state.messages.length) {
return (
<div className="messageList-container">
<div>
<h4>Uh Oooh..</h4>
<IoMdChatbubbles style={{ fontSize: '400%', color: '#29ABE2' }} />
<p>It looks like there are no messages here. Start chatting and others will join you :)</p>
</div>
</div>
)
}
function formatDate(datestring) {
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', "Aug", 'Sep', 'Oct', 'Nov', 'Dec'];
const date = new Date(datestring);
const month = date.getMonth();
const dateNum = date.getDate();
const time = date.toLocaleTimeString();
return `${months[month]} ${dateNum}, ${time}`;
}
return (
<div className="messageList-container">
<div>End of Messages</div>
{this.state.messages.map(message => {
return (
<div key={message._id}>
{this.props.user._id !== message.metadata.user_id
? <div className="message-info">
<p>{message.title}</p>
<p>{formatDate(message.created_at)}</p>
</div>
: null
}
<span
className="message-container"
dangerouslySetInnerHTML={{ __html: message.content }}
style={this.props.user._id === message.metadata.user_id
? Object.assign({}, styles.message, styles.isUserMessage)
: styles.message}
/>
{this.props.user._id === message.metadata.user_id
? <div className="message-info">
<p>You</p>
<p>{formatDate(message.created_at)}</p>
</div>
: null
}
</div>
)
})
}
<div id="bottomRef" />
</div >
)
}
scrollToBottom() {
const bottomRef = document.getElementById('bottomRef');
if (bottomRef) {
bottomRef.scrollIntoView({ behavior: 'smooth' });
}
}
}
export default graphql(GET_MESSAGES, {
options: {
variables: {
read_key: __COSMIC_READ_KEY__,
}
},
props: ({ data }) => ({
data,
})
})(MessageList);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment