diff --git a/src/analytics/features/types.ts b/src/analytics/features/types.ts
index 36a354bb49..af046736cf 100644
--- a/src/analytics/features/types.ts
+++ b/src/analytics/features/types.ts
@@ -15,5 +15,6 @@ export enum Features {
DmsNewMessageComposerEnable = 'dms:new_message_composer:enable',
KlipyGifProviderEnable = 'klipy_gif_provider:enable',
PostGalleryEmbedEnable = 'post_gallery_embed:enable',
+ NotificationsExpandedProfileCardEnable = 'notifications:expanded_profile_card:enable',
AATest = 'aa-test',
}
diff --git a/src/view/com/notifications/NotificationFeedItem.tsx b/src/view/com/notifications/NotificationFeedItem.tsx
index 79a8d746e8..404cda3edb 100644
--- a/src/view/com/notifications/NotificationFeedItem.tsx
+++ b/src/view/com/notifications/NotificationFeedItem.tsx
@@ -2,6 +2,7 @@ import {memo, useCallback, useEffect, useMemo, useState} from 'react'
import {
Animated,
type GestureResponderEvent,
+ type LayoutChangeEvent,
Pressable,
StyleSheet,
TouchableOpacity,
@@ -63,11 +64,14 @@ import {VerifiedCheck} from '#/components/icons/VerifiedCheck'
import {InlineLinkText, Link} from '#/components/Link'
import * as MediaPreview from '#/components/MediaPreview'
import {ProfileBadges} from '#/components/ProfileBadges'
+import * as ProfileCard from '#/components/ProfileCard'
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
import {Notification as StarterPackCard} from '#/components/StarterPack/StarterPackCard'
import {SubtleHover} from '#/components/SubtleHover'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
+import {useAnalytics} from '#/analytics'
+import {IS_WEB} from '#/env'
import * as bsky from '#/types/bsky'
const MAX_AUTHORS = 5
@@ -616,7 +620,7 @@ let NotificationFeedItem = ({
}}>
{({hovered}) => (
<>
-
+
{/* TODO: Prevent conditional rendering and move toward composable
notifications for clearer accessibility labeling */}
@@ -635,6 +639,7 @@ let NotificationFeedItem = ({
{
+ Animated.timing(isNativeFade ? opacityInterp : heightInterp, {
+ toValue: visible ? 1 : 0,
+ duration: 200,
+ useNativeDriver: isNativeFade,
+ }).start()
+ }, [heightInterp, opacityInterp, visible, isNativeFade])
+ const onInnerLayout = (e: LayoutChangeEvent) => {
+ if (measuredHeight === 0) {
+ setMeasuredHeight(e.nativeEvent.layout.height)
+ }
+ }
+
+ if (isNativeFade) {
+ return (
+
+ {visible && (
+
+ {authors.map((author, i) => (
+
+ ))}
+
+ )}
+
+ )
+ }
+
+ const targetHeight = profileCardEnabled
+ ? measuredHeight
+ : authors.length * (EXPANDED_AUTHOR_EL_HEIGHT + 10) /*10=margin*/
const heightStyle = {
height: Animated.multiply(heightInterp, targetHeight),
}
- useEffect(() => {
- Animated.timing(heightInterp, {
- toValue: visible ? 1 : 0,
- duration: 200,
- useNativeDriver: false,
- }).start()
- }, [heightInterp, visible])
-
return (
- {visible &&
+ {profileCardEnabled ? (
+
+ {authors.map((author, i) => (
+
+ ))}
+
+ ) : (
+ visible &&
authors.map(author => (
- ))}
+ ))
+ )}
)
}
+function ExpandedAuthorProfileCard({
+ author,
+ moderationOpts,
+ isLast,
+}: {
+ author: Author
+ moderationOpts: ModerationOpts
+ isLast: boolean
+}) {
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
+
function ExpandedAuthorCard({author}: {author: Author}) {
const t = useTheme()
const {_} = useLingui()
return (