Skip to content
Snippets Groups Projects
Unverified Commit d8e883b7 authored by Tasso Evangelista's avatar Tasso Evangelista Committed by GitHub
Browse files

Chore: Introduce `useQuery` as data source for the `Room` component (#26855)

parent cfd738a3
No related branches found
No related tags found
No related merge requests found
Showing
with 351 additions and 319 deletions
import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { callbacks } from '../../../lib/callbacks';
import { UiTextContext } from '../../../definition/IRoomTypeConfig';
import { ChatSubscription, Rooms, Users, Subscriptions } from '../../models/client';
import { ChatSubscription, Rooms, Users } from '../../models/client';
import { getUserPreference } from '../../utils';
import { settings } from '../../settings';
import { roomCoordinator } from '../../../client/lib/rooms/roomCoordinator';
......@@ -117,242 +116,3 @@ Template.roomList.helpers({
return roomCoordinator.getRoomDirectives(instance.data.identifier)?.getUiText(UiTextContext.NO_ROOMS_SUBSCRIBED) || 'No_channels_yet';
},
});
const getLowerCaseNames = (room, nameDefault = '', fnameDefault = '') => {
const name = room.name || nameDefault;
const fname = room.fname || fnameDefault || name;
return {
lowerCaseName: String(!room.prid ? name : fname).toLowerCase(),
lowerCaseFName: String(fname).toLowerCase(),
};
};
const mergeSubRoom = (subscription) => {
const options = {
fields: {
lm: 1,
lastMessage: 1,
uids: 1,
streamingOptions: 1,
usernames: 1,
usersCount: 1,
topic: 1,
encrypted: 1,
// autoTranslate: 1,
// autoTranslateLanguage: 1,
description: 1,
announcement: 1,
broadcast: 1,
archived: 1,
avatarETag: 1,
retention: 1,
teamId: 1,
teamMain: 1,
msgs: 1,
onHold: 1,
metrics: 1,
muted: 1,
servedBy: 1,
ts: 1,
waitingResponse: 1,
v: 1,
transcriptRequest: 1,
tags: 1,
closedAt: 1,
responseBy: 1,
priorityId: 1,
livechatData: 1,
departmentId: 1,
source: 1,
queuedAt: 1,
federated: 1,
},
};
const room = Rooms.findOne({ _id: subscription.rid }, options) || {};
const lastRoomUpdate = room.lm || subscription.ts || subscription._updatedAt;
const {
encrypted,
description,
cl,
topic,
announcement,
broadcast,
archived,
avatarETag,
retention,
lastMessage,
streamingOptions,
teamId,
teamMain,
uids,
usernames,
usersCount,
v,
transcriptRequest,
servedBy,
onHold,
tags,
closedAt,
metrics,
muted,
waitingResponse,
responseBy,
priorityId,
livechatData,
departmentId,
ts,
source,
queuedAt,
federated,
} = room;
subscription.lm = subscription.lr ? new Date(Math.max(subscription.lr, lastRoomUpdate)) : lastRoomUpdate;
return Object.assign(subscription, getLowerCaseNames(subscription), {
encrypted,
description,
cl,
topic,
announcement,
broadcast,
archived,
avatarETag,
retention,
lastMessage,
streamingOptions,
teamId,
teamMain,
uids,
usernames,
usersCount,
v,
transcriptRequest,
servedBy,
onHold,
tags,
closedAt,
metrics,
muted,
waitingResponse,
responseBy,
priorityId,
livechatData,
departmentId,
ts,
source,
queuedAt,
federated,
});
};
const mergeRoomSub = (room) => {
const sub = Subscriptions.findOne({ rid: room._id });
if (!sub) {
return room;
}
const {
encrypted,
description,
cl,
topic,
announcement,
broadcast,
archived,
avatarETag,
retention,
lastMessage,
streamingOptions,
teamId,
teamMain,
uids,
usernames,
usersCount,
v,
transcriptRequest,
servedBy,
onHold,
tags,
closedAt,
metrics,
muted,
waitingResponse,
responseBy,
priorityId,
livechatData,
departmentId,
ts,
source,
queuedAt,
federated,
} = room;
Subscriptions.update(
{
rid: room._id,
},
{
$set: {
encrypted,
description,
cl,
topic,
announcement,
broadcast,
archived,
avatarETag,
retention,
uids,
usernames,
usersCount,
lastMessage,
streamingOptions,
teamId,
teamMain,
v,
transcriptRequest,
servedBy,
onHold,
tags,
closedAt,
metrics,
muted,
waitingResponse,
responseBy,
priorityId,
livechatData,
departmentId,
ts,
source,
queuedAt,
federated,
...getLowerCaseNames(room, sub.name, sub.fname),
},
},
);
Subscriptions.update(
{
rid: room._id,
lm: { $lt: room.lm },
},
{
$set: {
lm: room.lm,
},
},
);
return room;
};
callbacks.add('cachedCollection-received-rooms', mergeRoomSub);
callbacks.add('cachedCollection-sync-rooms', mergeRoomSub);
callbacks.add('cachedCollection-loadFromServer-rooms', mergeRoomSub);
callbacks.add('cachedCollection-received-subscriptions', mergeSubRoom);
callbacks.add('cachedCollection-sync-subscriptions', mergeSubRoom);
callbacks.add('cachedCollection-loadFromServer-subscriptions', mergeSubRoom);
......@@ -10,7 +10,7 @@ import type { TranslationKey } from '@rocket.chat/ui-contexts';
import { Messages, Rooms, Subscriptions } from '../../../models/client';
import { roomCoordinator } from '../../../../client/lib/rooms/roomCoordinator';
import type { ToolboxContextValue } from '../../../../client/views/room/lib/Toolbox/ToolboxContext';
import type { ToolboxContextValue } from '../../../../client/views/room/contexts/ToolboxContext';
const call = (method: string, ...args: any[]): Promise<any> =>
new Promise((resolve, reject) => {
......
import type { ToolboxContextValue } from '../../../../../../client/views/room/lib/Toolbox/ToolboxContext';
import type { ToolboxContextValue } from '../../../../../../client/views/room/contexts/ToolboxContext';
export type CommonRoomTemplateInstance = {
data: {
......
......@@ -185,7 +185,7 @@ function handleOpenUserCardButtonClick(event: JQuery.ClickEvent, template: Commo
target: event.currentTarget,
open: (e: MouseEvent) => {
e.preventDefault();
tabBar.openUserInfo(username);
tabBar.openRoomInfo(username);
},
});
}
......@@ -327,7 +327,7 @@ function handleMentionLinkClick(event: JQuery.ClickEvent, template: CommonRoomTe
target: event.currentTarget,
open: (e: MouseEvent) => {
e.preventDefault();
tabBar.openUserInfo(username);
tabBar.openRoomInfo(username);
},
});
}
......
import { IOmnichannelRoom, IRoom, IRoomWithRetentionPolicy, ISubscription } from '@rocket.chat/core-typings';
export type SubscriptionWithRoom = ISubscription &
Pick<
IRoom,
| 'description'
| 'cl'
| 'topic'
| 'announcement'
| 'avatarETag'
| 'lastMessage'
| 'streamingOptions'
| 'uids'
| 'usernames'
| 'usersCount'
| 'muted'
| 'federated'
| 'lm'
> &
Pick<
IOmnichannelRoom,
| 'transcriptRequest'
| 'servedBy'
| 'tags'
| 'onHold'
| 'closedAt'
| 'metrics'
| 'waitingResponse'
| 'responseBy'
| 'priorityId'
| 'livechatData'
| 'departmentId'
| 'queuedAt'
> & {
source?: IOmnichannelRoom['source'];
} & Pick<Partial<IRoomWithRetentionPolicy>, 'retention'>;
......@@ -44,17 +44,17 @@ export const useStreamUpdatesForMessageList = (messageList: MessageList, uid: IU
return;
}
const unsubscribeFromRoomMessages = subscribeToRoomMessages<RoomMessagesRidEvent>(rid, (message) => {
const unsubscribeFromRoomMessages = subscribeToRoomMessages(rid, (message: RoomMessagesRidEvent) => {
messageList.handle(message);
});
const unsubscribeFromDeleteMessage = subscribeToNotifyRoom<NotifyRoomRidDeleteMessageEvent>(`${rid}/deleteMessage`, ({ _id: mid }) => {
const unsubscribeFromDeleteMessage = subscribeToNotifyRoom(`${rid}/deleteMessage`, ({ _id: mid }: NotifyRoomRidDeleteMessageEvent) => {
messageList.remove(mid);
});
const unsubscribeFromDeleteMessageBulk = subscribeToNotifyRoom<NotifyRoomRidDeleteMessageBulkEvent>(
const unsubscribeFromDeleteMessageBulk = subscribeToNotifyRoom(
`${rid}/deleteMessageBulk`,
(params) => {
(params: NotifyRoomRidDeleteMessageBulkEvent) => {
const matchDeleteCriteria = createDeleteCriteria(params);
messageList.prune(matchDeleteCriteria);
},
......
......@@ -8,7 +8,7 @@ import { AsyncState, useAsyncState } from './useAsyncState';
const log = (name: string): Console['log'] =>
process.env.NODE_ENV !== 'production' || getConfig('debug') === 'true'
? (...args): void => console.log(name, ...args)
? (...args): void => console.warn(name, ...args)
: (): void => undefined;
const deprecationWarning = log('useEndpointData is deprecated, use @tanstack/react-query instead');
......
import { IRole, IRoom, ISubscription, IUser } from '@rocket.chat/core-typings';
import { useQuery, UseQueryOptions, QueryKey, UseQueryResult, useQueryClient, QueryClient } from '@tanstack/react-query';
import { useEffect } from 'react';
import { Roles, RoomRoles, Rooms, Subscriptions, Users } from '../../app/models/client';
// For convenience as we want to minimize references to the old client models
const queryableCollections = {
users: Users as Mongo.Collection<IUser>,
rooms: Rooms as Mongo.Collection<IRoom>,
subscriptions: Subscriptions as Mongo.Collection<ISubscription>,
roles: Roles as Mongo.Collection<IRole>,
roomRoles: RoomRoles as Mongo.Collection<Pick<ISubscription, 'rid' | 'u' | 'roles'>>,
} as const;
const dep = new Tracker.Dependency();
const reactiveSources = new Set<{
reactiveQueryFn: (collections: typeof queryableCollections) => unknown | undefined;
queryClient: QueryClient;
queryKey: QueryKey;
}>();
export const runReactiveFunctions = (): void => {
if (!Tracker.currentComputation) {
throw new Error('runReactiveFunctions must be called inside a Tracker.autorun');
}
dep.depend();
for (const { reactiveQueryFn, queryClient, queryKey } of reactiveSources) {
// This tracker will be invalidated when the query data changes
Tracker.autorun((c) => {
const data = reactiveQueryFn(queryableCollections);
if (!c.firstRun) queryClient.setQueryData(queryKey, data);
});
}
};
// While React Query handles all async stuff, we need to handle the reactive stuff ourselves using effects
export const useReactiveQuery = <TQueryFnData, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(
queryKey: TQueryKey,
reactiveQueryFn: (collections: typeof queryableCollections) => TQueryFnData | undefined,
options?: UseQueryOptions<TQueryFnData, Error, TData, TQueryKey>,
): UseQueryResult<TData, Error> => {
const queryClient = useQueryClient();
useEffect(() => {
const reactiveSource = { reactiveQueryFn, queryClient, queryKey };
reactiveSources.add(reactiveSource);
dep.changed();
return (): void => {
reactiveSources.delete(reactiveSource);
dep.changed();
};
});
return useQuery(
queryKey,
(): Promise<TQueryFnData> => {
const result = Tracker.nonreactive(() => reactiveQueryFn(queryableCollections));
if (result) return Promise.resolve(result);
return new Promise(() => undefined);
},
{ staleTime: Infinity, ...options },
);
};
import { Tracker } from 'meteor/tracker';
import { queueMicrotask } from './utils/queueMicrotask';
interface ISubscriptionFactory<T> {
(...args: any[]): [subscribe: (onStoreChange: () => void) => () => void, getSnapshot: () => T];
}
......@@ -7,22 +9,26 @@ interface ISubscriptionFactory<T> {
export const createReactiveSubscriptionFactory =
<T>(computeCurrentValueWith: (...args: any[]) => T): ISubscriptionFactory<T> =>
(...args: any[]): [subscribe: (onStoreChange: () => void) => () => void, getSnapshot: () => T] => {
const computeCurrentValue = (): T => computeCurrentValueWith(...args);
const callbacks = new Set<() => void>();
let currentValue = computeCurrentValue();
let currentValue = computeCurrentValueWith(...args);
const computation = Tracker.autorun(() => {
currentValue = computeCurrentValue();
const reactiveFn = (): void => {
currentValue = computeCurrentValueWith(...args);
callbacks.forEach((callback) => {
Tracker.afterFlush(callback);
queueMicrotask(callback);
});
});
};
const { stop } = computation;
let computation: Tracker.Computation | undefined;
computation.stop = (): void => undefined;
queueMicrotask(() => {
if (Tracker.currentComputation) {
throw new Error('Cannot call createReactiveSubscriptionFactory inside a Tracker computation');
}
computation = Tracker.autorun(reactiveFn);
});
return [
(callback): (() => void) => {
......@@ -32,8 +38,7 @@ export const createReactiveSubscriptionFactory =
callbacks.delete(callback);
if (callbacks.size === 0) {
computation.stop = stop;
computation.stop();
queueMicrotask(() => computation?.stop());
}
};
},
......
import { QueryClient } from '@tanstack/react-query';
export const queryClient = new QueryClient();
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
onError: console.warn,
},
mutations: {
onError: console.warn,
},
},
});
......@@ -9,7 +9,6 @@ import { openRoom } from '../../../app/ui-utils/client/lib/openRoom';
import { RoomSettingsEnum, RoomMemberActions, UiTextContext } from '../../../definition/IRoomTypeConfig';
import type { IRoomTypeConfig, IRoomTypeClientDirectives, RoomIdentification } from '../../../definition/IRoomTypeConfig';
import { RoomCoordinator } from '../../../lib/rooms/coordinator';
import { ToolboxContextValue } from '../../views/room/lib/Toolbox/ToolboxContext';
import { roomExit } from './roomExit';
class RoomCoordinatorClient extends RoomCoordinator {
......@@ -27,13 +26,6 @@ class RoomCoordinatorClient extends RoomCoordinator {
isGroupChat(_room: Partial<IRoom>): boolean {
return false;
},
openCustomProfileTab<
T extends {
tabBar: ToolboxContextValue;
},
>(_instance: T, _room: IRoom, _username: string): boolean {
return false;
},
getUiText(_context: ValueOf<typeof UiTextContext>): string {
return '';
},
......
import type { IOmnichannelRoom, AtLeast, ValueOf } from '@rocket.chat/core-typings';
import type { AtLeast, ValueOf } from '@rocket.chat/core-typings';
import { Session } from 'meteor/session';
import { hasPermission } from '../../../../app/authorization/client';
......@@ -31,24 +31,6 @@ roomCoordinator.add(LivechatRoomType, {
return room.name || room.fname || (room as any).label;
},
openCustomProfileTab(instance, room, username) {
const omniRoom = room as IOmnichannelRoom;
if (!omniRoom?.v || (omniRoom.v as any).username !== username) {
return false;
}
/* @TODO Due to route information only updating on `Tracker.afterFlush`,
we found out that calling the tabBar.openUserInfo() method at this point will cause a route change
to the previous route instead of the current one, preventing livechat rooms from being opened.
As a provisory solution, we're delaying the opening of the contextual bar,
which then ensures that the route info is up to date. Although this solution works,
we need to find a more reliable way of ensuring consistent route changes with up-to-date information.
*/
setTimeout(() => instance.tabBar.openUserInfo(), 0);
return true;
},
getUiText(context) {
switch (context) {
case UiTextContext.HIDE_WARNING:
......
// Ponyfill for queueMicrotask
export const queueMicrotask =
(typeof window !== 'undefined' && window.queueMicrotask) ||
((cb: () => void): void => {
Promise.resolve().then(cb);
});
......@@ -54,15 +54,15 @@ const getStream = (
retransmit?: boolean | undefined;
retransmitToSelf?: boolean | undefined;
},
): (<T>(eventName: string, callback: (data: T) => void) => () => void) => {
): (<TEvent extends unknown[]>(eventName: string, callback: (...event: TEvent) => void) => () => void) => {
const streamer = Meteor.StreamerCentral.instances[streamName]
? Meteor.StreamerCentral.instances[streamName]
: new Meteor.Streamer(streamName, options);
return (eventName, callback): (() => void) => {
streamer.on(eventName, callback);
streamer.on(eventName, callback as (...args: any[]) => void);
return (): void => {
streamer.removeListener(eventName, callback);
streamer.removeListener(eventName, callback as (...args: any[]) => void);
};
};
};
......
......@@ -8,6 +8,7 @@ import { getUserPreference } from '../../app/utils/client';
import { callbacks } from '../../lib/callbacks';
import { useReactiveValue } from '../hooks/useReactiveValue';
import { createReactiveSubscriptionFactory } from '../lib/createReactiveSubscriptionFactory';
import { call } from '../lib/utils/call';
const getUserId = (): string | null => Meteor.userId();
......@@ -26,7 +27,7 @@ const loginWithPassword = (user: string | object, password: string): Promise<voi
});
const logout = (): Promise<void> =>
new Promise((resolve) => {
new Promise((resolve, reject) => {
const user = getUser();
if (!user) {
......@@ -35,7 +36,7 @@ const logout = (): Promise<void> =>
Meteor.logout(() => {
callbacks.run('afterLogoutCleanUp', user);
Meteor.call('logoutCleanUp', user, resolve);
call('logoutCleanUp', user).then(resolve, reject);
});
});
......
......@@ -20,6 +20,7 @@ import './notifications';
import './oauth';
import './openedRoom';
import './otr';
import './queryCache';
import './readMessage';
import './readReceipt';
import './reloadRoomAfterLogin';
......
import type { IUser } from '@rocket.chat/core-typings';
import { Meteor } from 'meteor/meteor';
import { Messages, RoomRoles, Subscriptions } from '../../../app/models/client';
import { Messages, Subscriptions } from '../../../app/models/client';
import { Notifications } from '../../../app/notifications/client';
type UsersNameChangedEvent = Partial<IUser>;
......@@ -51,19 +51,5 @@ Meteor.startup(() => {
},
},
);
RoomRoles.update(
{
'u._id': _id,
},
{
$set: {
'u.name': name,
},
},
{
multi: true,
},
);
});
});
import { IOmnichannelRoom, IRoom, IRoomWithRetentionPolicy, ISubscription } from '@rocket.chat/core-typings';
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { Tracker } from 'meteor/tracker';
import { Rooms, Subscriptions } from '../../app/models/client';
import { callbacks } from '../../lib/callbacks';
import { SubscriptionWithRoom } from '../definitions/SubscriptionWithRoom';
import { runReactiveFunctions } from '../hooks/useReactiveQuery';
const getLowerCaseNames = (
room: Pick<IRoom, 'name' | 'fname' | 'prid'>,
nameDefault = '',
fnameDefault = '',
): {
lowerCaseName: string;
lowerCaseFName: string;
} => {
const name = room.name || nameDefault;
const fname = room.fname || fnameDefault || name;
return {
lowerCaseName: String(!room.prid ? name : fname).toLowerCase(),
lowerCaseFName: String(fname).toLowerCase(),
};
};
const mergeSubRoom = (subscription: ISubscription): SubscriptionWithRoom => {
const options = {
fields: {
lm: 1,
lastMessage: 1,
uids: 1,
streamingOptions: 1,
usernames: 1,
usersCount: 1,
topic: 1,
encrypted: 1,
description: 1,
announcement: 1,
broadcast: 1,
archived: 1,
avatarETag: 1,
retention: 1,
teamId: 1,
teamMain: 1,
msgs: 1,
onHold: 1,
metrics: 1,
muted: 1,
servedBy: 1,
ts: 1,
waitingResponse: 1,
v: 1,
transcriptRequest: 1,
tags: 1,
closedAt: 1,
responseBy: 1,
priorityId: 1,
livechatData: 1,
departmentId: 1,
source: 1,
queuedAt: 1,
federated: 1,
},
};
const room = (Rooms as Mongo.Collection<IRoom>).findOne({ _id: subscription.rid }, options);
const lastRoomUpdate = room?.lm || subscription.ts || subscription._updatedAt;
return {
...subscription,
...getLowerCaseNames(subscription),
encrypted: room?.encrypted,
description: room?.description,
cl: room?.cl,
topic: room?.topic,
announcement: room?.announcement,
broadcast: room?.broadcast,
archived: room?.archived,
avatarETag: room?.avatarETag,
retention: (room as IRoomWithRetentionPolicy | undefined)?.retention,
lastMessage: room?.lastMessage,
streamingOptions: room?.streamingOptions,
teamId: room?.teamId,
teamMain: room?.teamMain,
uids: room?.uids,
usernames: room?.usernames,
usersCount: room?.usersCount ?? 0,
v: (room as IOmnichannelRoom | undefined)?.v,
transcriptRequest: (room as IOmnichannelRoom | undefined)?.transcriptRequest,
servedBy: (room as IOmnichannelRoom | undefined)?.servedBy,
onHold: (room as IOmnichannelRoom | undefined)?.onHold,
tags: (room as IOmnichannelRoom | undefined)?.tags,
closedAt: (room as IOmnichannelRoom | undefined)?.closedAt,
metrics: (room as IOmnichannelRoom | undefined)?.metrics,
muted: room?.muted,
waitingResponse: (room as IOmnichannelRoom | undefined)?.waitingResponse,
responseBy: (room as IOmnichannelRoom | undefined)?.responseBy,
priorityId: (room as IOmnichannelRoom | undefined)?.priorityId,
livechatData: (room as IOmnichannelRoom | undefined)?.livechatData,
departmentId: (room as IOmnichannelRoom | undefined)?.departmentId,
ts: room?.ts ?? subscription.ts,
source: (room as IOmnichannelRoom | undefined)?.source,
queuedAt: (room as IOmnichannelRoom | undefined)?.queuedAt,
federated: room?.federated,
lm: subscription.lr ? new Date(Math.max(subscription.lr.getTime(), lastRoomUpdate.getTime())) : lastRoomUpdate,
};
};
const mergeRoomSub = (room: IRoom): IRoom => {
const sub = (Subscriptions as Mongo.Collection<ISubscription>).findOne({ rid: room._id });
if (!sub) {
return room;
}
(Subscriptions as Mongo.Collection<ISubscription>).update(
{
rid: room._id,
},
{
$set: {
encrypted: room.encrypted,
description: room.description,
cl: room.cl,
topic: room.topic,
announcement: room.announcement,
broadcast: room.broadcast,
archived: room.archived,
avatarETag: room.avatarETag,
retention: (room as IRoomWithRetentionPolicy | undefined)?.retention,
uids: room.uids,
usernames: room.usernames,
usersCount: room.usersCount,
lastMessage: room.lastMessage,
streamingOptions: room.streamingOptions,
teamId: room.teamId,
teamMain: room.teamMain,
v: (room as IOmnichannelRoom | undefined)?.v,
transcriptRequest: (room as IOmnichannelRoom | undefined)?.transcriptRequest,
servedBy: (room as IOmnichannelRoom | undefined)?.servedBy,
onHold: (room as IOmnichannelRoom | undefined)?.onHold,
tags: (room as IOmnichannelRoom | undefined)?.tags,
closedAt: (room as IOmnichannelRoom | undefined)?.closedAt,
metrics: (room as IOmnichannelRoom | undefined)?.metrics,
muted: room.muted,
waitingResponse: (room as IOmnichannelRoom | undefined)?.waitingResponse,
responseBy: (room as IOmnichannelRoom | undefined)?.responseBy,
priorityId: (room as IOmnichannelRoom | undefined)?.priorityId,
livechatData: (room as IOmnichannelRoom | undefined)?.livechatData,
departmentId: (room as IOmnichannelRoom | undefined)?.departmentId,
ts: room.ts,
source: (room as IOmnichannelRoom | undefined)?.source,
queuedAt: (room as IOmnichannelRoom | undefined)?.queuedAt,
federated: room.federated,
...getLowerCaseNames(room, sub.name, sub.fname),
},
},
);
(Subscriptions as Mongo.Collection<ISubscription>).update(
{
rid: room._id,
lm: { $lt: room.lm },
},
{
$set: {
lm: room.lm,
},
},
);
return room;
};
callbacks.add('cachedCollection-received-rooms', mergeRoomSub);
callbacks.add('cachedCollection-sync-rooms', mergeRoomSub);
callbacks.add('cachedCollection-loadFromServer-rooms', mergeRoomSub);
callbacks.add('cachedCollection-received-subscriptions', mergeSubRoom);
callbacks.add('cachedCollection-sync-subscriptions', mergeSubRoom);
callbacks.add('cachedCollection-loadFromServer-subscriptions', mergeSubRoom);
Meteor.startup(() => {
Tracker.autorun(() => {
runReactiveFunctions();
});
});
......@@ -2,7 +2,7 @@ import type { IRocketChatRecord, IRole, IUser } from '@rocket.chat/core-typings'
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { UserRoles, RoomRoles, ChatMessage } from '../../app/models/client';
import { UserRoles, ChatMessage } from '../../app/models/client';
import { Notifications } from '../../app/notifications/client';
import { dispatchToastMessage } from '../lib/toast';
......@@ -24,9 +24,7 @@ Meteor.startup(() => {
'roles-change',
(role: { type: 'added' | 'removed' | 'changed'; _id: IRole['_id']; u: Partial<IUser>; scope: IRole['scope'] }) => {
if (role.type === 'added') {
if (role.scope) {
RoomRoles.upsert({ 'rid': role.scope, 'u._id': role.u._id }, { $setOnInsert: { u: role.u }, $addToSet: { roles: role._id } });
} else {
if (!role.scope) {
UserRoles.upsert({ _id: role.u._id }, { $addToSet: { roles: role._id }, $set: { username: role.u.username } });
ChatMessage.update({ 'u._id': role.u._id }, { $addToSet: { roles: role._id } }, { multi: true });
}
......@@ -35,9 +33,7 @@ Meteor.startup(() => {
}
if (role.type === 'removed') {
if (role.scope) {
RoomRoles.update({ 'rid': role.scope, 'u._id': role.u._id }, { $pull: { roles: role._id } });
} else {
if (!role.scope) {
UserRoles.update({ _id: role.u._id }, { $pull: { roles: role._id } });
ChatMessage.update({ 'u._id': role.u._id }, { $pull: { roles: role._id } }, { multi: true });
}
......
......@@ -18,14 +18,14 @@ const getStream = (
retransmit?: boolean | undefined;
retransmitToSelf?: boolean | undefined;
} = {},
): (<T>(eventName: string, callback: (data: T) => void) => () => void) => {
): (<TEvent extends unknown[]>(eventName: string, callback: (...event: TEvent) => void) => () => void) => {
logAction('getStream', streamName, options);
return (eventName, callback): (() => void) => {
return (eventName: string, callback: () => void): (() => void) => {
const subId = Math.random().toString(16).slice(2);
logAction('getStream.subscribe', streamName, eventName, subId);
randomDelay().then(() => callback(undefined as any));
randomDelay().then(() => callback());
return (): void => {
logAction('getStream.unsubscribe', streamName, eventName, subId);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment