<commit_before>// @flow
import * as Attachment from './attachment'
import * as ChatTypes from '../../constants/types/flow-types-chat'
import * as Constants from '../../constants/chat'
import * as Creators from './creators'
import * as EntityCreators from '../entities'
import * as SearchCreators from '../search/creators'
import * as Inbox from './inbox'
import * as Messages from './messages'
import * as Shared from './shared'
import * as Saga from '../../util/saga'
import * as EngineRpc from '../engine/helper'
import HiddenString from '../../util/hidden-string'
import engine from '../../engine'
import {Map, OrderedSet, Set} from 'immutable'
import {NotifyPopup} from '../../native/notifications'
import {
  apiserverGetRpcPromise,
  TlfKeysTLFIdentifyBehavior,
  CommonDeviceType,
  CommonTLFVisibility,
  ConstantsStatusCode,
  teamsTeamCreateRpcPromise,
  teamsTeamAddMemberRpcPromise,
  TeamsTeamRole,
} from '../../constants/types/flow-types'
import {call, put, all, take, select, race} from 'redux-saga/effects'
import {delay} from 'redux-saga'
import {isMobile} from '../../constants/platform'
import {navigateTo, switchTo} from '../route-tree'
import {openInKBFS} from '../kbfs'
import {parseFolderNameToUsers} from '../../util/kbfs'
import {publicFolderWithUsers, privateFolderWithUsers} from '../../constants/config'
import {chatTab} from '../../constants/tabs'
import {showMainWindow} from '../platform-specific'
import some from 'lodash/some'
import {toDeviceType} from '../../constants/types/more'
import {
  usernameSelector,
  inboxSearchSelector,
  previousConversationSelector,
  searchResultMapSelector,
} from '../../constants/selectors'
import {maybeUpgradeSearchResultIdToKeybaseId} from '../../constants/search'

import type {Action} from '../../constants/types/flux'
import type {KBOrderedSet} from '../../constants/types/more'
import type {ChangedFocus, ChangedActive} from '../../constants/app'
import type {TLFIdentifyBehavior} from '../../constants/types/flow-types'
import type {SagaGenerator} from '../../constants/types/saga'
import type {TypedState} from '../../constants/reducer'

