diff --git a/src/assets/stylesheets/scene-ui.scss b/src/assets/stylesheets/scene-ui.scss index bd3abf0a6d82cf898081da35c23add7ce692b024..aa9a809de55b22e1d36abd51a6a9e9b7fe7c82ab 100644 --- a/src/assets/stylesheets/scene-ui.scss +++ b/src/assets/stylesheets/scene-ui.scss @@ -38,10 +38,6 @@ justify-content: center; pointer-events: auto; - button { - @extend %action-button; - border: 0; - } } :local(.logoTagline) { @@ -147,3 +143,23 @@ width: 200px; } } + +:local(.createButtons) { + position: relative; + display: flex; +} + +:local(.createButton) { + @extend %action-button; + width: 100%; + border: 0; +} + +:local(.optionsButton) { + @extend %fa-icon-button; + @extend %fa-icon-big; + position: absolute; + right: 10px; + top: -12px; + color: white; +} diff --git a/src/assets/stylesheets/scene.scss b/src/assets/stylesheets/scene.scss index 44e6591aacfa994bb79a4a0354b129ae171c4741..49f588251e3067da70aae0151e0463d6508910e1 100644 --- a/src/assets/stylesheets/scene.scss +++ b/src/assets/stylesheets/scene.scss @@ -1,2 +1,3 @@ @import 'shared'; @import 'loader'; +@import 'info-dialog'; diff --git a/src/hub.js b/src/hub.js index f16044fa877f9afc61ee9c4b4b5a7aedd321a5fa..f877d9df0172d74d1f5232ca418e0e033b95f106 100644 --- a/src/hub.js +++ b/src/hub.js @@ -433,7 +433,7 @@ document.addEventListener("DOMContentLoaded", async () => { presenceLogEntries.splice(presenceLogEntries.indexOf(entry), 1); remountUI({ presenceLogEntries }); }, 5000); - }, entryManager.hasEntered() ? 10000 : 30000); // Fade out things faster once entered. + }, 20000); }; let isInitialSync = true; diff --git a/src/react-components/create-room-dialog.js b/src/react-components/create-room-dialog.js index 756cc9bf43736059999a1a66b2fdfe5d856a4e96..a42a2f36be7fea6bdfef0d74c6120ce59e24df01 100644 --- a/src/react-components/create-room-dialog.js +++ b/src/react-components/create-room-dialog.js @@ -4,8 +4,9 @@ import DialogContainer from "./dialog-container.js"; const HUB_NAME_PATTERN = "^[A-Za-z0-9-'\":!@#$%^&*(),.?~ ]{4,64}$"; -export default class CreateObjectDialog extends Component { +export default class CreateRoomDialog extends Component { static propTypes = { + includeScenePrompt: PropTypes.bool, onCustomScene: PropTypes.func, onClose: PropTypes.func }; @@ -25,7 +26,12 @@ export default class CreateObjectDialog extends Component { return ( <DialogContainer title="Create a Room" onClose={onClose} {...other}> <div> - <div>Choose a name and GLTF URL for your room's scene:</div> + {this.props.includeScenePrompt ? ( + <div>Choose a name and GLTF URL for your room's scene:</div> + ) : ( + <div>Choose a name for your room:</div> + )} + <form onSubmit={onCustomSceneClicked}> <div className="custom-scene-form"> <input @@ -38,16 +44,18 @@ export default class CreateObjectDialog extends Component { onChange={e => this.setState({ customRoomName: e.target.value })} required /> - <input - type="url" - placeholder="URL to Scene GLTF or GLB (Optional)" - className="custom-scene-form__link_field" - value={this.state.customSceneUrl} - onChange={e => this.setState({ customSceneUrl: e.target.value })} - /> + {this.props.includeScenePrompt && ( + <input + type="url" + placeholder="URL to Scene GLTF or GLB (Optional)" + className="custom-scene-form__link_field" + value={this.state.customSceneUrl} + onChange={e => this.setState({ customSceneUrl: e.target.value })} + /> + )} <div className="custom-scene-form__buttons"> <button className="custom-scene-form__action-button"> - <span>create</span> + <span>Create Room</span> </button> </div> </div> diff --git a/src/react-components/hub-create-panel.js b/src/react-components/hub-create-panel.js index 8a9ca35e28edb3d99c3685e483e3f031c755c557..640f00d5d790516e0d8cd2d71f9bb71f1a13e89c 100644 --- a/src/react-components/hub-create-panel.js +++ b/src/react-components/hub-create-panel.js @@ -235,6 +235,7 @@ class HubCreatePanel extends Component { </form> {this.state.showCustomSceneDialog && ( <CreateRoomDialog + includeScenePrompt={true} onClose={() => this.setState({ showCustomSceneDialog: false })} onCustomScene={(name, url) => { this.setState({ showCustomSceneDialog: false, name: name, customSceneUrl: url }, () => this.createHub()); diff --git a/src/react-components/scene-ui.js b/src/react-components/scene-ui.js index 2db97a04c5a0d56824f8b4677474b6ddb97540d9..cb724d21b5cac27bc15807e4e80a82b13d94e50a 100644 --- a/src/react-components/scene-ui.js +++ b/src/react-components/scene-ui.js @@ -8,6 +8,9 @@ import hubLogo from "../assets/images/hub-preview-white.png"; import spokeLogo from "../assets/images/spoke_logo_black.png"; import { getReticulumFetchUrl } from "../utils/phoenix-utils"; import { generateHubName } from "../utils/name-generation"; +import CreateRoomDialog from "./create-room-dialog.js"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faEllipsisH } from "@fortawesome/free-solid-svg-icons/faEllipsisH"; import { lang, messages } from "../utils/i18n"; @@ -25,7 +28,8 @@ class SceneUI extends Component { }; state = { - showScreenshot: false + showScreenshot: false, + showCustomRoomDialog: false }; constructor(props) { @@ -48,7 +52,7 @@ class SceneUI extends Component { } createRoom = async () => { - const payload = { hub: { name: generateHubName(), scene_id: this.props.sceneId } }; + const payload = { hub: { name: this.state.customRoomName || generateHubName(), scene_id: this.props.sceneId } }; const createUrl = getReticulumFetchUrl("/api/v1/hubs"); const res = await fetch(createUrl, { @@ -93,9 +97,14 @@ class SceneUI extends Component { <div className={styles.logoTagline}> <FormattedMessage id="scene.logo_tagline" /> </div> - <button onClick={this.createRoom}> - <FormattedMessage id="scene.create_button" /> - </button> + <div className={styles.createButtons}> + <button className={styles.createButton} onClick={this.createRoom}> + <FormattedMessage id="scene.create_button" /> + </button> + <button className={styles.optionsButton} onClick={() => this.setState({ showCustomRoomDialog: true })}> + <FontAwesomeIcon icon={faEllipsisH} /> + </button> + </div> <a href={tweetLink} rel="noopener noreferrer" target="_blank" className={styles.tweetButton}> <img src="../assets/images/twitter.svg" /> <div> @@ -114,6 +123,15 @@ class SceneUI extends Component { <img src={spokeLogo} /> </a> </div> + {this.state.showCustomRoomDialog && ( + <CreateRoomDialog + includeScenePrompt={false} + onClose={() => this.setState({ showCustomRoomDialog: false })} + onCustomScene={name => { + this.setState({ showCustomRoomDialog: false, customRoomName: name }, () => this.createRoom()); + }} + /> + )} </div> </IntlProvider> );