<commit_before>import { observer } from 'mobx-react'; // eslint-disable-line no-unused-vars
import React from 'react';
import { Ripples } from 'nersent-ui';

// Constants and defaults
import tabAnimations from '../../defaults/tab-animations';

// Utils
import { closeWindow } from '../../utils/window';

// Styles
import { Close, StyledTab, Title, Icon, Content } from './styles';

// Models
import Tab from '../../models/tab';
import TabGroup from '../../models/tab-group';

import Store from '../../store';

interface IProps {
  key: number;
  tab: Tab;
  tabGroup: TabGroup;
  selected: boolean;
  onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
  styles?: any;
}

@observer
export default class extends React.Component<IProps, {}> {
  private ripples: Ripples;
  private iconRipples: Ripples;
  private tab: HTMLDivElement;

  public componentDidMount() {
    const { tab } = this.props;

    const frame = () => {
      if (this.tab != null) {
        const boundingRect = this.tab.getBoundingClientRect();
        if (
          Store.mouse.x >= boundingRect.left &&
          Store.mouse.x <= boundingRect.left + this.tab.offsetWidth &&
          Store.mouse.y >= boundingRect.top &&
          Store.mouse.y <= boundingRect.top + this.tab.offsetHeight
        ) {
          if (!tab.hovered) {
            tab.hovered = true;
          }
        } else if (tab.hovered) {
          tab.hovered = false;
        }
        requestAnimationFrame(frame);
      }
    };

    requestAnimationFrame(frame);
  }

  public shouldComponentUpdate(nextProps: any) {
    const { tab, selected } = this.props;

    if (
      nextProps.tab.left !== tab.left ||
      nextProps.tab.width !== tab.width ||
      selected !== nextProps.selected
    ) {
      return true;
    }
    return false;
  }

  public onMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
    const { selected, tab, tabGroup } = this.props;

    this.ripples.makeRipple(e.pageX, e.pageY);
    Store.addressBar.canToggle = selected;
    tabGroup.selectTab(tab);

