Changeset View
Changeset View
Standalone View
Standalone View
native/chat/text-message.react.js
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | type Props = { | ||||
...BaseProps, | ...BaseProps, | ||||
// Redux state | // Redux state | ||||
+canCreateSidebarFromMessage: boolean, | +canCreateSidebarFromMessage: boolean, | ||||
// withOverlayContext | // withOverlayContext | ||||
+overlayContext: ?OverlayContextType, | +overlayContext: ?OverlayContextType, | ||||
// ChatContext | // ChatContext | ||||
+chatContext: ?ChatContextType, | +chatContext: ?ChatContextType, | ||||
// MarkdownContext | // MarkdownContext | ||||
+linkModalActive: boolean, | +isLinkModalActive: boolean, | ||||
}; | }; | ||||
class TextMessage extends React.PureComponent<Props> { | class TextMessage extends React.PureComponent<Props> { | ||||
message: ?React.ElementRef<typeof View>; | message: ?React.ElementRef<typeof View>; | ||||
messagePressResponderContext: MessagePressResponderContextType; | messagePressResponderContext: MessagePressResponderContextType; | ||||
constructor(props: Props) { | constructor(props: Props) { | ||||
super(props); | super(props); | ||||
this.messagePressResponderContext = { | this.messagePressResponderContext = { | ||||
onPressMessage: this.onPress, | onPressMessage: this.onPress, | ||||
}; | }; | ||||
} | } | ||||
render() { | render() { | ||||
const { | const { | ||||
item, | item, | ||||
navigation, | navigation, | ||||
route, | route, | ||||
focused, | focused, | ||||
toggleFocus, | toggleFocus, | ||||
verticalBounds, | verticalBounds, | ||||
overlayContext, | overlayContext, | ||||
chatContext, | chatContext, | ||||
linkModalActive, | isLinkModalActive, | ||||
canCreateSidebarFromMessage, | canCreateSidebarFromMessage, | ||||
...viewProps | ...viewProps | ||||
} = this.props; | } = this.props; | ||||
let swipeOptions = 'none'; | let swipeOptions = 'none'; | ||||
const canReply = this.canReply(); | const canReply = this.canReply(); | ||||
const canNavigateToSidebar = this.canNavigateToSidebar(); | const canNavigateToSidebar = this.canNavigateToSidebar(); | ||||
if (linkModalActive) { | if (isLinkModalActive) { | ||||
swipeOptions = 'none'; | swipeOptions = 'none'; | ||||
} else if (canReply && canNavigateToSidebar) { | } else if (canReply && canNavigateToSidebar) { | ||||
swipeOptions = 'both'; | swipeOptions = 'both'; | ||||
} else if (canReply) { | } else if (canReply) { | ||||
swipeOptions = 'reply'; | swipeOptions = 'reply'; | ||||
} else if (canNavigateToSidebar) { | } else if (canNavigateToSidebar) { | ||||
swipeOptions = 'sidebar'; | swipeOptions = 'sidebar'; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | class TextMessage extends React.PureComponent<Props> { | ||||
onPress = () => { | onPress = () => { | ||||
const visibleEntryIDs = this.visibleEntryIDs(); | const visibleEntryIDs = this.visibleEntryIDs(); | ||||
if (visibleEntryIDs.length === 0) { | if (visibleEntryIDs.length === 0) { | ||||
return; | return; | ||||
} | } | ||||
const { | const { | ||||
message, | message, | ||||
props: { verticalBounds, linkModalActive }, | props: { verticalBounds, isLinkModalActive }, | ||||
} = this; | } = this; | ||||
if (!message || !verticalBounds || linkModalActive) { | if (!message || !verticalBounds || isLinkModalActive) { | ||||
return; | return; | ||||
} | } | ||||
const { focused, toggleFocus, item } = this.props; | const { focused, toggleFocus, item } = this.props; | ||||
if (!focused) { | if (!focused) { | ||||
toggleFocus(messageKey(item.messageInfo)); | toggleFocus(messageKey(item.messageInfo)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | onPress = () => { | ||||
}); | }); | ||||
}; | }; | ||||
} | } | ||||
const ConnectedTextMessage: React.ComponentType<BaseProps> = React.memo<BaseProps>( | const ConnectedTextMessage: React.ComponentType<BaseProps> = React.memo<BaseProps>( | ||||
function ConnectedTextMessage(props: BaseProps) { | function ConnectedTextMessage(props: BaseProps) { | ||||
const overlayContext = React.useContext(OverlayContext); | const overlayContext = React.useContext(OverlayContext); | ||||
const chatContext = React.useContext(ChatContext); | const chatContext = React.useContext(ChatContext); | ||||
const markdownContext = React.useContext(MarkdownContext); | |||||
invariant(markdownContext, 'markdownContext should be set'); | |||||
const { linkModalActive, clearMarkdownContextData } = markdownContext; | |||||
const key = messageKey(props.item.messageInfo); | |||||
// We check if there is an key in the object - if not, we | |||||
// default to false. The likely situation where the former statement | |||||
// evaluates to null is when the thread is opened for the first time. | |||||
const isLinkModalActive = linkModalActive[key] ?? false; | |||||
const [linkModalActive, setLinkModalActive] = React.useState(false); | |||||
const markdownContext = React.useMemo( | |||||
() => ({ | |||||
setLinkModalActive, | |||||
}), | |||||
[setLinkModalActive], | |||||
); | |||||
const canCreateSidebarFromMessage = useCanCreateSidebarFromMessage( | const canCreateSidebarFromMessage = useCanCreateSidebarFromMessage( | ||||
props.item.threadInfo, | props.item.threadInfo, | ||||
props.item.messageInfo, | props.item.messageInfo, | ||||
); | ); | ||||
React.useEffect(() => clearMarkdownContextData, [clearMarkdownContextData]); | |||||
return ( | return ( | ||||
<MarkdownContext.Provider value={markdownContext}> | |||||
<TextMessage | <TextMessage | ||||
{...props} | {...props} | ||||
canCreateSidebarFromMessage={canCreateSidebarFromMessage} | canCreateSidebarFromMessage={canCreateSidebarFromMessage} | ||||
overlayContext={overlayContext} | overlayContext={overlayContext} | ||||
chatContext={chatContext} | chatContext={chatContext} | ||||
linkModalActive={linkModalActive} | isLinkModalActive={isLinkModalActive} | ||||
/> | /> | ||||
</MarkdownContext.Provider> | |||||
); | ); | ||||
}, | }, | ||||
); | ); | ||||
export { ConnectedTextMessage as TextMessage }; | export { ConnectedTextMessage as TextMessage }; |