Fix chat message spacing and alignment (#10579)
This commit is contained in:
@@ -68,7 +68,6 @@ function isWithinClusterBoundary({
|
|||||||
direction: 'prev' | 'next'
|
direction: 'prev' | 'next'
|
||||||
}): boolean {
|
}): boolean {
|
||||||
if (!isFromSameSender) return true
|
if (!isFromSameSender) return true
|
||||||
if (isPending && adjacentMessage) return false
|
|
||||||
if (ChatBskyConvoDefs.isMessageView(adjacentMessage)) {
|
if (ChatBskyConvoDefs.isMessageView(adjacentMessage)) {
|
||||||
const thisDate = new Date(currentSentAt)
|
const thisDate = new Date(currentSentAt)
|
||||||
const adjDate = new Date(adjacentMessage.sentAt)
|
const adjDate = new Date(adjacentMessage.sentAt)
|
||||||
@@ -76,7 +75,10 @@ function isWithinClusterBoundary({
|
|||||||
direction === 'next'
|
direction === 'next'
|
||||||
? adjDate.getTime() - thisDate.getTime()
|
? adjDate.getTime() - thisDate.getTime()
|
||||||
: thisDate.getTime() - adjDate.getTime()
|
: thisDate.getTime() - adjDate.getTime()
|
||||||
return diff > CLUSTERED_MESSAGE_THRESHOLD_MS
|
const isOutsideThreshold = diff > CLUSTERED_MESSAGE_THRESHOLD_MS
|
||||||
|
// For pending messages, still check the time threshold
|
||||||
|
if (isPending) return isOutsideThreshold
|
||||||
|
return isOutsideThreshold
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -386,7 +388,11 @@ let MessageItem = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{hasLargeGapFromPrev && <DateDivider date={message.sentAt} />}
|
{hasLargeGapFromPrev && <DateDivider date={message.sentAt} />}
|
||||||
<View style={[messageInset, isFirstInCluster && a.mt_md]}>
|
<View
|
||||||
|
style={[
|
||||||
|
messageInset,
|
||||||
|
isFirstInCluster ? a.mt_md : {marginTop: CLUSTERED_MESSAGE_GAP},
|
||||||
|
]}>
|
||||||
<View style={[a.relative]}>
|
<View style={[a.relative]}>
|
||||||
{showAvatar ? (
|
{showAvatar ? (
|
||||||
<View
|
<View
|
||||||
@@ -435,9 +441,9 @@ let MessageItem = ({
|
|||||||
<MessageItemEmbed
|
<MessageItemEmbed
|
||||||
embed={message.embed}
|
embed={message.embed}
|
||||||
isFromSelf={isFromSelf}
|
isFromSelf={isFromSelf}
|
||||||
|
isGroupChat={isGroupChat}
|
||||||
squaredBottomCorner={squaredBottomCorner || hasEmbedAndText}
|
squaredBottomCorner={squaredBottomCorner || hasEmbedAndText}
|
||||||
squaredTopCorner={squaredTopCorner}
|
squaredTopCorner={squaredTopCorner}
|
||||||
isFirstInCluster={isFirstInCluster}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{rt.text.length > 0 && (
|
{rt.text.length > 0 && (
|
||||||
@@ -450,10 +456,7 @@ let MessageItem = ({
|
|||||||
a.py_sm,
|
a.py_sm,
|
||||||
a.px_md,
|
a.px_md,
|
||||||
{
|
{
|
||||||
marginTop:
|
marginTop: hasEmbedAndText ? CLUSTERED_MESSAGE_GAP : 0,
|
||||||
hasEmbedAndText || !isFirstInCluster
|
|
||||||
? CLUSTERED_MESSAGE_GAP
|
|
||||||
: 0,
|
|
||||||
backgroundColor: isFromSelf
|
backgroundColor: isFromSelf
|
||||||
? isPending
|
? isPending
|
||||||
? pendingColor
|
? pendingColor
|
||||||
|
|||||||
@@ -6,22 +6,21 @@ import {atoms as a, native, useTheme, web} from '#/alf'
|
|||||||
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
|
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
|
||||||
import {MessageContextProvider} from './MessageContext'
|
import {MessageContextProvider} from './MessageContext'
|
||||||
|
|
||||||
const CLUSTERED_MESSAGE_GAP = 2
|
|
||||||
const BORDER_RADIUS = 20
|
const BORDER_RADIUS = 20
|
||||||
const SQUARED_BORDER_RADIUS = 4
|
const SQUARED_BORDER_RADIUS = 4
|
||||||
|
|
||||||
let MessageItemEmbed = ({
|
let MessageItemEmbed = ({
|
||||||
embed,
|
embed,
|
||||||
isFromSelf,
|
isFromSelf,
|
||||||
|
isGroupChat,
|
||||||
squaredTopCorner,
|
squaredTopCorner,
|
||||||
squaredBottomCorner,
|
squaredBottomCorner,
|
||||||
isFirstInCluster,
|
|
||||||
}: {
|
}: {
|
||||||
embed: $Typed<AppBskyEmbedRecord.View>
|
embed: $Typed<AppBskyEmbedRecord.View>
|
||||||
isFromSelf: boolean
|
isFromSelf: boolean
|
||||||
|
isGroupChat: boolean
|
||||||
squaredTopCorner: boolean
|
squaredTopCorner: boolean
|
||||||
squaredBottomCorner: boolean
|
squaredBottomCorner: boolean
|
||||||
isFirstInCluster: boolean
|
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const screen = useWindowDimensions()
|
const screen = useWindowDimensions()
|
||||||
@@ -30,18 +29,19 @@ let MessageItemEmbed = ({
|
|||||||
<MessageContextProvider>
|
<MessageContextProvider>
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
!isFromSelf && a.ml_sm,
|
!isFromSelf && isGroupChat && a.ml_sm,
|
||||||
native({
|
native({
|
||||||
flexBasis: 0,
|
flexBasis: 0,
|
||||||
width: Math.min(screen.width, 600) / 1.4,
|
width: Math.min(screen.width, 600) / 1.4,
|
||||||
}),
|
}),
|
||||||
web({
|
web({
|
||||||
|
width: '100%',
|
||||||
minWidth: 280,
|
minWidth: 280,
|
||||||
maxWidth: 360,
|
maxWidth: 360,
|
||||||
}),
|
}),
|
||||||
{
|
// Cancel out the embed's internal a.mt_sm so the container's
|
||||||
marginTop: isFirstInCluster ? 0 : CLUSTERED_MESSAGE_GAP,
|
// CLUSTERED_MESSAGE_GAP (2px) is the only spacing applied
|
||||||
},
|
{marginTop: -a.mt_sm.marginTop},
|
||||||
]}>
|
]}>
|
||||||
<View>
|
<View>
|
||||||
<Embed
|
<Embed
|
||||||
|
|||||||
Reference in New Issue
Block a user