    this.props.onMouseDown(e);
  };

  public onMouseUp = () => {
    this.ripples.removeRipples();
  };

  public onCloseMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
    e.stopPropagation();
    this.iconRipples.makeRipple(e.pageX, e.pageY);
  };

  public onCloseMouseUp = () => {
    this.ripples.removeRipples();
  };

  public onClick = () => {
    if (Store.addressBar.canToggle) {
      Store.addressBar.toggled = true;
    }
  };

  public onClose = (e: React.MouseEvent<HTMLDivElement>) => {
    const { tabGroup, tab, selected } = this.props;

    e.stopPropagation();

    const tabIndex = tabGroup.tabs.indexOf(tab);

    if (selected) {
      if (tabIndex + 1 < tabGroup.tabs.length && !tabGroup.tabs[tabIndex + 1].isRemoving) {
        tabGroup.selectedTab = tabGroup.tabs[tabIndex + 1].id;
      } else if (tabIndex - 1 >= 0 && !tabGroup.tabs[tabIndex - 1].isRemoving) {
        tabGroup.selectedTab = tabGroup.tabs[tabIndex - 1].id;
      } else if (Store.tabGroups.length === 1) {
        closeWindow();
      }
    }

    const previousTab = tabGroup.tabs[tabIndex - 1];
    tab.isRemoving = true;
    tab.setLeft(previousTab.getNewLeft() + previousTab.getWidth(), true);
    tab.setWidth(0, true);

    setTimeout(() => {
      tabGroup.removeTab(tab);
    }, tabAnimations.left.duration * 1000);

    tabGroup.updateTabsBounds();

    requestAnimationFrame(() => {
      tabGroup.line.moveToTab(tabGroup.getSelectedTab());
    });<commit_msg>:bug: Fix bug with tab closing<commit_after>import { observer } from 'mobx-react'; // eslint-disable-line no-unused-vars
import React from 'react';
import { Ripples } from 'nersent-ui';

// Constants and defaults
import tabAnimations from '../../defaults/tab-animations';

// Utils
import { closeWindow } from '../../utils/window';

// Styles
import { Close, StyledTab, Title, Icon, Content } from './styles';

// Models
import Tab from '../../models/tab';
import TabGroup from '../../models/tab-group';

import Store from '../../store';

interface IProps {
  key: number;
  tab: Tab;
  tabGroup: TabGroup;
  selected: boolean;
  onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => void;
  styles?: any;
}

@observer
export default class extends React.Component<IProps, {}> {
  private ripples: Ripples;
  private iconRipples: Ripples;
  private tab: HTMLDivElement;

  public componentDidMount() {
    const { tab } = this.props;

    const frame = () => {
      if (this.tab != null) {
        const boundingRect = this.tab.getBoundingClientRect();
        if (
          Store.mouse.x >= boundingRect.left &&
          Store.mouse.x <= boundingRect.left + this.tab.offsetWidth &&
          Store.mouse.y >= boundingRect.top &&
          Store.mouse.y <= boundingRect.top + this.tab.offsetHeight
        ) {
          if (!tab.hovered) {
            tab.hovered = true;
          }
        } else if (tab.hovered) {
          tab.hovered = false;
        }
        requestAnimationFrame(frame);
      }
    };

    requestAnimationFrame(frame);
  }

  public shouldComponentUpdate(nextProps: any) {
    const { tab, selected } = this.props;

    if (
      nextProps.tab.left !== tab.left ||
      nextProps.tab.width !== tab.width ||
      selected !== nextProps.selected
    ) {
      return true;
    }
    return false;
  }

  public onMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
    const { selected, tab, tabGroup } = this.props;

    this.ripples.makeRipple(e.pageX, e.pageY);
    Store.addressBar.canToggle = selected;
    tabGroup.selectTab(tab);

    this.props.onMouseDown(e);
  };

  public onMouseUp = () => {
    this.ripples.removeRipples();
  };

  public onCloseMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
    e.stopPropagation();
    this.iconRipples.makeRipple(e.pageX, e.pageY);
  };

  public onCloseMouseUp = () => {
    this.ripples.removeRipples();
  };

  public onClick = () => {
    if (Store.addressBar.canToggle) {
      Store.addressBar.toggled = true;
    }
  };

  public onClose = (e: React.MouseEvent<HTMLDivElement>) => {
    const { tabGroup, tab, selected } = this.props;

    e.stopPropagation();

    const tabIndex = tabGroup.tabs.indexOf(tab);

    if (selected) {
      if (tabIndex + 1 < tabGroup.tabs.length && !tabGroup.tabs[tabIndex + 1].isRemoving) {
        tabGroup.selectedTab = tabGroup.tabs[tabIndex + 1].id;
      } else if (tabIndex - 1 >= 0 && !tabGroup.tabs[tabIndex - 1].isRemoving) {
        tabGroup.selectedTab = tabGroup.tabs[tabIndex - 1].id;
      } else if (Store.tabGroups.length === 1) {
        closeWindow();
      }
    }

    tab.isRemoving = true;
    if (tabGroup.tabs.length - 1 === tabIndex) {
      const previousTab = tabGroup.tabs[tabIndex - 1];
      tab.setLeft(previousTab.getNewLeft() + previousTab.getWidth(), true);
    }

    tab.setWidth(0, true);

    setTimeout(() => {
      tabGroup.removeTab(tab);
    }, tabAnimations.left.duration * 1000);

    tabGroup.updateTabsBounds();

    requestAnimationFrame(() => {
      tabGroup.line.moveToTab(tabGroup.getSelectedTab());
    });
{'fraction_non_alphanumeric': 0.1483044885324328, 'fraction_numerical': 0.004080484029829745, 'mean_word_length': 2.6905503634475596, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 39, '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': '5694931', 'n_tokens_mistral': 2323, 'n_tokens_neox': 2252, 'n_words': 455}