Skip to content

Commit

Permalink
Merge pull request #6116 from mozilla/add-pronoun-field-for-users
Browse files Browse the repository at this point in the history
feat: Add pronoun field to entry modal for users
  • Loading branch information
nikk15 authored Jun 13, 2023
2 parents c7935ce + cbc829d commit ab4035d
Show file tree
Hide file tree
Showing 13 changed files with 664 additions and 824 deletions.
47 changes: 35 additions & 12 deletions src/components/name-tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ AFRAME.registerComponent("name-tag", {
init() {
this.store = window.APP.store;
this.displayName = null;
this.pronouns = null;
this.identityName = null;
this.isTalking = false;
this.isTyping = false;
Expand All @@ -61,6 +62,7 @@ AFRAME.registerComponent("name-tag", {
this.onModelLoaded = this.onModelLoaded.bind(this);
this.onModelIkFirstTick = this.onModelIkFirstTick.bind(this);
this.onStateChanged = this.onStateChanged.bind(this);
this.updateNametagWidth = this.updateNametagWidth.bind(this);

this.nametag = this.el.object3D;
this.nametagIdentityName = this.el.querySelector(".identityName").object3D;
Expand All @@ -69,6 +71,7 @@ AFRAME.registerComponent("name-tag", {
this.recordingBadge = this.el.querySelector(".recordingBadge").object3D;
this.modBadge = this.el.querySelector(".modBadge").object3D;
this.nametagText = this.el.querySelector(".nametag-text").object3D;
this.pronounsText = this.el.querySelector(".pronouns-text").object3D;

this.handRaised = new THREE.Mesh(handRaisedGeometry, handRaisedMaterial);
this.handRaised.position.set(0, -0.3, 0.001);
Expand Down Expand Up @@ -198,31 +201,33 @@ AFRAME.registerComponent("name-tag", {

updateFromPresenceMeta(presenceMeta) {
this.displayName = presenceMeta.profile.displayName;
this.pronouns = presenceMeta.profile.pronouns;
this.identityName = presenceMeta.profile.identityName;
this.isRecording = !!(presenceMeta.streaming || presenceMeta.recording);
this.isOwner = !!(presenceMeta.roles && presenceMeta.roles.owner);
this.isTyping = !!presenceMeta.typing;
this.isHandRaised = !!presenceMeta.hand_raised;
if (this.isAvatarReady) {
this.updateDisplayName();
this.updatePronouns();
this.updateHandRaised();
this.resizeNameTag();
}
},

updateNametagWidth() {
this.pronounsText.el.components["text"].getSize(this.size);
const pronounsTextSize = this.size.x || 0;
this.nametagText.el.components["text"].getSize(this.size);
this.size.x = Math.max(this.size.x, pronounsTextSize, NAMETAG_MIN_WIDTH);
this.resizeNameTag();
},

updateDisplayName() {
if (this.displayName && this.displayName !== this.prevDisplayName) {
this.nametagText.el.addEventListener(
"text-updated",
() => {
if (this.nametagText.el) {
this.nametagText.el.components["text"].getSize(this.size);
this.size.x = Math.max(this.size.x, NAMETAG_MIN_WIDTH);
this.resizeNameTag();
}
},
{ once: true }
);
this.nametagText.el.addEventListener("text-updated", () => this.updateNametagWidth(), {
once: true
});
if (this.displayName.length > DISPLAY_NAME_LENGTH) {
this.displayName = this.displayName.slice(0, DISPLAY_NAME_LENGTH).concat("...");
}
Expand All @@ -240,6 +245,21 @@ AFRAME.registerComponent("name-tag", {
}
},

updatePronouns() {
if (this.pronouns !== this.prevPronouns) {
this.pronounsText.el.addEventListener("text-updated", () => this.updateNametagWidth(), {
once: true
});
if (this.pronouns.length > DISPLAY_NAME_LENGTH) {
this.pronouns = this.pronouns.slice(0, DISPLAY_NAME_LENGTH).concat("...");
}
this.pronounsText.el.setAttribute("text", {
value: this.pronouns ? `(${this.pronouns})` : ""
});
this.prevPronouns = this.pronouns;
}
},

onModelLoading() {
this.model = null;
this.isAvatarReady = false;
Expand All @@ -262,11 +282,14 @@ AFRAME.registerComponent("name-tag", {
this.avatarAABBSize.y / 2 +
NAMETAG_OFFSET;
this.nametagElPosY = this.nametagHeight + (this.isHandRaised ? NAMETAG_OFFSET : 0);
this.pronounsText.el && this.pronounsText.el.components["text"].getSize(this.size);
const pronounsTextSize = this.size.x;
this.nametagText.el.components["text"].getSize(this.size);
this.size.x = Math.max(this.size.x, NAMETAG_MIN_WIDTH);
this.size.x = Math.max(this.size.x, pronounsTextSize, NAMETAG_MIN_WIDTH);
this.isAvatarReady = true;

this.updateDisplayName();
this.updatePronouns();
this.updateHandRaised();
this.resizeNameTag();
},
Expand Down
1,279 changes: 498 additions & 781 deletions src/hub.html

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/react-components/link-root.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ class LinkRoot extends Component {
.then(response => {
// If there is a profile from the linked device, copy it over if we don't have one yet.
if (response.profile) {
const { hasChangedName } = this.props.store.state.activity;
const { hasChangedNameOrPronouns } = this.props.store.state.activity;

if (!hasChangedName) {
this.props.store.update({ activity: { hasChangedName: true }, profile: response.profile });
if (!hasChangedNameOrPronouns) {
this.props.store.update({ activity: { hasChangedNameOrPronouns: true }, profile: response.profile });
}
}
this.props.store.update({ credentials: response.credentials });
Expand Down
27 changes: 17 additions & 10 deletions src/react-components/profile-entry-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export default class ProfileEntryPanel extends Component {
state = {
avatarId: null,
displayName: null,
avatar: null
avatar: null,
pronouns: null
};

constructor(props) {
Expand All @@ -42,27 +43,29 @@ export default class ProfileEntryPanel extends Component {
}

getStateFromProfile = () => {
const { displayName, avatarId } = this.props.store.state.profile;
return { displayName, avatarId };
const { displayName, avatarId, pronouns } = this.props.store.state.profile;
return { displayName, avatarId, pronouns };
};

storeUpdated = () => this.setState(this.getStateFromProfile());

saveStateAndFinish = e => {
e && e.preventDefault();

const { displayName } = this.props.store.state.profile;
const { hasChangedName } = this.props.store.state.activity;
const { displayName, pronouns } = this.props.store.state.profile;
const { hasChangedNameOrPronouns } = this.props.store.state.activity;

const hasChangedNowOrPreviously = hasChangedName || this.state.displayName !== displayName;
const hasChangedNowOrPreviously =
hasChangedNameOrPronouns || this.state.displayName !== displayName || this.state.pronouns !== pronouns;
this.props.store.update({
activity: {
hasChangedName: hasChangedNowOrPreviously,
hasChangedNameOrPronouns: hasChangedNowOrPreviously,
hasAcceptedProfile: true
},
profile: {
displayName: this.state.displayName,
avatarId: this.state.avatarId
avatarId: this.state.avatarId,
pronouns: this.state.pronouns
}
});
this.props.finished();
Expand All @@ -84,7 +87,7 @@ export default class ProfileEntryPanel extends Component {
};

componentDidMount() {
if (this.nameInput) {
if (this.nameInput || this.pronounsInput) {
// stop propagation so that avatar doesn't move when wasd'ing during text input.
this.nameInput.addEventListener("keydown", this.stopPropagation);
this.nameInput.addEventListener("keypress", this.stopPropagation);
Expand All @@ -105,7 +108,7 @@ export default class ProfileEntryPanel extends Component {

componentWillUnmount() {
this.props.store.removeEventListener("statechanged", this.storeUpdated);
if (this.nameInput) {
if (this.nameInput || this.pronounsInput) {
this.nameInput.removeEventListener("keydown", this.stopPropagation);
this.nameInput.removeEventListener("keypress", this.stopPropagation);
this.nameInput.removeEventListener("keyup", this.stopPropagation);
Expand All @@ -123,10 +126,14 @@ export default class ProfileEntryPanel extends Component {
render() {
const avatarSettingsProps = {
displayNameInputRef: inp => (this.nameInput = inp),
pronounsInputRef: inp => (this.pronounsInput = inp),
disableDisplayNameInput: !!this.props.displayNameOverride,
displayName: this.props.displayNameOverride ? this.props.displayNameOverride : this.state.displayName,
pronouns: this.state.pronouns,
displayNamePattern: this.props.store.schema.definitions.profile.properties.displayName.pattern,
pronounsPattern: this.props.store.schema.definitions.profile.properties.pronouns.pattern,
onChangeDisplayName: e => this.setState({ displayName: e.target.value }),
onChangePronouns: e => this.setState({ pronouns: e.target.value }),
avatarPreview: <AvatarPreview avatarGltfUrl={this.state.avatar && this.state.avatar.gltf_url} />,
onChangeAvatar: e => {
e.preventDefault();
Expand Down
16 changes: 16 additions & 0 deletions src/react-components/room/AvatarSettingsContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ import { FormattedMessage } from "react-intl";

export function AvatarSettingsContent({
displayName,
pronouns,
displayNameInputRef,
pronounsInputRef,
disableDisplayNameInput,
onChangeDisplayName,
onChangePronouns,
avatarPreview,
displayNamePattern,
pronounsPattern,
onChangeAvatar,
...rest
}) {
Expand All @@ -34,6 +38,14 @@ export function AvatarSettingsContent({
}
ref={displayNameInputRef}
/>
<TextInputField
label={<FormattedMessage id="avatar-settings-content.pronouns-label" defaultMessage="Pronouns (optional)" />}
value={pronouns}
pattern={pronounsPattern}
spellCheck="false"
onChange={onChangePronouns}
ref={pronounsInputRef}
/>
<div className={styles.avatarPreviewContainer}>
{avatarPreview || <div />}
<Button type="button" preset="basic" onClick={onChangeAvatar}>
Expand All @@ -48,10 +60,14 @@ export function AvatarSettingsContent({
AvatarSettingsContent.propTypes = {
className: PropTypes.string,
displayName: PropTypes.string,
pronouns: PropTypes.string,
displayNameInputRef: PropTypes.func,
pronounsInputRef: PropTypes.func,
disableDisplayNameInput: PropTypes.bool,
displayNamePattern: PropTypes.string,
pronounsPattern: PropTypes.string,
onChangeDisplayName: PropTypes.func,
onChangePronouns: PropTypes.func,
avatarPreview: PropTypes.node,
onChangeAvatar: PropTypes.func
};
3 changes: 2 additions & 1 deletion src/react-components/room/PeopleSidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ function getPersonName(person, intl) {
id: "people-sidebar.person-name.you",
defaultMessage: "You"
});
const suffix = person.isMe ? `(${you})` : person.profile?.pronouns ? `(${person.profile.pronouns})` : "";

return person.profile.displayName + (person.isMe ? ` (${you})` : "");
return `${person.profile.displayName} ${suffix}`;
}

export function PeopleSidebar({
Expand Down
5 changes: 4 additions & 1 deletion src/react-components/room/UserProfileSidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function UserProfileSidebar({
className,
userId,
displayName,
pronouns,
identityName,
avatarPreview,
hasMicPresence,
Expand Down Expand Up @@ -52,12 +53,13 @@ export function UserProfileSidebar({
const newLevel = calcLevel(multiplier);
return (
<Sidebar
title={identityName ? `${displayName} (${identityName})` : displayName}
beforeTitle={showBackButton ? <BackButton onClick={onBack} /> : <CloseButton onClick={onClose} />}
className={className}
{...rest}
>
<Column center padding>
<h2 className={styles.displayName}>{identityName ? `${displayName} (${identityName})` : displayName}</h2>
{pronouns && <span className={styles.pronouns}>{pronouns}</span>}
<div className={styles.avatarPreviewContainer}>{avatarPreview || <div />}</div>
{hasMicPresence && (
<div className={styles.sliderContainer}>
Expand Down Expand Up @@ -148,6 +150,7 @@ UserProfileSidebar.propTypes = {
className: PropTypes.string,
userId: PropTypes.string,
displayName: PropTypes.string,
pronouns: PropTypes.string,
identityName: PropTypes.string,
avatarPreview: PropTypes.node,
hasMicPresence: PropTypes.bool,
Expand Down
11 changes: 10 additions & 1 deletion src/react-components/room/UserProfileSidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,13 @@

:local(.slider-input-container) {
width: 209px;
}
}

:local(.displayName) {
font-weight: 400;
color: theme.$text1-color;
}

:local(.pronouns) {
color: theme.$text2-color;
}
Loading

0 comments on commit ab4035d

Please sign in to comment.