<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 */

import React, {useEffect, useState, useCallback} from 'react';
import {
  TrackingScope,
  useLogger,
  _Sidebar,
  Layout,
  Dialog,
  _PortalsManager,
} from 'flipper-plugin';
import {Link, styled} from '../ui';
import {theme} from 'flipper-plugin';
import {ipcRenderer} from 'electron';
import {Logger} from 'flipper-common';

import {LeftRail} from './LeftRail';
import {useStore, useDispatch} from '../utils/useStore';
import {FlipperDevTools} from '../chrome/FlipperDevTools';
import {setStaticView} from '../reducers/connections';
import {toggleLeftSidebarVisible} from '../reducers/application';
import {AppInspect} from './appinspect/AppInspect';
import PluginContainer from '../PluginContainer';
import {ContentContainer} from './ContentContainer';
import {Notification} from './notification/Notification';
import ChangelogSheet, {hasNewChangesToShow} from '../chrome/ChangelogSheet';
import {getVersionString} from '../utils/versionString';
import config from '../fb-stubs/config';
import {WelcomeScreenStaticView} from './WelcomeScreen';
import fbConfig from '../fb-stubs/config';
import {isFBEmployee} from '../utils/fbEmployee';
import {notification} from 'antd';
import isProduction from '../utils/isProduction';

export type ToplevelNavItem =
  | 'appinspect'
  | 'flipperlogs'
  | 'notification'
  | undefined;
export type ToplevelProps = {
  toplevelSelection: ToplevelNavItem;
  setToplevelSelection: (_newSelection: ToplevelNavItem) => void;
};

export function SandyApp() {
  const logger = useLogger();
  const dispatch = useDispatch();
  const leftSidebarVisible = useStore(
    (state) => state.application.leftSidebarVisible,
  );
  const staticView = useStore((state) => state.connections.staticView);

  /**
   * top level navigation uses two pieces of state, selection stored here, and selection that is based on what is stored in the reducer (which might be influenced by redux action dispatches to different means).
   * The logic here is to sync both, but without modifying the navigation related reducers to not break classic Flipper.
   * It is possible to simplify this in the future.
   */
  const [toplevelSelection, setStoredToplevelSelection] =
    useState<ToplevelNavItem>('appinspect');

  // Handle toplevel nav clicks from LeftRail
  const setToplevelSelection = useCallback(
    (newSelection: ToplevelNavItem) => {
      // toggle sidebar visibility if needed
      const hasLeftSidebar =
        newSelection === 'appinspect' || newSelection === 'notification';
      if (hasLeftSidebar) {
        if (newSelection === toplevelSelection) {
          dispatch(toggleLeftSidebarVisible());
        } else {
          dispatch(toggleLeftSidebarVisible(true));
        }
      }
      switch (newSelection) {
        case 'flipperlogs':
          dispatch(setStaticView(FlipperDevTools));
          break;
        default:
      }
      setStoredToplevelSelection(newSelection);
    },
    [dispatch, toplevelSelection],
  );

  useEffect(() => {
    document.title = `Flipper (${getVersionString()}${
      config.isFBBuild ? '@FB' : ''
    })`;

    registerStartupTime(logger);
    if (hasNewChangesToShow(window.localStorage)) {
      Dialog.showModal((onHide) => <ChangelogSheet onHide={onHide} recent />);
    }
    // don't warn about logger, even with a new logger we don't want to re-register
    // eslint-disable-next-line
  }, []);

  useEffect(() => {
    if (fbConfig.warnFBEmployees && isProduction()) {
      isFBEmployee()
        .then((isEmployee) => {
          if (isEmployee) {
            notification.warning({
              placement: 'bottomLeft',
              message: 'Please use Flipper@FB',
              description: (
                <>
                  You are using the open-source version of Flipper. Install the
                  internal build from{' '}
                  <Link href="munki://detail-Flipper">
                    Managed Software Center
                  </Link>{' '}
                  to get access to more plugins.
                </>
              ),
              duration: null,
            });
          }
        })
        .catch((e) => {
          console.warn('Failed to check if user is employee', e);
        });
    }
  }, []);

  const leftMenuContent = !leftSidebarVisible ? null : toplevelSelection ===
    'appinspect' ? (
    <AppInspect />
  ) : toplevelSelection === 'notification' ? (
    <Notification />
  ) : null;

  return (
    <Layout.Container grow>
      <Layout.Left>
        <Layout.Horizontal>
          <LeftRail
            toplevelSelection={toplevelSelection}
            setToplevelSelection={setToplevelSelection}
          />
          <_Sidebar width={250} minWidth={220} maxWidth={800} gutter>
            {leftMenuContent && (
              <TrackingScope scope={toplevelSelection!}>
                {leftMenuContent}
              </TrackingScope>
            )}
          </_Sidebar>
        </Layout.Horizontal>
        <MainContainer>
          {staticView ? (
            <TrackingScope
              scope={
                (staticView as any).displayName ??
                staticView.name ??
                staticView.constructor?.name ??
                'unknown static view'
              }>
              {staticView === WelcomeScreenStaticView ? (
                React.createElement(staticView) /* avoid shadow */
              ) : (
                <ContentContainer>
                  {React.createElement(staticView, {
                    logger: logger,
                  })}
                </ContentContainer>
              )}
            </TrackingScope>
          ) : (
            <PluginContainer logger={logger} />
          )}
          {outOfContentsContainer}
        </MainContainer>
      </Layout.Left>
      <_PortalsManager />
    </Layout.Container>
  );
}

