Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Locked down demo mvp #6030

Merged
merged 13 commits into from
Apr 24, 2023
5 changes: 3 additions & 2 deletions src/components/hud-controller.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CAMERA_MODE_FIRST_PERSON } from "../systems/camera-system";
import { isLockedDownDemoRoom } from "../utils/hub-utils";
const TWOPI = Math.PI * 2;
function deltaAngle(a, b) {
const p = Math.abs(b - a) % TWOPI;
Expand Down Expand Up @@ -75,10 +76,10 @@ AFRAME.registerComponent("hud-controller", {
hud.rotation.x = 0;
hud.rotation.z = 0;
}

hud.visible =
(!hudOutOfView || forceHudVisible) &&
this.el.sceneEl.systems["hubs-systems"].cameraSystem.mode === CAMERA_MODE_FIRST_PERSON;
this.el.sceneEl.systems["hubs-systems"].cameraSystem.mode === CAMERA_MODE_FIRST_PERSON &&
!isLockedDownDemoRoom();
mikemorran marked this conversation as resolved.
Show resolved Hide resolved
hud.position.y = (this.isYLocked ? this.lockedHeadPositionY : head.position.y) + offset + (1 - t) * offset;
hud.rotation.x = (1 - t) * THREE.MathUtils.DEG2RAD * 90;
hud.matrixNeedsUpdate = true;
Expand Down
5 changes: 3 additions & 2 deletions src/hub.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {
getCurrentHubId,
updateVRHudPresenceCount,
updateSceneCopresentState,
createHubChannelParams
createHubChannelParams,
isLockedDownDemoRoom
} from "./utils/hub-utils";
import "./utils/debug-log";
import configs from "./utils/configs";
Expand Down Expand Up @@ -764,7 +765,7 @@ document.addEventListener("DOMContentLoaded", async () => {

// If the stored avatar doesn't have a valid src, reset to a legacy avatar.
const avatarSrc = await getAvatarSrc(store.state.profile.avatarId);
if (!avatarSrc) {
if (!avatarSrc || isLockedDownDemoRoom(hubId)) {
await store.resetToRandomDefaultAvatar();
}

Expand Down
107 changes: 58 additions & 49 deletions src/react-components/preferences-screen.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
setMaxResolution
} from "../utils/screen-orientation-utils";
import { AAModes } from "../constants";
import { isLockedDownDemoRoom } from "../utils/hub-utils";

import dropdownArrowUrl from "../assets/images/dropdown_arrow.png";
import dropdownArrow2xUrl from "../assets/images/[email protected]";
Expand Down Expand Up @@ -1210,55 +1211,63 @@ class PreferencesScreen extends Component {
prefType: PREFERENCE_LIST_ITEM_TYPE.SELECT,
options: availableThemes
},
{
key: "nametagVisibility",
prefType: PREFERENCE_LIST_ITEM_TYPE.SELECT,
options: [
{
value: "showAll",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-all",
defaultMessage: "Always"
})
},
{
value: "showNone",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-none",
defaultMessage: "Never"
})
},
{
value: "showFrozen",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-frozen",
defaultMessage: "Only in Frozen state"
})
},
{
value: "showSpeaking",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-speaking",
defaultMessage: "Only speaking"
})
},
{
value: "showClose",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-close",
defaultMessage: "Close to me"
})
}
]
},
{
key: "nametagVisibilityDistance",
prefType: PREFERENCE_LIST_ITEM_TYPE.NUMBER_WITH_RANGE,
min: 1,
max: 20,
step: 1,
digits: 2
},
...(!isLockedDownDemoRoom()
mikemorran marked this conversation as resolved.
Show resolved Hide resolved
? [
{
key: "nametagVisibility",
prefType: PREFERENCE_LIST_ITEM_TYPE.SELECT,
options: [
{
value: "showAll",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-all",
defaultMessage: "Always"
})
},
{
value: "showNone",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-none",
defaultMessage: "Never"
})
},
{
value: "showFrozen",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-frozen",
defaultMessage: "Only in Frozen state"
})
},
{
value: "showSpeaking",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-speaking",
defaultMessage: "Only speaking"
})
},
{
value: "showClose",
text: intl.formatMessage({
id: "preferences-screen.nametag-visibility.show-close",
defaultMessage: "Close to me"
})
}
]
}
]
: []),
...(!isLockedDownDemoRoom()
? [
{
key: "nametagVisibilityDistance",
prefType: PREFERENCE_LIST_ITEM_TYPE.NUMBER_WITH_RANGE,
min: 1,
max: 20,
step: 1,
digits: 2
}
]
: []),
this.state.preferredCamera,
{
key: "allowMultipleHubsInstances",
Expand Down
4 changes: 4 additions & 0 deletions src/react-components/room/ChatSidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import styles from "./ChatSidebar.scss";
import { formatMessageBody } from "../../utils/chat-message";
import { FormattedMessage, useIntl, defineMessages, FormattedRelativeTime } from "react-intl";
import { permissionMessage } from "./PermissionNotifications";
import { isLockedDownDemoRoom } from "../../utils/hub-utils";

export function SpawnMessageButton(props) {
return (
Expand Down Expand Up @@ -279,6 +280,9 @@ const logMessages = defineMessages({

// TODO: use react-intl's defineMessages to get proper extraction
export function formatSystemMessage(entry, intl) {
if (isLockedDownDemoRoom()) {
mikemorran marked this conversation as resolved.
Show resolved Hide resolved
return null;
}
switch (entry.type) {
case "join":
return intl.formatMessage(joinedMessages[entry.presence], { name: <b>{entry.name}</b> });
Expand Down
10 changes: 7 additions & 3 deletions src/react-components/room/ContentMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@ import { ReactComponent as ObjectsIcon } from "../icons/Objects.svg";
import { ReactComponent as PeopleIcon } from "../icons/People.svg";
import { FormattedMessage } from "react-intl";

export function ContentMenuButton({ active, children, ...props }) {
export function ContentMenuButton({ active, disabled, children, ...props }) {
mikemorran marked this conversation as resolved.
Show resolved Hide resolved
return (
<button className={className(styles.contentMenuButton, { [styles.active]: active })} {...props}>
<button
className={className(styles.contentMenuButton, { [styles.active]: active, [styles.disabled]: disabled })}
{...props}
>
{children}
</button>
);
}

ContentMenuButton.propTypes = {
children: PropTypes.node,
active: PropTypes.bool
active: PropTypes.bool,
disabled: PropTypes.bool
};

export function ECSDebugMenuButton(props) {
Expand Down
9 changes: 9 additions & 0 deletions src/react-components/room/ContentMenu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,12 @@
margin: 0 8px;
background-color: theme.$border1-color;
}

:local(.disabled) {
pointer-events: none;
background-color: theme.$transparent;

svg {
color: theme.$text5-color;
}
mikemorran marked this conversation as resolved.
Show resolved Hide resolved
}
43 changes: 28 additions & 15 deletions src/react-components/ui-root.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { FormattedMessage } from "react-intl";
import screenfull from "screenfull";

import configs from "../utils/configs";
import { isLockedDownDemoRoom } from "../utils/hub-utils";
import { VR_DEVICE_AVAILABILITY } from "../utils/vr-caps-detect";
import { canShare } from "../utils/share";
import styles from "../assets/stylesheets/ui-root.scss";
Expand Down Expand Up @@ -817,7 +818,10 @@ class UIRoot extends Component {

renderEntryStartPanel = () => {
const { hasAcceptedProfile, hasChangedName } = this.props.store.state.activity;
const promptForNameAndAvatarBeforeEntry = this.props.hubIsBound ? !hasAcceptedProfile : !hasChangedName;
const isLockedDownDemo = isLockedDownDemoRoom(this.props.hub.hub_id);
mikemorran marked this conversation as resolved.
Show resolved Hide resolved
const promptForNameAndAvatarBeforeEntry = this.props.hubIsBound
? !hasAcceptedProfile && !isLockedDownDemo
: !hasChangedName && !isLockedDownDemo;

// TODO: What does onEnteringCanceled do?
return (
Expand Down Expand Up @@ -1099,7 +1103,9 @@ class UIRoot extends Component {

const streaming = this.state.isStreaming;

const showObjectList = enteredOrWatching;
const isLockedDownDemo = isLockedDownDemoRoom(this.props.hub.hub_id);

const showObjectList = enteredOrWatching && !isLockedDownDemo;
const showECSObjectsMenuButton = qsTruthy("ecsDebug");

const streamer = getCurrentStreamer();
Expand Down Expand Up @@ -1150,7 +1156,7 @@ class UIRoot extends Component {
reason: LeaveReason.createRoom
})
},
{
!isLockedDownDemo && {
id: "user-profile",
label: <FormattedMessage id="more-menu.profile" defaultMessage="Change Name & Avatar" />,
icon: AvatarIcon,
Expand Down Expand Up @@ -1391,7 +1397,8 @@ class UIRoot extends Component {
)}
<PeopleMenuButton
active={this.state.sidebarId === "people"}
onClick={() => this.toggleSidebar("people")}
disabled={isLockedDownDemo}
mikemorran marked this conversation as resolved.
Show resolved Hide resolved
onClick={!isLockedDownDemo ? () => this.toggleSidebar("people") : null}
presencecount={this.state.presenceCount}
/>
{showECSObjectsMenuButton && (
Expand Down Expand Up @@ -1593,14 +1600,18 @@ class UIRoot extends Component {
)}
{entered && (
<>
<AudioPopoverContainer scene={this.props.scene} />
<SharePopoverContainer scene={this.props.scene} hubChannel={this.props.hubChannel} />
<PlacePopoverContainer
scene={this.props.scene}
hubChannel={this.props.hubChannel}
mediaSearchStore={this.props.mediaSearchStore}
showNonHistoriedDialog={this.showNonHistoriedDialog}
/>
{!isLockedDownDemo && (
<>
<AudioPopoverContainer scene={this.props.scene} />
<SharePopoverContainer scene={this.props.scene} hubChannel={this.props.hubChannel} />
<PlacePopoverContainer
scene={this.props.scene}
hubChannel={this.props.hubChannel}
mediaSearchStore={this.props.mediaSearchStore}
showNonHistoriedDialog={this.showNonHistoriedDialog}
/>
</>
)}
{this.props.hubChannel.can("spawn_emoji") && (
<ReactionPopoverContainer
scene={this.props.scene}
Expand All @@ -1609,9 +1620,11 @@ class UIRoot extends Component {
)}
</>
)}
<ChatToolbarButtonContainer
onClick={() => this.toggleSidebar("chat", { chatPrefix: "", chatAutofocus: false })}
/>
{!isLockedDownDemo && (
<ChatToolbarButtonContainer
onClick={() => this.toggleSidebar("chat", { chatPrefix: "", chatAutofocus: false })}
/>
)}
{entered && isMobileVR && (
<ToolbarButton
className={styleUtils.hideLg}
Expand Down
1 change: 1 addition & 0 deletions src/schema.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ features.show_issue_report_dialog = { category = "features", type = "boolean", i
features.show_cloud = { category = "features", type = "boolean", internal = "true" }
features.show_newsletter_signup = { category = "features", type = "boolean", internal = "true" }
features.change_hub_near_room_links = { category = "features", type = "boolean", internal = "true" }
features.is_locked_down_demo_room = { category = "features", type = "string", internal = "true", description = "A comma separated list of hubIds to be designated as demo rooms with simplified UI." }

images.logo = { category = "images", type = "file", name = "Hub Logo", description = "Appears throughout your hub including lobby and loading screens." }
images.logo_dark = { category = "images", type = "file", name = "Hub logo for dark mode", description = "The hub logo which appears for visitors who have dark mode enabled." }
Expand Down
16 changes: 15 additions & 1 deletion src/storage/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Cookies from "js-cookie";
import jwtDecode from "jwt-decode";
import { qsGet } from "../utils/qs_truthy.js";
import detectMobile, { isAndroid, isMobileVR } from "../utils/is-mobile";
import { isLockedDownDemoRoom } from "../utils/hub-utils";

const LOCAL_STORE_KEY = "___hubs_store";
const STORE_STATE_CACHE_KEY = Symbol();
Expand Down Expand Up @@ -318,7 +319,7 @@ export default class Store extends EventTarget {
}

// Regenerate name to encourage users to change it.
if (!this.state.activity.hasChangedName) {
if (!this.state.activity.hasChangedName || isLockedDownDemoRoom()) {
mikemorran marked this conversation as resolved.
Show resolved Hide resolved
this.update({ profile: { displayName: generateRandomName() } });
}
};
Expand Down Expand Up @@ -401,6 +402,19 @@ export default class Store extends EventTarget {
}

update(newState, mergeOpts) {
// Check if in demo room before changing avatar. This feature is meant to prevent any avatarID changes triggered from an avatar.js panel ONLY. "Change Name & Avatar" button in More Menu is disabled at a UI level.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this again, I don't think this is avoiding an avatar update. This is called by the avatar.js page and there we don't have any context about the current hub_id. We just update the store and that event is recived in any other open document that is using the same local storage origin.

It seems that we are processing that here:
https://github.com/mozilla/hubs/blob/b8f775f10da2fdd2b9515adc992050ca7c3cf986/src/scene-entry-manager.js#L180

And there we can correctly get the hub_id so I think we can revert the changes here and add that logic there.

// Waiting for scene to load allows for avatarID to be set from default on scene load.
// TODO: Will need update with switch to bitECS loader
if (
newState.profile !== undefined &&
newState.profile.avatarId !== undefined &&
isLockedDownDemoRoom() &&
AFRAME !== undefined &&
AFRAME.scenes[0].is("loaded")
) {
return;
}

const finalState = merge({ ...this.state, preferences: this._preferences }, newState, mergeOpts);
const { valid, errors } = validator.validate(finalState, SCHEMA);

Expand Down
5 changes: 3 additions & 2 deletions src/systems/name-tag-visibility-system.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { waitForDOMContentLoaded } from "../utils/async-utils";
import { isLockedDownDemoRoom } from "../utils/hub-utils";

export class NameTagVisibilitySystem {
constructor(sceneEl) {
Expand All @@ -8,7 +9,7 @@ export class NameTagVisibilitySystem {
this.lastUpdateTime = Date.now();
this.tick = this.tick.bind(this);
this.onStateChanged = this.onStateChanged.bind(this);
this.nametagVisibility = this.store.state.preferences.nametagVisibility;
this.nametagVisibility = isLockedDownDemoRoom() ? "showNone" : this.store.state.preferences.nametagVisibility;
this.nametagVisibilityDistance = Math.pow(this.store.state.preferences.nametagVisibilityDistance, 2);
waitForDOMContentLoaded().then(() => {
this.avatarRig = document.getElementById("avatar-rig").object3D;
Expand Down Expand Up @@ -62,6 +63,6 @@ export class NameTagVisibilitySystem {

onStateChanged() {
this.nametagVisibilityDistance = Math.pow(this.store.state.preferences.nametagVisibilityDistance, 2);
this.nametagVisibility = this.store.state.preferences.nametagVisibility;
this.nametagVisibility = isLockedDownDemoRoom() ? "showNone" : this.store.state.preferences.nametagVisibility;
}
}
5 changes: 3 additions & 2 deletions src/systems/ui-hotkeys.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { paths } from "./userinput/paths";
import { SOURCES } from "../storage/media-search-store";
import { isLockedDownDemoRoom } from "../utils/hub-utils";

const MEDIA_SEARCH_PATHS = [
paths.actions.mediaSearch1,
Expand All @@ -23,11 +24,11 @@ AFRAME.registerSystem("ui-hotkeys", {
this.userinput = this.el.systems.userinput;
}

if (this.userinput.get(paths.actions.focusChat)) {
if (this.userinput.get(paths.actions.focusChat) && !isLockedDownDemoRoom()) {
mikemorran marked this conversation as resolved.
Show resolved Hide resolved
window.dispatchEvent(new CustomEvent("focus_chat", { detail: { prefix: "" } }));
}

if (this.userinput.get(paths.actions.focusChatCommand)) {
if (this.userinput.get(paths.actions.focusChatCommand) && !isLockedDownDemoRoom()) {
window.dispatchEvent(new CustomEvent("focus_chat", { detail: { prefix: "/" } }));
}

Expand Down
Loading