import React, { useCallback, useMemo } from 'react' import { StyleSheet, View, StyleProp, ViewStyle, TextStyle } from 'react-native' import { Actions, ActionsProps } from './Actions' import { Color } from './Color' import { ReplyPreview, ReplyPreviewProps } from './components/ReplyPreview' import { Composer, ComposerProps } from './Composer' import { useColorScheme } from './hooks/useColorScheme' import { IMessage, ReplyMessage } from './Models' import { Send, SendProps } from './Send' import { renderComponentOrElement } from './utils' export type { ReplyPreviewProps } from './components/ReplyPreview' export interface InputToolbarProps { actions?: Array<{ title: string, action: () => void }> actionSheetOptionTintColor?: string containerStyle?: StyleProp primaryStyle?: StyleProp renderAccessory?: (props: InputToolbarProps) => React.ReactNode renderActions?: (props: ActionsProps) => React.ReactNode renderSend?: (props: SendProps) => React.ReactNode renderComposer?: (props: ComposerProps) => React.ReactNode onPressActionButton?: () => void icon?: () => React.ReactNode wrapperStyle?: StyleProp /** Reply message to show in preview */ replyMessage?: ReplyMessage | null /** Callback to clear reply */ onClearReply?: () => void /** Custom render for reply preview */ renderReplyPreview?: (props: ReplyPreviewProps) => React.ReactNode /** Style for reply preview container */ replyPreviewContainerStyle?: StyleProp /** Style for reply preview text */ replyPreviewTextStyle?: StyleProp } export function InputToolbar ( props: InputToolbarProps ) { const { renderActions, onPressActionButton, renderComposer, renderSend, renderAccessory, actions, actionSheetOptionTintColor, icon, wrapperStyle, containerStyle, replyMessage, onClearReply, renderReplyPreview: renderReplyPreviewProp, replyPreviewContainerStyle, replyPreviewTextStyle, } = props const colorScheme = useColorScheme() const containerStyles = useMemo(() => [ styles.container, colorScheme === 'dark' && styles.container_dark, containerStyle, ], [colorScheme, containerStyle]) const primaryStyles = useMemo(() => [ styles.primary, props.primaryStyle, ], [props.primaryStyle]) const actionsFragment = useMemo(() => { const actionsProps = { onPressActionButton, actions, actionSheetOptionTintColor, icon, wrapperStyle, containerStyle, } if (renderActions) return renderComponentOrElement(renderActions, actionsProps) if (onPressActionButton) return return null }, [ renderActions, onPressActionButton, actions, actionSheetOptionTintColor, icon, wrapperStyle, containerStyle, ]) const composerFragment = useMemo(() => { const composerProps = props as ComposerProps if (renderComposer) return renderComponentOrElement(renderComposer, composerProps) return }, [renderComposer, props]) const sendFragment = useMemo(() => { if (renderSend) return renderComponentOrElement(renderSend, props) return }, [renderSend, props]) const accessoryFragment = useMemo(() => { if (!renderAccessory) return null return renderComponentOrElement(renderAccessory, props) }, [renderAccessory, props]) const handleClearReply = useCallback(() => { onClearReply?.() }, [onClearReply]) const replyPreviewFragment = useMemo(() => { if (!replyMessage) return null const replyPreviewProps: ReplyPreviewProps = { replyMessage, onClearReply: handleClearReply, containerStyle: replyPreviewContainerStyle, textStyle: replyPreviewTextStyle, } if (renderReplyPreviewProp) return renderComponentOrElement(renderReplyPreviewProp, replyPreviewProps) return }, [ replyMessage, handleClearReply, renderReplyPreviewProp, replyPreviewContainerStyle, replyPreviewTextStyle, ]) return ( {replyPreviewFragment} {actionsFragment} {composerFragment} {sendFragment} {accessoryFragment} ) } const styles = StyleSheet.create({ container: { borderTopWidth: StyleSheet.hairlineWidth, borderTopColor: Color.defaultColor, backgroundColor: Color.white, }, container_dark: { backgroundColor: '#1a1a1a', borderTopColor: '#444', }, primary: { flexDirection: 'row', alignItems: 'flex-end', }, })