From 410c306a616d8206cd32b10fdd4520d62610760d Mon Sep 17 00:00:00 2001 From: Mathias Jakobsen Date: Mon, 7 Jul 2025 12:11:54 +0100 Subject: [PATCH] Merge pull request #26850 from overleaf/mj-chat-deleted-user [web] Handle deleted users in chat threads GitOrigin-RevId: 6593bf37e4f2339b40069b7cf4198166660852fb --- .../web/frontend/js/features/chat/components/message.tsx | 8 +++++++- .../frontend/js/features/chat/context/chat-context.tsx | 2 +- .../js/features/chat/utils/message-list-appender.js | 2 ++ .../js/features/ide-redesign/components/chat/message.tsx | 6 ++---- .../components/review-panel-entry-user.tsx | 4 +++- .../review-panel-new/components/review-panel-message.tsx | 2 +- .../js/features/review-panel-new/utils/build-name.ts | 8 +++++--- services/web/types/review-panel/review-panel.ts | 2 +- 8 files changed, 22 insertions(+), 12 deletions(-) diff --git a/services/web/frontend/js/features/chat/components/message.tsx b/services/web/frontend/js/features/chat/components/message.tsx index 8a410c0d9d..dd5aeccb24 100644 --- a/services/web/frontend/js/features/chat/components/message.tsx +++ b/services/web/frontend/js/features/chat/components/message.tsx @@ -2,6 +2,7 @@ import { getHueForUserId } from '@/shared/utils/colors' import MessageContent from './message-content' import type { Message as MessageType } from '@/features/chat/context/chat-context' import { User } from '../../../../../types/user' +import { useTranslation } from 'react-i18next' export interface MessageProps { message: MessageType @@ -26,11 +27,16 @@ function getArrowStyle(user?: User) { } function Message({ message, fromSelf }: MessageProps) { + const { t } = useTranslation() return (
{!fromSelf && (
- {message.user.first_name || message.user.email} + + {message.user + ? message.user.first_name || message.user.email + : t('deleted_user')} +
)}
diff --git a/services/web/frontend/js/features/chat/context/chat-context.tsx b/services/web/frontend/js/features/chat/context/chat-context.tsx index 2ba0ff5f5d..b7a8a2c80d 100644 --- a/services/web/frontend/js/features/chat/context/chat-context.tsx +++ b/services/web/frontend/js/features/chat/context/chat-context.tsx @@ -29,7 +29,7 @@ export type Message = { id: string timestamp: number contents: string[] - user: User + user?: User } type State = { diff --git a/services/web/frontend/js/features/chat/utils/message-list-appender.js b/services/web/frontend/js/features/chat/utils/message-list-appender.js index 3362bf6fa0..be7ed0cb37 100644 --- a/services/web/frontend/js/features/chat/utils/message-list-appender.js +++ b/services/web/frontend/js/features/chat/utils/message-list-appender.js @@ -15,6 +15,7 @@ export function appendMessage(messageList, message, uniqueMessageIds) { lastMessage && message && message.user && + lastMessage.user && message.user.id && message.user.id === lastMessage.user.id && message.timestamp - lastMessage.timestamp < TIMESTAMP_GROUP_SIZE @@ -57,6 +58,7 @@ export function prependMessages(messageList, messages, uniqueMessageIds) { const shouldGroup = firstMessage && message && + firstMessage.user && message.user && message.user.id === firstMessage.user.id && firstMessage.timestamp - message.timestamp < TIMESTAMP_GROUP_SIZE diff --git a/services/web/frontend/js/features/ide-redesign/components/chat/message.tsx b/services/web/frontend/js/features/ide-redesign/components/chat/message.tsx index 057ea69266..9a4ffe3a1b 100644 --- a/services/web/frontend/js/features/ide-redesign/components/chat/message.tsx +++ b/services/web/frontend/js/features/ide-redesign/components/chat/message.tsx @@ -27,8 +27,6 @@ function getAvatarStyle(user?: User) { } function Message({ message, fromSelf }: MessageProps) { - const userAvailable = message.user?.id && message.user.email - return (
@@ -36,7 +34,7 @@ function Message({ message, fromSelf }: MessageProps) { {!fromSelf && (
- {userAvailable + {message.user?.id && message.user.email ? message.user.first_name || message.user.email : t('deleted_user')} @@ -49,7 +47,7 @@ function Message({ message, fromSelf }: MessageProps) { {!fromSelf && index === message.contents.length - 1 ? (
- {userAvailable ? ( + {message.user?.id && message.user.email ? ( message.user.first_name?.charAt(0) || message.user.email.charAt(0) ) : ( diff --git a/services/web/frontend/js/features/review-panel-new/components/review-panel-entry-user.tsx b/services/web/frontend/js/features/review-panel-new/components/review-panel-entry-user.tsx index ae53fbc8c8..221e297c4b 100644 --- a/services/web/frontend/js/features/review-panel-new/components/review-panel-entry-user.tsx +++ b/services/web/frontend/js/features/review-panel-new/components/review-panel-entry-user.tsx @@ -3,13 +3,15 @@ import { buildName } from '../utils/build-name' import { ReviewPanelUser } from '../../../../../types/review-panel/review-panel' import { ChangesUser } from '../context/changes-users-context' import { getBackgroundColorForUserId } from '@/shared/utils/colors' +import { useTranslation } from 'react-i18next' const ReviewPanelEntryUser = ({ user, }: { user?: ReviewPanelUser | ChangesUser }) => { - const userName = buildName(user) + const { t } = useTranslation() + const userName = user ? buildName(user) : t('deleted_user') return (
diff --git a/services/web/frontend/js/features/review-panel-new/components/review-panel-message.tsx b/services/web/frontend/js/features/review-panel-new/components/review-panel-message.tsx index d6017208d8..41c8a8d5a2 100644 --- a/services/web/frontend/js/features/review-panel-new/components/review-panel-message.tsx +++ b/services/web/frontend/js/features/review-panel-new/components/review-panel-message.tsx @@ -40,7 +40,7 @@ export const ReviewPanelMessage: FC<{ const user = useUserContext() const permissions = usePermissionsContext() - const isCommentAuthor = user.id === message.user.id + const isCommentAuthor = Boolean(message.user && user.id === message.user.id) const canEdit = isCommentAuthor && permissions.comment const canResolve = permissions.resolveAllComments || diff --git a/services/web/frontend/js/features/review-panel-new/utils/build-name.ts b/services/web/frontend/js/features/review-panel-new/utils/build-name.ts index 9bfb6902c4..bd1fbf1a12 100644 --- a/services/web/frontend/js/features/review-panel-new/utils/build-name.ts +++ b/services/web/frontend/js/features/review-panel-new/utils/build-name.ts @@ -1,15 +1,17 @@ -export const buildName = (user?: { +export const buildName = (user: { first_name?: string last_name?: string email?: string }) => { - const name = [user?.first_name, user?.last_name].filter(Boolean).join(' ') + const name = [user.first_name, user.last_name].filter(Boolean).join(' ') if (name) { return name } - if (user?.email) { + + if (user.email) { return user.email.split('@')[0] } + return 'Unknown' } diff --git a/services/web/types/review-panel/review-panel.ts b/services/web/types/review-panel/review-panel.ts index 200f904430..cba5490ab0 100644 --- a/services/web/types/review-panel/review-panel.ts +++ b/services/web/types/review-panel/review-panel.ts @@ -20,6 +20,6 @@ export interface ReviewPanelCommentThreadMessage { content: string id: CommentId timestamp: Date - user: ReviewPanelUser + user?: ReviewPanelUser user_id: UserId }