Upgrade React-Redux (2nd attempt)
Summary: - Update and include `react-redux` to Greenkeeper - Remove legacy context which is used to access `store` - Export `store` directly to use instead of legacy context Note: 1st attempt: D18169584 -> got backouted in D18203354 Reviewed By: jknoxville Differential Revision: D18297298 fbshipit-source-id: fd968f1b211eabb094113a0b35e84305f70117fc
This commit is contained in:
committed by
Facebook Github Bot
parent
61d4e0c6a5
commit
c1130a167b
@@ -8,13 +8,12 @@
|
||||
*/
|
||||
|
||||
import {Button, styled} from 'flipper';
|
||||
import {connect} from 'react-redux';
|
||||
import {connect, ReactReduxContext} from 'react-redux';
|
||||
import {spawn} from 'child_process';
|
||||
import {dirname} from 'path';
|
||||
import {selectDevice, preferDevice} from '../reducers/connections';
|
||||
import {default as which} from 'which';
|
||||
import {showOpenDialog} from '../utils/exportData';
|
||||
import PropTypes from 'prop-types';
|
||||
import BaseDevice from '../devices/BaseDevice';
|
||||
import React, {Component} from 'react';
|
||||
import {State} from '../reducers';
|
||||
@@ -38,10 +37,6 @@ const DropdownButton = styled(Button)({
|
||||
});
|
||||
|
||||
class DevicesButton extends Component<Props> {
|
||||
static contextTypes = {
|
||||
store: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
launchEmulator = (name: string) => {
|
||||
// On Linux, you must run the emulator from the directory it's in because
|
||||
// reasons ...
|
||||
@@ -85,7 +80,7 @@ class DevicesButton extends Component<Props> {
|
||||
icon = 'desktop';
|
||||
}
|
||||
|
||||
const dropdown = [];
|
||||
const dropdown: any[] = [];
|
||||
|
||||
// Physical devices
|
||||
const connectedDevices = [
|
||||
@@ -169,16 +164,22 @@ class DevicesButton extends Component<Props> {
|
||||
if (dropdown.length > 0) {
|
||||
dropdown.push({type: 'separator' as 'separator'});
|
||||
}
|
||||
dropdown.push({
|
||||
label: 'Open File...',
|
||||
click: () => {
|
||||
showOpenDialog(this.context.store);
|
||||
},
|
||||
});
|
||||
return (
|
||||
<DropdownButton compact={true} icon={icon} dropdown={dropdown}>
|
||||
{buttonLabel}
|
||||
</DropdownButton>
|
||||
<ReactReduxContext.Consumer>
|
||||
{({store}) => {
|
||||
dropdown.push({
|
||||
label: 'Open File...',
|
||||
click: () => {
|
||||
showOpenDialog(store);
|
||||
},
|
||||
});
|
||||
return (
|
||||
<DropdownButton compact={true} icon={icon} dropdown={dropdown}>
|
||||
{buttonLabel}
|
||||
</DropdownButton>
|
||||
);
|
||||
}}
|
||||
</ReactReduxContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
} from 'flipper';
|
||||
import {unsetShare} from '../reducers/application';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {ReactReduxContext} from 'react-redux';
|
||||
|
||||
export type SelectionType = 'multiple' | 'single';
|
||||
|
||||
@@ -122,10 +122,6 @@ class RowComponent extends Component<RowComponentProps> {
|
||||
}
|
||||
|
||||
export default class ListView extends Component<Props, State> {
|
||||
static contextTypes = {
|
||||
store: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
state: State = {selectedElements: new Set([])};
|
||||
static getDerivedStateFromProps(props: Props, state: State) {
|
||||
if (state.selectedElements.size > 0) {
|
||||
@@ -161,46 +157,51 @@ export default class ListView extends Component<Props, State> {
|
||||
};
|
||||
|
||||
render() {
|
||||
const onHide = () => {
|
||||
this.context.store.dispatch(unsetShare());
|
||||
this.props.onHide();
|
||||
};
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<FlexColumn>
|
||||
<Title>{this.props.title}</Title>
|
||||
<RowComponentContainer>
|
||||
{this.props.elements.map(id => {
|
||||
return (
|
||||
<RowComponent
|
||||
name={id}
|
||||
key={id}
|
||||
selected={this.state.selectedElements.has(id)}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</RowComponentContainer>
|
||||
</FlexColumn>
|
||||
<Padder paddingTop={8} paddingBottom={2}>
|
||||
<FlexRow>
|
||||
<Spacer />
|
||||
<Button compact padded onClick={onHide}>
|
||||
Close
|
||||
</Button>
|
||||
<Button
|
||||
compact
|
||||
padded
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
this.props.onSelect([...this.state.selectedElements]);
|
||||
}}>
|
||||
Submit
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</Padder>
|
||||
</Container>
|
||||
<ReactReduxContext.Consumer>
|
||||
{({store}) => {
|
||||
const onHide = () => {
|
||||
store.dispatch(unsetShare());
|
||||
this.props.onHide();
|
||||
};
|
||||
return (
|
||||
<Container>
|
||||
<FlexColumn>
|
||||
<Title>{this.props.title}</Title>
|
||||
<RowComponentContainer>
|
||||
{this.props.elements.map(id => {
|
||||
return (
|
||||
<RowComponent
|
||||
name={id}
|
||||
key={id}
|
||||
selected={this.state.selectedElements.has(id)}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</RowComponentContainer>
|
||||
</FlexColumn>
|
||||
<Padder paddingTop={8} paddingBottom={2}>
|
||||
<FlexRow>
|
||||
<Spacer />
|
||||
<Button compact padded onClick={onHide}>
|
||||
Close
|
||||
</Button>
|
||||
<Button
|
||||
compact
|
||||
padded
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
this.props.onSelect([...this.state.selectedElements]);
|
||||
}}>
|
||||
Submit
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</Padder>
|
||||
</Container>
|
||||
);
|
||||
}}
|
||||
</ReactReduxContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ import {
|
||||
exportStoreToFile,
|
||||
EXPORT_FLIPPER_TRACE_EVENT,
|
||||
} from '../utils/exportData';
|
||||
import PropTypes from 'prop-types';
|
||||
import ShareSheetErrorList from './ShareSheetErrorList';
|
||||
import ShareSheetPendingDialog from './ShareSheetPendingDialog';
|
||||
import {ReactReduxContext} from 'react-redux';
|
||||
import {store} from '../init';
|
||||
|
||||
const Container = styled(FlexColumn)({
|
||||
padding: 20,
|
||||
@@ -75,10 +76,6 @@ type State = {
|
||||
};
|
||||
|
||||
export default class ShareSheetExportFile extends Component<Props, State> {
|
||||
static contextTypes = {
|
||||
store: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
state: State = {
|
||||
errorArray: [],
|
||||
result: {kind: 'pending'},
|
||||
@@ -89,13 +86,13 @@ export default class ShareSheetExportFile extends Component<Props, State> {
|
||||
idler = new Idler();
|
||||
|
||||
dispatchAndUpdateToolBarStatus(msg: string) {
|
||||
this.context.store.dispatch(
|
||||
store.dispatch(
|
||||
setExportStatusComponent(
|
||||
<CancellableExportStatus
|
||||
msg={msg}
|
||||
onCancel={() => {
|
||||
this.idler.cancel();
|
||||
this.context.store.dispatch(unsetShare());
|
||||
store.dispatch(unsetShare());
|
||||
}}
|
||||
/>,
|
||||
),
|
||||
@@ -110,21 +107,16 @@ export default class ShareSheetExportFile extends Component<Props, State> {
|
||||
return;
|
||||
}
|
||||
const {errorArray} = await reportPlatformFailures(
|
||||
exportStoreToFile(
|
||||
this.props.file,
|
||||
this.context.store,
|
||||
this.idler,
|
||||
(msg: string) => {
|
||||
if (this.state.runInBackground) {
|
||||
this.dispatchAndUpdateToolBarStatus(msg);
|
||||
} else {
|
||||
this.setState({statusUpdate: msg});
|
||||
}
|
||||
},
|
||||
),
|
||||
exportStoreToFile(this.props.file, store, this.idler, (msg: string) => {
|
||||
if (this.state.runInBackground) {
|
||||
this.dispatchAndUpdateToolBarStatus(msg);
|
||||
} else {
|
||||
this.setState({statusUpdate: msg});
|
||||
}
|
||||
}),
|
||||
`${EXPORT_FLIPPER_TRACE_EVENT}:UI_FILE`,
|
||||
);
|
||||
this.context.store.dispatch(unsetShare());
|
||||
store.dispatch(unsetShare());
|
||||
if (this.state.runInBackground) {
|
||||
new Notification('Sharable Flipper trace created', {
|
||||
body: `Flipper trace exported to the ${this.props.file}`,
|
||||
@@ -142,64 +134,76 @@ export default class ShareSheetExportFile extends Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
renderSuccess(context: any) {
|
||||
renderSuccess() {
|
||||
return (
|
||||
<Container>
|
||||
<FlexColumn>
|
||||
<Title bold>Data Exported Successfully</Title>
|
||||
<InfoText>
|
||||
When sharing your Flipper data, consider that the captured data
|
||||
might contain sensitive information like access tokens used in
|
||||
network requests.
|
||||
</InfoText>
|
||||
<ShareSheetErrorList errors={this.state.errorArray} />
|
||||
</FlexColumn>
|
||||
<FlexRow>
|
||||
<Spacer />
|
||||
<Button compact padded onClick={() => this.cancelAndHide(context)}>
|
||||
Close
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</Container>
|
||||
<ReactReduxContext.Consumer>
|
||||
{({store}) => (
|
||||
<Container>
|
||||
<FlexColumn>
|
||||
<Title bold>Data Exported Successfully</Title>
|
||||
<InfoText>
|
||||
When sharing your Flipper data, consider that the captured data
|
||||
might contain sensitive information like access tokens used in
|
||||
network requests.
|
||||
</InfoText>
|
||||
<ShareSheetErrorList errors={this.state.errorArray} />
|
||||
</FlexColumn>
|
||||
<FlexRow>
|
||||
<Spacer />
|
||||
<Button compact padded onClick={() => this.cancelAndHide(store)}>
|
||||
Close
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</Container>
|
||||
)}
|
||||
</ReactReduxContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
renderError(context: any, result: {kind: 'error'; error: Error}) {
|
||||
renderError(result: {kind: 'error'; error: Error}) {
|
||||
return (
|
||||
<Container>
|
||||
<Title bold>Error</Title>
|
||||
<ErrorMessage code>
|
||||
{result.error.message || 'File could not be saved.'}
|
||||
</ErrorMessage>
|
||||
<FlexRow>
|
||||
<Spacer />
|
||||
<Button compact padded onClick={() => this.cancelAndHide(context)}>
|
||||
Close
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</Container>
|
||||
<ReactReduxContext.Consumer>
|
||||
{({store}) => (
|
||||
<Container>
|
||||
<Title bold>Error</Title>
|
||||
<ErrorMessage code>
|
||||
{result.error.message || 'File could not be saved.'}
|
||||
</ErrorMessage>
|
||||
<FlexRow>
|
||||
<Spacer />
|
||||
<Button compact padded onClick={() => this.cancelAndHide(store)}>
|
||||
Close
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</Container>
|
||||
)}
|
||||
</ReactReduxContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
renderPending(context: any, statusUpdate: string | null) {
|
||||
renderPending(statusUpdate: string | null) {
|
||||
return (
|
||||
<ShareSheetPendingDialog
|
||||
statusUpdate={statusUpdate}
|
||||
statusMessage="Exporting Flipper trace..."
|
||||
onCancel={() => this.cancelAndHide(context)}
|
||||
onRunInBackground={() => {
|
||||
this.setState({runInBackground: true});
|
||||
if (statusUpdate) {
|
||||
this.dispatchAndUpdateToolBarStatus(statusUpdate);
|
||||
}
|
||||
this.props.onHide();
|
||||
}}
|
||||
/>
|
||||
<ReactReduxContext.Consumer>
|
||||
{({store}) => (
|
||||
<ShareSheetPendingDialog
|
||||
statusUpdate={statusUpdate}
|
||||
statusMessage="Exporting Flipper trace..."
|
||||
onCancel={() => this.cancelAndHide(store)}
|
||||
onRunInBackground={() => {
|
||||
this.setState({runInBackground: true});
|
||||
if (statusUpdate) {
|
||||
this.dispatchAndUpdateToolBarStatus(statusUpdate);
|
||||
}
|
||||
this.props.onHide();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</ReactReduxContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
cancelAndHide(context: any) {
|
||||
context.store.dispatch(unsetShare());
|
||||
cancelAndHide(store: any) {
|
||||
store.dispatch(unsetShare());
|
||||
this.props.onHide();
|
||||
this.idler.cancel();
|
||||
}
|
||||
@@ -208,11 +212,11 @@ export default class ShareSheetExportFile extends Component<Props, State> {
|
||||
const {result, statusUpdate} = this.state;
|
||||
switch (result.kind) {
|
||||
case 'success':
|
||||
return this.renderSuccess(this.context);
|
||||
return this.renderSuccess();
|
||||
case 'error':
|
||||
return this.renderError(this.context, result);
|
||||
return this.renderError(result);
|
||||
case 'pending':
|
||||
return this.renderPending(this.context, statusUpdate);
|
||||
return this.renderPending(statusUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ import {
|
||||
Input,
|
||||
} from 'flipper';
|
||||
import React, {Component} from 'react';
|
||||
import {ReactReduxContext} from 'react-redux';
|
||||
import {store} from '../init';
|
||||
import {
|
||||
setExportStatusComponent,
|
||||
unsetShare,
|
||||
@@ -30,7 +32,6 @@ import {
|
||||
DataExportError,
|
||||
} from '../fb-stubs/user';
|
||||
import {exportStore, EXPORT_FLIPPER_TRACE_EVENT} from '../utils/exportData';
|
||||
import PropTypes from 'prop-types';
|
||||
import {clipboard} from 'electron';
|
||||
import ShareSheetErrorList from './ShareSheetErrorList';
|
||||
import {reportPlatformFailures} from '../utils/metrics';
|
||||
@@ -80,10 +81,6 @@ type State = {
|
||||
};
|
||||
|
||||
export default class ShareSheetExportUrl extends Component<Props, State> {
|
||||
static contextTypes = {
|
||||
store: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
state: State = {
|
||||
errorArray: [],
|
||||
result: null,
|
||||
@@ -94,13 +91,13 @@ export default class ShareSheetExportUrl extends Component<Props, State> {
|
||||
idler = new Idler();
|
||||
|
||||
dispatchAndUpdateToolBarStatus(msg: string) {
|
||||
this.context.store.dispatch(
|
||||
store.dispatch(
|
||||
setExportStatusComponent(
|
||||
<CancellableExportStatus
|
||||
msg={msg}
|
||||
onCancel={() => {
|
||||
this.idler.cancel();
|
||||
this.context.store.dispatch(unsetShare());
|
||||
store.dispatch(unsetShare());
|
||||
}}
|
||||
/>,
|
||||
),
|
||||
@@ -119,7 +116,7 @@ export default class ShareSheetExportUrl extends Component<Props, State> {
|
||||
}
|
||||
};
|
||||
const {serializedString, errorArray} = await reportPlatformFailures(
|
||||
exportStore(this.context.store, this.idler, statusUpdate),
|
||||
exportStore(store, this.idler, statusUpdate),
|
||||
`${EXPORT_FLIPPER_TRACE_EVENT}:UI_LINK`,
|
||||
);
|
||||
|
||||
@@ -135,7 +132,7 @@ export default class ShareSheetExportUrl extends Component<Props, State> {
|
||||
const flipperUrl = (result as DataExportResult).flipperUrl;
|
||||
if (flipperUrl) {
|
||||
clipboard.writeText(String(flipperUrl));
|
||||
this.context.store.dispatch(setExportURL(flipperUrl));
|
||||
store.dispatch(setExportURL(flipperUrl));
|
||||
new Notification('Sharable Flipper trace created', {
|
||||
body: 'URL copied to clipboard',
|
||||
requireInteraction: true,
|
||||
@@ -158,7 +155,7 @@ export default class ShareSheetExportUrl extends Component<Props, State> {
|
||||
}
|
||||
this.setState({result});
|
||||
}
|
||||
this.context.store.dispatch(unsetShare());
|
||||
store.dispatch(unsetShare());
|
||||
this.props.logger.trackTimeSince(mark, 'export:url-error');
|
||||
}
|
||||
}
|
||||
@@ -181,74 +178,82 @@ export default class ShareSheetExportUrl extends Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
renderPending(cancelAndHide: () => void, statusUpdate: string | null) {
|
||||
cancelAndHide = (store: any) => () => {
|
||||
store.dispatch(unsetShare());
|
||||
this.hideSheet();
|
||||
};
|
||||
|
||||
renderPending(statusUpdate: string | null) {
|
||||
return (
|
||||
<ShareSheetPendingDialog
|
||||
statusUpdate={statusUpdate}
|
||||
statusMessage="Uploading Flipper trace..."
|
||||
onCancel={cancelAndHide}
|
||||
onRunInBackground={() => {
|
||||
this.setState({runInBackground: true});
|
||||
if (statusUpdate) {
|
||||
this.dispatchAndUpdateToolBarStatus(statusUpdate);
|
||||
}
|
||||
this.props.onHide();
|
||||
}}
|
||||
/>
|
||||
<ReactReduxContext.Consumer>
|
||||
{({store}) => (
|
||||
<ShareSheetPendingDialog
|
||||
statusUpdate={statusUpdate}
|
||||
statusMessage="Uploading Flipper trace..."
|
||||
onCancel={this.cancelAndHide(store)}
|
||||
onRunInBackground={() => {
|
||||
this.setState({runInBackground: true});
|
||||
if (statusUpdate) {
|
||||
this.dispatchAndUpdateToolBarStatus(statusUpdate);
|
||||
}
|
||||
this.props.onHide();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</ReactReduxContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const cancelAndHide = () => {
|
||||
this.context.store.dispatch(unsetShare());
|
||||
this.hideSheet();
|
||||
};
|
||||
|
||||
const {result, statusUpdate, errorArray} = this.state;
|
||||
if (!result || !(result as DataExportResult).flipperUrl) {
|
||||
return this.renderPending(cancelAndHide, statusUpdate);
|
||||
return this.renderPending(statusUpdate);
|
||||
}
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<>
|
||||
<FlexColumn>
|
||||
{(result as DataExportResult).flipperUrl ? (
|
||||
<>
|
||||
<Title bold>Data Upload Successful</Title>
|
||||
<InfoText>
|
||||
Flipper's data was successfully uploaded. This URL can be used
|
||||
to share with other Flipper users. Opening it will import the
|
||||
data from your trace.
|
||||
</InfoText>
|
||||
<Copy value={(result as DataExportResult).flipperUrl} />
|
||||
<InfoText>
|
||||
When sharing your Flipper link, consider that the captured
|
||||
data might contain sensitve information like access tokens
|
||||
used in network requests.
|
||||
</InfoText>
|
||||
<ShareSheetErrorList errors={errorArray} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Title bold>
|
||||
{(result as DataExportError).error_class || 'Error'}
|
||||
</Title>
|
||||
<ErrorMessage code>
|
||||
{(result as DataExportError).error ||
|
||||
'The data could not be uploaded'}
|
||||
</ErrorMessage>
|
||||
</>
|
||||
)}
|
||||
</FlexColumn>
|
||||
<FlexRow>
|
||||
<Spacer />
|
||||
<Button compact padded onClick={cancelAndHide}>
|
||||
Close
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</>
|
||||
</Container>
|
||||
<ReactReduxContext.Consumer>
|
||||
{({store}) => (
|
||||
<Container>
|
||||
<>
|
||||
<FlexColumn>
|
||||
{(result as DataExportResult).flipperUrl ? (
|
||||
<>
|
||||
<Title bold>Data Upload Successful</Title>
|
||||
<InfoText>
|
||||
Flipper's data was successfully uploaded. This URL can be
|
||||
used to share with other Flipper users. Opening it will
|
||||
import the data from your trace.
|
||||
</InfoText>
|
||||
<Copy value={(result as DataExportResult).flipperUrl} />
|
||||
<InfoText>
|
||||
When sharing your Flipper link, consider that the captured
|
||||
data might contain sensitve information like access tokens
|
||||
used in network requests.
|
||||
</InfoText>
|
||||
<ShareSheetErrorList errors={errorArray} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Title bold>
|
||||
{(result as DataExportError).error_class || 'Error'}
|
||||
</Title>
|
||||
<ErrorMessage code>
|
||||
{(result as DataExportError).error ||
|
||||
'The data could not be uploaded'}
|
||||
</ErrorMessage>
|
||||
</>
|
||||
)}
|
||||
</FlexColumn>
|
||||
<FlexRow>
|
||||
<Spacer />
|
||||
<Button compact padded onClick={this.cancelAndHide(store)}>
|
||||
Close
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</>
|
||||
</Container>
|
||||
)}
|
||||
</ReactReduxContext.Consumer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user