Bluesky app fork with some witchin' additions 💫

Remove LiveIndicator from banner & make avatar lightbox accessible for live accounts

Open profile is replaced with View avatar when you're on a profile of a live user. (Could probably remove the rest of the lightbox TouchableWithoutFeedback element here in favor of Bluesky's official implementation upstream and just above on line :205?)

xan.lol 50bb9174 6982eb4f

verified
+50 -12
+38 -9
src/components/live/LiveStatusDialog.tsx
··· 32 32 profile, 33 33 embed, 34 34 status, 35 + onPressViewAvatar, 35 36 }: { 36 37 control: Dialog.DialogControlProps 37 38 profile: bsky.profile.AnyProfileView 38 39 status: AppBskyActorDefs.StatusView 39 40 embed: AppBskyEmbedExternal.View 41 + onPressViewAvatar?: () => void 40 42 }) { 41 43 const navigation = useNavigation<NavigationProp>() 42 44 return ( ··· 47 49 profile={profile} 48 50 embed={embed} 49 51 navigation={navigation} 52 + onPressViewAvatar={onPressViewAvatar} 50 53 /> 51 54 </Dialog.Outer> 52 55 ) ··· 57 60 embed, 58 61 navigation, 59 62 status, 63 + onPressViewAvatar, 60 64 }: { 61 65 profile: bsky.profile.AnyProfileView 62 66 embed: AppBskyEmbedExternal.View 63 67 navigation: NavigationProp 64 68 status: AppBskyActorDefs.StatusView 69 + onPressViewAvatar?: () => void 65 70 }) { 66 71 const {_} = useLingui() 67 72 const control = Dialog.useDialogContext() ··· 74 79 }) 75 80 }, [navigation, profile.handle, control]) 76 81 82 + const handlePressViewAvatar = useCallback(() => { 83 + if (onPressViewAvatar) { 84 + control.close(onPressViewAvatar) 85 + } 86 + }, [control, onPressViewAvatar]) 87 + 77 88 return ( 78 89 <Dialog.ScrollableInner 79 90 label={_(msg`${sanitizeHandle(profile.handle)} is live`)} ··· 84 95 profile={profile} 85 96 embed={embed} 86 97 onPressOpenProfile={onPressOpenProfile} 98 + onPressViewAvatar={handlePressViewAvatar} 87 99 /> 88 100 <Dialog.Close /> 89 101 </Dialog.ScrollableInner> ··· 96 108 embed, 97 109 padding = 'xl', 98 110 onPressOpenProfile, 111 + onPressViewAvatar, 99 112 }: { 100 113 status: AppBskyActorDefs.StatusView 101 114 profile: bsky.profile.AnyProfileView 102 115 embed: AppBskyEmbedExternal.View 103 116 padding?: 'lg' | 'xl' 104 117 onPressOpenProfile: () => void 118 + onPressViewAvatar?: () => void 105 119 }) { 106 120 const {_} = useLingui() 107 121 const t = useTheme() ··· 202 216 /> 203 217 </View> 204 218 <Button 205 - label={_(msg`Open profile`)} 219 + label={ 220 + onPressViewAvatar ? _(msg`View avatar`) : _(msg`Open profile`) 221 + } 206 222 size="small" 207 223 color="secondary" 208 224 variant="solid" 209 225 onPress={() => { 210 - logger.metric( 211 - 'live:card:openProfile', 212 - {subject: profile.did}, 213 - {statsig: true}, 214 - ) 215 - unstableCacheProfileView(queryClient, profile) 216 - onPressOpenProfile() 226 + if (onPressViewAvatar) { 227 + logger.metric( 228 + 'live:card:viewAvatar', 229 + {subject: profile.did}, 230 + {statsig: true}, 231 + ) 232 + onPressViewAvatar() 233 + } else { 234 + logger.metric( 235 + 'live:card:openProfile', 236 + {subject: profile.did}, 237 + {statsig: true}, 238 + ) 239 + unstableCacheProfileView(queryClient, profile) 240 + onPressOpenProfile() 241 + } 217 242 }}> 218 243 <ButtonText> 219 - <Trans>Open profile</Trans> 244 + {onPressViewAvatar ? ( 245 + <Trans>View avatar</Trans> 246 + ) : ( 247 + <Trans>Open profile</Trans> 248 + )} 220 249 </ButtonText> 221 250 </Button> 222 251 </ProfileCard.Header>
+1 -2
src/logger/metrics.ts
··· 374 374 | 'AvatarButton' 375 375 | 'StarterPackProfilesList' 376 376 | 'FeedInterstitial' 377 - | 'ProfileHeaderSuggestedFollows' 378 377 | 'PostOnboardingFindFollows' 379 378 | 'ImmersiveVideo' 380 379 | 'ExploreSuggestedAccounts' ··· 468 467 | 'AvatarButton' 469 468 | 'StarterPackProfilesList' 470 469 | 'FeedInterstitial' 471 - | 'ProfileHeaderSuggestedFollows' 472 470 | 'PostOnboardingFindFollows' 473 471 | 'ImmersiveVideo' 474 472 | 'ExploreSuggestedAccounts' ··· 632 630 'live:card:open': {subject: string; from: 'post' | 'profile'} 633 631 'live:card:watch': {subject: string} 634 632 'live:card:openProfile': {subject: string} 633 + 'live:card:viewAvatar': {subject: string} 635 634 'live:view:profile': {subject: string} 636 635 'live:view:post': {subject: string; feed?: string} 637 636
+11 -1
src/screens/Profile/Header/Shell.tsx
··· 266 266 banner={profile.banner} 267 267 moderation={moderation.ui('banner')} 268 268 /> 269 - {live.isActive && <LiveIndicator size="large" />} 270 269 </Animated.View> 271 270 </View> 272 271 </TouchableWithoutFeedback> ··· 348 347 status={live} 349 348 embed={live.embed} 350 349 profile={profile} 350 + onPressViewAvatar={() => { 351 + const modui = moderation.ui('avatar') 352 + const avatar = profile.avatar 353 + if (avatar && !(modui.blur && modui.noOverride)) { 354 + runOnUI(() => { 355 + 'worklet' 356 + const rect = measure(aviRef) 357 + runOnJS(_openLightbox)(avatar, rect) 358 + })() 359 + } 360 + }} 351 361 /> 352 362 ))} 353 363 </View>