function* _incomingMessage(action: Constants.IncomingMessage): SagaGenerator<any, any> {
  switch (action.payload.activity.activityType) {
    case ChatTypes.NotifyChatChatActivityType.setStatus:
      const setStatus: ?ChatTypes.SetStatusInfo = action.payload.activity.setStatus
      if (setStatus) {
        yield call(Inbox.processConversation, setStatus.conv)
        yield call(_ensureValidSelectedChat, false, true)
      }
      return
    case ChatTypes.NotifyChatChatActivityType.failedMessage:
      const failedMessage: ?ChatTypes.FailedMessageInfo = action.payload.activity.failedMessage
      if (failedMessage && failedMessage.outboxRecords) {
        for (const outboxRecord of failedMessage.outboxRecords) {
          const conversationIDKey = Constants.conversationIDToKey(outboxRecord.convID)
          const outboxID = outboxRecord.outboxID && Constants.outboxIDToKey(outboxRecord.outboxID)
          // $FlowIssue
          const errTyp = outboxRecord.state.error.typ
          const failureDescription = _decodeFailureDescription(errTyp)
          const isConversationLoaded = yield select(Shared.conversationStateSelector, conversationIDKey)
          if (!isConversationLoaded) return

          const pendingMessage = yield select(Shared.messageOutboxIDSelector, conversationIDKey, outboxID)
          if (pendingMessage) {
            yield put(
              Creators.updateTempMessage(
                conversationIDKey,
                {
                  ...pendingMessage,
                  failureDescription,
                  messageState: 'failed',
                },
                outboxID
              )
            )
          } else {
            throw new Error("Pending message wasn't found!")
          }
        }
      }
      return
    case ChatTypes.NotifyChatChatActivityType.readMessage:
      if (action.payload.activity.readMessage) {
        yield call(Inbox.processConversation, action.payload.activity.readMessage.conv)
      }
      return
    case ChatTypes.NotifyChatChatActivityType.incomingMessage:
      const incomingMessage: ?ChatTypes.IncomingMessage = action.payload.activity.incomingMessage
      if (incomingMessage) {
        // If it's a public chat, the GUI (currently) wants no part of it. We<commit_msg>Fix convID of undefined (#8278)<commit_after>// @flow
import * as Attachment from './attachment'
import * as ChatTypes from '../../constants/types/flow-types-chat'
import * as Constants from '../../constants/chat'
import * as Creators from './creators'
import * as EntityCreators from '../entities'
import * as SearchCreators from '../search/creators'
import * as Inbox from './inbox'
import * as Messages from './messages'
import * as Shared from './shared'
import * as Saga from '../../util/saga'
import * as EngineRpc from '../engine/helper'
import HiddenString from '../../util/hidden-string'
import engine from '../../engine'
import {Map, OrderedSet, Set} from 'immutable'
import {NotifyPopup} from '../../native/notifications'
import {
  apiserverGetRpcPromise,
  TlfKeysTLFIdentifyBehavior,
  CommonDeviceType,
  CommonTLFVisibility,
  ConstantsStatusCode,
  teamsTeamCreateRpcPromise,
  teamsTeamAddMemberRpcPromise,
  TeamsTeamRole,
} from '../../constants/types/flow-types'
import {call, put, all, take, select, race} from 'redux-saga/effects'
import {delay} from 'redux-saga'
import {isMobile} from '../../constants/platform'
import {navigateTo, switchTo} from '../route-tree'
import {openInKBFS} from '../kbfs'
import {parseFolderNameToUsers} from '../../util/kbfs'
import {publicFolderWithUsers, privateFolderWithUsers} from '../../constants/config'
import {chatTab} from '../../constants/tabs'
import {showMainWindow} from '../platform-specific'
import some from 'lodash/some'
import {toDeviceType} from '../../constants/types/more'
import {
  usernameSelector,
  inboxSearchSelector,
  previousConversationSelector,
  searchResultMapSelector,
} from '../../constants/selectors'
import {maybeUpgradeSearchResultIdToKeybaseId} from '../../constants/search'

import type {Action} from '../../constants/types/flux'
import type {KBOrderedSet} from '../../constants/types/more'
import type {ChangedFocus, ChangedActive} from '../../constants/app'
import type {TLFIdentifyBehavior} from '../../constants/types/flow-types'
import type {SagaGenerator} from '../../constants/types/saga'
import type {TypedState} from '../../constants/reducer'

function* _incomingMessage(action: Constants.IncomingMessage): SagaGenerator<any, any> {
  switch (action.payload.activity.activityType) {
    case ChatTypes.NotifyChatChatActivityType.setStatus:
      const setStatus: ?ChatTypes.SetStatusInfo = action.payload.activity.setStatus
      if (setStatus) {
        yield call(Inbox.processConversation, setStatus.conv)
        yield call(_ensureValidSelectedChat, false, true)
      }
      return
    case ChatTypes.NotifyChatChatActivityType.failedMessage:
      const failedMessage: ?ChatTypes.FailedMessageInfo = action.payload.activity.failedMessage
      if (failedMessage && failedMessage.outboxRecords) {
        for (const outboxRecord of failedMessage.outboxRecords) {
          const conversationIDKey = Constants.conversationIDToKey(outboxRecord.convID)
          const outboxID = outboxRecord.outboxID && Constants.outboxIDToKey(outboxRecord.outboxID)
          // $FlowIssue
          const errTyp = outboxRecord.state.error.typ
          const failureDescription = _decodeFailureDescription(errTyp)
          const isConversationLoaded = yield select(Shared.conversationStateSelector, conversationIDKey)
          if (!isConversationLoaded) return

          const pendingMessage = yield select(Shared.messageOutboxIDSelector, conversationIDKey, outboxID)
          if (pendingMessage) {
            yield put(
              Creators.updateTempMessage(
                conversationIDKey,
                {
                  ...pendingMessage,
                  failureDescription,
                  messageState: 'failed',
                },
                outboxID
              )
            )
          } else {
            throw new Error("Pending message wasn't found!")
          }
        }
      }
      return
    case ChatTypes.NotifyChatChatActivityType.readMessage:
      if (action.payload.activity.readMessage) {
        const inboxUIItem: ?ChatTypes.InboxUIItem = action.payload.activity.readMessage.conv
        if (inboxUIItem) {
          yield call(Inbox.processConversation, inboxUIItem)
        }
      }
      return
    case ChatTypes.NotifyChatChatActivityType.incomingMessage:
      const incomingMessage: ?ChatTypes.IncomingMessage = action.payload.activity.incomingMessage
      if (incomingMessage) {
        // If it's a public chat, the GUI (currently) wants no part of it. We
{'fraction_non_alphanumeric': 0.11432738696286324, 'fraction_numerical': 0.00044878267698866825, 'mean_word_length': 3.1790904828879514, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '2824909', 'n_tokens_mistral': 2402, 'n_tokens_neox': 2439, 'n_words': 595}