Pinned Messages (#2081)

* add pinned room events hook

* room pinned message - WIP

* add room event hook

* fetch pinned messages before displaying

* use react-query in room event hook

* disable staleTime and gc to 1 hour in room event hook

* use room event hook in reply component

* render pinned messages

* add option to pin/unpin messages

* remove message base from message placeholders and add variant

* display message placeholder while loading pinned messages

* render pinned event error

* show no pinned message placeholder

* fix message placeholder flickering
This commit is contained in:
Ajay Bura 2024-12-16 21:55:15 +11:00 committed by GitHub
parent 00d5553bcb
commit 35f0e400ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 940 additions and 192 deletions

View file

@ -0,0 +1,56 @@
import { MatrixEvent, Room } from 'matrix-js-sdk';
import { useCallback, useMemo } from 'react';
import to from 'await-to-js';
import { CryptoBackend } from 'matrix-js-sdk/lib/common-crypto/CryptoBackend';
import { useQuery } from '@tanstack/react-query';
import { useMatrixClient } from './useMatrixClient';
const useFetchEvent = (room: Room, eventId: string) => {
const mx = useMatrixClient();
const fetchEventCallback = useCallback(async () => {
const evt = await mx.fetchRoomEvent(room.roomId, eventId);
const mEvent = new MatrixEvent(evt);
if (mEvent.isEncrypted() && mx.getCrypto()) {
await to(mEvent.attemptDecryption(mx.getCrypto() as CryptoBackend));
}
return mEvent;
}, [mx, room.roomId, eventId]);
return fetchEventCallback;
};
/**
*
* @param room
* @param eventId
* @returns `MatrixEvent`, `undefined` means loading, `null` means failure
*/
export const useRoomEvent = (
room: Room,
eventId: string,
getLocally?: () => MatrixEvent | undefined
) => {
const event = useMemo(() => {
if (getLocally) return getLocally();
return room.findEventById(eventId);
}, [room, eventId, getLocally]);
const fetchEvent = useFetchEvent(room, eventId);
const { data, error } = useQuery({
enabled: event === undefined,
queryKey: [room.roomId, eventId],
queryFn: fetchEvent,
staleTime: Infinity,
gcTime: 60 * 60 * 1000, // 1hour
});
if (event) return event;
if (data) return data;
if (error) return null;
return undefined;
};

View file

@ -0,0 +1,15 @@
import { useMemo } from 'react';
import { RoomPinnedEventsEventContent } from 'matrix-js-sdk/lib/types';
import { Room } from 'matrix-js-sdk';
import { StateEvent } from '../../types/matrix/room';
import { useStateEvent } from './useStateEvent';
export const useRoomPinnedEvents = (room: Room): string[] => {
const pinEvent = useStateEvent(room, StateEvent.RoomPinnedEvents);
const events = useMemo(() => {
const content = pinEvent?.getContent<RoomPinnedEventsEventContent>();
return content?.pinned ?? [];
}, [pinEvent]);
return events;
};