feat: add `readThreads` params to `subscriptions.read` (#5184)
* add readThreads params to subscriptions.read * add tunread verification * fix e2e test * search cat message * fix when grouping by unread * increase timeout --------- Co-authored-by: Reinaldo Neto <reinaldonetof@hotmail.com> Co-authored-by: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com>
This commit is contained in:
parent
780f426031
commit
c31cb9b124
|
@ -3,6 +3,6 @@ export type SubscriptionsEndpoints = {
|
|||
POST: (params: { firstUnreadMessage: { _id: string } } | { roomId: string }) => {};
|
||||
};
|
||||
'subscriptions.read': {
|
||||
POST: (params: { rid: string }) => {};
|
||||
POST: (params: { rid: string; readThreads?: boolean }) => {};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -254,6 +254,8 @@ const debouncedUpdate = (subscription: ISubscription) => {
|
|||
if (batch[key]) {
|
||||
if (/SUB/.test(key)) {
|
||||
const sub = batch[key] as ISubscription;
|
||||
// When calling the api subscriptions.read passing readThreads as true it does not return this prop
|
||||
if (!sub.tunread) sub.tunread = [];
|
||||
const roomQueueId = getRoomQueueId(sub.rid);
|
||||
const room = batch[roomQueueId] as IRoom;
|
||||
delete batch[roomQueueId];
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
import {
|
||||
IAvatarSuggestion,
|
||||
IMessage,
|
||||
INotificationPreferences,
|
||||
IPreviewItem,
|
||||
IProfileParams,
|
||||
IRoom,
|
||||
IRoomNotifications,
|
||||
SubscriptionType,
|
||||
IServerRoom,
|
||||
IUser,
|
||||
IAvatarSuggestion,
|
||||
IProfileParams,
|
||||
RoomType,
|
||||
IServerRoom
|
||||
SubscriptionType
|
||||
} from '../../definitions';
|
||||
import { TParams } from '../../definitions/ILivechatEditView';
|
||||
import { ILivechatTag } from '../../definitions/ILivechatTag';
|
||||
import { ISpotlight } from '../../definitions/ISpotlight';
|
||||
import { TEAM_TYPE } from '../../definitions/ITeam';
|
||||
import { OperationParams, ResultFor } from '../../definitions/rest/helpers';
|
||||
import { SubscriptionsEndpoints } from '../../definitions/rest/v1/subscriptions';
|
||||
import { Encryption } from '../encryption';
|
||||
import { TParams } from '../../definitions/ILivechatEditView';
|
||||
import { store as reduxStore } from '../store/auxStore';
|
||||
import { getDeviceToken } from '../notifications';
|
||||
import { RoomTypes, roomTypeToApiType, unsubscribeRooms } from '../methods';
|
||||
import sdk from './sdk';
|
||||
import { compareServerVersion, getBundleId, isIOS } from '../methods/helpers';
|
||||
import { ILivechatTag } from '../../definitions/ILivechatTag';
|
||||
import { getDeviceToken } from '../notifications';
|
||||
import { store as reduxStore } from '../store/auxStore';
|
||||
import sdk from './sdk';
|
||||
|
||||
export const createChannel = ({
|
||||
name,
|
||||
|
@ -310,11 +312,33 @@ export const setReaction = (emoji: string, messageId: string) =>
|
|||
// RC 0.62.2
|
||||
sdk.post('chat.react', { emoji, messageId });
|
||||
|
||||
export const toggleRead = (read: boolean, roomId: string) => {
|
||||
if (read) {
|
||||
return sdk.post('subscriptions.unread', { roomId });
|
||||
/**
|
||||
* Toggles the read status of a room.
|
||||
*
|
||||
* @param isRead - Whether to mark the room as read or unread.
|
||||
* @param roomId - The ID of the room.
|
||||
* @param includeThreads - Optional flag to include threads when marking as read.
|
||||
* @returns A promise from the sdk post method.
|
||||
*/
|
||||
export const toggleReadStatus = (
|
||||
isRead: boolean,
|
||||
roomId: string,
|
||||
includeThreads?: boolean
|
||||
): Promise<ResultFor<'POST', keyof SubscriptionsEndpoints>> => {
|
||||
let endpoint: keyof SubscriptionsEndpoints;
|
||||
let payload: OperationParams<'POST', keyof SubscriptionsEndpoints> = { roomId };
|
||||
|
||||
if (isRead) {
|
||||
endpoint = 'subscriptions.unread';
|
||||
} else {
|
||||
endpoint = 'subscriptions.read';
|
||||
payload = { rid: roomId };
|
||||
if (includeThreads) {
|
||||
payload.readThreads = includeThreads;
|
||||
}
|
||||
}
|
||||
return sdk.post('subscriptions.read', { rid: roomId });
|
||||
|
||||
return sdk.post(endpoint, payload);
|
||||
};
|
||||
|
||||
export const getRoomCounters = (
|
||||
|
|
|
@ -56,7 +56,8 @@ import {
|
|||
isRead,
|
||||
debounce,
|
||||
isIOS,
|
||||
isTablet
|
||||
isTablet,
|
||||
compareServerVersion
|
||||
} from '../../lib/methods/helpers';
|
||||
import { E2E_BANNER_TYPE, DisplayMode, SortBy, MAX_SIDEBAR_WIDTH, themes } from '../../lib/constants';
|
||||
import { Services } from '../../lib/services';
|
||||
|
@ -103,6 +104,7 @@ interface IRoomsListViewProps {
|
|||
createPublicChannelPermission: [];
|
||||
createPrivateChannelPermission: [];
|
||||
createDiscussionPermission: [];
|
||||
serverVersion: string;
|
||||
}
|
||||
|
||||
interface IRoomsListViewState {
|
||||
|
@ -703,9 +705,11 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
|||
|
||||
toggleRead = async (rid: string, tIsRead: boolean) => {
|
||||
logEvent(tIsRead ? events.RL_UNREAD_CHANNEL : events.RL_READ_CHANNEL);
|
||||
const { serverVersion } = this.props;
|
||||
try {
|
||||
const db = database.active;
|
||||
const result = await Services.toggleRead(tIsRead, rid);
|
||||
const includeThreads = compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '5.4.0');
|
||||
const result = await Services.toggleReadStatus(tIsRead, rid, includeThreads);
|
||||
|
||||
if (result.success) {
|
||||
const subCollection = db.get('subscriptions');
|
||||
|
@ -715,6 +719,9 @@ class RoomsListView extends React.Component<IRoomsListViewProps, IRoomsListViewS
|
|||
await subRecord.update(sub => {
|
||||
sub.alert = tIsRead;
|
||||
sub.unread = 0;
|
||||
if (includeThreads) {
|
||||
sub.tunread = [];
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
log(e);
|
||||
|
@ -1064,7 +1071,8 @@ const mapStateToProps = (state: IApplicationState) => ({
|
|||
createDirectMessagePermission: state.permissions['create-d'],
|
||||
createPublicChannelPermission: state.permissions['create-c'],
|
||||
createPrivateChannelPermission: state.permissions['create-p'],
|
||||
createDiscussionPermission: state.permissions['start-discussion']
|
||||
createDiscussionPermission: state.permissions['start-discussion'],
|
||||
serverVersion: state.server.version
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomsListView))));
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
import { by, device, element, expect, waitFor } from 'detox';
|
||||
|
||||
import { TTextMatcher, login, navigateToLogin, platformTypes, searchRoom, tapBack, tryTapping } from '../../helpers/app';
|
||||
import { TTextMatcher, login, navigateToLogin, platformTypes, searchRoom, sleep, tapBack, tryTapping } from '../../helpers/app';
|
||||
import { ITestUser, createRandomRoom, createRandomUser, initApi } from '../../helpers/data_setup';
|
||||
import random from '../../helpers/random';
|
||||
|
||||
const roomId = '64b846e4760e618aa9f91ab7';
|
||||
|
||||
function getIndex() {
|
||||
if (device.getPlatform() === 'android') {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const sendMessageOnTranslationTestRoom = async (msg: string): Promise<{ user: ITestUser; msgId: string }> => {
|
||||
const user = await createRandomUser();
|
||||
const api = await initApi(user.username, user.password);
|
||||
|
@ -36,22 +43,37 @@ async function navigateToRoom(roomName: string) {
|
|||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function searchMessage(msg: string, textMatcher: TTextMatcher) {
|
||||
await sleep(1000); // wait for proper load the room
|
||||
await element(by.id('room-view-search')).tap();
|
||||
await waitFor(element(by.id('search-messages-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('search-message-view-input')).replaceText(msg);
|
||||
await waitFor(element(by[textMatcher](msg)).atIndex(getIndex()))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await sleep(1000);
|
||||
await element(by[textMatcher](msg)).atIndex(getIndex()).tap();
|
||||
await sleep(10000);
|
||||
}
|
||||
|
||||
export function waitForVisible(id: string) {
|
||||
return waitFor(element(by.id(id)))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
.withTimeout(10000);
|
||||
}
|
||||
|
||||
export function waitForVisibleTextMatcher(msg: string, textMatcher: TTextMatcher) {
|
||||
return waitFor(element(by[textMatcher](msg)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
.withTimeout(10000);
|
||||
}
|
||||
|
||||
export function waitForNotVisible(id: string) {
|
||||
return waitFor(element(by.id(id)))
|
||||
.not.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
.withTimeout(10000);
|
||||
}
|
||||
|
||||
describe('Auto Translate', () => {
|
||||
|
@ -97,6 +119,7 @@ describe('Auto Translate', () => {
|
|||
});
|
||||
|
||||
it('should see old message not translated before enable auto translate', async () => {
|
||||
await searchMessage(oldMessage[languages.default] as string, textMatcher);
|
||||
await waitForVisibleTextMatcher(oldMessage[languages.default] as string, textMatcher);
|
||||
await waitForVisibleTextMatcher(attachmentMessage[languages.default] as string, textMatcher);
|
||||
});
|
||||
|
@ -141,6 +164,7 @@ describe('Auto Translate', () => {
|
|||
});
|
||||
|
||||
it('should see old message translated after enable auto translate', async () => {
|
||||
await searchMessage(oldMessage[languages.default] as string, textMatcher);
|
||||
await waitForVisibleTextMatcher(oldMessage[languages.translated] as string, textMatcher);
|
||||
await waitForVisibleTextMatcher(attachmentMessage[languages.translated] as string, textMatcher);
|
||||
});
|
||||
|
@ -148,6 +172,7 @@ describe('Auto Translate', () => {
|
|||
it('should see new message translated', async () => {
|
||||
const randomMatcher = random();
|
||||
const data = await sendMessageOnTranslationTestRoom(`${newMessage[languages.default]} - ${randomMatcher}`);
|
||||
await searchMessage(`${newMessage[languages.default]} - ${randomMatcher}`, textMatcher); // will scroll the messages list to the last one
|
||||
await waitForVisibleTextMatcher(`${newMessage[languages.translated]} - ${randomMatcher}`, textMatcher);
|
||||
await deleteMessageOnTranslationTestRoom(data);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue