Mount message dialogs once at the list level (#10435)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
@@ -56,6 +56,7 @@ import {MessageListError} from '#/screens/Messages/components/MessageListError'
|
||||
import {atoms as a, platform, tokens, useTheme, web} from '#/alf'
|
||||
import {DateDivider} from '#/components/dms/DateDivider'
|
||||
import {MessageItem} from '#/components/dms/MessageItem'
|
||||
import {MessageOverlays} from '#/components/dms/MessageOverlays'
|
||||
import {NewMessagesPill} from '#/components/dms/NewMessagesPill'
|
||||
import {SystemMessageGroup} from '#/components/dms/SystemMessageGroup'
|
||||
import {SystemMessageItem} from '#/components/dms/SystemMessageItem'
|
||||
@@ -498,127 +499,133 @@ export function MessagesList({
|
||||
|
||||
return (
|
||||
<InviteLinkDialogProvider convo={convoState.convo}>
|
||||
<KeyboardGestureArea
|
||||
interpolator="ios"
|
||||
// HACKFIX: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/1419
|
||||
offset={Math.round(inputHeightJS)}
|
||||
// slightly too buggy unfortunately, enable when possible
|
||||
// textInputNativeID={textInputId}
|
||||
style={[a.flex_1]}>
|
||||
{/* Custom scroll provider so that we can use the `onScroll` event in our custom List implementation */}
|
||||
<Animated.View style={[a.flex_1, animatedListStyle]}>
|
||||
<ScrollProvider onScroll={onScroll}>
|
||||
<List
|
||||
ref={flatListRef}
|
||||
data={renderItems}
|
||||
renderItem={renderItem}
|
||||
keyExtractor={keyExtractor}
|
||||
disableFullWindowScroll={true}
|
||||
disableVirtualization={true}
|
||||
// The extra two items account for the header and the footer components
|
||||
initialNumToRender={IS_NATIVE ? 32 : 62}
|
||||
maxToRenderPerBatch={IS_WEB ? 32 : 62}
|
||||
keyboardDismissMode="interactive"
|
||||
keyboardShouldPersistTaps="handled"
|
||||
maintainVisibleContentPosition={{minIndexForVisible: 0}}
|
||||
removeClippedSubviews={false}
|
||||
sideBorders={false}
|
||||
onContentSizeChange={onContentSizeChange}
|
||||
onStartReached={onStartReached}
|
||||
onScrollToIndexFailed={onScrollToIndexFailed}
|
||||
showsVerticalScrollIndicator={!IS_ANDROID}
|
||||
scrollEventThrottle={100}
|
||||
ListHeaderComponent={
|
||||
<>
|
||||
<MaybeLoader isLoading={convoState.isFetchingHistory} />
|
||||
{convoState.hasAllHistory ? (
|
||||
convoState.convo?.kind === 'group' ? (
|
||||
<MessagesListGroupInfoPanel convo={convoState.convo} />
|
||||
) : (
|
||||
<MessagesListInfoPanel convo={convoState.convo} />
|
||||
)
|
||||
) : null}
|
||||
</>
|
||||
}
|
||||
// native only (prop is not supported on web)
|
||||
renderScrollComponent={renderScrollComponent}
|
||||
contentContainerStyle={{
|
||||
paddingBottom: platform({
|
||||
// ios is slightly larger as the input has no top padding
|
||||
ios: tokens.space.lg,
|
||||
android: tokens.space.md,
|
||||
web: 0, // web uses ListFooterComponent instead for scroll reasons
|
||||
}),
|
||||
}}
|
||||
ListFooterComponent={
|
||||
<View
|
||||
style={web({height: tokens.space.md + inputHeightJS})}
|
||||
onLayout={onFooterLayout}
|
||||
/>
|
||||
}
|
||||
style={[
|
||||
web({
|
||||
scrollbarWidth: 'thin',
|
||||
scrollbarColor: `${t.palette.contrast_100} transparent`,
|
||||
scrollbarGutter: 'stable',
|
||||
}),
|
||||
]}
|
||||
pointerEvents={!hasScrolled ? 'none' : 'auto'}
|
||||
contentInset={{top: transparentHeaderHeight}}
|
||||
scrollIndicatorInsets={{top: transparentHeaderHeight}}
|
||||
/>
|
||||
</ScrollProvider>
|
||||
</Animated.View>
|
||||
<KeyboardStickyView
|
||||
style={[a.absolute, a.bottom_0, a.left_0, a.right_0]}
|
||||
onLayout={onInputLayout}
|
||||
minimumOffset={bottomInset}
|
||||
offset={{
|
||||
closed: platform({
|
||||
ios: tokens.space.lg, // hide bottom padding when closed
|
||||
default: 0,
|
||||
}),
|
||||
opened: 0,
|
||||
}}>
|
||||
{footer ?? (
|
||||
<ConversationFooter
|
||||
convoState={convoState}
|
||||
hasAcceptOverride={hasAcceptOverride}>
|
||||
{({loading}) =>
|
||||
ax.features.enabled(ax.features.DmsNewMessageComposerEnable) ? (
|
||||
<MessageComposer
|
||||
textInputId={textInputId}
|
||||
onSendMessage={(message: string) =>
|
||||
void onSendMessage(message)
|
||||
}
|
||||
hasEmbed={!!embedUri}
|
||||
setEmbed={setEmbed}
|
||||
loading={loading}>
|
||||
<MessageInputEmbed
|
||||
embedUri={embedUri}
|
||||
<MessageOverlays>
|
||||
<KeyboardGestureArea
|
||||
interpolator="ios"
|
||||
// HACKFIX: https://github.com/kirillzyusko/react-native-keyboard-controller/issues/1419
|
||||
offset={Math.round(inputHeightJS)}
|
||||
// slightly too buggy unfortunately, enable when possible
|
||||
// textInputNativeID={textInputId}
|
||||
style={[a.flex_1]}>
|
||||
{/* Custom scroll provider so that we can use the `onScroll` event in our custom List implementation */}
|
||||
<Animated.View style={[a.flex_1, animatedListStyle]}>
|
||||
<ScrollProvider onScroll={onScroll}>
|
||||
<List
|
||||
ref={flatListRef}
|
||||
data={renderItems}
|
||||
renderItem={renderItem}
|
||||
keyExtractor={keyExtractor}
|
||||
disableFullWindowScroll={true}
|
||||
disableVirtualization={true}
|
||||
// The extra two items account for the header and the footer components
|
||||
initialNumToRender={IS_NATIVE ? 32 : 62}
|
||||
maxToRenderPerBatch={IS_WEB ? 32 : 62}
|
||||
keyboardDismissMode="interactive"
|
||||
keyboardShouldPersistTaps="handled"
|
||||
maintainVisibleContentPosition={{minIndexForVisible: 0}}
|
||||
removeClippedSubviews={false}
|
||||
sideBorders={false}
|
||||
onContentSizeChange={onContentSizeChange}
|
||||
onStartReached={onStartReached}
|
||||
onScrollToIndexFailed={onScrollToIndexFailed}
|
||||
showsVerticalScrollIndicator={!IS_ANDROID}
|
||||
scrollEventThrottle={100}
|
||||
ListHeaderComponent={
|
||||
<>
|
||||
<MaybeLoader isLoading={convoState.isFetchingHistory} />
|
||||
{convoState.hasAllHistory ? (
|
||||
convoState.convo?.kind === 'group' ? (
|
||||
<MessagesListGroupInfoPanel convo={convoState.convo} />
|
||||
) : (
|
||||
<MessagesListInfoPanel convo={convoState.convo} />
|
||||
)
|
||||
) : null}
|
||||
</>
|
||||
}
|
||||
// native only (prop is not supported on web)
|
||||
renderScrollComponent={renderScrollComponent}
|
||||
contentContainerStyle={{
|
||||
paddingBottom: platform({
|
||||
// ios is slightly larger as the input has no top padding
|
||||
ios: tokens.space.lg,
|
||||
android: tokens.space.md,
|
||||
web: 0, // web uses ListFooterComponent instead for scroll reasons
|
||||
}),
|
||||
}}
|
||||
ListFooterComponent={
|
||||
<View
|
||||
style={web({height: tokens.space.md + inputHeightJS})}
|
||||
onLayout={onFooterLayout}
|
||||
/>
|
||||
}
|
||||
style={[
|
||||
web({
|
||||
scrollbarWidth: 'thin',
|
||||
scrollbarColor: `${t.palette.contrast_100} transparent`,
|
||||
scrollbarGutter: 'stable',
|
||||
}),
|
||||
]}
|
||||
pointerEvents={!hasScrolled ? 'none' : 'auto'}
|
||||
contentInset={{top: transparentHeaderHeight}}
|
||||
scrollIndicatorInsets={{top: transparentHeaderHeight}}
|
||||
/>
|
||||
</ScrollProvider>
|
||||
</Animated.View>
|
||||
<KeyboardStickyView
|
||||
style={[a.absolute, a.bottom_0, a.left_0, a.right_0]}
|
||||
onLayout={onInputLayout}
|
||||
minimumOffset={bottomInset}
|
||||
offset={{
|
||||
closed: platform({
|
||||
ios: tokens.space.lg, // hide bottom padding when closed
|
||||
default: 0,
|
||||
}),
|
||||
opened: 0,
|
||||
}}>
|
||||
{footer ?? (
|
||||
<ConversationFooter
|
||||
convoState={convoState}
|
||||
hasAcceptOverride={hasAcceptOverride}>
|
||||
{({loading}) =>
|
||||
ax.features.enabled(
|
||||
ax.features.DmsNewMessageComposerEnable,
|
||||
) ? (
|
||||
<MessageComposer
|
||||
textInputId={textInputId}
|
||||
onSendMessage={(message: string) =>
|
||||
void onSendMessage(message)
|
||||
}
|
||||
hasEmbed={!!embedUri}
|
||||
setEmbed={setEmbed}
|
||||
/>
|
||||
</MessageComposer>
|
||||
) : (
|
||||
<MessageInput
|
||||
textInputId={textInputId}
|
||||
onSendMessage={onSendMessage}
|
||||
hasEmbed={!!embedUri}
|
||||
setEmbed={setEmbed}
|
||||
loading={loading}>
|
||||
<MessageInputEmbed
|
||||
embedUri={embedUri}
|
||||
loading={loading}>
|
||||
<MessageInputEmbed
|
||||
embedUri={embedUri}
|
||||
setEmbed={setEmbed}
|
||||
/>
|
||||
</MessageComposer>
|
||||
) : (
|
||||
<MessageInput
|
||||
textInputId={textInputId}
|
||||
onSendMessage={onSendMessage}
|
||||
hasEmbed={!!embedUri}
|
||||
setEmbed={setEmbed}
|
||||
/>
|
||||
</MessageInput>
|
||||
)
|
||||
}
|
||||
</ConversationFooter>
|
||||
)}
|
||||
</KeyboardStickyView>
|
||||
</KeyboardGestureArea>
|
||||
loading={loading}>
|
||||
<MessageInputEmbed
|
||||
embedUri={embedUri}
|
||||
setEmbed={setEmbed}
|
||||
/>
|
||||
</MessageInput>
|
||||
)
|
||||
}
|
||||
</ConversationFooter>
|
||||
)}
|
||||
</KeyboardStickyView>
|
||||
</KeyboardGestureArea>
|
||||
|
||||
{newMessagesPill.show && <NewMessagesPill onPress={scrollToEndOnPress} />}
|
||||
{newMessagesPill.show && (
|
||||
<NewMessagesPill onPress={scrollToEndOnPress} />
|
||||
)}
|
||||
</MessageOverlays>
|
||||
</InviteLinkDialogProvider>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user