diff --git a/packages/messenger-widget/README.md b/packages/messenger-widget/README.md
index da3d62201..efc6e3a0c 100644
--- a/packages/messenger-widget/README.md
+++ b/packages/messenger-widget/README.md
@@ -475,14 +475,17 @@ Example :
push: false,
},
profile: {
- dm3: boolean | {
+ dm3: {
cloud: false,
optimism: true,
},
- self: boolean | {
+ self: {
gnosis: true,
ens: false,
}
+ },
+ settings: {
+ messageView: true,
}
}
disableDialogOptions: {
diff --git a/packages/messenger-widget/src/components/Chat/Chat.tsx b/packages/messenger-widget/src/components/Chat/Chat.tsx
index a9552fc7d..6996f77a7 100644
--- a/packages/messenger-widget/src/components/Chat/Chat.tsx
+++ b/packages/messenger-widget/src/components/Chat/Chat.tsx
@@ -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);
@@ -46,6 +47,50 @@ 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
+ // It also adds a property isFirstMsgofDay which indicates its a first message of particular day
+ const formatMessages = (
+ 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
+ ? messageList[index - 1].envelop.message.metadata?.from
+ : '';
+ // the date on which current message was sent
+ const currentMsgDate = new Date(
+ Number(m.envelop.message.metadata?.timestamp),
+ ).getDate();
+ // the date on which last message was sent
+ const lastMsgDate = index
+ ? new Date(
+ Number(
+ messageList[index - 1].envelop.message.metadata
+ ?.timestamp,
+ ),
+ ).getDate()
+ : 0;
+ return {
+ ...m,
+ // 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
+ showProfile: !(index && currentMsgSender === lastMsgSender),
+ // if the index is 0, then its first message of specific date, so set to true
+ // otherwise check 2 dates, if they are same then its not first msg else it is first msg of day
+ isFirstMsgOfDay: !index ? true : lastMsgDate !== currentMsgDate,
+ };
+ });
+
+ // after setting the property, the list is returned back in actual order
+ return list.reverse();
+ };
+
useEffect(() => {
if (!selectedContact) {
return;
@@ -59,7 +104,9 @@ export function Chat() {
if (!selectedContact) {
return [];
}
- return getMessages(selectedContact.contactDetails.account.ensName!);
+ return formatMessages(
+ getMessages(selectedContact.contactDetails.account.ensName!),
+ );
}, [getMessages, selectedContact]);
// handles messages list
@@ -192,7 +239,10 @@ export function Chat() {
>
{messages.length > 0 &&
messages.map(
- (messageModel: MessageModel, index) => (
+ (
+ messageModel: MessagePropsModel,
+ index,
+ ) => (
- {/* Reply message preview */}
-
-
- {/* Attachments preview */}
- {props.envelop.message.attachments &&
- props.envelop.message.attachments.length > 0 &&
- props.envelop.message.metadata.type !==
- MessageActionType.DELETE && (
-
+ {/*
+ 1. Shows the date, month and year
+ 2. Only visible when new message layout is enabled
+ 3. Visible only before the first message of each date
+ */}
+ {msgViewSelected.viewType === MsgViewType.NEW &&
+ props.isFirstMsgOfDay && (
+
+ {formatDate(props.envelop.message.metadata?.timestamp)}
+
+ )}
+
+
+
+ {/* Profile preview before every message content to show the actual sender of it */}
+ {msgViewSelected.viewType === MsgViewType.NEW && (
+
+
+
+ )}
+
+
)}
diff --git a/packages/messenger-widget/src/components/MessageInputBox/MessageInputBox.tsx b/packages/messenger-widget/src/components/MessageInputBox/MessageInputBox.tsx
index 5c737d509..3cf30f8f1 100644
--- a/packages/messenger-widget/src/components/MessageInputBox/MessageInputBox.tsx
+++ b/packages/messenger-widget/src/components/MessageInputBox/MessageInputBox.tsx
@@ -78,7 +78,7 @@ export function MessageInputBox() {
{/* Reply message preview */}
{messageView.actionType === MessageActionType.REPLY && (
diff --git a/packages/messenger-widget/src/components/Preferences/NormalView.tsx b/packages/messenger-widget/src/components/Preferences/NormalView.tsx
index bbba597a4..423aac94a 100644
--- a/packages/messenger-widget/src/components/Preferences/NormalView.tsx
+++ b/packages/messenger-widget/src/components/Preferences/NormalView.tsx
@@ -1,6 +1,6 @@
import './Preferences.css';
import infoIcon from './../../assets/images/preferences-info.svg';
-import { useContext, useEffect, useState } from 'react';
+import { useContext, useEffect } from 'react';
import closeIcon from '../../assets/images/cross.svg';
import { closeConfigurationModal } from '../ConfigureProfile/bl';
import { ModalContext } from '../../context/ModalContext';
diff --git a/packages/messenger-widget/src/components/Preferences/Preferences.css b/packages/messenger-widget/src/components/Preferences/Preferences.css
index 0a6ea1029..708d46e68 100644
--- a/packages/messenger-widget/src/components/Preferences/Preferences.css
+++ b/packages/messenger-widget/src/components/Preferences/Preferences.css
@@ -35,6 +35,7 @@
cursor: pointer;
padding: 0.5rem 1.3rem 0.5rem 1.3rem;
font-size: 1rem;
+ align-items: center;
}
.preferences-aside-content {
diff --git a/packages/messenger-widget/src/components/Preferences/Settings/Settings.css b/packages/messenger-widget/src/components/Preferences/Settings/Settings.css
new file mode 100644
index 000000000..f100e047e
--- /dev/null
+++ b/packages/messenger-widget/src/components/Preferences/Settings/Settings.css
@@ -0,0 +1,27 @@
+.settings-option-container{
+ padding: 2rem 1rem 1rem 1rem;
+}
+
+.settings-option{
+ color: var(--text-primary-color);
+ font-weight: 500;
+ font-size: 14px;
+ line-height: 24px;
+ margin-left: 0.5rem;
+ display: flex;
+ align-items: center;
+}
+
+.settings-msg-view{
+ padding-left: 2rem;
+}
+
+@media only screen and (max-width: 500px) {
+ .msg-view-heading{
+ font-size: 0.9rem;
+ }
+
+ .msg-view-desc{
+ font-size: 12px;
+ }
+}
\ No newline at end of file
diff --git a/packages/messenger-widget/src/components/Preferences/Settings/Settings.tsx b/packages/messenger-widget/src/components/Preferences/Settings/Settings.tsx
new file mode 100644
index 000000000..5ab66b17a
--- /dev/null
+++ b/packages/messenger-widget/src/components/Preferences/Settings/Settings.tsx
@@ -0,0 +1,67 @@
+import './Settings.css';
+import { useContext } from 'react';
+import { Heading } from '../Heading/Heading';
+import { ModalContext } from '../../../context/ModalContext';
+import { SettingsContext } from '../../../context/SettingsContext';
+
+export function Settings() {
+ // heading of the page
+ const heading = 'Settings';
+
+ // description of the page
+ const description = 'Define how you want to enable/disable components';
+
+ const { disabledOptions } = useContext(ModalContext);
+ const { msgViewOptions, msgViewSelected, updateMsgView } =
+ useContext(SettingsContext);
+
+ return (
+
+ {/* heading of the page */}
+
+
+ {/* Show message option selection when option is not disabled */}
+ {!disabledOptions.settings.messageView && (
+ <>
+ {/* title and description of the property */}
+
+
+ Message View
+
+
+ Select a view how the message should look like
+
+
+
+ {/* radio button options to select the message view type */}
+
+
+ {msgViewOptions.map((option, index) => (
+
{
+ updateMsgView(option);
+ }}
+ >
+
+
+
+ ))}
+
+
+ >
+ )}
+
+ );
+}
diff --git a/packages/messenger-widget/src/components/Preferences/bl.tsx b/packages/messenger-widget/src/components/Preferences/bl.tsx
index 9f84bcb8f..a31985850 100644
--- a/packages/messenger-widget/src/components/Preferences/bl.tsx
+++ b/packages/messenger-widget/src/components/Preferences/bl.tsx
@@ -4,12 +4,14 @@ import spamIcon from './../../assets/images/spam.svg';
import notificationIcon from './../../assets/images/notification.svg';
import networkIcon from './../../assets/images/network.svg';
import storageIcon from './../../assets/images/storage.svg';
+import settingsIcon from './../../assets/images/settings.svg';
import { Spam } from './Spam/Spam';
import { Properties } from './Properties/Properties';
import { Notification } from './Notification/Notification';
import { Network } from './Network/Network';
import { Storage } from './Storage/Storage';
import { DM3Profile } from './DM3Profile/DM3Profile';
+import { Settings } from './Settings/Settings';
export enum PREFERENCES_ITEMS {
PROPERTIES = 'PROPERTIES',
@@ -18,6 +20,7 @@ export enum PREFERENCES_ITEMS {
NOTIFICATION = 'NOTIFICATION',
NETWORK = 'NETWORK',
STORAGE = 'STORAGE',
+ SETTINGS = 'SETTINGS',
}
export const preferencesItems = [
@@ -79,4 +82,13 @@ export const preferencesItems = [
ticker: PREFERENCES_ITEMS.STORAGE,
isEnabled: false,
},
+ {
+ icon: (
+
+ ),
+ name: 'Settings',
+ ticker: PREFERENCES_ITEMS.SETTINGS,
+ component: ,
+ isEnabled: true,
+ },
];
diff --git a/packages/messenger-widget/src/components/RightHeader/NormalView.tsx b/packages/messenger-widget/src/components/RightHeader/NormalView.tsx
index b7234d545..c291719b8 100644
--- a/packages/messenger-widget/src/components/RightHeader/NormalView.tsx
+++ b/packages/messenger-widget/src/components/RightHeader/NormalView.tsx
@@ -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);
@@ -20,21 +19,7 @@ export function NormalView() {
const { setSelectedRightView, selectedRightView } =
useContext(UiViewContext);
- const mainnetProvider = useMainnetProvider();
-
- // state to store profile pic of signed in user
- const [profilePic, setProfilePic] = useState('');
-
- // 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 = () => {
@@ -42,11 +27,6 @@ export function NormalView() {
setSelectedContactName(undefined);
};
- // loads the profile pic on page render
- useEffect(() => {
- fetchAndSetProfilePic();
- }, []);
-
return (