diff --git a/desktop/app/src/MenuBar.tsx b/desktop/app/src/MenuBar.tsx index 7a0731fd1..13244aa34 100644 --- a/desktop/app/src/MenuBar.tsx +++ b/desktop/app/src/MenuBar.tsx @@ -26,7 +26,11 @@ import electron, {MenuItemConstructorOptions} from 'electron'; import {notNull} from './utils/typeUtils'; import constants from './fb-stubs/constants'; import {Logger} from './fb-interfaces/Logger'; -import {NormalizedMenuEntry, _buildInMenuEntries} from 'flipper-plugin'; +import { + NormalizedMenuEntry, + _buildInMenuEntries, + _wrapInteractionHandler, +} from 'flipper-plugin'; import {StyleGuide} from './sandy-chrome/StyleGuide'; import {showEmulatorLauncher} from './sandy-chrome/appinspect/LaunchEmulator'; @@ -191,7 +195,13 @@ export function addSandyPluginEntries(entries: NormalizedMenuEntry[]) { if (parent) { const item = new electron.remote.MenuItem({ enabled: true, - click: () => pluginActionHandler?.(entry.action!), + click: _wrapInteractionHandler( + () => pluginActionHandler?.(entry.action!), + 'MenuItem', + 'onClick', + 'flipper:menu:' + entry.topLevelMenu, + entry.label, + ), label: entry.label, accelerator: entry.accelerator, }); @@ -206,6 +216,20 @@ export function addSandyPluginEntries(entries: NormalizedMenuEntry[]) { } } +function trackMenuItems(menu: string, items: MenuItemConstructorOptions[]) { + items.forEach((item) => { + if (item.label && item.click) { + item.click = _wrapInteractionHandler( + item.click, + 'MenuItem', + 'onClick', + 'flipper:menu:' + menu, + item.label, + ); + } + }); +} + function getTemplate( app: electron.App, shell: electron.Shell, @@ -226,6 +250,8 @@ function getTemplate( click: () => startLinkExport(store.dispatch), }); } + trackMenuItems('export', exportSubmenu); + const fileSubmenu: MenuItemConstructorOptions[] = [ { label: 'Launch Emulator...', @@ -250,6 +276,8 @@ function getTemplate( submenu: exportSubmenu, }, ]; + trackMenuItems('file', fileSubmenu); + const supportRequestSubmenu = [ { label: 'Create...', @@ -259,11 +287,101 @@ function getTemplate( }, }, ]; + trackMenuItems('support', supportRequestSubmenu); + fileSubmenu.push({ label: 'Support Requests', submenu: supportRequestSubmenu, }); + const viewMenu: MenuItemConstructorOptions[] = [ + { + label: 'Reload', + accelerator: 'CmdOrCtrl+R', + click: function (_, focusedWindow: electron.BrowserWindow | undefined) { + if (focusedWindow) { + logger.track('usage', 'reload'); + focusedWindow.reload(); + } + }, + }, + { + label: 'Toggle Full Screen', + accelerator: (function () { + if (process.platform === 'darwin') { + return 'Ctrl+Command+F'; + } else { + return 'F11'; + } + })(), + click: function (_, focusedWindow: electron.BrowserWindow | undefined) { + if (focusedWindow) { + focusedWindow.setFullScreen(!focusedWindow.isFullScreen()); + } + }, + }, + { + label: 'Manage Plugins...', + click: function () { + store.dispatch(setActiveSheet(ACTIVE_SHEET_PLUGINS)); + }, + }, + { + label: 'Flipper style guide', + click() { + store.dispatch(setStaticView(StyleGuide)); + }, + }, + { + label: 'Toggle Developer Tools', + accelerator: (function () { + if (process.platform === 'darwin') { + return 'Alt+Command+I'; + } else { + return 'Ctrl+Shift+I'; + } + })(), + click: function (_, focusedWindow: electron.BrowserWindow | undefined) { + if (focusedWindow) { + // @ts-ignore: https://github.com/electron/electron/issues/7832 + focusedWindow.toggleDevTools(); + } + }, + }, + { + type: 'separator', + }, + ]; + trackMenuItems('view', viewMenu); + + const helpMenu: MenuItemConstructorOptions[] = [ + { + label: 'Getting started', + click: function () { + shell.openExternal('https://fbflipper.com/docs/getting-started/index'); + }, + }, + { + label: 'Create plugins', + click: function () { + shell.openExternal('https://fbflipper.com/docs/tutorial/intro'); + }, + }, + { + label: 'Report problems', + click: function () { + shell.openExternal(constants.FEEDBACK_GROUP_LINK); + }, + }, + { + label: 'Changelog', + click() { + store.dispatch(setActiveSheet(ACTIVE_SHEET_CHANGELOG)); + }, + }, + ]; + trackMenuItems('help', helpMenu); + const template: MenuItemConstructorOptions[] = [ { label: 'File', @@ -309,73 +427,7 @@ function getTemplate( }, { label: 'View', - submenu: [ - { - label: 'Reload', - accelerator: 'CmdOrCtrl+R', - click: function ( - _, - focusedWindow: electron.BrowserWindow | undefined, - ) { - if (focusedWindow) { - logger.track('usage', 'reload'); - focusedWindow.reload(); - } - }, - }, - { - label: 'Toggle Full Screen', - accelerator: (function () { - if (process.platform === 'darwin') { - return 'Ctrl+Command+F'; - } else { - return 'F11'; - } - })(), - click: function ( - _, - focusedWindow: electron.BrowserWindow | undefined, - ) { - if (focusedWindow) { - focusedWindow.setFullScreen(!focusedWindow.isFullScreen()); - } - }, - }, - { - label: 'Manage Plugins...', - click: function () { - store.dispatch(setActiveSheet(ACTIVE_SHEET_PLUGINS)); - }, - }, - { - label: 'Flipper style guide', - click() { - store.dispatch(setStaticView(StyleGuide)); - }, - }, - { - label: 'Toggle Developer Tools', - accelerator: (function () { - if (process.platform === 'darwin') { - return 'Alt+Command+I'; - } else { - return 'Ctrl+Shift+I'; - } - })(), - click: function ( - _, - focusedWindow: electron.BrowserWindow | undefined, - ) { - if (focusedWindow) { - // @ts-ignore: https://github.com/electron/electron/issues/7832 - focusedWindow.toggleDevTools(); - } - }, - }, - { - type: 'separator', - }, - ], + submenu: viewMenu, }, { label: 'Window', @@ -396,36 +448,10 @@ function getTemplate( { label: 'Help', role: 'help', - submenu: [ - { - label: 'Getting started', - click: function () { - shell.openExternal( - 'https://fbflipper.com/docs/getting-started/index', - ); - }, - }, - { - label: 'Create plugins', - click: function () { - shell.openExternal('https://fbflipper.com/docs/tutorial/intro'); - }, - }, - { - label: 'Report problems', - click: function () { - shell.openExternal(constants.FEEDBACK_GROUP_LINK); - }, - }, - { - label: 'Changelog', - click() { - store.dispatch(setActiveSheet(ACTIVE_SHEET_CHANGELOG)); - }, - }, - ], + submenu: helpMenu, }, ]; + trackMenuItems('support', supportRequestSubmenu); if (process.platform === 'darwin') { const name = app.name; diff --git a/desktop/app/src/chrome/ScreenCaptureButtons.tsx b/desktop/app/src/chrome/ScreenCaptureButtons.tsx index da28cf3e3..6683f0126 100644 --- a/desktop/app/src/chrome/ScreenCaptureButtons.tsx +++ b/desktop/app/src/chrome/ScreenCaptureButtons.tsx @@ -48,15 +48,15 @@ export default function ScreenCaptureButtons({useSandy}: {useSandy?: boolean}) { const handleScreenshot = useCallback(() => { setIsTakingScreenshot(true); - capture(selectedDevice!) - .then(openFile) - .catch((e) => { - console.error('Taking screenshot failed:', e); - message.error('Taking screenshot failed:' + e); - }) - .finally(() => { - setIsTakingScreenshot(false); - }); + const p = capture(selectedDevice!).then(openFile); + + p.catch((e) => { + console.error('Taking screenshot failed:', e); + message.error('Taking screenshot failed:' + e); + }).finally(() => { + setIsTakingScreenshot(false); + }); + return p; }, [selectedDevice]); const handleRecording = useCallback(() => { if (!selectedDevice) { @@ -65,13 +65,13 @@ export default function ScreenCaptureButtons({useSandy}: {useSandy?: boolean}) { if (!isRecording) { setIsRecording(true); const videoPath = path.join(CAPTURE_LOCATION, getFileName('mp4')); - selectedDevice.startScreenCapture(videoPath).catch((e) => { + return selectedDevice.startScreenCapture(videoPath).catch((e) => { console.error('Failed to start recording', e); message.error('Failed to start recording' + e); setIsRecording(false); }); } else { - selectedDevice + return selectedDevice .stopScreenCapture() .then(openFile) .catch((e) => { diff --git a/desktop/app/src/chrome/SettingsSheet.tsx b/desktop/app/src/chrome/SettingsSheet.tsx index c4d1b9383..09e87feda 100644 --- a/desktop/app/src/chrome/SettingsSheet.tsx +++ b/desktop/app/src/chrome/SettingsSheet.tsx @@ -28,7 +28,7 @@ import LauncherSettingsPanel from '../fb-stubs/LauncherSettingsPanel'; import SandySettingsPanel from '../fb-stubs/SandySettingsPanel'; import {reportUsage} from '../utils/metrics'; import {Modal} from 'antd'; -import {Layout, _NuxManagerContext} from 'flipper-plugin'; +import {Layout, withTrackingScope, _NuxManagerContext} from 'flipper-plugin'; const Container = styled(FlexColumn)({ padding: 20, @@ -356,7 +356,7 @@ export default connect( isXcodeDetected: application.xcodeCommandLineToolsDetected, }), {updateSettings, updateLauncherSettings}, -)(SettingsSheet); +)(withTrackingScope(SettingsSheet)); function ResetTooltips() { const nuxManager = useContext(_NuxManagerContext); diff --git a/desktop/app/src/chrome/SignInSheet.tsx b/desktop/app/src/chrome/SignInSheet.tsx index d44ce984a..96169cc4a 100644 --- a/desktop/app/src/chrome/SignInSheet.tsx +++ b/desktop/app/src/chrome/SignInSheet.tsx @@ -27,6 +27,7 @@ import ContextMenu from '../ui/components/ContextMenu'; import {clipboard} from 'electron'; import {reportPlatformFailures} from '../utils/metrics'; import {Modal} from 'antd'; +import {TrackingScope} from 'flipper-plugin'; const Container = styled(FlexColumn)({ padding: 20, @@ -135,15 +136,17 @@ class SignInSheet extends Component { footer: React.ReactElement, ) { return ( - - {contents} - + + + {contents} + + ); } diff --git a/desktop/app/src/chrome/WelcomeScreen.tsx b/desktop/app/src/chrome/WelcomeScreen.tsx index a2563a1a4..691df32bd 100644 --- a/desktop/app/src/chrome/WelcomeScreen.tsx +++ b/desktop/app/src/chrome/WelcomeScreen.tsx @@ -21,6 +21,7 @@ const {shell, remote} = !isHeadless() : {shell: undefined, remote: undefined}; import {PureComponent} from 'react'; import React from 'react'; +import {Tracked, TrackingScope} from 'flipper-plugin'; const Container = styled(FlexColumn)({ height: '100%', @@ -127,64 +128,72 @@ export default class WelcomeScreen extends PureComponent { render() { return ( - - - Welcome to Flipper - - {isProduction() && remote - ? `Version ${remote.app.getVersion()}` - : 'Development Mode'} - - - shell && - shell.openExternal('https://fbflipper.com/docs/features/index') - }> - - - Using Flipper - - Learn how Flipper can help you debug your App - - - - - shell && - shell.openExternal('https://fbflipper.com/docs/tutorial/intro') - }> - - - Create your own plugin - Get started with these pointers - - - - shell && - shell.openExternal( - 'https://fbflipper.com/docs/getting-started/index', - ) - }> - - - Add Flipper support to your app - Get started with these pointers - - - - shell && shell.openExternal(constants.FEEDBACK_GROUP_LINK) - }> - - - Contributing and Feedback - - Report issues and help us improve Flipper - - - - + + + + Welcome to Flipper + + {isProduction() && remote + ? `Version ${remote.app.getVersion()}` + : 'Development Mode'} + + + { + shell && + shell.openExternal( + 'https://fbflipper.com/docs/features/index', + ); + }}> + + + Using Flipper + + Learn how Flipper can help you debug your App + + + + + shell && + shell.openExternal( + 'https://fbflipper.com/docs/tutorial/intro', + ) + }> + + + Create your own plugin + Get started with these pointers + + + + shell && + shell.openExternal( + 'https://fbflipper.com/docs/getting-started/index', + ) + }> + + + Add Flipper support to your app + Get started with these pointers + + + + shell && shell.openExternal(constants.FEEDBACK_GROUP_LINK) + }> + + + Contributing and Feedback + + Report issues and help us improve Flipper + + + + + + ); } diff --git a/desktop/app/src/sandy-chrome/DesignComponentDemos.tsx b/desktop/app/src/sandy-chrome/DesignComponentDemos.tsx index 379512d28..669d99c4c 100644 --- a/desktop/app/src/sandy-chrome/DesignComponentDemos.tsx +++ b/desktop/app/src/sandy-chrome/DesignComponentDemos.tsx @@ -343,7 +343,7 @@ const demos: PreviewProps[] = [ ], demos: { 'Basic example': ( - + @@ -356,65 +356,67 @@ const demos: PreviewProps[] = [ function ComponentPreview({title, demos, description, props}: PreviewProps) { return ( - - {description} - - - - {Object.entries(demos).map(([name, children]) => ( -
- - -
- {children} -
-
- } key="2"> -
-
{reactElementToJSXString(children)}
-
-
-
-
- ))} -
-
- - - Object.assign(prop, {key: prop[0]}), - )} - columns={[ - { - title: 'Property', - dataIndex: 0, - width: 100, - }, - { - title: 'Type and default', - dataIndex: 1, - width: 200, - }, - { - title: 'Description', - dataIndex: 2, - }, - ]} - /> - - - + + + {description} + + + + {Object.entries(demos).map(([name, children]) => ( +
+ + +
+ {children} +
+
+ } key="2"> +
+
{reactElementToJSXString(children)}
+
+
+
+
+ ))} +
+
+ +
+ Object.assign(prop, {key: prop[0]}), + )} + columns={[ + { + title: 'Property', + dataIndex: 0, + width: 100, + }, + { + title: 'Type and default', + dataIndex: 1, + width: 200, + }, + { + title: 'Description', + dataIndex: 2, + }, + ]} + /> + + + + ); } diff --git a/desktop/app/src/sandy-chrome/LeftRail.tsx b/desktop/app/src/sandy-chrome/LeftRail.tsx index d2840ead9..b8d12e99d 100644 --- a/desktop/app/src/sandy-chrome/LeftRail.tsx +++ b/desktop/app/src/sandy-chrome/LeftRail.tsx @@ -35,7 +35,7 @@ import { toggleLeftSidebarVisible, toggleRightSidebarVisible, } from '../reducers/application'; -import {theme, Layout} from 'flipper-plugin'; +import {theme, Layout, withTrackingScope} from 'flipper-plugin'; import SetupDoctorScreen, {checkHasNewProblem} from './SetupDoctorScreen'; import SettingsSheet from '../chrome/SettingsSheet'; import WelcomeScreen from './WelcomeScreen'; @@ -98,6 +98,7 @@ export function LeftRailButton({ return ( ); -} +}); function LeftSidebarToggleButton() { const dispatch = useDispatch(); diff --git a/desktop/app/src/sandy-chrome/SandyApp.tsx b/desktop/app/src/sandy-chrome/SandyApp.tsx index e316e0de9..c1333482b 100644 --- a/desktop/app/src/sandy-chrome/SandyApp.tsx +++ b/desktop/app/src/sandy-chrome/SandyApp.tsx @@ -127,9 +127,9 @@ export function SandyApp({logger}: {logger: Logger}) { {staticView ? ( diff --git a/desktop/app/src/sandy-chrome/WelcomeScreen.tsx b/desktop/app/src/sandy-chrome/WelcomeScreen.tsx index c04ead97e..f61e79e48 100644 --- a/desktop/app/src/sandy-chrome/WelcomeScreen.tsx +++ b/desktop/app/src/sandy-chrome/WelcomeScreen.tsx @@ -16,7 +16,7 @@ import { CodeOutlined, BugOutlined, } from '@ant-design/icons'; -import {theme} from 'flipper-plugin'; +import {theme, Tracked, TrackingScope} from 'flipper-plugin'; const {Text, Title} = Typography; @@ -45,19 +45,21 @@ function Row(props: { onClick?: () => void; }) { return ( - - - {cloneElement(props.icon, { - style: {fontSize: 36, color: theme.primaryColor}, - })} - - - {props.title} - - {props.subtitle} - - - + + + + {cloneElement(props.icon, { + style: {fontSize: 36, color: theme.primaryColor}, + })} + + + {props.title} + + {props.subtitle} + + + + ); } @@ -114,46 +116,48 @@ export default function WelcomeScreen({ /> } onCancel={onClose}> - - - Welcome to Flipper - - {isProduction() && remote - ? `Version ${remote.app.getVersion()}` - : 'Development Mode'} - - - - } - title="Using Flipper" - subtitle="Learn how Flipper can help you debug your App" - onClick={openExternal('https://fbflipper.com/docs/features/index')} - /> - } - title="Create Your Own Plugin" - subtitle="Get started with these pointers" - onClick={openExternal('https://fbflipper.com/docs/tutorial/intro')} - /> - } - title="Add Flipper Support to Your App" - subtitle="Get started with these pointers" - onClick={openExternal( - 'https://fbflipper.com/docs/getting-started/index', - )} - /> - } - title="Contributing and Feedback" - subtitle="Report issues and help us improve Flipper" - onClick={openExternal(constants.FEEDBACK_GROUP_LINK)} - /> - + + + + Welcome to Flipper + + {isProduction() && remote + ? `Version ${remote.app.getVersion()}` + : 'Development Mode'} + + + + } + title="Using Flipper" + subtitle="Learn how Flipper can help you debug your App" + onClick={openExternal('https://fbflipper.com/docs/features/index')} + /> + } + title="Create Your Own Plugin" + subtitle="Get started with these pointers" + onClick={openExternal('https://fbflipper.com/docs/tutorial/intro')} + /> + } + title="Add Flipper Support to Your App" + subtitle="Get started with these pointers" + onClick={openExternal( + 'https://fbflipper.com/docs/getting-started/index', + )} + /> + } + title="Contributing and Feedback" + subtitle="Report issues and help us improve Flipper" + onClick={openExternal(constants.FEEDBACK_GROUP_LINK)} + /> + + ); } diff --git a/desktop/app/src/sandy-chrome/appinspect/AppSelector.tsx b/desktop/app/src/sandy-chrome/appinspect/AppSelector.tsx index 41a7daffb..7e1265f9c 100644 --- a/desktop/app/src/sandy-chrome/appinspect/AppSelector.tsx +++ b/desktop/app/src/sandy-chrome/appinspect/AppSelector.tsx @@ -16,9 +16,9 @@ import { CaretDownOutlined, } from '@ant-design/icons'; import {Glyph, Layout, styled} from '../../ui'; -import {theme} from 'flipper-plugin'; +import {theme, useTrackedCallback} from 'flipper-plugin'; import {batch} from 'react-redux'; -import {Dispatch, useDispatch, useStore} from '../../utils/useStore'; +import {useDispatch, useStore} from '../../utils/useStore'; import { canBeDefaultDevice, getAvailableClients, @@ -55,11 +55,34 @@ export function AppSelector() { uninitializedClients, selectedApp, } = useStore((state) => state.connections); + + const onSelectDevice = useTrackedCallback( + 'select-device', + (device: BaseDevice) => { + batch(() => { + dispatch(selectDevice(device)); + dispatch(selectClient(null)); + }); + }, + [], + ); + const onSelectApp = useTrackedCallback( + 'select-app', + (device: BaseDevice, client: Client) => { + batch(() => { + dispatch(selectDevice(device)); + dispatch(selectClient(client.id)); + }); + }, + [], + ); + const entries = computeEntries( devices, - dispatch, clients, uninitializedClients, + onSelectDevice, + onSelectApp, ); const client = clients.find((client) => client.id === selectedApp); @@ -144,9 +167,10 @@ const AppIconContainer = styled.div({ function computeEntries( devices: BaseDevice[], - dispatch: Dispatch, clients: Client[], uninitializedClients: State['connections']['uninitializedClients'], + onSelectDevice: (device: BaseDevice) => void, + onSelectApp: (device: BaseDevice, client: Client) => void, ) { const entries = devices.filter(canBeDefaultDevice).map((device) => { const deviceEntry = ( @@ -155,10 +179,7 @@ function computeEntries( key={device.serial} style={{fontWeight: 'bold'}} onClick={() => { - batch(() => { - dispatch(selectDevice(device)); - dispatch(selectClient(null)); - }); + onSelectDevice(device); }}> {device.displayTitle()} @@ -167,10 +188,7 @@ function computeEntries( { - batch(() => { - dispatch(selectDevice(device)); - dispatch(selectClient(client.id)); - }); + onSelectApp(device, client); }}> {client.query.app} diff --git a/desktop/app/src/sandy-chrome/appinspect/BookmarkSection.tsx b/desktop/app/src/sandy-chrome/appinspect/BookmarkSection.tsx index 995b9314b..cc44443ba 100644 --- a/desktop/app/src/sandy-chrome/appinspect/BookmarkSection.tsx +++ b/desktop/app/src/sandy-chrome/appinspect/BookmarkSection.tsx @@ -7,11 +7,17 @@ * @format */ -import React, {useCallback, useMemo} from 'react'; +import React, {useMemo} from 'react'; import {AutoComplete, Input, Typography} from 'antd'; import {StarFilled, StarOutlined} from '@ant-design/icons'; import {useStore} from '../../utils/useStore'; -import {Layout, NUX, useValue} from 'flipper-plugin'; +import { + Layout, + NUX, + TrackingScope, + useTrackedCallback, + useValue, +} from 'flipper-plugin'; import {navPluginStateSelector} from '../../chrome/LocationsButton'; // eslint-disable-next-line flipper/no-relative-imports-across-packages @@ -25,11 +31,13 @@ export function BookmarkSection() { const navPlugin = useStore(navPluginStateSelector); return navPlugin ? ( - - - + + + + + ) : null; } @@ -48,16 +56,22 @@ function BookmarkSectionInput({navPlugin}: {navPlugin: NavigationPlugin}) { [currentURI, bookmarks, patterns, 20], ); - const handleBookmarkClick = useCallback(() => { - if (isBookmarked) { - navPlugin.removeBookmark(currentURI); - } else if (currentURI) { - navPlugin.addBookmark({ - uri: currentURI, - commonName: null, - }); - } - }, [navPlugin, currentURI, isBookmarked]); + const handleBookmarkClick = useTrackedCallback( + 'bookmark', + () => { + if (isBookmarked) { + navPlugin.removeBookmark(currentURI); + } else if (currentURI) { + navPlugin.addBookmark({ + uri: currentURI, + commonName: null, + }); + } + }, + [navPlugin, currentURI, isBookmarked], + ); + + const navigate = useTrackedCallback('navigate', navPlugin.navigateTo, []); const bookmarkButton = isBookmarked ? ( @@ -69,7 +83,7 @@ function BookmarkSectionInput({navPlugin}: {navPlugin: NavigationPlugin}) { { - navPlugin.navigateTo(currentURI); + navigate(currentURI); }} /> diff --git a/desktop/app/src/sandy-chrome/appinspect/LaunchEmulator.tsx b/desktop/app/src/sandy-chrome/appinspect/LaunchEmulator.tsx index 1f8def9bf..c21ab7479 100644 --- a/desktop/app/src/sandy-chrome/appinspect/LaunchEmulator.tsx +++ b/desktop/app/src/sandy-chrome/appinspect/LaunchEmulator.tsx @@ -13,7 +13,7 @@ import {AndroidOutlined, AppleOutlined} from '@ant-design/icons'; import {Store} from '../../reducers'; import {useStore} from '../../utils/useStore'; import {launchEmulator} from '../../devices/AndroidDevice'; -import {Layout, renderReactRoot} from 'flipper-plugin'; +import {Layout, renderReactRoot, withTrackingScope} from 'flipper-plugin'; import {Provider} from 'react-redux'; import { launchSimulator, @@ -31,77 +31,81 @@ export function showEmulatorLauncher(store: Store) { type GetSimulators = typeof getSimulators; -export function LaunchEmulatorDialog({ - onClose, - getSimulators, -}: { - onClose: () => void; - getSimulators: GetSimulators; -}) { - const iosEnabled = useStore((state) => state.settingsState.enableIOS); - const androidEmulators = useStore((state) => - state.settingsState.enableAndroid ? state.connections.androidEmulators : [], - ); - const [iosEmulators, setIosEmulators] = useState([]); +export const LaunchEmulatorDialog = withTrackingScope( + function LaunchEmulatorDialog({ + onClose, + getSimulators, + }: { + onClose: () => void; + getSimulators: GetSimulators; + }) { + const iosEnabled = useStore((state) => state.settingsState.enableIOS); + const androidEmulators = useStore((state) => + state.settingsState.enableAndroid + ? state.connections.androidEmulators + : [], + ); + const [iosEmulators, setIosEmulators] = useState([]); - useEffect(() => { - if (!iosEnabled) { - return; - } - getSimulators(false).then((emulators) => { - setIosEmulators( - emulators.filter( - (device) => - device.state === 'Shutdown' && - device.deviceTypeIdentifier?.match(/iPhone|iPad/i), - ), - ); - }); - }, [iosEnabled, getSimulators]); + useEffect(() => { + if (!iosEnabled) { + return; + } + getSimulators(false).then((emulators) => { + setIosEmulators( + emulators.filter( + (device) => + device.state === 'Shutdown' && + device.deviceTypeIdentifier?.match(/iPhone|iPad/i), + ), + ); + }); + }, [iosEnabled, getSimulators]); - const items = [ - ...androidEmulators.map((name) => ( - - )), - ...iosEmulators.map((device) => ( - - )), - ]; + const items = [ + ...androidEmulators.map((name) => ( + + )), + ...iosEmulators.map((device) => ( + + )), + ]; - return ( - - - {items.length ? items : } - - - ); -} + return ( + + + {items.length ? items : } + + + ); + }, +); diff --git a/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx b/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx index f94482721..8bcfe8d20 100644 --- a/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx +++ b/desktop/app/src/sandy-chrome/appinspect/PluginList.tsx @@ -12,7 +12,7 @@ import {Badge, Button, Menu, Tooltip, Typography} from 'antd'; import {InfoIcon, SidebarTitle} from '../LeftSidebar'; import {PlusOutlined, MinusOutlined} from '@ant-design/icons'; import {Glyph, Layout, styled} from '../../ui'; -import {theme, NUX} from 'flipper-plugin'; +import {theme, NUX, Tracked} from 'flipper-plugin'; import {useDispatch, useStore} from '../../utils/useStore'; import {getPluginTitle, sortPluginsByName} from '../../utils/pluginUtils'; import {ClientPluginDefinition, DevicePluginDefinition} from '../../plugin'; @@ -225,8 +225,9 @@ function ActionButton({ icon={icon} title={title} style={{border: 'none', color: theme.textColorPrimary}} - onClick={() => { + onClick={(e) => { onClick(id); + e.stopPropagation(); }} /> ); @@ -273,26 +274,28 @@ const PluginEntry = memo(function PluginEntry({ }, [active]); return ( - - - - - - - {getPluginTitle(plugin)} - - {hovering && actions} - - + + + + + + + + {getPluginTitle(plugin)} + + {hovering && actions} + + + ); }); diff --git a/desktop/app/src/ui/components/Button.tsx b/desktop/app/src/ui/components/Button.tsx index aba99e5a8..78be3307a 100644 --- a/desktop/app/src/ui/components/Button.tsx +++ b/desktop/app/src/ui/components/Button.tsx @@ -21,7 +21,7 @@ import {useStore} from '../../utils/useStore'; import {useIsSandy} from '../../sandy-chrome/SandyContext'; import type {ButtonProps} from 'antd/lib/button'; import {DownOutlined, CheckOutlined} from '@ant-design/icons'; -import {theme} from 'flipper-plugin'; +import {theme, Tracked} from 'flipper-plugin'; type ButtonType = 'primary' | 'success' | 'warning' | 'danger'; @@ -366,17 +366,19 @@ function ClassicButton(props: Props) { } return ( - - {iconComponent} - {children} - + + + {iconComponent} + {children} + + ); } diff --git a/desktop/app/src/ui/components/ToolbarIcon.tsx b/desktop/app/src/ui/components/ToolbarIcon.tsx index 687817477..dcc15a7ec 100644 --- a/desktop/app/src/ui/components/ToolbarIcon.tsx +++ b/desktop/app/src/ui/components/ToolbarIcon.tsx @@ -12,6 +12,7 @@ import Tooltip from './Tooltip'; import {colors} from './colors'; import styled from '@emotion/styled'; import React from 'react'; +import {Tracked} from 'flipper-plugin'; type Props = React.ComponentProps & { active?: boolean; @@ -30,17 +31,19 @@ const ToolbarIconContainer = styled.div({ export default function ToolbarIcon({active, icon, title, ...props}: Props) { return ( - - - + + + + + ); } diff --git a/desktop/flipper-plugin/src/index.ts b/desktop/flipper-plugin/src/index.ts index daad65b5a..fc33ff481 100644 --- a/desktop/flipper-plugin/src/index.ts +++ b/desktop/flipper-plugin/src/index.ts @@ -58,6 +58,7 @@ export { setGlobalInteractionReporter as _setGlobalInteractionReporter, withTrackingScope, useTrackedCallback, + wrapInteractionHandler as _wrapInteractionHandler, } from './ui/Tracked'; export {sleep} from './utils/sleep'; diff --git a/desktop/flipper-plugin/src/ui/NUX.tsx b/desktop/flipper-plugin/src/ui/NUX.tsx index e35895e38..6a48f8329 100644 --- a/desktop/flipper-plugin/src/ui/NUX.tsx +++ b/desktop/flipper-plugin/src/ui/NUX.tsx @@ -21,6 +21,7 @@ import {createHash} from 'crypto'; import type {TooltipPlacement} from 'antd/lib/tooltip'; import {SandyPluginInstance} from '../plugin/Plugin'; import {theme} from './theme'; +import {Tracked} from './Tracked'; const {Text} = Typography; @@ -121,9 +122,11 @@ export function NUX({ style={{color: theme.textColorPrimary}}> {title} - + + + }> diff --git a/desktop/flipper-plugin/src/ui/Tracked.tsx b/desktop/flipper-plugin/src/ui/Tracked.tsx index 86daef4e8..b5f616e8a 100644 --- a/desktop/flipper-plugin/src/ui/Tracked.tsx +++ b/desktop/flipper-plugin/src/ui/Tracked.tsx @@ -109,7 +109,6 @@ export function useTrackedCallback( }, deps) as any; } -// Exported for test export function wrapInteractionHandler( fn: T, element: React.ReactElement | null | string,