diff --git a/src/react-components/room/Tip.scss b/src/react-components/room/Tip.scss index 91bdcd6fb1..b7a4a0b541 100644 --- a/src/react-components/room/Tip.scss +++ b/src/react-components/room/Tip.scss @@ -48,4 +48,18 @@ border-color: theme.$tip-button-color-pressed; background-color: theme.$tip-button-color-pressed; } -} \ No newline at end of file +} + +:local(.toast) { + animation: vanish 5s; + animation-fill-mode: forwards; + @keyframes vanish { + 70% { + opacity: 1; + } + 100% { + opacity: 0; + visibility: hidden; + } + } +} diff --git a/src/react-components/room/TipContainer.js b/src/react-components/room/TipContainer.js index d7f7ca6def..7e27e1cb0a 100644 --- a/src/react-components/room/TipContainer.js +++ b/src/react-components/room/TipContainer.js @@ -2,6 +2,7 @@ import React, { useCallback, useState } from "react"; import PropTypes from "prop-types"; import { FormattedMessage, useIntl, defineMessages } from "react-intl"; import { Tip } from "./Tip"; +import { ToastTip } from "./ToastTip"; import { useEffect } from "react"; import { discordBridgesForPresences, hasEmbedPresences } from "../../utils/phoenix-utils"; import configs from "../../utils/configs"; @@ -75,7 +76,26 @@ export function FullscreenTip(props) { ); } -export function TipContainer({ hide, inLobby, inRoom, isStreaming, isEmbedded, scene, store, hubId, presences }) { +export function RecordModeTip(props) { + return ( + + + + ); +} + +export function TipContainer({ + hide, + inLobby, + inRoom, + isStreaming, + isEmbedded, + scene, + store, + hubId, + presences, + isRecordMode +}) { const intl = useIntl(); const [lobbyTipDismissed, setLobbyTipDismissed] = useState(false); const [broadcastTipDismissed, setBroadcastTipDismissed] = useState(() => @@ -94,15 +114,15 @@ export function TipContainer({ hide, inLobby, inRoom, isStreaming, isEmbedded, s useEffect( () => { - function onSceneTipChanged({ detail: tipId }) { - setOnboardingTipId(tipId); - } + function onSceneTipChanged({ detail: tipId }) { + setOnboardingTipId(tipId); + } - scene.addEventListener("tip-changed", onSceneTipChanged); + scene.addEventListener("tip-changed", onSceneTipChanged); - setOnboardingTipId(scene.systems.tips.activeTip); - }, - [scene] + setOnboardingTipId(scene.systems.tips.activeTip); + }, + [scene] ); const discordBridges = presences ? discordBridgesForPresences(presences) : []; diff --git a/src/react-components/room/ToastTip.js b/src/react-components/room/ToastTip.js new file mode 100644 index 0000000000..dff6c818d9 --- /dev/null +++ b/src/react-components/room/ToastTip.js @@ -0,0 +1,17 @@ +import React from "react"; +import PropTypes from "prop-types"; +import classNames from "classnames"; +import styles from "./Tip.scss"; + +export function ToastTip({ className, children, ...rest }) { + return ( +
+
{children}
+
+ ); +} + +ToastTip.propTypes = { + className: PropTypes.string, + children: PropTypes.node +}; diff --git a/src/react-components/ui-root.js b/src/react-components/ui-root.js index 3e217fdbfc..801fc8bb48 100644 --- a/src/react-components/ui-root.js +++ b/src/react-components/ui-root.js @@ -90,7 +90,7 @@ import { UserProfileSidebarContainer } from "./room/UserProfileSidebarContainer" import { CloseRoomModal } from "./room/CloseRoomModal"; import { WebVRUnsupportedModal } from "./room/WebVRUnsupportedModal"; import { TweetModalContainer } from "./room/TweetModalContainer"; -import { TipContainer, FullscreenTip } from "./room/TipContainer"; +import { TipContainer, FullscreenTip, RecordModeTip } from "./room/TipContainer"; import { SpectatingLabel } from "./room/SpectatingLabel"; import { SignInMessages } from "./auth/SignInModal"; import { MediaDevicesEvents } from "../utils/media-devices-utils"; @@ -185,6 +185,7 @@ class UIRoot extends Component { showPrefs: false, watching: false, isStreaming: false, + isRecordingMode: false, waitingOnAudio: false, audioTrackClone: null, @@ -327,6 +328,21 @@ class UIRoot extends Component { this.props.scene.addEventListener("action_toggle_ui", () => this.setState({ hide: !this.state.hide, hideUITip: false }) ); + this.props.scene.addEventListener("action_toggle_record", () => { + const cursor = document.querySelector("#right-cursor"); + if (this.state.isRecordingMode) { + // If isRecordingMode is true then toggle it off. + cursor.object3D.children[1].material.visible = true; + this.setState({ hide: false, hideUITip: false, isRecordingMode: false }); + document.querySelector(".rs-fps-counter").style.visibility = "visible"; + document.querySelector(".rs-base").style.visibility = "visible"; + } else { + cursor.object3D.children[1].material.visible = false; + this.setState({ hide: true, hideUITip: true, isRecordingMode: true }); + document.querySelector(".rs-fps-counter").style.visibility = "hidden"; + document.querySelector(".rs-base").style.visibility = "hidden"; + } + }); this.props.scene.addEventListener("devicechange", () => { this.forceUpdate(); }); @@ -948,6 +964,13 @@ class UIRoot extends Component { isGhost, hide }; + if (this.state.isRecordingMode) { + return ( +
+ } /> +
+ ); + } if (this.props.hide || this.state.hide) { return (
diff --git a/src/systems/ui-hotkeys.js b/src/systems/ui-hotkeys.js index 841f89ddd2..2e399d7384 100644 --- a/src/systems/ui-hotkeys.js +++ b/src/systems/ui-hotkeys.js @@ -18,7 +18,7 @@ AFRAME.registerSystem("ui-hotkeys", { this.mediaSearchStore = window.APP.mediaSearchStore; }, - tick: function() { + tick: function () { if (!this.userinput) { this.userinput = this.el.systems.userinput; } @@ -62,5 +62,8 @@ AFRAME.registerSystem("ui-hotkeys", { if (this.userinput.get(paths.actions.toggleUI)) { this.el.emit("action_toggle_ui"); } + if (this.userinput.get(paths.actions.toggleRecord)) { + this.el.emit("action_toggle_record"); + } } }); diff --git a/src/systems/userinput/bindings/keyboard-mouse-user.js b/src/systems/userinput/bindings/keyboard-mouse-user.js index 720d52a28c..336dade45e 100644 --- a/src/systems/userinput/bindings/keyboard-mouse-user.js +++ b/src/systems/userinput/bindings/keyboard-mouse-user.js @@ -151,6 +151,11 @@ export const keyboardMouseUserBindings = addSetsToBindings({ dest: { value: paths.actions.snapRotateRight }, xform: xforms.rising }, + { + src: { value: paths.device.keyboard.key("b") }, + dest: { value: paths.actions.toggleRecord }, + xform: xforms.rising + }, { src: { value: paths.device.keyboard.key("Tab") }, dest: { value: paths.actions.toggleFreeze }, diff --git a/src/systems/userinput/paths.js b/src/systems/userinput/paths.js index 6fbffdee23..cfdcaa545e 100644 --- a/src/systems/userinput/paths.js +++ b/src/systems/userinput/paths.js @@ -24,6 +24,7 @@ paths.actions.thaw = "/actions/thaw"; paths.actions.muteMic = "/actions/muteMic"; paths.actions.toggleFly = "/actions/toggleFly"; paths.actions.toggleUI = "/actions/toggleUI"; +paths.actions.toggleRecord = "/actions/toggleRecord"; paths.actions.waypointDeltaDistance = "/actions/waypointDeltaDistance"; paths.actions.focusChat = "/actions/focusChat"; paths.actions.focusChatCommand = "/actions/focusChatCommand";