Skip to content

Commit

Permalink
Extract a ChatLogList component
Browse files Browse the repository at this point in the history
  • Loading branch information
gdbroman committed Apr 5, 2023
1 parent a86f44e commit a781614
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 82 deletions.
90 changes: 8 additions & 82 deletions app/src/renderer/apps/Courier/views/ChatLog.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { useMemo, useEffect, useState, useRef } from 'react';
import { useMemo, useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import styled from 'styled-components';
import { AnimatePresence } from 'framer-motion';
import { Virtuoso } from 'react-virtuoso';
import {
Box,
Flex,
Text,
Reply,
Expand All @@ -18,12 +16,11 @@ import { ChatInputBox } from '../components/ChatInputBox';
import { ChatLogHeader } from '../components/ChatLogHeader';
import { ChatAvatar } from '../components/ChatAvatar';
import { IuseStorage } from 'renderer/logic/lib/useStorage';
import { ChatMessage } from '../components/ChatMessage';
import { PinnedContainer } from '../components/PinnedMessage';
import { useServices } from 'renderer/logic/store';
import { ChatMessageType, ChatModelType } from '../models';
import { useAccountStore } from 'renderer/apps/Account/store';
import { displayDate } from 'os/lib/time';
import { ChatLogList } from './ChatLogList';

const FullWidthAnimatePresence = styled(AnimatePresence)`
width: 100%;
Expand All @@ -42,7 +39,6 @@ export const ChatLogPresenter = ({ storage }: ChatLogProps) => {
const accountStore = useAccountStore();
const { ship, friends } = useServices();
const [showAttachments, setShowAttachments] = useState(false);
const listRef = useRef<any>(null);

const { color: ourColor } = useMemo(() => {
if (!ship) return { color: '#000' };
Expand Down Expand Up @@ -199,82 +195,12 @@ export const ChatLogPresenter = ({ storage }: ChatLogProps) => {
/>
</FullWidthAnimatePresence>
)}
<Virtuoso
ref={listRef}
style={{
height,
width: containerWidth,
}}
data={messages}
initialTopMostItemIndex={messages.length - 1}
followOutput="auto"
itemContent={(index, row) => {
const isLast = selectedChat
? index === messages.length - 1
: false;

const isNextGrouped =
index < messages.length - 1 &&
row.sender === messages[index + 1].sender;

const isPrevGrouped =
index > 0 &&
row.sender === messages[index - 1].sender &&
Object.keys(messages[index - 1].contents[0])[0] !==
'status';

const topSpacing = isPrevGrouped ? '3px' : 2;
const bottomSpacing = isNextGrouped ? '3px' : 2;

const thisMsgDate = new Date(row.createdAt).toDateString();
const prevMsgDate =
messages[index - 1] &&
new Date(messages[index - 1].createdAt).toDateString();
const showDate = index === 0 || thisMsgDate !== prevMsgDate;

return (
<Box
key={row.id}
mx="1px"
pt={topSpacing}
pb={isLast ? bottomSpacing : 0}
>
{showDate && (
<Text.Custom
opacity={0.5}
fontSize="12px"
fontWeight={500}
textAlign="center"
mt={2}
mb={2}
>
{displayDate(row.createdAt)}
</Text.Custom>
)}
<ChatMessage
isPrevGrouped={isPrevGrouped}
isNextGrouped={isNextGrouped}
containerWidth={containerWidth}
message={row as ChatMessageType}
ourColor={ourColor}
onReplyClick={(replyId) => {
const replyIndex = messages.findIndex(
(msg) => msg.id === replyId
);
if (replyIndex === -1) return;

console.log('reply index', replyIndex);

listRef.current?.scrollToIndex({
index: replyIndex,
align: 'start',
behavior: 'smooth',
});
}}
/>
</Box>
);
}}
<ChatLogList
messages={messages}
selectedChat={selectedChat}
width={containerWidth}
height={height}
ourColor={ourColor}
/>
</Flex>
)}
Expand Down
97 changes: 97 additions & 0 deletions app/src/renderer/apps/Courier/views/ChatLogList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useRef } from 'react';
import { Virtuoso } from 'react-virtuoso';
import { Box, Text } from '@holium/design-system';
import { displayDate } from 'os/lib/time';
import { ChatMessage } from '../components/ChatMessage';
import { ChatMessageType, ChatModelType } from '../models';

type Props = {
width: number;
height: number;
messages: ChatMessageType[];
selectedChat: ChatModelType;
ourColor: string;
};

export const ChatLogList = ({
width,
height,
messages,
selectedChat,
ourColor,
}: Props) => {
const listRef = useRef<any>(null);

const renderChatRow = (index: number, row: ChatMessageType) => {
const isLast = selectedChat ? index === messages.length - 1 : false;

const isNextGrouped =
index < messages.length - 1 && row.sender === messages[index + 1].sender;

const isPrevGrouped =
index > 0 &&
row.sender === messages[index - 1].sender &&
Object.keys(messages[index - 1].contents[0])[0] !== 'status';

const topSpacing = isPrevGrouped ? '3px' : 2;
const bottomSpacing = isNextGrouped ? '3px' : 2;

const thisMsgDate = new Date(row.createdAt).toDateString();
const prevMsgDate =
messages[index - 1] &&
new Date(messages[index - 1].createdAt).toDateString();
const showDate = index === 0 || thisMsgDate !== prevMsgDate;

return (
<Box
key={row.id}
mx="1px"
pt={topSpacing}
pb={isLast ? bottomSpacing : 0}
>
{showDate && (
<Text.Custom
opacity={0.5}
fontSize="12px"
fontWeight={500}
textAlign="center"
mt={2}
mb={2}
>
{displayDate(row.createdAt)}
</Text.Custom>
)}
<ChatMessage
isPrevGrouped={isPrevGrouped}
isNextGrouped={isNextGrouped}
containerWidth={width}
message={row as ChatMessageType}
ourColor={ourColor}
onReplyClick={(replyId) => {
const replyIndex = messages.findIndex((msg) => msg.id === replyId);
if (replyIndex === -1) return;

console.log('reply index', replyIndex);

listRef.current?.scrollToIndex({
index: replyIndex,
align: 'start',
behavior: 'smooth',
});
}}
/>
</Box>
);
};

return (
<Virtuoso
ref={listRef}
data={messages}
followOutput="auto"
style={{ width, height }}
initialTopMostItemIndex={messages.length - 1}
itemContent={renderChatRow}
/>
);
};

0 comments on commit a781614

Please sign in to comment.