diff options
-rw-r--r-- | package.json | 4 | ||||
-rw-r--r-- | src/lib/api/feed-manip.ts | 8 | ||||
-rw-r--r-- | src/screens/Search/Explore.tsx | 1 | ||||
-rw-r--r-- | src/screens/VideoFeed/index.tsx | 16 | ||||
-rw-r--r-- | src/state/feed-feedback.tsx | 18 | ||||
-rw-r--r-- | src/state/queries/explore-feed-previews.tsx | 1 | ||||
-rw-r--r-- | src/state/queries/post-feed.ts | 3 | ||||
-rw-r--r-- | src/view/com/posts/PostFeed.tsx | 20 | ||||
-rw-r--r-- | src/view/com/posts/PostFeedItem.tsx | 30 | ||||
-rw-r--r-- | src/view/com/util/forms/PostDropdownBtn.tsx | 3 | ||||
-rw-r--r-- | src/view/com/util/forms/PostDropdownBtnMenuItems.tsx | 111 | ||||
-rw-r--r-- | src/view/com/util/post-ctrls/PostCtrls.tsx | 53 | ||||
-rw-r--r-- | src/view/screens/DebugMod.tsx | 1 | ||||
-rw-r--r-- | yarn.lock | 116 |
14 files changed, 201 insertions, 184 deletions
diff --git a/package.json b/package.json index 62762bfc7..fed0d4fc1 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "icons:optimize": "svgo -f ./assets/icons" }, "dependencies": { - "@atproto/api": "^0.15.7", + "@atproto/api": "^0.15.8", "@bitdrift/react-native": "^0.6.8", "@braintree/sanitize-url": "^6.0.2", "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", @@ -219,7 +219,7 @@ "zod": "^3.20.2" }, "devDependencies": { - "@atproto/dev-env": "^0.3.131", + "@atproto/dev-env": "^0.3.132", "@babel/core": "^7.26.0", "@babel/preset-env": "^7.26.0", "@babel/runtime": "^7.26.0", diff --git a/src/lib/api/feed-manip.ts b/src/lib/api/feed-manip.ts index a1b2e2bc9..3309191f3 100644 --- a/src/lib/api/feed-manip.ts +++ b/src/lib/api/feed-manip.ts @@ -1,5 +1,5 @@ import { - AppBskyActorDefs, + type AppBskyActorDefs, AppBskyEmbedRecord, AppBskyEmbedRecordWithMedia, AppBskyFeedDefs, @@ -9,7 +9,7 @@ import { import * as bsky from '#/types/bsky' import {isPostInLanguage} from '../../locale/helpers' import {FALLBACK_MARKER_POST} from './feed/home' -import {ReasonFeedSource} from './feed/types' +import {type ReasonFeedSource} from './feed/types' type FeedViewPost = AppBskyFeedDefs.FeedViewPost @@ -187,6 +187,10 @@ export class FeedViewPostsSlice { return this._feedPost.feedContext } + get reqId() { + return this._feedPost.reqId + } + get isRepost() { const reason = this._feedPost.reason return AppBskyFeedDefs.isReasonRepost(reason) diff --git a/src/screens/Search/Explore.tsx b/src/screens/Search/Explore.tsx index 8050d7f73..1aac68c43 100644 --- a/src/screens/Search/Explore.tsx +++ b/src/screens/Search/Explore.tsx @@ -882,6 +882,7 @@ export function Explore({ record={subItem.record} reason={indexInSlice === 0 ? slice.reason : undefined} feedContext={slice.feedContext} + reqId={slice.reqId} moderation={subItem.moderation} parentAuthor={subItem.parentAuthor} showReplyTo={item.showReplyTo} diff --git a/src/screens/VideoFeed/index.tsx b/src/screens/VideoFeed/index.tsx index aabfe4b20..047961766 100644 --- a/src/screens/VideoFeed/index.tsx +++ b/src/screens/VideoFeed/index.tsx @@ -178,6 +178,7 @@ type VideoItem = { post: AppBskyFeedDefs.PostView video: AppBskyEmbedVideo.View feedContext: string | undefined + reqId: string | undefined } function Feed() { @@ -216,6 +217,7 @@ function Feed() { post: AppBskyFeedDefs.PostView video: AppBskyEmbedVideo.View feedContext: string | undefined + reqId: string | undefined }[] = [] for (const slice of page.slices) { const feedPost = slice.items.find( @@ -228,6 +230,7 @@ function Feed() { post: feedPost.post, video: feedPost.post.embed, feedContext: slice.feedContext, + reqId: slice.reqId, }) } } @@ -274,6 +277,7 @@ function Feed() { moderation={item.moderation} scrollGesture={scrollGesture} feedContext={item.feedContext} + reqId={item.reqId} /> ) }, @@ -470,6 +474,7 @@ let VideoItem = ({ scrollGesture, moderation, feedContext, + reqId, }: { player?: VideoPlayer post: AppBskyFeedDefs.PostView @@ -479,6 +484,7 @@ let VideoItem = ({ scrollGesture: NativeGesture moderation?: ModerationDecision feedContext: string | undefined + reqId: string | undefined }): React.ReactNode => { const postShadow = usePostShadow(post) const {width, height} = useSafeAreaFrame() @@ -490,9 +496,10 @@ let VideoItem = ({ item: post.uri, event: 'app.bsky.feed.defs#interactionSeen', feedContext, + reqId, }) } - }, [active, post.uri, feedContext, sendInteraction]) + }, [active, post.uri, feedContext, reqId, sendInteraction]) // TODO: high-performance android phones should also // be capable of rendering 3 video players, but currently @@ -537,6 +544,7 @@ let VideoItem = ({ scrollGesture={scrollGesture} moderation={moderation} feedContext={feedContext} + reqId={reqId} /> )} </> @@ -682,6 +690,7 @@ function Overlay({ scrollGesture, moderation, feedContext, + reqId, }: { player?: VideoPlayer post: Shadow<AppBskyFeedDefs.PostView> @@ -690,6 +699,7 @@ function Overlay({ scrollGesture: NativeGesture moderation: ModerationDecision feedContext: string | undefined + reqId: string | undefined }) { const {_} = useLingui() const t = useTheme() @@ -760,6 +770,7 @@ function Overlay({ player={player} post={post} feedContext={feedContext} + reqId={reqId} /> )} </View> @@ -1002,10 +1013,12 @@ function PlayPauseTapArea({ player, post, feedContext, + reqId, }: { player: VideoPlayer post: Shadow<AppBskyFeedDefs.PostView> feedContext: string | undefined + reqId: string | undefined }) { const {_} = useLingui() const doubleTapRef = useRef<ReturnType<typeof setTimeout> | null>(null) @@ -1036,6 +1049,7 @@ function PlayPauseTapArea({ item: post.uri, event: 'app.bsky.feed.defs#interactionLike', feedContext, + reqId, }) } else { doubleTapRef.current = setTimeout(togglePlayPause, 200) diff --git a/src/state/feed-feedback.tsx b/src/state/feed-feedback.tsx index 2ad5ff91a..8880cb6b3 100644 --- a/src/state/feed-feedback.tsx +++ b/src/state/feed-feedback.tsx @@ -1,12 +1,15 @@ import React from 'react' -import {AppState, AppStateStatus} from 'react-native' -import {AppBskyFeedDefs} from '@atproto/api' +import {AppState, type AppStateStatus} from 'react-native' +import {type AppBskyFeedDefs} from '@atproto/api' import throttle from 'lodash.throttle' import {FEEDBACK_FEEDS, STAGING_FEEDS} from '#/lib/constants' import {logEvent} from '#/lib/statsig/statsig' import {logger} from '#/logger' -import {FeedDescriptor, FeedPostSliceItem} from '#/state/queries/post-feed' +import { + type FeedDescriptor, + type FeedPostSliceItem, +} from '#/state/queries/post-feed' import {getItemsForFeedback} from '#/view/com/posts/PostFeed' import {useAgent} from './session' @@ -103,7 +106,7 @@ export function useFeedFeedback(feed: FeedDescriptor, hasSession: boolean) { return } const items = getItemsForFeedback(feedItem) - for (const {item: postItem, feedContext} of items) { + for (const {item: postItem, feedContext, reqId} of items) { if (!history.current.has(postItem)) { history.current.add(postItem) queue.current.add( @@ -111,6 +114,7 @@ export function useFeedFeedback(feed: FeedDescriptor, hasSession: boolean) { item: postItem.uri, event: 'app.bsky.feed.defs#interactionSeen', feedContext, + reqId, }), ) sendToFeed() @@ -164,12 +168,12 @@ function isDiscoverFeed(feed: FeedDescriptor) { function toString(interaction: AppBskyFeedDefs.Interaction): string { return `${interaction.item}|${interaction.event}|${ interaction.feedContext || '' - }` + }|${interaction.reqId || ''}` } function toInteraction(str: string): AppBskyFeedDefs.Interaction { - const [item, event, feedContext] = str.split('|') - return {item, event, feedContext} + const [item, event, feedContext, reqId] = str.split('|') + return {item, event, feedContext, reqId} } type AggregatedStats = { diff --git a/src/state/queries/explore-feed-previews.tsx b/src/state/queries/explore-feed-previews.tsx index 4cd7336c0..45bfc5c48 100644 --- a/src/state/queries/explore-feed-previews.tsx +++ b/src/state/queries/explore-feed-previews.tsx @@ -215,6 +215,7 @@ export function useFeedPreviews( isFallbackMarker: false, isIncompleteThread: item.isIncompleteThread, feedContext: item.feedContext, + reqId: item.reqId, reason: item.reason, feedPostUri: item.feedPostUri, items: item.items diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index f3fa13cfb..920892924 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -92,6 +92,7 @@ export interface FeedPostSlice { isIncompleteThread: boolean isFallbackMarker: boolean feedContext: string | undefined + reqId: string | undefined feedPostUri: string reason?: | AppBskyFeedDefs.ReasonRepost @@ -316,6 +317,7 @@ export function usePostFeedQuery( userActionHistory.seen( slice.items.map(item => ({ feedContext: slice.feedContext, + reqId: slice.reqId, likeCount: item.post.likeCount ?? 0, repostCount: item.post.repostCount ?? 0, replyCount: item.post.replyCount ?? 0, @@ -333,6 +335,7 @@ export function usePostFeedQuery( isIncompleteThread: slice.isIncompleteThread, isFallbackMarker: slice.isFallbackMarker, feedContext: slice.feedContext, + reqId: slice.reqId, reason: slice.reason, feedPostUri: slice.feedPostUri, items: slice.items.map((item, i) => { diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx index 732d0fcab..9aa4512a4 100644 --- a/src/view/com/posts/PostFeed.tsx +++ b/src/view/com/posts/PostFeed.tsx @@ -103,6 +103,7 @@ type FeedRow = items: FeedPostSliceItem[] sourceFeedUri: string feedContexts: (string | undefined)[] + reqIds: (string | undefined)[] } | { type: 'sliceViewFullThread' @@ -134,16 +135,19 @@ export function getItemsForFeedback(feedRow: FeedRow): | { item: FeedPostSliceItem feedContext: string | undefined + reqId: string | undefined }[] { if (feedRow.type === 'sliceItem') { return feedRow.slice.items.map(item => ({ item, feedContext: feedRow.slice.feedContext, + reqId: feedRow.slice.reqId, })) } else if (feedRow.type === 'videoGridRow') { return feedRow.items.map((item, i) => ({ item, feedContext: feedRow.feedContexts[i], + reqId: feedRow.reqIds[i], })) } else { return [] @@ -398,6 +402,7 @@ let PostFeed = ({ const videos: { item: FeedPostSliceItem feedContext: string | undefined + reqId: string | undefined }[] = [] for (const page of data.pages) { for (const slice of page.slices) { @@ -405,7 +410,11 @@ let PostFeed = ({ item => item.uri === slice.feedPostUri, ) if (item && AppBskyEmbedVideo.isView(item.post.embed)) { - videos.push({item, feedContext: slice.feedContext}) + videos.push({ + item, + feedContext: slice.feedContext, + reqId: slice.reqId, + }) } } } @@ -413,12 +422,17 @@ let PostFeed = ({ const rows: { item: FeedPostSliceItem feedContext: string | undefined + reqId: string | undefined }[][] = [] for (let i = 0; i < videos.length; i++) { const video = videos[i] const item = video.item const cols = gtMobile ? 3 : 2 - const rowItem = {item, feedContext: video.feedContext} + const rowItem = { + item, + feedContext: video.feedContext, + reqId: video.reqId, + } if (i % cols === 0) { rows.push([rowItem]) } else { @@ -434,6 +448,7 @@ let PostFeed = ({ items: row.map(r => r.item), sourceFeedUri: feedUriOrActorDid, feedContexts: row.map(r => r.feedContext), + reqIds: row.map(r => r.reqId), }) } } else { @@ -685,6 +700,7 @@ let PostFeed = ({ record={item.record} reason={indexInSlice === 0 ? slice.reason : undefined} feedContext={slice.feedContext} + reqId={slice.reqId} moderation={item.moderation} parentAuthor={item.parentAuthor} showReplyTo={row.showReplyTo} diff --git a/src/view/com/posts/PostFeedItem.tsx b/src/view/com/posts/PostFeedItem.tsx index ceb653b9c..2cc749404 100644 --- a/src/view/com/posts/PostFeedItem.tsx +++ b/src/view/com/posts/PostFeedItem.tsx @@ -70,6 +70,7 @@ interface FeedItemProps { isThreadLastChild?: boolean isThreadParent?: boolean feedContext: string | undefined + reqId: string | undefined hideTopBorder?: boolean isParentBlocked?: boolean isParentNotFound?: boolean @@ -80,6 +81,7 @@ export function PostFeedItem({ record, reason, feedContext, + reqId, moderation, parentAuthor, showReplyTo, @@ -117,6 +119,7 @@ export function PostFeedItem({ record={record} reason={reason} feedContext={feedContext} + reqId={reqId} richText={richText} parentAuthor={parentAuthor} showReplyTo={showReplyTo} @@ -140,6 +143,7 @@ let FeedItemInner = ({ record, reason, feedContext, + reqId, richText, moderation, parentAuthor, @@ -171,11 +175,12 @@ let FeedItemInner = ({ }, [post.uri, post.author]) const {sendInteraction} = useFeedFeedbackContext() - const onPressReply = useCallback(() => { + const onPressReply = () => { sendInteraction({ item: post.uri, event: 'app.bsky.feed.defs#interactionReply', feedContext, + reqId, }) openComposer({ replyTo: { @@ -187,40 +192,44 @@ let FeedItemInner = ({ moderation, }, }) - }, [post, record, openComposer, moderation, sendInteraction, feedContext]) + } - const onOpenAuthor = useCallback(() => { + const onOpenAuthor = () => { sendInteraction({ item: post.uri, event: 'app.bsky.feed.defs#clickthroughAuthor', feedContext, + reqId, }) - }, [sendInteraction, post, feedContext]) + } - const onOpenReposter = useCallback(() => { + const onOpenReposter = () => { sendInteraction({ item: post.uri, event: 'app.bsky.feed.defs#clickthroughReposter', feedContext, + reqId, }) - }, [sendInteraction, post, feedContext]) + } - const onOpenEmbed = useCallback(() => { + const onOpenEmbed = () => { sendInteraction({ item: post.uri, event: 'app.bsky.feed.defs#clickthroughEmbed', feedContext, + reqId, }) - }, [sendInteraction, post, feedContext]) + } - const onBeforePress = useCallback(() => { + const onBeforePress = () => { sendInteraction({ item: post.uri, event: 'app.bsky.feed.defs#clickthroughItem', feedContext, + reqId, }) precacheProfile(queryClient, post.author) - }, [queryClient, post, sendInteraction, feedContext]) + } const outerStyles = [ styles.outer, @@ -437,6 +446,7 @@ let FeedItemInner = ({ onPressReply={onPressReply} logContext="FeedItem" feedContext={feedContext} + reqId={reqId} threadgateRecord={threadgateRecord} onShowLess={onShowLess} /> diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx index c50b36640..57ee95e31 100644 --- a/src/view/com/util/forms/PostDropdownBtn.tsx +++ b/src/view/com/util/forms/PostDropdownBtn.tsx @@ -28,6 +28,7 @@ let PostDropdownBtn = ({ testID, post, postFeedContext, + postReqId, record, richText, style, @@ -40,6 +41,7 @@ let PostDropdownBtn = ({ testID: string post: Shadow<AppBskyFeedDefs.PostView> postFeedContext: string | undefined + postReqId: string | undefined record: AppBskyFeedPost.Record richText: RichTextAPI style?: StyleProp<ViewStyle> @@ -99,6 +101,7 @@ let PostDropdownBtn = ({ testID={testID} post={post} postFeedContext={postFeedContext} + postReqId={postReqId} record={record} richText={richText} timestamp={timestamp} diff --git a/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx b/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx index 7958968b4..a5f41ea7a 100644 --- a/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx +++ b/src/view/com/util/forms/PostDropdownBtnMenuItems.tsx @@ -1,4 +1,4 @@ -import React, {memo, useCallback} from 'react' +import React, {memo} from 'react' import { Platform, type PressableProps, @@ -97,6 +97,7 @@ import * as Toast from '../Toast' let PostDropdownMenuItems = ({ post, postFeedContext, + postReqId, record, richText, timestamp, @@ -106,6 +107,7 @@ let PostDropdownMenuItems = ({ testID: string post: Shadow<AppBskyFeedDefs.PostView> postFeedContext: string | undefined + postReqId: string | undefined record: AppBskyFeedPost.Record richText: RichTextAPI style?: StyleProp<ViewStyle> @@ -189,7 +191,7 @@ let PostDropdownMenuItems = ({ langPrefs.primaryLanguage, ) - const onDeletePost = React.useCallback(() => { + const onDeletePost = () => { deletePostMutate({uri: postUri}).then( () => { Toast.show(_(msg({message: 'Post deleted', context: 'toast'}))) @@ -215,18 +217,9 @@ let PostDropdownMenuItems = ({ Toast.show(_(msg`Failed to delete post, please try again`), 'xmark') }, ) - }, [ - navigation, - postUri, - deletePostMutate, - postAuthor, - currentAccount, - isAuthor, - href, - _, - ]) - - const onToggleThreadMute = React.useCallback(() => { + } + + const onToggleThreadMute = () => { try { if (isThreadMuted) { unmuteThread() @@ -246,16 +239,16 @@ let PostDropdownMenuItems = ({ ) } } - }, [isThreadMuted, unmuteThread, _, muteThread]) + } - const onCopyPostText = React.useCallback(() => { + const onCopyPostText = () => { const str = richTextToString(richText, true) Clipboard.setStringAsync(str) Toast.show(_(msg`Copied to clipboard`), 'clipboard-check') - }, [_, richText]) + } - const onPressTranslate = React.useCallback(async () => { + const onPressTranslate = async () => { await openLink(translatorUrl, true) if ( @@ -270,40 +263,40 @@ let PostDropdownMenuItems = ({ textLength: post.record.text.length, }) } - }, [openLink, translatorUrl, langPrefs, post]) + } - const onHidePost = React.useCallback(() => { + const onHidePost = () => { hidePost({uri: postUri}) - }, [postUri, hidePost]) + } - const hideInPWI = React.useMemo(() => { - return !!postAuthor.labels?.find( - label => label.val === '!no-unauthenticated', - ) - }, [postAuthor]) + const hideInPWI = !!postAuthor.labels?.find( + label => label.val === '!no-unauthenticated', + ) const showLoggedOutWarning = postAuthor.did !== currentAccount?.did && hideInPWI - const onSharePost = React.useCallback(() => { + const onSharePost = () => { const url = toShareUrl(href) shareUrl(url) - }, [href]) + } - const onPressShowMore = React.useCallback(() => { + const onPressShowMore = () => { feedFeedback.sendInteraction({ event: 'app.bsky.feed.defs#requestMore', item: postUri, feedContext: postFeedContext, + reqId: postReqId, }) Toast.show(_(msg({message: 'Feedback sent!', context: 'toast'}))) - }, [feedFeedback, postUri, postFeedContext, _]) + } - const onPressShowLess = React.useCallback(() => { + const onPressShowLess = () => { feedFeedback.sendInteraction({ event: 'app.bsky.feed.defs#requestLess', item: postUri, feedContext: postFeedContext, + reqId: postReqId, }) if (onShowLess) { onShowLess({ @@ -313,19 +306,16 @@ let PostDropdownMenuItems = ({ } else { Toast.show(_(msg({message: 'Feedback sent!', context: 'toast'}))) } - }, [feedFeedback, postUri, postFeedContext, _, onShowLess]) + } - const onSelectChatToShareTo = React.useCallback( - (conversation: string) => { - navigation.navigate('MessagesConversation', { - conversation, - embed: postUri, - }) - }, - [navigation, postUri], - ) + const onSelectChatToShareTo = (conversation: string) => { + navigation.navigate('MessagesConversation', { + conversation, + embed: postUri, + }) + } - const onToggleQuotePostAttachment = React.useCallback(async () => { + const onToggleQuotePostAttachment = async () => { if (!quoteEmbed) return const action = quoteEmbed.isDetached ? 'reattach' : 'detach' @@ -348,7 +338,7 @@ let PostDropdownMenuItems = ({ ) logger.error(`Failed to ${action} quote`, {safeMessage: e.message}) } - }, [_, quoteEmbed, post, toggleQuoteDetachment]) + } const canHidePostForMe = !isAuthor && !isPostHidden const canEmbed = isWeb && gtMobile && !hideInPWI @@ -356,7 +346,7 @@ let PostDropdownMenuItems = ({ !isAuthor && isRootPostAuthor && !isPostHidden && isReply const canDetachQuote = quoteEmbed && quoteEmbed.isOwnedByViewer - const onToggleReplyVisibility = React.useCallback(async () => { + const onToggleReplyVisibility = async () => { // TODO no threadgate? if (!canHideReplyForEveryone) return @@ -380,25 +370,18 @@ let PostDropdownMenuItems = ({ ) logger.error(`Failed to ${action} reply`, {safeMessage: e.message}) } - }, [ - _, - isReplyHiddenByThreadgate, - rootUri, - postUri, - canHideReplyForEveryone, - toggleReplyVisibility, - ]) + } - const onPressPin = useCallback(() => { + const onPressPin = () => { logEvent(isPinned ? 'post:unpin' : 'post:pin', {}) pinPostMutate({ postUri, postCid, action: isPinned ? 'unpin' : 'pin', }) - }, [isPinned, pinPostMutate, postCid, postUri]) + } - const onBlockAuthor = useCallback(async () => { + const onBlockAuthor = async () => { try { await queueBlock() Toast.show(_(msg({message: 'Account blocked', context: 'toast'}))) @@ -408,9 +391,9 @@ let PostDropdownMenuItems = ({ Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') } } - }, [_, queueBlock]) + } - const onMuteAuthor = useCallback(async () => { + const onMuteAuthor = async () => { if (postAuthor.viewer?.muted) { try { await queueUnmute() @@ -432,22 +415,22 @@ let PostDropdownMenuItems = ({ } } } - }, [_, queueMute, queueUnmute, postAuthor.viewer?.muted]) + } - const onShareATURI = useCallback(() => { + const onShareATURI = () => { shareText(postUri) - }, [postUri]) + } - const onShareAuthorDID = useCallback(() => { + const onShareAuthorDID = () => { shareText(postAuthor.did) - }, [postAuthor.did]) + } - const onReportMisclassification = useCallback(() => { + const onReportMisclassification = () => { const url = `https://docs.google.com/forms/d/e/1FAIpQLSd0QPqhNFksDQf1YyOos7r1ofCLvmrKAH1lU042TaS3GAZaWQ/viewform?entry.1756031717=${toShareUrl( href, )}` openLink(url) - }, [href, openLink]) + } return ( <> diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index a9cae8886..3f82eb294 100644 --- a/src/view/com/util/post-ctrls/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -1,4 +1,4 @@ -import React, {memo, useCallback} from 'react' +import React, {memo} from 'react' import { Pressable, type PressableStateCallbackType, @@ -55,6 +55,7 @@ let PostCtrls = ({ record, richText, feedContext, + reqId, style, onPressReply, onPostReply, @@ -67,6 +68,7 @@ let PostCtrls = ({ record: AppBskyFeedPost.Record richText: RichTextAPI feedContext?: string | undefined + reqId?: string | undefined style?: StyleProp<ViewStyle> onPressReply: () => void onPostReply?: (postUri: string | undefined) => void @@ -117,7 +119,7 @@ let PostCtrls = ({ const [hasLikeIconBeenToggled, setHasLikeIconBeenToggled] = React.useState(false) - const onPressToggleLike = React.useCallback(async () => { + const onPressToggleLike = async () => { if (isBlocked) { Toast.show( _(msg`Cannot interact with a blocked user`), @@ -134,6 +136,7 @@ let PostCtrls = ({ item: post.uri, event: 'app.bsky.feed.defs#interactionLike', feedContext, + reqId, }) captureAction(ProgressGuideAction.Like) await queueLike() @@ -145,20 +148,9 @@ let PostCtrls = ({ throw e } } - }, [ - _, - playHaptic, - post.uri, - post.viewer?.like, - queueLike, - queueUnlike, - sendInteraction, - captureAction, - feedContext, - isBlocked, - ]) + } - const onRepost = useCallback(async () => { + const onRepost = async () => { if (isBlocked) { Toast.show( _(msg`Cannot interact with a blocked user`), @@ -173,6 +165,7 @@ let PostCtrls = ({ item: post.uri, event: 'app.bsky.feed.defs#interactionRepost', feedContext, + reqId, }) await queueRepost() } else { @@ -183,18 +176,9 @@ let PostCtrls = ({ throw e } } - }, [ - _, - post.uri, - post.viewer?.repost, - queueRepost, - queueUnrepost, - sendInteraction, - feedContext, - isBlocked, - ]) + } - const onQuote = useCallback(() => { + const onQuote = () => { if (isBlocked) { Toast.show( _(msg`Cannot interact with a blocked user`), @@ -207,22 +191,15 @@ let PostCtrls = ({ item: post.uri, event: 'app.bsky.feed.defs#interactionQuote', feedContext, + reqId, }) openComposer({ quote: post, onPost: onPostReply, }) - }, [ - _, - sendInteraction, - post, - feedContext, - openComposer, - onPostReply, - isBlocked, - ]) + } - const onShare = useCallback(() => { + const onShare = () => { const urip = new AtUri(post.uri) const href = makeProfileLink(post.author, 'post', urip.rkey) const url = toShareUrl(href) @@ -231,8 +208,9 @@ let PostCtrls = ({ item: post.uri, event: 'app.bsky.feed.defs#interactionShare', feedContext, + reqId, }) - }, [post.uri, post.author, sendInteraction, feedContext]) + } const btnStyle = React.useCallback( ({pressed, hovered}: PressableStateCallbackType) => [ @@ -374,6 +352,7 @@ let PostCtrls = ({ testID="postDropdownBtn" post={post} postFeedContext={feedContext} + postReqId={reqId} record={record} richText={richText} style={{padding: 5}} diff --git a/src/view/screens/DebugMod.tsx b/src/view/screens/DebugMod.tsx index c3a82ac8e..0ccf9b67a 100644 --- a/src/view/screens/DebugMod.tsx +++ b/src/view/screens/DebugMod.tsx @@ -829,6 +829,7 @@ function MockPostFeedItem({ showReplyTo={false} reason={undefined} feedContext={''} + reqId={undefined} rootPost={post} /> ) diff --git a/yarn.lock b/yarn.lock index 54b18d8cc..776f5ef7e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20,28 +20,27 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@atproto-labs/fetch-node@0.1.8": - version "0.1.8" - resolved "https://registry.yarnpkg.com/@atproto-labs/fetch-node/-/fetch-node-0.1.8.tgz#687fc8be6107f10a4247c17989792862affd838b" - integrity sha512-OOTIhZNPEDDm7kaYU8iYRgzM+D5n3mP2iiBSyKuLakKTaZBL5WwYlUsJVsqX26SnUXtGEroOJEVJ6f66OcG80w== +"@atproto-labs/fetch-node@0.1.9": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@atproto-labs/fetch-node/-/fetch-node-0.1.9.tgz#5df902413cc2ebfff914999ad3fbbc13b20e1dd0" + integrity sha512-8sHDDXZEzQptLu8ddUU/8U+THS6dumgPynVX0/1PjUYd4S/FWyPcz6yMIiVChTfzKnZvYRRz47+qvOKhydrHQw== dependencies: - "@atproto-labs/fetch" "0.2.2" - "@atproto-labs/pipe" "0.1.0" + "@atproto-labs/fetch" "0.2.3" + "@atproto-labs/pipe" "0.1.1" ipaddr.js "^2.1.0" - psl "^1.9.0" undici "^6.14.1" -"@atproto-labs/fetch@0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@atproto-labs/fetch/-/fetch-0.2.2.tgz#c65acfd7b2265a8fe7d4ba3997126cce07bafe26" - integrity sha512-QyafkedbFeVaN20DYUpnY2hcArYxjdThPXbYMqOSoZhcvkrUqaw4xDND4wZB5TBD9cq2yqe9V6mcw9P4XQKQuQ== +"@atproto-labs/fetch@0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@atproto-labs/fetch/-/fetch-0.2.3.tgz#d47afec078f630c50e291c56264cc0ff13d0c6cc" + integrity sha512-NZtbJOCbxKUFRFKMpamT38PUQMY0hX0p7TG5AEYOPhZKZEP7dHZ1K2s1aB8MdVH0qxmqX7nQleNrrvLf09Zfdw== dependencies: - "@atproto-labs/pipe" "0.1.0" + "@atproto-labs/pipe" "0.1.1" -"@atproto-labs/pipe@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@atproto-labs/pipe/-/pipe-0.1.0.tgz#c8d86923b6d8e900d39efe6fdcdf0d897c434086" - integrity sha512-ghOqHFyJlQVFPESzlVHjKroP0tPzbmG5Jms0dNI9yLDEfL8xp4OFPWLX4f6T8mRq69wWs4nIDM3sSsFbFqLa1w== +"@atproto-labs/pipe@0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@atproto-labs/pipe/-/pipe-0.1.1.tgz#1c4232d16bf95f251e993cb6ee440f9aa4e87ce6" + integrity sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg== "@atproto-labs/simple-store-memory@0.1.3": version "0.1.3" @@ -64,10 +63,10 @@ "@atproto/xrpc" "^0.7.0" "@atproto/xrpc-server" "^0.7.18" -"@atproto/api@^0.15.7": - version "0.15.7" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.15.7.tgz#8436162d9fa5dac627bdd5c0f5c9598309ec1383" - integrity sha512-YRETLcOwDCYfGs7Sl9ObqPwhOlVWrPkw4f1AYGIrXLQS58WHe/vz1lZbqOqMsC6gvCnyZnOuKlhsRHZ14rBLzg== +"@atproto/api@^0.15.8": + version "0.15.8" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.15.8.tgz#f284a9c225191ebd35b46f5695932ab649c04a61" + integrity sha512-PsCgmV4zPjN8VuJMruxqauhn88PuS0b8t2Xsjl4617+bCPpY513jVlxgNH/XExxO7TSVvJM7EzdLY4o3fqh/xQ== dependencies: "@atproto/common-web" "^0.4.2" "@atproto/lexicon" "^0.4.11" @@ -95,14 +94,14 @@ multiformats "^9.9.0" uint8arrays "3.0.0" -"@atproto/bsky@^0.0.149": - version "0.0.149" - resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.149.tgz#3e9cfb999b9958e9a61776eddb72d424905ec3be" - integrity sha512-7j2KgWHm1nOTQDmtEcNwtldTArS9WwZS3M+aw7OmGH8wCa8vEljNxP6HETjtktDMNTrSipHmmyqh25+Rc5+Ziw== +"@atproto/bsky@^0.0.150": + version "0.0.150" + resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.150.tgz#6626095875d805d0d3f38fa4e184b9f7d274c80f" + integrity sha512-dn1jzP1EId842+g78Q6EMdOmgEZxa9bSq20HMdd5/R8uu559mPs8zigFuddqCoT1fRaJXFC8ZP7Jk5asvBQhrA== dependencies: - "@atproto-labs/fetch-node" "0.1.8" + "@atproto-labs/fetch-node" "0.1.9" "@atproto-labs/xrpc-utils" "0.0.14" - "@atproto/api" "^0.15.7" + "@atproto/api" "^0.15.8" "@atproto/common" "^0.4.11" "@atproto/crypto" "^0.4.4" "@atproto/did" "^0.1.5" @@ -219,20 +218,20 @@ "@noble/hashes" "^1.6.1" uint8arrays "3.0.0" -"@atproto/dev-env@^0.3.131": - version "0.3.131" - resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.131.tgz#b3b4cee5f367766d542515b1713523423ecb5a71" - integrity sha512-Tijqc/vq7qKGTpgoKm1BwyvP2QfoOQRjNm9Ro5CDAMXsKqHfXxPiytxYqxj6QR/PptC27aDUqgmexluZN6XbWg== +"@atproto/dev-env@^0.3.132": + version "0.3.132" + resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.132.tgz#78d55ef08a368a752c55b1ee7b7c08a41f27b5ac" + integrity sha512-RFd/9kgvmbP859N6NLu/FxCzLsj01iq22P9jNpL+dQNXbWXHYwGMUa6edf/ZrljNi3dFBNxabdDZJ2q+8uvBJQ== dependencies: - "@atproto/api" "^0.15.7" - "@atproto/bsky" "^0.0.149" + "@atproto/api" "^0.15.8" + "@atproto/bsky" "^0.0.150" "@atproto/bsync" "^0.0.19" "@atproto/common-web" "^0.4.2" "@atproto/crypto" "^0.4.4" "@atproto/identity" "^0.4.8" "@atproto/lexicon" "^0.4.11" - "@atproto/ozone" "^0.1.110" - "@atproto/pds" "^0.4.137" + "@atproto/ozone" "^0.1.111" + "@atproto/pds" "^0.4.138" "@atproto/sync" "^0.1.23" "@atproto/syntax" "^0.4.0" "@atproto/xrpc-server" "^0.7.18" @@ -302,21 +301,21 @@ optionalDependencies: "@atproto/oauth-provider-api" "0.1.2" -"@atproto/oauth-provider-ui@0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-ui/-/oauth-provider-ui-0.1.4.tgz#5e092d30afa583fdab54fc78371aecb1cbfa017d" - integrity sha512-GTQnB7OUBFSeXcdRseAGYzKe9UUFB/kGjRcIA8+pO5pCMD7JdXI+WliUhsbdmQ2I+OK78aAlCrmygNWpLtpZgg== +"@atproto/oauth-provider-ui@0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-ui/-/oauth-provider-ui-0.1.5.tgz#b080c5e814975821689c5976c27ac1081211106f" + integrity sha512-pW0Vx3kvIWH1Mu3SOImNHP9JbmhSj2e3ChDvtfXCWI1oC03fiaMlJfdxrx9Plq5Z+DajnCzPzrf1Lvbopjf94Q== optionalDependencies: "@atproto/oauth-provider-api" "0.1.2" -"@atproto/oauth-provider@^0.7.6": - version "0.7.6" - resolved "https://registry.yarnpkg.com/@atproto/oauth-provider/-/oauth-provider-0.7.6.tgz#68bc37303611d548bae9f653d41bc89bd8890152" - integrity sha512-4YcnddACznmpuRmHlt9G+kccdv2Gct5qQOF9Yyjse8cl2Td+Rg1gkchpRdWUnyr9fgZzmCsSBYzEfVXge3eUiQ== +"@atproto/oauth-provider@^0.7.7": + version "0.7.7" + resolved "https://registry.yarnpkg.com/@atproto/oauth-provider/-/oauth-provider-0.7.7.tgz#dbbdeb405ab1d239fd926340f83fb41e13455011" + integrity sha512-ElphzmOjw1hr42HN4dD6sMAQFtpTkaJ8bBDAsbL9YBVJDEGhmHsF3Ye8mDUO4nhEdg7PUTWiCzXyqnaorAjiTA== dependencies: - "@atproto-labs/fetch" "0.2.2" - "@atproto-labs/fetch-node" "0.1.8" - "@atproto-labs/pipe" "0.1.0" + "@atproto-labs/fetch" "0.2.3" + "@atproto-labs/fetch-node" "0.1.9" + "@atproto-labs/pipe" "0.1.1" "@atproto-labs/simple-store" "0.2.0" "@atproto-labs/simple-store-memory" "0.1.3" "@atproto/common" "^0.4.11" @@ -324,7 +323,7 @@ "@atproto/jwk-jose" "0.1.6" "@atproto/oauth-provider-api" "0.1.2" "@atproto/oauth-provider-frontend" "0.1.4" - "@atproto/oauth-provider-ui" "0.1.4" + "@atproto/oauth-provider-ui" "0.1.5" "@atproto/oauth-types" "0.2.7" "@atproto/syntax" "0.4.0" "@hapi/accept" "^6.0.3" @@ -337,7 +336,6 @@ http-errors "^2.0.0" ioredis "^5.3.2" jose "^5.2.0" - psl "^1.9.0" zod "^3.23.8" "@atproto/oauth-types@0.2.7": @@ -348,12 +346,12 @@ "@atproto/jwk" "0.1.5" zod "^3.23.8" -"@atproto/ozone@^0.1.110": - version "0.1.110" - resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.110.tgz#78ad57961b4699c8aa3e6f7d5b6f215d7760a723" - integrity sha512-X7VU7QAkwJrwpgmAuAHqvVDX9CEW0Ts5R4ovATgEt2lbxyxtJtYIm1dG346fAlOfC9f3RGN+HI8vBMWrrrLKAQ== +"@atproto/ozone@^0.1.111": + version "0.1.111" + resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.111.tgz#7ef4a02f1af045ab44254fb9d44ab0e50fd94ba9" + integrity sha512-NY+Cn/3dY4tPFkMUoJR1KMZN/v9ZIxjx6EQBMwn/nqTiHk0E3rtGEbyL2jLQ7x+FxpPTjDgpnn3K725+8XUaAg== dependencies: - "@atproto/api" "^0.15.7" + "@atproto/api" "^0.15.8" "@atproto/common" "^0.4.11" "@atproto/crypto" "^0.4.4" "@atproto/identity" "^0.4.8" @@ -378,20 +376,20 @@ undici "^6.14.1" ws "^8.12.0" -"@atproto/pds@^0.4.137": - version "0.4.137" - resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.137.tgz#87468703b02bf42681ddd50049ee906331655731" - integrity sha512-DRUck9CgOdK0cP6B6/1Cku2gb5t31Vhh9su2TcqF9eymZP1dNSI6nfTIEp+cuwpW/VpDeu7AfHCSgYfnJeZ5yg== +"@atproto/pds@^0.4.138": + version "0.4.138" + resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.138.tgz#437d785c83f710bf37bef8baf687b0a46ce9dc68" + integrity sha512-WLzDhmguTgs2wQNKoGxCbpKNegDnRiemSslenMbPrB7kSiXYj+XZobLyoIXHv1EnAd2pbThwNEL8z8EfkM0mDg== dependencies: - "@atproto-labs/fetch-node" "0.1.8" + "@atproto-labs/fetch-node" "0.1.9" "@atproto-labs/xrpc-utils" "0.0.14" - "@atproto/api" "^0.15.7" + "@atproto/api" "^0.15.8" "@atproto/aws" "^0.2.21" "@atproto/common" "^0.4.11" "@atproto/crypto" "^0.4.4" "@atproto/identity" "^0.4.8" "@atproto/lexicon" "^0.4.11" - "@atproto/oauth-provider" "^0.7.6" + "@atproto/oauth-provider" "^0.7.7" "@atproto/repo" "^0.8.1" "@atproto/syntax" "^0.4.0" "@atproto/xrpc" "^0.7.0" |