<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 from 'react';
import {Button, Dropdown, Menu, Radio, Typography} from 'antd';
import {
  AppleOutlined,
  AndroidOutlined,
  WindowsOutlined,
  CaretDownOutlined,
} from '@ant-design/icons';
import {Glyph, Layout, styled} from '../../ui';
import {theme, useTrackedCallback, useValue} from 'flipper-plugin';
import {batch} from 'react-redux';
import {useDispatch, useStore} from '../../utils/useStore';
import {
  canBeDefaultDevice,
  getAvailableClients,
  selectClient,
  selectDevice,
} from '../../reducers/connections';
import BaseDevice, {OS} from '../../server/devices/BaseDevice';
import Client from '../../Client';
import {State} from '../../reducers';
import {brandColors, brandIcons, colors} from '../../ui/components/colors';
import {TroubleshootingGuide} from './fb-stubs/TroubleshootingGuide';
import GK from '../../fb-stubs/GK';

const {Text} = Typography;

function getOsIcon(os?: OS) {
  switch (os) {
    case 'iOS':
      return <AppleOutlined />;
    case 'Android':
      return <AndroidOutlined />;
    case 'Windows':
      return <WindowsOutlined />;
    default:
      undefined;
  }
}

export function AppSelector() {
  const dispatch = useDispatch();
  const {devices, selectedDevice, clients, uninitializedClients, selectedApp} =
    useStore((state) => state.connections);
  useValue(selectedDevice?.connected, false); // subscribe to future archived state changes

  const onSelectDevice = useTrackedCallback(
    'select-device',
    (device: BaseDevice) => {
      batch(() => {
        dispatch(selectDevice(device));
        dispatch(selectClient(null));
      });
    },
    [],
  );
  const onSelectApp = useTrackedCallback(
    'select-app',
    (device: BaseDevice, client: Client) => {
      batch(() => {
        dispatch(selectDevice(device));
        dispatch(selectClient(client.id));
      });
    },
    [],
  );

  const entries = computeEntries(
    devices,
    clients,
    uninitializedClients,
    onSelectDevice,
    onSelectApp,
  );
  const client = clients.find((client) => client.id === selectedApp);

  return (
    <>
      <Radio.Group
        value={selectedApp}
        size="small"
        style={{
          display: 'flex',
          flex: 1,
        }}>
        <Dropdown
          trigger={['click']}
          overlay={
            <Menu selectedKeys={selectedApp ? [selectedApp] : []}>
              {entries}
            </Menu>
          }>
          <AppInspectButton title="Select the device / app to inspect">
            <Layout.Horizontal gap center>
              <AppIcon appname={client?.query.app} device={selectedDevice} />
              <Layout.Container grow shrink>
                <Text strong>{client?.query.app ?? ''}</Text>
                <Text>{selectedDevice?.title || 'Available devices'}</Text>
              </Layout.Container>
              <CaretDownOutlined />
            </Layout.Horizontal>
          </AppInspectButton>
        </Dropdown>
      </Radio.Group>
      <TroubleshootingGuide
        showGuide={GK.get('flipper_self_sufficiency')}
        devicesDetected={entries.length}
      />
    </>
  );
}<commit_msg>Improve UI when no devices connected<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 from 'react';
import {Button, Dropdown, Menu, Radio, Typography} from 'antd';
import {
  AppleOutlined,
  AndroidOutlined,
  WindowsOutlined,
  CaretDownOutlined,
} from '@ant-design/icons';
import {Glyph, Layout, styled} from '../../ui';
import {theme, useTrackedCallback, useValue} from 'flipper-plugin';
import {batch} from 'react-redux';
import {useDispatch, useStore} from '../../utils/useStore';
import {
  canBeDefaultDevice,
  getAvailableClients,
  selectClient,
  selectDevice,
} from '../../reducers/connections';
import BaseDevice, {OS} from '../../server/devices/BaseDevice';
import Client from '../../Client';
import {State} from '../../reducers';
import {brandColors, brandIcons, colors} from '../../ui/components/colors';
import {TroubleshootingGuide} from './fb-stubs/TroubleshootingGuide';
import GK from '../../fb-stubs/GK';

const {Text} = Typography;

function getOsIcon(os?: OS) {
  switch (os) {
    case 'iOS':
      return <AppleOutlined />;
    case 'Android':
      return <AndroidOutlined />;
    case 'Windows':
      return <WindowsOutlined />;
    default:
      undefined;
  }
}

export function AppSelector() {
  const dispatch = useDispatch();
  const {devices, selectedDevice, clients, uninitializedClients, selectedApp} =
    useStore((state) => state.connections);
  useValue(selectedDevice?.connected, false); // subscribe to future archived state changes

  const onSelectDevice = useTrackedCallback(
    'select-device',
    (device: BaseDevice) => {
      batch(() => {
        dispatch(selectDevice(device));
        dispatch(selectClient(null));
      });
    },
    [],
  );
  const onSelectApp = useTrackedCallback(
    'select-app',
    (device: BaseDevice, client: Client) => {
      batch(() => {
        dispatch(selectDevice(device));
        dispatch(selectClient(client.id));
      });
    },
    [],
  );

  const entries = computeEntries(
    devices,
    clients,
    uninitializedClients,
    onSelectDevice,
    onSelectApp,
  );
  const client = clients.find((client) => client.id === selectedApp);

  return (
    <>
      {entries.length ? (
        <Radio.Group
          value={selectedApp}
          size="small"
          style={{
            display: 'flex',
            flex: 1,
          }}>
          <Dropdown
            trigger={['click']}
            overlay={
              <Menu selectedKeys={selectedApp ? [selectedApp] : []}>
                {entries}
              </Menu>
            }>
            <AppInspectButton title="Select the device / app to inspect">
              <Layout.Horizontal gap center>
                <AppIcon appname={client?.query.app} device={selectedDevice} />
                <Layout.Container grow shrink>
                  <Text strong>{client?.query.app ?? ''}</Text>
                  <Text>{selectedDevice?.title || 'Available devices'}</Text>
                </Layout.Container>
                <CaretDownOutlined />
              </Layout.Horizontal>
            </AppInspectButton>
          </Dropdown>
        </Radio.Group>
      ) : (
        <Text>{'No devices available'}</Text>
      )}
      <TroubleshootingGuide
        showGuide={GK.get('flipper_self_sufficiency')}
        devicesDetected={entries.length}
      />
    </>
  );
}
{'fraction_non_alphanumeric': 0.14289871944121071, 'fraction_numerical': 0.0002910360884749709, 'mean_word_length': 2.5318602261048304, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 65, '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': '5392103', 'n_tokens_mistral': 1977, 'n_tokens_neox': 1952, 'n_words': 469}