Set up the infra to show the static screen

Summary:
This makes the implementation of static view generic. Right now the only non-plugin view which is shown is the WelcomeScreen. The implementation it is hardcoded. I want to make it generic, so that we can show the bug request screen too.

This diff sets the default value of the `staticView` to `WelcomeScreen`, which will be set to null when the `selectedDevice` is set. And viceversa, it will be assigned back to `WelcomScreen`, when the `selectedDevice` is set to `null`

Reviewed By: danielbuechele

Differential Revision: D16965734

fbshipit-source-id: 69d700184f44d4e5ab531f5f8fc0e23bafa07e72
This commit is contained in:
Pritesh Nandgaonkar
2019-09-03 08:36:33 -07:00
committed by Facebook Github Bot
parent 590ad81c2b
commit 61c033daaf
5 changed files with 65 additions and 27 deletions

View File

@@ -8,7 +8,6 @@
import React from 'react'; import React from 'react';
import {FlexColumn, FlexRow} from 'flipper'; import {FlexColumn, FlexRow} from 'flipper';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import WelcomeScreen from './chrome/WelcomeScreen';
import TitleBar from './chrome/TitleBar'; import TitleBar from './chrome/TitleBar';
import MainSidebar from './chrome/MainSidebar'; import MainSidebar from './chrome/MainSidebar';
import BugReporterDialog from './chrome/BugReporterDialog'; import BugReporterDialog from './chrome/BugReporterDialog';
@@ -34,8 +33,8 @@ import {
} from './reducers/application'; } from './reducers/application';
import {Logger} from './fb-interfaces/Logger'; import {Logger} from './fb-interfaces/Logger';
import BugReporter from './fb-stubs/BugReporter'; import BugReporter from './fb-stubs/BugReporter';
import BaseDevice from './devices/BaseDevice';
import {State as Store} from './reducers/index'; import {State as Store} from './reducers/index';
import {StaticView} from './reducers/connections';
const version = remote.app.getVersion(); const version = remote.app.getVersion();
type OwnProps = { type OwnProps = {
@@ -45,10 +44,10 @@ type OwnProps = {
type StateFromProps = { type StateFromProps = {
leftSidebarVisible: boolean; leftSidebarVisible: boolean;
selectedDevice: BaseDevice | undefined; error: string | null;
error: string | null | undefined;
activeSheet: ActiveSheet; activeSheet: ActiveSheet;
share: ShareType | undefined; share: ShareType | null;
staticView: StaticView;
}; };
type Props = StateFromProps & OwnProps; type Props = StateFromProps & OwnProps;
@@ -58,7 +57,7 @@ export class App extends React.Component<Props> {
// track time since launch // track time since launch
const [s, ns] = process.hrtime(); const [s, ns] = process.hrtime();
const launchEndTime = s * 1e3 + ns / 1e6; const launchEndTime = s * 1e3 + ns / 1e6;
ipcRenderer.on('getLaunchTime', (event, launchStartTime) => { ipcRenderer.on('getLaunchTime', (_: any, launchStartTime: number) => {
this.props.logger.track( this.props.logger.track(
'performance', 'performance',
'launchTime', 'launchTime',
@@ -114,10 +113,10 @@ export class App extends React.Component<Props> {
<Sheet>{this.getSheet}</Sheet> <Sheet>{this.getSheet}</Sheet>
<FlexRow grow={true}> <FlexRow grow={true}>
{this.props.leftSidebarVisible && <MainSidebar />} {this.props.leftSidebarVisible && <MainSidebar />}
{this.props.selectedDevice ? ( {this.props.staticView != null ? (
<PluginContainer logger={this.props.logger} /> React.createElement(this.props.staticView)
) : ( ) : (
<WelcomeScreen /> <PluginContainer logger={this.props.logger} />
)} )}
</FlexRow> </FlexRow>
<ErrorBar text={this.props.error} /> <ErrorBar text={this.props.error} />
@@ -129,12 +128,12 @@ export class App extends React.Component<Props> {
export default connect<StateFromProps, {}, OwnProps, Store>( export default connect<StateFromProps, {}, OwnProps, Store>(
({ ({
application: {leftSidebarVisible, activeSheet, share}, application: {leftSidebarVisible, activeSheet, share},
connections: {selectedDevice, error}, connections: {error, staticView},
}) => ({ }) => ({
leftSidebarVisible, leftSidebarVisible,
selectedDevice,
activeSheet, activeSheet,
share: share, share: share,
error, error,
staticView,
}), }),
)(App); )(App);

View File

@@ -26,7 +26,7 @@ test('Empty app state matches snapshot', () => {
logger={logger} logger={logger}
bugReporter={bugReporter} bugReporter={bugReporter}
leftSidebarVisible={false} leftSidebarVisible={false}
selectedDevice={null} staticView={null}
error={null} error={null}
activeSheet={null} activeSheet={null}
share={null} share={null}

View File

@@ -5,18 +5,19 @@
* @format * @format
*/ */
import { import {styled} from '../ui/index';
styled, import FlexColumn from '../ui/components/FlexColumn';
FlexColumn, import FlexRow from '../ui/components/FlexRow';
FlexRow, import Text from '../ui/components/FlexRow';
Text, import Glyph from '../ui/components/Glyph';
Glyph, import {colors, brandColors} from '../ui/components/colors';
colors,
brandColors,
} from 'flipper';
import isProduction from '../utils/isProduction'; import isProduction from '../utils/isProduction';
import {shell, remote} from 'electron'; import isHeadless from '../utils/isHeadless';
import React, {PureComponent} from 'react'; const {shell, remote} = !isHeadless()
? require('electron')
: {shell: undefined, remote: undefined};
import {PureComponent} from 'react';
import React from 'react';
const Container = styled(FlexColumn)({ const Container = styled(FlexColumn)({
height: '100%', height: '100%',
@@ -43,6 +44,7 @@ const Title = styled(Text)({
textAlign: 'center', textAlign: 'center',
color: colors.light50, color: colors.light50,
marginBottom: 16, marginBottom: 16,
flexDirection: 'column',
}); });
const Version = styled(Text)({ const Version = styled(Text)({
@@ -51,6 +53,7 @@ const Version = styled(Text)({
fontWeight: 300, fontWeight: 300,
color: colors.light30, color: colors.light30,
marginBottom: 60, marginBottom: 60,
flexDirection: 'column',
}); });
const Item = styled(FlexRow)({ const Item = styled(FlexRow)({
@@ -125,12 +128,13 @@ export default class WelcomeScreen extends PureComponent<Props, State> {
<Logo src="./icon.png" /> <Logo src="./icon.png" />
<Title>Welcome to Flipper</Title> <Title>Welcome to Flipper</Title>
<Version> <Version>
{isProduction() {isProduction() && remote
? `Version ${remote.app.getVersion()}` ? `Version ${remote.app.getVersion()}`
: 'Development Mode'} : 'Development Mode'}
</Version> </Version>
<Item <Item
onClick={() => onClick={() =>
shell &&
shell.openExternal( shell.openExternal(
'https://fbflipper.com/docs/getting-started.html', 'https://fbflipper.com/docs/getting-started.html',
) )
@@ -145,6 +149,7 @@ export default class WelcomeScreen extends PureComponent<Props, State> {
</Item> </Item>
<Item <Item
onClick={() => onClick={() =>
shell &&
shell.openExternal( shell.openExternal(
'https://fbflipper.com/docs/tutorial/intro.html', 'https://fbflipper.com/docs/tutorial/intro.html',
) )
@@ -157,6 +162,7 @@ export default class WelcomeScreen extends PureComponent<Props, State> {
</Item> </Item>
<Item <Item
onClick={() => onClick={() =>
shell &&
shell.openExternal( shell.openExternal(
'https://fbflipper.com/docs/getting-started.html', 'https://fbflipper.com/docs/getting-started.html',
) )
@@ -169,6 +175,7 @@ export default class WelcomeScreen extends PureComponent<Props, State> {
</Item> </Item>
<Item <Item
onClick={() => onClick={() =>
shell &&
shell.openExternal('https://github.com/facebook/flipper/issues') shell.openExternal('https://github.com/facebook/flipper/issues')
}> }>
<Icon size={20} name="posts" color={brandColors.Flipper} /> <Icon size={20} name="posts" color={brandColors.Flipper} />

View File

@@ -0,0 +1,10 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
export class WelcomeScreenHeadless {
// NoOp
}

View File

@@ -13,6 +13,11 @@ import {isEqual} from 'lodash';
import iosUtil from '../fb-stubs/iOSContainerUtility'; import iosUtil from '../fb-stubs/iOSContainerUtility';
import {performance} from 'perf_hooks'; import {performance} from 'perf_hooks';
import {SAVED_PLUGINS_COUNT} from '../Client'; import {SAVED_PLUGINS_COUNT} from '../Client';
import isHeadless from '../utils/isHeadless';
const WelcomeScreen = isHeadless()
? require('../chrome/WelcomeScreenHeadless').default
: require('../chrome/WelcomeScreen').default;
export type StaticView = null | typeof WelcomeScreen;
export type State = { export type State = {
devices: Array<BaseDevice>; devices: Array<BaseDevice>;
@@ -32,6 +37,7 @@ export type State = {
errorMessage?: string; errorMessage?: string;
}>; }>;
deepLinkPayload: null | string; deepLinkPayload: null | string;
staticView: StaticView;
}; };
export type Action = export type Action =
@@ -99,11 +105,14 @@ export type Action =
type: 'CLIENT_SHOW_MORE_OR_LESS'; type: 'CLIENT_SHOW_MORE_OR_LESS';
payload: string; payload: string;
} }
| {type: 'CLEAR_LRU_PLUGINS_HISTORY'}; | {type: 'CLEAR_LRU_PLUGINS_HISTORY'}
| {
type: 'SET_STATIC_VIEW';
payload: StaticView;
};
const DEFAULT_PLUGIN = 'DeviceLogs'; const DEFAULT_PLUGIN = 'DeviceLogs';
const DEFAULT_DEVICE_BLACKLIST = [MacDevice]; const DEFAULT_DEVICE_BLACKLIST = [MacDevice];
const INITAL_STATE: State = { const INITAL_STATE: State = {
devices: [], devices: [],
androidEmulators: [], androidEmulators: [],
@@ -118,15 +127,24 @@ const INITAL_STATE: State = {
clients: [], clients: [],
uninitializedClients: [], uninitializedClients: [],
deepLinkPayload: null, deepLinkPayload: null,
staticView: WelcomeScreen,
}; };
const reducer = (state: State = INITAL_STATE, action: Action): State => { const reducer = (state: State = INITAL_STATE, action: Action): State => {
switch (action.type) { switch (action.type) {
case 'SET_STATIC_VIEW': {
const {payload} = action;
return {
...state,
staticView: payload,
};
}
case 'SELECT_DEVICE': { case 'SELECT_DEVICE': {
const {payload} = action; const {payload} = action;
return { return {
...state, ...state,
selectedApp: null, selectedApp: null,
staticView: null,
selectedPlugin: DEFAULT_PLUGIN, selectedPlugin: DEFAULT_PLUGIN,
selectedDevice: payload, selectedDevice: payload,
userPreferredDevice: payload.title, userPreferredDevice: payload.title,
@@ -143,7 +161,7 @@ const reducer = (state: State = INITAL_STATE, action: Action): State => {
const {payload} = action; const {payload} = action;
const devices = state.devices.concat(payload); const devices = state.devices.concat(payload);
let {selectedDevice, selectedPlugin} = state; let {selectedDevice, selectedPlugin} = state;
let staticView: StaticView = state.staticView;
// select the default plugin // select the default plugin
let selection: Partial<State> = { let selection: Partial<State> = {
selectedApp: null, selectedApp: null,
@@ -156,6 +174,7 @@ const reducer = (state: State = INITAL_STATE, action: Action): State => {
if (!selectedDevice && canBeDefaultDevice) { if (!selectedDevice && canBeDefaultDevice) {
selectedDevice = payload; selectedDevice = payload;
staticView = null;
if (selectedPlugin) { if (selectedPlugin) {
// We already had a plugin selected, but no device. This is happening // We already had a plugin selected, but no device. This is happening
// when the Client connected before the Device. // when the Client connected before the Device.
@@ -163,6 +182,7 @@ const reducer = (state: State = INITAL_STATE, action: Action): State => {
} }
} else if (payload.title === state.userPreferredDevice) { } else if (payload.title === state.userPreferredDevice) {
selectedDevice = payload; selectedDevice = payload;
staticView = null;
} else { } else {
// We didn't select the newly connected device, so we don't want to // We didn't select the newly connected device, so we don't want to
// change the plugin. // change the plugin.
@@ -175,6 +195,7 @@ const reducer = (state: State = INITAL_STATE, action: Action): State => {
// select device if none was selected before // select device if none was selected before
selectedDevice, selectedDevice,
...selection, ...selection,
staticView,
}; };
} }
case 'UNREGISTER_DEVICES': { case 'UNREGISTER_DEVICES': {
@@ -197,6 +218,7 @@ const reducer = (state: State = INITAL_STATE, action: Action): State => {
if (selectedDeviceWasRemoved) { if (selectedDeviceWasRemoved) {
selection = { selection = {
selectedDevice: devices[devices.length - 1] || null, selectedDevice: devices[devices.length - 1] || null,
staticView: selectedDevice != null ? null : WelcomeScreen,
selectedApp: null, selectedApp: null,
selectedPlugin: DEFAULT_PLUGIN, selectedPlugin: DEFAULT_PLUGIN,
}; };