Skip to content

Commit

Permalink
fix: sidepanel list not sorting by last message inside thread (#34080)
Browse files Browse the repository at this point in the history
  • Loading branch information
juliajforesti authored and MartinSchoeler committed Dec 30, 2024
1 parent 5828995 commit e2db58e
Show file tree
Hide file tree
Showing 11 changed files with 31 additions and 32 deletions.
5 changes: 5 additions & 0 deletions .changeset/quiet-lions-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixes sidepanel list not sorting by last message inside thread
4 changes: 2 additions & 2 deletions apps/meteor/client/sidebarv2/RoomList/RoomListRow.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IRoom, ISubscription } from '@rocket.chat/core-typings';
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts';
import type { TFunction } from 'i18next';
import React, { memo, useMemo } from 'react';

Expand All @@ -17,7 +17,7 @@ type RoomListRowProps = {
sidebarViewMode: 'extended' | 'condensed' | 'medium';
isAnonymous: boolean;
};
item: ISubscription & IRoom;
item: SubscriptionWithRoom;
};

const RoomListRow = ({ data, item }: RoomListRowProps) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { IMessage, IRoom, ISubscription } from '@rocket.chat/core-typings';
import type { IMessage } from '@rocket.chat/core-typings';
import { isDirectMessageRoom, isMultipleDirectMessageRoom, isOmnichannelRoom, isVideoConfMessage } from '@rocket.chat/core-typings';
import { SidebarV2Action, SidebarV2Actions, SidebarV2ItemBadge, SidebarV2ItemIcon } from '@rocket.chat/fuselage';
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts';
import { useLayout } from '@rocket.chat/ui-contexts';
import type { TFunction } from 'i18next';
import type { AllHTMLAttributes, ComponentType, ReactElement, ReactNode } from 'react';
Expand All @@ -16,7 +17,7 @@ import { OmnichannelBadges } from '../badges/OmnichannelBadges';
import type { useAvatarTemplate } from '../hooks/useAvatarTemplate';
import { useUnreadDisplay } from '../hooks/useUnreadDisplay';

