mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-29 21:15:19 +00:00
Use fetchRelations to backfill.
This commit is contained in:
@@ -11,8 +11,6 @@ import {
|
|||||||
RelationType,
|
RelationType,
|
||||||
RoomEvent as MatrixRoomEvent,
|
RoomEvent as MatrixRoomEvent,
|
||||||
MatrixEventEvent,
|
MatrixEventEvent,
|
||||||
ClientEvent,
|
|
||||||
SyncState,
|
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
import { ReactionEventContent } from "matrix-js-sdk/src/types";
|
import { ReactionEventContent } from "matrix-js-sdk/src/types";
|
||||||
import {
|
import {
|
||||||
@@ -93,7 +91,6 @@ export const ReactionsProvider = ({
|
|||||||
clientState?.state === "valid" && clientState.supportedFeatures.reactions;
|
clientState?.state === "valid" && clientState.supportedFeatures.reactions;
|
||||||
const room = rtcSession.room;
|
const room = rtcSession.room;
|
||||||
const myUserId = room.client.getUserId();
|
const myUserId = room.client.getUserId();
|
||||||
const [hasBackfilled, setHasBackfilled] = useState(false);
|
|
||||||
|
|
||||||
const [reactions, setReactions] = useState<Record<string, ReactionOption>>(
|
const [reactions, setReactions] = useState<Record<string, ReactionOption>>(
|
||||||
{},
|
{},
|
||||||
@@ -124,19 +121,29 @@ export const ReactionsProvider = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// This effect will check the state whenever the membership of the session changes.
|
// This effect will check the state whenever the membership of the session changes.
|
||||||
// This function is safe to run multiple times.
|
useEffect(() => {
|
||||||
const backfillHandRaised = useCallback(() => {
|
|
||||||
// Fetches the first reaction for a given event.
|
// Fetches the first reaction for a given event.
|
||||||
const getLastReactionEvent = (
|
const getLastReactionEvent = async (
|
||||||
eventId: string,
|
eventId: string,
|
||||||
expectedSender: string,
|
expectedSender: string,
|
||||||
): MatrixEvent | undefined => {
|
): Promise<MatrixEvent | undefined> => {
|
||||||
const relations = room.relations.getChildEventsForEvent(
|
const relations = room.relations.getChildEventsForEvent(
|
||||||
eventId,
|
eventId,
|
||||||
RelationType.Annotation,
|
RelationType.Annotation,
|
||||||
EventType.Reaction,
|
EventType.Reaction,
|
||||||
);
|
);
|
||||||
const allEvents = relations?.getRelations() ?? [];
|
let allEvents = relations?.getRelations() ?? [];
|
||||||
|
// We might not have synced this far.
|
||||||
|
if (allEvents.length === 0) {
|
||||||
|
const res = await room.client.fetchRelations(
|
||||||
|
room.roomId,
|
||||||
|
eventId,
|
||||||
|
RelationType.Annotation,
|
||||||
|
EventType.Reaction,
|
||||||
|
);
|
||||||
|
allEvents = res.chunk.map((e) => new MatrixEvent(e));
|
||||||
|
}
|
||||||
|
|
||||||
return allEvents.find(
|
return allEvents.find(
|
||||||
(reaction) =>
|
(reaction) =>
|
||||||
reaction.event.sender === expectedSender &&
|
reaction.event.sender === expectedSender &&
|
||||||
@@ -166,47 +173,32 @@ export const ReactionsProvider = ({
|
|||||||
// was raised, reset.
|
// was raised, reset.
|
||||||
removeRaisedHand(m.sender);
|
removeRaisedHand(m.sender);
|
||||||
}
|
}
|
||||||
const reaction = getLastReactionEvent(m.eventId, m.sender);
|
getLastReactionEvent(m.eventId, m.sender)
|
||||||
if (reaction) {
|
.then((reaction) => {
|
||||||
const eventId = reaction?.getId();
|
if (reaction) {
|
||||||
if (!eventId) {
|
const eventId = reaction.getId();
|
||||||
continue;
|
if (!eventId) {
|
||||||
}
|
return;
|
||||||
addRaisedHand(m.sender, {
|
}
|
||||||
membershipEventId: m.eventId,
|
addRaisedHand(m.sender!, {
|
||||||
reactionEventId: eventId,
|
membershipEventId: m.eventId!,
|
||||||
time: new Date(reaction.localTimestamp),
|
reactionEventId: eventId,
|
||||||
|
time: new Date(reaction.localTimestamp),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((ex) => {
|
||||||
|
logger.warn(
|
||||||
|
`Failed to fetch reaction for member ${m.sender} (${m.eventId})`,
|
||||||
|
ex,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Ignoring raisedHands here because we don't want to trigger each time the raised
|
// Ignoring raisedHands here because we don't want to trigger each time the raised
|
||||||
// hands set is updated.
|
// hands set is updated.
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [room, memberships, myUserId, addRaisedHand, removeRaisedHand]);
|
}, [room, memberships, myUserId, addRaisedHand, removeRaisedHand]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Run once on startup (and will rerun when membership changes above)
|
|
||||||
backfillHandRaised();
|
|
||||||
|
|
||||||
function onSync(state: SyncState | null): void {
|
|
||||||
if (state === SyncState.Prepared) {
|
|
||||||
logger.debug("Backfilling hand raised after successful sync.");
|
|
||||||
backfillHandRaised();
|
|
||||||
setHasBackfilled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The *first* time we successfully sync, fetch reactions as they may not
|
|
||||||
// be immediately available.
|
|
||||||
if (!hasBackfilled) {
|
|
||||||
room.client.on(ClientEvent.Sync, onSync);
|
|
||||||
}
|
|
||||||
return (): void => {
|
|
||||||
if (!hasBackfilled) {
|
|
||||||
room.client.off(ClientEvent.Sync, onSync);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [backfillHandRaised, room, hasBackfilled]);
|
|
||||||
|
|
||||||
const latestMemberships = useLatest(memberships);
|
const latestMemberships = useLatest(memberships);
|
||||||
const latestRaisedHands = useLatest(raisedHands);
|
const latestRaisedHands = useLatest(raisedHands);
|
||||||
|
|
||||||
@@ -348,8 +340,6 @@ export const ReactionsProvider = ({
|
|||||||
removeRaisedHand,
|
removeRaisedHand,
|
||||||
latestMemberships,
|
latestMemberships,
|
||||||
latestRaisedHands,
|
latestRaisedHands,
|
||||||
backfillHandRaised,
|
|
||||||
hasBackfilled,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const lowerHand = useCallback(async () => {
|
const lowerHand = useCallback(async () => {
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ export class MockRoom extends EventEmitter {
|
|||||||
return Promise.resolve({ event_id: randomUUID() });
|
return Promise.resolve({ event_id: randomUUID() });
|
||||||
},
|
},
|
||||||
decryptEventIfNeeded: async () => {},
|
decryptEventIfNeeded: async () => {},
|
||||||
|
fetchRelations: async () => Promise.resolve({ chunk: [] }),
|
||||||
on() {
|
on() {
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user