1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. import * as React from 'react';
    
  11. import {useCallback, useContext, useMemo} from 'react';
    
  12. import Button from '../Button';
    
  13. import ButtonIcon from '../ButtonIcon';
    
  14. import {BridgeContext, StoreContext} from '../context';
    
  15. import {useSubscription} from '../hooks';
    
  16. 
    
  17. type SubscriptionData = {
    
  18.   recordChangeDescriptions: boolean,
    
  19.   supportsReloadAndProfile: boolean,
    
  20. };
    
  21. 
    
  22. export default function ReloadAndProfileButton({
    
  23.   disabled,
    
  24. }: {
    
  25.   disabled: boolean,
    
  26. }): React.Node {
    
  27.   const bridge = useContext(BridgeContext);
    
  28.   const store = useContext(StoreContext);
    
  29. 
    
  30.   const subscription = useMemo(
    
  31.     () => ({
    
  32.       getCurrentValue: () => ({
    
  33.         recordChangeDescriptions: store.recordChangeDescriptions,
    
  34.         supportsReloadAndProfile: store.supportsReloadAndProfile,
    
  35.       }),
    
  36.       subscribe: (callback: Function) => {
    
  37.         store.addListener('recordChangeDescriptions', callback);
    
  38.         store.addListener('supportsReloadAndProfile', callback);
    
  39.         return () => {
    
  40.           store.removeListener('recordChangeDescriptions', callback);
    
  41.           store.removeListener('supportsReloadAndProfile', callback);
    
  42.         };
    
  43.       },
    
  44.     }),
    
  45.     [store],
    
  46.   );
    
  47.   const {recordChangeDescriptions, supportsReloadAndProfile} =
    
  48.     useSubscription<SubscriptionData>(subscription);
    
  49. 
    
  50.   const reloadAndProfile = useCallback(() => {
    
  51.     // TODO If we want to support reload-and-profile for e.g. React Native,
    
  52.     // we might need to also start profiling here before reloading the app (since DevTools itself isn't reloaded).
    
  53.     // We'd probably want to do this before reloading though, to avoid sending a message on a disconnected port in the browser.
    
  54.     // For now, let's just skip doing it entirely to avoid paying snapshot costs for data we don't need.
    
  55.     // startProfiling();
    
  56. 
    
  57.     bridge.send('reloadAndProfile', recordChangeDescriptions);
    
  58.   }, [bridge, recordChangeDescriptions]);
    
  59. 
    
  60.   if (!supportsReloadAndProfile) {
    
  61.     return null;
    
  62.   }
    
  63. 
    
  64.   return (
    
  65.     <Button
    
  66.       disabled={disabled}
    
  67.       onClick={reloadAndProfile}
    
  68.       title="Reload and start profiling">
    
  69.       <ButtonIcon type="reload" />
    
  70.     </Button>
    
  71.   );
    
  72. }