Changeset View
Changeset View
Standalone View
Standalone View
native/chat/inner-text-message.react.js
// @flow | // @flow | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { View, StyleSheet, TouchableWithoutFeedback } from 'react-native'; | import { View, StyleSheet, TouchableWithoutFeedback } from 'react-native'; | ||||
import Animated from 'react-native-reanimated'; | import Animated from 'react-native-reanimated'; | ||||
import { colorIsDark } from 'lib/shared/thread-utils.js'; | import { colorIsDark } from 'lib/shared/thread-utils.js'; | ||||
import { avatarOffset } from './chat-constants.js'; | |||||
import { useComposedMessageMaxWidth } from './composed-message-width.js'; | import { useComposedMessageMaxWidth } from './composed-message-width.js'; | ||||
import { useTextMessageMarkdownRules } from './message-list-types.js'; | import { useTextMessageMarkdownRules } from './message-list-types.js'; | ||||
import { | import { | ||||
allCorners, | allCorners, | ||||
filterCorners, | filterCorners, | ||||
getRoundedContainerStyle, | getRoundedContainerStyle, | ||||
} from './rounded-corners.js'; | } from './rounded-corners.js'; | ||||
import { | import { | ||||
Show All 17 Lines | |||||
} | } | ||||
type DummyTextNodeProps = { | type DummyTextNodeProps = { | ||||
...React.ElementConfig<typeof View>, | ...React.ElementConfig<typeof View>, | ||||
+children: string, | +children: string, | ||||
}; | }; | ||||
function DummyTextNode(props: DummyTextNodeProps): React.Node { | function DummyTextNode(props: DummyTextNodeProps): React.Node { | ||||
const { children, style, ...rest } = props; | const { children, style, ...rest } = props; | ||||
const maxWidth = useComposedMessageMaxWidth(); | const maxWidth = useComposedMessageMaxWidth() - avatarOffset; | ||||
const viewStyle = [props.style, styles.dummyMessage, { maxWidth }]; | const viewStyle = [props.style, styles.dummyMessage, { maxWidth }]; | ||||
const rules = useTextMessageMarkdownRules(false); | const rules = useTextMessageMarkdownRules(false); | ||||
return ( | return ( | ||||
<View {...rest} style={viewStyle}> | <View {...rest} style={viewStyle}> | ||||
<Markdown style={styles.text} rules={rules}> | <Markdown style={styles.text} rules={rules}> | ||||
{children} | {children} | ||||
</Markdown> | </Markdown> | ||||
</View> | </View> | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | const textStyle = { | ||||
color: darkColor | color: darkColor | ||||
? colors.dark.listForegroundLabel | ? colors.dark.listForegroundLabel | ||||
: colors.light.listForegroundLabel, | : colors.light.listForegroundLabel, | ||||
}; | }; | ||||
return [styles.text, textStyle]; | return [styles.text, textStyle]; | ||||
}, [darkColor]); | }, [darkColor]); | ||||
const maxWidth = useComposedMessageMaxWidth() - avatarOffset; | |||||
const maxWidthStyle = React.useMemo(() => ({ maxWidth }), [maxWidth]); | |||||
// If we need to render a Text with an onPress prop inside, we're going to | // If we need to render a Text with an onPress prop inside, we're going to | ||||
// have an issue: the GestureTouchableOpacity below will trigger too when the | // have an issue: the GestureTouchableOpacity below will trigger too when the | ||||
// the onPress is pressed. We have to use a GestureTouchableOpacity in order | // the onPress is pressed. We have to use a GestureTouchableOpacity in order | ||||
// for the message touch gesture to play nice with the message swipe gesture, | // for the message touch gesture to play nice with the message swipe gesture, | ||||
// so we need to find a way to disable the GestureTouchableOpacity. | // so we need to find a way to disable the GestureTouchableOpacity. | ||||
// | // | ||||
// Our solution is to keep using the GestureTouchableOpacity for the padding | // Our solution is to keep using the GestureTouchableOpacity for the padding | ||||
// around the text, and to have the Texts inside ALL implement an onPress prop | // around the text, and to have the Texts inside ALL implement an onPress prop | ||||
Show All 16 Lines | function InnerTextMessage(props: Props): React.Node { | ||||
const message = ( | const message = ( | ||||
<TextMessageMarkdownContext.Provider value={textMessageMarkdown}> | <TextMessageMarkdownContext.Provider value={textMessageMarkdown}> | ||||
<TouchableWithoutFeedback> | <TouchableWithoutFeedback> | ||||
<View> | <View> | ||||
<GestureTouchableOpacity | <GestureTouchableOpacity | ||||
onPress={props.onPress} | onPress={props.onPress} | ||||
onLongPress={props.onPress} | onLongPress={props.onPress} | ||||
activeOpacity={0.6} | activeOpacity={0.6} | ||||
style={[styles.message, cornerStyle]} | style={[styles.message, cornerStyle, maxWidthStyle]} | ||||
animatedStyle={messageStyle} | animatedStyle={messageStyle} | ||||
> | > | ||||
<Markdown style={markdownStyles} rules={rules}> | <Markdown style={markdownStyles} rules={rules}> | ||||
{text} | {text} | ||||
</Markdown> | </Markdown> | ||||
</GestureTouchableOpacity> | </GestureTouchableOpacity> | ||||
{secondMessage} | {secondMessage} | ||||
</View> | </View> | ||||
Show All 36 Lines |