diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx
index f99a41b7f1..a92f3d50aa 100644
--- a/src/screens/Messages/Conversation/MessagesList.tsx
+++ b/src/screens/Messages/Conversation/MessagesList.tsx
@@ -10,7 +10,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {AppBskyRichtextFacet, RichText} from '@atproto/api'
import {shortenLinks} from '#/lib/strings/rich-text-manip'
-import {isIOS} from '#/platform/detection'
+import {isIOS, isNative} from '#/platform/detection'
import {useConvo} from '#/state/messages/convo'
import {ConvoItem, ConvoStatus} from '#/state/messages/convo/types'
import {useAgent} from '#/state/session'
@@ -85,7 +85,7 @@ export function MessagesList() {
// Instead, we use `onMomentumScrollEnd` and this value to determine if we need to start scrolling or not.
const isMomentumScrolling = useSharedValue(false)
- const [hasInitiallyScrolled, setHasInitiallyScrolled] = React.useState(false)
+ const hasInitiallyScrolled = useSharedValue(false)
// Every time the content size changes, that means one of two things is happening:
// 1. New messages are being added from the log or from a message you have sent
@@ -101,7 +101,7 @@ export function MessagesList() {
(_: number, height: number) => {
// Because web does not have `maintainVisibleContentPosition` support, we will need to manually scroll to the
// previous offset whenever we add new content to the previous offset whenever we add new content to the list.
- if (isWeb && isAtTop.value && hasInitiallyScrolled) {
+ if (isWeb && isAtTop.value && hasInitiallyScrolled.value) {
flatListRef.current?.scrollToOffset({
animated: false,
offset: height - contentHeight.value,
@@ -116,7 +116,7 @@ export function MessagesList() {
}
flatListRef.current?.scrollToOffset({
- animated: hasInitiallyScrolled,
+ animated: hasInitiallyScrolled.value,
offset: height,
})
isMomentumScrolling.value = true
@@ -133,7 +133,7 @@ export function MessagesList() {
// The check for `hasInitiallyScrolled` prevents an initial fetch on mount. FlatList triggers `onStartReached`
// immediately on mount, since we are in fact at an offset of zero, so we have to ignore those initial calls.
const onStartReached = useCallback(() => {
- if (convo.status === ConvoStatus.Ready && hasInitiallyScrolled) {
+ if (convo.status === ConvoStatus.Ready && hasInitiallyScrolled.value) {
convo.fetchMessageHistory()
}
}, [convo, hasInitiallyScrolled])
@@ -178,8 +178,8 @@ export function MessagesList() {
// This number _must_ be the height of the MaybeLoader component.
// We don't check for zero, because the `MaybeLoader` component is always present, even when not visible, which
// adds a 50 pixel offset.
- if (contentHeight.value > 50 && !hasInitiallyScrolled) {
- runOnJS(setHasInitiallyScrolled)(true)
+ if (contentHeight.value > 50 && !hasInitiallyScrolled.value) {
+ hasInitiallyScrolled.value = true
}
},
[contentHeight.value, hasInitiallyScrolled, isAtBottom, isAtTop],
@@ -228,17 +228,20 @@ export function MessagesList() {
data={convo.items}
renderItem={renderItem}
keyExtractor={keyExtractor}
+ containWeb={true}
+ contentContainerStyle={{
+ paddingHorizontal: 10,
+ }}
disableVirtualization={true}
- initialNumToRender={isWeb ? 50 : 25}
- maxToRenderPerBatch={isWeb ? 50 : 25}
+ initialNumToRender={isNative ? 30 : 60}
+ maxToRenderPerBatch={isWeb ? 30 : 60}
keyboardDismissMode="on-drag"
keyboardShouldPersistTaps="handled"
maintainVisibleContentPosition={{
minIndexForVisible: 1,
}}
- containWeb={true}
- contentContainerStyle={{paddingHorizontal: 10}}
removeClippedSubviews={false}
+ sideBorders={false}
onContentSizeChange={onContentSizeChange}
onStartReached={onStartReached}
onScrollToIndexFailed={onScrollToIndexFailed}
@@ -246,7 +249,6 @@ export function MessagesList() {
ListHeaderComponent={
}
- sideBorders={false}
/>
diff --git a/src/screens/Messages/Conversation/index.tsx b/src/screens/Messages/Conversation/index.tsx
index af9064cc30..4c8cfe7ed9 100644
--- a/src/screens/Messages/Conversation/index.tsx
+++ b/src/screens/Messages/Conversation/index.tsx
@@ -22,6 +22,7 @@ import {atoms as a, useBreakpoints, useTheme} from '#/alf'
import {ConvoMenu} from '#/components/dms/ConvoMenu'
import {Error} from '#/components/Error'
import {ListMaybePlaceholder} from '#/components/Lists'
+import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
import {ClipClopGate} from '../gate'
@@ -53,20 +54,27 @@ export function MessagesConversationScreen({route}: Props) {
}
function Inner() {
+ const t = useTheme()
const convo = useConvo()
const {_} = useLingui()
- if (
- convo.status === ConvoStatus.Uninitialized ||
- convo.status === ConvoStatus.Initializing
- ) {
- return (
-
-
-
-
- )
- }
+ const [hasInitiallyRendered, setHasInitiallyRendered] = React.useState(false)
+
+ // HACK: Because we need to scroll to the bottom of the list once initial items are added to the list, we also have
+ // to take into account that scrolling to the end of the list on native will happen asynchronously. This will cause
+ // a little flicker when the items are first renedered at the top and immediately scrolled to the bottom. to prevent
+ // this, we will wait until the first render has completed to remove the loading overlay.
+ React.useEffect(() => {
+ if (
+ !hasInitiallyRendered &&
+ convo.status === ConvoStatus.Ready &&
+ !convo.isFetchingHistory
+ ) {
+ setTimeout(() => {
+ setHasInitiallyRendered(true)
+ }, 15)
+ }
+ }, [convo.isFetchingHistory, convo.items, convo.status, hasInitiallyRendered])
if (convo.status === ConvoStatus.Error) {
return (
@@ -88,8 +96,30 @@ function Inner() {
return (
-
-
+
+
+ {convo.status !== ConvoStatus.Ready ? (
+
+ ) : (
+
+ )}
+ {!hasInitiallyRendered && (
+
+
+
+
+
+ )}
+
)
@@ -128,7 +158,8 @@ let Header = ({
a.justify_between,
a.align_start,
a.gap_lg,
- a.px_lg,
+ a.pl_xl,
+ a.pr_lg,
a.py_sm,
]}>
{!gtTablet ? (
@@ -154,12 +185,19 @@ let Header = ({
)}
{profile ? (
- <>
+
-
+
{profile.displayName}
- >
+
+ @{profile.handle}
+
+
) : (
<>
+
>
diff --git a/src/state/messages/convo/agent.ts b/src/state/messages/convo/agent.ts
index 12e24577e7..6801def751 100644
--- a/src/state/messages/convo/agent.ts
+++ b/src/state/messages/convo/agent.ts
@@ -554,7 +554,7 @@ export class Convo {
{
cursor: nextCursor,
convoId: this.convoId,
- limit: isNative ? 40 : 60,
+ limit: isNative ? 30 : 60,
},
{
headers: {