Merge pull request #329 from vector-im/dbkr/rageshake_ptt
Enable rageshake on PTT mode
This commit is contained in:
		
				commit
				
					
						d81c52e9bb
					
				
			
		
					 5 changed files with 56 additions and 19 deletions
				
			
		| 
						 | 
					@ -35,6 +35,7 @@ import { useRageshakeRequestModal } from "../settings/submit-rageshake";
 | 
				
			||||||
import { RageshakeRequestModal } from "./RageshakeRequestModal";
 | 
					import { RageshakeRequestModal } from "./RageshakeRequestModal";
 | 
				
			||||||
import { usePreventScroll } from "@react-aria/overlays";
 | 
					import { usePreventScroll } from "@react-aria/overlays";
 | 
				
			||||||
import { useMediaHandler } from "../settings/useMediaHandler";
 | 
					import { useMediaHandler } from "../settings/useMediaHandler";
 | 
				
			||||||
 | 
					import { useModalTriggerState } from "../Modal";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const canScreenshare = "getDisplayMedia" in navigator.mediaDevices;
 | 
					const canScreenshare = "getDisplayMedia" in navigator.mediaDevices;
 | 
				
			||||||
// There is currently a bug in Safari our our code with cloning and sending MediaStreams
 | 
					// There is currently a bug in Safari our our code with cloning and sending MediaStreams
 | 
				
			||||||
