mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-09 16:50:28 +03:00
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:
parent
00d5553bcb
commit
35f0e400ad
14 changed files with 940 additions and 192 deletions
56
src/app/hooks/useRoomEvent.ts
Normal file
56
src/app/hooks/useRoomEvent.ts
Normal 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;
|
||||
};
|
||||
15
src/app/hooks/useRoomPinnedEvents.ts
Normal file
15
src/app/hooks/useRoomPinnedEvents.ts
Normal 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;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue