Move feedback button to overflow menu

To be consistent with normal view and avoid nested dialogs.

Also disable space for the PTT key when the feedback dialog is visible,
since otherwise you can't type a space. Involves some rearrangement of
modal state.

Remove accidentally comitted vite port config.
This commit is contained in:
David Baker 2022-05-17 15:36:13 +01:00
parent b3285974f9
commit cc8ce7a05c
7 changed files with 49 additions and 42 deletions

View file

@ -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>

View file

@ -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}>
{showInvite && (
<Item key="invite" textValue="Invite people"> <Item key="invite" textValue="Invite people">
<AddUserIcon /> <AddUserIcon />
<span>Invite people</span> <span>Invite people</span>
</Item> </Item>
)}
<Item key="settings" textValue="Settings"> <Item key="settings" textValue="Settings">
<SettingsIcon /> <SettingsIcon />
<span>Settings</span> <span>Settings</span>

View file

@ -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";
@ -38,7 +37,7 @@ 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 { GroupCallInspector } from "./GroupCallInspector";
import { FeedbackModal } from "./FeedbackModal"; import { OverflowMenu } from "./OverflowMenu";
function getPromptText( function getPromptText(
showTalkOverError: boolean, showTalkOverError: boolean,
@ -102,8 +101,6 @@ export const PTTCallView: React.FC<Props> = ({
}) => { }) => {
const { modalState: inviteModalState, modalProps: inviteModalProps } = const { modalState: inviteModalState, modalProps: inviteModalProps } =
useModalTriggerState(); useModalTriggerState();
const { modalState: settingsModalState, modalProps: settingsModalProps } =
useModalTriggerState();
const { modalState: feedbackModalState, modalProps: feedbackModalProps } = const { modalState: feedbackModalState, modalProps: feedbackModalProps } =
useModalTriggerState(); useModalTriggerState();
const [containerRef, bounds] = useMeasure({ polyfill: ResizeObserver }); const [containerRef, bounds] = useMeasure({ polyfill: ResizeObserver });
@ -125,7 +122,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;
@ -179,7 +182,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>
@ -238,21 +251,6 @@ export const PTTCallView: React.FC<Props> = ({
</div> </div>
</div> </div>
{settingsModalState.isOpen && (
<SettingsModal
{...settingsModalProps}
setShowInspector={setShowInspector}
showInspector={showInspector}
showFeedbackDialog={feedbackModalState.open}
/>
)}
{feedbackModalState.isOpen && (
<FeedbackModal
{...feedbackModalProps}
roomId={groupCall?.room.roomId}
inCall
/>
)}
{inviteModalState.isOpen && ( {inviteModalState.isOpen && (
<InviteModal roomId={roomId} {...inviteModalProps} /> <InviteModal roomId={roomId} {...inviteModalProps} />
)} )}

View file

@ -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>
</> </>

View file

@ -37,7 +37,8 @@ export const usePTT = (
client: MatrixClient, client: MatrixClient,
groupCall: GroupCall, groupCall: GroupCall,
userMediaFeeds: CallFeed[], userMediaFeeds: CallFeed[],
playClip: PlayClipFunction playClip: PlayClipFunction,
enablePTTButton: boolean
): PTTState => { ): PTTState => {
const [ const [
{ {
@ -162,6 +163,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;
@ -204,6 +207,7 @@ export const usePTT = (
isAdmin, isAdmin,
talkOverEnabled, talkOverEnabled,
pttButtonHeld, pttButtonHeld,
enablePTTButton,
]); ]);
const setTalkOverEnabled = useCallback((talkOverEnabled) => { const setTalkOverEnabled = useCallback((talkOverEnabled) => {

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React, { useCallback } from "react"; import React from "react";
import { Modal } from "../Modal"; import { Modal } from "../Modal";
import styles from "./SettingsModal.module.css"; import styles from "./SettingsModal.module.css";
import { TabContainer, TabItem } from "../tabs/Tabs"; import { TabContainer, TabItem } from "../tabs/Tabs";
@ -29,12 +29,7 @@ import { Button } from "../button";
import { useDownloadDebugLog } from "./submit-rageshake"; import { useDownloadDebugLog } from "./submit-rageshake";
import { Body } from "../typography/Typography"; import { Body } from "../typography/Typography";
export function SettingsModal({ export function SettingsModal({ setShowInspector, showInspector, ...rest }) {
setShowInspector,
showInspector,
showFeedbackDialog,
...rest
}) {
const { const {
audioInput, audioInput,
audioInputs, audioInputs,
@ -130,7 +125,6 @@ export function SettingsModal({
</FieldRow> </FieldRow>
<FieldRow> <FieldRow>
<Button onPress={downloadDebugLog}>Download Debug Logs</Button> <Button onPress={downloadDebugLog}>Download Debug Logs</Button>
<Button onPress={showFeedbackDialog}>Submit Feedback</Button>
</FieldRow> </FieldRow>
</TabItem> </TabItem>
</TabContainer> </TabContainer>

View file

@ -39,11 +39,6 @@ export default defineConfig(({ mode }) => {
proxy: { proxy: {
"/_matrix": env.VITE_DEFAULT_HOMESERVER || "http://localhost:8008", "/_matrix": env.VITE_DEFAULT_HOMESERVER || "http://localhost:8008",
}, },
strictPort: true,
hmr: {
port: 443,
protocol: 'wss',
},
}, },
resolve: { resolve: {
dedupe: [ dedupe: [