diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js --- a/native/chat/chat-input-bar.react.js +++ b/native/chat/chat-input-bar.react.js @@ -31,7 +31,6 @@ newThreadActionTypes, useJoinThread, } from 'lib/actions/thread-actions.js'; -import type { UseJoinThreadInput } from 'lib/actions/thread-actions.js'; import { useChatMentionContext, useThreadChatMentionCandidates, @@ -51,12 +50,10 @@ } from 'lib/shared/mention-utils.js'; import { messageKey, - type MessagePreviewResult, trimMessage, useMessagePreview, getNextLocalID, } from 'lib/shared/message-utils.js'; -import SentencePrefixSearchIndex from 'lib/shared/sentence-prefix-search-index.js'; import { checkIfDefaultMembersAreVoiced, draftKeyFromThreadID, @@ -65,35 +62,18 @@ useThreadHasPermission, viewerIsMember, } from 'lib/shared/thread-utils.js'; -import type { CalendarQuery } from 'lib/types/entry-types.js'; -import type { SetState } from 'lib/types/hook-types.js'; -import type { LoadingStatus } from 'lib/types/loading-types.js'; import type { PhotoPaste } from 'lib/types/media-types.js'; import { messageTypes } from 'lib/types/message-types-enum.js'; import type { MessageInfo } from 'lib/types/message-types.js'; -import type { - RelativeMemberInfo, - ThreadInfo, - RawThreadInfo, -} from 'lib/types/minimally-encoded-thread-permissions-types.js'; -import type { Dispatch } from 'lib/types/redux-types.js'; +import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { threadPermissions } from 'lib/types/thread-permission-types.js'; -import type { - ChatMentionCandidates, - ThreadJoinPayload, -} from 'lib/types/thread-types.js'; -import { - type DispatchActionPromise, - useDispatchActionPromise, -} from 'lib/utils/redux-promise-utils.js'; +import type { ThreadJoinPayload } from 'lib/types/thread-types.js'; +import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; import { useDispatch } from 'lib/utils/redux-utils.js'; import { ChatContext } from './chat-context.js'; import type { ChatNavigationProp } from './chat.react.js'; -import { - MessageEditingContext, - type MessageEditingContextType, -} from './message-editing-context.react.js'; +import { MessageEditingContext } from './message-editing-context.react.js'; import type { RemoveEditMode } from './message-list-types.js'; import TypeaheadTooltip from './typeahead-tooltip.react.js'; import MentionTypeaheadTooltipButton from '../chat/mention-typeahead-tooltip-button.react.js'; @@ -110,10 +90,7 @@ InputStateContext, } from '../input/input-state.js'; import KeyboardInputHost from '../keyboard/keyboard-input-host.react.js'; -import { - KeyboardContext, - type KeyboardState, -} from '../keyboard/keyboard-state.js'; +import { KeyboardContext } from '../keyboard/keyboard-state.js'; import { getKeyboardHeight } from '../keyboard/keyboard.js'; import { getDefaultTextMessageRules } from '../markdown/rules.react.js'; import { @@ -128,13 +105,9 @@ type NavigationRoute, } from '../navigation/route-names.js'; import { useSelector } from '../redux/redux-utils.js'; -import { type Colors, useColors, useStyles } from '../themes/colors.js'; +import { useColors, useStyles } from '../themes/colors.js'; import type { ImagePasteEvent, LayoutEvent } from '../types/react-native.js'; -import { - AnimatedView, - type AnimatedViewStyle, - type ViewStyle, -} from '../types/styles.js'; +import { AnimatedView, type ViewStyle } from '../types/styles.js'; import Alert from '../utils/alert.js'; import { runTiming } from '../utils/animation-utils.js'; import { exitEditAlert } from '../utils/edit-messages-utils.js'; @@ -282,319 +255,6 @@ type BaseProps = { +threadInfo: ThreadInfo, }; -type Props = { - ...BaseProps, - +rawThreadInfo: RawThreadInfo, - +draft: string, - +joinThreadLoadingStatus: LoadingStatus, - +threadCreationInProgress: boolean, - +calendarQuery: () => CalendarQuery, - +colors: Colors, - +styles: $ReadOnly, - +onInputBarLayout?: (event: LayoutEvent) => mixed, - +openCamera: () => mixed, - +isActive: boolean, - +keyboardState: ?KeyboardState, - +dispatch: Dispatch, - +dispatchActionPromise: DispatchActionPromise, - +joinThread: (input: UseJoinThreadInput) => Promise, - +userMentionsCandidates: $ReadOnlyArray, - +chatMentionSearchIndex: ?SentencePrefixSearchIndex, - +chatMentionCandidates: ChatMentionCandidates, - +editedMessagePreview: ?MessagePreviewResult, - +editedMessageInfo: ?MessageInfo, - +navigation: ?ChatNavigationProp<'MessageList'>, - +messageEditingContext: ?MessageEditingContextType, - +selectionState: SyncedSelectionData, - +setSelectionState: SetState, - +suggestions: $ReadOnlyArray, - +typeaheadMatchedStrings: ?TypeaheadMatchedStrings, - +currentUserCanJoin: boolean, - +threadFrozen: boolean, - +text: string, - +setText: (text: string) => void, - +textEdited: boolean, - +buttonsExpanded: boolean, - +expandoButtonsStyle: AnimatedViewStyle, - +cameraRollIconStyle: AnimatedViewStyle, - +cameraIconStyle: AnimatedViewStyle, - +expandIconStyle: AnimatedViewStyle, - +sendButtonContainerStyle: AnimatedViewStyle, - +shouldShowTextInput: () => boolean, - +isEditMode: () => boolean, - +updateSendButton: (currentText: string) => void, - +expandButtons: () => void, - +hideButtons: () => void, - +textInputRef: { current: ?React.ElementRef }, - +clearableTextInputRef: { current: ?ClearableTextInput }, - +selectableTextInputRef: { - current: ?React.ElementRef, - }, - +setTextInputRef: (ref: ?React.ElementRef) => void, - +setClearableTextInputRef: (ref: ?ClearableTextInput) => void, - +addEditInputMessageListener: () => void, - +removeEditInputMessageListener: () => void, - +focusAndUpdateTextAndSelection: ( - newText: string, - selection: Selection, - ) => void, - +scrollToEditedMessage: () => void, - +onPressExitEditMode: () => void, - +updateText: (newText: string) => void, - +onSend: () => Promise, - +isMessageEdited: (newText?: string) => boolean, - +blockNavigation: () => void, - +onPressJoin: () => void, - +setIOSKeyboardHeight: () => void, - +showMediaGallery: () => void, - +dismissKeyboard: () => void, -}; - -class ChatInputBar extends React.PureComponent { - render(): React.Node { - const isMember = viewerIsMember(this.props.threadInfo); - let joinButton = null; - const threadColor = `#${this.props.threadInfo.color}`; - const isEditMode = this.props.isEditMode(); - if ( - !isMember && - this.props.currentUserCanJoin && - !this.props.threadCreationInProgress - ) { - let buttonContent; - if (this.props.joinThreadLoadingStatus === 'loading') { - buttonContent = ( - - ); - } else { - const textStyle = colorIsDark(this.props.threadInfo.color) - ? this.props.styles.joinButtonTextLight - : this.props.styles.joinButtonTextDark; - buttonContent = ( - - - Join Chat - - ); - } - joinButton = ( - - - - ); - } - - let typeaheadTooltip = null; - - if ( - this.props.suggestions.length > 0 && - this.props.typeaheadMatchedStrings && - !isEditMode - ) { - typeaheadTooltip = ( - - ); - } - - let content; - const defaultMembersAreVoiced = checkIfDefaultMembersAreVoiced( - this.props.threadInfo, - ); - if (this.props.shouldShowTextInput()) { - content = this.renderInput(); - } else if ( - this.props.threadFrozen && - threadActualMembers(this.props.threadInfo.members).length === 2 - ) { - content = ( - - You can’t send messages to a user that you’ve blocked. - - ); - } else if (isMember) { - content = ( - - You don’t have permission to send messages. - - ); - } else if (defaultMembersAreVoiced && this.props.currentUserCanJoin) { - content = null; - } else { - content = ( - - You don’t have permission to send messages. - - ); - } - - const keyboardInputHost = - Platform.OS === 'android' ? null : ( - - ); - - let editedMessage; - if (isEditMode && this.props.editedMessagePreview) { - const { message } = this.props.editedMessagePreview; - editedMessage = ( - - - - - Editing message - - - {message.text} - - - - - - ); - } - - return ( - - {typeaheadTooltip} - {joinButton} - {editedMessage} - {content} - {keyboardInputHost} - - ); - } - - renderInput(): React.Node { - const expandoButton = ( - - - - - - ); - const threadColor = `#${this.props.threadInfo.color}`; - const expandoButtonsViewStyle: Array = [ - this.props.styles.innerExpandoButtons, - ]; - if (this.props.isEditMode()) { - expandoButtonsViewStyle.push({ display: 'none' }); - } - return ( - - - - - {this.props.buttonsExpanded ? expandoButton : null} - - - - - - - - - - - {this.props.buttonsExpanded ? null : expandoButton} - - - - - - - - - - - ); - } -} const joinThreadLoadingStatusSelector = createLoadingStatusSelector( joinThreadActionTypes, @@ -1433,67 +1093,222 @@ prevEditedMessage.current = editedMessage; }, [blockNavigation, messageEditingContext?.editState.editedMessage]); + const renderInput = () => { + const expandoButton = ( + + + + + + ); + const threadColor = `#${props.threadInfo.color}`; + const expandoButtonsViewStyle: Array = [ + styles.innerExpandoButtons, + ]; + if (isEditMode()) { + expandoButtonsViewStyle.push({ display: 'none' }); + } + return ( + + + + + {buttonsExpanded ? expandoButton : null} + + + + + + + + + + + {buttonsExpanded ? null : expandoButton} + + + + + + + + + + + ); + }; + + const isMember = viewerIsMember(props.threadInfo); + let joinButton = null; + const threadColor = `#${props.threadInfo.color}`; + + if (!isMember && currentUserCanJoin && !threadCreationInProgress) { + let buttonContent; + if (joinThreadLoadingStatus === 'loading') { + buttonContent = ( + + ); + } else { + const textStyle = colorIsDark(props.threadInfo.color) + ? styles.joinButtonTextLight + : styles.joinButtonTextDark; + buttonContent = ( + + + Join Chat + + ); + } + joinButton = ( + + + + ); + } + + let typeaheadTooltip = null; + + if (suggestions.length > 0 && typeaheadMatchedStrings && !isEditMode()) { + typeaheadTooltip = ( + + ); + } + + let content; + const defaultMembersAreVoiced = checkIfDefaultMembersAreVoiced( + props.threadInfo, + ); + if (shouldShowTextInput()) { + content = renderInput(); + } else if ( + threadFrozen && + threadActualMembers(props.threadInfo.members).length === 2 + ) { + content = ( + + You can’t send messages to a user that you’ve blocked. + + ); + } else if (isMember) { + content = ( + + You don’t have permission to send messages. + + ); + } else if (defaultMembersAreVoiced && currentUserCanJoin) { + content = null; + } else { + content = ( + + You don’t have permission to send messages. + + ); + } + + const keyboardInputHost = + Platform.OS === 'android' ? null : ( + + ); + + let editedMessage; + if (isEditMode() && editedMessagePreview) { + const { message } = editedMessagePreview; + editedMessage = ( + + + + + Editing message + + + {message.text} + + + + + + ); + } + return ( - + + {typeaheadTooltip} + {joinButton} + {editedMessage} + {content} + {keyboardInputHost} + ); }