Files
expo-cli/packages/dev-tools/components/ProjectManagerSidebarOptions.js
Łukasz Kosmaty b5c59a7910 [Interstitial page] Fix QR on web UI & fallback to SDK version if the runtime version wasn't defined (#4214)
# Why

Fixes that QR code on web UI pointed to the `Expo Go` directly instead of to the interstitial page.
Fallback to the SDK version if the runtime version wasn't defined. 

# How

- Extended the dev graphQL server to serve Interstitial page URL if available. 

# Test Plan

- runs the local version of the CLI and confirms that the web QR code points to the correct place.
- checks if the SDK version was detected when the runtime version isn't available.
2022-02-16 13:17:37 +01:00

247 lines
6.9 KiB
JavaScript

import * as Constants from 'app/common/constants';
import * as SVG from 'app/common/svg';
import ContentGroup from 'app/components/ContentGroup';
import InputWithButton from 'app/components/InputWithButton';
import NetworkGroupButton from 'app/components/NetworkGroupButton';
import QRCode from 'app/components/QRCode';
import SettingsControl from 'app/components/SettingsControl';
import copyToClipboard from 'copy-to-clipboard';
import * as React from 'react';
import { css } from 'react-emotion';
const STYLES_CONNECTION_SECTION = css`
display: flex;
align-items: center;
justify-content: space-between;
`;
const STYLES_CONNECTION_SECTION_LEFT = css`
min-width: 25%;
width: 100%;
`;
const STYLES_CONNECTION_SECTION_RIGHT = css`
flex-shrink: 0;
`;
const STYLES_URL_SECTION = css`
padding: 16px;
`;
const STYLES_URL_SECTION_BOTTOM = css`
font-family: ${Constants.fontFamilies.regular};
font-size: 12px;
margin-top: 16px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
`;
const STYLES_URL_SECTION_BOTTOM_LEFT = css`
flex-shrink: 0;
padding-right: 8px;
`;
const STYLES_URL_SECTION_BOTTOM_RIGHT = css`
font-family: ${Constants.fontFamilies.mono};
font-size: 10px;
padding-bottom: 3px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
min-width: 25%;
width: 100%;
`;
const STYLES_QR_SECTION = css`
padding-top: 16px;
`;
const STYLES_SUBTITLE = css`
font-family: ${Constants.fontFamilies.mono};
color: #555555;
font-size: 10px;
text-transform: uppercase;
margin-bottom: 8px;
`;
const STYLES_CONTENT_GROUP = css`
color: currentColor;
text-decoration: none;
border-bottom: 1px solid ${Constants.colors.border};
font-family: ${Constants.fontFamilies.demi};
height: 32px;
padding: 0 16px 0 16px;
display: flex;
justify-content: space-between;
align-items: center;
transition: 200ms ease all;
cursor: pointer;
:hover {
background: ${Constants.colors.primary};
color: ${Constants.colors.white};
}
`;
const STYLES_CONTENT_GROUP_DISABLED = css`
opacity: 0.5;
cursor: not-allowed;
:hover {
background: unset;
color: currentColor;
}
`;
const STYLES_CONTENT_GROUP_LEFT = css`
min-width: 25%;
width: 100%;
`;
const STYLES_CONTENT_GROUP_RIGHT = css`
flex-shrink: 0;
display: inline-flex;
align-items: center;
justify-content: center;
`;
function SidebarOption({ children, onClick, tooltip, isDisabled = false }) {
return (
<div
className={`
${STYLES_CONTENT_GROUP}
${isDisabled ? STYLES_CONTENT_GROUP_DISABLED : ''}
`}
title={tooltip}
onClick={isDisabled ? undefined : onClick}>
<span className={STYLES_CONTENT_GROUP_LEFT}>{children}</span>
</div>
);
}
function PlatformSidebarOption({ platform, ...props }) {
return (
<SidebarOption
tooltip={
props.isDisabled
? `Add '${platform}' to the 'platforms' array in the project app.json to enable this platform`
: ''
}
{...props}
/>
);
}
export default class ProjectManagerSidebarOptions extends React.Component {
state = { isSendFormVisible: false, showCopiedMessage: false };
_handleShowPublishView = () => {
this.props.onUpdateState({
isPublishing: !this.props.isPublishing,
isActiveDeviceIOS: false,
isActiveDeviceAndroid: false,
});
};
_handleCopyLink = () => {
copyToClipboard(this.props.url, {});
this.setState({ showCopiedMessage: true });
setTimeout(() => {
this.setState({ showCopiedMessage: false });
}, 2000);
};
_handleSendHeaderClick = () => {
this.setState(state => ({ isSendFormVisible: !state.isSendFormVisible }));
};
render() {
const { showCopiedMessage, isSendFormVisible } = this.state;
const isDisabled = !this.props.url;
const sendHeader = (
<SidebarOption onClick={this._handleSendHeaderClick}>Send link with email…</SidebarOption>
);
return (
<div>
<PlatformSidebarOption
platform="android"
onClick={this.props.onSimulatorClickAndroid}
isDisabled={this.props.isAndroidDisabled}>
Run on Android device/emulator
</PlatformSidebarOption>
<PlatformSidebarOption
platform="ios"
onClick={this.props.onSimulatorClickIOS}
isDisabled={this.props.isIosDisabled}>
Run on iOS simulator
</PlatformSidebarOption>
<PlatformSidebarOption
platform="web"
onClick={this.props.onStartWebClick}
isDisabled={this.props.isWebDisabled}>
Run in web browser
</PlatformSidebarOption>
<ContentGroup header={sendHeader} isActive={isSendFormVisible}>
<InputWithButton
placeholder="Enter email address"
value={this.props.recipient}
onChange={this.props.onRecipientChange}
onValidation={this.props.onEmailOrNumberValidation}
onSubmit={this.props.onSubmitPhoneNumberOrEmail}>
Send
</InputWithButton>
</ContentGroup>
{this.props.user ? (
<div className={STYLES_CONTENT_GROUP} onClick={this._handleShowPublishView}>
<span className={STYLES_CONTENT_GROUP_LEFT}>Publish or republish project…</span>
<span className={STYLES_CONTENT_GROUP_RIGHT}>
<SVG.Arrow size="16px" />
</span>
</div>
) : null}
<div className={STYLES_URL_SECTION}>
<SettingsControl
onClick={this.props.onToggleProductionMode}
isActive={this.props.isProduction}>
Production Mode
</SettingsControl>
<div className={STYLES_CONNECTION_SECTION}>
<span className={STYLES_CONNECTION_SECTION_LEFT}>
<div className={STYLES_SUBTITLE} style={{ marginBottom: 0 }}>
Connection
</div>
</span>
<span className={STYLES_CONNECTION_SECTION_RIGHT}>
<NetworkGroupButton
activeState={this.props.hostType}
onHostTypeClick={this.props.onHostTypeClick}
onUpdateState={this.props.onUpdateState}
loading={this.props.hostTypeLoading}
/>
</span>
</div>
<div className={STYLES_URL_SECTION_BOTTOM} title="Click to copy to clipboard">
<div className={STYLES_URL_SECTION_BOTTOM_LEFT} onClick={this._handleCopyLink}>
<SVG.Link size="12px" />
</div>
<div className={STYLES_URL_SECTION_BOTTOM_RIGHT} onClick={this._handleCopyLink}>
{!isDisabled && !this.props.hostTypeLoading ? this.props.url : '-'}
</div>
{showCopiedMessage ? <p>Copied!</p> : null}
</div>
<div className={STYLES_QR_SECTION}>
<QRCode url={this.props.interstitialPageUrl ?? this.props.url} />
</div>
</div>
</div>
);
}
}