Implement lower hand suggestion in group calls

This commit is contained in:
trevor-signal 2024-12-20 13:35:11 -05:00 committed by GitHub
parent 4312d03db0
commit f2d4f669fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 206 additions and 3 deletions

View file

@ -181,6 +181,7 @@ const getActiveCallForCallLink = (
pendingParticipants: overrideProps.pendingParticipants ?? [],
raisedHands: new Set<number>(),
remoteAudioLevels: new Map<number, number>(),
suggestLowerHand: false,
};
};
@ -232,6 +233,7 @@ export function OngoingGroupCall(): JSX.Element {
raisedHands: new Set<number>(),
remoteParticipants: [],
remoteAudioLevels: new Map<number, number>(),
suggestLowerHand: false,
},
})}
/>

View file

@ -74,6 +74,7 @@ type GroupCallOverrideProps = OverridePropsBase & {
raisedHands?: Set<number>;
remoteParticipants?: Array<GroupCallRemoteParticipantType>;
remoteAudioLevel?: number;
suggestLowerHand?: boolean;
};
const createActiveDirectCallProp = (
@ -153,6 +154,7 @@ const createActiveGroupCallProp = (overrideProps: GroupCallOverrideProps) => ({
])
),
reactions: overrideProps.reactions || [],
suggestLowerHand: overrideProps.suggestLowerHand ?? false,
});
const createActiveCallProp = (
@ -799,6 +801,37 @@ export function GroupCallHandRaising(): JSX.Element {
return <CallScreen {...props} activeCall={activeCall} />;
}
export function GroupCallSuggestLowerHand(): JSX.Element {
const remoteParticipants = allRemoteParticipants.slice(0, 10);
const [props, setProps] = React.useState(
createProps({
callMode: CallMode.Group,
remoteParticipants,
raisedHands: new Set([LOCAL_DEMUX_ID]),
viewMode: CallViewMode.Sidebar,
suggestLowerHand: false,
})
);
React.useEffect(() => {
setTimeout(
() =>
setProps(
createProps({
callMode: CallMode.Group,
remoteParticipants,
viewMode: CallViewMode.Sidebar,
suggestLowerHand: true,
})
),
200
);
}, [remoteParticipants]);
return <CallScreen {...props} />;
}
// Every [frequency] ms, all hands are lowered and [random min to max] random hands
// are raised
function useHandRaiser(

View file

@ -855,6 +855,13 @@ export function CallScreen({
outgoingRing={undefined}
raisedHands={raisedHands}
renderRaisedHandsToast={renderRaisedHandsToast}
handleLowerHand={() => toggleRaiseHand(false)}
suggestLowerHand={
isGroupOrAdhocActiveCall(activeCall)
? activeCall.suggestLowerHand
: false
}
isHandRaised={localHandRaised}
i18n={i18n}
/>
{isCallLinkAdmin ? (

View file

@ -144,6 +144,7 @@ export function GroupCall(args: PropsType): JSX.Element {
raisedHands: new Set<number>(),
remoteParticipants: [],
remoteAudioLevels: new Map<number, number>(),
suggestLowerHand: false,
}}
/>
);

View file

@ -11,6 +11,7 @@ import { usePrevious } from '../hooks/usePrevious';
import { difference as setDifference } from '../util/setUtil';
import { isMoreRecentThan } from '../util/timestamp';
import { isGroupOrAdhocActiveCall } from '../util/isGroupOrAdhocCall';
import { SECOND } from '../util/durations';
type PropsType = {
activeCall: ActiveCallType;
@ -251,6 +252,75 @@ function useRaisedHandsToast({
]);
}
function useLowerHandSuggestionToast({
suggestLowerHand,
handleLowerHand,
i18n,
isHandRaised,
}: {
suggestLowerHand: boolean | undefined;
i18n: LocalizerType;
handleLowerHand: (() => void) | undefined;
isHandRaised: boolean | undefined;
}): void {
const previousSuggestLowerHand = usePrevious(
suggestLowerHand,
suggestLowerHand
);
const { showToast, hideToast } = useCallingToasts();
const SUGGEST_LOWER_HAND_TOAST_KEY = 'SUGGEST_LOWER_HAND_TOAST_KEY';
useEffect(() => {
if (!handleLowerHand) {
return;
}
if (
previousSuggestLowerHand !== undefined &&
suggestLowerHand !== previousSuggestLowerHand
) {
if (suggestLowerHand && isHandRaised) {
showToast({
key: SUGGEST_LOWER_HAND_TOAST_KEY,
content: (
<div className="CallingRaisedHandsToast__Content">
<span className="CallingRaisedHandsToast__HandIcon" />
{i18n('icu:CallControls__LowerHandSuggestionToast')}
<button
className="CallingRaisedHandsToasts__Link"
type="button"
onClick={() => {
handleLowerHand();
hideToast(SUGGEST_LOWER_HAND_TOAST_KEY);
}}
>
{i18n('icu:CallControls__LowerHandSuggestionToast--button')}
</button>
</div>
),
dismissable: false,
autoClose: true,
lifetime: 10 * SECOND,
});
}
}
}, [
suggestLowerHand,
handleLowerHand,
previousSuggestLowerHand,
hideToast,
showToast,
SUGGEST_LOWER_HAND_TOAST_KEY,
isHandRaised,
i18n,
]);
useEffect(() => {
if (!isHandRaised) {
hideToast(SUGGEST_LOWER_HAND_TOAST_KEY);
}
}, [isHandRaised, hideToast]);
}
type CallingButtonToastsType = {
hasLocalAudio: boolean;
outgoingRing: boolean | undefined;
@ -258,6 +328,9 @@ type CallingButtonToastsType = {
renderRaisedHandsToast?: (
hands: Array<number>
) => JSX.Element | string | undefined;
suggestLowerHand?: boolean;
isHandRaised?: boolean;
handleLowerHand?: () => void;
i18n: LocalizerType;
};
@ -284,11 +357,20 @@ function CallingButtonToasts({
outgoingRing,
raisedHands,
renderRaisedHandsToast,
suggestLowerHand,
handleLowerHand,
isHandRaised,
i18n,
}: CallingButtonToastsType) {
useMutedToast({ hasLocalAudio, i18n });
useOutgoingRingToast({ outgoingRing, i18n });
useRaisedHandsToast({ raisedHands, renderRaisedHandsToast });
useLowerHandSuggestionToast({
suggestLowerHand,
i18n,
handleLowerHand,
isHandRaised,
});
return null;
}