BOD-14 Cleanup and re-org of some components for messaging.
This commit is contained in:
@@ -2,15 +2,8 @@ import { ShrinkOutlined } from "@ant-design/icons";
|
||||
import { Avatar, Badge, Col, List, Row } from "antd";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import {
|
||||
openConversation,
|
||||
toggleChatVisible
|
||||
} from "../../redux/messaging/messaging.actions";
|
||||
import { openConversation, toggleChatVisible } from "../../redux/messaging/messaging.actions";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
});
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
toggleChatVisible: () => dispatch(toggleChatVisible()),
|
||||
openConversation: number => dispatch(openConversation(number))
|
||||
@@ -59,7 +52,4 @@ export function ChatConversationListComponent({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ChatConversationListComponent);
|
||||
export default connect(null, mapDispatchToProps)(ChatConversationListComponent);
|
||||
|
||||
@@ -21,8 +21,8 @@ function ChatConversationClosedComponent({
|
||||
closeConversation
|
||||
}) {
|
||||
return (
|
||||
<div className='chat-overlay-closed'>
|
||||
<div onClick={() => toggleConversationVisible(conversation.phone_num)}>
|
||||
<div>
|
||||
<div onClick={() => toggleConversationVisible(conversation.id)}>
|
||||
<PhoneFormatter>{conversation.phone_num}</PhoneFormatter>
|
||||
</div>
|
||||
<Button
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
import { useSubscription } from "@apollo/react-hooks";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { MESSAGES_SUBSCRIPTION } from "../../graphql/messages.queries";
|
||||
import ChatConversationComponent from "./chat-conversation.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
});
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
|
||||
export function ChatConversationContainer({ conversation }) {
|
||||
export default function ChatConversationContainer({ conversation }) {
|
||||
const { loading, error, data } = useSubscription(MESSAGES_SUBSCRIPTION, {
|
||||
variables: { conversationId: conversation.id }
|
||||
});
|
||||
@@ -26,7 +17,3 @@ export function ChatConversationContainer({ conversation }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ChatConversationContainer);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import React from "react";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import ChatSendMessage from "../chat-send-message/chat-send-message.component";
|
||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||
import { CheckOutlined, CheckCircleOutlined } from "@ant-design/icons";
|
||||
import ChatMessageListComponent from "../chat-messages-list/chat-message-list.component";
|
||||
|
||||
export default function ChatConversationOpenComponent({
|
||||
conversation,
|
||||
@@ -10,49 +10,13 @@ export default function ChatConversationOpenComponent({
|
||||
subState
|
||||
}) {
|
||||
const [loading, error] = subState;
|
||||
const messagesEndRef = useRef(null);
|
||||
|
||||
const scrollToBottom = () => {
|
||||
console.log("use");
|
||||
!!messagesEndRef.current &&
|
||||
messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
|
||||
};
|
||||
|
||||
useEffect(scrollToBottom, [messages]);
|
||||
|
||||
if (loading) return <LoadingSpinner />;
|
||||
if (error) return <AlertComponent message={error.message} type='error' />;
|
||||
|
||||
const StatusRender = status => {
|
||||
switch (status) {
|
||||
case "sent":
|
||||
return <CheckOutlined style={{ margin: "2px", float: "right" }} />;
|
||||
case "delivered":
|
||||
return (
|
||||
<CheckCircleOutlined style={{ margin: "2px", float: "right" }} />
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='chat-overlay-open'>
|
||||
<div className='messages'>
|
||||
<ul>
|
||||
{messages.map(item => (
|
||||
<li
|
||||
key={item.id}
|
||||
className={`${item.isoutbound ? "replies" : "sent"}`}>
|
||||
<p>
|
||||
{item.text}
|
||||
{StatusRender(item.status)}
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
<li ref={messagesEndRef} />
|
||||
</ul>
|
||||
</div>
|
||||
<ChatMessageListComponent messages={messages} />
|
||||
<ChatSendMessage conversation={conversation} />
|
||||
</div>
|
||||
);
|
||||
|
||||
30
client/src/components/chat-dock/chat-dock.container.jsx
Normal file
30
client/src/components/chat-dock/chat-dock.container.jsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Affix } from "antd";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectConversations } from "../../redux/messaging/messaging.selectors";
|
||||
import ChatConversationContainer from "../chat-conversation/chat-conversation.container";
|
||||
import ChatMessagesButton from "../chat-messages-button/chat-messages-button.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
activeConversations: selectConversations
|
||||
});
|
||||
|
||||
export function ChatOverlayContainer({ activeConversations }) {
|
||||
return (
|
||||
<Affix offsetBottom={0}>
|
||||
<ChatMessagesButton />
|
||||
|
||||
{activeConversations
|
||||
? activeConversations.map(conversation => (
|
||||
<ChatConversationContainer
|
||||
conversation={conversation}
|
||||
key={conversation.id}
|
||||
/>
|
||||
))
|
||||
: null}
|
||||
</Affix>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, null)(ChatOverlayContainer);
|
||||
@@ -0,0 +1,37 @@
|
||||
import { MessageFilled } from "@ant-design/icons";
|
||||
import { Card } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ChatConversationListContainer from "../chat-conversation-list/chat-conversation-list.container";
|
||||
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectChatVisible } from "../../redux/messaging/messaging.selectors";
|
||||
import { toggleChatVisible } from "../../redux/messaging/messaging.actions";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
chatVisible: selectChatVisible
|
||||
});
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
toggleChatVisible: () => dispatch(toggleChatVisible())
|
||||
});
|
||||
|
||||
export function ChatWindowComponent({ chatVisible, toggleChatVisible }) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Card size='small'>
|
||||
{chatVisible ? (
|
||||
<ChatConversationListContainer />
|
||||
) : (
|
||||
<div onClick={() => toggleChatVisible()}>
|
||||
<MessageFilled />
|
||||
<strong>{t("messaging.labels.messaging")}</strong>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ChatWindowComponent);
|
||||
@@ -0,0 +1,44 @@
|
||||
import { CheckCircleOutlined, CheckOutlined } from "@ant-design/icons";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
|
||||
export default function ChatMessageListComponent({ messages }) {
|
||||
const messagesEndRef = useRef(null);
|
||||
|
||||
const scrollToBottom = () => {
|
||||
console.log("use");
|
||||
!!messagesEndRef.current &&
|
||||
messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
|
||||
};
|
||||
|
||||
useEffect(scrollToBottom, [messages]);
|
||||
const StatusRender = status => {
|
||||
switch (status) {
|
||||
case "sent":
|
||||
return <CheckOutlined style={{ margin: "2px", float: "right" }} />;
|
||||
case "delivered":
|
||||
return (
|
||||
<CheckCircleOutlined style={{ margin: "2px", float: "right" }} />
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='messages'>
|
||||
<ul>
|
||||
{messages.map(item => (
|
||||
<li
|
||||
key={item.id}
|
||||
className={`${item.isoutbound ? "replies" : "sent"}`}>
|
||||
<p>
|
||||
{item.text}
|
||||
{StatusRender(item.status)}
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
<li ref={messagesEndRef} />
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import { MessageFilled } from "@ant-design/icons";
|
||||
import { Card } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ChatConversationListContainer from "../chat-conversation-list/chat-conversation-list.container";
|
||||
|
||||
export default function ChatWindowComponent({
|
||||
chatVisible,
|
||||
toggleChatVisible
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Card
|
||||
className="chat-overlay"
|
||||
size='small'>
|
||||
{chatVisible ? (
|
||||
|
||||
<ChatConversationListContainer />
|
||||
|
||||
) : (
|
||||
<div className="chat-overlay-closed" onClick={() => toggleChatVisible()}>
|
||||
<MessageFilled />
|
||||
<strong style={{ paddingLeft: "10px" }}>
|
||||
{t("messaging.labels.messaging")}
|
||||
</strong>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
import { Affix, Badge } from "antd";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { toggleChatVisible } from "../../redux/messaging/messaging.actions";
|
||||
import {
|
||||
selectChatVisible,
|
||||
selectConversations
|
||||
} from "../../redux/messaging/messaging.selectors";
|
||||
import ChatConversationContainer from "../chat-conversation/chat-conversation.container";
|
||||
import ChatOverlayComponent from "./chat-overlay.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
chatVisible: selectChatVisible,
|
||||
activeConversations: selectConversations
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
toggleChatVisible: () => dispatch(toggleChatVisible())
|
||||
});
|
||||
|
||||
export function ChatOverlayContainer({
|
||||
chatVisible,
|
||||
toggleChatVisible,
|
||||
activeConversations
|
||||
}) {
|
||||
return (
|
||||
<Affix offsetBottom={0}>
|
||||
<div className={`chat-overlay-wrapper`}>
|
||||
<div className={`chat-overlay-scroller`}>
|
||||
<Badge count={10}>
|
||||
<ChatOverlayComponent
|
||||
chatVisible={chatVisible}
|
||||
toggleChatVisible={toggleChatVisible}
|
||||
/>
|
||||
</Badge>
|
||||
{activeConversations
|
||||
? activeConversations.map(conversation => (
|
||||
<ChatConversationContainer
|
||||
conversation={conversation}
|
||||
key={conversation.id}
|
||||
/>
|
||||
))
|
||||
: null}
|
||||
</div>
|
||||
</div>
|
||||
</Affix>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ChatOverlayContainer);
|
||||
@@ -20,8 +20,8 @@ const ProfilePage = lazy(() => import("../profile/profile.container.page"));
|
||||
const JobsAvailablePage = lazy(() =>
|
||||
import("../jobs-available/jobs-available.page.container")
|
||||
);
|
||||
const ChatWindowContainer = lazy(() =>
|
||||
import("../../components/chat-overlay/chat-overlay.container")
|
||||
const ChatDockContainer = lazy(() =>
|
||||
import("../../components/chat-dock/chat-dock.container")
|
||||
);
|
||||
const ScheduleContainer = lazy(() =>
|
||||
import("../schedule/schedule.page.container")
|
||||
@@ -135,7 +135,7 @@ export default function Manage({ match }) {
|
||||
<Footer>
|
||||
<FooterComponent />
|
||||
</Footer>
|
||||
<ChatWindowContainer />
|
||||
<ChatDockContainer />
|
||||
<BackTop />
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -94,7 +94,7 @@ const messagingReducer = (state = INITIAL_STATE, action) => {
|
||||
return {
|
||||
...state,
|
||||
conversations: state.conversations.map(c =>
|
||||
c.phone_num === action.payload ? { ...c, open: !c.open } : c
|
||||
c.id === action.payload ? { ...c, open: !c.open } : c
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user