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, useRef} from 'react';
    
  12. import {useSubscription} from '../hooks';
    
  13. import {StoreContext} from '../context';
    
  14. import {ProfilerContext} from 'react-devtools-shared/src/devtools/views/Profiler/ProfilerContext';
    
  15. 
    
  16. import styles from './SettingsShared.css';
    
  17. 
    
  18. export default function ProfilerSettings(_: {}): React.Node {
    
  19.   const {
    
  20.     isCommitFilterEnabled,
    
  21.     minCommitDuration,
    
  22.     setIsCommitFilterEnabled,
    
  23.     setMinCommitDuration,
    
  24.   } = useContext(ProfilerContext);
    
  25.   const store = useContext(StoreContext);
    
  26. 
    
  27.   const recordChangeDescriptionsSubscription = useMemo(
    
  28.     () => ({
    
  29.       getCurrentValue: () => store.recordChangeDescriptions,
    
  30.       subscribe: (callback: Function) => {
    
  31.         store.addListener('recordChangeDescriptions', callback);
    
  32.         return () => store.removeListener('recordChangeDescriptions', callback);
    
  33.       },
    
  34.     }),
    
  35.     [store],
    
  36.   );
    
  37.   const recordChangeDescriptions = useSubscription<boolean>(
    
  38.     recordChangeDescriptionsSubscription,
    
  39.   );
    
  40. 
    
  41.   const updateRecordChangeDescriptions = useCallback(
    
  42.     ({currentTarget}: $FlowFixMe) => {
    
  43.       store.recordChangeDescriptions = currentTarget.checked;
    
  44.     },
    
  45.     [store],
    
  46.   );
    
  47.   const updateMinCommitDuration = useCallback(
    
  48.     (event: SyntheticEvent<HTMLInputElement>) => {
    
  49.       const newValue = parseFloat(event.currentTarget.value);
    
  50.       setMinCommitDuration(
    
  51.         Number.isNaN(newValue) || newValue <= 0 ? 0 : newValue,
    
  52.       );
    
  53.     },
    
  54.     [setMinCommitDuration],
    
  55.   );
    
  56.   const updateIsCommitFilterEnabled = useCallback(
    
  57.     (event: SyntheticEvent<HTMLInputElement>) => {
    
  58.       const checked = event.currentTarget.checked;
    
  59.       setIsCommitFilterEnabled(checked);
    
  60.       if (checked) {
    
  61.         if (minCommitDurationInputRef.current !== null) {
    
  62.           minCommitDurationInputRef.current.focus();
    
  63.         }
    
  64.       }
    
  65.     },
    
  66.     [setIsCommitFilterEnabled],
    
  67.   );
    
  68. 
    
  69.   const minCommitDurationInputRef = useRef<HTMLInputElement | null>(null);
    
  70. 
    
  71.   return (
    
  72.     <div className={styles.Settings}>
    
  73.       <div className={styles.Setting}>
    
  74.         <label>
    
  75.           <input
    
  76.             type="checkbox"
    
  77.             checked={recordChangeDescriptions}
    
  78.             onChange={updateRecordChangeDescriptions}
    
  79.           />{' '}
    
  80.           Record why each component rendered while profiling.
    
  81.         </label>
    
  82.       </div>
    
  83. 
    
  84.       <div className={styles.Setting}>
    
  85.         <label>
    
  86.           <input
    
  87.             checked={isCommitFilterEnabled}
    
  88.             onChange={updateIsCommitFilterEnabled}
    
  89.             type="checkbox"
    
  90.           />{' '}
    
  91.           Hide commits below
    
  92.         </label>{' '}
    
  93.         <input
    
  94.           className={styles.Input}
    
  95.           onChange={updateMinCommitDuration}
    
  96.           ref={minCommitDurationInputRef}
    
  97.           type="number"
    
  98.           value={minCommitDuration}
    
  99.         />{' '}
    
  100.         (ms)
    
  101.       </div>
    
  102.     </div>
    
  103.   );
    
  104. }