diff --git a/src/assets/translations.data.json b/src/assets/translations.data.json index 0201cf0fca4a81f60217ab97679f6f2e7316fc43..79d11599544849a83f9982617dafddd3bb6c268a 100644 --- a/src/assets/translations.data.json +++ b/src/assets/translations.data.json @@ -3,6 +3,7 @@ "entry.screen-prefix": "Enter on ", "entry.desktop-screen": "Screen", "entry.mobile-screen": "Phone", + "entry.mobile-safari": "Safari", "entry.generic-prefix": "Enter in ", "entry.generic-medium": "VR", "entry.generic-subtitle-desktop": "Oculus or SteamVR", diff --git a/src/react-components/entry-buttons.js b/src/react-components/entry-buttons.js index 9e8302b3c7bbf9bd44edbaf6538100f11abf3fb8..f2551df70f99813c5e74be91e7e627de3374feab 100644 --- a/src/react-components/entry-buttons.js +++ b/src/react-components/entry-buttons.js @@ -87,6 +87,17 @@ export const DaydreamEntryButton = props => { return <EntryButton {...entryButtonProps} />; }; +export const SafariEntryButton = props => { + const entryButtonProps = { + ...props, + iconSrc: MobileScreenEntryImg, + prefixMessageId: "entry.screen-prefix", + mediumMessageId: "entry.mobile-safari" + }; + + return <EntryButton {...entryButtonProps} />; +}; + export const DeviceEntryButton = props => { const entryButtonProps = { ...props, diff --git a/src/react-components/info-dialog.js b/src/react-components/info-dialog.js index 7a48099b400203abcadced08ac5c5df6cb41552d..a04127ff74ff2b4722d0a2fbe1a99dd07568efc0 100644 --- a/src/react-components/info-dialog.js +++ b/src/react-components/info-dialog.js @@ -13,6 +13,7 @@ class InfoDialog extends Component { slack: Symbol("slack"), email_submitted: Symbol("email_submitted"), invite: Symbol("invite"), + safari: Symbol("safari"), updates: Symbol("updates"), report: Symbol("report"), help: Symbol("help"), @@ -62,8 +63,8 @@ class InfoDialog extends Component { }); }; - copyLinkClicked = () => { - copy(this.shareLink); + copyLinkClicked = link => { + copy(link); this.setState({ copyLinkButtonText: "Copied!" }); }; @@ -147,7 +148,35 @@ class InfoDialog extends Component { <span>Share</span> </button> )} - <button className="invite-form__action-button" onClick={this.copyLinkClicked}> + <button + className="invite-form__action-button" + onClick={this.copyLinkClicked.bind(this, this.shareLink)} + > + <span>{this.state.copyLinkButtonText}</span> + </button> + </div> + </div> + </div> + ); + break; + case InfoDialog.dialogTypes.safari: + dialogTitle = "Open in Safari"; + dialogBody = ( + <div> + <div>Hubs does not support your current browser on iOS. Copy and paste this link directly in Safari.</div> + <div className="invite-form"> + <input + type="text" + readOnly + onFocus={e => e.target.select()} + value={document.location} + className="invite-form__link_field" + /> + <div className="invite-form__buttons"> + <button + className="invite-form__action-button" + onClick={this.copyLinkClicked.bind(this, document.location)} + > <span>{this.state.copyLinkButtonText}</span> </button> </div> diff --git a/src/react-components/ui-root.js b/src/react-components/ui-root.js index c4f146d2232360f421e5f79f756877c8a5fddc18..9b6c10ea2149fd02899fe217a2ba89b2c33d2187 100644 --- a/src/react-components/ui-root.js +++ b/src/react-components/ui-root.js @@ -11,7 +11,13 @@ import screenfull from "screenfull"; import { lang, messages } from "../utils/i18n"; import AutoExitWarning from "./auto-exit-warning"; -import { TwoDEntryButton, DeviceEntryButton, GenericEntryButton, DaydreamEntryButton } from "./entry-buttons.js"; +import { + TwoDEntryButton, + DeviceEntryButton, + GenericEntryButton, + DaydreamEntryButton, + SafariEntryButton +} from "./entry-buttons.js"; import { ProfileInfoHeader } from "./profile-info-header.js"; import ProfileEntryPanel from "./profile-entry-panel"; import InfoDialog from "./info-dialog.js"; @@ -260,6 +266,10 @@ class UIRoot extends Component { await this.performDirectEntryFlow(false); }; + linkSafari = async () => { + this.setState({ infoDialogType: InfoDialog.dialogTypes.safari }); + }; + enterVR = async () => { if (this.props.availableVREntryTypes.generic !== VR_DEVICE_AVAILABILITY.maybe) { await this.performDirectEntryFlow(true); @@ -616,9 +626,12 @@ class UIRoot extends Component { this.state.entryStep === ENTRY_STEPS.start ? ( <div className="entry-panel"> <div className="entry-panel__button-container"> - {this.props.availableVREntryTypes.screen !== VR_DEVICE_AVAILABILITY.no && ( + {this.props.availableVREntryTypes.screen === VR_DEVICE_AVAILABILITY.yes && ( <TwoDEntryButton onClick={this.enter2D} /> )} + {this.props.availableVREntryTypes.safari === VR_DEVICE_AVAILABILITY.maybe && ( + <SafariEntryButton onClick={this.linkSafari} /> + )} {this.props.availableVREntryTypes.generic !== VR_DEVICE_AVAILABILITY.no && ( <GenericEntryButton onClick={this.enterVR} /> )} diff --git a/src/utils/vr-caps-detect.js b/src/utils/vr-caps-detect.js index 224f1bb49ba60a0627808a73dc6c3139d7df8aac..8953f12a86f24e9848c08e3619d718a2b0eda615 100644 --- a/src/utils/vr-caps-detect.js +++ b/src/utils/vr-caps-detect.js @@ -57,8 +57,16 @@ export async function getAvailableVREntryTypes() { const isDaydreamCapableBrowser = !!(isWebVRCapableBrowser && browser.name === "chrome" && !isSamsungBrowser); const isIDevice = ["iPhone", "iPad", "iPod"].indexOf(deviceDetect.device) > -1; const isFirefoxBrowser = browser.name === "firefox"; + const isUIWebView = typeof navigator.mediaDevices === "undefined"; + + const safari = isIDevice + ? !isUIWebView ? VR_DEVICE_AVAILABILITY.yes : VR_DEVICE_AVAILABILITY.maybe + : VR_DEVICE_AVAILABILITY.no; + + const screen = isInHMD + ? VR_DEVICE_AVAILABILITY.no + : isIDevice && isUIWebView ? VR_DEVICE_AVAILABILITY.maybe : VR_DEVICE_AVAILABILITY.yes; - const screen = isInHMD ? VR_DEVICE_AVAILABILITY.no : VR_DEVICE_AVAILABILITY.yes; let generic = mobiledetect.mobile() ? VR_DEVICE_AVAILABILITY.no : VR_DEVICE_AVAILABILITY.maybe; let cardboard = VR_DEVICE_AVAILABILITY.no; @@ -107,5 +115,5 @@ export async function getAvailableVREntryTypes() { } } - return { screen, generic, gearvr, daydream, cardboard, isInHMD }; + return { screen, generic, gearvr, daydream, cardboard, isInHMD, safari }; }