mattermost-mobile-upstream/app/components/post_draft/send_handler/send_handler.tsx
Elias Nahum b6fc85385e
Migrate from RNN to Expo router (#9402)
* Expo-Router partial migration

* Full migration to ExpoRouter

* i18n

* add tests

* Merge branch 'main' into expo-router

* align package-lock.json

* i18n

* feedback review

* feedback review

* android 16kb patch

* Refactored emoji picker keyboard using a state machine

* set android launch_screen in drawables instead of layout

* no conditional hooks

* remove duplicate call in test

* address feedback

* fix tests and address more feedback

* small corrections

* small corrections

* small corrections

* fix draft test

* fix draft test 2

* remove navigateToScreen in draff test

* fix nit in draft test

* remove doc file

* Feedback review

* fix snapshots

* improve test coverage

* fix i18n

* Upgrade t o RN 0.83, other dependencies and new architecture (#9737)

* library hardware-keyboard android new arch support fix

* library rnshare android new arch support fix

* library rnutils android new arch support fix

* library secure-pdf-viewer add new arch support

* Enable new arch on iOS and Android

* update emm and network client with new-arch

* update intune to use new-arch

* performance improvements

* fix tests

* fixes post input on new-arch

* fix android emoji picker

* remove doc

* run tests in parallel

* upgrade to React Native 0.83.9, Expo 55, React 19, and New Architecture

Bumps core dependencies to their latest versions:
- React Native 0.77.3 → 0.83.9 (New Architecture enabled)
- React 18.3.1 → 19.2.5
- Expo SDK 52 → 55
- TypeScript 5.8.3 → 6.0.3
- Node.js 22.16.0 → 24.15.0
- react-native-reanimated 3.17.3 → 4.3.0
- Various other dependency upgrades

Migrates iOS AppDelegate from Objective-C to Swift, updates Android
build tooling and Gradle wrapper, refreshes all patches and font
assets, and adapts app code, tests, and CI workflows throughout for
API changes introduced by these upgrades.

* remove unecessary dismissKeyboard in notifications

* feedback review

* update intune to use new-arch

* update @mattermost deps

* missing i18n string

* additional fixes

* update fastlane
2026-05-13 17:44:55 +08:00

188 lines
5.9 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback} from 'react';
import {updateDraftBoRConfig, updateDraftPriority} from '@actions/local/draft';
import SendDraft from '@components/draft_scheduled_post/draft_scheduled_post_actions/send_draft';
import DraftInput from '@components/post_draft/draft_input/';
import {PostPriorityType} from '@constants/post';
import {useServerUrl} from '@context/server';
import {useHandleSendMessage} from '@hooks/handle_send_message';
import type {DraftType} from '@constants/draft';
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
testID?: string;
channelId: string;
channelType?: ChannelType;
channelName?: string;
rootId: string;
canShowPostPriority?: boolean;
setIsFocused: (isFocused: boolean) => void;
// From database
currentUserId: string;
cursorPosition: number;
enableConfirmNotificationsToChannel?: boolean;
maxMessageLength: number;
membersCount?: number;
useChannelMentions: boolean;
userIsOutOfOffice: boolean;
customEmojis: CustomEmojiModel[];
// DRAFT Handler
value: string;
files: FileInfo[];
clearDraft: () => void;
updateValue: React.Dispatch<React.SetStateAction<string>>;
updateCursorPosition: React.Dispatch<React.SetStateAction<number>>;
updatePostInputTop: (top: number) => void;
addFiles: (file: FileInfo[]) => void;
uploadFileError: React.ReactNode;
persistentNotificationInterval: number;
persistentNotificationMaxRecipients: number;
postPriority: PostPriority;
postBoRConfig?: PostBoRConfig;
draftType?: DraftType;
postId?: string;
channelDisplayName?: string;
isFromDraftView?: boolean;
draftReceiverUserName?: string;
onPostCreated?: (postId: string) => void;
location?: AvailableScreens;
}
export const INITIAL_PRIORITY = {
priority: PostPriorityType.STANDARD,
requested_ack: false,
persistent_notifications: false,
};
export default function SendHandler({
testID,
channelId,
channelType,
channelName,
channelDisplayName,
currentUserId,
enableConfirmNotificationsToChannel,
files,
maxMessageLength,
membersCount = 0,
cursorPosition,
rootId,
canShowPostPriority,
useChannelMentions,
userIsOutOfOffice,
customEmojis,
value,
clearDraft,
updateValue,
addFiles,
uploadFileError,
updateCursorPosition,
updatePostInputTop,
setIsFocused,
persistentNotificationInterval,
persistentNotificationMaxRecipients,
postPriority,
draftReceiverUserName,
isFromDraftView,
draftType,
postId,
onPostCreated,
postBoRConfig,
location,
}: Props) {
const serverUrl = useServerUrl();
const handlePostPriority = useCallback((priority: PostPriority) => {
updateDraftPriority(serverUrl, channelId, rootId, priority);
}, [serverUrl, channelId, rootId]);
const handlePostBoRStatus = useCallback((config: PostBoRConfig) => {
updateDraftBoRConfig(serverUrl, channelId, rootId, config);
}, [channelId, rootId, serverUrl]);
const {handleSendMessage, canSend} = useHandleSendMessage({
value,
channelId,
rootId,
files,
maxMessageLength,
customEmojis,
enableConfirmNotificationsToChannel,
useChannelMentions,
membersCount,
userIsOutOfOffice,
currentUserId,
channelType,
postPriority,
clearDraft,
onPostCreated,
postBoRConfig,
});
if (isFromDraftView) {
return (
<SendDraft
channelId={channelId}
rootId={rootId}
channelType={channelType}
currentUserId={currentUserId}
channelName={channelName}
channelDisplayName={channelDisplayName}
enableConfirmNotificationsToChannel={enableConfirmNotificationsToChannel}
maxMessageLength={maxMessageLength}
membersCount={membersCount}
useChannelMentions={useChannelMentions}
userIsOutOfOffice={userIsOutOfOffice}
customEmojis={customEmojis}
value={value}
files={files}
postPriority={postPriority}
persistentNotificationInterval={persistentNotificationInterval}
persistentNotificationMaxRecipients={persistentNotificationMaxRecipients}
draftReceiverUserName={draftReceiverUserName}
draftType={draftType}
postId={postId}
/>
);
}
return (
<DraftInput
testID={testID}
channelId={channelId}
channelType={channelType}
channelName={channelName}
currentUserId={currentUserId}
rootId={rootId}
canShowPostPriority={canShowPostPriority}
cursorPosition={cursorPosition}
updateCursorPosition={updateCursorPosition}
value={value}
files={files}
updateValue={updateValue}
addFiles={addFiles}
uploadFileError={uploadFileError}
sendMessage={handleSendMessage}
canSend={canSend}
maxMessageLength={maxMessageLength}
updatePostInputTop={updatePostInputTop}
postPriority={postPriority}
postBoRConfig={postBoRConfig}
updatePostPriority={handlePostPriority}
updatePostBoRStatus={handlePostBoRStatus}
persistentNotificationInterval={persistentNotificationInterval}
persistentNotificationMaxRecipients={persistentNotificationMaxRecipients}
setIsFocused={setIsFocused}
location={location}
/>
);
}