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

[FIX] User's Custom Status to be displayed in Direct Chat #20257

Closed
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
15 changes: 15 additions & 0 deletions client/components/UserStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ export const usePresence = (uid, presence) => {
return status;
};

export const usePresenceStatusText = (uid, defaultStatusText = null) => {
const [statusText, setStatusText] = useSafely(useState(defaultStatusText));
useEffect(() => {
const handle = ({ statusText = null }) => {
setStatusText(statusText);
};
Presence.listen(uid, handle);
return () => {
Presence.stop(uid, handle);
};
}, [setStatusText, uid]);

return statusText;
};

export const ReactiveUserStatus = React.memo(({ uid, presence, ...props }) => {
const status = usePresence(uid, presence);
return <UserStatus status={status} {...props} />;
Expand Down
10 changes: 9 additions & 1 deletion client/lib/presence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IUser } from '../../definition/IUser';

const emitter = new Emitter();
const statuses = new Map();
const statusTexts = new Map();

type User = Pick<IUser, '_id' | 'username' | 'name' | 'status' | 'utcOffset' | 'statusText' | 'avatarETag'>;

Expand Down Expand Up @@ -63,10 +64,13 @@ const getPresence = ((): ((uid: User['_id']) => void) => {
}

statuses.delete(uid);
statusTexts.delete(uid);
});

emitter.on('reset', () => {
statuses.clear();
statusTexts.clear();

emitter.once('restart', () => {
emitter.events()
.filter(isUid)
Expand All @@ -82,6 +86,8 @@ type PresenceUpdate = Partial<Pick<User, '_id' | 'username' | 'status' | 'status
const update: Handler<PresenceUpdate> = (update) => {
if (update?._id) {
statuses.set(update._id, update.status);
statusTexts.set(update._id, update.statusText);

uids.delete(update._id);
}
};
Expand All @@ -92,7 +98,7 @@ const listen = (uid: User['_id'], handler: Handler<PresenceUpdate>): void => {
emitter.on('reset', handler);

if (statuses.has(uid)) {
return handler({ status: statuses.get(uid) });
return handler({ status: statuses.get(uid), statusText: statusTexts.get(uid) });
}

getPresence(uid);
Expand All @@ -109,7 +115,9 @@ const stop = (uid: User['_id'], handler: Handler<PresenceUpdate>): void => {

const reset = (): void => {
emitter.emit('reset', {});

statuses.clear();
statusTexts.clear();
};

const restart = (): void => {
Expand Down
25 changes: 23 additions & 2 deletions client/views/room/Header/Header.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useMemo } from 'react';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { ActionButton } from '@rocket.chat/fuselage';
Expand All @@ -14,6 +14,9 @@ import { useLayout } from '../../../contexts/LayoutContext';
import Burger from './Burger';
import { useTranslation } from '../../../contexts/TranslationContext';
import MarkdownText from '../../../components/MarkdownText';
import { useEndpointData } from '../../../hooks/useEndpointData';
import { useUser } from '../../../contexts/UserContext';
import { usePresenceStatusText } from '../../../components/UserStatus';

export default React.memo(({ room }) => {
const { isEmbedded, showTopNavbarEmbeddedLayout } = useLayout();
Expand All @@ -34,6 +37,24 @@ const BackToRoom = React.memo(({ small, prid }) => {

const RoomHeader = ({ room }) => {
const icon = useRoomIcon(room);

const user = useUser();

const otherUser = useMemo(() => {
// check if room is direct message with 2 members
if (room.t === 'd' && room.uids?.length === 2) {
const userId = room.uids.find((uid) => uid !== user._id);
return { userId };
}
return null;
}, [room, user]);

const { value: data } = useEndpointData('users.info', otherUser);

const liveStatusText = usePresenceStatusText(otherUser?.userId, null);

const roomTopic = liveStatusText || data?.user?.statusText || room.topic;

const { isMobile } = useLayout();
const avatar = <RoomAvatar room={room}/>;
return <Header>
Expand All @@ -51,7 +72,7 @@ const RoomHeader = ({ room }) => {
<Translate room={room} />
</Header.Content.Row>
<Header.Content.Row>
<Header.Subtitle>{room.topic && <MarkdownText withRichContent={false} content={room.topic}/>}</Header.Subtitle>
<Header.Subtitle>{roomTopic && <MarkdownText withRichContent={false} content={roomTopic}/>}</Header.Subtitle>
</Header.Content.Row>
</Header.Content>
<Header.ToolBox>
Expand Down