From f2b900a2904d6ddca0c76fcf38e2a18cb05a2104 Mon Sep 17 00:00:00 2001 From: Daniela Henkel Date: Tue, 18 Nov 2025 03:18:54 +0100 Subject: [PATCH] redo expanding banner code, fix HQ images for pfp n banner --- src/screens/Profile/Header/Shell.tsx | 90 ++++++++++++++++++++++++---- src/view/com/util/UserBanner.tsx | 72 ++++------------------ 2 files changed, 89 insertions(+), 73 deletions(-) diff --git a/src/screens/Profile/Header/Shell.tsx b/src/screens/Profile/Header/Shell.tsx index 65f76b338..05f0d79fa 100644 --- a/src/screens/Profile/Header/Shell.tsx +++ b/src/screens/Profile/Header/Shell.tsx @@ -22,6 +22,10 @@ import {logger} from '#/logger' import {isIOS} from '#/platform/detection' import {type Shadow} from '#/state/cache/types' import {useLightboxControls} from '#/state/lightbox' +import { + maybeModifyHighQualityImage, + useHighQualityImages, +} from '#/state/preferences/high-quality-images' import {useSession} from '#/state/session' import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' import {UserAvatar} from '#/view/com/util/UserAvatar' @@ -61,8 +65,10 @@ let ProfileHeaderShell = ({ const {top: topInset} = useSafeAreaInsets() const playHaptic = useHaptics() const liveStatusControl = useDialogControl() + const highQualityImages = useHighQualityImages() const aviRef = useAnimatedRef() + const bannerRef = useAnimatedRef() const onPressBack = useCallback(() => { if (navigation.canGoBack()) { @@ -72,13 +78,13 @@ let ProfileHeaderShell = ({ } }, [navigation]) - const _openLightbox = useCallback( + const _openLightboxAvi = useCallback( (uri: string, thumbRect: MeasuredDimensions | null) => { openLightbox({ images: [ { - uri, - thumbUri: uri, + uri: maybeModifyHighQualityImage(uri, highQualityImages), + thumbUri: maybeModifyHighQualityImage(uri, highQualityImages), thumbRect, dimensions: { // It's fine if it's actually smaller but we know it's 1:1. @@ -92,7 +98,27 @@ let ProfileHeaderShell = ({ index: 0, }) }, - [openLightbox], + [openLightbox, highQualityImages], + ) + + // theres probs a better way instead of just making a separate one but this works:tm: so its whatever + const _openLightboxBanner = useCallback( + (uri: string, thumbRect: MeasuredDimensions | null) => { + openLightbox({ + images: [ + { + uri: maybeModifyHighQualityImage(uri, highQualityImages), + thumbUri: maybeModifyHighQualityImage(uri, highQualityImages), + thumbRect, + dimensions: thumbRect, + thumbDimensions: null, + type: 'image', + }, + ], + index: 0, + }) + }, + [openLightbox, highQualityImages], ) const isMe = useMemo( @@ -128,20 +154,50 @@ let ProfileHeaderShell = ({ runOnUI(() => { 'worklet' const rect = measure(aviRef) - runOnJS(_openLightbox)(avatar, rect) + runOnJS(_openLightboxAvi)(avatar, rect) })() } } }, [ profile, moderation, - _openLightbox, + _openLightboxAvi, aviRef, liveStatusControl, live, playHaptic, ]) + const onPressBanner = useCallback(() => { + if (live.isActive) { + playHaptic('Light') + logger.metric( + 'live:card:open', + {subject: profile.did, from: 'profile'}, + {statsig: true}, + ) + liveStatusControl.open() + } else { + const modui = moderation.ui('banner') + const banner = profile.banner + if (banner && !(modui.blur && modui.noOverride)) { + runOnUI(() => { + 'worklet' + const rect = measure(bannerRef) + runOnJS(_openLightboxBanner)(banner, rect) + })() + } + } + }, [ + profile, + moderation, + _openLightboxBanner, + bannerRef, + liveStatusControl, + live, + playHaptic, + ]) + return ( ) : ( - + + + + + {live.isActive && } + + + )} diff --git a/src/view/com/util/UserBanner.tsx b/src/view/com/util/UserBanner.tsx index c218be70c..8699c3e9d 100644 --- a/src/view/com/util/UserBanner.tsx +++ b/src/view/com/util/UserBanner.tsx @@ -1,17 +1,5 @@ import {useCallback, useState} from 'react' -import { - Pressable, - StyleSheet, - TouchableWithoutFeedback, - View, -} from 'react-native' -import { - measure, - type MeasuredDimensions, - runOnJS, - runOnUI, - useAnimatedRef, -} from 'react-native-reanimated' +import {Pressable, StyleSheet, View} from 'react-native' import {Image} from 'expo-image' import {type ModerationUI} from '@atproto/api' import {msg, Trans} from '@lingui/macro' @@ -31,7 +19,6 @@ import { compressImage, createComposerImage, } from '#/state/gallery' -import {useLightboxControls} from '#/state/lightbox' import { maybeModifyHighQualityImage, useHighQualityImages, @@ -67,11 +54,8 @@ export function UserBanner({ const sheetWrapper = useSheetWrapper() const [rawImage, setRawImage] = useState() const editImageDialogControl = useDialogControl() - const {openLightbox} = useLightboxControls() const highQualityImages = useHighQualityImages() - const bannerRef = useAnimatedRef() - const onOpenCamera = useCallback(async () => { if (!(await requestCameraAccessIfNeeded())) { return @@ -124,35 +108,6 @@ export function UserBanner({ onSelectNewBanner?.(null) }, [onSelectNewBanner]) - const _openLightbox = useCallback( - (uri: string, thumbRect: MeasuredDimensions | null) => { - openLightbox({ - images: [ - { - uri: maybeModifyHighQualityImage(uri, highQualityImages), - thumbUri: maybeModifyHighQualityImage(uri, highQualityImages), - thumbRect, - dimensions: thumbRect, - thumbDimensions: null, - type: 'image', - }, - ], - index: 0, - }) - }, - [openLightbox, highQualityImages], - ) - - const onPressBanner = useCallback(() => { - if (banner && !(moderation?.blur && moderation?.noOverride)) { - runOnUI(() => { - 'worklet' - const rect = measure(bannerRef) - runOnJS(_openLightbox)(banner, rect) - })() - } - }, [banner, moderation, _openLightbox, bannerRef]) - const onChangeEditImage = useCallback( async (image: ComposerImage) => { const compressed = await compressImage(image) @@ -261,22 +216,15 @@ export function UserBanner({ ) : banner && !((moderation?.blur && isAndroid) /* android crashes with blur */) ? ( - - - + ) : (