From 9d77e8ab9f881809032ecef356c2fcd00c4dd44a Mon Sep 17 00:00:00 2001 From: Shea Duma Date: Sat, 11 Apr 2026 20:43:34 +0300 Subject: [PATCH 1/3] small fix sticking and showing the wrong item in the preview --- .changeset/fix-status-sticking-issue.md | 4 ++++ src/app/features/room-nav/RoomNavItem.tsx | 4 +--- src/app/pages/client/sidebar/DirectDMsList.tsx | 7 +++++-- 3 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 .changeset/fix-status-sticking-issue.md diff --git a/.changeset/fix-status-sticking-issue.md b/.changeset/fix-status-sticking-issue.md new file mode 100644 index 000000000..f9731da7e --- /dev/null +++ b/.changeset/fix-status-sticking-issue.md @@ -0,0 +1,4 @@ +--- +default: patch +--- +Fix status sometimes sticking in member tile diff --git a/src/app/features/room-nav/RoomNavItem.tsx b/src/app/features/room-nav/RoomNavItem.tsx index 15e615720..9ae9766fa 100644 --- a/src/app/features/room-nav/RoomNavItem.tsx +++ b/src/app/features/room-nav/RoomNavItem.tsx @@ -293,10 +293,8 @@ export function RoomNavItem({ const matrixRoomName = useRoomName(room); const roomName = (dmUserId && nicknames[dmUserId]) || matrixRoomName; const presence = useUserPresence(dmUserId ?? ''); - const [topicEvent, setTopicEvent] = useState(getStateEvent(room, StateEvent.RoomTopic)); + const topicEvent = getStateEvent(room, StateEvent.RoomTopic); - // Ensures that the description does not stick to the position the room is in the row - useEffect(() => setTopicEvent(getStateEvent(room, StateEvent.RoomTopic)), [room, setTopicEvent]); const roomDescription = direct ? (customDMCards && (topicEvent?.getContent().topic as string)) || presence?.status : undefined; diff --git a/src/app/pages/client/sidebar/DirectDMsList.tsx b/src/app/pages/client/sidebar/DirectDMsList.tsx index 16e829ce5..fa277695a 100644 --- a/src/app/pages/client/sidebar/DirectDMsList.tsx +++ b/src/app/pages/client/sidebar/DirectDMsList.tsx @@ -15,7 +15,7 @@ import { } from '$components/sidebar'; import { RoomAvatar } from '$components/room-avatar'; import { UserAvatar } from '$components/user-avatar'; -import { getDirectRoomAvatarUrl } from '$utils/room'; +import { getDirectRoomAvatarUrl, getRoomAvatarUrl } from '$utils/room'; import { useMediaAuthentication } from '$hooks/useMediaAuthentication'; import { nameInitials } from '$utils/common'; import { getCanonicalAliasOrRoomId, mxcUrlToHttp } from '$utils/matrix'; @@ -69,7 +69,10 @@ function DMItem({ room, selected }: DMItemProps) { ( From e0c61ebdcc3b09a54a73e23b7bb37dc0ceddea8f Mon Sep 17 00:00:00 2001 From: Shea Duma Date: Sat, 11 Apr 2026 20:51:05 +0300 Subject: [PATCH 2/3] making the md checker happi --- .changeset/fix-status-sticking-issue.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/fix-status-sticking-issue.md b/.changeset/fix-status-sticking-issue.md index f9731da7e..c954c09ca 100644 --- a/.changeset/fix-status-sticking-issue.md +++ b/.changeset/fix-status-sticking-issue.md @@ -1,4 +1,5 @@ --- default: patch --- + Fix status sometimes sticking in member tile From 0b658e671b74a5b793a4c32b30f8336bacffce07 Mon Sep 17 00:00:00 2001 From: Shea Duma Date: Sun, 12 Apr 2026 03:06:57 +0300 Subject: [PATCH 3/3] proper fix for more wide presence issues too! --- src/app/features/room-nav/RoomNavItem.tsx | 21 ++++++--------------- src/app/hooks/useUserPresence.ts | 23 ++++++++++++++--------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/app/features/room-nav/RoomNavItem.tsx b/src/app/features/room-nav/RoomNavItem.tsx index 9ae9766fa..22886c224 100644 --- a/src/app/features/room-nav/RoomNavItem.tsx +++ b/src/app/features/room-nav/RoomNavItem.tsx @@ -26,12 +26,7 @@ import { useNavigate } from 'react-router-dom'; import { NavButton, NavItem, NavItemContent, NavItemOptions } from '$components/nav'; import { UnreadBadge, UnreadBadgeCenter } from '$components/unread-badge'; import { RoomAvatar, RoomIcon } from '$components/room-avatar'; -import { - getDirectRoomAvatarUrl, - getRoomAvatarUrl, - getStateEvent, - roomHaveUnread, -} from '$utils/room'; +import { getDirectRoomAvatarUrl, getRoomAvatarUrl, roomHaveUnread } from '$utils/room'; import { nameInitials } from '$utils/common'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { useRoomUnread } from '$state/hooks/unread'; @@ -61,7 +56,7 @@ import { useRoomCreators } from '$hooks/useRoomCreators'; import { useRoomPermissions } from '$hooks/useRoomPermissions'; import { InviteUserPrompt } from '$components/invite-user-prompt'; import { ScreenSize, useScreenSizeContext } from '$hooks/useScreenSize'; -import { useRoomName } from '$hooks/useRoomMeta'; +import { useRoomName, useRoomTopic } from '$hooks/useRoomMeta'; import { nicknamesAtom } from '$state/nicknames'; import { useRoomNavigate } from '$hooks/useRoomNavigate'; @@ -74,7 +69,6 @@ import { CallControlState } from '$plugins/call/CallControlState'; import { useAutoDiscoveryInfo } from '$hooks/useAutoDiscoveryInfo'; import { livekitSupport } from '$hooks/useLivekitSupport'; import { Presence, useUserPresence } from '$hooks/useUserPresence'; -import { StateEvent } from '$types/matrix/room'; import { AvatarPresence, PresenceBadge } from '$components/presence'; import { RoomNavUser } from './RoomNavUser'; @@ -293,11 +287,8 @@ export function RoomNavItem({ const matrixRoomName = useRoomName(room); const roomName = (dmUserId && nicknames[dmUserId]) || matrixRoomName; const presence = useUserPresence(dmUserId ?? ''); - const topicEvent = getStateEvent(room, StateEvent.RoomTopic); - - const roomDescription = direct - ? (customDMCards && (topicEvent?.getContent().topic as string)) || presence?.status - : undefined; + const getRoomTopic = useRoomTopic(room); + const roomTopic = direct ? ((customDMCards && getRoomTopic) ?? presence?.status) : undefined; const { navigateRoom } = useRoomNavigate(); const navigate = useNavigate(); @@ -447,7 +438,7 @@ export function RoomNavItem({ > {roomName} - {roomDescription && ( + {roomTopic && ( - {roomDescription} + {roomTopic} )} diff --git a/src/app/hooks/useUserPresence.ts b/src/app/hooks/useUserPresence.ts index f1b858422..2c040b989 100644 --- a/src/app/hooks/useUserPresence.ts +++ b/src/app/hooks/useUserPresence.ts @@ -25,22 +25,27 @@ const getUserPresence = (user: User): UserPresence => ({ export const useUserPresence = (userId: string): UserPresence | undefined => { const mx = useMatrixClient(); const user = mx.getUser(userId); - const [presence, setPresence] = useState(() => (user ? getUserPresence(user) : undefined)); useEffect(() => { - const updatePresence: UserEventHandlerMap[UserEvent.Presence] = (event, u) => { - if (u.userId === user?.userId) { + if (!user) { + setPresence(undefined); + return undefined; + } + setPresence(getUserPresence(user)); + const updatePresence: UserEventHandlerMap[UserEvent.Presence] = (e, u) => { + if (u.userId === user.userId) { setPresence(getUserPresence(user)); } }; - user?.on(UserEvent.Presence, updatePresence); - user?.on(UserEvent.CurrentlyActive, updatePresence); - user?.on(UserEvent.LastPresenceTs, updatePresence); + user.on(UserEvent.Presence, updatePresence); + user.on(UserEvent.CurrentlyActive, updatePresence); + user.on(UserEvent.LastPresenceTs, updatePresence); + return () => { - user?.removeListener(UserEvent.Presence, updatePresence); - user?.removeListener(UserEvent.CurrentlyActive, updatePresence); - user?.removeListener(UserEvent.LastPresenceTs, updatePresence); + user.removeListener(UserEvent.Presence, updatePresence); + user.removeListener(UserEvent.CurrentlyActive, updatePresence); + user.removeListener(UserEvent.LastPresenceTs, updatePresence); }; }, [user]);