/
ashipov
/
react
Обзор
Документация
Войти
/
ashipov
/
react
Код
Запросы
0
Задачи 2.0
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
packages/react-devtools-shared/src/devtools/views/Settings/SettingsModal.js
147 строк
4 KB
Ruslan Lesiutin
fix[react-devtools]: update profiling status before receiving response from backend (#31117)
09 окт 2024, 15:23
Не верифицирован
09 окт 2024, 15:23
dbf80c8
Код
Авторство
О чём код?
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import * as React from 'react'; import {useCallback, useContext, useEffect, useMemo, useRef} from 'react'; import {SettingsModalContext} from './SettingsModalContext'; import Button from '../Button'; import ButtonIcon from '../ButtonIcon'; import TabBar from '../TabBar'; import {StoreContext} from '../context'; import { useLocalStorage, useModalDismissSignal, useSubscription, } from '../hooks'; import ComponentsSettings from './ComponentsSettings'; import DebuggingSettings from './DebuggingSettings'; import GeneralSettings from './GeneralSettings'; import ProfilerSettings from './ProfilerSettings'; import styles from './SettingsModal.css'; import type Store from 'react-devtools-shared/src/devtools/store'; type TabID = 'general' | 'debugging' | 'components' | 'profiler'; export default function SettingsModal(): React.Node { const {isModalShowing, setIsModalShowing} = useContext(SettingsModalContext); const store = useContext(StoreContext); const {profilerStore} = store; // Updating preferences while profiling is in progress could break things (e.g. filtering) // Explicitly disallow it for now. const isProfilingSubscription = useMemo( () => ({ getCurrentValue: () => profilerStore.isProfilingBasedOnUserInput, subscribe: (callback: Function) => { profilerStore.addListener('isProfiling', callback); return () => profilerStore.removeListener('isProfiling', callback); }, }), [profilerStore], ); const isProfiling = useSubscription<boolean>(isProfilingSubscription); if (isProfiling && isModalShowing) { setIsModalShowing(false); } if (!isModalShowing) { return null; } return <SettingsModalImpl store={store} />; } type ImplProps = {store: Store}; function SettingsModalImpl({store}: ImplProps) { const {setIsModalShowing, environmentNames, hookSettings} = useContext(SettingsModalContext); const dismissModal = useCallback( () => setIsModalShowing(false), [setIsModalShowing], ); const [selectedTabID, selectTab] = useLocalStorage<TabID>( 'React::DevTools::selectedSettingsTabID', 'general', ); const modalRef = useRef<HTMLDivElement | null>(null); useModalDismissSignal(modalRef, dismissModal); useEffect(() => { if (modalRef.current !== null) { modalRef.current.focus(); } }, [modalRef]); let view = null; switch (selectedTabID) { case 'components': view = <ComponentsSettings environmentNames={environmentNames} />; break; case 'debugging': view = <DebuggingSettings hookSettings={hookSettings} store={store} />; break; case 'general': view = <GeneralSettings />; break; case 'profiler': view = <ProfilerSettings />; break; default: break; } return ( <div className={styles.Background}> <div className={styles.Modal} ref={modalRef}> <div className={styles.Tabs}> <TabBar currentTab={selectedTabID} id="Settings" selectTab={selectTab} tabs={tabs} type="settings" /> <div className={styles.Spacer} /> <Button onClick={dismissModal} title="Close settings dialog"> <ButtonIcon type="close" /> </Button> </div> <div className={styles.Content}>{view}</div> </div> </div> ); } const tabs = [ { id: 'general', icon: 'settings', label: 'General', }, { id: 'debugging', icon: 'bug', label: 'Debugging', }, { id: 'components', icon: 'components', label: 'Components', }, { id: 'profiler', icon: 'profiler', label: 'Profiler', }, ];