diff --git a/desktop/plugins/hermesdebuggerrn/Banner.tsx b/desktop/plugins/hermesdebuggerrn/Banner.tsx
new file mode 100644
index 000000000..ce4d3918e
--- /dev/null
+++ b/desktop/plugins/hermesdebuggerrn/Banner.tsx
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @format
+ */
+
+import React from 'react';
+import {shell} from 'electron';
+import {styled, colors, FlexRow, Text, GK} from 'flipper';
+
+const BannerContainer = styled(FlexRow)({
+ height: '30px',
+ width: '100%',
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: '#2bb673', // Hermes green.
+});
+
+const BannerText = styled(Text)({
+ color: colors.white,
+ fontSize: 14,
+ lineHeight: '20px',
+});
+
+const BannerLink = styled(CustomLink)({
+ color: colors.white,
+ textDecoration: 'underline',
+ '&:hover': {
+ cursor: 'pointer',
+ color: '#303846',
+ },
+});
+
+const StyledLink = styled.span({
+ '&:hover': {
+ cursor: 'pointer',
+ },
+});
+
+StyledLink.displayName = 'CustomLink:StyledLink';
+
+function CustomLink(props: {
+ href: string;
+ className?: string;
+ children?: React.ReactNode;
+ style?: React.CSSProperties;
+}) {
+ return (
+ shell.openExternal(props.href)}
+ style={props.style}>
+ {props.children || props.href}
+
+ );
+}
+
+export const isBannerEnabled: () => boolean = function () {
+ return GK.get('flipper_plugin_hermes_debugger_survey');
+};
+
+export default function Banner() {
+ if (!GK.get('flipper_plugin_hermes_debugger_survey')) {
+ return null;
+ }
+ return (
+
+
+ Help us improve your debugging experience with this{' '}
+
+ single page survey
+
+ !
+
+
+ );
+}
diff --git a/desktop/plugins/hermesdebuggerrn/ChromeDevTools.tsx b/desktop/plugins/hermesdebuggerrn/ChromeDevTools.tsx
index 37db35061..24cb98df6 100644
--- a/desktop/plugins/hermesdebuggerrn/ChromeDevTools.tsx
+++ b/desktop/plugins/hermesdebuggerrn/ChromeDevTools.tsx
@@ -8,6 +8,7 @@
*/
import React from 'react';
+import {styled, colors, FlexColumn} from 'flipper';
import electron from 'electron';
@@ -17,7 +18,10 @@ const devToolsNodeId = (url: string) =>
// TODO: build abstractionf or this: T62306732
const TARGET_CONTAINER_ID = 'flipper-out-of-contents-container'; // should be a hook in the future
-function createDevToolsNode(url: string): HTMLElement {
+function createDevToolsNode(
+ url: string,
+ marginTop: string | null,
+): HTMLElement {
const existing = findDevToolsNode(url);
if (existing) {
return existing;
@@ -40,6 +44,11 @@ function createDevToolsNode(url: string): HTMLElement {
iframe.src = url.replace(/^chrome-/, '');
wrapper.appendChild(iframe);
+
+ if (marginTop) {
+ document.getElementById(TARGET_CONTAINER_ID)!.style.marginTop = marginTop;
+ }
+
document.getElementById(TARGET_CONTAINER_ID)!.appendChild(wrapper);
return wrapper;
}
@@ -61,15 +70,24 @@ function detachDevTools(devToolsNode: HTMLElement | null) {
}
}
+const EmptyContainer = styled(FlexColumn)({
+ height: '100%',
+ width: '100%',
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: colors.light02,
+});
+
type ChromeDevToolsProps = {
url: string;
+ marginTop: string | null;
};
export default class ChromeDevTools extends React.Component<
ChromeDevToolsProps
> {
- createDevTools(url: string) {
- const devToolsNode = createDevToolsNode(url);
+ createDevTools(url: string, marginTop: string | null) {
+ const devToolsNode = createDevToolsNode(url, marginTop);
attachDevTools(devToolsNode);
}
@@ -78,7 +96,7 @@ export default class ChromeDevTools extends React.Component<
}
componentDidMount() {
- this.createDevTools(this.props.url);
+ this.createDevTools(this.props.url, this.props.marginTop);
}
componentWillUnmount() {
@@ -90,11 +108,11 @@ export default class ChromeDevTools extends React.Component<
const newUrl = this.props.url;
if (oldUrl != newUrl) {
this.hideDevTools(oldUrl);
- this.createDevTools(newUrl);
+ this.createDevTools(newUrl, this.props.marginTop);
}
}
render() {
- return
;
+ return ;
}
}
diff --git a/desktop/plugins/hermesdebuggerrn/index.tsx b/desktop/plugins/hermesdebuggerrn/index.tsx
index 250cb3d80..6d57459f0 100644
--- a/desktop/plugins/hermesdebuggerrn/index.tsx
+++ b/desktop/plugins/hermesdebuggerrn/index.tsx
@@ -8,8 +8,16 @@
*/
import React from 'react';
-import {FlipperDevicePlugin, Device} from 'flipper';
+import {
+ FlipperDevicePlugin,
+ Device,
+ styled,
+ colors,
+ FlexRow,
+ FlexColumn,
+} from 'flipper';
import LaunchScreen from './LaunchScreen';
+import Banner, {isBannerEnabled} from './Banner';
import SelectScreen from './SelectScreen';
import ErrorScreen from './ErrorScreen';
import ChromeDevTools from './ChromeDevTools';
@@ -36,6 +44,22 @@ type State = Readonly<{
error?: Error | null;
}>;
+const Content = styled(FlexRow)({
+ height: '100%',
+ width: '100%',
+ flexGrow: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+});
+
+const Container = styled(FlexColumn)({
+ height: '100%',
+ width: '100%',
+ justifyContent: 'flex-start',
+ alignItems: 'flex-start',
+ backgroundColor: colors.light02,
+});
+
export default class extends FlipperDevicePlugin {
static title = 'Hermes Debugger';
static id = 'Hermesdebuggerrn';
@@ -117,11 +141,21 @@ export default class extends FlipperDevicePlugin {
handleSelect = (selectedTarget: Target) => this.setState({selectedTarget});
- render() {
+ renderContent() {
const {error, selectedTarget, targets} = this.state;
if (selectedTarget) {
- return ;
+ let bannerMargin = null;
+ if (isBannerEnabled()) {
+ bannerMargin = '29px';
+ }
+
+ return (
+
+ );
} else if (targets != null && targets.length === 0) {
return ;
} else if (targets != null && targets.length > 0) {
@@ -132,4 +166,13 @@ export default class extends FlipperDevicePlugin {
return null;
}
}
+
+ render() {
+ return (
+
+
+ {this.renderContent()}
+
+ );
+ }
}