diff --git a/src/assets/stylesheets/2d-hud.scss b/src/assets/stylesheets/2d-hud.scss index 263569b58b04e599868e601cd0c960cee543c843..475e4615923a6e1359984b1c6ea9be72e9242947 100644 --- a/src/assets/stylesheets/2d-hud.scss +++ b/src/assets/stylesheets/2d-hud.scss @@ -1,3 +1,5 @@ +@import 'shared'; + :local(.container) { position: absolute; top: 10px; @@ -37,9 +39,24 @@ width: 40px; height: 40px; background-size: 100%; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; cursor: pointer; } +:local(.addMediaButton) { + position: absolute; + top: 90px; + background-color: #404040; +} + +:local(.iconButton.small) { + width: 30px; + height: 30px; +} + :local(.iconButton.large) { width: 80px; height: 80px; diff --git a/src/assets/stylesheets/info-dialog.scss b/src/assets/stylesheets/info-dialog.scss index 690db56c83a0fee301b0bb95952f6a1622ec9140..58b2259fc71f0097d8f2b032b1fcc9bfa5305251 100644 --- a/src/assets/stylesheets/info-dialog.scss +++ b/src/assets/stylesheets/info-dialog.scss @@ -79,7 +79,7 @@ } } -.invite-form { +.invite-form, .add-media-form { display: flex; flex-direction: column; align-items: center; diff --git a/src/react-components/2d-hud.js b/src/react-components/2d-hud.js index 141606a83d121f0a280ac5ac6b6d997856f7fc1e..952de6cf8b8b18a57c0cb0515364fc68ffa2372e 100644 --- a/src/react-components/2d-hud.js +++ b/src/react-components/2d-hud.js @@ -4,7 +4,18 @@ import cx from "classnames"; import styles from "../assets/stylesheets/2d-hud.scss"; -const TwoDHUD = ({ muted, frozen, spacebubble, onToggleMute, onToggleFreeze, onToggleSpaceBubble }) => ( +import FontAwesomeIcon from "@fortawesome/react-fontawesome"; +import faPlus from "@fortawesome/fontawesome-free-solid/faPlus"; + +const TwoDHUD = ({ + muted, + frozen, + spacebubble, + onToggleMute, + onToggleFreeze, + onToggleSpaceBubble, + onClickAddMedia +}) => ( <div className={styles.container}> <div className={cx("ui-interactive", styles.panel, styles.left)}> <div @@ -25,6 +36,13 @@ const TwoDHUD = ({ muted, frozen, spacebubble, onToggleMute, onToggleFreeze, onT onClick={onToggleSpaceBubble} /> </div> + <div + className={cx("ui-interactive", styles.iconButton, styles.small, styles.addMediaButton)} + title="Add Media" + onClick={onClickAddMedia} + > + <FontAwesomeIcon icon={faPlus} /> + </div> </div> ); @@ -34,7 +52,8 @@ TwoDHUD.propTypes = { spacebubble: PropTypes.bool, onToggleMute: PropTypes.func, onToggleFreeze: PropTypes.func, - onToggleSpaceBubble: PropTypes.func + onToggleSpaceBubble: PropTypes.func, + onClickAddMedia: PropTypes.func }; export default TwoDHUD; diff --git a/src/react-components/info-dialog.js b/src/react-components/info-dialog.js index 7a48099b400203abcadced08ac5c5df6cb41552d..4b432e01cb5c04116e6c199d3a873eea8c2540c1 100644 --- a/src/react-components/info-dialog.js +++ b/src/react-components/info-dialog.js @@ -8,6 +8,8 @@ import LinkDialog from "./link-dialog.js"; // TODO i18n +let lastAddMediaUrl = ""; + class InfoDialog extends Component { static dialogTypes = { slack: Symbol("slack"), @@ -17,12 +19,14 @@ class InfoDialog extends Component { report: Symbol("report"), help: Symbol("help"), link: Symbol("link"), - webvr_recommend: Symbol("webvr_recommend") + webvr_recommend: Symbol("webvr_recommend"), + add_media: Symbol("add_media") }; static propTypes = { dialogType: PropTypes.oneOf(Object.values(InfoDialog.dialogTypes)), onCloseDialog: PropTypes.func, onSubmittedEmail: PropTypes.func, + onAddMedia: PropTypes.func, linkCode: PropTypes.string }; @@ -33,14 +37,17 @@ class InfoDialog extends Component { this.shareLink = `${loc.protocol}//${loc.host}${loc.pathname}`; this.onKeyDown = this.onKeyDown.bind(this); this.onContainerClicked = this.onContainerClicked.bind(this); + this.onAddMediaClicked = this.onAddMediaClicked.bind(this); } componentDidMount() { window.addEventListener("keydown", this.onKeyDown); + this.setState({ addMediaUrl: lastAddMediaUrl }); } componentWillUnmount() { window.removeEventListener("keydown", this.onKeyDown); + lastAddMediaUrl = this.state.addMediaUrl; } onKeyDown(e) { @@ -55,6 +62,11 @@ class InfoDialog extends Component { } } + onAddMediaClicked() { + this.props.onAddMedia(this.state.addMediaUrl); + this.props.onCloseDialog(); + } + shareLinkClicked = () => { navigator.share({ title: document.title, @@ -70,7 +82,8 @@ class InfoDialog extends Component { state = { mailingListEmail: "", mailingListPrivacy: false, - copyLinkButtonText: "Copy" + copyLinkButtonText: "Copy", + addMediaUrl: "" }; signUpForMailingList = async e => { @@ -155,6 +168,31 @@ class InfoDialog extends Component { </div> ); break; + case InfoDialog.dialogTypes.add_media: + dialogTitle = "Add Media"; + dialogBody = ( + <div> + <div>Tip: You can paste media urls directly into hubs with ctrl+v</div> + <form onSubmit={this.onAddMediaClicked}> + <div className="add-media-form"> + <input + type="url" + placeholder="Image or Video URL" + className="add-media-form__link_field" + value={this.state.addMediaUrl} + onChange={e => this.setState({ addMediaUrl: e.target.value })} + required + /> + <div className="add-media-form__buttons"> + <button className="add-media-form__action-button"> + <span>Add</span> + </button> + </div> + </div> + </form> + </div> + ); + break; case InfoDialog.dialogTypes.updates: dialogTitle = ""; dialogBody = ( diff --git a/src/react-components/ui-root.js b/src/react-components/ui-root.js index cb69c63436f8d9d72479fc10e9ce541d5fde2ceb..5014d6af494e2f4ea551e8eb174c03b381db8c79 100644 --- a/src/react-components/ui-root.js +++ b/src/react-components/ui-root.js @@ -319,7 +319,7 @@ class UIRoot extends Component { mediaSource: "screen", // Work around BMO 1449832 by calculating the width. This will break for multi monitors if you share anything // other than your current monitor that has a different aspect ratio. - width: screen.width / screen.height * 720, + width: (screen.width / screen.height) * 720, height: 720, frameRate: 30 } @@ -514,6 +514,10 @@ class UIRoot extends Component { this.setState({ infoDialogType: null, linkCode: null, linkCodeCancel: null }); }; + handleAddMedia = url => { + this.props.scene.emit("add_media", url); + }; + render() { if (this.state.exited || this.props.roomUnavailableReason || this.props.platformUnsupportedReason) { let subtitle = null; @@ -818,6 +822,7 @@ class UIRoot extends Component { linkCode={this.state.linkCode} onSubmittedEmail={() => this.setState({ infoDialogType: InfoDialog.dialogTypes.email_submitted })} onCloseDialog={this.handleCloseDialog} + onAddMedia={this.handleAddMedia} /> {this.state.entryStep === ENTRY_STEPS.finished && ( @@ -855,6 +860,7 @@ class UIRoot extends Component { onToggleMute={this.toggleMute} onToggleFreeze={this.toggleFreeze} onToggleSpaceBubble={this.toggleSpaceBubble} + onClickAddMedia={() => this.setState({ infoDialogType: InfoDialog.dialogTypes.add_media })} /> <Footer hubName={this.props.hubName}