<commit_before>import { t } from 'app/i18next-t';
import { ItemTriage } from 'app/item-triage/ItemTriage';
import clsx from 'clsx';
import React from 'react';
import { Frame, Track, View, ViewPager } from 'react-view-pager';
import { DimItem } from '../inventory/item-types';
import { percent } from '../shell/filters';
import { AppIcon, openDropdownIcon } from '../shell/icons';
import { ItemPopupExtraInfo } from './item-popup';
import ItemDetails from './ItemDetails';
import './ItemPopupBody.scss';

export const enum ItemPopupTab {
  Overview,
  Triage,
}

const spring = { stiffness: 200, damping: 22 };

/** The main portion of the item popup, with pages of info (Actions, Details, Reviews) */
export default function ItemPopupBody({
  item,
  failureStrings,
  extraInfo,
  tab,
  expanded,
  onTabChanged,
  onToggleExpanded,
}: {
  item: DimItem;
  failureStrings?: string[];
  extraInfo?: ItemPopupExtraInfo;
  tab: ItemPopupTab;
  expanded: boolean;
  onTabChanged(tab: ItemPopupTab): void;
  onToggleExpanded(): void;
}) {
  failureStrings = Array.from(failureStrings || []);
  if (!item.canPullFromPostmaster && item.location.inPostmaster) {
    failureStrings.push(t('MovePopup.CantPullFromPostmaster'));
  }

  const showDetailsByDefault = !item.equipment && item.notransfer;
  const itemDetails = showDetailsByDefault || expanded;

  const tabs = [
    {
      tab: ItemPopupTab.Overview,
      title: t('MovePopup.OverviewTab'),
      component: <ItemDetails item={item} extraInfo={extraInfo} />,
    },
  ];
  if (
    $featureFlags.triage &&
    item.destinyVersion === 2 &&
    (item.bucket.inArmor ||
      (item.bucket.sort === 'Weapons' &&
        item.bucket.type !== 'SeasonalArtifacts' &&
        item.bucket.type !== 'Class'))
    //   ||
    // (item.bucket.sort === 'General' &&
    //   (item.bucket.type === 'Ghost' ||        // enable these once there's
    //     item.bucket.type === 'Vehicle' ||     // factor rules for them
    //     item.bucket.type === 'Ships'))
  ) {
    tabs.push({
      tab: ItemPopupTab.Triage,
      title: t('MovePopup.TriageTab'),
      component: <ItemTriage item={item} />,
    });
  }

  const onViewChange = (indices) => {
    onTabChanged(tabs[indices[0]].tab);
  };

  const onRest = () => onTabChanged(tab);

  return (
    <div>
      {/* TODO: Should these be in the details? Or in the header? */}
      {item.percentComplete !== 0 && !item.complete && (
        <div className="item-xp-bar" style={{ width: percent(item.percentComplete) }} />
      )}
      {failureStrings.map(
        (failureString) =>
          failureString.length > 0 && (
            <div className="item-details failure-reason" key={failureString}>
              {failureString}
            </div>
          )
      )}
      <div className="move-popup-details">
        {itemDetails ? (
          tabs.length > 1 ? (
            <>
              <div className="move-popup-tabs">
                {tabs.map((ta) => (
                  <span
                    key={ta.tab}
                    className={clsx('move-popup-tab', {
                      selected: tab === ta.tab,
                    })}
                    onClick={() => onTabChanged(ta.tab)}
                  >
                    {ta.title}
                  </span>
                ))}
              </div>
              <ViewPager>
                <Frame className="frame" autoSize="height">
                  <Track
                    currentView={tab}
                    contain={false}
                    className="track"
                    onViewChange={onViewChange}
                    onRest={onRest}
                    springConfig={spring}
                  >
                    {tabs.map((ta) => (
                      <View key={ta.tab}>{ta.component}</View>
                    ))}
                  </Track>
                </Frame>
              </ViewPager>
            </><commit_msg>Remove react-view-pager from item popup<commit_after>import { t } from 'app/i18next-t';
import { ItemTriage } from 'app/item-triage/ItemTriage';
import clsx from 'clsx';
import React from 'react';
import { DimItem } from '../inventory/item-types';
import { percent } from '../shell/filters';
import { AppIcon, openDropdownIcon } from '../shell/icons';
import { ItemPopupExtraInfo } from './item-popup';
import ItemDetails from './ItemDetails';
import './ItemPopupBody.scss';

export const enum ItemPopupTab {
  Overview,
  Triage,
}

/** The main portion of the item popup, with pages of info (Actions, Details, Reviews) */
export default function ItemPopupBody({
  item,
  failureStrings,
  extraInfo,
  tab,
  expanded,
  onTabChanged,
  onToggleExpanded,
}: {
  item: DimItem;
  failureStrings?: string[];
  extraInfo?: ItemPopupExtraInfo;
  tab: ItemPopupTab;
  expanded: boolean;
  onTabChanged(tab: ItemPopupTab): void;
  onToggleExpanded(): void;
}) {
  failureStrings = Array.from(failureStrings || []);
  if (!item.canPullFromPostmaster && item.location.inPostmaster) {
    failureStrings.push(t('MovePopup.CantPullFromPostmaster'));
  }

  const showDetailsByDefault = !item.equipment && item.notransfer;
  const itemDetails = showDetailsByDefault || expanded;

  const tabs = [
    {
      tab: ItemPopupTab.Overview,
      title: t('MovePopup.OverviewTab'),
      component: <ItemDetails item={item} extraInfo={extraInfo} />,
    },
  ];
  if (
    $featureFlags.triage &&
    item.destinyVersion === 2 &&
    (item.bucket.inArmor ||
      (item.bucket.sort === 'Weapons' &&
        item.bucket.type !== 'SeasonalArtifacts' &&
        item.bucket.type !== 'Class'))
    //   ||
    // (item.bucket.sort === 'General' &&
    //   (item.bucket.type === 'Ghost' ||        // enable these once there's
    //     item.bucket.type === 'Vehicle' ||     // factor rules for them
    //     item.bucket.type === 'Ships'))
  ) {
    tabs.push({
      tab: ItemPopupTab.Triage,
      title: t('MovePopup.TriageTab'),
      component: <ItemTriage item={item} />,
    });
  }

  return (
    <div>
      {/* TODO: Should these be in the details? Or in the header? */}
      {item.percentComplete !== 0 && !item.complete && (
        <div className="item-xp-bar" style={{ width: percent(item.percentComplete) }} />
      )}
      {failureStrings.map(
        (failureString) =>
          failureString.length > 0 && (
            <div className="item-details failure-reason" key={failureString}>
              {failureString}
            </div>
          )
      )}
      <div className="move-popup-details">
        {itemDetails ? (
          tabs.length > 1 ? (
            <>
              <div className="move-popup-tabs">
                {tabs.map((ta) => (
                  <span
                    key={ta.tab}
                    className={clsx('move-popup-tab', {
                      selected: tab === ta.tab,
                    })}
                    onClick={() => onTabChanged(ta.tab)}
                  >
                    {ta.title}
                  </span>
                ))}
              </div>
              <div>{tabs.find((t) => t.tab === tab)?.component}</div>
            </>
{'fraction_non_alphanumeric': 0.14926419060967064, 'fraction_numerical': 0.0025227750525578137, 'mean_word_length': 2.0288624787775893, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1541799', 'n_tokens_mistral': 2140, 'n_tokens_neox': 2080, 'n_words': 432}