diff --git a/src/common/store.js b/src/common/store.js index b5b304a..9ad7161 100644 --- a/src/common/store.js +++ b/src/common/store.js @@ -13,7 +13,8 @@ const intitialState = { glyph: "", title: "", content: "" - } + }, + messagesLoadedIn: [] }; const reducer = (state = intitialState, payload) => { @@ -74,6 +75,16 @@ const reducer = (state = intitialState, payload) => { }; } + case 'channels/firstmessageload': { + return { + ...state, + messagesLoadedIn: [ + ...state.messagesLoadedIn, + payload.channelId + ] + }; + } + case 'channels/updatepresence': { return { ...state, diff --git a/src/components/channel/ChannelMessageView.js b/src/components/channel/ChannelMessageView.js index 0403e36..b618ecb 100644 --- a/src/components/channel/ChannelMessageView.js +++ b/src/components/channel/ChannelMessageView.js @@ -1,52 +1,83 @@ -import { useRef, useEffect, useState } from 'react'; -import { useDispatch } from "react-redux"; +import { PureComponent, createRef } from 'react'; +import { connect } from "react-redux"; import { authenticated } from "../../api/request"; +import { getJsonValue } from '../../common/environmentmanager'; import Message from "../Message"; -export default function ChannelMessageView({ messages, channelId }) { - const invisibleBottomMessageRef = useRef(); +class ChannelMessageView extends PureComponent { + constructor() { + super(); + this.state = { + isLoading: false + }; + this.invisibleBottomMessageRef = createRef(); + this.scroller = createRef(); - const [isLoading, setIsLoading] = useState(false); - const dispatch = useDispatch(); - const scroller = useRef(); + this.onScroll = this.onScroll.bind(this); + } - const loadOlderMessages = () => { - if (isLoading) return; - if (!channelId) return; - setIsLoading(true); + loadOlderMessages() { + if (this.state.isLoading) return; + if (!getJsonValue("loadMessages")) return; // parse as json to get boolean + if (!this.props.channelId) return; + this.setState({ isLoading: true }); - const request = messages[0] ? `/api/v1/content/channel/${channelId}/messages?before=${messages[0]._id}` : `/api/v1/content/channel/${channelId}/messages`; + const request = this.props.messages[0] ? `/api/v1/content/channel/${this.props.channelId}/messages?before=${this.props.messages[0]._id}` : `/api/v1/content/channel/${this.props.channelId}/messages`; authenticated(request) .then((res) => { if (res.json.channelMessages) - dispatch({ + this.props.dispatch({ type: "messagestore/addmessagesback", messages: res.json.channelMessages.reverse(), - channelId - }) + channelId: this.props.channelId + }); }) .then(() => { - setIsLoading(false); + this.setState({ isLoading: false }); }); - }; + } - const onScroll = () => { - if (scroller.current.scrollTop === 0) { - loadOlderMessages(); + firstTimeMessageLoad() { + if (!this.props.channelId) return false; + if (this.props.messagesLoadedIn.includes(this.props.channelId)) return false; + this.props.dispatch({ + type: "channels/firstmessageload", + channelId: this.props.channelId + }); + this.loadOlderMessages(); + } + + onScroll() { + // TODO: this triggers when switching between channels so the firstmessageload check does not take effect + if (this.scroller.current.scrollTop === 0) + this.loadOlderMessages(); + } + + componentDidMount() { + this.firstTimeMessageLoad(); + } + + componentDidUpdate(prevProps) { + if (prevProps.messages !== this.props.messages) { + this.invisibleBottomMessageRef.current.scrollIntoView(true); } - }; + if (prevProps.channelId !== this.props.channelId) { + this.firstTimeMessageLoad(); + } + } - // eslint-disable-next-line react-hooks/exhaustive-deps - useEffect(loadOlderMessages, [channelId, dispatch]); - - useEffect(() => { - invisibleBottomMessageRef.current.scrollIntoView(true); - }, [messages]); - - return
- {messages.map(message => )} -
-
; + render() { + return
+ {this.props.messages.map(message => )} +
+
; + } } + +export default connect((state) => { + return { + messagesLoadedIn: state.messagesLoadedIn + }; +}, null)(ChannelMessageView); diff --git a/src/config.js b/src/config.js index 3c734c9..3bbdfd8 100644 --- a/src/config.js +++ b/src/config.js @@ -1,7 +1,8 @@ const config = { apiUrl: "http://localhost:3000", gatewayUrl: "ws://localhost:3005/gateway", - gatewayConnectionAttributes: ["PRESENCE_UPDATES"] + gatewayConnectionAttributes: ["PRESENCE_UPDATES"], + loadMessages: true }; export default config; \ No newline at end of file