diff --git a/src/chrome/DoctorBar.tsx b/src/chrome/DoctorBar.tsx index 3bbe3a8fd..008482fc4 100644 --- a/src/chrome/DoctorBar.tsx +++ b/src/chrome/DoctorBar.tsx @@ -14,6 +14,7 @@ import { setActiveSheet, ActiveSheet, ACTIVE_SHEET_DOCTOR, + ACTIVE_SHEET_SETTINGS, } from '../reducers/application'; import {State as Store} from '../reducers/index'; import {ButtonGroup, Button} from 'flipper'; @@ -23,23 +24,24 @@ import runHealthchecks, { HealthcheckEventsHandler, } from '../utils/runHealthchecks'; import { - HealthcheckResult, updateHealthcheckResult, startHealthchecks, finishHealthchecks, + HealthcheckReport, + HealthcheckResult, } from '../reducers/healthchecks'; import {reportUsage} from '../utils/metrics'; type StateFromProps = { - healthcheckResult: HealthcheckResult; + healthcheckReport: HealthcheckReport; } & HealthcheckSettings; type DispatchFromProps = { setActiveSheet: (payload: ActiveSheet) => void; } & HealthcheckEventsHandler; -type State = {visible: boolean}; +type State = {visible: boolean; message: string; showSettingsButton: boolean}; type Props = DispatchFromProps & StateFromProps; class DoctorBar extends Component { @@ -47,18 +49,41 @@ class DoctorBar extends Component { super(props); this.state = { visible: false, + message: '', + showSettingsButton: false, }; } componentDidMount() { this.showMessageIfChecksFailed(); } + static getDerivedStateFromProps(props: Props, state: State): State | null { + const failedCategories = Object.values( + props.healthcheckReport.categories, + ).filter(cat => hasProblems(cat.result)); + if (failedCategories.length == 1) { + const failedCat = failedCategories[0]; + if (failedCat.key === 'ios' || failedCat.key === 'android') { + return { + ...state, + message: `Doctor has discovered problems with your ${failedCat.label} setup. If you are not interested in ${failedCat.label} development you can disable it in Settings.`, + showSettingsButton: true, + }; + } + } + if (failedCategories.length) { + return { + ...state, + message: 'Doctor has discovered problems with your installation.', + showSettingsButton: false, + }; + } + return null; + } async showMessageIfChecksFailed() { await runHealthchecks(this.props); - if ( - this.props.healthcheckResult.status === 'FAILED' || - this.props.healthcheckResult.status === 'WARNING' - ) { - if (this.props.healthcheckResult.isAcknowledged) { + const result = this.props.healthcheckReport.result; + if (hasProblems(result)) { + if (result.isAcknowledged) { reportUsage('doctor:warning:suppressed'); } else { this.setVisible(true); @@ -76,18 +101,28 @@ class DoctorBar extends Component { + {this.state.showSettingsButton && ( + + )} - Doctor has discovered problems with your installation + {this.state.message} @@ -107,13 +142,12 @@ class DoctorBar extends Component { export default connect( ({ - settingsState: {enableAndroid}, - healthchecks: { - healthcheckReport: {result}, - }, + settingsState: {enableAndroid, enableIOS}, + healthchecks: {healthcheckReport}, }) => ({ enableAndroid, - healthcheckResult: result, + enableIOS, + healthcheckReport, }), { setActiveSheet, @@ -149,3 +183,7 @@ const ButtonSection = styled(FlexColumn)({ flexShrink: 0, flexGrow: 0, }); + +function hasProblems(result: HealthcheckResult) { + return result.status === 'WARNING' || result.status === 'FAILED'; +} diff --git a/src/chrome/DoctorSheet.tsx b/src/chrome/DoctorSheet.tsx index f6d251804..b7b3695a9 100644 --- a/src/chrome/DoctorSheet.tsx +++ b/src/chrome/DoctorSheet.tsx @@ -201,7 +201,7 @@ function ResultMessage(props: {result: HealthcheckResult}) { return (

Doctor has discovered problems with your installation. Please click to - each item to get details. + an item to get its details.

); } else { @@ -404,9 +404,13 @@ class DoctorSheet extends Component { } export default connect( - ({healthchecks: {healthcheckReport}, settingsState}) => ({ + ({ + healthchecks: {healthcheckReport}, + settingsState: {enableAndroid, enableIOS}, + }) => ({ healthcheckReport, - enableAndroid: settingsState.enableAndroid, + enableAndroid, + enableIOS, }), { startHealthchecks, diff --git a/src/chrome/SettingsSheet.tsx b/src/chrome/SettingsSheet.tsx index 247a4c855..aa4ef5e98 100644 --- a/src/chrome/SettingsSheet.tsx +++ b/src/chrome/SettingsSheet.tsx @@ -24,6 +24,10 @@ import {FilePathConfigField, ConfigText} from './settings/configFields'; import isEqual from 'lodash.isequal'; import restartFlipper from '../utils/restartFlipper'; import LauncherSettingsPanel from '../fb-stubs/LauncherSettingsPanel'; +import {reportUsage} from '../utils/metrics'; +import os from 'os'; + +const platform = os.platform(); const Container = styled(FlexColumn)({ padding: 20, @@ -64,6 +68,10 @@ class SettingsSheet extends Component { updatedLauncherSettings: {...this.props.launcherSettings}, }; + componentDidMount() { + reportUsage('settings:opened'); + } + applyChanges = async () => { this.props.updateSettings(this.state.updatedSettings); this.props.updateLauncherSettings(this.state.updatedLauncherSettings); @@ -104,15 +112,26 @@ class SettingsSheet extends Component { + toggled={ + this.state.updatedSettings.enableIOS && platform === 'darwin' + } + frozen={platform !== 'darwin'} + onChange={v => { + this.setState({ + updatedSettings: {...this.state.updatedSettings, enableIOS: v}, + }); + }}> {' '} - + {platform === 'darwin' && ( + + )} + {platform !== 'darwin' && ( + + )} (({focused}) => ({ background: focused @@ -175,7 +176,10 @@ class TitleBar extends React.Component { icon="settings" title="Settings" compact={true} - onClick={() => this.props.setActiveSheet(ACTIVE_SHEET_SETTINGS)} + onClick={() => { + this.props.setActiveSheet(ACTIVE_SHEET_SETTINGS); + reportUsage('settings:opened:fromTitleBar'); + }} /> {config.bugReportButtonVisible && (