fix layout shifting in notifs

This commit is contained in:
Samuel Newman
2025-06-27 12:02:16 +03:00
parent f5f34979af
commit 8bddafc492
4 changed files with 34 additions and 58 deletions
+26 -34
View File
@@ -2,7 +2,6 @@ import {
Linking, Linking,
Pressable, Pressable,
type StyleProp, type StyleProp,
StyleSheet,
View, View,
type ViewStyle, type ViewStyle,
} from 'react-native' } from 'react-native'
@@ -15,9 +14,7 @@ import {
import {Plural, Trans} from '@lingui/macro' import {Plural, Trans} from '@lingui/macro'
import {useNavigationDeduped} from '#/lib/hooks/useNavigationDeduped' import {useNavigationDeduped} from '#/lib/hooks/useNavigationDeduped'
import {usePalette} from '#/lib/hooks/usePalette'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
import {s} from '#/lib/styles'
import { import {
type FeedSourceInfo, type FeedSourceInfo,
hydrateFeedGenerator, hydrateFeedGenerator,
@@ -25,11 +22,11 @@ import {
useFeedSourceInfoQuery, useFeedSourceInfoQuery,
} from '#/state/queries/feed' } from '#/state/queries/feed'
import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
import {Text} from '#/view/com/util/text/Text'
import {UserAvatar} from '#/view/com/util/UserAvatar' import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {shouldClickOpenNewTab} from '#/components/Link' import {shouldClickOpenNewTab} from '#/components/Link'
import {RichText} from '#/components/RichText' import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography'
type FeedSourceCardProps = { type FeedSourceCardProps = {
feedUri: string feedUri: string
@@ -90,8 +87,6 @@ export function FeedSourceCardLoaded({
hideTopBorder?: boolean hideTopBorder?: boolean
}) { }) {
const t = useTheme() const t = useTheme()
const pal = usePalette('default')
const navigation = useNavigationDeduped() const navigation = useNavigationDeduped()
/* /*
@@ -102,30 +97,16 @@ export function FeedSourceCardLoaded({
*/ */
if (!feed) if (!feed)
return ( return (
<View <FeedLoadingPlaceholder
style={[ style={[
pal.border, t.atoms.border_contrast_low,
{ !(showMinimalPlaceholder || hideTopBorder) && a.border_t,
borderTopWidth: a.flex_1,
showMinimalPlaceholder || hideTopBorder style,
? 0 ]}
: StyleSheet.hairlineWidth, showTopBorder={false}
flexDirection: 'row', showLowerPlaceholder={!showMinimalPlaceholder}
alignItems: 'center', />
flex: 1,
paddingRight: 18,
},
]}>
{showMinimalPlaceholder ? (
<FeedLoadingPlaceholder
style={[a.flex_1]}
showTopBorder={false}
showLowerPlaceholder={false}
/>
) : (
<FeedLoadingPlaceholder style={[a.flex_1]} showTopBorder={false} />
)}
</View>
) )
return ( return (
@@ -168,14 +149,19 @@ export function FeedSourceCardLoaded({
}} }}
key={feed.uri}> key={feed.uri}>
<View style={[a.flex_row, a.align_center]}> <View style={[a.flex_row, a.align_center]}>
<View style={[s.mr10]}> <View style={[a.mr_md]}>
<UserAvatar type="algo" size={36} avatar={feed.avatar} /> <UserAvatar type="algo" size={36} avatar={feed.avatar} />
</View> </View>
<View style={[a.flex_1, a.gap_2xs]}> <View style={[a.flex_1, a.gap_xs]}>
<Text emoji style={[pal.text, s.bold]} numberOfLines={1}> <Text
emoji
style={[a.text_md, a.font_bold, a.leading_tight]}
numberOfLines={1}>
{feed.displayName} {feed.displayName}
</Text> </Text>
<Text type="sm" style={[pal.textLight]} numberOfLines={1}> <Text
style={[a.text_sm, t.atoms.text_contrast_medium, a.leading_tight]}
numberOfLines={1}>
{feed.type === 'feed' ? ( {feed.type === 'feed' ? (
<Trans>Feed by {sanitizeHandle(feed.creatorHandle, '@')}</Trans> <Trans>Feed by {sanitizeHandle(feed.creatorHandle, '@')}</Trans>
) : ( ) : (
@@ -194,7 +180,13 @@ export function FeedSourceCardLoaded({
) : null} ) : null}
{showLikes && feed.type === 'feed' ? ( {showLikes && feed.type === 'feed' ? (
<Text type="sm-medium" style={[pal.text, pal.textLight]}> <Text
style={[
a.text_sm,
a.font_bold,
t.atoms.text_contrast_medium,
a.leading_tight,
]}>
<Trans> <Trans>
Liked by{' '} Liked by{' '}
<Plural value={feed.likeCount || 0} one="# user" other="# users" /> <Plural value={feed.likeCount || 0} one="# user" other="# users" />
@@ -675,6 +675,7 @@ let NotificationFeedItem = ({
t.atoms.bg, t.atoms.bg,
t.atoms.border_contrast_low, t.atoms.border_contrast_low,
a.border, a.border,
a.p_md,
styles.feedcard, styles.feedcard,
]} ]}
showLikes showLikes
@@ -1000,7 +1001,6 @@ const styles = StyleSheet.create({
}, },
feedcard: { feedcard: {
borderRadius: 8, borderRadius: 8,
paddingVertical: 12,
marginTop: 6, marginTop: 6,
}, },
addedContainer: { addedContainer: {
+3 -9
View File
@@ -233,8 +233,7 @@ export function FeedLoadingPlaceholder({
<View <View
style={[ style={[
{ {
paddingHorizontal: 16, padding: 16,
paddingVertical: 16,
borderTopWidth: showTopBorder ? StyleSheet.hairlineWidth : 0, borderTopWidth: showTopBorder ? StyleSheet.hairlineWidth : 0,
}, },
pal.border, pal.border,
@@ -252,12 +251,7 @@ export function FeedLoadingPlaceholder({
</View> </View>
</View> </View>
{showLowerPlaceholder && ( {showLowerPlaceholder && (
<View style={{paddingHorizontal: 5, marginTop: 10}}> <View style={{marginTop: 12}}>
<LoadingPlaceholder
width={260}
height={8}
style={{marginVertical: 12}}
/>
<LoadingPlaceholder width={120} height={8} /> <LoadingPlaceholder width={120} height={8} />
</View> </View>
)} )}
@@ -352,7 +346,7 @@ const styles = StyleSheet.create({
}, },
avatar: { avatar: {
borderRadius: 999, borderRadius: 999,
marginRight: 10, marginRight: 12,
}, },
notification: { notification: {
flexDirection: 'row', flexDirection: 'row',
+4 -14
View File
@@ -296,7 +296,7 @@ function ListItem({
<FeedSourceCard <FeedSourceCard
key={feedUri} key={feedUri}
feedUri={feedUri} feedUri={feedUri}
style={[isPinned && {paddingRight: 8}]} style={[isPinned && a.pr_sm]}
showMinimalPlaceholder showMinimalPlaceholder
hideTopBorder={true} hideTopBorder={true}
/> />
@@ -391,26 +391,17 @@ function ListItem({
function FollowingFeedCard() { function FollowingFeedCard() {
const t = useTheme() const t = useTheme()
return ( return (
<View <View style={[a.flex_row, a.align_center, a.flex_1, a.p_lg]}>
style={[
a.flex_row,
a.align_center,
a.flex_1,
{
paddingHorizontal: 16,
paddingVertical: 16,
},
]}>
<View <View
style={[ style={[
a.align_center, a.align_center,
a.justify_center, a.justify_center,
a.rounded_sm, a.rounded_sm,
a.mr_md,
{ {
width: 36, width: 36,
height: 36, height: 36,
backgroundColor: t.palette.primary_500, backgroundColor: t.palette.primary_500,
marginRight: 10,
}, },
]}> ]}>
<FilterTimeline <FilterTimeline
@@ -423,8 +414,7 @@ function FollowingFeedCard() {
fill={t.palette.white} fill={t.palette.white}
/> />
</View> </View>
<View <View style={[a.flex_1, a.flex_row, a.gap_sm, a.align_center]}>
style={{flex: 1, flexDirection: 'row', gap: 8, alignItems: 'center'}}>
<Text type="lg-medium" style={[t.atoms.text]} numberOfLines={1}> <Text type="lg-medium" style={[t.atoms.text]} numberOfLines={1}>
<Trans>Following</Trans> <Trans>Following</Trans>
</Text> </Text>