Files
upstream-mirror 30810eecd7
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 2s
snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:21:02 +05:00

128 lines
4.1 KiB
TypeScript

import type { IRoom } from '@rocket.chat/core-typings';
import { useSearchParameter } from '@rocket.chat/ui-contexts';
import type { ReactNode, ContextType } from 'react';
import { useMemo, memo, useEffect } from 'react';
import ComposerPopupProvider from './ComposerPopupProvider';
import RoomToolboxProvider from './RoomToolboxProvider';
import UserCardProvider from './UserCardProvider';
import { useRedirectOnSettingsChanged } from './hooks/useRedirectOnSettingsChanged';
import { useUsersNameChanged } from './hooks/useUsersNameChanged';
import { omit } from '../../../../lib/utils/omit';
import { useFireGlobalEvent } from '../../../hooks/useFireGlobalEvent';
import { useRoomRolesQuery } from '../../../hooks/useRoomRolesQuery';
import { RoomHistoryManager, useRoomHistoryState } from '../../../lib/RoomHistoryManager';
import { RoomManager } from '../../../lib/RoomManager';
import { UserAction } from '../../../lib/UserAction';
import { roomCoordinator } from '../../../lib/rooms/roomCoordinator';
import ImageGalleryProvider from '../../../providers/ImageGalleryProvider';
import { Rooms, Subscriptions } from '../../../stores';
import RoomNotFound from '../RoomNotFound';
import RoomSkeleton from '../RoomSkeleton';
import type { IRoomWithFederationOriginalName } from '../contexts/RoomContext';
import { RoomContext } from '../contexts/RoomContext';
export type RoomProviderProps = {
children: ReactNode;
rid: IRoom['_id'];
};
const RoomProvider = ({ rid, children }: RoomProviderProps) => {
const room = Rooms.use((state) => state.get(rid));
const messageJumpParam = useSearchParameter('msg');
const subscritionFromLocal = Subscriptions.use((state) => state.find((record) => record.rid === rid));
useRedirectOnSettingsChanged(subscritionFromLocal);
useUsersNameChanged();
const pseudoRoom: IRoomWithFederationOriginalName | null = useMemo(() => {
if (!room) {
return null;
}
return {
...subscritionFromLocal,
...room,
name: roomCoordinator.getRoomName(room.t, room),
federationOriginalName: room.name,
};
}, [room, subscritionFromLocal]);
const hasMorePreviousMessages = useRoomHistoryState(rid, (state) => state.hasMore);
const hasMoreNextMessages = useRoomHistoryState(rid, (state) => state.hasMoreNext);
const isLoadingMoreMessages = useRoomHistoryState(rid, (state) => state.isLoading);
const context = useMemo((): ContextType<typeof RoomContext> => {
if (!pseudoRoom) {
return null;
}
return {
rid,
room: pseudoRoom,
subscription: subscritionFromLocal ?? undefined,
hasMorePreviousMessages,
hasMoreNextMessages,
isLoadingMoreMessages,
};
}, [hasMoreNextMessages, hasMorePreviousMessages, isLoadingMoreMessages, pseudoRoom, rid, subscritionFromLocal]);
const { mutate: fireRoomOpenedEvent } = useFireGlobalEvent('room-opened', rid);
useEffect(() => {
if (room) {
fireRoomOpenedEvent(omit(room, 'usernames'));
}
}, [rid, room, fireRoomOpenedEvent]);
useEffect(() => {
RoomManager.open(rid);
return (): void => {
RoomManager.back(rid);
};
}, [rid]);
// Prefetch first batch of history in parallel with room metadata fetches, instead of waiting
// for RoomBody's scroll/resize observer in useGetMore to fire.
useEffect(() => {
if (!room || messageJumpParam || RoomHistoryManager.isLoaded(rid) || RoomHistoryManager.isLoading(rid)) {
return;
}
void RoomHistoryManager.getMore(rid);
}, [rid, room, messageJumpParam]);
// Prefetch room roles alongside history so message rendering doesn't trigger a late fetch.
useRoomRolesQuery(rid, { enabled: !!room });
const subscribed = !!subscritionFromLocal;
useEffect(() => {
if (!subscribed) {
return;
}
return UserAction.addStream(rid);
}, [rid, subscribed]);
if (!pseudoRoom) {
return !room && !subscritionFromLocal ? <RoomNotFound /> : <RoomSkeleton />;
}
return (
<RoomContext.Provider value={context}>
<RoomToolboxProvider>
<ImageGalleryProvider>
<UserCardProvider>
<ComposerPopupProvider room={pseudoRoom}>{children}</ComposerPopupProvider>
</UserCardProvider>
</ImageGalleryProvider>
</RoomToolboxProvider>
</RoomContext.Provider>
);
};
export default memo(RoomProvider);