Skip to content

Commit

Permalink
added new msg layout with functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Bhupesh-mfsi committed Oct 5, 2024
1 parent c910f9d commit 511dade
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 30 deletions.
43 changes: 41 additions & 2 deletions packages/messenger-widget/src/components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { MessageInputBox } from '../MessageInputBox/MessageInputBox';
import { scrollToBottomOfChat } from './scrollToBottomOfChat';
import { ModalContext } from '../../context/ModalContext';
import InfiniteScroll from 'react-infinite-scroll-component';
import { MessagePropsModel } from '../../interfaces/utils';

export function Chat() {
const { account } = useContext(AuthContext);
Expand Down Expand Up @@ -46,6 +47,36 @@ export function Chat() {
}
};

// This function adds a property called showProfile which is of type boolean
// It helps to indicate whether a profile preview has to be shown with message or not
const addShowProfileProperty = (
messageList: MessageModel[],
): MessagePropsModel[] => {
// The message list is reversed and then property is added because the pagination library
// reverses the message list and then it is visible.
// So to keep profile preview updated list is reversed
const list = messageList.reverse().map((m, index) => {
// the sender or current message
const currentMsgSender = m.envelop.message.metadata?.from;
// the sender of message before the current message
const lastMsgSender =
index != 0 &&
messageList[index - 1].envelop.message.metadata?.from;
// if its not a first message and last 2 messages sender is same then no need to show
// profile for this message otherwise show profile
return {
...m,
showProfile:
index != 0 && currentMsgSender === lastMsgSender
? false
: true,
};
});

// after setting the property, the list is returned back in actual order
return list.reverse();
};

useEffect(() => {
if (!selectedContact) {
return;
Expand All @@ -59,7 +90,9 @@ export function Chat() {
if (!selectedContact) {
return [];
}
return getMessages(selectedContact.contactDetails.account.ensName!);
return addShowProfileProperty(
getMessages(selectedContact.contactDetails.account.ensName!),
);
}, [getMessages, selectedContact]);

// handles messages list
Expand Down Expand Up @@ -192,7 +225,10 @@ export function Chat() {
>
{messages.length > 0 &&
messages.map(
(messageModel: MessageModel, index) => (
(
messageModel: MessagePropsModel,
index,
) => (
<div key={index} className="mt-2">
<Message
message={
Expand Down Expand Up @@ -221,6 +257,9 @@ export function Chat() {
indicator={
messageModel.indicator
}
showProfile={
messageModel.showProfile
}
/>
</div>
),
Expand Down
6 changes: 6 additions & 0 deletions packages/messenger-widget/src/components/Message/Message.css
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@
color: var(--text-primary-color);
}

.chat-profile-pic{
height: 1.5rem;
width: 1.5rem;
border-radius: 3px;
}

/* =================== Mobile Responsive CSS =================== */
@media only screen and (max-width: 800px) {
.content-style {
Expand Down
26 changes: 26 additions & 0 deletions packages/messenger-widget/src/components/Message/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,20 @@ import { ReplyMessagePreview } from './ReplyMessagePreview';
import { MessageReactions } from './MessageReactions';
import { Action } from './Action';
import { MessageDetail } from './MessageDetail';
import { ProfilePreview } from './ProfilePreview';
import { AuthContext } from '../../context/AuthContext';
import { ConversationContext } from '../../context/ConversationContext';
import { DM3UserProfileContext } from '../../context/DM3UserProfileContext';

export function Message(props: MessageProps) {
const { messageView } = useContext(UiViewContext);

const { displayName } = useContext(AuthContext);

const { selectedContact } = useContext(ConversationContext);

const { accountProfilePicture } = useContext(DM3UserProfileContext);

return (
<span
id={props.envelop.metadata?.messageHash}
Expand All @@ -27,6 +37,22 @@ export function Message(props: MessageProps) {
: 'ms-2 justify-content-start',
)}
>
{/* Profile preview before every message content to show the actual sender of it */}
{props.showProfile && (
<ProfilePreview
name={
props.ownMessage
? (displayName as string)
: (selectedContact?.name as string)
}
picture={
props.ownMessage
? accountProfilePicture
: (selectedContact?.image as string)
}
/>
)}

<div className="d-flex">
<div className={getMessageStyleClasses(props, messageView)}>
{/* Reply message preview */}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import './Message.css';

export interface ProfilePreviewProps {
picture: string;
name: string;
}

export function ProfilePreview(props: ProfilePreviewProps) {
return (
<div className="d-flex align-items-center">
<img
className="chat-profile-pic mb-1 pointer-cursor"
src={props.picture}
/>
<div className="ms-2 font-size-12 font-weight-800 pointer-cursor">
{props.name.length > 16 ? props.name.slice(0, 16) : props.name}
</div>
</div>
);
}
2 changes: 1 addition & 1 deletion packages/messenger-widget/src/components/Message/bl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const getMessageStyleClasses = (
messageView.messageData?.envelop.message.signature ===
props.envelop.message.signature
? 'msg-editing-active'
: 'ms-3 own-msg-background own-msg-text'
: 'own-msg-background own-msg-text'
: !props.message &&
props.envelop.message.metadata.type ===
MessageActionType.DELETE &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import './RightHeader.css';
import { useContext, useEffect, useState } from 'react';
import { useContext } from 'react';
import humanIcon from '../../assets/images/human.svg';
import menuIcon from '../../assets/images/menu.svg';
import { AuthContext } from '../../context/AuthContext';
import { useMainnetProvider } from '../../hooks/mainnetprovider/useMainnetProvider';
import { getAvatarProfilePic } from '../../utils/ens-utils';
import { RightViewSelected } from '../../utils/enum-type-utils';
import { ConversationContext } from '../../context/ConversationContext';
import { DM3ConfigurationContext } from '../../context/DM3ConfigurationContext';
import { UiViewContext } from '../../context/UiViewContext';
import { DM3UserProfileContext } from '../../context/DM3UserProfileContext';

export function NormalView() {
const { account, displayName } = useContext(AuthContext);
const { displayName } = useContext(AuthContext);

const { setSelectedContactName } = useContext(ConversationContext);

Expand All @@ -20,33 +19,14 @@ export function NormalView() {
const { setSelectedRightView, selectedRightView } =
useContext(UiViewContext);

const mainnetProvider = useMainnetProvider();

// state to store profile pic of signed in user
const [profilePic, setProfilePic] = useState<string>('');

// fetched profile pic of signed in user
const fetchAndSetProfilePic = async () => {
setProfilePic(
await getAvatarProfilePic(
mainnetProvider,
account?.ensName as string,
dm3Configuration.addressEnsSubdomain,
),
);
};
const { accountProfilePicture } = useContext(DM3UserProfileContext);

// method to set profile page and set contact
const updateView = () => {
setSelectedRightView(RightViewSelected.Profile);
setSelectedContactName(undefined);
};

// loads the profile pic on page render
useEffect(() => {
fetchAndSetProfilePic();
}, []);

return (
<div
className={(dm3Configuration.showContacts
Expand Down Expand Up @@ -82,7 +62,11 @@ export function NormalView() {
{displayName}
</span>
<img
src={profilePic ? profilePic : humanIcon}
src={
accountProfilePicture
? accountProfilePicture
: humanIcon
}
alt="menu"
className="me-2 pointer-cursor border-radius-3 default-profile-pic"
onClick={() => updateView()}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@
import { useContext } from 'react';
import { useContext, useEffect } from 'react';
import { MobileView } from './MobileView';
import { NormalView } from './NormalView';
import { MOBILE_SCREEN_WIDTH } from '../../utils/common-utils';
import { DM3ConfigurationContext } from '../../context/DM3ConfigurationContext';
import { DM3UserProfileContext } from '../../context/DM3UserProfileContext';
import { useMainnetProvider } from '../../hooks/mainnetprovider/useMainnetProvider';
import { AuthContext } from '../../context/AuthContext';
import { getAvatarProfilePic } from '../../utils/ens-utils';

export function RightHeader() {
const { screenWidth } = useContext(DM3ConfigurationContext);
const { account } = useContext(AuthContext);

const { screenWidth, dm3Configuration } = useContext(
DM3ConfigurationContext,
);

const { setAccountProfilePicture } = useContext(DM3UserProfileContext);

const mainnetProvider = useMainnetProvider();

// fetched profile pic of signed in user
const fetchAndSetProfilePic = async () => {
setAccountProfilePicture(
await getAvatarProfilePic(
mainnetProvider,
account?.ensName as string,
dm3Configuration.addressEnsSubdomain,
),
);
};

// loads the profile pic on page render
useEffect(() => {
fetchAndSetProfilePic();
}, []);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export type DM3UserProfileContextType = {
isProfileUpdatedForAddrName: boolean;
isProfileUpdatedForDm3Name: boolean;
isProfileUpdatedForEnsName: boolean;
accountProfilePicture: string;
setAccountProfilePicture: (pic: string) => void;
};

export const DM3UserProfileContext =
Expand All @@ -45,6 +47,8 @@ export const DM3UserProfileContext =
isProfileUpdatedForAddrName: true,
isProfileUpdatedForDm3Name: true,
isProfileUpdatedForEnsName: true,
accountProfilePicture: '',
setAccountProfilePicture: (pic: string) => {},
});

export const DM3UserProfileContextProvider = ({
Expand All @@ -70,6 +74,8 @@ export const DM3UserProfileContextProvider = ({
isProfileUpdatedForDm3Name,
isProfileUpdatedForEnsName,
setNodeName,
accountProfilePicture,
setAccountProfilePicture,
} = useDm3UserProfile();

return (
Expand All @@ -92,6 +98,8 @@ export const DM3UserProfileContextProvider = ({
isProfileUpdatedForDm3Name,
isProfileUpdatedForEnsName,
setNodeName,
accountProfilePicture,
setAccountProfilePicture,
}}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
fetchChainIdFromServiceName,
NAME_SERVICES,
} from '../../components/ConfigureProfile/bl';
import profPicture from '../../assets/images/human.svg';

export interface INodeDetails {
dsNames: string[];
Expand Down Expand Up @@ -100,6 +101,9 @@ export const useDm3UserProfile = () => {
ensName: null,
});

const [accountProfilePicture, setAccountProfilePicture] =
useState<string>(profPicture);

// adds DS nodes in local storage of browser
const setDsNodesInLocalStorage = (data: INodeDetails) => {
// fetch data from local storage
Expand Down Expand Up @@ -751,5 +755,7 @@ export const useDm3UserProfile = () => {
isProfileUpdatedForAddrName,
isProfileUpdatedForDm3Name,
isProfileUpdatedForEnsName,
accountProfilePicture,
setAccountProfilePicture,
};
};
1 change: 1 addition & 0 deletions packages/messenger-widget/src/interfaces/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface MessageProps {
isLastMessage?: boolean;
hideFunction?: string;
indicator?: MessageIndicator;
showProfile?: boolean;
}

export interface MessageAction {
Expand Down
11 changes: 11 additions & 0 deletions packages/messenger-widget/src/interfaces/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { Contact } from './context';
import humanIcon from '../assets/images/human.svg';
import { Socket } from 'socket.io-client';
import { DefaultEventsMap } from 'socket.io/dist/typed-events';
import { Envelop } from '@dm3-org/dm3-lib-messaging';
import { MessageIndicator, MessageSource } from '../hooks/messages/useMessage';
import { StorageEnvelopContainer as StorageEnvelopContainerNew } from '@dm3-org/dm3-lib-storage';

export interface Connection {
socket?: Socket<DefaultEventsMap, DefaultEventsMap>;
Expand Down Expand Up @@ -50,6 +53,14 @@ export interface IAttachmentPreview {
isImage: boolean;
}

export type MessagePropsModel = StorageEnvelopContainerNew & {
reactions: Envelop[];
replyToMessageEnvelop?: Envelop;
source: MessageSource;
indicator?: MessageIndicator;
showProfile?: boolean;
};

export const getEmptyContact = (
ensName: string,
message: string | undefined,
Expand Down

0 comments on commit 511dade

Please sign in to comment.