diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 315c9cfa..c1484a59 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -78,7 +78,10 @@ export interface FeedPostSliceItem { uri: string post: AppBskyFeedDefs.PostView record: AppBskyFeedPost.Record - reason?: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource + reason?: + | AppBskyFeedDefs.ReasonRepost + | ReasonFeedSource + | {[k: string]: unknown; $type: string} feedContext: string | undefined moderation: ModerationDecision parentAuthor?: AppBskyActorDefs.ProfileViewBasic @@ -323,7 +326,7 @@ export function usePostFeedQuery( ) } - return { + const feedPostSlice: FeedPostSlice = { _reactKey: slice._reactKey, _isFeedPostSlice: true, rootUri: slice.rootItem.post.uri, @@ -341,15 +344,23 @@ export function usePostFeedQuery( AppBskyFeedPost.validateRecord(item.post.record) .success ) { - const parentAuthor = - item.reply?.parent?.author ?? - slice.items[i + 1]?.reply?.grandparentAuthor + const parent = item.reply?.parent + let parentAuthor: + | AppBskyActorDefs.ProfileViewBasic + | undefined + if (AppBskyFeedDefs.isPostView(parent)) { + parentAuthor = parent.author + } + if (!parentAuthor) { + parentAuthor = + slice.items[i + 1]?.reply?.grandparentAuthor + } const replyRef = item.reply const isParentBlocked = AppBskyFeedDefs.isBlockedPost( replyRef?.parent, ) - return { + const feedPostSliceItem: FeedPostSliceItem = { _reactKey: `${slice._reactKey}-${i}-${item.post.uri}`, uri: item.post.uri, post: item.post, @@ -363,13 +374,15 @@ export function usePostFeedQuery( parentAuthor, isParentBlocked, } + return feedPostSliceItem } return undefined }) - .filter(Boolean) as FeedPostSliceItem[], + .filter((n?: T): n is T => Boolean(n)), } + return feedPostSlice }) - .filter(Boolean) as FeedPostSlice[], + .filter((n?: T): n is T => Boolean(n)), })), ], } diff --git a/src/state/queries/threadgate.ts b/src/state/queries/threadgate.ts index 67c6f8c0..c05d1f56 100644 --- a/src/state/queries/threadgate.ts +++ b/src/state/queries/threadgate.ts @@ -4,7 +4,7 @@ export type ThreadgateSetting = | {type: 'nobody'} | {type: 'mention'} | {type: 'following'} - | {type: 'list'; list: string} + | {type: 'list'; list: unknown} export function threadgateViewToSettings( threadgate: AppBskyFeedDefs.ThreadgateView | undefined, @@ -21,18 +21,18 @@ export function threadgateViewToSettings( if (!record.allow?.length) { return [{type: 'nobody'}] } - return record.allow + const settings: ThreadgateSetting[] = record.allow .map(allow => { + let setting: ThreadgateSetting | undefined if (allow.$type === 'app.bsky.feed.threadgate#mentionRule') { - return {type: 'mention'} + setting = {type: 'mention'} + } else if (allow.$type === 'app.bsky.feed.threadgate#followingRule') { + setting = {type: 'following'} + } else if (allow.$type === 'app.bsky.feed.threadgate#listRule') { + setting = {type: 'list', list: allow.list} } - if (allow.$type === 'app.bsky.feed.threadgate#followingRule') { - return {type: 'following'} - } - if (allow.$type === 'app.bsky.feed.threadgate#listRule') { - return {type: 'list', list: allow.list} - } - return undefined + return setting }) - .filter(Boolean) as ThreadgateSetting[] + .filter((n?: T): n is T => Boolean(n)) + return settings } diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index a59eeea5..dbc5796d 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -48,7 +48,11 @@ import {Repost_Stroke2_Corner2_Rounded as Repost} from '#/components/icons/Repos interface FeedItemProps { record: AppBskyFeedPost.Record - reason: AppBskyFeedDefs.ReasonRepost | ReasonFeedSource | undefined + reason: + | AppBskyFeedDefs.ReasonRepost + | ReasonFeedSource + | {[k: string]: unknown; $type: string} + | undefined moderation: ModerationDecision parentAuthor: AppBskyActorDefs.ProfileViewBasic | undefined showReplyTo: boolean @@ -337,9 +341,11 @@ let FeedItemInner = ({ postHref={href} onOpenAuthor={onOpenAuthor} /> - {!isThreadChild && showReplyTo && parentAuthor && ( - - )} + {!isThreadChild && + showReplyTo && + (parentAuthor || isParentBlocked) && ( + + )} Reply to a blocked post + } else if (profile != null) { + const isMe = profile.did === currentAccount?.did + if (isMe) { + label = Reply to you + } else { + label = ( + + Reply to{' '} + + + + + ) + } + } + + if (!label) { + // Should not happen. + return null + } return ( @@ -450,29 +490,7 @@ function ReplyToLabel({ style={[pal.textLight, s.mr2]} lineHeight={1.2} numberOfLines={1}> - {isMe ? ( - Reply to you - ) : blocked ? ( - Reply to a blocked post - ) : ( - - Reply to{' '} - - - - - )} + {label} ) diff --git a/src/view/screens/Search/Explore.tsx b/src/view/screens/Search/Explore.tsx index 05fd85ef..e9b74452 100644 --- a/src/view/screens/Search/Explore.tsx +++ b/src/view/screens/Search/Explore.tsx @@ -75,17 +75,17 @@ function SuggestedItemsHeader({ ) } -type LoadMoreItems = +type LoadMoreItem = | { type: 'profile' key: string - avatar: string + avatar: string | undefined moderation: ModerationDecision } | { type: 'feed' key: string - avatar: string + avatar: string | undefined moderation: undefined } @@ -98,27 +98,28 @@ function LoadMore({ }) { const t = useTheme() const {_} = useLingui() - const items = React.useMemo(() => { + const items: LoadMoreItem[] = React.useMemo(() => { return item.items .map(_item => { + let loadMoreItem: LoadMoreItem | undefined if (_item.type === 'profile') { - return { + loadMoreItem = { type: 'profile', key: _item.profile.did, avatar: _item.profile.avatar, moderation: moderateProfile(_item.profile, moderationOpts!), } } else if (_item.type === 'feed') { - return { + loadMoreItem = { type: 'feed', key: _item.feed.uri, avatar: _item.feed.avatar, moderation: undefined, } } - return undefined + return loadMoreItem }) - .filter(Boolean) as LoadMoreItems[] + .filter((n?: T): n is T => Boolean(n)) }, [item.items, moderationOpts]) if (items.length === 0) return null