const outOfContentsContainer = (
  <div
    style={{
      position: 'relative',
      width: '100%',
      height: '100%',
      display: 'none',
    }}>
    <div
      id="flipper-out-of-contents-container"
      style={{
        display: 'none',
        position: 'absolute',
        right: 0,
        bottom: 0,<commit_msg>Fix layout issue on plugin container<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 */

import React, {useEffect, useState, useCallback} from 'react';
import {
  TrackingScope,
  useLogger,
  _Sidebar,
  Layout,
  Dialog,
  _PortalsManager,
} from 'flipper-plugin';
import {Link, styled} from '../ui';
import {theme} from 'flipper-plugin';
import {ipcRenderer} from 'electron';
import {Logger} from 'flipper-common';

import {LeftRail} from './LeftRail';
import {useStore, useDispatch} from '../utils/useStore';
import {FlipperDevTools} from '../chrome/FlipperDevTools';
import {setStaticView} from '../reducers/connections';
import {toggleLeftSidebarVisible} from '../reducers/application';
import {AppInspect} from './appinspect/AppInspect';
import PluginContainer from '../PluginContainer';
import {ContentContainer} from './ContentContainer';
import {Notification} from './notification/Notification';
import ChangelogSheet, {hasNewChangesToShow} from '../chrome/ChangelogSheet';
import {getVersionString} from '../utils/versionString';
import config from '../fb-stubs/config';
import {WelcomeScreenStaticView} from './WelcomeScreen';
import fbConfig from '../fb-stubs/config';
import {isFBEmployee} from '../utils/fbEmployee';
import {notification} from 'antd';
import isProduction from '../utils/isProduction';

export type ToplevelNavItem =
  | 'appinspect'
  | 'flipperlogs'
  | 'notification'
  | undefined;
export type ToplevelProps = {
  toplevelSelection: ToplevelNavItem;
  setToplevelSelection: (_newSelection: ToplevelNavItem) => void;
};

export function SandyApp() {
  const logger = useLogger();
  const dispatch = useDispatch();
  const leftSidebarVisible = useStore(
    (state) => state.application.leftSidebarVisible,
  );
  const staticView = useStore((state) => state.connections.staticView);

  /**
   * top level navigation uses two pieces of state, selection stored here, and selection that is based on what is stored in the reducer (which might be influenced by redux action dispatches to different means).
   * The logic here is to sync both, but without modifying the navigation related reducers to not break classic Flipper.
   * It is possible to simplify this in the future.
   */
  const [toplevelSelection, setStoredToplevelSelection] =
    useState<ToplevelNavItem>('appinspect');

  // Handle toplevel nav clicks from LeftRail
  const setToplevelSelection = useCallback(
    (newSelection: ToplevelNavItem) => {
      // toggle sidebar visibility if needed
      const hasLeftSidebar =
        newSelection === 'appinspect' || newSelection === 'notification';
      if (hasLeftSidebar) {
        if (newSelection === toplevelSelection) {
          dispatch(toggleLeftSidebarVisible());
        } else {
          dispatch(toggleLeftSidebarVisible(true));
        }
      }
      switch (newSelection) {
        case 'flipperlogs':
          dispatch(setStaticView(FlipperDevTools));
          break;
        default:
      }
      setStoredToplevelSelection(newSelection);
    },
    [dispatch, toplevelSelection],
  );

  useEffect(() => {
    document.title = `Flipper (${getVersionString()}${
      config.isFBBuild ? '@FB' : ''
    })`;

    registerStartupTime(logger);
    if (hasNewChangesToShow(window.localStorage)) {
      Dialog.showModal((onHide) => <ChangelogSheet onHide={onHide} recent />);
    }
    // don't warn about logger, even with a new logger we don't want to re-register
    // eslint-disable-next-line
  }, []);

  useEffect(() => {
    if (fbConfig.warnFBEmployees && isProduction()) {
      isFBEmployee()
        .then((isEmployee) => {
          if (isEmployee) {
            notification.warning({
              placement: 'bottomLeft',
              message: 'Please use Flipper@FB',
              description: (
                <>
                  You are using the open-source version of Flipper. Install the
                  internal build from{' '}
                  <Link href="munki://detail-Flipper">
                    Managed Software Center
                  </Link>{' '}
                  to get access to more plugins.
                </>
              ),
              duration: null,
            });
          }
        })
        .catch((e) => {
          console.warn('Failed to check if user is employee', e);
        });
    }
  }, []);

  const leftMenuContent = !leftSidebarVisible ? null : toplevelSelection ===
    'appinspect' ? (
    <AppInspect />
  ) : toplevelSelection === 'notification' ? (
    <Notification />
  ) : null;

  return (
    <Layout.Bottom>
      <Layout.Left>
        <Layout.Horizontal>
          <LeftRail
            toplevelSelection={toplevelSelection}
            setToplevelSelection={setToplevelSelection}
          />
          <_Sidebar width={250} minWidth={220} maxWidth={800} gutter>
            {leftMenuContent && (
              <TrackingScope scope={toplevelSelection!}>
                {leftMenuContent}
              </TrackingScope>
            )}
          </_Sidebar>
        </Layout.Horizontal>
        <MainContainer>
          {staticView ? (
            <TrackingScope
              scope={
                (staticView as any).displayName ??
                staticView.name ??
                staticView.constructor?.name ??
                'unknown static view'
              }>
              {staticView === WelcomeScreenStaticView ? (
                React.createElement(staticView) /* avoid shadow */
              ) : (
                <ContentContainer>
                  {React.createElement(staticView, {
                    logger: logger,
                  })}
                </ContentContainer>
              )}
            </TrackingScope>
          ) : (
            <PluginContainer logger={logger} />
          )}
          {outOfContentsContainer}
        </MainContainer>
      </Layout.Left>
      <_PortalsManager />
    </Layout.Bottom>
  );
}

const outOfContentsContainer = (
  <div
    style={{
      position: 'relative',
      width: '100%',
      height: '100%',
      display: 'none',
    }}>
    <div
      id="flipper-out-of-contents-container"
      style={{
        display: 'none',
        position: 'absolute',
        right: 0,
        bottom: 0,
{'fraction_non_alphanumeric': 0.11857769423558898, 'fraction_numerical': 0.002662907268170426, 'mean_word_length': 2.347051114023591, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2481077', 'n_tokens_mistral': 3543, 'n_tokens_neox': 3444, 'n_words': 879}