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 {Fragment, useContext, useEffect} from 'react';
    
  12. import {BridgeContext} from './context';
    
  13. import {ModalDialogContext} from './ModalDialog';
    
  14. 
    
  15. import styles from './WarnIfLegacyBackendDetected.css';
    
  16. 
    
  17. export default function WarnIfLegacyBackendDetected(_: {}): null {
    
  18.   const bridge = useContext(BridgeContext);
    
  19.   const {dispatch} = useContext(ModalDialogContext);
    
  20. 
    
  21.   // Detect pairing with legacy v3 backend.
    
  22.   // We do this by listening to a message that it broadcasts but the v4 backend doesn't.
    
  23.   // In this case the frontend should show upgrade instructions.
    
  24.   useEffect(() => {
    
  25.     // Wall.listen returns a cleanup function
    
  26.     let unlisten: $FlowFixMe = bridge.wall.listen(message => {
    
  27.       switch (message.type) {
    
  28.         case 'call':
    
  29.         case 'event':
    
  30.         case 'many-events':
    
  31.           // Any of these types indicate the v3 backend.
    
  32.           dispatch({
    
  33.             canBeDismissed: false,
    
  34.             id: 'WarnIfLegacyBackendDetected',
    
  35.             type: 'SHOW',
    
  36.             title: 'DevTools v4 is incompatible with this version of React',
    
  37.             content: <InvalidBackendDetected />,
    
  38.           });
    
  39. 
    
  40.           // Once we've identified the backend version, it's safe to unsubscribe.
    
  41.           if (typeof unlisten === 'function') {
    
  42.             unlisten();
    
  43.             unlisten = null;
    
  44.           }
    
  45.           break;
    
  46.         default:
    
  47.           break;
    
  48.       }
    
  49. 
    
  50.       switch (message.event) {
    
  51.         case 'isBackendStorageAPISupported':
    
  52.         case 'isNativeStyleEditorSupported':
    
  53.         case 'operations':
    
  54.         case 'overrideComponentFilters':
    
  55.           // Any of these is sufficient to indicate a v4 backend.
    
  56.           // Once we've identified the backend version, it's safe to unsubscribe.
    
  57.           if (typeof unlisten === 'function') {
    
  58.             unlisten();
    
  59.             unlisten = null;
    
  60.           }
    
  61.           break;
    
  62.         default:
    
  63.           break;
    
  64.       }
    
  65.     });
    
  66. 
    
  67.     return () => {
    
  68.       if (typeof unlisten === 'function') {
    
  69.         unlisten();
    
  70.         unlisten = null;
    
  71.       }
    
  72.     };
    
  73.   }, [bridge, dispatch]);
    
  74. 
    
  75.   return null;
    
  76. }
    
  77. 
    
  78. function InvalidBackendDetected(_: {}) {
    
  79.   return (
    
  80.     <Fragment>
    
  81.       <p>Either upgrade React or install React DevTools v3:</p>
    
  82.       <code className={styles.Command}>npm install -d react-devtools@^3</code>
    
  83.     </Fragment>
    
  84.   );
    
  85. }