cleanup ReactionData

This commit is contained in:
Timo K
2026-04-15 13:06:47 +02:00
parent 3cb092f541
commit dbf76db590
5 changed files with 31 additions and 18 deletions

View File

@@ -140,13 +140,16 @@ interface LoudspeakerButtonProps extends ComponentPropsWithoutRef<"button"> {
*/ */
isEarpieceTarget: boolean; isEarpieceTarget: boolean;
} }
export const LoudspeakerButton: FC<LoudspeakerButtonProps> = (props) => { export const LoudspeakerButton: FC<LoudspeakerButtonProps> = ({
isEarpieceTarget,
...props
}) => {
const { t } = useTranslation(); const { t } = useTranslation();
const label = props.isEarpieceTarget const label = isEarpieceTarget
? t("settings.devices.handset") ? t("settings.devices.handset")
: t("settings.devices.loudspeaker"); : t("settings.devices.loudspeaker");
// if the target is the earpice, we are currently in loudspeaker mode. // if the target is the earpice, we are currently in loudspeaker mode.
const enabled = props.isEarpieceTarget; const enabled = isEarpieceTarget;
return ( return (
<Tooltip label={label}> <Tooltip label={label}>
<CpdButton <CpdButton

View File

@@ -37,7 +37,13 @@ function TestComponent({
vm={vm} vm={vm}
rtcSession={rtcSession.asMockedSession()} rtcSession={rtcSession.asMockedSession()}
> >
<ReactionToggleButton reactionData={vm} identifier={localIdent} /> <ReactionToggleButton
reactionData={{
reactions$: vm.reactions$,
handsRaised$: vm.handsRaised$,
}}
identifier={localIdent}
/>
</ReactionsSenderProvider> </ReactionsSenderProvider>
</TooltipProvider> </TooltipProvider>
); );

View File

@@ -28,13 +28,14 @@ import classNames from "classnames";
import { useReactionsSender } from "../reactions/useReactionsSender"; import { useReactionsSender } from "../reactions/useReactionsSender";
import styles from "./ReactionToggleButton.module.css"; import styles from "./ReactionToggleButton.module.css";
import { import {
type RaisedHandInfo,
type ReactionOption, type ReactionOption,
ReactionSet, ReactionSet,
ReactionsRowSize, ReactionsRowSize,
} from "../reactions"; } from "../reactions";
import { Modal } from "../Modal"; import { Modal } from "../Modal";
import { type CallViewModel } from "../state/CallViewModel/CallViewModel";
import { useBehavior } from "../useBehavior"; import { useBehavior } from "../useBehavior";
import { type Behavior } from "../state/Behavior";
interface InnerButtonProps extends ComponentPropsWithoutRef<"button"> { interface InnerButtonProps extends ComponentPropsWithoutRef<"button"> {
raised: boolean; raised: boolean;
@@ -163,15 +164,22 @@ export function ReactionPopupMenu({
); );
} }
export interface ReactionData {
handsRaised$: Behavior<Record<string, RaisedHandInfo>>;
/** List of reactions. Keys are: membership.membershipId (currently predefined as: `${membershipEvent.userId}:${membershipEvent.deviceId}`)*/
reactions$: Behavior<Record<string, ReactionOption>>;
}
interface ReactionToggleButtonProps extends ComponentPropsWithoutRef<"button"> { interface ReactionToggleButtonProps extends ComponentPropsWithoutRef<"button"> {
reactionData: ReactionData;
identifier: string; identifier: string;
reactionData: Pick<CallViewModel, "handsRaised$" | "reactions$">;
size?: "sm" | "lg"; size?: "sm" | "lg";
/** List of participants raising their hand */
} }
export function ReactionToggleButton({ export function ReactionToggleButton({
identifier, identifier,
reactionData, reactionData: { handsRaised$, reactions$ },
...props ...props
}: ReactionToggleButtonProps): ReactNode { }: ReactionToggleButtonProps): ReactNode {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -180,8 +188,8 @@ export function ReactionToggleButton({
const [showReactionsMenu, setShowReactionsMenu] = useState(false); const [showReactionsMenu, setShowReactionsMenu] = useState(false);
const [errorText, setErrorText] = useState<string>(); const [errorText, setErrorText] = useState<string>();
const isHandRaised = !!useBehavior(reactionData.handsRaised$)[identifier]; const isHandRaised = !!useBehavior(handsRaised$)[identifier];
const canReact = !useBehavior(reactionData.reactions$)[identifier]; const canReact = !useBehavior(reactions$)[identifier];
useEffect(() => { useEffect(() => {
// Clear whenever the reactions menu state changes. // Clear whenever the reactions menu state changes.

View File

@@ -124,7 +124,6 @@ export const Pip: Story = {
asPip: true, asPip: true,
}, },
}; };
export const NoControlsWithLogo: Story = { export const NoControlsWithLogo: Story = {
...Default, ...Default,
args: { args: {

View File

@@ -20,13 +20,11 @@ import {
ReactionToggleButton, ReactionToggleButton,
LoudspeakerButton, LoudspeakerButton,
SettingsIconButton, SettingsIconButton,
type ReactionData,
} from "../button"; } from "../button";
import styles from "./CallFooter.module.css"; import styles from "./CallFooter.module.css";
import { LayoutToggle } from "../room/LayoutToggle"; import { LayoutToggle } from "../room/LayoutToggle";
import { import { type GridMode } from "../state/CallViewModel/CallViewModel";
type CallViewModel,
type GridMode,
} from "../state/CallViewModel/CallViewModel";
export interface AudioOutputSwitcher { export interface AudioOutputSwitcher {
targetOutput: string; targetOutput: string;
@@ -69,7 +67,7 @@ export interface FooterProps {
hangup?: () => void; hangup?: () => void;
reactionIdentifier?: string; reactionIdentifier?: string;
reactionData?: Pick<CallViewModel, "handsRaised$" | "reactions$">; reactionData?: ReactionData;
hideLogo?: boolean; hideLogo?: boolean;
// debug stuff // debug stuff
@@ -157,11 +155,10 @@ export const CallFooter: FC<FooterProps> = ({
<ReactionToggleButton <ReactionToggleButton
size={buttonSize} size={buttonSize}
reactionData={ reactionData={
reactionData ?? reactionData ?? {
({
handsRaised$: new BehaviorSubject({}), handsRaised$: new BehaviorSubject({}),
reactions$: new BehaviorSubject({}), reactions$: new BehaviorSubject({}),
} as Pick<CallViewModel, "handsRaised$" | "reactions$">) }
} }
key="raise_hand" key="raise_hand"
className={styles.raiseHand} className={styles.raiseHand}