add reqId to feed feedback (#8396)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 (
|
||||
<>
|
||||
|
||||
@@ -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}}
|
||||
|
||||
@@ -829,6 +829,7 @@ function MockPostFeedItem({
|
||||
showReplyTo={false}
|
||||
reason={undefined}
|
||||
feedContext={''}
|
||||
reqId={undefined}
|
||||
rootPost={post}
|
||||
/>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user