Prefer RoomStateEvent.Update where possible as it fires far less (#7878)
This commit is contained in:
parent
36ae0ea49d
commit
c257bc3f7a
40 changed files with 223 additions and 190 deletions
|
@ -15,11 +15,11 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { useCallback, useState } from "react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { ClientEvent, MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { Room, RoomEvent } from "matrix-js-sdk/src/models/room";
|
||||
|
||||
import { useEventEmitter } from "./useEventEmitter";
|
||||
import { useTypedEventEmitter } from "./useEventEmitter";
|
||||
|
||||
const tryGetContent = <T extends {}>(ev?: MatrixEvent) => ev ? ev.getContent<T>() : undefined;
|
||||
|
||||
|
@ -31,7 +31,7 @@ export const useAccountData = <T extends {}>(cli: MatrixClient, eventType: strin
|
|||
if (event.getType() !== eventType) return;
|
||||
setValue(event.getContent());
|
||||
}, [eventType]);
|
||||
useEventEmitter(cli, "accountData", handler);
|
||||
useTypedEventEmitter(cli, ClientEvent.AccountData, handler);
|
||||
|
||||
return value || {} as T;
|
||||
};
|
||||
|
@ -44,7 +44,7 @@ export const useRoomAccountData = <T extends {}>(room: Room, eventType: string)
|
|||
if (event.getType() !== eventType) return;
|
||||
setValue(event.getContent());
|
||||
}, [eventType]);
|
||||
useEventEmitter(room, "Room.accountData", handler);
|
||||
useTypedEventEmitter(room, RoomEvent.AccountData, handler);
|
||||
|
||||
return value || {} as T;
|
||||
};
|
||||
|
|
|
@ -15,17 +15,29 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { useRef, useEffect, useState, useCallback } from "react";
|
||||
import { ListenerMap, TypedEventEmitter } from "matrix-js-sdk/src/models/typed-event-emitter";
|
||||
|
||||
import type { EventEmitter } from "events";
|
||||
|
||||
type Handler = (...args: any[]) => void;
|
||||
|
||||
export function useTypedEventEmitter<
|
||||
Events extends string,
|
||||
Arguments extends ListenerMap<Events>,
|
||||
>(
|
||||
emitter: TypedEventEmitter<Events, Arguments>,
|
||||
eventName: Events,
|
||||
handler: Handler,
|
||||
): void {
|
||||
useEventEmitter(emitter, eventName, handler);
|
||||
}
|
||||
|
||||
// Hook to wrap event emitter on and removeListener in hook lifecycle
|
||||
export const useEventEmitter = (
|
||||
export function useEventEmitter(
|
||||
emitter: EventEmitter | undefined,
|
||||
eventName: string | symbol,
|
||||
handler: Handler,
|
||||
) => {
|
||||
): void {
|
||||
// Create a ref that stores handler
|
||||
const savedHandler = useRef(handler);
|
||||
|
||||
|
@ -52,15 +64,27 @@ export const useEventEmitter = (
|
|||
},
|
||||
[eventName, emitter], // Re-run if eventName or emitter changes
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
type Mapper<T> = (...args: any[]) => T;
|
||||
|
||||
export const useEventEmitterState = <T>(
|
||||
export function useTypedEventEmitterState<
|
||||
T,
|
||||
Events extends string,
|
||||
Arguments extends ListenerMap<Events>,
|
||||
>(
|
||||
emitter: TypedEventEmitter<Events, Arguments>,
|
||||
eventName: Events,
|
||||
fn: Mapper<T>,
|
||||
): T {
|
||||
return useEventEmitterState<T>(emitter, eventName, fn);
|
||||
}
|
||||
|
||||
export function useEventEmitterState<T>(
|
||||
emitter: EventEmitter | undefined,
|
||||
eventName: string | symbol,
|
||||
fn: Mapper<T>,
|
||||
): T => {
|
||||
): T {
|
||||
const [value, setValue] = useState<T>(fn());
|
||||
const handler = useCallback((...args: any[]) => {
|
||||
setValue(fn(...args));
|
||||
|
@ -69,4 +93,4 @@ export const useEventEmitterState = <T>(
|
|||
useEffect(handler, [emitter]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
useEventEmitter(emitter, eventName, handler);
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,19 +18,21 @@ import { useCallback, useState } from "react";
|
|||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
|
||||
import { useEventEmitter } from "./useEventEmitter";
|
||||
import { useTypedEventEmitter } from "./useEventEmitter";
|
||||
|
||||
// Hook to simplify watching whether a Matrix room is encrypted, returns undefined if room is undefined
|
||||
export function useIsEncrypted(cli: MatrixClient, room?: Room): boolean | undefined {
|
||||
const [isEncrypted, setIsEncrypted] = useState(room ? cli.isRoomEncrypted(room.roomId) : undefined);
|
||||
|
||||
const update = useCallback((event: MatrixEvent) => {
|
||||
if (room && event.getType() === "m.room.encryption") {
|
||||
if (room && event.getType() === EventType.RoomEncryption) {
|
||||
setIsEncrypted(cli.isRoomEncrypted(room.roomId));
|
||||
}
|
||||
}, [cli, room]);
|
||||
useEventEmitter(room ? room.currentState : undefined, "RoomState.events", update);
|
||||
useTypedEventEmitter(room?.currentState, RoomStateEvent.Events, update);
|
||||
|
||||
return isEncrypted;
|
||||
}
|
||||
|
|
|
@ -17,14 +17,15 @@ limitations under the License.
|
|||
import { useState } from "react";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
|
||||
import { throttle } from "lodash";
|
||||
|
||||
import { useEventEmitter } from "./useEventEmitter";
|
||||
import { useTypedEventEmitter } from "./useEventEmitter";
|
||||
|
||||
// Hook to simplify watching Matrix Room joined members
|
||||
export const useRoomMembers = (room: Room, throttleWait = 250) => {
|
||||
const [members, setMembers] = useState<RoomMember[]>(room.getJoinedMembers());
|
||||
useEventEmitter(room.currentState, "RoomState.members", throttle(() => {
|
||||
useTypedEventEmitter(room.currentState, RoomStateEvent.Update, throttle(() => {
|
||||
setMembers(room.getJoinedMembers());
|
||||
}, throttleWait, { leading: true, trailing: true }));
|
||||
return members;
|
||||
|
@ -33,7 +34,7 @@ export const useRoomMembers = (room: Room, throttleWait = 250) => {
|
|||
// Hook to simplify watching Matrix Room joined member count
|
||||
export const useRoomMemberCount = (room: Room, throttleWait = 250) => {
|
||||
const [count, setCount] = useState<number>(room.getJoinedMemberCount());
|
||||
useEventEmitter(room.currentState, "RoomState.members", throttle(() => {
|
||||
useTypedEventEmitter(room.currentState, RoomStateEvent.Update, throttle(() => {
|
||||
setCount(room.getJoinedMemberCount());
|
||||
}, throttleWait, { leading: true, trailing: true }));
|
||||
return count;
|
||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
|||
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { RoomState } from "matrix-js-sdk/src/models/room-state";
|
||||
import { RoomState, RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
|
||||
|
||||
import { useEventEmitter } from "./useEventEmitter";
|
||||
import { useTypedEventEmitter } from "./useEventEmitter";
|
||||
|
||||
type Mapper<T> = (roomState: RoomState) => T;
|
||||
const defaultMapper: Mapper<RoomState> = (roomState: RoomState) => roomState;
|
||||
|
@ -36,7 +36,7 @@ export const useRoomState = <T extends any = RoomState>(
|
|||
setValue(mapper(room.currentState));
|
||||
}, [room, mapper]);
|
||||
|
||||
useEventEmitter(room?.currentState, "RoomState.events", update);
|
||||
useTypedEventEmitter(room?.currentState, RoomStateEvent.Update, update);
|
||||
useEffect(() => {
|
||||
update();
|
||||
return () => {
|
||||
|
|
|
@ -15,11 +15,11 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { User } from "matrix-js-sdk/src/models/user";
|
||||
import { User, UserEvent } from "matrix-js-sdk/src/models/user";
|
||||
import { useContext } from "react";
|
||||
|
||||
import MatrixClientContext from "../contexts/MatrixClientContext";
|
||||
import { useEventEmitterState } from "./useEventEmitter";
|
||||
import { useTypedEventEmitterState } from "./useEventEmitter";
|
||||
import { Member } from "../components/views/right_panel/UserInfo";
|
||||
import { useFeatureEnabled } from "./useSettings";
|
||||
|
||||
|
@ -29,10 +29,11 @@ const getStatusMessage = (cli: MatrixClient, user: Member): string => {
|
|||
};
|
||||
|
||||
// Hook to simplify handling Matrix User status
|
||||
export const useUserStatusMessage = (user?: Member): string => {
|
||||
export const useUserStatusMessage = (member?: Member): string => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const enabled = useFeatureEnabled("feature_custom_status");
|
||||
return useEventEmitterState(enabled && getUser(cli, user), "User.unstable_statusMessage", () => {
|
||||
const user = enabled ? getUser(cli, member) : undefined;
|
||||
return useTypedEventEmitterState(user, UserEvent._UnstableStatusMessage, () => {
|
||||
return getStatusMessage(cli, user);
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue