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 (
+
+ );
+}
+
+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";