| 
						 | 
					@ -65,6 +66,9 @@ export function InCallView({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { audioOutput } = useMediaHandler();
 | 
					  const { audioOutput } = useMediaHandler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { modalState: feedbackModalState, modalProps: feedbackModalProps } =
 | 
				
			||||||
 | 
					    useModalTriggerState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const items = useMemo(() => {
 | 
					  const items = useMemo(() => {
 | 
				
			||||||
    const participants = [];
 | 
					    const participants = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -196,6 +200,9 @@ export function InCallView({
 | 
				
			||||||
          showInspector={showInspector}
 | 
					          showInspector={showInspector}
 | 
				
			||||||
          client={client}
 | 
					          client={client}
 | 
				
			||||||
          groupCall={groupCall}
 | 
					          groupCall={groupCall}
 | 
				
			||||||
 | 
					          showInvite={true}
 | 
				
			||||||
 | 
					          feedbackModalState={feedbackModalState}
 | 
				
			||||||
 | 
					          feedbackModalProps={feedbackModalProps}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <HangupButton onPress={onLeave} />
 | 
					        <HangupButton onPress={onLeave} />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,13 +35,14 @@ export function OverflowMenu({
 | 
				
			||||||
  showInspector,
 | 
					  showInspector,
 | 
				
			||||||
  inCall,
 | 
					  inCall,
 | 
				
			||||||
  groupCall,
 | 
					  groupCall,
 | 
				
			||||||
 | 
					  showInvite,
 | 
				
			||||||
 | 
					  feedbackModalState,
 | 
				
			||||||
 | 
					  feedbackModalProps,
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  const { modalState: inviteModalState, modalProps: inviteModalProps } =
 | 
					  const { modalState: inviteModalState, modalProps: inviteModalProps } =
 | 
				
			||||||
    useModalTriggerState();
 | 
					    useModalTriggerState();
 | 
				
			||||||
  const { modalState: settingsModalState, modalProps: settingsModalProps } =
 | 
					  const { modalState: settingsModalState, modalProps: settingsModalProps } =
 | 
				
			||||||
    useModalTriggerState();
 | 
					    useModalTriggerState();
 | 
				
			||||||
  const { modalState: feedbackModalState, modalProps: feedbackModalProps } =
 | 
					 | 
				
			||||||
    useModalTriggerState();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO: On closing modal, focus should be restored to the trigger button
 | 
					  // TODO: On closing modal, focus should be restored to the trigger button
 | 
				
			||||||
  // https://github.com/adobe/react-spectrum/issues/2444
 | 
					  // https://github.com/adobe/react-spectrum/issues/2444
 | 
				
			||||||
| 
						 | 
					@ -70,10 +71,12 @@ export function OverflowMenu({
 | 
				
			||||||
        </TooltipTrigger>
 | 
					        </TooltipTrigger>
 | 
				
			||||||
        {(props) => (
 | 
					        {(props) => (
 | 
				
			||||||
          <Menu {...props} label="More menu" onAction={onAction}>
 | 
					          <Menu {...props} label="More menu" onAction={onAction}>
 | 
				
			||||||
            <Item key="invite" textValue="Invite people">
 | 
					            {showInvite && (
 | 
				
			||||||
              <AddUserIcon />
 | 
					              <Item key="invite" textValue="Invite people">
 | 
				
			||||||
              <span>Invite people</span>
 | 
					                <AddUserIcon />
 | 
				
			||||||
            </Item>
 | 
					                <span>Invite people</span>
 | 
				
			||||||
 | 
					              </Item>
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
            <Item key="settings" textValue="Settings">
 | 
					            <Item key="settings" textValue="Settings">
 | 
				
			||||||
              <SettingsIcon />
 | 
					              <SettingsIcon />
 | 
				
			||||||
              <span>Settings</span>
 | 
					              <span>Settings</span>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,9 +21,8 @@ import { GroupCall, MatrixClient, RoomMember } from "matrix-js-sdk";
 | 
				
			||||||
import { CallFeed } from "matrix-js-sdk/src/webrtc/callFeed";
 | 
					import { CallFeed } from "matrix-js-sdk/src/webrtc/callFeed";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { useModalTriggerState } from "../Modal";
 | 
					import { useModalTriggerState } from "../Modal";
 | 
				
			||||||
import { SettingsModal } from "../settings/SettingsModal";
 | 
					 | 
				
			||||||
import { InviteModal } from "./InviteModal";
 | 
					import { InviteModal } from "./InviteModal";
 | 
				
			||||||
import { HangupButton, InviteButton, SettingsButton } from "../button";
 | 
					import { HangupButton, InviteButton } from "../button";
 | 
				
			||||||
import { Header, LeftNav, RightNav, RoomSetupHeaderInfo } from "../Header";
 | 
					import { Header, LeftNav, RightNav, RoomSetupHeaderInfo } from "../Header";
 | 
				
			||||||
import styles from "./PTTCallView.module.css";
 | 
					import styles from "./PTTCallView.module.css";
 | 
				
			||||||
import { Facepile } from "../Facepile";
 | 
					import { Facepile } from "../Facepile";
 | 
				
			||||||
| 
						 | 
					@ -37,6 +36,8 @@ import { getAvatarUrl } from "../matrix-utils";
 | 
				
			||||||
import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
 | 
					import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
 | 
				
			||||||
import { usePTTSounds } from "../sound/usePttSounds";
 | 
					import { usePTTSounds } from "../sound/usePttSounds";
 | 
				
			||||||
import { PTTClips } from "../sound/PTTClips";
 | 
					import { PTTClips } from "../sound/PTTClips";
 | 
				
			||||||
 | 
					import { GroupCallInspector } from "./GroupCallInspector";
 | 
				
			||||||
 | 
					import { OverflowMenu } from "./OverflowMenu";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getPromptText(
 | 
					function getPromptText(
 | 
				
			||||||
  showTalkOverError: boolean,
 | 
					  showTalkOverError: boolean,
 | 
				
			||||||
| 
						 | 
					@ -100,7 +101,7 @@ export const PTTCallView: React.FC<Props> = ({
 | 
				
			||||||
}) => {
 | 
					}) => {
 | 
				
			||||||
  const { modalState: inviteModalState, modalProps: inviteModalProps } =
 | 
					  const { modalState: inviteModalState, modalProps: inviteModalProps } =
 | 
				
			||||||
    useModalTriggerState();
 | 
					    useModalTriggerState();
 | 
				
			||||||
  const { modalState: settingsModalState, modalProps: settingsModalProps } =
 | 
					  const { modalState: feedbackModalState, modalProps: feedbackModalProps } =
 | 
				
			||||||
    useModalTriggerState();
 | 
					    useModalTriggerState();
 | 
				
			||||||
  const [containerRef, bounds] = useMeasure({ polyfill: ResizeObserver });
 | 
					  const [containerRef, bounds] = useMeasure({ polyfill: ResizeObserver });
 | 
				
			||||||
  const facepileSize = bounds.width < 800 ? "sm" : "md";
 | 
					  const facepileSize = bounds.width < 800 ? "sm" : "md";
 | 
				
			||||||
| 
						 | 
					@ -126,7 +127,13 @@ export const PTTCallView: React.FC<Props> = ({
 | 
				
			||||||
    startTalking,
 | 
					    startTalking,
 | 
				
			||||||
    stopTalking,
 | 
					    stopTalking,
 | 
				
			||||||
    transmitBlocked,
 | 
					    transmitBlocked,
 | 
				
			||||||
  } = usePTT(client, groupCall, userMediaFeeds, playClip);
 | 
					  } = usePTT(
 | 
				
			||||||
 | 
					    client,
 | 
				
			||||||
 | 
					    groupCall,
 | 
				
			||||||
 | 
					    userMediaFeeds,
 | 
				
			||||||
 | 
					    playClip,
 | 
				
			||||||
 | 
					    !feedbackModalState.isOpen
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const showTalkOverError = pttButtonHeld && transmitBlocked;
 | 
					  const showTalkOverError = pttButtonHeld && transmitBlocked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -154,6 +161,13 @@ export const PTTCallView: React.FC<Props> = ({
 | 
				
			||||||
        endTalkingRef={endTalkingRef}
 | 
					        endTalkingRef={endTalkingRef}
 | 
				
			||||||
        blockedRef={blockedRef}
 | 
					        blockedRef={blockedRef}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
 | 
					      <GroupCallInspector
 | 
				
			||||||
 | 
					        client={client}
 | 
				
			||||||
 | 
					        groupCall={groupCall}
 | 
				
			||||||
 | 
					        // Never shown in PTT mode, but must be present to collect call state
 | 
				
			||||||
 | 
					        // https://github.com/vector-im/element-call/issues/328
 | 
				
			||||||
 | 
					        show={false}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
      <Header className={styles.header}>
 | 
					      <Header className={styles.header}>
 | 
				
			||||||
        <LeftNav>
 | 
					        <LeftNav>
 | 
				
			||||||
          <RoomSetupHeaderInfo roomName={roomName} onPress={onLeave} />
 | 
					          <RoomSetupHeaderInfo roomName={roomName} onPress={onLeave} />
 | 
				
			||||||
| 
						 | 
					@ -174,7 +188,17 @@ export const PTTCallView: React.FC<Props> = ({
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div className={styles.footer}>
 | 
					        <div className={styles.footer}>
 | 
				
			||||||
          <SettingsButton onPress={() => settingsModalState.open()} />
 | 
					          <OverflowMenu
 | 
				
			||||||
 | 
					            inCall
 | 
				
			||||||
 | 
					            roomId={roomId}
 | 
				
			||||||
 | 
					            setShowInspector={setShowInspector}
 | 
				
			||||||
 | 
					            showInspector={showInspector}
 | 
				
			||||||
 | 
					            client={client}
 | 
				
			||||||
 | 
					            groupCall={groupCall}
 | 
				
			||||||
 | 
					            showInvite={false}
 | 
				
			||||||
 | 
					            feedbackModalState={feedbackModalState}
 | 
				
			||||||
 | 
					            feedbackModalProps={feedbackModalProps}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
          <HangupButton onPress={onLeave} />
 | 
					          <HangupButton onPress={onLeave} />
 | 
				
			||||||
          <InviteButton onPress={() => inviteModalState.open()} />
 | 
					          <InviteButton onPress={() => inviteModalState.open()} />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
| 
						 | 
					@ -233,13 +257,6 @@ export const PTTCallView: React.FC<Props> = ({
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      {settingsModalState.isOpen && (
 | 
					 | 
				
			||||||
        <SettingsModal
 | 
					 | 
				
			||||||
          {...settingsModalProps}
 | 
					 | 
				
			||||||
          setShowInspector={setShowInspector}
 | 
					 | 
				
			||||||
          showInspector={showInspector}
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      )}
 | 
					 | 
				
			||||||
      {inviteModalState.isOpen && (
 | 
					      {inviteModalState.isOpen && (
 | 
				
			||||||
        <InviteModal roomId={roomId} {...inviteModalProps} />
 | 
					        <InviteModal roomId={roomId} {...inviteModalProps} />
 | 
				
			||||||
      )}
 | 
					      )}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@ import { ResizeObserver } from "@juggle/resize-observer";
 | 
				
			||||||
import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
 | 
					import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
 | 
				
			||||||
import styles from "./VideoPreview.module.css";
 | 
					import styles from "./VideoPreview.module.css";
 | 
				
			||||||
import { Body } from "../typography/Typography";
 | 
					import { Body } from "../typography/Typography";
 | 
				
			||||||
 | 
					import { useModalTriggerState } from "../Modal";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function VideoPreview({
 | 
					export function VideoPreview({
 | 
				
			||||||
  client,
 | 
					  client,
 | 
				
			||||||
| 
						 | 
					@ -44,6 +45,9 @@ export function VideoPreview({
 | 
				
			||||||
  const [previewRef, previewBounds] = useMeasure({ polyfill: ResizeObserver });
 | 
					  const [previewRef, previewBounds] = useMeasure({ polyfill: ResizeObserver });
 | 
				
			||||||
  const avatarSize = (previewBounds.height - 66) / 2;
 | 
					  const avatarSize = (previewBounds.height - 66) / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { modalState: feedbackModalState, modalProps: feedbackModalProps } =
 | 
				
			||||||
 | 
					    useModalTriggerState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className={styles.preview} ref={previewRef}>
 | 
					    <div className={styles.preview} ref={previewRef}>
 | 
				
			||||||
      <video ref={videoRef} muted playsInline disablePictureInPicture />
 | 
					      <video ref={videoRef} muted playsInline disablePictureInPicture />
 | 
				
			||||||
| 
						 | 
					@ -87,6 +91,8 @@ export function VideoPreview({
 | 
				
			||||||
              setShowInspector={setShowInspector}
 | 
					              setShowInspector={setShowInspector}
 | 
				
			||||||
              showInspector={showInspector}
 | 
					              showInspector={showInspector}
 | 
				
			||||||
              client={client}
 | 
					              client={client}
 | 
				
			||||||
 | 
					              feedbackModalState={feedbackModalState}
 | 
				
			||||||
 | 
					              feedbackModalProps={feedbackModalProps}
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </>
 | 
					        </>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,8 @@ export const usePTT = (
 | 
				
			||||||
  client: MatrixClient,
 | 
					  client: MatrixClient,
 | 
				
			||||||
  groupCall: GroupCall,
 | 
					  groupCall: GroupCall,
 | 
				
			||||||
  userMediaFeeds: CallFeed[],
 | 
					  userMediaFeeds: CallFeed[],
 | 
				
			||||||
  playClip: PlayClipFunction
 | 
					  playClip: PlayClipFunction,
 | 
				
			||||||
 | 
					  enablePTTButton: boolean
 | 
				
			||||||
): PTTState => {
 | 
					): PTTState => {
 | 
				
			||||||
  // Used to serialise all the mute calls so they don't race. It has
 | 
					  // Used to serialise all the mute calls so they don't race. It has
 | 
				
			||||||
  // its own state as its always set separately from anything else.
 | 
					  // its own state as its always set separately from anything else.
 | 
				
			||||||
| 
						 | 
					@ -213,6 +214,8 @@ export const usePTT = (
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    function onKeyDown(event: KeyboardEvent): void {
 | 
					    function onKeyDown(event: KeyboardEvent): void {
 | 
				
			||||||
      if (event.code === "Space") {
 | 
					      if (event.code === "Space") {
 | 
				
			||||||
 | 
					        if (!enablePTTButton) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        event.preventDefault();
 | 
					        event.preventDefault();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (pttButtonHeld) return;
 | 
					        if (pttButtonHeld) return;
 | 
				
			||||||
| 
						 | 
					@ -255,6 +258,7 @@ export const usePTT = (
 | 
				
			||||||
    isAdmin,
 | 
					    isAdmin,
 | 
				
			||||||
    talkOverEnabled,
 | 
					    talkOverEnabled,
 | 
				
			||||||
    pttButtonHeld,
 | 
					    pttButtonHeld,
 | 
				
			||||||
 | 
					    enablePTTButton,
 | 
				
			||||||
    setMicMuteWrapper,
 | 
					    setMicMuteWrapper,
 | 
				
			||||||
  ]);
 | 
					  ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue