Merge branch 'livekit' into remove-walkie-talkie
This commit is contained in:
@@ -45,7 +45,6 @@ import {
|
||||
import { useEnableE2EE } from "../settings/useSetting";
|
||||
import { useRoomAvatar } from "./useRoomAvatar";
|
||||
import { useRoomName } from "./useRoomName";
|
||||
import { useModalTriggerState } from "../Modal";
|
||||
import { useJoinRule } from "./useJoinRule";
|
||||
import { ShareModal } from "./ShareModal";
|
||||
|
||||
@@ -286,12 +285,15 @@ export function GroupCallView({
|
||||
|
||||
const joinRule = useJoinRule(rtcSession.room);
|
||||
|
||||
const { modalState: shareModalState, modalProps: shareModalProps } =
|
||||
useModalTriggerState();
|
||||
const [shareModalOpen, setShareModalOpen] = useState(false);
|
||||
const onDismissShareModal = useCallback(
|
||||
() => setShareModalOpen(false),
|
||||
[setShareModalOpen]
|
||||
);
|
||||
|
||||
const onShareClickFn = useCallback(
|
||||
() => shareModalState.open(),
|
||||
[shareModalState]
|
||||
() => setShareModalOpen(true),
|
||||
[setShareModalOpen]
|
||||
);
|
||||
const onShareClick = joinRule === JoinRule.Public ? onShareClickFn : null;
|
||||
|
||||
@@ -311,8 +313,12 @@ export function GroupCallView({
|
||||
return <ErrorView error={new Error("You need to enable E2EE to join.")} />;
|
||||
}
|
||||
|
||||
const shareModal = shareModalState.isOpen && (
|
||||
<ShareModal roomId={rtcSession.room.roomId} {...shareModalProps} />
|
||||
const shareModal = (
|
||||
<ShareModal
|
||||
roomId={rtcSession.room.roomId}
|
||||
open={shareModalOpen}
|
||||
onDismiss={onDismissShareModal}
|
||||
/>
|
||||
);
|
||||
|
||||
if (isJoined) {
|
||||
|
||||
@@ -30,7 +30,6 @@ import { Room as MatrixRoom } from "matrix-js-sdk/src/models/room";
|
||||
import { Ref, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useMeasure from "react-use-measure";
|
||||
import { OverlayTriggerState } from "@react-stately/overlays";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSession";
|
||||
|
||||
@@ -51,7 +50,6 @@ import {
|
||||
VideoGrid,
|
||||
} from "../video-grid/VideoGrid";
|
||||
import { useShowConnectionStats } from "../settings/useSetting";
|
||||
import { useModalTriggerState } from "../Modal";
|
||||
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
||||
import { useUrlParams } from "../UrlParams";
|
||||
import { useCallViewKeyboardShortcuts } from "../useCallViewKeyboardShortcuts";
|
||||
@@ -313,25 +311,20 @@ export function InCallView({
|
||||
);
|
||||
};
|
||||
|
||||
const {
|
||||
modalState: rageshakeRequestModalState,
|
||||
modalProps: rageshakeRequestModalProps,
|
||||
} = useRageshakeRequestModal(rtcSession.room.roomId);
|
||||
const rageshakeRequestModalProps = useRageshakeRequestModal(
|
||||
rtcSession.room.roomId
|
||||
);
|
||||
|
||||
const {
|
||||
modalState: settingsModalState,
|
||||
modalProps: settingsModalProps,
|
||||
}: {
|
||||
modalState: OverlayTriggerState;
|
||||
modalProps: {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
};
|
||||
} = useModalTriggerState();
|
||||
const [settingsModalOpen, setSettingsModalOpen] = useState(false);
|
||||
|
||||
const openSettings = useCallback(() => {
|
||||
settingsModalState.open();
|
||||
}, [settingsModalState]);
|
||||
const openSettings = useCallback(
|
||||
() => setSettingsModalOpen(true),
|
||||
[setSettingsModalOpen]
|
||||
);
|
||||
const closeSettings = useCallback(
|
||||
() => setSettingsModalOpen(false),
|
||||
[setSettingsModalOpen]
|
||||
);
|
||||
|
||||
const toggleScreensharing = useCallback(async () => {
|
||||
exitFullscreen();
|
||||
@@ -442,19 +435,13 @@ export function InCallView({
|
||||
show={showInspector}
|
||||
/>
|
||||
)*/}
|
||||
{rageshakeRequestModalState.isOpen && !noControls && (
|
||||
<RageshakeRequestModal
|
||||
{...rageshakeRequestModalProps}
|
||||
roomId={rtcSession.room.roomId}
|
||||
/>
|
||||
)}
|
||||
{settingsModalState.isOpen && (
|
||||
<SettingsModal
|
||||
client={client}
|
||||
roomId={rtcSession.room.roomId}
|
||||
{...settingsModalProps}
|
||||
/>
|
||||
)}
|
||||
{!noControls && <RageshakeRequestModal {...rageshakeRequestModalProps} />}
|
||||
<SettingsModal
|
||||
client={client}
|
||||
roomId={rtcSession.room.roomId}
|
||||
open={settingsModalOpen}
|
||||
onDismiss={closeSettings}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
import { FC, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Modal, ModalContent, ModalProps } from "../Modal";
|
||||
import { Modal, ModalProps } from "../Modal";
|
||||
import { Button } from "../button";
|
||||
import { FieldRow, ErrorMessage } from "../input/Input";
|
||||
import { useSubmitRageshake } from "../settings/submit-rageshake";
|
||||
@@ -26,51 +26,49 @@ import { Body } from "../typography/Typography";
|
||||
interface Props extends Omit<ModalProps, "title" | "children"> {
|
||||
rageshakeRequestId: string;
|
||||
roomId: string;
|
||||
onClose: () => void;
|
||||
open: boolean;
|
||||
onDismiss: () => void;
|
||||
}
|
||||
|
||||
export const RageshakeRequestModal: FC<Props> = ({
|
||||
rageshakeRequestId,
|
||||
roomId,
|
||||
...rest
|
||||
open,
|
||||
onDismiss,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { submitRageshake, sending, sent, error } = useSubmitRageshake();
|
||||
|
||||
useEffect(() => {
|
||||
if (sent) {
|
||||
rest.onClose();
|
||||
}
|
||||
}, [sent, rest]);
|
||||
if (sent) onDismiss();
|
||||
}, [sent, onDismiss]);
|
||||
|
||||
return (
|
||||
<Modal title={t("Debug log request")} isDismissable {...rest}>
|
||||
<ModalContent>
|
||||
<Body>
|
||||
{t(
|
||||
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log."
|
||||
)}
|
||||
</Body>
|
||||
<FieldRow>
|
||||
<Button
|
||||
onPress={() =>
|
||||
submitRageshake({
|
||||
sendLogs: true,
|
||||
rageshakeRequestId,
|
||||
roomId,
|
||||
})
|
||||
}
|
||||
disabled={sending}
|
||||
>
|
||||
{sending ? t("Sending debug logs…") : t("Send debug logs")}
|
||||
</Button>
|
||||
</FieldRow>
|
||||
{error && (
|
||||
<FieldRow>
|
||||
<ErrorMessage error={error} />
|
||||
</FieldRow>
|
||||
<Modal title={t("Debug log request")} open={open} onDismiss={onDismiss}>
|
||||
<Body>
|
||||
{t(
|
||||
"Another user on this call is having an issue. In order to better diagnose these issues we'd like to collect a debug log."
|
||||
)}
|
||||
</ModalContent>
|
||||
</Body>
|
||||
<FieldRow>
|
||||
<Button
|
||||
onPress={() =>
|
||||
submitRageshake({
|
||||
sendLogs: true,
|
||||
rageshakeRequestId,
|
||||
roomId,
|
||||
})
|
||||
}
|
||||
disabled={sending}
|
||||
>
|
||||
{sending ? t("Sending debug logs…") : t("Send debug logs")}
|
||||
</Button>
|
||||
</FieldRow>
|
||||
{error && (
|
||||
<FieldRow>
|
||||
<ErrorMessage error={error} />
|
||||
</FieldRow>
|
||||
)}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.inviteModal {
|
||||
max-width: 413px;
|
||||
}
|
||||
|
||||
.copyButton {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -17,35 +17,30 @@ limitations under the License.
|
||||
import { FC } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Modal, ModalContent, ModalProps } from "../Modal";
|
||||
import { Modal } from "../Modal";
|
||||
import { CopyButton } from "../button";
|
||||
import { getRoomUrl } from "../matrix-utils";
|
||||
import styles from "./ShareModal.module.css";
|
||||
import { useRoomSharedKey } from "../e2ee/sharedKeyManagement";
|
||||
|
||||
interface Props extends Omit<ModalProps, "title" | "children"> {
|
||||
interface Props {
|
||||
roomId: string;
|
||||
open: boolean;
|
||||
onDismiss: () => void;
|
||||
}
|
||||
|
||||
export const ShareModal: FC<Props> = ({ roomId, ...rest }) => {
|
||||
export const ShareModal: FC<Props> = ({ roomId, open, onDismiss }) => {
|
||||
const { t } = useTranslation();
|
||||
const roomSharedKey = useRoomSharedKey(roomId);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t("Share this call")}
|
||||
isDismissable
|
||||
className={styles.inviteModal}
|
||||
{...rest}
|
||||
>
|
||||
<ModalContent>
|
||||
<p>{t("Copy and share this call link")}</p>
|
||||
<CopyButton
|
||||
className={styles.copyButton}
|
||||
value={getRoomUrl(roomId, roomSharedKey ?? undefined)}
|
||||
data-testid="modal_inviteLink"
|
||||
/>
|
||||
</ModalContent>
|
||||
<Modal title={t("Share this call")} open={open} onDismiss={onDismiss}>
|
||||
<p>{t("Copy and share this call link")}</p>
|
||||
<CopyButton
|
||||
className={styles.copyButton}
|
||||
value={getRoomUrl(roomId, roomSharedKey ?? undefined)}
|
||||
data-testid="modal_inviteLink"
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,10 +14,9 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { useEffect, useCallback, useMemo, useRef, FC } from "react";
|
||||
import { useEffect, useCallback, useMemo, useRef, FC, useState } from "react";
|
||||
import useMeasure from "react-use-measure";
|
||||
import { ResizeObserver } from "@juggle/resize-observer";
|
||||
import { OverlayTriggerState } from "@react-stately/overlays";
|
||||
import { usePreviewTracks } from "@livekit/components-react";
|
||||
import {
|
||||
CreateLocalTracksOptions,
|
||||
@@ -28,7 +27,6 @@ import {
|
||||
import { MicButton, SettingsButton, VideoButton } from "../button";
|
||||
import { Avatar } from "../Avatar";
|
||||
import styles from "./VideoPreview.module.css";
|
||||
import { useModalTriggerState } from "../Modal";
|
||||
import { SettingsModal } from "../settings/SettingsModal";
|
||||
import { useClient } from "../ClientContext";
|
||||
import { useMediaDevices } from "../livekit/MediaDevicesContext";
|
||||
@@ -54,20 +52,16 @@ export const VideoPreview: FC<Props> = ({ matrixInfo, muteStates }) => {
|
||||
const { client } = useClient();
|
||||
const [previewRef, previewBounds] = useMeasure({ polyfill: ResizeObserver });
|
||||
|
||||
const {
|
||||
modalState: settingsModalState,
|
||||
modalProps: settingsModalProps,
|
||||
}: {
|
||||
modalState: OverlayTriggerState;
|
||||
modalProps: {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
};
|
||||
} = useModalTriggerState();
|
||||
const [settingsModalOpen, setSettingsModalOpen] = useState(false);
|
||||
|
||||
const openSettings = useCallback(() => {
|
||||
settingsModalState.open();
|
||||
}, [settingsModalState]);
|
||||
const openSettings = useCallback(
|
||||
() => setSettingsModalOpen(true),
|
||||
[setSettingsModalOpen]
|
||||
);
|
||||
const closeSettings = useCallback(
|
||||
() => setSettingsModalOpen(false),
|
||||
[setSettingsModalOpen]
|
||||
);
|
||||
|
||||
const devices = useMediaDevices();
|
||||
|
||||
@@ -153,8 +147,12 @@ export const VideoPreview: FC<Props> = ({ matrixInfo, muteStates }) => {
|
||||
<SettingsButton onPress={openSettings} />
|
||||
</div>
|
||||
</>
|
||||
{settingsModalState.isOpen && client && (
|
||||
<SettingsModal client={client} {...settingsModalProps} />
|
||||
{client && (
|
||||
<SettingsModal
|
||||
client={client}
|
||||
open={settingsModalOpen}
|
||||
onDismiss={closeSettings}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -16,21 +16,7 @@ limitations under the License.
|
||||
|
||||
import { useEffect } from "react";
|
||||
|
||||
// https://stackoverflow.com/a/9039885
|
||||
function isIOS() {
|
||||
return (
|
||||
[
|
||||
"iPad Simulator",
|
||||
"iPhone Simulator",
|
||||
"iPod Simulator",
|
||||
"iPad",
|
||||
"iPhone",
|
||||
"iPod",
|
||||
].includes(navigator.platform) ||
|
||||
// iPad on iOS 13 detection
|
||||
(navigator.userAgent.includes("Mac") && "ontouchend" in document)
|
||||
);
|
||||
}
|
||||
import { platform } from "../Platform";
|
||||
|
||||
export function usePageUnload(callback: () => void) {
|
||||
useEffect(() => {
|
||||
@@ -53,7 +39,7 @@ export function usePageUnload(callback: () => void) {
|
||||
}
|
||||
|
||||
// iOS doesn't fire beforeunload event, so leave the call when you hide the page.
|
||||
if (isIOS()) {
|
||||
if (platform === "ios") {
|
||||
window.addEventListener("pagehide", onBeforeUnload);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
|
||||
Reference in New Issue
Block a user