feat: message history from message-history branch

This commit is contained in:
hippoz 2021-10-04 22:43:20 +03:00
parent 8f4e3980c7
commit 5eb1c2d0ae
No known key found for this signature in database
GPG key ID: 7C52899193467641
5 changed files with 57 additions and 13 deletions

View file

@ -18,6 +18,7 @@ const wsCloseCodes = {
NOT_AUTHORIZED: [4006, "Not authorized"], NOT_AUTHORIZED: [4006, "Not authorized"],
FLOODING: [4007, "Flooding"], FLOODING: [4007, "Flooding"],
NO_PING: [4008, "No ping"], NO_PING: [4008, "No ping"],
UNSUPPORTED_ATTRIBUTE: [4009, "Unsupported attribute."],
}; };
const cancelReconnectionForCodes = [ const cancelReconnectionForCodes = [
wsCloseCodes.NOT_AUTHENTICATED[0], wsCloseCodes.NOT_AUTHENTICATED[0],
@ -25,6 +26,7 @@ const cancelReconnectionForCodes = [
wsCloseCodes.SERVER_DENIED_CONNECTION[0], wsCloseCodes.SERVER_DENIED_CONNECTION[0],
wsCloseCodes.TOO_MANY_SESSIONS[0], wsCloseCodes.TOO_MANY_SESSIONS[0],
wsCloseCodes.FLOODING[0], wsCloseCodes.FLOODING[0],
wsCloseCodes.UNSUPPORTED_ATTRIBUTE[0],
]; ];
globalGatewayConnection.onopen = (sessionData) => { globalGatewayConnection.onopen = (sessionData) => {

View file

@ -54,6 +54,19 @@ const reducer = (state = intitialState, payload) => {
}; };
} }
case 'messagestore/addmessagesback': {
return {
...state,
messages: {
...state.messages,
[payload.channelId]: [
...payload.messages,
...state.messages[payload.channelId] || []
]
}
};
}
case 'channels/selectchannel': { case 'channels/selectchannel': {
return { return {
...state, ...state,

View file

@ -1,22 +1,51 @@
import { useRef, useEffect } from 'react'; import { useRef, useEffect, useState } from 'react';
import { useDispatch } from "react-redux";
import { authenticated } from "../../api/request";
import Message from "../Message"; import Message from "../Message";
export default function ChannelMessageView({messages}) { export default function ChannelMessageView({ messages, channelId }) {
const invisibleBottomMessageRef = useRef(); const invisibleBottomMessageRef = useRef();
const [isLoading, setIsLoading] = useState(false);
const dispatch = useDispatch();
const scroller = useRef();
const loadOlderMessages = () => {
if (isLoading) return;
if (!channelId) return;
setIsLoading(true);
const request = messages[0] ? `/api/v1/content/channel/${channelId}/messages?before=${messages[0]._id}` : `/api/v1/content/channel/${channelId}/messages`;
authenticated(request)
.then((res) => {
if (res.json.channelMessages)
dispatch({
type: "messagestore/addmessagesback",
messages: res.json.channelMessages.reverse(),
channelId
})
})
.then(() => {
setIsLoading(false);
});
};
const onScroll = () => {
if (scroller.current.scrollTop === 0) {
loadOlderMessages();
}
};
useEffect(loadOlderMessages, [channelId, dispatch]);
useEffect(() => { useEffect(() => {
invisibleBottomMessageRef.current.scrollIntoView(true); invisibleBottomMessageRef.current.scrollIntoView(true);
}, [messages]); }, [messages]);
let messagesView = messages.map((message) => (<Message key={message._id} message={message} />)); return <div className="message-list" id="message-list" ref={ scroller } onScroll={ onScroll }>
if (messagesView === undefined || messagesView.length <= 0) {messages.map(message => <Message message={message} key={message._id} />)}
messagesView = (<div className='no-messages-warning'>
<span style={{ margin: "12px" }}>No messages yet...</span>
</div>);
return <div className="message-list">
{ messagesView }
<div className="messages-scroll-div" ref={ invisibleBottomMessageRef }></div> <div className="messages-scroll-div" ref={ invisibleBottomMessageRef }></div>
</div>; </div>;
} }

View file

@ -41,7 +41,7 @@ const ChannelView = ({ messages, channel, channelPresenceClientList }) => {
<div className="row-flex hidden-overflow"> <div className="row-flex hidden-overflow">
<div className="channel-message-panel"> <div className="channel-message-panel">
<ChannelMessageView messages={messages}></ChannelMessageView> <ChannelMessageView messages={messages} channelId={channel._id}></ChannelMessageView>
<div className="col-flex"> <div className="col-flex">
<input className="text-input message-input" type="text" placeholder="Go on, type something interesting!" ref={ textInputRef } onKeyDown={ handleTextboxKeydown } onChange={ ({ target }) => setTextInput(target.value) }></input> <input className="text-input message-input" type="text" placeholder="Go on, type something interesting!" ref={ textInputRef } onKeyDown={ handleTextboxKeydown } onChange={ ({ target }) => setTextInput(target.value) }></input>
</div> </div>

View file

@ -69,7 +69,7 @@
} }
.profile-username { .profile-username {
font-weight: 500; font-weight: 600;
font-size: 1rem; font-size: 1rem;
line-height: 1.256rem; line-height: 1.256rem;
} }