don't load feed data if we already have it

This commit is contained in:
Samuel Newman
2025-06-27 11:26:40 +03:00
parent 3dde539a1a
commit 5d50a1b559
2 changed files with 61 additions and 52 deletions
+10 -13
View File
@@ -1,10 +1,9 @@
import React from 'react' import React from 'react'
import {StyleSheet} from 'react-native'
import {moderateFeedGenerator} from '@atproto/api' import {moderateFeedGenerator} from '@atproto/api'
import {usePalette} from '#/lib/hooks/usePalette'
import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {FeedSourceCard} from '#/view/com/feeds/FeedSourceCard' import {FeedSourceCard} from '#/view/com/feeds/FeedSourceCard'
import {atoms as a, useTheme} from '#/alf'
import {ContentHider} from '#/components/moderation/ContentHider' import {ContentHider} from '#/components/moderation/ContentHider'
import {type EmbedType} from '#/types/bsky/post' import {type EmbedType} from '#/types/bsky/post'
import {type CommonProps} from './types' import {type CommonProps} from './types'
@@ -14,11 +13,18 @@ export function FeedEmbed({
}: CommonProps & { }: CommonProps & {
embed: EmbedType<'feed'> embed: EmbedType<'feed'>
}) { }) {
const pal = usePalette('default') const t = useTheme()
return ( return (
<FeedSourceCard <FeedSourceCard
feedUri={embed.view.uri} feedUri={embed.view.uri}
style={[pal.view, pal.border, styles.customFeedOuter]} feedData={embed.view}
style={[
t.atoms.bg,
t.atoms.border_contrast_low,
a.p_md,
a.rounded_sm,
a.border,
]}
showLikes showLikes
/> />
) )
@@ -41,12 +47,3 @@ export function ModeratedFeedEmbed({
</ContentHider> </ContentHider>
) )
} }
const styles = StyleSheet.create({
customFeedOuter: {
borderWidth: StyleSheet.hairlineWidth,
borderRadius: 8,
paddingHorizontal: 12,
paddingVertical: 12,
},
})
+51 -39
View File
@@ -2,12 +2,17 @@ import React from 'react'
import { import {
Linking, Linking,
Pressable, Pressable,
StyleProp, type StyleProp,
StyleSheet, StyleSheet,
View, View,
ViewStyle, type ViewStyle,
} from 'react-native' } from 'react-native'
import {AtUri} from '@atproto/api' import {
type $Typed,
AppBskyFeedDefs,
type AppBskyGraphDefs,
AtUri,
} from '@atproto/api'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {msg, Plural, Trans} from '@lingui/macro' import {msg, Plural, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
@@ -17,34 +22,31 @@ import {usePalette} from '#/lib/hooks/usePalette'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
import {s} from '#/lib/styles' import {s} from '#/lib/styles'
import {logger} from '#/logger' import {logger} from '#/logger'
import {FeedSourceInfo, useFeedSourceInfoQuery} from '#/state/queries/feed' import {
type FeedSourceInfo,
hydrateFeedGenerator,
hydrateList,
useFeedSourceInfoQuery,
} from '#/state/queries/feed'
import { import {
useAddSavedFeedsMutation, useAddSavedFeedsMutation,
usePreferencesQuery, usePreferencesQuery,
UsePreferencesQueryResponse,
useRemoveFeedMutation, useRemoveFeedMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
import {Text} from '#/view/com/util/text/Text'
import * as Toast from '#/view/com/util/Toast' import * as Toast from '#/view/com/util/Toast'
import {useTheme} from '#/alf' import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {shouldClickOpenNewTab} from '#/components/Link' import {shouldClickOpenNewTab} from '#/components/Link'
import * as Prompt from '#/components/Prompt' import * as Prompt from '#/components/Prompt'
import {RichText} from '#/components/RichText' import {RichText} from '#/components/RichText'
import {Text} from '../util/text/Text'
import {UserAvatar} from '../util/UserAvatar'
export function FeedSourceCard({ type FeedSourceCardProps = {
feedUri,
style,
showSaveBtn = false,
showDescription = false,
showLikes = false,
pinOnSave = false,
showMinimalPlaceholder,
hideTopBorder,
}: {
feedUri: string feedUri: string
feedData?:
| $Typed<AppBskyFeedDefs.GeneratorView>
| $Typed<AppBskyGraphDefs.ListView>
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
showSaveBtn?: boolean showSaveBtn?: boolean
showDescription?: boolean showDescription?: boolean
@@ -52,30 +54,40 @@ export function FeedSourceCard({
pinOnSave?: boolean pinOnSave?: boolean
showMinimalPlaceholder?: boolean showMinimalPlaceholder?: boolean
hideTopBorder?: boolean hideTopBorder?: boolean
}) { }
const {data: preferences} = usePreferencesQuery()
const {data: feed} = useFeedSourceInfoQuery({uri: feedUri})
return ( export function FeedSourceCard({
<FeedSourceCardLoaded feedUri,
feedUri={feedUri} feedData,
feed={feed} ...props
preferences={preferences} }: FeedSourceCardProps) {
style={style} if (feedData) {
showSaveBtn={showSaveBtn} let feed: FeedSourceInfo
showDescription={showDescription} if (AppBskyFeedDefs.isGeneratorView(feedData)) {
showLikes={showLikes} feed = hydrateFeedGenerator(feedData)
pinOnSave={pinOnSave} } else {
showMinimalPlaceholder={showMinimalPlaceholder} feed = hydrateList(feedData)
hideTopBorder={hideTopBorder} }
/> return <FeedSourceCardLoaded feedUri={feedUri} feed={feed} {...props} />
) } else {
return <FeedSourceCardWithoutData feedUri={feedUri} {...props} />
}
}
export function FeedSourceCardWithoutData({
feedUri,
...props
}: Omit<FeedSourceCardProps, 'feedData'>) {
const {data: feed} = useFeedSourceInfoQuery({
uri: feedUri,
})
return <FeedSourceCardLoaded feedUri={feedUri} feed={feed} {...props} />
} }
export function FeedSourceCardLoaded({ export function FeedSourceCardLoaded({
feedUri, feedUri,
feed, feed,
preferences,
style, style,
showSaveBtn = false, showSaveBtn = false,
showDescription = false, showDescription = false,
@@ -86,7 +98,6 @@ export function FeedSourceCardLoaded({
}: { }: {
feedUri: string feedUri: string
feed?: FeedSourceInfo feed?: FeedSourceInfo
preferences?: UsePreferencesQueryResponse
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
showSaveBtn?: boolean showSaveBtn?: boolean
showDescription?: boolean showDescription?: boolean
@@ -95,6 +106,7 @@ export function FeedSourceCardLoaded({
showMinimalPlaceholder?: boolean showMinimalPlaceholder?: boolean
hideTopBorder?: boolean hideTopBorder?: boolean
}) { }) {
const {data: preferences} = usePreferencesQuery()
const t = useTheme() const t = useTheme()
const pal = usePalette('default') const pal = usePalette('default')
const {_} = useLingui() const {_} = useLingui()
@@ -248,7 +260,7 @@ export function FeedSourceCardLoaded({
<Text emoji style={[pal.text, s.bold]} numberOfLines={1}> <Text emoji style={[pal.text, s.bold]} numberOfLines={1}>
{feed.displayName} {feed.displayName}
</Text> </Text>
<Text style={[pal.textLight]} numberOfLines={1}> <Text type="sm" style={[pal.textLight]} numberOfLines={1}>
{feed.type === 'feed' ? ( {feed.type === 'feed' ? (
<Trans>Feed by {sanitizeHandle(feed.creatorHandle, '@')}</Trans> <Trans>Feed by {sanitizeHandle(feed.creatorHandle, '@')}</Trans>
) : ( ) : (