From db79c918b2e929c1317cbb91918eb00252fdc136 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 13 Mar 2024 12:06:03 -0700 Subject: [PATCH 1/8] 1.73 Version Bump (#3200) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6e17fcb02a..8962018208 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bsky.app", - "version": "1.72.0", + "version": "1.73.0", "private": true, "engines": { "node": ">=18" From 7eaa573b57c6fb3a37abe105d4a8de10e9b9f893 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 13 Mar 2024 22:31:51 +0000 Subject: [PATCH 2/8] [Statsig] Track likes, reposts, follows (#3195) * [Statsig] Track likes * Move tracking to intent * Track repost/unrepost * Track profile follows/unfollows * Less copy paste * Reorder --- src/lib/statsig/events.ts | 32 ++++++++++++- src/lib/statsig/statsig.tsx | 8 ++-- src/state/queries/post.ts | 47 ++++++++++++++----- src/state/queries/profile.ts | 17 +++++-- .../onboarding/RecommendedFollowsItem.tsx | 7 ++- .../com/post-thread/PostThreadFollowBtn.tsx | 5 +- src/view/com/post-thread/PostThreadItem.tsx | 2 + src/view/com/post/Post.tsx | 1 + src/view/com/posts/FeedItem.tsx | 1 + src/view/com/profile/FollowButton.tsx | 7 ++- src/view/com/profile/ProfileCard.tsx | 4 +- src/view/com/profile/ProfileHeader.tsx | 5 +- .../profile/ProfileHeaderSuggestedFollows.tsx | 5 +- src/view/com/profile/ProfileMenu.tsx | 5 +- src/view/com/util/post-ctrls/PostCtrls.tsx | 9 +++- 15 files changed, 125 insertions(+), 30 deletions(-) diff --git a/src/lib/statsig/events.ts b/src/lib/statsig/events.ts index bc647710ce..321a0f6816 100644 --- a/src/lib/statsig/events.ts +++ b/src/lib/statsig/events.ts @@ -1,5 +1,35 @@ -export type Events = { +export type LogEvents = { init: { initMs: number } + 'post:like': { + logContext: 'FeedItem' | 'PostThreadItem' | 'Post' + } + 'post:repost': { + logContext: 'FeedItem' | 'PostThreadItem' | 'Post' + } + 'post:unlike': { + logContext: 'FeedItem' | 'PostThreadItem' | 'Post' + } + 'post:unrepost': { + logContext: 'FeedItem' | 'PostThreadItem' | 'Post' + } + 'profile:follow': { + logContext: + | 'RecommendedFollowsItem' + | 'PostThreadItem' + | 'ProfileCard' + | 'ProfileHeader' + | 'ProfileHeaderSuggestedFollows' + | 'ProfileMenu' + } + 'profile:unfollow': { + logContext: + | 'RecommendedFollowsItem' + | 'PostThreadItem' + | 'ProfileCard' + | 'ProfileHeader' + | 'ProfileHeaderSuggestedFollows' + | 'ProfileMenu' + } } diff --git a/src/lib/statsig/statsig.tsx b/src/lib/statsig/statsig.tsx index a46cef4da0..5745d204ad 100644 --- a/src/lib/statsig/statsig.tsx +++ b/src/lib/statsig/statsig.tsx @@ -6,7 +6,9 @@ import { } from 'statsig-react-native-expo' import {useSession} from '../../state/session' import {sha256} from 'js-sha256' -import {Events} from './events' +import {LogEvents} from './events' + +export type {LogEvents} const statsigOptions = { environment: { @@ -31,9 +33,9 @@ export function attachRouteToLogEvents( getCurrentRouteName = getRouteName } -export function logEvent( +export function logEvent( eventName: E & string, - rawMetadata?: Events[E] & FlatJSONRecord, + rawMetadata: LogEvents[E] & FlatJSONRecord, ) { const fullMetadata = { ...rawMetadata, diff --git a/src/state/queries/post.ts b/src/state/queries/post.ts index eb59f7da40..e3682e304d 100644 --- a/src/state/queries/post.ts +++ b/src/state/queries/post.ts @@ -5,6 +5,7 @@ import {Shadow} from '#/state/cache/types' import {getAgent} from '#/state/session' import {updatePostShadow} from '#/state/cache/post-shadow' import {track} from '#/lib/analytics/analytics' +import {logEvent, LogEvents} from '#/lib/statsig/statsig' import {useToggleMutationQueue} from '#/lib/hooks/useToggleMutationQueue' export const RQKEY = (postUri: string) => ['post', postUri] @@ -58,12 +59,14 @@ export function useGetPost() { export function usePostLikeMutationQueue( post: Shadow, + logContext: LogEvents['post:like']['logContext'] & + LogEvents['post:unlike']['logContext'], ) { const postUri = post.uri const postCid = post.cid const initialLikeUri = post.viewer?.like - const likeMutation = usePostLikeMutation() - const unlikeMutation = usePostUnlikeMutation() + const likeMutation = usePostLikeMutation(logContext) + const unlikeMutation = usePostUnlikeMutation(logContext) const queueToggle = useToggleMutationQueue({ initialState: initialLikeUri, @@ -111,22 +114,30 @@ export function usePostLikeMutationQueue( return [queueLike, queueUnlike] } -function usePostLikeMutation() { +function usePostLikeMutation(logContext: LogEvents['post:like']['logContext']) { return useMutation< {uri: string}, // responds with the uri of the like Error, {uri: string; cid: string} // the post's uri and cid >({ - mutationFn: post => getAgent().like(post.uri, post.cid), + mutationFn: post => { + logEvent('post:like', {logContext}) + return getAgent().like(post.uri, post.cid) + }, onSuccess() { track('Post:Like') }, }) } -function usePostUnlikeMutation() { +function usePostUnlikeMutation( + logContext: LogEvents['post:unlike']['logContext'], +) { return useMutation({ - mutationFn: ({likeUri}) => getAgent().deleteLike(likeUri), + mutationFn: ({likeUri}) => { + logEvent('post:unlike', {logContext}) + return getAgent().deleteLike(likeUri) + }, onSuccess() { track('Post:Unlike') }, @@ -135,12 +146,14 @@ function usePostUnlikeMutation() { export function usePostRepostMutationQueue( post: Shadow, + logContext: LogEvents['post:repost']['logContext'] & + LogEvents['post:unrepost']['logContext'], ) { const postUri = post.uri const postCid = post.cid const initialRepostUri = post.viewer?.repost - const repostMutation = usePostRepostMutation() - const unrepostMutation = usePostUnrepostMutation() + const repostMutation = usePostRepostMutation(logContext) + const unrepostMutation = usePostUnrepostMutation(logContext) const queueToggle = useToggleMutationQueue({ initialState: initialRepostUri, @@ -188,22 +201,32 @@ export function usePostRepostMutationQueue( return [queueRepost, queueUnrepost] } -function usePostRepostMutation() { +function usePostRepostMutation( + logContext: LogEvents['post:repost']['logContext'], +) { return useMutation< {uri: string}, // responds with the uri of the repost Error, {uri: string; cid: string} // the post's uri and cid >({ - mutationFn: post => getAgent().repost(post.uri, post.cid), + mutationFn: post => { + logEvent('post:repost', {logContext}) + return getAgent().repost(post.uri, post.cid) + }, onSuccess() { track('Post:Repost') }, }) } -function usePostUnrepostMutation() { +function usePostUnrepostMutation( + logContext: LogEvents['post:unrepost']['logContext'], +) { return useMutation({ - mutationFn: ({repostUri}) => getAgent().deleteRepost(repostUri), + mutationFn: ({repostUri}) => { + logEvent('post:unrepost', {logContext}) + return getAgent().deleteRepost(repostUri) + }, onSuccess() { track('Post:Unrepost') }, diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts index e81ea0f3f0..3c9e3e41c3 100644 --- a/src/state/queries/profile.ts +++ b/src/state/queries/profile.ts @@ -26,6 +26,7 @@ import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts' import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts' import {STALE} from '#/state/queries' import {track} from '#/lib/analytics/analytics' +import {logEvent, LogEvents} from '#/lib/statsig/statsig' import {ThreadNode} from './post-thread' export const RQKEY = (did: string) => ['profile', did] @@ -186,11 +187,13 @@ export function useProfileUpdateMutation() { export function useProfileFollowMutationQueue( profile: Shadow, + logContext: LogEvents['profile:follow']['logContext'] & + LogEvents['profile:unfollow']['logContext'], ) { const did = profile.did const initialFollowingUri = profile.viewer?.following - const followMutation = useProfileFollowMutation() - const unfollowMutation = useProfileUnfollowMutation() + const followMutation = useProfileFollowMutation(logContext) + const unfollowMutation = useProfileUnfollowMutation(logContext) const queueToggle = useToggleMutationQueue({ initialState: initialFollowingUri, @@ -237,9 +240,12 @@ export function useProfileFollowMutationQueue( return [queueFollow, queueUnfollow] } -function useProfileFollowMutation() { +function useProfileFollowMutation( + logContext: LogEvents['profile:follow']['logContext'], +) { return useMutation<{uri: string; cid: string}, Error, {did: string}>({ mutationFn: async ({did}) => { + logEvent('profile:follow', {logContext}) return await getAgent().follow(did) }, onSuccess(data, variables) { @@ -248,9 +254,12 @@ function useProfileFollowMutation() { }) } -function useProfileUnfollowMutation() { +function useProfileUnfollowMutation( + logContext: LogEvents['profile:unfollow']['logContext'], +) { return useMutation({ mutationFn: async ({followUri}) => { + logEvent('profile:unfollow', {logContext}) track('Profile:Unfollow', {username: followUri}) return await getAgent().deleteFollow(followUri) }, diff --git a/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx b/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx index 07001068cc..5f81a4d657 100644 --- a/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx +++ b/src/view/com/auth/onboarding/RecommendedFollowsItem.tsx @@ -56,7 +56,7 @@ export function RecommendedFollowsItem({ ) } -export function ProfileCard({ +function ProfileCard({ profile, onFollowStateChange, moderation, @@ -72,7 +72,10 @@ export function ProfileCard({ const pal = usePalette('default') const [addingMoreSuggestions, setAddingMoreSuggestions] = React.useState(false) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'RecommendedFollowsItem', + ) const onToggleFollow = React.useCallback(async () => { try { diff --git a/src/view/com/post-thread/PostThreadFollowBtn.tsx b/src/view/com/post-thread/PostThreadFollowBtn.tsx index e5b747cc9a..45c3771f50 100644 --- a/src/view/com/post-thread/PostThreadFollowBtn.tsx +++ b/src/view/com/post-thread/PostThreadFollowBtn.tsx @@ -42,7 +42,10 @@ function PostThreadFollowBtnLoaded({ const {isTabletOrDesktop} = useWebMediaQueries() const profile: Shadow = useProfileShadow(profileUnshadowed) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'PostThreadItem', + ) const requireAuth = useRequireAuth() const isFollowing = !!profile.viewer?.following diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 9522ea6a07..7efd535f2b 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -407,6 +407,7 @@ let PostThreadItemLoaded = ({ record={record} richText={richText} onPressReply={onPressReply} + logContext="PostThreadItem" /> @@ -560,6 +561,7 @@ let PostThreadItemLoaded = ({ record={record} richText={richText} onPressReply={onPressReply} + logContext="PostThreadItem" /> diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index 5fa4da84e1..0fe3420ba7 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -220,6 +220,7 @@ function PostInner({ record={record} richText={richText} onPressReply={onPressReply} + logContext="Post" /> diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 7d29703e2d..4b78dce7a1 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -310,6 +310,7 @@ let FeedItemInner = ({ showAppealLabelItem={ post.author.did === currentAccount?.did && isModeratedPost } + logContext="FeedItem" /> diff --git a/src/view/com/profile/FollowButton.tsx b/src/view/com/profile/FollowButton.tsx index 9cc635b664..7b090ffeb0 100644 --- a/src/view/com/profile/FollowButton.tsx +++ b/src/view/com/profile/FollowButton.tsx @@ -13,13 +13,18 @@ export function FollowButton({ followedType = 'default', profile, labelStyle, + logContext, }: { unfollowedType?: ButtonType followedType?: ButtonType profile: Shadow labelStyle?: StyleProp + logContext: 'ProfileCard' }) { - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + logContext, + ) const {_} = useLingui() const onPressFollow = async () => { diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx index 266adc51de..019e6c10e7 100644 --- a/src/view/com/profile/ProfileCard.tsx +++ b/src/view/com/profile/ProfileCard.tsx @@ -230,7 +230,9 @@ export function ProfileCardWithFollowBtn({ renderButton={ isMe ? undefined - : profileShadow => + : profileShadow => ( + + ) } /> ) diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx index 75e06eb9b7..17dc5ce1bd 100644 --- a/src/view/com/profile/ProfileHeader.tsx +++ b/src/view/com/profile/ProfileHeader.tsx @@ -103,7 +103,10 @@ let ProfileHeader = ({ const invalidHandle = isInvalidHandle(profile.handle) const {isDesktop} = useWebMediaQueries() const [showSuggestedFollows, setShowSuggestedFollows] = React.useState(false) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'ProfileHeader', + ) const [__, queueUnblock] = useProfileBlockMutationQueue(profile) const unblockPromptControl = Prompt.usePromptControl() const moderation = useMemo( diff --git a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx index 6edc61fcf8..8f2c894994 100644 --- a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx +++ b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx @@ -170,7 +170,10 @@ function SuggestedFollow({ const pal = usePalette('default') const moderationOpts = useModerationOpts() const profile = useProfileShadow(profileUnshadowed) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'ProfileHeaderSuggestedFollows', + ) const onPressFollow = React.useCallback(async () => { try { diff --git a/src/view/com/profile/ProfileMenu.tsx b/src/view/com/profile/ProfileMenu.tsx index 4153b819ea..7c6db1ed82 100644 --- a/src/view/com/profile/ProfileMenu.tsx +++ b/src/view/com/profile/ProfileMenu.tsx @@ -52,7 +52,10 @@ let ProfileMenu = ({ const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile) const [queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) - const [, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'ProfileMenu', + ) const blockPromptControl = Prompt.usePromptControl() diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index 1e26eeccee..c96954a114 100644 --- a/src/view/com/util/post-ctrls/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -44,6 +44,7 @@ let PostCtrls = ({ showAppealLabelItem, style, onPressReply, + logContext, }: { big?: boolean post: Shadow @@ -52,13 +53,17 @@ let PostCtrls = ({ showAppealLabelItem?: boolean style?: StyleProp onPressReply: () => void + logContext: 'FeedItem' | 'PostThreadItem' | 'Post' }): React.ReactNode => { const theme = useTheme() const {_} = useLingui() const {openComposer} = useComposerControls() const {closeModal} = useModalControls() - const [queueLike, queueUnlike] = usePostLikeMutationQueue(post) - const [queueRepost, queueUnrepost] = usePostRepostMutationQueue(post) + const [queueLike, queueUnlike] = usePostLikeMutationQueue(post, logContext) + const [queueRepost, queueUnrepost] = usePostRepostMutationQueue( + post, + logContext, + ) const requireAuth = useRequireAuth() const defaultCtrlColor = React.useMemo( From 1c25c76645564c4581530ec604b7862bb3b8fdda Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 14 Mar 2024 00:21:42 +0000 Subject: [PATCH 3/8] [Statsig] Track posting, end reached (#3206) * Track post create * Track feed endReached --- src/lib/statsig/events.ts | 12 ++++++++++++ src/view/com/composer/Composer.tsx | 11 +++++++++++ src/view/com/posts/Feed.tsx | 16 +++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/lib/statsig/events.ts b/src/lib/statsig/events.ts index 321a0f6816..fa7e597fbc 100644 --- a/src/lib/statsig/events.ts +++ b/src/lib/statsig/events.ts @@ -2,6 +2,18 @@ export type LogEvents = { init: { initMs: number } + 'feed:endReached': { + feedType: string + itemCount: number + } + 'post:create': { + imageCount: number + isReply: boolean + hasLink: boolean + hasQuote: boolean + langs: string + logContext: 'Composer' + } 'post:like': { logContext: 'FeedItem' | 'PostThreadItem' | 'Post' } diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index ef965b271d..97f8e51940 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -65,6 +65,7 @@ import {logger} from '#/logger' import {ComposerReplyTo} from 'view/com/composer/ComposerReplyTo' import * as Prompt from '#/components/Prompt' import {useDialogStateControlContext} from 'state/dialogs' +import {logEvent} from '#/lib/statsig/statsig' type Props = ComposerOpts export const ComposePost = observer(function ComposePost({ @@ -255,6 +256,16 @@ export const ComposePost = observer(function ComposePost({ setIsProcessing(false) return } finally { + if (postUri) { + logEvent('post:create', { + imageCount: gallery.size, + isReply: replyTo != null, + hasLink: extLink != null, + hasQuote: quote != null, + langs: langPrefs.postLanguage, + logContext: 'Composer', + }) + } track('Create Post', { imageCount: gallery.size, }) diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx index cd3e98785d..b86646a4dc 100644 --- a/src/view/com/posts/Feed.tsx +++ b/src/view/com/posts/Feed.tsx @@ -33,6 +33,7 @@ import {useLingui} from '@lingui/react' import {DiscoverFallbackHeader} from './DiscoverFallbackHeader' import {FALLBACK_MARKER_POST} from '#/lib/api/feed/home' import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' +import {logEvent} from '#/lib/statsig/statsig' const LOADING_ITEM = {_reactKey: '__loading__'} const EMPTY_FEED_ITEM = {_reactKey: '__empty__'} @@ -223,16 +224,29 @@ let Feed = ({ setIsPTRing(false) }, [refetch, track, setIsPTRing, onHasNew]) + const feedType = feed.split('|')[0] const onEndReached = React.useCallback(async () => { if (isFetching || !hasNextPage || isError) return + logEvent('feed:endReached', { + feedType: feedType, + itemCount: feedItems.length, + }) track('Feed:onEndReached') try { await fetchNextPage() } catch (err) { logger.error('Failed to load more posts', {message: err}) } - }, [isFetching, hasNextPage, isError, fetchNextPage, track]) + }, [ + isFetching, + hasNextPage, + isError, + fetchNextPage, + track, + feedType, + feedItems.length, + ]) const onPressTryAgain = React.useCallback(() => { refetch() From 7bdaa624b708b11e4c7f711a4de632c1b0daca90 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 13 Mar 2024 18:13:36 +0000 Subject: [PATCH 4/8] use prompt.basic instead of full prompt --- src/view/com/util/forms/PostDropdownBtn.tsx | 30 +++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx index 84a047c406..8fc3d9ea62 100644 --- a/src/view/com/util/forms/PostDropdownBtn.tsx +++ b/src/view/com/util/forms/PostDropdownBtn.tsx @@ -85,11 +85,13 @@ let PostDropdownBtn = ({ const {mutedWordsDialogControl} = useGlobalDialogsControlContext() const deletePromptControl = useDialogControl() const hidePromptControl = useDialogControl() + const loggedOutWarningPromptControl = useDialogControl() const rootUri = record.reply?.root?.uri || postUri const isThreadMuted = mutedThreads.includes(rootUri) const isPostHidden = hiddenPosts && hiddenPosts.includes(postUri) const isAuthor = postAuthor.did === currentAccount?.did + const href = React.useMemo(() => { const urip = new AtUri(postUri) return makeProfileLink(postAuthor, 'post', urip.rkey) @@ -167,6 +169,17 @@ let PostDropdownBtn = ({ hidePost({uri: postUri}) }, [postUri, hidePost]) + const shouldShowLoggedOutWarning = React.useMemo(() => { + return !!postAuthor.labels?.find( + label => label.val === '!no-unauthenticated', + ) + }, [postAuthor]) + + const onSharePost = React.useCallback(() => { + const url = toShareUrl(href) + shareUrl(url) + }, [href]) + return ( @@ -217,8 +230,11 @@ let PostDropdownBtn = ({ testID="postDropdownShareBtn" label={isWeb ? _(msg`Copy link to post`) : _(msg`Share`)} onPress={() => { - const url = toShareUrl(href) - shareUrl(url) + if (shouldShowLoggedOutWarning) { + loggedOutWarningPromptControl.open() + } else { + onSharePost() + } }}> {isWeb ? _(msg`Copy link to post`) : _(msg`Share`)} @@ -342,6 +358,16 @@ let PostDropdownBtn = ({ onConfirm={onHidePost} confirmButtonCta={_(msg`Hide`)} /> + + ) } From 78a836d2b1ec2ba53bd1cf6c19846c61eb240065 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 13 Mar 2024 18:18:23 +0000 Subject: [PATCH 5/8] add warning to profile as well --- src/view/com/profile/ProfileMenu.tsx | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/view/com/profile/ProfileMenu.tsx b/src/view/com/profile/ProfileMenu.tsx index 7c6db1ed82..0baa4f3945 100644 --- a/src/view/com/profile/ProfileMenu.tsx +++ b/src/view/com/profile/ProfileMenu.tsx @@ -58,6 +58,11 @@ let ProfileMenu = ({ ) const blockPromptControl = Prompt.usePromptControl() + const loggedOutWarningPromptControl = Prompt.usePromptControl() + + const showLoggedOutWarning = React.useMemo(() => { + return !!profile.labels?.find(label => label.val === '!no-unauthenticated') + }, [profile.labels]) const invalidateProfileQuery = React.useCallback(() => { queryClient.invalidateQueries({ @@ -192,7 +197,13 @@ let ProfileMenu = ({ + onPress={() => { + if (showLoggedOutWarning) { + loggedOutWarningPromptControl.open() + } else { + onPressShare() + } + }}> Share @@ -310,6 +321,16 @@ let ProfileMenu = ({ } confirmButtonColor={profile.viewer?.blocking ? undefined : 'negative'} /> + + ) } From 67edca4fbb47635fdbdcecab1d7f34ea33991178 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 14 Mar 2024 14:48:52 -0500 Subject: [PATCH 6/8] Mute 'account' not 'user' --- src/components/moderation/ModerationDetailsDialog.tsx | 2 +- src/lib/moderation/useModerationCauseDescription.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/moderation/ModerationDetailsDialog.tsx b/src/components/moderation/ModerationDetailsDialog.tsx index 7320bfb223..42bc6da0df 100644 --- a/src/components/moderation/ModerationDetailsDialog.tsx +++ b/src/components/moderation/ModerationDetailsDialog.tsx @@ -92,7 +92,7 @@ function ModerationDetailsDialogInner({ ) } else { name = _(msg`Account Muted`) - description = _(msg`You have muted this user.`) + description = _(msg`You have muted this account.`) } } else if (modcause.type === 'mute-word') { name = _(msg`Post Hidden by Muted Word`) diff --git a/src/lib/moderation/useModerationCauseDescription.ts b/src/lib/moderation/useModerationCauseDescription.ts index 10c2b4ed28..05757e0257 100644 --- a/src/lib/moderation/useModerationCauseDescription.ts +++ b/src/lib/moderation/useModerationCauseDescription.ts @@ -81,8 +81,8 @@ export function useModerationCauseDescription( } else { return { icon: EyeSlash, - name: _(msg`Muted User`), - description: _(msg`You have muted this user`), + name: _(msg`Account Muted`), + description: _(msg`You have muted this account.`), } } } From 4e525cd44f30114565504b43a19718504efaff27 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 14 Mar 2024 14:51:45 -0500 Subject: [PATCH 7/8] Show metrics if self --- src/screens/Profile/Header/ProfileHeaderLabeler.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/screens/Profile/Header/ProfileHeaderLabeler.tsx b/src/screens/Profile/Header/ProfileHeaderLabeler.tsx index b7f89ab369..0eeedc66d4 100644 --- a/src/screens/Profile/Header/ProfileHeaderLabeler.tsx +++ b/src/screens/Profile/Header/ProfileHeaderLabeler.tsx @@ -32,6 +32,7 @@ import {ProfileHeaderShell} from './Shell' import {ProfileMenu} from '#/view/com/profile/ProfileMenu' import {ProfileHeaderDisplayName} from './DisplayName' import {ProfileHeaderHandle} from './Handle' +import {ProfileHeaderMetrics} from './Metrics' import { Heart2_Stroke2_Corner0_Rounded as Heart, Heart2_Filled_Stroke2_Corner0_Rounded as HeartFilled, @@ -65,6 +66,7 @@ let ProfileHeaderLabeler = ({ const {openModal} = useModalControls() const {track} = useAnalytics() const cantSubscribePrompt = Prompt.usePromptControl() + const isSelf = currentAccount?.did === profile.did const moderation = useMemo( () => moderateProfile(profile, moderationOpts), @@ -207,6 +209,7 @@ let ProfileHeaderLabeler = ({ {!isPlaceholderProfile && ( <> + {isSelf && } {descriptionRT && !moderation.ui('profileView').blur ? ( Date: Thu, 14 Mar 2024 15:06:55 -0500 Subject: [PATCH 8/8] Fix bad merge --- src/screens/Profile/Header/ProfileHeaderStandard.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/screens/Profile/Header/ProfileHeaderStandard.tsx b/src/screens/Profile/Header/ProfileHeaderStandard.tsx index 8b79ac6baf..8b90382441 100644 --- a/src/screens/Profile/Header/ProfileHeaderStandard.tsx +++ b/src/screens/Profile/Header/ProfileHeaderStandard.tsx @@ -63,7 +63,10 @@ let ProfileHeaderStandard = ({ [profile, moderationOpts], ) const [showSuggestedFollows, setShowSuggestedFollows] = React.useState(false) - const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue(profile) + const [queueFollow, queueUnfollow] = useProfileFollowMutationQueue( + profile, + 'ProfileHeader', + ) const [_queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) const unblockPromptControl = Prompt.usePromptControl() const requireAuth = useRequireAuth()