// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import React, {useCallback} from 'react'; import {useIntl} from 'react-intl'; import {Keyboard, type LayoutChangeEvent, Platform, ScrollView, View} from 'react-native'; import {type Edge, SafeAreaView} from 'react-native-safe-area-context'; import {Screens} from '@constants'; import {useKeyboardAnimationContext} from '@context/keyboard_animation'; import {useServerUrl} from '@context/server'; import {useTheme} from '@context/theme'; import {useIsTablet} from '@hooks/device'; import {usePersistentNotificationProps} from '@hooks/persistent_notification_props'; import {openAsBottomSheet} from '@screens/navigation'; import {persistentNotificationsConfirmation} from '@utils/post'; import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme'; import PostInput from '../post_input'; import QuickActions from '../quick_actions'; import SendAction from '../send_button'; import Typing from '../typing'; import Uploads from '../uploads'; import Header from './header'; import type {AvailableScreens} from '@typings/screens/navigation'; export type Props = { testID?: string; channelId: string; channelType?: ChannelType; channelName?: string; rootId?: string; currentUserId: string; canShowPostPriority?: boolean; location?: AvailableScreens; // Post Props postPriority: PostPriority; postBoRConfig?: PostBoRConfig; updatePostPriority: (postPriority: PostPriority) => void; updatePostBoRStatus: (config: PostBoRConfig) => void; persistentNotificationInterval: number; persistentNotificationMaxRecipients: number; // Cursor Position Handler updateCursorPosition: React.Dispatch>; cursorPosition: number; // Send Handler sendMessage: (schedulingInfo?: SchedulingInfo) => Promise; canSend: boolean; maxMessageLength: number; // Draft Handler files: FileInfo[]; value: string; uploadFileError: React.ReactNode; updateValue: React.Dispatch>; addFiles: (files: FileInfo[]) => void; updatePostInputTop: (top: number) => void; setIsFocused: (isFocused: boolean) => void; scheduledPostsEnabled: boolean; } const SCHEDULED_POST_PICKER_BUTTON = 'close-scheduled-post-picker'; const SAFE_AREA_VIEW_EDGES: Edge[] = ['left', 'right']; const getStyleSheet = makeStyleSheetFromTheme((theme) => { return { actionsContainer: { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingBottom: Platform.select({ ios: 1, android: 2, }), }, inputContainer: { flex: 1, flexDirection: 'column', }, inputContentContainer: { alignItems: 'stretch', paddingTop: Platform.select({ ios: 7, android: 0, }), }, inputWrapper: { alignItems: 'flex-end', flexDirection: 'row', justifyContent: 'center', paddingBottom: 2, backgroundColor: theme.centerChannelBg, borderWidth: 1, borderBottomWidth: 0, borderColor: changeOpacity(theme.centerChannelColor, 0.20), borderTopLeftRadius: 12, borderTopRightRadius: 12, }, postPriorityLabel: { marginLeft: 12, marginTop: Platform.select({ ios: 3, android: 10, }), }, }; }); function DraftInput({ testID, channelId, channelType, channelName, currentUserId, canShowPostPriority, files, maxMessageLength, rootId = '', value, uploadFileError, sendMessage, canSend, updateValue, addFiles, updateCursorPosition, cursorPosition, updatePostInputTop, postPriority, updatePostPriority, updatePostBoRStatus, persistentNotificationInterval, persistentNotificationMaxRecipients, setIsFocused, scheduledPostsEnabled, postBoRConfig, location, }: Props) { const intl = useIntl(); const serverUrl = useServerUrl(); const theme = useTheme(); const isTablet = useIsTablet(); const {inputRef, focusInput: focus} = useKeyboardAnimationContext(); const handleLayout = useCallback((e: LayoutChangeEvent) => { updatePostInputTop(e.nativeEvent.layout.height); }, [updatePostInputTop]); // Render const postInputTestID = `${testID}.post.input`; const quickActionsTestID = `${testID}.quick_actions`; const sendActionTestID = `${testID}.send_action`; const style = getStyleSheet(theme); const {persistentNotificationsEnabled, noMentionsError, mentionsList} = usePersistentNotificationProps({ value, channelType, postPriority, }); const handleSendMessage = useCallback(async (schedulingInfoParam?: SchedulingInfo) => { const schedulingInfo = (schedulingInfoParam && 'scheduled_at' in schedulingInfoParam) ? schedulingInfoParam : undefined; if (persistentNotificationsEnabled) { const sendMessageWithScheduledPost = () => sendMessage(schedulingInfo); await persistentNotificationsConfirmation(serverUrl, value, mentionsList, intl, sendMessageWithScheduledPost, persistentNotificationMaxRecipients, persistentNotificationInterval, currentUserId, channelName, channelType); return Promise.resolve(); } return sendMessage(schedulingInfo); }, [persistentNotificationsEnabled, serverUrl, value, mentionsList, intl, sendMessage, persistentNotificationMaxRecipients, persistentNotificationInterval, currentUserId, channelName, channelType]); const handleShowScheduledPostOptions = useCallback(() => { if (!scheduledPostsEnabled) { return; } Keyboard.dismiss(); const title = isTablet ? intl.formatMessage({id: 'scheduled_post.picker.title', defaultMessage: 'Schedule draft'}) : ''; openAsBottomSheet({ closeButtonId: SCHEDULED_POST_PICKER_BUTTON, screen: Screens.SCHEDULED_POST_OPTIONS, theme, title, props: { closeButtonId: SCHEDULED_POST_PICKER_BUTTON, onSchedule: handleSendMessage, }, }); }, [handleSendMessage, intl, isTablet, scheduledPostsEnabled, theme]); const sendActionDisabled = !canSend || noMentionsError; return ( <>
); } export default DraftInput;