<commit_before>// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

import { ChatChannelLoadEarlierMessages } from 'actions/chat-actions';
import { dispatch, dispatchListener } from 'app-dispatcher';
import { route } from 'laroute';
import * as _ from 'lodash';
import { computed } from 'mobx';
import { inject, observer } from 'mobx-react';
import Message from 'models/chat/message';
import * as moment from 'moment';
import * as React from 'react';
import { ShowMoreLink } from 'show-more-link';
import { Spinner } from 'spinner';
import RootDataStore from 'stores/root-data-store';
import { StringWithComponent } from 'string-with-component';
import { UserAvatar } from 'user-avatar';
import { ChatChannelSwitchAction } from '../actions/chat-actions';
import DispatcherAction from '../actions/dispatcher-action';
import DispatchListener from '../dispatch-listener';
import { MessageDivider } from './message-divider';
import MessageGroup from './message-group';

interface Props {
  dataStore?: RootDataStore;
}

interface Snapshot {
  chatHeight: number;
  chatTop: number;
}

const blankSnapshot = (): Snapshot => ({ chatHeight: 0, chatTop: 0 });

@inject('dataStore')
@observer
@dispatchListener
export default class ConversationView extends React.Component<Props> implements DispatchListener {

  @computed
  get currentChannel() {
    return this.dataStore.channelStore.channels.get(this.dataStore.uiState.chat.selected);
  }
  private assumeHasBacklog: boolean = false;
  private chatViewRef = React.createRef<HTMLDivElement>();
  private readonly dataStore: RootDataStore;
  private didSwitchChannel: boolean = true;
  private firstMessage?: Message;
  private unreadMarkerRef = React.createRef<HTMLDivElement>();

  constructor(props: Props) {
    super(props);

    this.dataStore = props.dataStore!;
  }

  componentDidMount() {
    this.componentDidUpdate();
    $(window).on('throttled-scroll', _.throttle(this.onScroll, 1000));
  }

  componentDidUpdate = (prevProps?: Props, prevState?: {}, snapshot?: Snapshot) => {
    const chatView = this.chatViewRef.current;
    if (!chatView) {
      return;
    }

    const dataStore = this.dataStore;
    const channel = dataStore.channelStore.channels.get(dataStore.uiState.chat.selected);
    if (!channel?.loaded) {
      return;
    }

    if (this.didSwitchChannel) {<commit_msg>Move where getters belong<commit_after>// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the GNU Affero General Public License v3.0.
// See the LICENCE file in the repository root for full licence text.

import { ChatChannelLoadEarlierMessages } from 'actions/chat-actions';
import { dispatch, dispatchListener } from 'app-dispatcher';
import { route } from 'laroute';
import * as _ from 'lodash';
import { computed } from 'mobx';
import { inject, observer } from 'mobx-react';
import Message from 'models/chat/message';
import * as moment from 'moment';
import * as React from 'react';
import { ShowMoreLink } from 'show-more-link';
import { Spinner } from 'spinner';
import RootDataStore from 'stores/root-data-store';
import { StringWithComponent } from 'string-with-component';
import { UserAvatar } from 'user-avatar';
import { ChatChannelSwitchAction } from '../actions/chat-actions';
import DispatcherAction from '../actions/dispatcher-action';
import DispatchListener from '../dispatch-listener';
import { MessageDivider } from './message-divider';
import MessageGroup from './message-group';

interface Props {
  dataStore?: RootDataStore;
}

interface Snapshot {
  chatHeight: number;
  chatTop: number;
}

const blankSnapshot = (): Snapshot => ({ chatHeight: 0, chatTop: 0 });

@inject('dataStore')
@observer
@dispatchListener
export default class ConversationView extends React.Component<Props> implements DispatchListener {
  private assumeHasBacklog: boolean = false;
  private chatViewRef = React.createRef<HTMLDivElement>();
  private readonly dataStore: RootDataStore;
  private didSwitchChannel: boolean = true;
  private firstMessage?: Message;
  private unreadMarkerRef = React.createRef<HTMLDivElement>();

  @computed
  get currentChannel() {
    return this.dataStore.channelStore.channels.get(this.dataStore.uiState.chat.selected);
  }

  constructor(props: Props) {
    super(props);

    this.dataStore = props.dataStore!;
  }

  componentDidMount() {
    this.componentDidUpdate();
    $(window).on('throttled-scroll', _.throttle(this.onScroll, 1000));
  }

  componentDidUpdate = (prevProps?: Props, prevState?: {}, snapshot?: Snapshot) => {
    const chatView = this.chatViewRef.current;
    if (!chatView) {
      return;
    }

    const dataStore = this.dataStore;
    const channel = dataStore.channelStore.channels.get(dataStore.uiState.chat.selected);
    if (!channel?.loaded) {
      return;
    }

    if (this.didSwitchChannel) {
{'fraction_non_alphanumeric': 0.12160518848804215, 'fraction_numerical': 0.0032428050263477908, 'mean_word_length': 4.646453089244852, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, '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': '3863031', 'n_tokens_mistral': 1439, 'n_tokens_neox': 1402, 'n_words': 393}