export const getMessage = (room: IRoom, lastMessage: IMessage | undefined, t: TFunction): string | undefined => {
export const getMessage = (room: SubscriptionWithRoom, lastMessage: IMessage | undefined, t: TFunction): string | undefined => {
if (!lastMessage) {
return t('No_messages_yet');
}
Expand Down Expand Up @@ -62,7 +63,7 @@ type RoomListRowProps = {
// sidebarViewMode: 'extended';
isAnonymous?: boolean;

room: ISubscription & IRoom;
room: SubscriptionWithRoom;
id?: string;
/* @deprecated */
style?: AllHTMLAttributes<HTMLElement>['style'];
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/client/sidebarv2/header/hooks/useSearchItems.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IRoom, ISubscription } from '@rocket.chat/core-typings';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts';
import { useMethod, useUserSubscriptions } from '@rocket.chat/ui-contexts';
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
import { useMemo } from 'react';
Expand All @@ -16,7 +16,7 @@ const options = {
limit: LIMIT,
} as const;

export const useSearchItems = (filterText: string): UseQueryResult<(ISubscription & IRoom)[] | undefined, Error> => {
export const useSearchItems = (filterText: string): UseQueryResult<SubscriptionWithRoom[] | undefined, Error> => {
const [, mention, name] = useMemo(() => filterText.match(/(@|#)?(.*)/i) || [], [filterText]);
const query = useMemo(() => {
const filterRegex = new RegExp(escapeRegExp(name), 'i');
Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/client/sidebarv2/hooks/useAvatarTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { RoomAvatar } from '@rocket.chat/ui-avatar';
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts';
import { useUserPreference } from '@rocket.chat/ui-contexts';
import type { ComponentType } from 'react';
import React, { useMemo } from 'react';

export const useAvatarTemplate = (
sidebarViewMode?: 'extended' | 'medium' | 'condensed',
sidebarDisplayAvatar?: boolean,
): null | ComponentType<IRoom & { rid: string }> => {
): null | ComponentType<SubscriptionWithRoom & { rid: string }> => {
const sidebarViewModeFromSettings = useUserPreference<'extended' | 'medium' | 'condensed'>('sidebarViewMode');
const sidebarDisplayAvatarFromSettings = useUserPreference('sidebarDisplayAvatar');

Expand All @@ -30,7 +30,7 @@ export const useAvatarTemplate = (
}
})();

const renderRoomAvatar: ComponentType<IRoom & { rid: string }> = (room) => (
const renderRoomAvatar: ComponentType<SubscriptionWithRoom & { rid: string }> = (room) => (
<RoomAvatar size={size} room={{ ...room, _id: room.rid || room._id, type: room.t }} />
);

Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/client/sidebarv2/hooks/useRoomList.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ILivechatInquiryRecord, IRoom, ISubscription } from '@rocket.chat/core-typings';
import type { ILivechatInquiryRecord } from '@rocket.chat/core-typings';
import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import type { SubscriptionWithRoom, TranslationKey } from '@rocket.chat/ui-contexts';
import { useUserPreference, useUserSubscriptions, useSetting } from '@rocket.chat/ui-contexts';
Expand Down Expand Up @@ -28,7 +28,7 @@ const order = [
] as const;

type useRoomListReturnType = {
roomList: Array<ISubscription & IRoom>;
roomList: Array<SubscriptionWithRoom>;
groupsCount: number[];
groupsList: TranslationKey[];
groupedUnreadInfo: Pick<
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/client/sidebarv2/search/Row.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { IRoom, ISubscription } from '@rocket.chat/core-typings';
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React, { memo } from 'react';

import UserItem from './UserItem';
import SidebarItemTemplateWithData from '../RoomList/SidebarItemTemplateWithData';

type RowProps = {
item: ISubscription & IRoom;
item: SubscriptionWithRoom;
data: Record<string, any>;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { IRoom, ISubscription } from '@rocket.chat/core-typings';
import { useUserSubscription } from '@rocket.chat/ui-contexts';
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts';
import React, { memo } from 'react';

import { goToRoomById } from '../../../../lib/utils/goToRoomById';
Expand All @@ -8,20 +7,15 @@ import { useItemData } from '../hooks/useItemData';

type RoomSidepanelItemProps = {
openedRoom?: string;
room: IRoom;
room: SubscriptionWithRoom;
parentRid: string;
viewMode?: 'extended' | 'medium' | 'condensed';
};

const RoomSidepanelItem = ({ room, openedRoom, viewMode }: RoomSidepanelItemProps) => {
const SidepanelItem = useTemplateByViewMode();
const subscription = useUserSubscription(room._id);

const itemData = useItemData({ ...room, ...subscription } as ISubscription & IRoom, { viewMode, openedRoom }); // as any because of divergent and overlaping timestamp types in subs and room (type Date vs type string)

if (!subscription) {
return <SidepanelItem onClick={goToRoomById} is='a' {...itemData} />;
}
const itemData = useItemData(room, { viewMode, openedRoom });

return <SidepanelItem onClick={goToRoomById} {...itemData} />;
};
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/client/views/room/Sidepanel/hooks/useItemData.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IRoom, ISubscription } from '@rocket.chat/core-typings';
import { SidebarV2ItemBadge as SidebarItemBadge, SidebarV2ItemIcon as SidebarItemIcon } from '@rocket.chat/fuselage';
import type { SubscriptionWithRoom } from '@rocket.chat/ui-contexts';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';

Expand All @@ -10,7 +10,7 @@ import { useAvatarTemplate } from '../../../../sidebarv2/hooks/useAvatarTemplate
import { useUnreadDisplay } from '../../../../sidebarv2/hooks/useUnreadDisplay';

export const useItemData = (
room: ISubscription & IRoom,
room: SubscriptionWithRoom,
{ openedRoom, viewMode }: { openedRoom: string | undefined; viewMode?: 'extended' | 'medium' | 'condensed' },
) => {
const { t } = useTranslation();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { IRoom } from '@rocket.chat/core-typings';
import type { ISubscription } from '@rocket.chat/core-typings';
import { useQuery } from '@tanstack/react-query';
import type { Mongo } from 'meteor/mongo';
import { useEffect, useMemo } from 'react';

import { Rooms } from '../../../../../app/models/client';
import { Subscriptions } from '../../../../../app/models/client';
import { useSortQueryOptions } from '../../../../hooks/useSortQueryOptions';

export const useTeamsListChildrenUpdate = (
Expand All @@ -14,7 +14,7 @@ export const useTeamsListChildrenUpdate = (
const options = useSortQueryOptions();

const query = useMemo(() => {
const query: Mongo.Selector<IRoom> = {
const query: Mongo.Selector<ISubscription> = {
$or: [
{
_id: parentRid,
Expand All @@ -38,7 +38,7 @@ export const useTeamsListChildrenUpdate = (

const result = useQuery({
queryKey: ['sidepanel', 'list', parentRid, sidepanelItems, options],
queryFn: () => Rooms.find(query, options).fetch(),
queryFn: () => Subscriptions.find(query, options).fetch(),
enabled: sidepanelItems !== null && teamId !== null,
refetchInterval: 5 * 60 * 1000,
keepPreviousData: true,
Expand All @@ -47,7 +47,7 @@ export const useTeamsListChildrenUpdate = (
const { refetch } = result;

useEffect(() => {
const liveQueryHandle = Rooms.find(query).observe({
const liveQueryHandle = Subscriptions.find(query).observe({
added: () => queueMicrotask(() => refetch({ exact: false })),
changed: () => queueMicrotask(() => refetch({ exact: false })),
removed: () => queueMicrotask(() => refetch({ exact: false })),
Expand Down
3 changes: 1 addition & 2 deletions apps/meteor/tests/e2e/feature-preview.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,7 @@ test.describe.serial('feature preview', () => {
await expect(poHomeChannel.sidepanel.getItemByName(targetChannel)).toBeVisible();
});

// remove .fail after fix
test.fail('should sort by last message even if unread message is inside thread', async ({ page, browser }) => {
test('should sort by last message even if unread message is inside thread', async ({ page, browser }) => {
const user1Page = await browser.newPage({ storageState: Users.user1.state });
const user1Channel = new HomeChannel(user1Page);

Expand Down

0 comments on commit e2db58e

Please sign in to comment.