Skip to content

Commit

Permalink
more optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
kesha-antonov committed Jul 12, 2024
1 parent 87393fc commit d060916
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 44 deletions.
1 change: 0 additions & 1 deletion example/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ const App = () => {
)

const onLoadEarlier = useCallback(() => {
console.log('loading')
dispatch({ type: ActionKind.LOAD_EARLIER_START })
setTimeout(() => {
const newMessages = GiftedChat.prepend(
Expand Down
16 changes: 8 additions & 8 deletions src/Actions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types'
import React, { ReactNode } from 'react'
import React, { ReactNode, useCallback } from 'react'
import {
StyleSheet,
Text,
Expand All @@ -12,7 +12,6 @@ import {
import Color from './Color'
import { StylePropType } from './utils'
import { useChatContext } from './GiftedChatContext'
import { useCallbackOne } from 'use-memo-one'

export interface ActionsProps {
options?: { [key: string]: any }
Expand All @@ -25,7 +24,7 @@ export interface ActionsProps {
}

export function Actions ({
options = {},
options,
optionTintColor = Color.optionTintColor,
icon,
wrapperStyle,
Expand All @@ -35,7 +34,9 @@ export function Actions ({
}: ActionsProps) {
const { actionSheet } = useChatContext()

const onActionsPress = useCallbackOne(() => {
const onActionsPress = useCallback(() => {
if (!options) return

const optionKeys = Object.keys(options)
const cancelButtonIndex = optionKeys.indexOf('Cancel')

Expand All @@ -51,9 +52,9 @@ export function Actions ({
options[key]()
}
)
}, [])
}, [actionSheet, options, optionTintColor])

const renderIcon = useCallbackOne(() => {
const renderIcon = useCallback(() => {
if (icon)
return icon()

Expand All @@ -62,7 +63,7 @@ export function Actions ({
<Text style={[styles.iconText, iconTextStyle]}>{'+'}</Text>
</View>
)
}, [])
}, [icon, iconTextStyle, wrapperStyle])

return (
<TouchableOpacity
Expand All @@ -75,7 +76,6 @@ export function Actions ({
}

Actions.propTypes = {
onSend: PropTypes.func,
options: PropTypes.object,
optionTintColor: PropTypes.string,
icon: PropTypes.func,
Expand Down
21 changes: 14 additions & 7 deletions src/GiftedChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,18 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
inverted = true,
minComposerHeight = MIN_COMPOSER_HEIGHT,
maxComposerHeight = MAX_COMPOSER_HEIGHT,
messageContainerRef = createRef<FlatList<IMessage>>(),
textInputRef = createRef<TextInput>(),
} = props

const actionSheetRef = useRef<ActionSheetProviderRef>(null)

const messageContainerRef = useMemo(() =>
props.messageContainerRef || createRef<FlatList<IMessage>>()
, [props.messageContainerRef])

const textInputRef = useMemo(() =>
props.textInputRef || createRef<TextInput>()
, [props.textInputRef])

const isTextInputWasFocused: MutableRefObject<boolean> = useRef(false)

const [isInitialized, setIsInitialized] = useState<boolean>(false)
Expand Down Expand Up @@ -326,7 +332,9 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
messageContainerRef.current.scrollToEnd({ animated: isAnimated })
}, [inverted, messageContainerRef])

const renderMessages = useCallback(() => {
const renderMessages = useMemo(() => {
if (!isInitialized) return null

const { messagesContainerStyle, ...messagesContainerProps } = props

const fragment = (
Expand All @@ -352,6 +360,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (

return fragment
}, [
isInitialized,
isTyping,
messages,
props,
Expand Down Expand Up @@ -416,9 +425,8 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
onInputTextChanged?.(_text)

// Only set state if it's not being overridden by a prop.
if (props.text === undefined) {
if (props.text === undefined)
setText(_text)
}
}, [onInputTextChanged, isTypingDisabled, props.text])

const onInitialLayoutViewLayout = useCallback((e: any) => {
Expand Down Expand Up @@ -518,7 +526,6 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
[keyboard, trackingKeyboardMovement, insets, handleTextInputFocusWhenKeyboardHide, handleTextInputFocusWhenKeyboardShow, enableTyping, diableTyping, debounceEnableTyping]
)


return (
<GiftedChatContext.Provider value={contextValues}>
<ActionSheetProvider ref={actionSheetRef}>
Expand All @@ -531,7 +538,7 @@ function GiftedChat<TMessage extends IMessage = IMessage> (
isInitialized
? (
<Animated.View style={[styles.fill, contentStyleAnim]}>
{renderMessages()}
{renderMessages}
{inputToolbarFragment}
</Animated.View>
)
Expand Down
42 changes: 36 additions & 6 deletions src/InputToolbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types'
import React from 'react'
import React, { useMemo } from 'react'
import { StyleSheet, View, StyleProp, ViewStyle } from 'react-native'

import { Composer, ComposerProps } from './Composer'
Expand All @@ -20,26 +20,56 @@ export interface InputToolbarProps<TMessage extends IMessage> {
renderSend?(props: SendProps<TMessage>): React.ReactNode
renderComposer?(props: ComposerProps): React.ReactNode
onPressActionButton?(): void
icon?: () => React.ReactNode
wrapperStyle?: StyleProp<ViewStyle>
}

export function InputToolbar<TMessage extends IMessage = IMessage> (
props: InputToolbarProps<TMessage>
) {
const { containerStyle, ...rest } = props
const {
renderActions,
onPressActionButton,
renderComposer,
renderSend,
renderAccessory,
} = rest
options,
optionTintColor,
icon,
wrapperStyle,
containerStyle,
} = props

const actionsFragment = useMemo(() => {
const props = {
options,
optionTintColor,
icon,
wrapperStyle,
containerStyle,
}

return renderActions?.(props) ||
(onPressActionButton && <Actions {...props} />)
}, [
renderActions,
onPressActionButton,
options,
optionTintColor,
icon,
wrapperStyle,
containerStyle,
])

const composerFragment = useMemo(() => {
return renderComposer?.(props as ComposerProps) || <Composer {...props as ComposerProps} />
}, [renderComposer, props])

return (
<View style={[styles.container, containerStyle]}>
<View style={[styles.primary, props.primaryStyle]}>
{renderActions?.(rest) ||
(onPressActionButton && <Actions {...rest} />)}
{renderComposer?.(props as ComposerProps) || <Composer {...props} />}
{actionsFragment}
{composerFragment}
{renderSend?.(props) || <Send {...props} />}
</View>
{renderAccessory && (
Expand Down
25 changes: 9 additions & 16 deletions src/Message.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import PropTypes from 'prop-types'
import React from 'react'
import { View, StyleSheet, ViewStyle, LayoutChangeEvent } from 'react-native'
import isEqual from 'lodash.isequal'

Check failure on line 4 in src/Message.tsx

View workflow job for this annotation

GitHub Actions / checks (18)

Cannot find module 'lodash.isequal' or its corresponding type declarations.

import { Avatar, AvatarProps } from './Avatar'
import Bubble from './Bubble'
Expand Down Expand Up @@ -99,24 +100,16 @@ export default class Message<
const nextPropsMessage = nextProps.nextMessage
const nextPropsPreviousMessage = nextProps.previousMessage

const shouldUpdate =
(this.props.shouldUpdateMessage &&
this.props.shouldUpdateMessage(this.props, nextProps)) ||
let shouldUpdate =
this.props.shouldUpdateMessage?.(this.props, nextProps) ||
false

return (
next.sent !== current.sent ||
next.received !== current.received ||
next.pending !== current.pending ||
next.createdAt !== current.createdAt ||
next.text !== current.text ||
next.image !== current.image ||
next.video !== current.video ||
next.audio !== current.audio ||
previousMessage !== nextPropsPreviousMessage ||
nextMessage !== nextPropsMessage ||
shouldUpdate
)
shouldUpdate = shouldUpdate ||
!isEqual(current, next) ||
!isEqual(previousMessage, nextPropsPreviousMessage) ||
!isEqual(nextMessage, nextPropsMessage)

return shouldUpdate
}

renderDay () {
Expand Down
1 change: 1 addition & 0 deletions src/MessageContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ export default class MessageContainer<

render () {
const { inverted } = this.props

return (
<View
style={
Expand Down
11 changes: 5 additions & 6 deletions src/Send.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from 'react'
import React, { useMemo, useCallback } from 'react'
import PropTypes from 'prop-types'
import {
StyleSheet,
Expand All @@ -10,7 +10,6 @@ import {
TextStyle,
TouchableOpacityProps,
} from 'react-native'
import { useCallbackOne, useMemoOne } from 'use-memo-one'

import Color from './Color'
import { IMessage } from './Models'
Expand Down Expand Up @@ -49,22 +48,22 @@ export interface SendProps<TMessage extends IMessage> {
}

export const Send = <TMessage extends IMessage = IMessage>({
text = '',
text,
containerStyle,
children,
textStyle,
label = 'Send',
alwaysShowSend = false,
disabled = false,
sendButtonProps,
onSend = () => {},
onSend,
}: SendProps<TMessage>) => {
const handleOnPress = useCallbackOne(() => {
const handleOnPress = useCallback(() => {
if (text && onSend)
onSend({ text: text.trim() } as Partial<TMessage>, true)
}, [text, onSend])

const showSend = useMemoOne(
const showSend = useMemo(
() => alwaysShowSend || (text && text.trim().length > 0),
[alwaysShowSend, text]
)
Expand Down

0 comments on commit d060916

Please sign in to comment.