<commit_before>import * as Chat2Gen from '../../actions/chat2-gen'
import * as ChatTypes from '../../constants/types/chat2'
import * as Container from '../../util/container'
import * as RPCChatTypes from '../../constants/types/rpc-chat-gen'
import * as React from 'react'
import * as RouteTreeGen from '../../actions/route-tree-gen'
import * as TeamsGen from '../../actions/teams-gen'
import ManageChannels, {RowProps} from '.'
import {ChannelMembershipState} from '../../constants/types/teams'
import {anyWaiting} from '../../constants/waiting'
import {formatTimeRelativeToNow} from '../../util/timestamp'
import {getChannelsWaitingKey, getCanPerform, getTeamChannelInfos, hasCanPerform} from '../../constants/teams'
import {isEqual} from 'lodash-es'
import {makeInsertMatcher} from '../../util/string'

type OwnProps = Container.RouteProps<{teamname: string}>

const mapStateToProps = (state: Container.TypedState, ownProps: OwnProps) => {
  const teamname = Container.getRouteProps(ownProps, 'teamname', '')
  const waitingKey = getChannelsWaitingKey(teamname)
  const waitingForGet = anyWaiting(state, waitingKey)
  const channelInfos = getTeamChannelInfos(state, teamname)
  const yourOperations = getCanPerform(state, teamname)
  // We can get here without loading team operations
  // if we manage channels on mobile without loading the conversation first
  const _hasOperations = hasCanPerform(state, teamname)

  const canEditChannels =
    yourOperations.editChannelDescription || yourOperations.renameChannel || yourOperations.deleteChannel
  const canCreateChannels = yourOperations.createChannel

  const generalCh = channelInfos.find(i => i.channelname === 'general')
  const teamSize = generalCh ? generalCh.numParticipants : 0

  const searchText = state.chat2.channelSearchText
  const isFiltered = !!searchText

  const channels = channelInfos
    .map((info, convID) => ({
      convID,
      description: info.description,
      hasAllMembers: info.numParticipants === teamSize,
      mtimeHuman: formatTimeRelativeToNow(info.mtime),
      name: info.channelname,
      numParticipants: info.numParticipants,
      selected: info.memberStatus === RPCChatTypes.ConversationMemberStatus.active,
    }))
    .filter(conv => (searchText ? conv.name.match(makeInsertMatcher(searchText)) : true))
    .valueSeq()
    .toArray()
    .sort((a, b) => a.name.localeCompare(b.name))

  const selectedChatID = state.chat2.selectedConversation

  return {
    _hasOperations,
    canCreateChannels,<commit_msg>make channel search work on channel descriptions (#20000)<commit_after>import * as Chat2Gen from '../../actions/chat2-gen'
import * as ChatTypes from '../../constants/types/chat2'
import * as Container from '../../util/container'
import * as RPCChatTypes from '../../constants/types/rpc-chat-gen'
import * as React from 'react'
import * as RouteTreeGen from '../../actions/route-tree-gen'
import * as TeamsGen from '../../actions/teams-gen'
import ManageChannels, {RowProps} from '.'
import {ChannelMembershipState} from '../../constants/types/teams'
import {anyWaiting} from '../../constants/waiting'
import {formatTimeRelativeToNow} from '../../util/timestamp'
import {getChannelsWaitingKey, getCanPerform, getTeamChannelInfos, hasCanPerform} from '../../constants/teams'
import {isEqual} from 'lodash-es'
import {makeInsertMatcher} from '../../util/string'

type OwnProps = Container.RouteProps<{teamname: string}>

const mapStateToProps = (state: Container.TypedState, ownProps: OwnProps) => {
  const teamname = Container.getRouteProps(ownProps, 'teamname', '')
  const waitingKey = getChannelsWaitingKey(teamname)
  const waitingForGet = anyWaiting(state, waitingKey)
  const channelInfos = getTeamChannelInfos(state, teamname)
  const yourOperations = getCanPerform(state, teamname)
  // We can get here without loading team operations
  // if we manage channels on mobile without loading the conversation first
  const _hasOperations = hasCanPerform(state, teamname)

  const canEditChannels =
    yourOperations.editChannelDescription || yourOperations.renameChannel || yourOperations.deleteChannel
  const canCreateChannels = yourOperations.createChannel

  const generalCh = channelInfos.find(i => i.channelname === 'general')
  const teamSize = generalCh ? generalCh.numParticipants : 0

  const searchText = state.chat2.channelSearchText
  const isFiltered = !!searchText

  const channels = channelInfos
    .map((info, convID) => ({
      convID,
      description: info.description,
      hasAllMembers: info.numParticipants === teamSize,
      mtimeHuman: formatTimeRelativeToNow(info.mtime),
      name: info.channelname,
      numParticipants: info.numParticipants,
      selected: info.memberStatus === RPCChatTypes.ConversationMemberStatus.active,
    }))
    .filter(conv => {
      if (!searchText) {
        return true // no search text means show all
      }
      return (
        // match channel name for search as subsequence (like the identity modal)
        // match channel desc by strict substring (less noise in results)
        conv.name.match(makeInsertMatcher(searchText)) || conv.description.match(new RegExp(searchText, 'i'))
      )
    })
    .valueSeq()
    .toArray()
    .sort((a, b) => a.name.localeCompare(b.name))

  const selectedChatID = state.chat2.selectedConversation

  return {
    _hasOperations,
    canCreateChannels,
{'fraction_non_alphanumeric': 0.11962166172106825, 'fraction_numerical': 0.003152818991097923, 'mean_word_length': 4.15090735434575, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, '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': '5204838', 'n_tokens_mistral': 1531, 'n_tokens_neox': 1537, 'n_words': 393}