First PoC for reactions

This commit is contained in:
Half-Shot
2024-11-01 14:11:36 +00:00
parent f54e1e2046
commit 373a12a3b5
10 changed files with 339 additions and 12 deletions

View File

@@ -26,11 +26,18 @@ import { logger } from "matrix-js-sdk/src/logger";
import { useMatrixRTCSessionMemberships } from "./useMatrixRTCSessionMemberships";
import { useClientState } from "./ClientContext";
import {
ECallReactionEventContent,
GenericReaction,
ReactionOption,
ReactionSet,
} from "./reactions";
interface ReactionsContextType {
raisedHands: Record<string, Date>;
supportsReactions: boolean;
myReactionId: string | null;
reactions: Record<string, ReactionOption>;
}
const ReactionsContext = createContext<ReactionsContextType | undefined>(
@@ -80,6 +87,10 @@ export const ReactionsProvider = ({
const room = rtcSession.room;
const myUserId = room.client.getUserId();
const [reactions, setReactions] = useState<Record<string, ReactionOption>>(
{},
);
// Calculate our own reaction event.
const myReactionId = useMemo(
(): string | null =>
@@ -184,7 +195,44 @@ export const ReactionsProvider = ({
return;
}
if (event.getType() === EventType.Reaction) {
if (event.getType() === "io.element.call.reaction") {
// TODO: Validate content.
const content: ECallReactionEventContent = event.getContent();
const membershipEventId = content["m.relates_to"].event_id;
// Check to see if this reaction was made to a membership event (and the
// sender of the reaction matches the membership)
if (
!memberships.some(
(e) => e.eventId === membershipEventId && e.sender === sender,
)
) {
logger.warn(
`Reaction target was not a membership event for ${sender}, ignoring`,
);
return;
}
// One of our custom reactions
const reaction = ReactionSet.find((r) => r.name === content.name) ?? {
...GenericReaction,
emoji: content.emoji,
};
setReactions((reactions) => {
if (reactions[sender]) {
// We've still got a reaction from this user, ignore it to prevent spamming
return reactions;
}
setTimeout(() => {
// Clear the reaction after some time.
setReactions(({ [sender]: _unused, ...remaining }) => remaining);
}, 3000);
return {
...reactions,
[sender]: reaction,
};
});
} else if (event.getType() === EventType.Reaction) {
const content = event.getContent() as ReactionEventContent;
const membershipEventId = content["m.relates_to"].event_id;
@@ -241,6 +289,7 @@ export const ReactionsProvider = ({
raisedHands: resultRaisedHands,
supportsReactions,
myReactionId,
reactions,
}}
>
{children}