Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FLXAGNTUI-202: Participant name map #145

Open
wants to merge 1 commit into
base: flex-webchat-ui
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions src/components/MessageBubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ export const MessageBubble = ({
}) => {
const [read, setRead] = useState(false);
const [isMouseDown, setIsMouseDown] = useState(false);
const { conversationsClient, participants, users, fileAttachmentConfig } = useSelector((state: AppState) => ({
conversationsClient: state.chat.conversationsClient,
participants: state.chat.participants,
users: state.chat.users,
fileAttachmentConfig: state.config.fileAttachment
}));
const { conversationsClient, participants, fileAttachmentConfig, participantNames } = useSelector(
(state: AppState) => ({
conversationsClient: state.chat.conversationsClient,
participants: state.chat.participants,
fileAttachmentConfig: state.config.fileAttachment,
participantNames: state.chat.participantNames
})
);
const messageRef = useRef<HTMLDivElement>(null);

const belongsToCurrentUser = message.author === conversationsClient?.user.identity;
Expand All @@ -54,7 +56,7 @@ export const MessageBubble = ({
const getOtherParticipants = participants.filter((p) => p.identity !== conversationsClient?.user.identity);
setRead(
Boolean(getOtherParticipants.length) &&
getOtherParticipants.every((p) => p.lastReadMessageIndex === message.index)
getOtherParticipants.every((p) => p.lastReadMessageIndex === message.index)
);
} else {
setRead(false);
Expand Down Expand Up @@ -109,7 +111,8 @@ export const MessageBubble = ({
}
};

const author = users?.find((u) => u.identity === message.author)?.friendlyName || message.author;
// const author = users?.find((u) => u.identity === message.author)?.friendlyName || message.author;
const name = participantNames ? participantNames[message.participantSid] : "";

return (
<Box
Expand All @@ -131,13 +134,11 @@ export const MessageBubble = ({
)}
<Box {...getInnerContainerStyles(belongsToCurrentUser)}>
<Flex hAlignContent="between" width="100%" vAlignContent="center" marginBottom="space20">
<Text {...authorStyles} as="p" aria-hidden style={{ textOverflow: "ellipsis" }} title={author}>
{author}
<Text {...authorStyles} as="p" aria-hidden style={{ textOverflow: "ellipsis" }} title={name}>
{name}
</Text>
<ScreenReaderOnly as="p">
{belongsToCurrentUser
? "You sent at"
: `${users?.find((u) => u.identity === message.author)?.friendlyName} sent at`}
{belongsToCurrentUser ? "You sent at" : `${name} sent at`}
</ScreenReaderOnly>
<Text {...timeStampStyles} as="p">
{`${doubleDigit(message.dateCreated.getHours())}:${doubleDigit(
Expand Down
1 change: 1 addition & 0 deletions src/sessionDataHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const CUSTOMER_DEFAULT_NAME = "Customer";

type SessionDataStorage = ProcessedTokenResponse & {
loginTimestamp: string | null;
participantNameMap?: Record<string, string>;
};

type InitWebchatAPIPayload = {
Expand Down
1 change: 1 addition & 0 deletions src/store/actions/actionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const ACTION_DETACH_FILES = "ACTION_DETACH_FILES";
export const ACTION_UPDATE_CONVERSATION_STATE = "ACTION_UPDATE_CONVERSATION_STATE";
export const ACTION_UPDATE_SESSION_DATA = "ACTION_UPDATE_SESSION_DATA";
export const ACTION_UPDATE_PRE_ENGAGEMENT_DATA = "ACTION_UPDATE_PRE_ENGAGEMENT_DATA";
export const ACTION_UPDATE_PARTICIPANT_NAME = "ACTION_UPDATE_PARTICIPANT_NAME";

// Notification reducer actions
export const ACTION_ADD_NOTIFICATION = "ACTION_ADD_NOTIFICATION";
Expand Down
12 changes: 11 additions & 1 deletion src/store/actions/initActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { addNotification, changeEngagementPhase } from "./genericActions";
import { MESSAGES_LOAD_COUNT } from "../../constants";
import { parseRegionForConversations } from "../../utils/regionUtil";
import { sessionDataHandler } from "../../sessionDataHandler";
import { createParticipantNameMap } from "../../utils/participantNameMap";

export function initConfig(config: ConfigState) {
return {
Expand All @@ -33,6 +34,7 @@ export function initSession({ token, conversationSid }: InitSessionPayload) {
let participants;
let users;
let messages;
let participantNameMap;

try {
conversationsClient = await Client.create(token, {
Expand All @@ -49,6 +51,13 @@ export function initSession({ token, conversationSid }: InitSessionPayload) {
participants = await conversation.getParticipants();
users = await Promise.all(participants.map(async (p) => p.getUser()));
messages = (await conversation.getMessages(MESSAGES_LOAD_COUNT)).items;

/*
* TODO: If we have an existing participantNameMap for this conversationSid,
* in localStorage, use it and update it with the new participants.
*/
participantNameMap = createParticipantNameMap(participants, users);

} catch (e) {
logger.error("Something went wrong when initializing session", e);
throw e;
Expand All @@ -65,7 +74,8 @@ export function initSession({ token, conversationSid }: InitSessionPayload) {
participants,
messages,
conversationState: conversation.state?.current,
currentPhase: EngagementPhase.MessagingCanvas
currentPhase: EngagementPhase.MessagingCanvas,
participantNames: participantNameMap
}
});

Expand Down
15 changes: 14 additions & 1 deletion src/store/actions/listeners/participantsListener.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { Conversation, Participant } from "@twilio/conversations";
import { Dispatch } from "redux";

import { ACTION_ADD_PARTICIPANT, ACTION_REMOVE_PARTICIPANT, ACTION_UPDATE_PARTICIPANT } from "../actionTypes";
import {
ACTION_ADD_PARTICIPANT,
ACTION_REMOVE_PARTICIPANT,
ACTION_UPDATE_PARTICIPANT,
ACTION_UPDATE_PARTICIPANT_NAME
} from "../actionTypes";

export const initParticipantsListener = (conversation: Conversation, dispatch: Dispatch) => {
conversation.addListener("participantJoined", async (participant: Participant) => {
Expand All @@ -10,6 +15,14 @@ export const initParticipantsListener = (conversation: Conversation, dispatch: D
type: ACTION_ADD_PARTICIPANT,
payload: { participant, user }
});

// set the name to empty string if we do not have a user
const name = user ? user.friendlyName : "";

dispatch({
type: ACTION_UPDATE_PARTICIPANT_NAME,
payload: { participantSid: participant.sid, name }
});
});

conversation.addListener("participantLeft", (participant: Participant) => {
Expand Down
15 changes: 13 additions & 2 deletions src/store/chat.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
ACTION_START_SESSION,
ACTION_UPDATE_CONVERSATION_STATE,
ACTION_UPDATE_MESSAGE,
ACTION_UPDATE_PARTICIPANT
ACTION_UPDATE_PARTICIPANT,
ACTION_UPDATE_PARTICIPANT_NAME
} from "./actions/actionTypes";

const initialState: ChatState = {};
Expand All @@ -40,7 +41,8 @@ export const ChatReducer: Reducer = (state: ChatState = initialState, action: An
conversationState: action.payload.conversationState,
users: action.payload.users,
participants: action.payload.participants,
messages: action.payload.messages
messages: action.payload.messages,
participantNames: action.payload.participantNames
};
}
case ACTION_ADD_MULTIPLE_MESSAGES: {
Expand Down Expand Up @@ -124,6 +126,15 @@ export const ChatReducer: Reducer = (state: ChatState = initialState, action: An
conversationState: action.payload.conversationState
};
}
case ACTION_UPDATE_PARTICIPANT_NAME: {
return {
...state,
participantNames: {
...state.participantNames,
[action.payload.participantSid]: action.payload.name
}
};
}

default:
return state;
Expand Down
1 change: 1 addition & 0 deletions src/store/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type ChatState = {
messages?: Message[];
attachedFiles?: File[];
conversationState?: string;
participantNames?: { [key: string]: string };
};

export type PreEngagementData = { name: string; email: string; query: string };
Expand Down
13 changes: 13 additions & 0 deletions src/utils/participantNameMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* eslint-disable import/no-unused-modules */
import { Participant, User } from "@twilio/conversations";

// return a map of participant sid to participant name
export const createParticipantNameMap = (participants: Participant[], users: User[]) => {
return participants.reduce((acc: { [key: string]: string }, p) => {
const user = users.find((u) => u.identity === p.identity);
if (user) {
acc[p.sid] = user.friendlyName;
}
return acc;
}, {});
};